From b3787c26dd3add9a6efb16d765607b0bc3c8be3d Mon Sep 17 00:00:00 2001 From: Nick Westerhausen <2317381+nwesterhausen@users.noreply.github.com> Date: Sun, 25 Feb 2024 08:33:30 -0500 Subject: [PATCH 01/51] feat: update game_library to support spells BREAKING: Changes spell types and library locations. --- Cargo.lock | 2 +- game_data/_schemas/spell_talisman.json | 120 ++++ game_library/Cargo.toml | 2 +- game_library/src/data_loader/events.rs | 4 +- game_library/src/data_loader/header_def.rs | 4 +- game_library/src/data_loader/loader.rs | 5 +- game_library/src/data_loader/spells.rs | 5 +- game_library/src/data_loader/storage.rs | 4 +- game_library/src/lib.rs | 9 +- game_library/src/spell_choices.rs | 75 --- game_library/src/spell_data.rs | 277 --------- .../src/{spell_bundle.rs => spells/bundle.rs} | 6 +- game_library/src/spells/definition.rs | 544 ++++++++++++++++++ .../{spell_lifetime.rs => spells/lifetime.rs} | 15 +- game_library/src/spells/mod.rs | 41 ++ game_library/src/spells/particles.rs | 17 + game_library/src/spells/selection.rs | 131 +++++ game_library/src/spells/talisman.rs | 144 +++++ game_library/tests/data_file.rs | 8 +- game_library/tests/spell_lifetime.rs | 14 +- game_library/tests/spells.rs | 48 ++ 21 files changed, 1085 insertions(+), 390 deletions(-) create mode 100644 game_data/_schemas/spell_talisman.json delete mode 100644 game_library/src/spell_choices.rs delete mode 100644 game_library/src/spell_data.rs rename game_library/src/{spell_bundle.rs => spells/bundle.rs} (84%) create mode 100644 game_library/src/spells/definition.rs rename game_library/src/{spell_lifetime.rs => spells/lifetime.rs} (76%) create mode 100644 game_library/src/spells/mod.rs create mode 100644 game_library/src/spells/particles.rs create mode 100644 game_library/src/spells/selection.rs create mode 100644 game_library/src/spells/talisman.rs create mode 100644 game_library/tests/spells.rs diff --git a/Cargo.lock b/Cargo.lock index db1ede6..122786b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2176,7 +2176,7 @@ dependencies = [ [[package]] name = "game_library" -version = "1.5.0" +version = "2.0.0" dependencies = [ "bevy", "bevy-inspector-egui", diff --git a/game_data/_schemas/spell_talisman.json b/game_data/_schemas/spell_talisman.json new file mode 100644 index 0000000..5308243 --- /dev/null +++ b/game_data/_schemas/spell_talisman.json @@ -0,0 +1,120 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.nwest.one/games/elementalist/spell_talisman.json", + "title": "Elementalist Spell Talisman Schema", + "description": "A spell talisman defines the properties of a spell, and is used to create a spell in the game.", + "type": "object", + "properties": { + "shaping": { + "description": "The shaping of the spell talisman. This defines the shape of the spell.", + "type": "string", + "oneOf": [ + { + "const": "Projectile", + "title": "Projectile spells are cast at a target and travel away from the caster." + }, + { + "const": "AreaOfEffect", + "title": "Area of Effect spells affect all targets within a specified area." + }, + { + "const": "Cone", + "title": "Cone spells affect all targets within a specified cone." + }, + { + "const": "Line", + "title": "Line spells affect all targets within a specified line." + }, + { + "const": "Touch", + "title": "Touch spells are cast by touching the target." + }, + { + "const": "OnSelf", + "title": "On Self spells affect the caster." + } + ] + }, + "behavior": { + "description": "The behavior of the spell talisman. This defines the behavior of the spell.", + "type": "string", + "oneOf": [ + { + "const": "Damage", + "title": "Damage spells deal damage to the target." + }, + { + "const": "Heal", + "title": "Heal spells heal the target." + }, + { + "const": "Buff", + "title": "Buff spells provide a beneficial effect to the target." + }, + { + "const": "Debuff", + "title": "Debuff spells provide a detrimental effect to the target." + }, + { + "const": "Utility", + "title": "Utility spells provide a non-damaging effect to the target." + }, + { + "const": "Summon", + "title": "Summon spells summon a creature to fight for the caster." + } + ] + }, + "tier": { + "description": "The tier of the spell talisman. This defines the power of the spell.", + "type": "string", + "oneOf": [ + { + "const": "Mundane", + "title": "Mundane or Tier 0" + }, + { + "const": "Common", + "title": "Common or Tier 1" + }, + { + "const": "Uncommon", + "title": "Uncommon or Tier 2" + }, + { + "const": "Rare", + "title": "Rare or Tier 3" + }, + { + "const": "Epic", + "title": "Epic or Tier 4" + }, + { + "const": "Legendary", + "title": "Legendary or Tier 5" + }, + { + "const": "Mythic", + "title": "Mythic or Tier 6" + }, + { + "const": "Divine", + "title": "Divine or Tier 7 (highest)" + }, + { + "const": "Unique", + "title": "Unique tier should only be used for restricted spells that are unique to a specific character or have other requirements. It cannot be inscribed by the player." + }, + { + "const": "Astral", + "title": "Astral tier spells are a step above divine. An astral talisman is not possible in the normal game." + } + ] + } + }, + "required": [ + "shaping", + "behavior", + "tier" + ] +} diff --git a/game_library/Cargo.toml b/game_library/Cargo.toml index d3ea94b..4666fa0 100644 --- a/game_library/Cargo.toml +++ b/game_library/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "game_library" -version = "1.5.0" +version = "2.0.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/game_library/src/data_loader/events.rs b/game_library/src/data_loader/events.rs index 45b6222..efeecb9 100644 --- a/game_library/src/data_loader/events.rs +++ b/game_library/src/data_loader/events.rs @@ -9,7 +9,7 @@ use bevy::ecs::event::Event; use crate::{ - particle::Particle, realm_data::Realm, simple_object::SimpleObject, SpellData, Tileset, + particle::Particle, realm_data::Realm, simple_object::SimpleObject, spells::Spell, Tileset, }; use super::DataFile; @@ -18,7 +18,7 @@ use super::DataFile; /// Event that is fired when a spell is loaded. pub struct LoadedSpellData { /// The spell data that was loaded. - pub spell_data: DataFile, + pub spell_data: DataFile, } #[derive(Event)] diff --git a/game_library/src/data_loader/header_def.rs b/game_library/src/data_loader/header_def.rs index 0985f89..d9f8aed 100644 --- a/game_library/src/data_loader/header_def.rs +++ b/game_library/src/data_loader/header_def.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; use std::hash::Hash; -use crate::{enums::GameSystem, InternalId, Tileset}; +use crate::{enums::GameSystem, spells::Spell, InternalId, Tileset}; /// Each data file includes header information about the data in the file. #[derive(Debug, Serialize, Deserialize)] @@ -75,7 +75,7 @@ impl DataFile { } /// Get the data file as a spell. Otherwise, return None. #[must_use] - pub fn as_spell(&self) -> Option { + pub fn as_spell(&self) -> Option { if self.header.system != GameSystem::Spell { return None; } diff --git a/game_library/src/data_loader/loader.rs b/game_library/src/data_loader/loader.rs index bceaa84..eac2149 100644 --- a/game_library/src/data_loader/loader.rs +++ b/game_library/src/data_loader/loader.rs @@ -5,7 +5,7 @@ use walkdir::WalkDir; use crate::{ data_loader::DATA_FILE_DIR, enums::GameSystem, particle::Particle, realm_data::Realm, - simple_object::SimpleObject, InternalId, SpellData, Tileset, + simple_object::SimpleObject, spells::Spell, InternalId, Tileset, }; use super::{ @@ -114,8 +114,7 @@ pub fn load_data_file_dir( ); match header.system { GameSystem::Spell => { - let spell_data: DataFile = if let Some(d) = read_data_file(filepath) - { + let spell_data: DataFile = if let Some(d) = read_data_file(filepath) { d } else { tracing::debug!( diff --git a/game_library/src/data_loader/spells.rs b/game_library/src/data_loader/spells.rs index c16b1b0..10423bb 100644 --- a/game_library/src/data_loader/spells.rs +++ b/game_library/src/data_loader/spells.rs @@ -15,13 +15,12 @@ pub(super) fn load_spells( tracing::info!("Load spells event with {} spells", events.len()); for event in events.read() { let unique_id = &event.spell_data.header.unique_id; - let mut spell = event.spell_data.data.clone(); - spell.update_internal_id(); + let spell = event.spell_data.data.clone().with_unique_id(&unique_id); game_data.spells.insert(unique_id.clone(), spell); tracing::debug!( "load_spells: loaded spell {} as {}", - event.spell_data.data.name, + event.spell_data.data.name(), unique_id ); } diff --git a/game_library/src/data_loader/storage.rs b/game_library/src/data_loader/storage.rs index d8fa276..dcd5ebc 100644 --- a/game_library/src/data_loader/storage.rs +++ b/game_library/src/data_loader/storage.rs @@ -2,7 +2,7 @@ use bevy::{prelude::*, utils::hashbrown::HashMap}; use bevy_hanabi::EffectAsset; -use crate::{realm_data::Realm, SimpleObject, SpellData}; +use crate::{realm_data::Realm, spells::Spell, SimpleObject}; /// The vault resource is a generic resource that holds data that is stored by a unique id. /// @@ -55,7 +55,7 @@ impl Vault { #[derive(Resource, Default, Debug, Clone)] pub struct GameData { /// The spells that have been loaded into the game. - pub spells: Vault, + pub spells: Vault, /// The tile atlases that have been loaded into the game. pub tile_atlas: Vault>, /// The particles that have been loaded into the game. diff --git a/game_library/src/lib.rs b/game_library/src/lib.rs index 6a49c92..751921c 100644 --- a/game_library/src/lib.rs +++ b/game_library/src/lib.rs @@ -29,6 +29,7 @@ pub mod math; pub mod menu_helper; pub mod progress_bar; pub mod settings; +pub mod spells; pub mod state; mod acceleration; @@ -50,10 +51,6 @@ mod schedule; mod shared_traits; mod simple_object; mod skill; -mod spell_bundle; -mod spell_choices; -mod spell_data; -mod spell_lifetime; mod stat; mod stat_bonus; mod stat_bundle; @@ -81,10 +78,6 @@ pub use schedule::*; pub use shared_traits::InternalId; pub use simple_object::SimpleObject; pub use skill::Skills; -pub use spell_bundle::SpellBundle; -pub use spell_choices::SpellChoices; -pub use spell_data::SpellData; -pub use spell_lifetime::SpellLifetime; pub use stat::Stat; pub use stat_bonus::StatBonus; pub use stat_bundle::StatBundle; diff --git a/game_library/src/spell_choices.rs b/game_library/src/spell_choices.rs deleted file mode 100644 index 9ed9f7c..0000000 --- a/game_library/src/spell_choices.rs +++ /dev/null @@ -1,75 +0,0 @@ -//! A resource that stores the player's spell choices. - -use bevy::prelude::*; -use bevy_inspector_egui::prelude::*; -use serde::{Deserialize, Serialize}; - -use crate::{enums::CastSlot, InternalId, SpellData}; - -/// A resource that stores the player's spell choices. -#[derive( - Resource, - Default, - Debug, - Reflect, - Clone, - PartialEq, - Eq, - Serialize, - Deserialize, - InspectorOptions, -)] -#[reflect(InspectorOptions)] -pub struct SpellChoices { - /// The spell to cast when the player presses the primary cast button. - pub primary: Option, - /// The spell to cast when the player presses the secondary cast button. - pub secondary: Option, - /// The spell to cast when the player presses the defensive cast button. - pub defensive: Option, - /// The spell to cast when the player presses the ultimate cast button. - pub ultimate: Option, -} - -impl SpellChoices { - /// Set the primary spell choice. - pub fn set_primary(&mut self, spell: &SpellData) { - if spell.cast_slot == CastSlot::Primary { - self.primary = Some(spell.get_internal_id()); - } - } - /// Set the secondary spell choice. - pub fn set_secondary(&mut self, spell: &SpellData) { - if spell.cast_slot == CastSlot::Secondary { - self.secondary = Some(spell.get_internal_id()); - } - } - /// Set the defensive spell choice. - pub fn set_defensive(&mut self, spell: &SpellData) { - if spell.cast_slot == CastSlot::Defensive { - self.defensive = Some(spell.get_internal_id()); - } - } - /// Set the ultimate spell choice. - pub fn set_ultimate(&mut self, spell: &SpellData) { - if spell.cast_slot == CastSlot::Ultimate { - self.ultimate = Some(spell.get_internal_id()); - } - } - /// Set the primary spell choice by spell id. - pub fn set_primary_by_id(&mut self, spell_id: String) { - self.primary = Some(spell_id); - } - /// Set the secondary spell choice by spell id. - pub fn set_secondary_by_id(&mut self, spell_id: String) { - self.secondary = Some(spell_id); - } - /// Set the defensive spell choice by spell id. - pub fn set_defensive_by_id(&mut self, spell_id: String) { - self.defensive = Some(spell_id); - } - /// Set the ultimate spell choice by spell id. - pub fn set_ultimate_by_id(&mut self, spell_id: String) { - self.ultimate = Some(spell_id); - } -} diff --git a/game_library/src/spell_data.rs b/game_library/src/spell_data.rs deleted file mode 100644 index 5ca70ef..0000000 --- a/game_library/src/spell_data.rs +++ /dev/null @@ -1,277 +0,0 @@ -//! Spell data describes how a spell works and how it should be displayed. -//! -//! You can describe spell data using YAML or JSON using the schema: -//! -//! ```yaml -//! # $schema: "https://schemas.nwest.one/games/elementalist/spell.json" -//! ``` -use bevy::reflect::Reflect; -use serde_default_utils::{default_i32, default_usize}; -use std::{any::Any, hash::Hash}; - -use crate::{ - data_loader::DataFile, - enums::{ - CastCategory, CastSlot, CastType, GameSystem, MagicType, ParticleAttachment, Skill, - SpellCollision, - }, - shared_traits::KnownCastSlot, - InternalId, StatEffect, -}; - -/// Details about a spell. -/// -/// Describes in detail how a spell works and how it should be displayed. -#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Reflect)] -#[serde(rename_all = "camelCase")] -pub struct SpellData { - /// The internal ID of the spell. - pub internal_id: Option, - /// The name of the spell. - pub name: String, - /// A short description of the spell. - pub description: String, - /// A longer description of the spell. - #[serde(default = "String::new")] - pub long_description: String, - /// The tier of the spell (0-9 officially). - pub spell_tier: usize, - /// The type of magic the spell uses. - pub magic: MagicType, - /// The slot the spell can be cast from. - pub cast_slot: CastSlot, - /// The type of collision the spell has. - #[serde(default = "spell_defaults::collision")] - pub collision: SpellCollision, - /// The type of cast the spell has. - #[serde(default = "spell_defaults::cast_type")] - pub cast_type: CastType, - /// How the spell is targeted - #[serde(default = "spell_defaults::cast_category")] - pub cast_category: CastCategory, - - // #### SPELL ICONS #### - /// The path to the icon for the spell (relative to the game's asset directory). - #[serde(default = "spell_defaults::placeholder_png_path")] - pub icon_tileset: String, - /// The index of the spell's icon in the tileset. - #[serde(default = "default_usize::<0>")] - pub icon_index: usize, - /// The path to the sprite tileset for the spell (relative to the game's asset directory). - #[serde(default = "spell_defaults::placeholder_png_path")] - pub sprite_tileset: String, - /// The index of the spell's sprite in the tileset. - #[serde(default = "default_usize::<0>")] - pub sprite_index: usize, - - // #### SPELL BASE STATS #### - /// The cooldown of the spell in seconds - #[serde(default = "spell_defaults::spell_cooldown")] - pub cooldown: f32, - /// The cast time of the spell in seconds - #[serde(default = "spell_defaults::spell_cast_time")] - pub cast_time: f32, - /// The mana cost of the spell (mana is an integer value) - #[serde(default = "default_usize::<0>")] - pub mana_cost: usize, - /// The range of the spell in centimeters. - #[serde(default = "spell_defaults::spell_range")] - pub range: f32, - /// The speed of the spell in meters per second. - #[serde(default = "spell_defaults::spell_speed")] - pub speed: f32, - /// The duration of the spell in seconds. - #[serde(default = "spell_defaults::spell_duration")] - pub duration: f32, - /// The base damage of the spell, 0 if the spell does not deal damage. - #[serde(default = "default_i32::<0>")] - pub damage: i32, - /// The base healing of the spell, 0 if the spell does not heal. - #[serde(default = "default_i32::<0>")] - pub healing: i32, - /// Radius of the spell "detonation" in centimeters. - /// - /// Spells which target the ground use this value to determine the radius of the area of effect. - /// - /// Spells which are cone or line shaped use this value to determine the width of the cone or line. - #[serde(default = "default_i32::<0>")] - pub radius: i32, - /// The angle of the spell in degrees. - /// - /// Spells which are cone shaped use this value to determine the angle of the cone. - #[serde(default = "default_i32::<0>")] - pub angle: i32, - - // #### SPELL EFFECTS #### - /// Buffs that the spell can apply to the caster or to the target. - #[serde(default = "Vec::new")] - pub buffs: Vec, - /// Debuffs that the spell can apply to the caster or to the target. - #[serde(default = "Vec::new")] - pub debuffs: Vec, - - // #### SPELL PARTICLES #### - /// Particles that the spell can create. - #[serde(default = "Vec::new")] - pub particles: Vec, -} - -impl Hash for SpellData { - fn hash(&self, state: &mut H) { - self.name.hash(state); - self.spell_tier.hash(state); - self.magic.hash(state); - self.cast_slot.hash(state); - } -} - -impl InternalId for SpellData { - /// Update the spell's internal ID. - fn update_internal_id(&mut self) { - self.internal_id = Some(self.get_internal_id()); - } - /// Get the spell's internal ID. - #[must_use] - fn get_internal_id(&self) -> String { - if self.internal_id.is_some() { - let id = self.internal_id.clone().unwrap_or_default(); - if !id.is_empty() { - return id; - } - } - - format!( - "{}{}{}{}", - self.name.replace(' ', ""), - self.spell_tier, - self.magic, - self.cast_slot - ) - } -} - -/// A particle that a spell can create. -#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Reflect)] -#[serde(rename_all = "camelCase")] -pub struct SpellParticles { - /// The unique_id for the particle effect - pub particle_id: String, - /// The attachment point for the particle effect - pub attachment: ParticleAttachment, -} - -impl KnownCastSlot for SpellData { - fn cast_slot(&self) -> CastSlot { - self.cast_slot - } -} - -impl SpellData { - /// Returns the skill that the spell uses. - #[must_use] - pub fn skill(&self) -> Skill { - self.magic.into() - } - /// Get the spell's sprite as a texture atlas sprite. - #[must_use] - pub fn texture_atlas_index(&self) -> bevy::sprite::TextureAtlasSprite { - bevy::sprite::TextureAtlasSprite::new(self.sprite_index) - } -} - -/// #### DEFAULTS FOR SERDE #### -mod spell_defaults { - use crate::enums::{CastCategory, CastType, SpellCollision}; - - pub(super) const fn collision() -> SpellCollision { - SpellCollision::Point - } - pub(super) const fn cast_type() -> CastType { - CastType::Instant - } - pub(super) const fn cast_category() -> CastCategory { - CastCategory::Projectile - } - pub(super) fn placeholder_png_path() -> String { - "placeholder.png".to_string() - } - pub(super) const fn spell_cooldown() -> f32 { - 1.0 - } - pub(super) const fn spell_cast_time() -> f32 { - 0.0 - } - pub(super) const fn spell_range() -> f32 { - 5.0 - } - pub(super) const fn spell_speed() -> f32 { - 1.0 - } - pub(super) const fn spell_duration() -> f32 { - 5.0 - } -} - -impl TryInto for DataFile { - type Error = (); - - fn try_into(self) -> Result { - if self.header.system != GameSystem::Spell { - return Err(()); - } - - (&self.data as &dyn Any) - .downcast_ref::() - .cloned() - .ok_or(()) - } -} - -impl TryFrom<&DataFile> for SpellData { - type Error = (); - - fn try_from(data_file: &DataFile) -> Result { - if data_file.header.system != GameSystem::Tileset { - return Err(()); - } - - (&data_file.data as &dyn Any) - .downcast_ref::() - .cloned() - .ok_or(()) - } -} - -impl Default for SpellData { - fn default() -> Self { - Self { - internal_id: None, - name: "Unnamed Spell".to_string(), - description: "No description provided.".to_string(), - long_description: String::new(), - spell_tier: 0, - magic: MagicType::Arcane, - cast_slot: CastSlot::Primary, - collision: SpellCollision::Point, - cast_type: CastType::Instant, - cast_category: CastCategory::Projectile, - icon_tileset: spell_defaults::placeholder_png_path(), - icon_index: 0, - sprite_tileset: spell_defaults::placeholder_png_path(), - sprite_index: 0, - cooldown: spell_defaults::spell_cooldown(), - cast_time: spell_defaults::spell_cast_time(), - mana_cost: 0, - range: spell_defaults::spell_range(), - speed: spell_defaults::spell_speed(), - duration: spell_defaults::spell_duration(), - damage: 0, - healing: 0, - radius: 0, - angle: 0, - buffs: Vec::new(), - debuffs: Vec::new(), - particles: Vec::new(), - } - } -} diff --git a/game_library/src/spell_bundle.rs b/game_library/src/spells/bundle.rs similarity index 84% rename from game_library/src/spell_bundle.rs rename to game_library/src/spells/bundle.rs index f27f0b5..c2a8ade 100644 --- a/game_library/src/spell_bundle.rs +++ b/game_library/src/spells/bundle.rs @@ -1,8 +1,8 @@ -//! This file contains the spell bundle, which is a bundle of components that are needed for a spell. +//! The spell bundle used when spawning a spell in game. //! //! This bundle contains the movement bundle, the sprite sheet bundle, and the spell lifetime component. - -use crate::{MovementBundle, SpellLifetime}; +use super::SpellLifetime; +use crate::MovementBundle; use bevy::prelude::*; /// Bundle that contains all components needed for a spell diff --git a/game_library/src/spells/definition.rs b/game_library/src/spells/definition.rs new file mode 100644 index 0000000..e2ef0e9 --- /dev/null +++ b/game_library/src/spells/definition.rs @@ -0,0 +1,544 @@ +//! Defines the `Spell` struct and its methods. + +use super::{talisman::SpellTalisman, SpellParticles}; +use crate::{ + data_loader::DataFile, + enums::{CastSlot, CastType, GameSystem, Skill}, + InternalId, StatEffect, +}; +use bevy::prelude::*; +use serde::{Deserialize, Serialize}; +use serde_default_utils::default_usize; +use std::{any::Any, hash::Hash}; + +/// A spell that can be cast by the player. +#[derive(Debug, Clone, Serialize, Deserialize, Reflect, Component, Resource)] +#[serde(rename_all = "camelCase")] +pub struct Spell { + /// The unique ID of the spell. This is actually in the header of the spell definition file. + #[serde(default = "String::new")] + unique_id: String, + /// The name of the spell. + #[serde(default = "String::new")] + name: String, + /// A short description of the spell. + #[serde(default = "String::new")] + description: String, + /// A longer description, with more details and lore. + #[serde(default = "String::new")] + lore: String, + /// The spell talisman that creates this spell + #[serde(default = "spell_defaults::talisman")] + talisman: SpellTalisman, + /// The skill that the spell uses + #[serde(default = "spell_defaults::skill")] + skill: Skill, + /// The spell slot that the spell is cast from + #[serde(default = "spell_defaults::cast_slot")] + cast_slot: CastSlot, + /// The type of casting that the spell uses + #[serde(default = "spell_defaults::cast_type")] + cast_type: CastType, + + /// Cooldown time in seconds + #[serde(default = "spell_defaults::cooldown")] + cooldown: f32, + /// Cast time in seconds + #[serde(default = "spell_defaults::cast_time")] + cast_time: f32, + /// Mana cost + #[serde(default = "spell_defaults::mana_cost")] + mana_cost: f32, + /// Range in meters + #[serde(default = "spell_defaults::range")] + range: f32, + /// Speed in meters per second (this is the maximum speed) + #[serde(default = "spell_defaults::speed")] + speed: f32, + /// The acceleration of the spell + #[serde(default = "spell_defaults::acceleration")] + acceleration: f32, + /// The duration of the spell in seconds + #[serde(default = "spell_defaults::duration")] + duration: f32, + + /// Base damage of the spell + #[serde(default = "spell_defaults::base_damage")] + base_damage: f32, + /// Base healing of the spell + #[serde(default = "spell_defaults::base_healing")] + base_healing: f32, + /// Buffs applied by the spell + #[serde(default = "Vec::new")] + buffs: Vec, + /// Debuffs applied by the spell + #[serde(default = "Vec::new")] + debuffs: Vec, + + /// Radius of the spell's area of effect. This affects the collision for `Projectile`, `Cone`, and `Line` spells, while + /// `AreaOfEffect` spells use this for their area of effect. + #[serde(default = "spell_defaults::radius")] + radius: f32, + /// An angle in radians to affect the area covered by a `Cone` spell. + #[serde(default = "spell_defaults::angle")] + angle: f32, + + /// The spell icon's tileset id + #[serde(default = "String::new")] + icon_tileset: String, + /// The spell icon's index in the tileset + #[serde(default = "default_usize::<0>")] + icon_index: usize, + /// The spell sprite's tileset id + #[serde(default = "String::new")] + sprite_tileset: String, + /// The spell sprite's index in the tileset + #[serde(default = "default_usize::<0>")] + sprite_index: usize, + + /// The particle effects that the spell creates + #[serde(default = "Vec::new")] + particles: Vec, + // The sound effects that the spell creates + // not implemented yet +} + +impl Default for Spell { + fn default() -> Self { + Self { + unique_id: String::new(), + name: String::from("Default Spell"), + description: String::from("This is the default spell, has no effects."), + lore: String::new(), + talisman: SpellTalisman::default(), + skill: Skill::Arcanomancy, + cast_slot: CastSlot::Primary, + cast_type: CastType::Instant, + cooldown: 0.0, + cast_time: 0.0, + mana_cost: 0.0, + range: 0.0, + speed: 0.0, + acceleration: 0.0, + duration: 0.0, + base_damage: 0.0, + base_healing: 0.0, + buffs: Vec::new(), + debuffs: Vec::new(), + radius: 0.0, + angle: 0.0, + icon_tileset: String::new(), + icon_index: 0, + sprite_tileset: String::new(), + sprite_index: 0, + particles: Vec::new(), + } + } +} + +impl Hash for Spell { + fn hash(&self, state: &mut H) { + self.unique_id.hash(state); + self.skill.hash(state); + self.cast_slot.hash(state); + } +} + +impl InternalId for Spell { + fn update_internal_id(&mut self) { + if self.unique_id.is_empty() { + warn!( + "Spell '{}' has no unique_id, using name as unique_id.", + self.name + ); + // Replace spaces with underscores, and make it lowercase + self.unique_id = self.name.to_lowercase().replace(' ', "_"); + } + } + + #[must_use] + fn get_internal_id(&self) -> String { + self.unique_id.clone() + } +} + +impl Spell { + /// Create a new spell with the given name and description. + #[must_use] + pub fn new(name: &str, description: &str) -> Self { + Self { + name: name.to_string(), + description: description.to_string(), + ..Default::default() + } + } + + /// Set the unique_id of the spell. + #[must_use] + pub fn with_unique_id(mut self, unique_id: &str) -> Self { + self.unique_id = unique_id.to_string(); + self + } + + /// Set the lore of the spell. + #[must_use] + pub fn with_lore(mut self, lore: &str) -> Self { + self.lore = lore.to_string(); + self + } + + /// Set the talisman of the spell. + #[must_use] + pub fn with_talisman(mut self, talisman: SpellTalisman) -> Self { + self.talisman = talisman; + self + } + + /// Set the skill of the spell. + #[must_use] + pub fn with_skill(mut self, skill: Skill) -> Self { + self.skill = skill; + self + } + + /// Set the cast slot of the spell. + #[must_use] + pub fn with_cast_slot(mut self, cast_slot: CastSlot) -> Self { + self.cast_slot = cast_slot; + self + } + + /// Set the cooldown of the spell. + #[must_use] + pub fn with_cooldown(mut self, cooldown: f32) -> Self { + self.cooldown = cooldown; + self + } + + /// Set the cast time of the spell. + #[must_use] + pub fn with_cast_time(mut self, cast_time: f32) -> Self { + self.cast_time = cast_time; + self + } + + /// Set the mana cost of the spell. + #[must_use] + pub fn with_mana_cost(mut self, mana_cost: f32) -> Self { + self.mana_cost = mana_cost; + self + } + + /// Set the range of the spell. + #[must_use] + pub fn with_range(mut self, range: f32) -> Self { + self.range = range; + self + } + + /// Set the speed of the spell. + #[must_use] + pub fn with_speed(mut self, speed: f32) -> Self { + self.speed = speed; + self + } + + /// Set the acceleration of the spell. + #[must_use] + pub fn with_acceleration(mut self, acceleration: f32) -> Self { + self.acceleration = acceleration; + self + } + + /// Set the duration of the spell. + #[must_use] + pub fn with_duration(mut self, duration: f32) -> Self { + self.duration = duration; + self + } + + /// Set the base damage of the spell. + #[must_use] + pub fn with_base_damage(mut self, base_damage: f32) -> Self { + self.base_damage = base_damage; + self + } + + /// Set the base healing of the spell. + #[must_use] + pub fn with_base_healing(mut self, base_healing: f32) -> Self { + self.base_healing = base_healing; + self + } + + /// Set the buffs of the spell. + #[must_use] + pub fn with_buffs(mut self, buffs: Vec) -> Self { + self.buffs = buffs; + self + } + + /// Set the debuffs of the spell. + #[must_use] + pub fn with_debuffs(mut self, debuffs: Vec) -> Self { + self.debuffs = debuffs; + self + } + + /// Set the radius of the spell. + #[must_use] + pub fn with_radius(mut self, radius: f32) -> Self { + self.radius = radius; + self + } + + /// Set the angle of the spell. + #[must_use] + pub fn with_angle(mut self, angle: f32) -> Self { + self.angle = angle; + self + } + + /// Set the icon tileset and index of the spell. + #[must_use] + pub fn with_icon_tileset_index(mut self, tileset: &str, index: usize) -> Self { + self.icon_tileset = tileset.to_string(); + self.icon_index = index; + self + } + + /// Set the sprite tileset and index of the spell. + #[must_use] + pub fn with_sprite_tileset_index(mut self, tileset: &str, index: usize) -> Self { + self.sprite_tileset = tileset.to_string(); + self.sprite_index = index; + self + } + + /// Set the particles of the spell. + #[must_use] + pub fn with_particles(mut self, particles: Vec) -> Self { + self.particles = particles; + self + } + + /// Get the unique_id of the spell. + #[must_use] + pub fn unique_id(&self) -> &str { + &self.unique_id + } + + /// Get the name of the spell. + #[must_use] + pub fn name(&self) -> &str { + &self.name + } + + /// Get the description of the spell. + #[must_use] + pub fn description(&self) -> &str { + &self.description + } + + /// Get the lore of the spell. + #[must_use] + pub fn lore(&self) -> &str { + &self.lore + } + + /// Get the talisman of the spell. + #[must_use] + pub fn talisman(&self) -> &SpellTalisman { + &self.talisman + } + + /// Get the skill of the spell. + #[must_use] + pub fn skill(&self) -> Skill { + self.skill + } + + /// Get the cast slot of the spell. + #[must_use] + pub fn cast_slot(&self) -> CastSlot { + self.cast_slot + } + + /// Get the cooldown of the spell. + #[must_use] + pub fn cooldown(&self) -> f32 { + self.cooldown + } + + /// Get the cast time of the spell. + #[must_use] + pub fn cast_time(&self) -> f32 { + self.cast_time + } + + /// Get the mana cost of the spell. + #[must_use] + pub fn mana_cost(&self) -> f32 { + self.mana_cost + } + + /// Get the range of the spell. + #[must_use] + pub fn range(&self) -> f32 { + self.range + } + + /// Get the speed of the spell. + #[must_use] + pub fn speed(&self) -> f32 { + self.speed + } + + /// Get the acceleration of the spell. + #[must_use] + pub fn acceleration(&self) -> f32 { + self.acceleration + } + + /// Get the duration of the spell. + #[must_use] + pub fn duration(&self) -> f32 { + self.duration + } + + /// Get the base damage of the spell. + #[must_use] + pub fn base_damage(&self) -> f32 { + self.base_damage + } + + /// Get the base healing of the spell. + #[must_use] + pub fn base_healing(&self) -> f32 { + self.base_healing + } + + /// Get the buffs of the spell. + #[must_use] + pub fn buffs(&self) -> &[StatEffect] { + &self.buffs + } + + /// Get the debuffs of the spell. + #[must_use] + pub fn debuffs(&self) -> &[StatEffect] { + &self.debuffs + } + + /// Get the radius of the spell. + #[must_use] + pub fn radius(&self) -> f32 { + self.radius + } + + /// Get the angle of the spell. + #[must_use] + pub fn angle(&self) -> f32 { + self.angle + } + + /// Get the icon tileset and index of the spell. + #[must_use] + pub fn icon_tileset_index(&self) -> (&str, usize) { + (&self.icon_tileset, self.icon_index) + } + + /// Get the sprite tileset and index of the spell. + #[must_use] + pub fn sprite_tileset_index(&self) -> (&str, usize) { + (&self.sprite_tileset, self.sprite_index) + } + + /// Get the particles of the spell. + #[must_use] + pub fn particles(&self) -> &[SpellParticles] { + &self.particles + } +} + +/// #### DEFAULTS FOR SERDE #### +mod spell_defaults { + use super::SpellTalisman; + use crate::enums::{CastSlot, CastType, Skill}; + + pub(super) const fn skill() -> Skill { + Skill::Arcanomancy + } + pub(super) const fn cast_slot() -> CastSlot { + CastSlot::Primary + } + pub(super) fn talisman() -> SpellTalisman { + SpellTalisman::default() + } + pub(super) const fn cast_type() -> CastType { + CastType::Instant + } + pub(super) const fn mana_cost() -> f32 { + 0.0 + } + pub(super) const fn cooldown() -> f32 { + 1.0 + } + pub(super) const fn cast_time() -> f32 { + 0.0 + } + pub(super) const fn range() -> f32 { + 5.0 + } + pub(super) const fn speed() -> f32 { + 1.0 + } + pub(super) const fn duration() -> f32 { + 5.0 + } + pub(super) const fn acceleration() -> f32 { + 0.0 + } + pub(super) const fn radius() -> f32 { + 0.0 + } + pub(super) const fn angle() -> f32 { + 0.0 + } + pub(super) const fn base_damage() -> f32 { + 0.0 + } + pub(super) const fn base_healing() -> f32 { + 0.0 + } +} + +impl TryInto for DataFile { + type Error = (); + + fn try_into(self) -> Result { + if self.header.system != GameSystem::Spell { + return Err(()); + } + + (&self.data as &dyn Any) + .downcast_ref::() + .cloned() + .ok_or(()) + } +} + +impl TryFrom<&DataFile> for Spell { + type Error = (); + + fn try_from(data_file: &DataFile) -> Result { + if data_file.header.system != GameSystem::Tileset { + return Err(()); + } + + (&data_file.data as &dyn Any) + .downcast_ref::() + .cloned() + .ok_or(()) + } +} diff --git a/game_library/src/spell_lifetime.rs b/game_library/src/spells/lifetime.rs similarity index 76% rename from game_library/src/spell_lifetime.rs rename to game_library/src/spells/lifetime.rs index a667c56..56f5dec 100644 --- a/game_library/src/spell_lifetime.rs +++ b/game_library/src/spells/lifetime.rs @@ -9,9 +9,9 @@ use bevy::prelude::*; #[derive(Debug, Clone, Copy, PartialEq, Component, Default, Reflect)] pub struct SpellLifetime { /// The remaining lifetime of the spell in seconds - pub remaining: f32, + remaining: f32, /// The maximum lifetime of the spell in seconds - pub max: f32, + max: f32, } impl SpellLifetime { @@ -32,4 +32,15 @@ impl SpellLifetime { pub fn is_expired(&self) -> bool { self.remaining <= 0.0 } + + /// Returns the remaining lifetime of the spell + #[must_use] + pub fn remaining(&self) -> f32 { + self.remaining + } + /// Returns the maximum lifetime of the spell + #[must_use] + pub fn max(&self) -> f32 { + self.max + } } diff --git a/game_library/src/spells/mod.rs b/game_library/src/spells/mod.rs new file mode 100644 index 0000000..f96d4da --- /dev/null +++ b/game_library/src/spells/mod.rs @@ -0,0 +1,41 @@ +//! Elementalist spell components, resources, and systems. +//! +//! This module contains the spell components, resources, and systems for the Elementalist game. +//! +//! ## Spell Casting Overview +//! +//! See the [design document](https://github.com/nwesterhausen/elementalist/blob/main/design_notes/game_design_document.md) +//! for a more comprehensive overview of the spell casting system and how it fits into the game. Here is a brief overview: +//! +//! The player has spell slots which can be slotted with a "spell talisman" and assigned a skill to cast the spell. The spell talisman +//! is a talisman to define how the spell behaves (e.g. projectile, area of effect, etc.). The skill is on of the 16 skills the player +//! can have, and the skill determines the element of the spell (e.g. fire, water, etc.). Together, they create the "spell" which +//! can be cast by the player. +//! +//! ## Spell Definitions +//! +//! Only talisman and skill combinations which result in a valid spell are allowed. The spell definitions are defined by the files +//! in the `game_data` directory. Additional spell definitions are supported through loading mods (yet to be implemented). The spell +//! definitions are loaded into the game and used to validate the player's spell slots. +//! +//! Spells are defined in a `YAML` file with this schema: `https://schemas.nwest.one/games/elementalist/spell.json` +//! +//! To have schema validation in your editor, you can add the following to the top of your `YAML` file: +//! +//! ```yaml +//! # yaml-language-server: $schema=https://schemas.nwest.one/games/elementalist/spell.json +//! ``` +//! + +mod bundle; +mod definition; +mod lifetime; +mod particles; +mod selection; +pub mod talisman; + +pub use bundle::SpellBundle; +pub use definition::Spell; +pub use lifetime::SpellLifetime; +pub use particles::SpellParticles; +pub use selection::SpellSelection; diff --git a/game_library/src/spells/particles.rs b/game_library/src/spells/particles.rs new file mode 100644 index 0000000..19196e6 --- /dev/null +++ b/game_library/src/spells/particles.rs @@ -0,0 +1,17 @@ +//! Particle effects for spells. +use bevy::prelude::*; +use serde::{Deserialize, Serialize}; + +use crate::enums::ParticleAttachment; + +/// A particle that a spell can create. +#[derive( + Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Reflect, Component, Resource, +)] +#[serde(rename_all = "camelCase")] +pub struct SpellParticles { + /// The unique_id for the particle effect + pub particle_id: String, + /// The attachment point for the particle effect + pub attachment: ParticleAttachment, +} diff --git a/game_library/src/spells/selection.rs b/game_library/src/spells/selection.rs new file mode 100644 index 0000000..39db91f --- /dev/null +++ b/game_library/src/spells/selection.rs @@ -0,0 +1,131 @@ +//! A resource that stores the player's spell choices. + +use bevy::prelude::*; +use serde::{Deserialize, Serialize}; + +use super::Spell; +use crate::InternalId; + +/// A resource that stores the player's spell choices. +#[derive(Resource, Default, Debug, Reflect, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct SpellSelection { + /// The spell to cast when the player presses the primary cast button. + primary: Option, + /// The spell to cast when the player presses the secondary cast button. + secondary: Option, + /// The spell to cast when the player presses the tertiary cast button. + tertiary: Option, + /// The spell to cast when the player presses the ultimate cast button. + ultimate: Option, +} + +impl SpellSelection { + /// Create a new spell selection with no spells chosen. + #[must_use] + pub fn new() -> Self { + Self { + primary: None, + secondary: None, + tertiary: None, + ultimate: None, + } + } + /// Set the primary spell choice at creation. + #[must_use] + pub fn with_primary(&self, spell: &Spell) -> Self { + Self { + primary: Some(spell.get_internal_id()), + ..self.clone() + } + } + /// Set the primary spell choice at creation using the spell's unique id. + #[must_use] + pub fn with_primary_by_id(&self, unique_id: String) -> Self { + Self { + primary: Some(unique_id), + ..self.clone() + } + } + /// Set the secondary spell choice at creation. + #[must_use] + pub fn with_secondary(&self, spell: &Spell) -> Self { + Self { + secondary: Some(spell.get_internal_id()), + ..self.clone() + } + } + /// Set the secondary spell choice at creation using the spell's unique id. + #[must_use] + pub fn with_secondary_by_id(&self, unique_id: String) -> Self { + Self { + secondary: Some(unique_id), + ..self.clone() + } + } + /// Set the tertiary spell choice at creation. + #[must_use] + pub fn with_tertiary(&self, spell: &Spell) -> Self { + Self { + tertiary: Some(spell.get_internal_id()), + ..self.clone() + } + } + /// Set the tertiary spell choice at creation using the spell's unique id. + #[must_use] + pub fn with_tertiary_by_id(&self, unique_id: String) -> Self { + Self { + tertiary: Some(unique_id), + ..self.clone() + } + } + + /// Set the primary spell choice. + pub fn set_primary(&mut self, spell: &Spell) { + self.primary = Some(spell.get_internal_id()); + } + /// Set the primary spell choice by spell id. + pub fn set_primary_by_id(&mut self, unique_id: String) { + self.primary = Some(unique_id); + } + /// Set the secondary spell choice. + pub fn set_secondary(&mut self, spell: &Spell) { + self.secondary = Some(spell.get_internal_id()); + } + /// Set the secondary spell choice by spell id. + pub fn set_secondary_by_id(&mut self, unique_id: String) { + self.secondary = Some(unique_id); + } + /// Set the tertiary spell choice. + pub fn set_tertiary(&mut self, spell: &Spell) { + self.tertiary = Some(spell.get_internal_id()); + } + /// Set the tertiary spell choice by spell id. + pub fn set_tertiary_by_id(&mut self, unique_id: String) { + self.tertiary = Some(unique_id); + } + /// Set the ultimate spell choice. + pub fn set_ultimate(&mut self, spell: &Spell) { + self.ultimate = Some(spell.get_internal_id()); + } + /// Set the ultimate spell choice by spell id. + pub fn set_ultimate_by_id(&mut self, unique_id: String) { + self.ultimate = Some(unique_id); + } + + /// Clear the primary spell choice. + pub fn clear_primary(&mut self) { + self.primary = None; + } + /// Clear the secondary spell choice. + pub fn clear_secondary(&mut self) { + self.secondary = None; + } + /// Clear the defensive spell choice. + pub fn clear_tertiary(&mut self) { + self.tertiary = None; + } + /// Clear the ultimate spell choice. + pub fn clear_ultimate(&mut self) { + self.ultimate = None; + } +} diff --git a/game_library/src/spells/talisman.rs b/game_library/src/spells/talisman.rs new file mode 100644 index 0000000..0257c37 --- /dev/null +++ b/game_library/src/spells/talisman.rs @@ -0,0 +1,144 @@ +//! The spell talisman is a component that defines how the spell behaves. + +use bevy::prelude::*; +use serde::{Deserialize, Serialize}; + +/// The spell talisman defines how the spell behaves. It contains a shaping, a behavior, and a tier. +#[derive( + Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Reflect, Component, Resource, +)] +pub struct SpellTalisman { + /// The shaping of the spell talisman. This defines the shape of the spell. + shaping: Shaping, + /// The behavior of the spell talisman. This defines the behavior of the spell. + behavior: Behavior, + /// The tier of the spell talisman. This defines the power level of the spell. + tier: Tier, +} + +/// The shaping of the spell talisman. This defines the shape of the spell. +#[derive( + Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Reflect, Component, Resource, +)] +pub enum Shaping { + /// A projectile spell is a spell that launches away from the caster. + Projectile, + /// Area of Effect spells affect a specified area. + AreaOfEffect, + /// A cone spell affects an area in front of the caster in a cone shape. + Cone, + /// A line spell affects an area in front of the caster in a line. + Line, + /// A touch spell affects a target that the caster touches. + Touch, + /// A spell with the `OnSelf` shaping affects the caster. + OnSelf, +} + +/// The behavior of the spell talisman. This defines the behavior of the spell. +#[derive( + Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Reflect, Component, Resource, +)] +pub enum Behavior { + /// A spell with the `Damage` behavior deals damage to the target. + Damage, + /// A spell with the `Heal` behavior heals the target. + Heal, + /// A spell with the `Buff` behavior applies a buff to the target. + Buff, + /// A spell with the `Debuff` behavior applies a debuff to the target. + Debuff, + /// A spell with the `Utility` behavior has a utility effect. + Utility, + /// A spell with the `Summon` behavior summons a creature. + Summon, +} + +/// The tier of the spell talisman. This defines the power level of the spell. +#[derive( + Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Reflect, Component, Resource, +)] +pub enum Tier { + /// A spell with the `Mundane` tier is the lowest tier. + Mundane, + /// A spell with the `Common` tier is the second lowest tier. + Common, + /// A spell with the `Uncommon` tier is the third lowest tier. + Uncommon, + /// A spell with the `Rare` tier is the fourth lowest tier. + Rare, + /// A spell with the `Epic` tier is the fifth lowest tier. + Epic, + /// A spell with the `Legendary` tier is the third highest tier. + Legendary, + /// A spell with the `Mythic` tier is the second highest tier. + Mythic, + /// A spell with the `Divine` tier is the highest tier. + Divine, + /// `Astral` is a special tier that is above Divine. It cannot be inscribed on a spell talisman normally. + Astral, + /// `Unique` should only be used for restricted spells that are unique to a specific character or have other requirements. + /// It cannot be inscribed on a spell talisman normally. + Unique, +} + +impl Default for SpellTalisman { + fn default() -> Self { + Self { + shaping: Shaping::Projectile, + behavior: Behavior::Damage, + tier: Tier::Mundane, + } + } +} + +impl SpellTalisman { + /// Set the shaping of the spell talisman. + #[must_use] + pub fn with_shaping(mut self, shaping: Shaping) -> Self { + self.shaping = shaping; + self + } + + /// Set the behavior of the spell talisman. + #[must_use] + pub fn with_behavior(mut self, behavior: Behavior) -> Self { + self.behavior = behavior; + self + } + + /// Set the tier of the spell talisman. + #[must_use] + pub fn with_tier(mut self, tier: Tier) -> Self { + self.tier = tier; + self + } + + /// Create a new spell talisman with the given shaping, behavior, and tier. + #[must_use] + pub fn new(shaping: Shaping, behavior: Behavior, tier: Tier) -> Self { + Self { + shaping, + behavior, + tier, + } + } + + /// Get the shaping of the spell talisman. + #[must_use] + pub fn shaping(&self) -> Shaping { + self.shaping + } + + /// Get the behavior of the spell talisman. + #[must_use] + pub fn behavior(&self) -> Behavior { + self.behavior + } + + /// Get the tier of the spell talisman. + #[must_use] + pub fn tier(&self) -> Tier { + self.tier + } +} diff --git a/game_library/tests/data_file.rs b/game_library/tests/data_file.rs index 0ca6bdd..2ba6930 100644 --- a/game_library/tests/data_file.rs +++ b/game_library/tests/data_file.rs @@ -1,6 +1,6 @@ use game_library::data_loader::*; use game_library::enums::GameSystem; -use game_library::{SpellData, Tileset}; +use game_library::{spells::Spell, Tileset}; #[test] fn try_into() { @@ -9,10 +9,10 @@ fn try_into() { system: GameSystem::Spell, ..DataFileHeader::default() }, - data: SpellData::default(), + data: Spell::default(), }; - let spell: Result = data_file.try_into(); + let spell: Result = data_file.try_into(); assert!(spell.is_ok()); let data_file = DataFile { @@ -34,7 +34,7 @@ fn try_into_wrong() { system: GameSystem::Spell, ..DataFileHeader::default() }, - data: SpellData::default(), + data: Spell::default(), }; let tileset: Result = data_file.try_into(); diff --git a/game_library/tests/spell_lifetime.rs b/game_library/tests/spell_lifetime.rs index b19c1cd..2163762 100644 --- a/game_library/tests/spell_lifetime.rs +++ b/game_library/tests/spell_lifetime.rs @@ -1,27 +1,27 @@ -use game_library::SpellLifetime; +use game_library::spells::SpellLifetime; #[test] fn spell_lifetime() { let mut spell_lifetime = SpellLifetime::new(10.0); - let almost_eq = (spell_lifetime.max - 10.0).abs() < f32::EPSILON; + let almost_eq = (spell_lifetime.max() - 10.0).abs() < f32::EPSILON; assert!(almost_eq); - let almost_eq = (spell_lifetime.remaining - 10.0).abs() < f32::EPSILON; + let almost_eq = (spell_lifetime.remaining() - 10.0).abs() < f32::EPSILON; assert!(almost_eq); assert!(!spell_lifetime.is_expired()); spell_lifetime.update(2.); - let almost_eq = (spell_lifetime.max - 10.0).abs() < f32::EPSILON; + let almost_eq = (spell_lifetime.max() - 10.0).abs() < f32::EPSILON; assert!(almost_eq); - let almost_eq = (spell_lifetime.remaining - 8.0).abs() < f32::EPSILON; + let almost_eq = (spell_lifetime.remaining() - 8.0).abs() < f32::EPSILON; assert!(almost_eq); assert!(!spell_lifetime.is_expired()); spell_lifetime.update(8.); - let almost_eq = (spell_lifetime.max - 10.0).abs() < f32::EPSILON; + let almost_eq = (spell_lifetime.max() - 10.0).abs() < f32::EPSILON; assert!(almost_eq); - let almost_eq = (spell_lifetime.remaining - 0.0).abs() < f32::EPSILON; + let almost_eq = (spell_lifetime.remaining() - 0.0).abs() < f32::EPSILON; assert!(almost_eq); assert!(spell_lifetime.is_expired()); } diff --git a/game_library/tests/spells.rs b/game_library/tests/spells.rs new file mode 100644 index 0000000..ccaf017 --- /dev/null +++ b/game_library/tests/spells.rs @@ -0,0 +1,48 @@ +use game_library::spells; + +#[test] +fn spell_talisman_default() { + let talisman = spells::talisman::SpellTalisman::default(); + assert_eq!(talisman.shaping(), spells::talisman::Shaping::Projectile); + assert_eq!(talisman.behavior(), spells::talisman::Behavior::Damage); + assert_eq!(talisman.tier(), spells::talisman::Tier::Mundane); +} + +#[test] +fn spell_talisman_with_shaping() { + let talisman = + spells::talisman::SpellTalisman::default().with_shaping(spells::talisman::Shaping::Touch); + assert_eq!(talisman.shaping(), spells::talisman::Shaping::Touch); + assert_eq!(talisman.behavior(), spells::talisman::Behavior::Damage); + assert_eq!(talisman.tier(), spells::talisman::Tier::Mundane); +} + +#[test] +fn spell_talisman_with_behavior() { + let talisman = + spells::talisman::SpellTalisman::default().with_behavior(spells::talisman::Behavior::Heal); + assert_eq!(talisman.shaping(), spells::talisman::Shaping::Projectile); + assert_eq!(talisman.behavior(), spells::talisman::Behavior::Heal); + assert_eq!(talisman.tier(), spells::talisman::Tier::Mundane); +} + +#[test] +fn spell_talisman_with_tier() { + let talisman = + spells::talisman::SpellTalisman::default().with_tier(spells::talisman::Tier::Rare); + assert_eq!(talisman.shaping(), spells::talisman::Shaping::Projectile); + assert_eq!(talisman.behavior(), spells::talisman::Behavior::Damage); + assert_eq!(talisman.tier(), spells::talisman::Tier::Rare); +} + +#[test] +fn spell_talisman_new() { + let talisman = spells::talisman::SpellTalisman::new( + spells::talisman::Shaping::AreaOfEffect, + spells::talisman::Behavior::Debuff, + spells::talisman::Tier::Epic, + ); + assert_eq!(talisman.shaping(), spells::talisman::Shaping::AreaOfEffect); + assert_eq!(talisman.behavior(), spells::talisman::Behavior::Debuff); + assert_eq!(talisman.tier(), spells::talisman::Tier::Epic); +} From ea7b7e73d8794b08c95dd1038358adf875697743 Mon Sep 17 00:00:00 2001 From: Nick Westerhausen <2317381+nwesterhausen@users.noreply.github.com> Date: Sun, 25 Feb 2024 08:42:18 -0500 Subject: [PATCH 02/51] fix: split tileset and index accessors --- game_library/src/spells/definition.rs | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/game_library/src/spells/definition.rs b/game_library/src/spells/definition.rs index e2ef0e9..4547665 100644 --- a/game_library/src/spells/definition.rs +++ b/game_library/src/spells/definition.rs @@ -442,16 +442,28 @@ impl Spell { self.angle } + /// Get the icon tileset id + #[must_use] + pub fn icon_tileset(&self) -> &str { + &self.icon_tileset + } + /// Get the icon tileset and index of the spell. #[must_use] - pub fn icon_tileset_index(&self) -> (&str, usize) { - (&self.icon_tileset, self.icon_index) + pub fn icon_tileset_index(&self) -> usize { + self.icon_index + } + + /// Get the sprite tileset id + #[must_use] + pub fn sprite_tileset(&self) -> &str { + &self.sprite_tileset } /// Get the sprite tileset and index of the spell. #[must_use] - pub fn sprite_tileset_index(&self) -> (&str, usize) { - (&self.sprite_tileset, self.sprite_index) + pub fn sprite_tileset_index(&self) -> usize { + self.sprite_index } /// Get the particles of the spell. From 48fd076b8b9e86d07c25700bfcf2b1c2812dd974 Mon Sep 17 00:00:00 2001 From: Nick Westerhausen <2317381+nwesterhausen@users.noreply.github.com> Date: Sun, 25 Feb 2024 08:42:33 -0500 Subject: [PATCH 03/51] chore: remove unused import --- game_library/src/data_loader/spells.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/game_library/src/data_loader/spells.rs b/game_library/src/data_loader/spells.rs index 10423bb..3f558b5 100644 --- a/game_library/src/data_loader/spells.rs +++ b/game_library/src/data_loader/spells.rs @@ -1,7 +1,5 @@ use bevy::prelude::*; -use crate::InternalId; - use super::{events::LoadedSpellData, storage::GameData}; pub(super) fn load_spells( From 1bf26153b5df33cbed5d1eacb6e70264ca5d3858 Mon Sep 17 00:00:00 2001 From: Nick Westerhausen <2317381+nwesterhausen@users.noreply.github.com> Date: Sun, 25 Feb 2024 08:42:41 -0500 Subject: [PATCH 04/51] feat: add accessors --- game_library/src/spells/selection.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/game_library/src/spells/selection.rs b/game_library/src/spells/selection.rs index 39db91f..6c1fa77 100644 --- a/game_library/src/spells/selection.rs +++ b/game_library/src/spells/selection.rs @@ -128,4 +128,25 @@ impl SpellSelection { pub fn clear_ultimate(&mut self) { self.ultimate = None; } + + /// Get the primary spell choice. + #[must_use] + pub fn primary(&self) -> Option { + self.primary.clone() + } + /// Get the secondary spell choice. + #[must_use] + pub fn secondary(&self) -> Option { + self.secondary.clone() + } + /// Get the tertiary spell choice. + #[must_use] + pub fn tertiary(&self) -> Option { + self.tertiary.clone() + } + /// Get the ultimate spell choice. + #[must_use] + pub fn ultimate(&self) -> Option { + self.ultimate.clone() + } } From ed4cf836d2e944fc7e54feb143cc3270703d1e0f Mon Sep 17 00:00:00 2001 From: Nick Westerhausen <2317381+nwesterhausen@users.noreply.github.com> Date: Sun, 25 Feb 2024 08:43:10 -0500 Subject: [PATCH 05/51] chore: bump library --- Cargo.lock | 2 +- game_library/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 122786b..9d8d733 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2176,7 +2176,7 @@ dependencies = [ [[package]] name = "game_library" -version = "2.0.0" +version = "2.1.0" dependencies = [ "bevy", "bevy-inspector-egui", diff --git a/game_library/Cargo.toml b/game_library/Cargo.toml index 4666fa0..9b8cb96 100644 --- a/game_library/Cargo.toml +++ b/game_library/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "game_library" -version = "2.0.0" +version = "2.1.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html From 1757ac38a3129417f557d1fcaef4260577d9441b Mon Sep 17 00:00:00 2001 From: Nick Westerhausen <2317381+nwesterhausen@users.noreply.github.com> Date: Sun, 25 Feb 2024 08:43:48 -0500 Subject: [PATCH 06/51] fix: update game to use updated library --- Cargo.lock | 2 +- game/Cargo.toml | 2 +- game/src/dev_systems.rs | 13 ++----------- game/src/player/avatar.rs | 5 +++-- game/src/player/player_control.rs | 18 +++++++++--------- game/src/resources/plugin.rs | 5 +++-- game/src/spells/cast_spell.rs | 23 +++++++++++++---------- game/src/spells/components.rs | 2 +- 8 files changed, 33 insertions(+), 37 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9d8d733..89019d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1814,7 +1814,7 @@ checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" [[package]] name = "elementalist" -version = "0.6.0" +version = "0.7.0" dependencies = [ "bevy", "bevy-inspector-egui", diff --git a/game/Cargo.toml b/game/Cargo.toml index 20bc9c4..3c5cd27 100644 --- a/game/Cargo.toml +++ b/game/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elementalist" -version = "0.6.0" +version = "0.7.0" edition = "2021" build = "build.rs" diff --git a/game/src/dev_systems.rs b/game/src/dev_systems.rs index d42f44e..af7b066 100644 --- a/game/src/dev_systems.rs +++ b/game/src/dev_systems.rs @@ -9,8 +9,8 @@ use game_library::Xp; use game_library::{ enums::Skill, font_resource::{FontChoice, FontResource}, - Acceleration, Attribute, CameraScaleLevel, CursorPosition, Health, Mana, MovementBundle, - SpellChoices, Stat, StatBonus, Volume, + Acceleration, Attribute, CameraScaleLevel, CursorPosition, Health, Mana, MovementBundle, Stat, + StatBonus, Volume, }; pub struct DevSystemsPlugin; @@ -28,7 +28,6 @@ impl Plugin for DevSystemsPlugin { .register_type::() .register_type::() .register_type::() - .register_type::() .register_type::() .register_type::() .register_type::() @@ -59,14 +58,6 @@ fn inspector_ui(world: &mut World) { .show(egui_context.get_mut(), |ui| { // The world inspector plugin bevy_inspector_egui::bevy_inspector::ui_for_world(world, ui); - - // Add a collapsable section for the SpellChoices resource. - egui::CollapsingHeader::new("Spell Choices") - .default_open(false) - .show(ui, |ui| { - // The resource inspector plugin - bevy_inspector_egui::bevy_inspector::ui_for_resource::(world, ui); - }); // Add collapsable sections for the settings resources. egui::CollapsingHeader::new("Volume Settings") .default_open(false) diff --git a/game/src/player/avatar.rs b/game/src/player/avatar.rs index b20ea1f..aa1bcba 100644 --- a/game/src/player/avatar.rs +++ b/game/src/player/avatar.rs @@ -5,7 +5,8 @@ use game_library::{ data_loader::storage::GameData, enums::StatEnum, progress_bar::{BarState, ProgressBarConfig}, - Health, Layer, Mana, MovementBundle, SpellChoices, StatBundle, Xp, + spells::SpellSelection, + Health, Layer, Mana, MovementBundle, StatBundle, Xp, }; use super::{ @@ -29,7 +30,7 @@ pub struct PlayerAvatar; /// This will put the avatar as a child of the player entity, which should exist already. pub fn spawn_player_avatar( mut commands: Commands, - mut spell_choices: ResMut, + mut spell_choices: ResMut, game_data: Res, existing_players: Query<&PlayerAvatar>, ) { diff --git a/game/src/player/player_control.rs b/game/src/player/player_control.rs index f6aec37..b40a2f4 100644 --- a/game/src/player/player_control.rs +++ b/game/src/player/player_control.rs @@ -2,8 +2,8 @@ use bevy::prelude::*; use game_library::{ events::CastSpell, settings::GameplaySettings, + spells::SpellSelection, state::{AppState, Overlay}, - SpellChoices, }; use leafwing_input_manager::action_state::ActionState; @@ -32,7 +32,7 @@ impl Plugin for PlayerControlsPlugin { /// System to handle player casting primary spell fn player_cast_primary_spell_system( mut ew_cast_spell: EventWriter, - spell_choices: Res, + spell_choices: Res, query: Query<&ActionState, With>, ) { let Ok(action_state) = query.get_single() else { @@ -42,7 +42,7 @@ fn player_cast_primary_spell_system( if action_state.just_pressed(PlayerAction::CastPrimary) { // Cast a the primary spell - if let Some(spell_id) = spell_choices.primary.clone() { + if let Some(spell_id) = spell_choices.primary() { ew_cast_spell.send(CastSpell(spell_id)); } else { tracing::warn!("No primary spell selected"); @@ -53,7 +53,7 @@ fn player_cast_primary_spell_system( /// System to handle player casting secondary spell fn player_cast_secondary_spell_system( mut ew_cast_spell: EventWriter, - spell_choices: Res, + spell_choices: Res, query: Query<&ActionState, With>, ) { let Ok(action_state) = query.get_single() else { @@ -63,7 +63,7 @@ fn player_cast_secondary_spell_system( if action_state.just_pressed(PlayerAction::CastSecondary) { // Cast a the secondary spell - if let Some(spell_id) = spell_choices.secondary.clone() { + if let Some(spell_id) = spell_choices.secondary() { ew_cast_spell.send(CastSpell(spell_id)); } else { tracing::warn!("No secondary spell selected"); @@ -74,7 +74,7 @@ fn player_cast_secondary_spell_system( /// System to handle player casting defensive spell fn player_cast_defensive_spell_system( mut ew_cast_spell: EventWriter, - spell_choices: Res, + spell_choices: Res, query: Query<&ActionState, With>, ) { let Ok(action_state) = query.get_single() else { @@ -84,7 +84,7 @@ fn player_cast_defensive_spell_system( if action_state.just_pressed(PlayerAction::CastDefensive) { // Cast a the defensive spell - if let Some(spell_id) = spell_choices.defensive.clone() { + if let Some(spell_id) = spell_choices.tertiary() { ew_cast_spell.send(CastSpell(spell_id)); } else { tracing::warn!("No defensive spell selected"); @@ -95,7 +95,7 @@ fn player_cast_defensive_spell_system( /// System to handle player casting ultimate spell fn player_cast_ultimate_spell_system( mut ew_cast_spell: EventWriter, - spell_choices: Res, + spell_choices: Res, query: Query<&ActionState, With>, ) { let Ok(action_state) = query.get_single() else { @@ -105,7 +105,7 @@ fn player_cast_ultimate_spell_system( if action_state.just_pressed(PlayerAction::CastUltimate) { // Cast a the ultimate spell - if let Some(spell_id) = spell_choices.ultimate.clone() { + if let Some(spell_id) = spell_choices.ultimate() { ew_cast_spell.send(CastSpell(spell_id)); } else { tracing::warn!("No ultimate spell selected"); diff --git a/game/src/resources/plugin.rs b/game/src/resources/plugin.rs index 0061262..e58c4b8 100644 --- a/game/src/resources/plugin.rs +++ b/game/src/resources/plugin.rs @@ -6,8 +6,9 @@ use game_library::{ font_resource::{change_font, ChangeFont, FontResource}, progress_bar::ProgressBarPlugin, settings::SettingsPlugin, + spells::SpellSelection, state::{AppState, Game, Save, Settings}, - CursorPosition, Health, Mana, SpellChoices, Xp, + CursorPosition, Health, Mana, Xp, }; use crate::{app_systems, resources::buttons}; @@ -65,7 +66,7 @@ impl Plugin for ElementalistResourcesPlugin { // The cursor position resource, used to aim spells or know cursor coordinates easily .insert_resource(CursorPosition::default()) // The player's spell choices - .insert_resource(SpellChoices::default()) + .insert_resource(SpellSelection::default()) // The font resource has handles to the fonts used in the game to save loading assets constantly // and to easily allow the user to change the font (e.g. for accessibility) .add_event::() diff --git a/game/src/spells/cast_spell.rs b/game/src/spells/cast_spell.rs index bf58ec0..8f0fb73 100644 --- a/game/src/spells/cast_spell.rs +++ b/game/src/spells/cast_spell.rs @@ -3,8 +3,12 @@ use bevy::prelude::*; use bevy_hanabi::{ParticleEffect, ParticleEffectBundle}; use bevy_rapier2d::prelude::*; use game_library::{ - data_loader::storage::GameData, enums::ParticleAttachment, events::CastSpell, math, - Acceleration, CursorPosition, InternalId, Layer, MovementBundle, SpellBundle, SpellLifetime, + data_loader::storage::GameData, + enums::ParticleAttachment, + events::CastSpell, + math, + spells::{SpellBundle, SpellLifetime}, + Acceleration, CursorPosition, InternalId, Layer, MovementBundle, }; use crate::player::Player; @@ -13,7 +17,6 @@ use super::components::SpellEntity; const SPELL_SPRITE_SCALE: f32 = 0.5; const SPELL_SPEED_MULTIPLIER: f32 = 100.0; -const SPELL_ACCELERATION: f32 = 5.0; pub(super) fn cast_spells( mut commands: Commands, @@ -33,10 +36,10 @@ pub(super) fn cast_spells( continue; }; - let Some(texture_atlas) = game_data.tile_atlas.get(&spell.sprite_tileset) else { + let Some(texture_atlas) = game_data.tile_atlas.get(&spell.sprite_tileset()) else { tracing::error!( "cast_spells: No texture atlas found for {} (spell:{})", - spell.sprite_tileset, + spell.sprite_tileset(), spell.get_internal_id() ); continue; @@ -52,17 +55,17 @@ pub(super) fn cast_spells( let spell_projectile = commands .spawn(( SpellBundle { - lifetime: SpellLifetime::new(spell.duration), + lifetime: SpellLifetime::new(spell.duration()), movement: MovementBundle { velocity: Velocity { - linvel: slope_vec * (spell.speed * SPELL_SPEED_MULTIPLIER), + linvel: slope_vec * (spell.speed() * SPELL_SPEED_MULTIPLIER), ..default() }, - acceleration: Acceleration::new(slope_vec * SPELL_ACCELERATION), + acceleration: Acceleration::new(slope_vec * spell.acceleration()), }, sprite: SpriteSheetBundle { texture_atlas: texture_atlas.clone(), - sprite: spell.texture_atlas_index(), + sprite: TextureAtlasSprite::new(spell.sprite_tileset_index()), transform: Transform { translation: player_transform.translation - Vec3::new(0.0, 0.0, 0.1), rotation: Quat::from_rotation_z(slope_vec.y.atan2(slope_vec.x)), @@ -80,7 +83,7 @@ pub(super) fn cast_spells( // check for any particles that go on the projectile let projectile_particles = spell - .particles + .particles() .iter() .filter_map(|particle_link| { if particle_link.attachment == ParticleAttachment::Projectile { diff --git a/game/src/spells/components.rs b/game/src/spells/components.rs index 11e773f..aeb2750 100644 --- a/game/src/spells/components.rs +++ b/game/src/spells/components.rs @@ -1,5 +1,5 @@ use bevy::prelude::*; -use game_library::SpellLifetime; +use game_library::spells::SpellLifetime; /// Despawns spells when their lifetime expires, and updates their lifetime pub fn despawn_expired_spells( From 4e0370c0adc584bd5d68ae3f30e716b990516e5d Mon Sep 17 00:00:00 2001 From: Nick Westerhausen <2317381+nwesterhausen@users.noreply.github.com> Date: Sun, 25 Feb 2024 09:07:50 -0500 Subject: [PATCH 07/51] feat: update schema definitions --- game_data/_schemas/game_system.json | 23 +++- game_data/_schemas/skill.json | 81 ++++++++++++ game_data/_schemas/spell_data.json | 178 ++++++++++++-------------- game_library/src/enums/cast_slot.rs | 23 ++-- game_library/src/spells/definition.rs | 6 +- 5 files changed, 199 insertions(+), 112 deletions(-) create mode 100644 game_data/_schemas/skill.json diff --git a/game_data/_schemas/game_system.json b/game_data/_schemas/game_system.json index 2f9cdb0..0f3eaa1 100644 --- a/game_data/_schemas/game_system.json +++ b/game_data/_schemas/game_system.json @@ -4,5 +4,26 @@ "title": "Elementalist Game System", "description": "A system in the Elementalist game", "type": "string", - "enum": ["Spell", "Tileset", "Particle", "Realm", "SimpleObject"] + "oneOf": [ + { + "const": "Spell", + "title": "A spell that can be learned and cast by a player" + }, + { + "const": "Tileset", + "title": "A spritesheet" + }, + { + "const": "Particle", + "title": "A particle effect that can be used to create a visual effect" + }, + { + "const": "Realm", + "title": "A realm that can be explored by a player" + }, + { + "const": "SimpleObject", + "title": "A simple object that can be placed in a realm" + } + ] } diff --git a/game_data/_schemas/skill.json b/game_data/_schemas/skill.json new file mode 100644 index 0000000..9747c41 --- /dev/null +++ b/game_data/_schemas/skill.json @@ -0,0 +1,81 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.nwest.one/games/elementalist/skill.json", + "title": "Skill in the Elementalist game", + "description": "A skill governs the player's magical abilities for the various schools of magic.", + "type": "string", + "oneOf": [ + { + "title": "Pyromancy is the school of fire magic.", + "const": "Pyromancy" + }, + { + "title": "Fulgomancy is the school of lightning magic.", + "const": "Fulgomancy" + }, + { + "title": "Hydromancy is the school of water magic.", + "const": "Hydromancy" + }, + { + "title": "Geomancy is the school of earth magic.", + "const": "Geomancy" + }, + { + "title": "Aeromancy is the school of air magic.", + "const": "Aeromancy" + }, + { + "title": "Cryomancy is the school of ice magic.", + "const": "Cryomancy" + }, + { + "title": "Trudomancy is the school of force magic.", + "const": "Trudomancy" + }, + { + "title": "Photomancy is the school of light magic.", + "const": "Photomancy" + }, + { + "title": "Umbramancy is the school of dark magic.", + "const": "Umbramancy" + }, + { + "title": "Arcanomancy is the school of arcane magic.", + "const": "Arcanomancy" + }, + { + "title": "Vitomancy is the school of life magic.", + "const": "Vitomancy" + }, + { + "title": "Mortomancy is the school of death magic.", + "const": "Mortomancy" + }, + { + "title": "Ampiliomancy is the school of enhancement magic.", + "const": "Ampiliomancy" + }, + { + "title": "Diminiomancy is the school of reduction magic.", + "const": "Diminiomancy" + }, + { + "title": "Citomancy is the school of summoning magic.", + "const": "Citomancy" + }, + { + "title": "Necromancy is the school of necromancy.", + "const": "Necromancy" + }, + { + "title": "Mutatiomancy is the school of polymorph magic.", + "const": "Mutatiomancy" + }, + { + "title": "Chronomancy is the school of time magic.", + "const": "Chronomancy" + } + ] +} diff --git a/game_data/_schemas/spell_data.json b/game_data/_schemas/spell_data.json index 7554ce3..5740f79 100644 --- a/game_data/_schemas/spell_data.json +++ b/game_data/_schemas/spell_data.json @@ -13,76 +13,81 @@ "description": "A description of the spell", "type": "string" }, - "longDescription": { + "lore": { "description": "A longer, more thematic description of the spell that can be used in-game to add lore and flavor", "type": "string" }, - "manaCost": { - "description": "The cost of the spell", - "type": "integer" + "talisman": { + "description": "The spell talisman which creates this spell", + "ref": "https://schemas.nwest.one/games/elementalist/spell_talisman.json" + }, + "skill": { + "description": "The skill which powers this spell", + "ref": "https://schemas.nwest.one/games/elementalist/skill.json" }, "castSlot": { - "description": "The slot the spell is cast in", + "description": "The slot the spell can fit in", "type": "string", - "enum": ["primary", "secondary", "defensive", "ultimate"] + "oneOf": [ + { + "const": "Cantrip", + "title": "Cantrips are typically basic attacks that don't cost mana and are a player's primary means of dealing damage. They are typically the most spammable spell in a player's arsenal." + }, + { + "const": "Slot", + "title": "Slotted spells are the primary spells a player uses. They are typically more powerful than cantrips and have a variety of effects." + }, + { + "const": "Ultimate", + "title": "Ultimate spells are the most powerful spells a player can cast. They are typically on a long cooldown and have a variety of powerful effects." + } + ] }, - "castTime": { - "description": "The time it takes to cast the spell", - "type": "number", - "inclusiveMinimum": 0 + "castType": { + "description": "The type of cast the spell uses", + "type": "string", + "oneOf": [ + { + "const": "Instant", + "title": "Instant spells are cast immediately." + }, + { + "const": "Channel", + "title": "Channel spells must be maintained to be active." + }, + { + "const": "Cast", + "title": "Cast spells are cast over a period of time and can be interrupted. Only when the cast is complete does the spell take effect." + } + ] }, "cooldown": { "description": "The time it takes to cool down after casting the spell", "type": "number", "inclusiveMinimum": 0 }, - "magic": { - "description": "The family of magic the spell belongs to", - "$ref": "https://schemas.nwest.one/games/elementalist/magic_school.json" + "castTime": { + "description": "The time it takes to cast the spell", + "type": "number", + "inclusiveMinimum": 0 }, - "flags": { - "description": "Flags to specify general behavior", - "type": "array", - "items": { - "type": "string", - "enum": [ - "aoe", - "self", - "target", - "projectile", - "instant", - "homing", - "cone", - "line", - "beam", - "wall", - "ground", - "summon", - "buff", - "debuff", - "heal", - "damage", - "movement", - "touch", - "sustained", - "dot", - "circle", - "square" - ] - } + "manaCost": { + "description": "The cost of the spell", + "type": "number", + "inclusiveMinimum": 0 }, - "spellTier": { - "description": "The tier of the spell, used to indicate how soon it can be unlocked or learned. One of the tier 0 spells will be a free choice when learning a type of magic.", - "type": "integer", - "enum": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + "range": { + "description": "The range of the spell, used to determine how far it can travel", + "type": "number", + "inclusiveMinimum": 0 }, "speed": { "description": "The speed of the spell, used to determine how quickly it travels", "type": "number", "inclusiveMinimum": 0 }, - "range": { - "description": "The range of the spell, used to determine how far it can travel", + "acceleration": { + "description": "The acceleration of the spell, used to determine how quickly it gets up to max speed.", "type": "number", "inclusiveMinimum": 0 }, @@ -91,16 +96,24 @@ "type": "number", "inclusiveMinimum": 0 }, - "damage": { + "baseDamage": { "description": "The damage of the spell, used to determine how much damage it does", "type": "number", "inclusiveMinimum": 0 }, - "healing": { + "baseHealing": { "description": "The healing of the spell, used to determine how much healing it does", "type": "number", "inclusiveMinimum": 0 }, + "buffs": { + "description": "The buffs applied by the spell", + "$ref": "https://schemas.nwest.one/games/elementalist/stat_effect.json" + }, + "debuffs": { + "description": "The debuffs applied by the spell", + "$ref": "https://schemas.nwest.one/games/elementalist/stat_effect.json" + }, "radius": { "description": "The radius of the spell, used to determine how large the area of effect is", "type": "number", @@ -111,30 +124,29 @@ "type": "number", "inclusiveMinimum": 0 }, - "collider": { - "description": "The collider of the spell, used to determine how it interacts with the world", - "$ref": "https://schemas.nwest.one/games/elementalist/collider.json" - }, - "debuffs": { - "description": "The debuffs applied by the spell", - "$ref": "https://schemas.nwest.one/games/elementalist/stat_effect.json" + "iconTileset": { + "description": "The tileset with the icon of the spell (path in the assets folder)", + "type": "string" }, - "buffs": { - "description": "The buffs applied by the spell", - "$ref": "https://schemas.nwest.one/games/elementalist/stat_effect.json" + "iconIndex": { + "description": "The index of the icon in the tileset", + "type": "integer", + "inclusiveMinimum": 0 }, - "castType": { - "description": "The type of cast the spell uses", - "type": "string", - "enum": ["instant", "channeled", "cast"] + "spriteTileset": { + "description": "The sprite of the spell (path in the assets folder)", + "type": "string" }, - "castCategory": { - "description": "The broad category of the spell", - "type": "string", - "enum": ["touch", "projectile", "ground", "summon", "onSelf"] + "spriteIndex": { + "description": "The index of the sprite in the tileset", + "type": "integer", + "inclusiveMinimum": 0 }, "particles": { - "required": ["particleId", "attachment"], + "required": [ + "particleId", + "attachment" + ], "description": "Particles to attach to the spell", "type": "array", "items": { @@ -159,37 +171,15 @@ } } } - }, - "iconTileset": { - "description": "The tileset with the icon of the spell (path in the assets folder)", - "type": "string" - }, - "iconIndex": { - "description": "The index of the icon in the tileset", - "type": "integer", - "inclusiveMinimum": 0 - }, - "spriteTileset": { - "description": "The sprite of the spell (path in the assets folder)", - "type": "string" - }, - "spriteIndex": { - "description": "The index of the sprite in the tileset", - "type": "integer", - "inclusiveMinimum": 0 } }, "required": [ "name", "description", - "manaCost", + "talisman", + "skill", "castSlot", - "castTime", - "cooldown", - "spellTier", - "flags", "castType", - "castCategory", "spriteTileset", "spriteIndex" ] diff --git a/game_library/src/enums/cast_slot.rs b/game_library/src/enums/cast_slot.rs index aaedfe3..f4128a2 100644 --- a/game_library/src/enums/cast_slot.rs +++ b/game_library/src/enums/cast_slot.rs @@ -10,16 +10,12 @@ use serde::{Deserialize, Serialize}; )] #[serde(rename_all = "camelCase")] pub enum CastSlot { - /// Primary spells typically have no mana cost and a short cooldown. Typically used for basic - /// attacks. - Primary, - /// Secondary spells will have a mana cost (usually) and can range from really powerful to - /// other kinds of spells. Typically used for something that is not a basic attack. - Secondary, - /// Defensive spells are typically used to defend against attacks or to heal. The common - /// type of spell used for this slot is a shield or barrier. Other things might generate a - /// wall or other obstacle. - Defensive, + /// Cantrips are typically basic attacks that don't cost mana and are a player's primary means + /// of dealing damage. They are typically the most spammable spell in a player's arsenal. + Cantrip, + /// Slotted spells are the primary spells a player uses. They are typically more powerful than + /// cantrips and have a variety of effects. + Slot, /// Ultimate spells are not in the player's spellbook, instead they are learned organically /// while in the "primal realm." They are typically very powerful and have a long cooldown. Ultimate, @@ -28,10 +24,9 @@ pub enum CastSlot { impl std::fmt::Display for CastSlot { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - Self::Primary => write!(f, "Primary"), - Self::Secondary => write!(f, "Secondary"), - Self::Defensive => write!(f, "Defensive"), - Self::Ultimate => write!(f, "Ultimate"), + CastSlot::Cantrip => write!(f, "Cantrip"), + CastSlot::Slot => write!(f, "Slot"), + CastSlot::Ultimate => write!(f, "Ultimate"), } } } diff --git a/game_library/src/spells/definition.rs b/game_library/src/spells/definition.rs index 4547665..a134855 100644 --- a/game_library/src/spells/definition.rs +++ b/game_library/src/spells/definition.rs @@ -33,7 +33,7 @@ pub struct Spell { /// The skill that the spell uses #[serde(default = "spell_defaults::skill")] skill: Skill, - /// The spell slot that the spell is cast from + /// The slot that the spell can be cast from #[serde(default = "spell_defaults::cast_slot")] cast_slot: CastSlot, /// The type of casting that the spell uses @@ -112,7 +112,7 @@ impl Default for Spell { lore: String::new(), talisman: SpellTalisman::default(), skill: Skill::Arcanomancy, - cast_slot: CastSlot::Primary, + cast_slot: CastSlot::Cantrip, cast_type: CastType::Instant, cooldown: 0.0, cast_time: 0.0, @@ -482,7 +482,7 @@ mod spell_defaults { Skill::Arcanomancy } pub(super) const fn cast_slot() -> CastSlot { - CastSlot::Primary + CastSlot::Cantrip } pub(super) fn talisman() -> SpellTalisman { SpellTalisman::default() From fc1e0ba0b044ed2ba5370403a02ff322e56e554b Mon Sep 17 00:00:00 2001 From: Nick Westerhausen <2317381+nwesterhausen@users.noreply.github.com> Date: Sun, 25 Feb 2024 09:13:20 -0500 Subject: [PATCH 08/51] fix: update aging bolt to new schema --- game_data/spells/aging_bolt.yaml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/game_data/spells/aging_bolt.yaml b/game_data/spells/aging_bolt.yaml index 8a04f83..660f63c 100644 --- a/game_data/spells/aging_bolt.yaml +++ b/game_data/spells/aging_bolt.yaml @@ -2,8 +2,12 @@ data: name: Aging Bolt description: Shoot a bolt of aging magic at a target. + talisman: + shaping: Projectile + behavior: Damage + tier: Mundane manaCost: 1 - castSlot: primary + castSlot: Cantrip castTime: 0 cooldown: 2.50 magic: time @@ -13,7 +17,7 @@ data: - debuff - projectile castCategory: projectile - castType: instant + castType: Instant spriteTileset: spell_projectiles spriteIndex: 11 particles: From ef7b001e0e7c1277032fb569172b2cd88b1aff9e Mon Sep 17 00:00:00 2001 From: Nick Westerhausen <2317381+nwesterhausen@users.noreply.github.com> Date: Sun, 25 Feb 2024 09:22:43 -0500 Subject: [PATCH 09/51] chore: lint with clippy --- game/src/spells/cast_spell.rs | 2 +- game_library/src/data_loader/spells.rs | 2 +- game_library/src/enums/cast_slot.rs | 6 +- game_library/src/spells/bundle.rs | 1 + game_library/src/spells/definition.rs | 78 +++++++++++++------------- game_library/src/spells/lifetime.rs | 5 +- game_library/src/spells/particles.rs | 1 + game_library/src/spells/selection.rs | 3 +- game_library/src/spells/talisman.rs | 15 ++--- 9 files changed, 59 insertions(+), 54 deletions(-) diff --git a/game/src/spells/cast_spell.rs b/game/src/spells/cast_spell.rs index 8f0fb73..af4b114 100644 --- a/game/src/spells/cast_spell.rs +++ b/game/src/spells/cast_spell.rs @@ -36,7 +36,7 @@ pub(super) fn cast_spells( continue; }; - let Some(texture_atlas) = game_data.tile_atlas.get(&spell.sprite_tileset()) else { + let Some(texture_atlas) = game_data.tile_atlas.get(spell.sprite_tileset()) else { tracing::error!( "cast_spells: No texture atlas found for {} (spell:{})", spell.sprite_tileset(), diff --git a/game_library/src/data_loader/spells.rs b/game_library/src/data_loader/spells.rs index 3f558b5..cdb96a9 100644 --- a/game_library/src/data_loader/spells.rs +++ b/game_library/src/data_loader/spells.rs @@ -13,7 +13,7 @@ pub(super) fn load_spells( tracing::info!("Load spells event with {} spells", events.len()); for event in events.read() { let unique_id = &event.spell_data.header.unique_id; - let spell = event.spell_data.data.clone().with_unique_id(&unique_id); + let spell = event.spell_data.data.clone().with_unique_id(unique_id); game_data.spells.insert(unique_id.clone(), spell); tracing::debug!( diff --git a/game_library/src/enums/cast_slot.rs b/game_library/src/enums/cast_slot.rs index f4128a2..10fd049 100644 --- a/game_library/src/enums/cast_slot.rs +++ b/game_library/src/enums/cast_slot.rs @@ -24,9 +24,9 @@ pub enum CastSlot { impl std::fmt::Display for CastSlot { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - CastSlot::Cantrip => write!(f, "Cantrip"), - CastSlot::Slot => write!(f, "Slot"), - CastSlot::Ultimate => write!(f, "Ultimate"), + Self::Cantrip => write!(f, "Cantrip"), + Self::Slot => write!(f, "Slot"), + Self::Ultimate => write!(f, "Ultimate"), } } } diff --git a/game_library/src/spells/bundle.rs b/game_library/src/spells/bundle.rs index c2a8ade..cf85c63 100644 --- a/game_library/src/spells/bundle.rs +++ b/game_library/src/spells/bundle.rs @@ -9,6 +9,7 @@ use bevy::prelude::*; /// /// This has the information to move the spell, display it, and despawn it when it's lifetime expires. #[derive(Bundle)] +#[allow(clippy::module_name_repetitions)] pub struct SpellBundle { /// The movement bundle (velocity and acceleration) /// diff --git a/game_library/src/spells/definition.rs b/game_library/src/spells/definition.rs index a134855..d9cd1d1 100644 --- a/game_library/src/spells/definition.rs +++ b/game_library/src/spells/definition.rs @@ -173,100 +173,100 @@ impl Spell { } } - /// Set the unique_id of the spell. + /// Set the `unique_id` of the spell. #[must_use] pub fn with_unique_id(mut self, unique_id: &str) -> Self { self.unique_id = unique_id.to_string(); self } - /// Set the lore of the spell. + /// Set the `lore` of the spell. #[must_use] pub fn with_lore(mut self, lore: &str) -> Self { self.lore = lore.to_string(); self } - /// Set the talisman of the spell. + /// Set the `talisman` of the spell. #[must_use] - pub fn with_talisman(mut self, talisman: SpellTalisman) -> Self { + pub const fn with_talisman(mut self, talisman: SpellTalisman) -> Self { self.talisman = talisman; self } /// Set the skill of the spell. #[must_use] - pub fn with_skill(mut self, skill: Skill) -> Self { + pub const fn with_skill(mut self, skill: Skill) -> Self { self.skill = skill; self } /// Set the cast slot of the spell. #[must_use] - pub fn with_cast_slot(mut self, cast_slot: CastSlot) -> Self { + pub const fn with_cast_slot(mut self, cast_slot: CastSlot) -> Self { self.cast_slot = cast_slot; self } /// Set the cooldown of the spell. #[must_use] - pub fn with_cooldown(mut self, cooldown: f32) -> Self { + pub const fn with_cooldown(mut self, cooldown: f32) -> Self { self.cooldown = cooldown; self } /// Set the cast time of the spell. #[must_use] - pub fn with_cast_time(mut self, cast_time: f32) -> Self { + pub const fn with_cast_time(mut self, cast_time: f32) -> Self { self.cast_time = cast_time; self } /// Set the mana cost of the spell. #[must_use] - pub fn with_mana_cost(mut self, mana_cost: f32) -> Self { + pub const fn with_mana_cost(mut self, mana_cost: f32) -> Self { self.mana_cost = mana_cost; self } /// Set the range of the spell. #[must_use] - pub fn with_range(mut self, range: f32) -> Self { + pub const fn with_range(mut self, range: f32) -> Self { self.range = range; self } /// Set the speed of the spell. #[must_use] - pub fn with_speed(mut self, speed: f32) -> Self { + pub const fn with_speed(mut self, speed: f32) -> Self { self.speed = speed; self } /// Set the acceleration of the spell. #[must_use] - pub fn with_acceleration(mut self, acceleration: f32) -> Self { + pub const fn with_acceleration(mut self, acceleration: f32) -> Self { self.acceleration = acceleration; self } /// Set the duration of the spell. #[must_use] - pub fn with_duration(mut self, duration: f32) -> Self { + pub const fn with_duration(mut self, duration: f32) -> Self { self.duration = duration; self } /// Set the base damage of the spell. #[must_use] - pub fn with_base_damage(mut self, base_damage: f32) -> Self { + pub const fn with_base_damage(mut self, base_damage: f32) -> Self { self.base_damage = base_damage; self } /// Set the base healing of the spell. #[must_use] - pub fn with_base_healing(mut self, base_healing: f32) -> Self { + pub const fn with_base_healing(mut self, base_healing: f32) -> Self { self.base_healing = base_healing; self } @@ -287,14 +287,14 @@ impl Spell { /// Set the radius of the spell. #[must_use] - pub fn with_radius(mut self, radius: f32) -> Self { + pub const fn with_radius(mut self, radius: f32) -> Self { self.radius = radius; self } /// Set the angle of the spell. #[must_use] - pub fn with_angle(mut self, angle: f32) -> Self { + pub const fn with_angle(mut self, angle: f32) -> Self { self.angle = angle; self } @@ -322,99 +322,99 @@ impl Spell { self } - /// Get the unique_id of the spell. + /// Get the `unique_id` of the spell. #[must_use] pub fn unique_id(&self) -> &str { &self.unique_id } - /// Get the name of the spell. + /// Get the `name` of the spell. #[must_use] pub fn name(&self) -> &str { &self.name } - /// Get the description of the spell. + /// Get the `description` of the spell. #[must_use] pub fn description(&self) -> &str { &self.description } - /// Get the lore of the spell. + /// Get the `lore` of the spell. #[must_use] pub fn lore(&self) -> &str { &self.lore } - /// Get the talisman of the spell. + /// Get the `talisman` of the spell. #[must_use] - pub fn talisman(&self) -> &SpellTalisman { + pub const fn talisman(&self) -> &SpellTalisman { &self.talisman } - /// Get the skill of the spell. + /// Get the `skill` of the spell. #[must_use] - pub fn skill(&self) -> Skill { + pub const fn skill(&self) -> Skill { self.skill } /// Get the cast slot of the spell. #[must_use] - pub fn cast_slot(&self) -> CastSlot { + pub const fn cast_slot(&self) -> CastSlot { self.cast_slot } /// Get the cooldown of the spell. #[must_use] - pub fn cooldown(&self) -> f32 { + pub const fn cooldown(&self) -> f32 { self.cooldown } /// Get the cast time of the spell. #[must_use] - pub fn cast_time(&self) -> f32 { + pub const fn cast_time(&self) -> f32 { self.cast_time } /// Get the mana cost of the spell. #[must_use] - pub fn mana_cost(&self) -> f32 { + pub const fn mana_cost(&self) -> f32 { self.mana_cost } /// Get the range of the spell. #[must_use] - pub fn range(&self) -> f32 { + pub const fn range(&self) -> f32 { self.range } /// Get the speed of the spell. #[must_use] - pub fn speed(&self) -> f32 { + pub const fn speed(&self) -> f32 { self.speed } /// Get the acceleration of the spell. #[must_use] - pub fn acceleration(&self) -> f32 { + pub const fn acceleration(&self) -> f32 { self.acceleration } /// Get the duration of the spell. #[must_use] - pub fn duration(&self) -> f32 { + pub const fn duration(&self) -> f32 { self.duration } /// Get the base damage of the spell. #[must_use] - pub fn base_damage(&self) -> f32 { + pub const fn base_damage(&self) -> f32 { self.base_damage } /// Get the base healing of the spell. #[must_use] - pub fn base_healing(&self) -> f32 { + pub const fn base_healing(&self) -> f32 { self.base_healing } @@ -432,13 +432,13 @@ impl Spell { /// Get the radius of the spell. #[must_use] - pub fn radius(&self) -> f32 { + pub const fn radius(&self) -> f32 { self.radius } /// Get the angle of the spell. #[must_use] - pub fn angle(&self) -> f32 { + pub const fn angle(&self) -> f32 { self.angle } @@ -450,7 +450,7 @@ impl Spell { /// Get the icon tileset and index of the spell. #[must_use] - pub fn icon_tileset_index(&self) -> usize { + pub const fn icon_tileset_index(&self) -> usize { self.icon_index } @@ -462,7 +462,7 @@ impl Spell { /// Get the sprite tileset and index of the spell. #[must_use] - pub fn sprite_tileset_index(&self) -> usize { + pub const fn sprite_tileset_index(&self) -> usize { self.sprite_index } diff --git a/game_library/src/spells/lifetime.rs b/game_library/src/spells/lifetime.rs index 56f5dec..7cb7695 100644 --- a/game_library/src/spells/lifetime.rs +++ b/game_library/src/spells/lifetime.rs @@ -7,6 +7,7 @@ use bevy::prelude::*; /// When a spell is spawned, it is given a lifetime. When the lifetime expires, /// the spell is despawned. #[derive(Debug, Clone, Copy, PartialEq, Component, Default, Reflect)] +#[allow(clippy::module_name_repetitions)] pub struct SpellLifetime { /// The remaining lifetime of the spell in seconds remaining: f32, @@ -35,12 +36,12 @@ impl SpellLifetime { /// Returns the remaining lifetime of the spell #[must_use] - pub fn remaining(&self) -> f32 { + pub const fn remaining(&self) -> f32 { self.remaining } /// Returns the maximum lifetime of the spell #[must_use] - pub fn max(&self) -> f32 { + pub const fn max(&self) -> f32 { self.max } } diff --git a/game_library/src/spells/particles.rs b/game_library/src/spells/particles.rs index 19196e6..2d472cf 100644 --- a/game_library/src/spells/particles.rs +++ b/game_library/src/spells/particles.rs @@ -9,6 +9,7 @@ use crate::enums::ParticleAttachment; Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Reflect, Component, Resource, )] #[serde(rename_all = "camelCase")] +#[allow(clippy::module_name_repetitions)] pub struct SpellParticles { /// The unique_id for the particle effect pub particle_id: String, diff --git a/game_library/src/spells/selection.rs b/game_library/src/spells/selection.rs index 6c1fa77..1fdc516 100644 --- a/game_library/src/spells/selection.rs +++ b/game_library/src/spells/selection.rs @@ -8,6 +8,7 @@ use crate::InternalId; /// A resource that stores the player's spell choices. #[derive(Resource, Default, Debug, Reflect, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[allow(clippy::module_name_repetitions)] pub struct SpellSelection { /// The spell to cast when the player presses the primary cast button. primary: Option, @@ -22,7 +23,7 @@ pub struct SpellSelection { impl SpellSelection { /// Create a new spell selection with no spells chosen. #[must_use] - pub fn new() -> Self { + pub const fn new() -> Self { Self { primary: None, secondary: None, diff --git a/game_library/src/spells/talisman.rs b/game_library/src/spells/talisman.rs index 0257c37..5ddf299 100644 --- a/game_library/src/spells/talisman.rs +++ b/game_library/src/spells/talisman.rs @@ -7,6 +7,7 @@ use serde::{Deserialize, Serialize}; #[derive( Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Reflect, Component, Resource, )] +#[allow(clippy::module_name_repetitions)] pub struct SpellTalisman { /// The shaping of the spell talisman. This defines the shape of the spell. shaping: Shaping, @@ -95,28 +96,28 @@ impl Default for SpellTalisman { impl SpellTalisman { /// Set the shaping of the spell talisman. #[must_use] - pub fn with_shaping(mut self, shaping: Shaping) -> Self { + pub const fn with_shaping(mut self, shaping: Shaping) -> Self { self.shaping = shaping; self } /// Set the behavior of the spell talisman. #[must_use] - pub fn with_behavior(mut self, behavior: Behavior) -> Self { + pub const fn with_behavior(mut self, behavior: Behavior) -> Self { self.behavior = behavior; self } /// Set the tier of the spell talisman. #[must_use] - pub fn with_tier(mut self, tier: Tier) -> Self { + pub const fn with_tier(mut self, tier: Tier) -> Self { self.tier = tier; self } /// Create a new spell talisman with the given shaping, behavior, and tier. #[must_use] - pub fn new(shaping: Shaping, behavior: Behavior, tier: Tier) -> Self { + pub const fn new(shaping: Shaping, behavior: Behavior, tier: Tier) -> Self { Self { shaping, behavior, @@ -126,19 +127,19 @@ impl SpellTalisman { /// Get the shaping of the spell talisman. #[must_use] - pub fn shaping(&self) -> Shaping { + pub const fn shaping(&self) -> Shaping { self.shaping } /// Get the behavior of the spell talisman. #[must_use] - pub fn behavior(&self) -> Behavior { + pub const fn behavior(&self) -> Behavior { self.behavior } /// Get the tier of the spell talisman. #[must_use] - pub fn tier(&self) -> Tier { + pub const fn tier(&self) -> Tier { self.tier } } From b0c5571a9186c9fb276ec6b0fa9ef0d578c4f8cb Mon Sep 17 00:00:00 2001 From: Nick Westerhausen <2317381+nwesterhausen@users.noreply.github.com> Date: Sun, 25 Feb 2024 11:32:08 -0500 Subject: [PATCH 10/51] feat: update to bevy 0.13 --- Cargo.lock | 1272 ++++++++++++---------- game/Cargo.toml | 14 +- game/src/events/menu_interaction.rs | 17 +- game/src/events/player_action.rs | 39 +- game/src/game_overlays/plugin.rs | 2 +- game/src/game_overlays/skill_book.rs | 21 +- game/src/game_overlays/status_screen.rs | 2 +- game/src/main.rs | 18 +- game/src/main_menu/plugin.rs | 2 +- game/src/player/animation.rs | 12 +- game/src/player/avatar.rs | 10 +- game/src/player/menu_control.rs | 8 +- game/src/player/movement.rs | 4 +- game/src/player/player_control.rs | 20 +- game/src/player/plugin.rs | 12 +- game/src/resources/plugin.rs | 8 +- game/src/settings_menu/base.rs | 2 +- game/src/settings_menu/plugin.rs | 2 +- game/src/spells/cast_spell.rs | 7 +- game_library/Cargo.toml | 10 +- game_library/src/data_loader/storage.rs | 11 +- game_library/src/data_loader/tilesets.rs | 20 +- game_library/src/physics/plugin.rs | 2 +- game_library/src/progress_bar/config.rs | 8 +- game_library/src/progress_bar/plugin.rs | 78 +- 25 files changed, 894 insertions(+), 707 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 89019d1..2a314c2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,7 +41,7 @@ checksum = "cd3b6ae1eabbfbced10e840fd3fce8a93ae84f174b3e4ba892ab7bcb42e477a7" dependencies = [ "accesskit", "accesskit_consumer", - "objc2", + "objc2 0.3.0-beta.3.patch-leaks.3", "once_cell", ] @@ -61,25 +61,17 @@ dependencies = [ [[package]] name = "accesskit_winit" -version = "0.15.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88e39fcec2e10971e188730b7a76bab60647dacc973d4591855ebebcadfaa738" +checksum = "45f8f7c9f66d454d5fd8e344c8c8c7324b57194e1041b955519fc58a01e77a25" dependencies = [ "accesskit", "accesskit_macos", "accesskit_windows", + "raw-window-handle 0.6.0", "winit", ] -[[package]] -name = "addr2line" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" -dependencies = [ - "gimli", -] - [[package]] name = "adler" version = "1.0.2" @@ -138,20 +130,23 @@ dependencies = [ [[package]] name = "android-activity" -version = "0.4.3" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64529721f27c2314ced0890ce45e469574a73e5e6fdd6e9da1860eb29285f5e0" +checksum = "ee91c0c2905bae44f84bfa4e044536541df26b7703fd0888deeb9060fcc44289" dependencies = [ "android-properties", - "bitflags 1.3.2", + "bitflags 2.4.2", "cc", + "cesu8", + "jni 0.21.1", "jni-sys", "libc", "log", - "ndk", + "ndk 0.8.0", "ndk-context", - "ndk-sys", - "num_enum 0.6.1", + "ndk-sys 0.5.0+25.2.9519653", + "num_enum 0.7.2", + "thiserror", ] [[package]] @@ -197,7 +192,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aafb29b107435aa276664c1db8954ac27a6e105cdad3c88287a199eb0e313c08" dependencies = [ "clipboard-win", - "core-graphics", + "core-graphics 0.22.3", "image", "log", "objc", @@ -206,7 +201,7 @@ dependencies = [ "parking_lot", "thiserror", "winapi", - "x11rb", + "x11rb 0.12.0", ] [[package]] @@ -221,6 +216,12 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +[[package]] +name = "as-raw-xcb-connection" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" + [[package]] name = "ash" version = "0.37.3+1.3.251" @@ -240,17 +241,6 @@ dependencies = [ "futures-core", ] -[[package]] -name = "async-channel" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" -dependencies = [ - "concurrent-queue", - "event-listener 2.5.3", - "futures-core", -] - [[package]] name = "async-channel" version = "2.2.0" @@ -270,33 +260,23 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17ae5ebefcc48e7452b4987947920dac9450be1110cadf34d1b8c116bdbaf97c" dependencies = [ - "async-lock 3.3.0", + "async-lock", "async-task", "concurrent-queue", - "fastrand 2.0.1", - "futures-lite 2.2.0", + "fastrand", + "futures-lite", "slab", ] [[package]] name = "async-fs" -version = "1.6.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06" +checksum = "bc19683171f287921f2405677dd2ed2549c3b3bda697a563ebc3a121ace2aba1" dependencies = [ - "async-lock 2.8.0", - "autocfg", + "async-lock", "blocking", - "futures-lite 1.13.0", -] - -[[package]] -name = "async-lock" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" -dependencies = [ - "event-listener 2.5.3", + "futures-lite", ] [[package]] @@ -328,27 +308,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" -[[package]] -name = "backtrace" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" -dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - -[[package]] -name = "base64" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" - [[package]] name = "base64" version = "0.21.7" @@ -357,18 +316,18 @@ checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "bevy" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4bc7e09282a82a48d70ade0c4c1154b0fd7882a735a39c66766a5d0f4718ea9" +checksum = "611dd99f412e862610adb43e2243b16436c6d8009f6d9dbe8ce3d6d840b34029" dependencies = [ "bevy_internal", ] [[package]] name = "bevy-inspector-egui" -version = "0.22.1" +version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c3efee9165f9be9c6a180c6a9bbb4bd39ee0a98a594f4cb7127704e15415cdd" +checksum = "9cf0713a3456f6533d274a4ff6a124fc7ec5de89b9dac25c7eca73c9799badcc" dependencies = [ "bevy-inspector-egui-derive", "bevy_app", @@ -386,7 +345,7 @@ dependencies = [ "bevy_time", "bevy_utils", "bevy_window", - "egui 0.24.1", + "egui", "image", "once_cell", "pretty-type-name", @@ -395,9 +354,9 @@ dependencies = [ [[package]] name = "bevy-inspector-egui-derive" -version = "0.22.0" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ec77479f56958ed1b2802c3129ebc704d12245627b2d4dae61f11e6ed5c21b1" +checksum = "b3c488161a04a123e10273e16d4533945943fcfcf345f066242790e8977aee2d" dependencies = [ "proc-macro2", "quote", @@ -406,9 +365,9 @@ dependencies = [ [[package]] name = "bevy_a11y" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68080288c932634f6563d3a8299efe0ddc9ea6787539c4c771ba250d089a94f0" +checksum = "5bf80cd6d0dca4073f9b34b16f1d187a4caa035fd841892519431783bbc9e287" dependencies = [ "accesskit", "bevy_app", @@ -418,9 +377,9 @@ dependencies = [ [[package]] name = "bevy_animation" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aa37683b1281e1ba8cf285644e6e3f0704f14b3901c5ee282067ff7ff6f4a56" +checksum = "aa4ef4c35533df3f0c4e938cf6a831456ea563775bab799336f74331140c7665" dependencies = [ "bevy_app", "bevy_asset", @@ -437,9 +396,9 @@ dependencies = [ [[package]] name = "bevy_app" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d41731817993f92e4363dd3335558e779e290bc71eefc0b5547052b85810907e" +checksum = "8bce3544afc010ffed39c136f6d5a9322d20d38df1394d468ba9106caa0434cb" dependencies = [ "bevy_derive", "bevy_ecs", @@ -453,13 +412,13 @@ dependencies = [ [[package]] name = "bevy_asset" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "935984568f75867dd7357133b06f4b1502cd2be55e4642d483ce597e46e63bff" +checksum = "ac185d8e29c7eb0194f8aae7af3f7234f7ca7a448293be1d3d0d8fef435f65ec" dependencies = [ "async-broadcast", "async-fs", - "async-lock 2.8.0", + "async-lock", "bevy_app", "bevy_asset_macros", "bevy_ecs", @@ -472,7 +431,7 @@ dependencies = [ "crossbeam-channel", "downcast-rs", "futures-io", - "futures-lite 1.13.0", + "futures-lite", "js-sys", "parking_lot", "ron", @@ -485,9 +444,9 @@ dependencies = [ [[package]] name = "bevy_asset_macros" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f48b9bbe4ec605e4910b5cd1e1a0acbfbe0b80af5f3bcc4489a9fdd1e80058c" +checksum = "cb82d1aac8251378c45a8d0ad788d1bf75f54db28c1750f84f1fd7c00127927a" dependencies = [ "bevy_macro_utils", "proc-macro2", @@ -497,9 +456,9 @@ dependencies = [ [[package]] name = "bevy_audio" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18a69889e1bfa4dbac4e641536b94f91c441da55796ad9832e77836b8264688b" +checksum = "f4fe7f952e5e0a343fbde43180db7b8e719ad78594480c91b26876623944a3a1" dependencies = [ "bevy_app", "bevy_asset", @@ -515,9 +474,9 @@ dependencies = [ [[package]] name = "bevy_core" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3daa24502a14839509f02407bc7e48299fe84d260877de23b60662de0f4f4b6c" +checksum = "f7b1b340b8d08f48ecd51b97589d261f5023a7b073d25e300382c49146524103" dependencies = [ "bevy_app", "bevy_ecs", @@ -531,9 +490,9 @@ dependencies = [ [[package]] name = "bevy_core_pipeline" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4b77c4fca6e90edbe2e72da7bc9aa7aed7dfdfded0920ae0a0c845f5e11084a" +checksum = "626a5aaadbdd69eae020c5856575d2d0113423ae1ae1351377e20956d940052c" dependencies = [ "bevy_app", "bevy_asset", @@ -553,9 +512,9 @@ dependencies = [ [[package]] name = "bevy_derive" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f484318350462c58ba3942a45a656c1fd6b6e484a6b6b7abc3a787ad1a51e500" +checksum = "028ae2a34678055185d7f1beebb1ebe6a8dcf3733e139e4ee1383a7f29ae8ba6" dependencies = [ "bevy_macro_utils", "quote", @@ -564,9 +523,9 @@ dependencies = [ [[package]] name = "bevy_diagnostic" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa38ca5967d335cc1006a0e0f1a86c350e2f15fd1878449f61d04cd57a7c4060" +checksum = "01a104acfdc5280accd01a3524810daf3bda72924e3da0c8a9ec816a57eef4e3" dependencies = [ "bevy_app", "bevy_core", @@ -574,23 +533,23 @@ dependencies = [ "bevy_log", "bevy_time", "bevy_utils", + "const-fnv1a-hash", "sysinfo", ] [[package]] name = "bevy_ecs" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7709fbd22f81fb681534cd913c41e1cd18b17143368743281195d7f024b61aea" +checksum = "b85406d5febbbdbcac4444ef61cd9a816f2f025ed692a3fc5439a32153070304" dependencies = [ - "async-channel 1.9.0", + "async-channel", "bevy_ecs_macros", "bevy_ptr", "bevy_reflect", "bevy_tasks", "bevy_utils", "downcast-rs", - "event-listener 2.5.3", "fixedbitset", "rustc-hash", "serde", @@ -600,9 +559,9 @@ dependencies = [ [[package]] name = "bevy_ecs_macros" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8843aa489f159f25cdcd9fee75cd7d221a7098a71eaa72cb2d6b40ac4e3f1ba" +checksum = "9a3ce4b65d7c5f1990e729df75cec2ea6e2241b4a0c37b31c281a04c59c11b7b" dependencies = [ "bevy_macro_utils", "proc-macro2", @@ -612,22 +571,23 @@ dependencies = [ [[package]] name = "bevy_egui" -version = "0.24.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c90c01202dbcebc03315a01ea71553b35e1f20b0da6b1cc8c2605344032a3d96" +checksum = "b84bfb8d4104a1467910cf2090bc6a6d394ebde39c0dbc02397b45aa9ef88e80" dependencies = [ "arboard", "bevy", - "egui 0.24.1", + "egui", "thread_local", + "web-sys", "webbrowser", ] [[package]] name = "bevy_encase_derive" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5328a3715e933ebbff07d0e99528dc423c4f7a53590ed1ac19a120348b028990" +checksum = "6c3d301922e76b16819e17c8cc43b34e92c13ccd06ad19dfa3e52a91a0e13e5c" dependencies = [ "bevy_macro_utils", "encase_derive_impl", @@ -635,9 +595,9 @@ dependencies = [ [[package]] name = "bevy_gilrs" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b81ca2ebf66cbc7f998f1f142b15038ffe3c4ae1d51f70adda26dcf51b0c4ca" +checksum = "96364a1875ee4545fcf825c78dc065ddb9a3b2a509083ef11142f9de0eb8aa17" dependencies = [ "bevy_app", "bevy_ecs", @@ -651,15 +611,17 @@ dependencies = [ [[package]] name = "bevy_gizmos" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db232274ddca2ae452eb2731b98267b795d133ddd14013121bc7daddde1c7491" +checksum = "bdca80b7b4db340eb666d69374a0195b3935759120d0b990fcef8b27d0fb3680" dependencies = [ "bevy_app", "bevy_asset", "bevy_core", "bevy_core_pipeline", "bevy_ecs", + "bevy_gizmos_macros", + "bevy_log", "bevy_math", "bevy_pbr", "bevy_reflect", @@ -669,13 +631,25 @@ dependencies = [ "bevy_utils", ] +[[package]] +name = "bevy_gizmos_macros" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a949eb8b4538a6e4d875321cda2b63dc0fb0317cf18c8245ca5a32f24f6d26d" +dependencies = [ + "bevy_macro_utils", + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "bevy_gltf" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85adc6b1fc86687bf67149e0bafaa4d6da432232fa956472d1b37f19121d3ace" +checksum = "031d0c2a7c0353bb9ac08a5130e58b9a2de3cdaa3c31b5da00b22a9e4732a155" dependencies = [ - "base64 0.13.1", + "base64", "bevy_animation", "bevy_app", "bevy_asset", @@ -701,15 +675,17 @@ dependencies = [ [[package]] name = "bevy_hanabi" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "127702dc9ccba4eb286c54b3307c0ff18d59b35e4de4e361d8e49fee3abe0b59" +checksum = "6f63879a7274ed0d629f7240b0acc4c262aca0276503bdc182552b0f69cba163" dependencies = [ "anyhow", "bevy", "bitflags 2.4.2", "bytemuck", "copyless", + "naga", + "naga_oil", "rand 0.8.5", "rand_pcg", "ron", @@ -720,9 +696,9 @@ dependencies = [ [[package]] name = "bevy_hierarchy" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06bd477152ce2ae1430f5e0a4f19216e5785c22fee1ab23788b5982dc59d1a55" +checksum = "a9f9f843e43d921f07658c24eae74285efc7a335c87998596f3f365155320c69" dependencies = [ "bevy_app", "bevy_core", @@ -730,14 +706,13 @@ dependencies = [ "bevy_log", "bevy_reflect", "bevy_utils", - "smallvec", ] [[package]] name = "bevy_input" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cab9a599189b2a694c182d60cd52219dd9364f9892ff542d87799b8e45d9e6dc" +checksum = "a9cb5b2f3747ffb00cf7e3d6b52f7384476921cd31f0cfd3d1ddff31f83d9252" dependencies = [ "bevy_app", "bevy_ecs", @@ -745,14 +720,15 @@ dependencies = [ "bevy_reflect", "bevy_utils", "serde", + "smol_str", "thiserror", ] [[package]] name = "bevy_internal" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f124bece9831afd80897815231072d51bfe3ac58c6bb58eca8880963b6d0487c" +checksum = "7af89c7083830b1d65fcf0260c3d2537c397fe8ce871471b6e97198a4704f23e" dependencies = [ "bevy_a11y", "bevy_animation", @@ -789,9 +765,9 @@ dependencies = [ [[package]] name = "bevy_log" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc10ba1d225a8477b9e80a1bf797d8a8b8274e83c9b24fb4d9351aec9229755" +checksum = "cfd5bcc3531f8008897fb03cc8751b86d0d29ef94f8fd38b422f9603b7ae80d0" dependencies = [ "android_log-sys", "bevy_app", @@ -805,22 +781,22 @@ dependencies = [ [[package]] name = "bevy_macro_utils" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e566640c6b6dced73d2006c764c2cffebe1a82be4809486c4a5d7b4b50efed4d" +checksum = "ac4401c25b197e7c1455a4875a90b61bba047a9e8d290ce029082c818ab1a21c" dependencies = [ "proc-macro2", "quote", "rustc-hash", "syn 2.0.48", - "toml_edit 0.20.2", + "toml_edit 0.21.1", ] [[package]] name = "bevy_math" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58ddc2b76783939c530178f88e5711a1b01044d7b02db4033e2eb8b43b6cf4ec" +checksum = "6f312b1b8aa6d3965b65040b08e33efac030db3071f20b44f9da9c4c3dfcaf76" dependencies = [ "glam", "serde", @@ -828,18 +804,18 @@ dependencies = [ [[package]] name = "bevy_mikktspace" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ec4962977a746d870170532fc92759e04d3dbcae8b7b82e7ca3bb83b1d75277" +checksum = "3075c01f2b1799945892d5310fc1836e47c045dfe6af5878a304a475931a0c5f" dependencies = [ "glam", ] [[package]] name = "bevy_pbr" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520bfd2a898c74f84ea52cfb8eb061f37373ad15e623489d5f75d27ebd6138fe" +checksum = "c31c72bf12e50ff76c9ed9a7c51ceb88bfea9865d00f24d95b12344fffe1e270" dependencies = [ "bevy_app", "bevy_asset", @@ -855,7 +831,6 @@ dependencies = [ "bitflags 2.4.2", "bytemuck", "fixedbitset", - "naga_oil", "radsort", "smallvec", "thread_local", @@ -864,8 +839,7 @@ dependencies = [ [[package]] name = "bevy_pkv" version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c91c1f9dc84f86cb77ba29677e9fa45975e3de72aeb8e9bf72abd637a7fe6dd6" +source = "git+https://github.com/johanhelsing/bevy_pkv#af0b750b1dbfc8db58dbb2bd07c5eda72e714b79#af0b750b1dbfc8db58dbb2bd07c5eda72e714b79" dependencies = [ "bevy_ecs", "cfg_aliases", @@ -881,15 +855,15 @@ dependencies = [ [[package]] name = "bevy_ptr" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c77ec20c8fafcdc196508ef5ccb4f0400a8d193cb61f7b14a36ed9a25ad423cf" +checksum = "86afa4a88ee06b10fe1e6f28a796ba2eedd16804717cbbb911df0cbb0cd6677b" [[package]] name = "bevy_rapier2d" -version = "0.24.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "457bb7e63adc64000033baf83813c2592a11f9579a0fe574f09f943d88d6815c" +checksum = "dc1f2ef2ae7fcf68ccb33f95c1dfc7c679bbc0e33b7f2e461353073065ff6e1e" dependencies = [ "bevy", "bitflags 2.4.2", @@ -900,28 +874,27 @@ dependencies = [ [[package]] name = "bevy_reflect" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7921f15fc944c9c8ad01d7dbcea6505b8909c6655cd9382bab1407181556038" +checksum = "133dfab8d403d0575eeed9084e85780bbb449dcf75dd687448439117789b40a2" dependencies = [ "bevy_math", "bevy_ptr", "bevy_reflect_derive", "bevy_utils", "downcast-rs", - "erased-serde 0.3.31", + "erased-serde", "glam", "serde", - "smallvec", "smol_str", "thiserror", ] [[package]] name = "bevy_reflect_derive" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4a8c5475f216e751ef4452a1306b00711f33d2d04d9f149e4c845dfeb6753a0" +checksum = "ce1679a4dfdb2c9ff24ca590914c3cec119d7c9e1b56fa637776913acc030386" dependencies = [ "bevy_macro_utils", "proc-macro2", @@ -932,11 +905,11 @@ dependencies = [ [[package]] name = "bevy_render" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdefdd3737125b0d94a6ff20bb70fa8cfe9d7d5dcd72ba4dfe6c5f1d30d9f6e4" +checksum = "d3b194b7029b7541ef9206ac3cb696d3cb37f70bd3260d293fc00d378547e892" dependencies = [ - "async-channel 1.9.0", + "async-channel", "bevy_app", "bevy_asset", "bevy_core", @@ -959,7 +932,7 @@ dependencies = [ "codespan-reporting", "downcast-rs", "encase", - "futures-lite 1.13.0", + "futures-lite", "hexasphere", "image", "js-sys", @@ -968,7 +941,6 @@ dependencies = [ "naga_oil", "ruzstd", "serde", - "smallvec", "thiserror", "thread_local", "wasm-bindgen", @@ -978,9 +950,9 @@ dependencies = [ [[package]] name = "bevy_render_macros" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64d86bfc5a1e7fbeeaec0c4ceab18155530f5506624670965db3415f75826bea" +checksum = "4aa6d99b50375bb7f63be2c3055dfe2f926f7b3c4db108bb0b1181b4f02766aa" dependencies = [ "bevy_macro_utils", "proc-macro2", @@ -990,9 +962,9 @@ dependencies = [ [[package]] name = "bevy_scene" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7df078b5e406e37c8a1c6ba0d652bf105fde713ce3c3efda7263fe27467eee5" +checksum = "2c3c82eaff0b22949183a75a7e2d7fc4ece808235918b34c5b282aab52c3563a" dependencies = [ "bevy_app", "bevy_asset", @@ -1003,7 +975,6 @@ dependencies = [ "bevy_render", "bevy_transform", "bevy_utils", - "ron", "serde", "thiserror", "uuid", @@ -1011,9 +982,9 @@ dependencies = [ [[package]] name = "bevy_sprite" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7cc0c9d946e17e3e0aaa202f182837bc796c4f862b2e5a805134f873f21cf7f" +checksum = "5ea977d7d7c48fc4ba283d449f09528c4e70db17c9048e32e99ecd9890d72223" dependencies = [ "bevy_app", "bevy_asset", @@ -1037,23 +1008,23 @@ dependencies = [ [[package]] name = "bevy_tasks" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4fefa7fe0da8923525f7500e274f1bd60dbd79918a25cf7d0dfa0a6ba15c1cf" +checksum = "b20f243f6fc4c4ba10c2dbff891e947ddae947bb20b263f43e023558b35294bd" dependencies = [ - "async-channel 1.9.0", + "async-channel", "async-executor", "async-task", "concurrent-queue", - "futures-lite 1.13.0", + "futures-lite", "wasm-bindgen-futures", ] [[package]] name = "bevy_text" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a9a79d49ca06170d69149949b134c14e8b99ace1444c1ca2cd4743b19d5b055" +checksum = "006990d27551dbc339774178e833290952511621662fd5ca23a4e6e922ab2d9f" dependencies = [ "ab_glyph", "bevy_app", @@ -1073,9 +1044,9 @@ dependencies = [ [[package]] name = "bevy_time" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6250d76eed3077128b6a3d004f9f198b01107800b9824051e32bb658054e837" +checksum = "9738901b6b251d2c9250542af7002d6f671401fc3b74504682697c5ec822f210" dependencies = [ "bevy_app", "bevy_ecs", @@ -1088,9 +1059,9 @@ dependencies = [ [[package]] name = "bevy_transform" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d541e0c292edbd96afae816ee680e02247422423ccd5dc635c1e211a20ed64be" +checksum = "ba73744a95bc4b8683e91cea3e79b1ad0844c1d677f31fbbc1814c79a5b4f8f0" dependencies = [ "bevy_app", "bevy_ecs", @@ -1103,9 +1074,9 @@ dependencies = [ [[package]] name = "bevy_ui" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d785e3b75dabcb2a8ad0d50933f8f3446d59e512cabc2d2a145e28c2bb8792ba" +checksum = "fafe872906bac6d7fc8ecff166f56b4253465b2895ed88801499aa113548ccc6" dependencies = [ "bevy_a11y", "bevy_app", @@ -1126,34 +1097,34 @@ dependencies = [ "bevy_window", "bytemuck", "serde", - "smallvec", "taffy", "thiserror", ] [[package]] name = "bevy_utils" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7915222f4a08ccc782e08d10b751b42e5f9d786e697d0cb3fd09333cb7e8b6ea" +checksum = "94a06aca1c1863606416b892f4c79e300dbc6211b6690953269051a431c2cca0" dependencies = [ "ahash", "bevy_utils_proc_macros", "getrandom 0.2.12", - "hashbrown 0.14.3", - "instant", + "hashbrown", "nonmax", "petgraph", + "smallvec", "thiserror", "tracing", "uuid", + "web-time", ] [[package]] name = "bevy_utils_proc_macros" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aafecc952b6b8eb1a93c12590bd867d25df2f4ae1033a01dfdfc3c35ebccfff" +checksum = "31ae98e9c0c08b0f5c90e22cd713201f759b98d4fd570b99867a695f8641859a" dependencies = [ "proc-macro2", "quote", @@ -1162,9 +1133,9 @@ dependencies = [ [[package]] name = "bevy_window" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41ee72bf7f974000e9b31bb971a89387f1432ba9413f35c4fef59fef49767260" +checksum = "cb627efd7622a61398ac0d3674f93c997cffe16f13c59fb8ae8a05c9e28de961" dependencies = [ "bevy_a11y", "bevy_app", @@ -1173,15 +1144,16 @@ dependencies = [ "bevy_math", "bevy_reflect", "bevy_utils", - "raw-window-handle", + "raw-window-handle 0.6.0", "serde", + "smol_str", ] [[package]] name = "bevy_winit" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1eb71f287eca9006dda998784c7b931e400ae2cc4c505da315882a8b082f21ad" +checksum = "55105324a201941ae587790f83f6d9caa327e0baa0205558ec41e5ee05a1f703" dependencies = [ "accesskit_winit", "approx", @@ -1196,7 +1168,7 @@ dependencies = [ "bevy_utils", "bevy_window", "crossbeam-channel", - "raw-window-handle", + "raw-window-handle 0.6.0", "wasm-bindgen", "web-sys", "winit", @@ -1283,7 +1255,16 @@ version = "0.1.0-beta.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fa55741ee90902547802152aaf3f8e5248aab7e21468089560d4c8840561146" dependencies = [ - "objc-sys", + "objc-sys 0.2.0-beta.2", +] + +[[package]] +name = "block-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae85a0696e7ea3b835a453750bf002770776609115e6d25c6d2ff28a8200f7e7" +dependencies = [ + "objc-sys 0.3.2", ] [[package]] @@ -1292,8 +1273,18 @@ version = "0.2.0-alpha.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8dd9e63c1744f755c2f60332b88de39d341e5e86239014ad839bd71c106dec42" dependencies = [ - "block-sys", - "objc2-encode", + "block-sys 0.1.0-beta.1", + "objc2-encode 2.0.0-pre.2", +] + +[[package]] +name = "block2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15b55663a85f33501257357e6421bb33e769d5c9ffb5ba0921c975a123e35e68" +dependencies = [ + "block-sys 0.2.1", + "objc2 0.4.1", ] [[package]] @@ -1302,12 +1293,12 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118" dependencies = [ - "async-channel 2.2.0", - "async-lock 3.3.0", + "async-channel", + "async-lock", "async-task", - "fastrand 2.0.1", + "fastrand", "futures-io", - "futures-lite 2.2.0", + "futures-lite", "piper", "tracing", ] @@ -1361,16 +1352,28 @@ checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "calloop" -version = "0.10.6" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52e0d00eb1ea24371a97d2da6201c6747a633dc6dc1988ef503403b4c59504a8" +checksum = "fba7adb4dd5aa98e5553510223000e7148f621165ec5f9acd7113f6ca4995298" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.2", "log", - "nix 0.25.1", - "slotmap", + "polling", + "rustix", + "slab", "thiserror", - "vec_map", +] + +[[package]] +name = "calloop-wayland-source" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f0ea9b9476c7fad82841a8dbb380e2eae480c21910feba80725b46931ed8f02" +dependencies = [ + "calloop", + "rustix", + "wayland-backend", + "wayland-client", ] [[package]] @@ -1449,10 +1452,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" [[package]] -name = "com-rs" -version = "0.2.1" +name = "com" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf43edc576402991846b093a7ca18a3477e0ef9c588cde84964b5d3e43016642" +checksum = "7e17887fd17353b65b1b2ef1c526c83e26cd72e74f598a8dc1bee13a48f3d9f6" +dependencies = [ + "com_macros", +] + +[[package]] +name = "com_macros" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d375883580a668c7481ea6631fc1a8863e33cc335bf56bfad8d7e6d4b04b13a5" +dependencies = [ + "com_macros_support", + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "com_macros_support" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad899a1087a9296d5644792d7cb72b8e34c1bec8e7d4fbc002230169a6e8710c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] [[package]] name = "combine" @@ -1483,6 +1511,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "const-fnv1a-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b13ea120a812beba79e34316b3942a857c86ec1593cb34f27bb28272ce2cca" + [[package]] name = "const_panic" version = "0.2.8" @@ -1545,6 +1579,19 @@ dependencies = [ "libc", ] +[[package]] +name = "core-graphics" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "970a29baf4110c26fedbc7f82107d42c23f7e88e404c4577ed73fe99ff85a212" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-graphics-types", + "foreign-types 0.5.0", + "libc", +] + [[package]] name = "core-graphics-types" version = "0.1.3" @@ -1590,7 +1637,7 @@ dependencies = [ "js-sys", "libc", "mach2", - "ndk", + "ndk 0.7.0", "ndk-context", "oboe", "once_cell", @@ -1672,11 +1719,17 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +[[package]] +name = "cursor-icon" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991" + [[package]] name = "d3d12" -version = "0.7.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e16e44ab292b1dddfdaf7be62cfd8877df52f2f3fde5858d95bab606be259f20" +checksum = "3e3d747f100290a1ca24b752186f61f6637e1deffe3bf6320de6fcb29510a307" dependencies = [ "bitflags 2.4.2", "libloading 0.8.1", @@ -1758,30 +1811,13 @@ dependencies = [ "proc-macro-error", ] -[[package]] -name = "ecolor" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b7637fc2e74d17e52931bac90ff4fc061ac776ada9c7fa272f24cdca5991972" -dependencies = [ - "bytemuck", -] - [[package]] name = "ecolor" version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c912193fa5698d4fbc857b831fb96b42215dcf565e06012993a65901299a21f" - -[[package]] -name = "egui" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c55bcb864b764eb889515a38b8924757657a250738ad15126637ee2df291ee6b" dependencies = [ - "ahash", - "epaint 0.24.1", - "nohash-hasher", + "bytemuck", ] [[package]] @@ -1791,7 +1827,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abecd396ede556116fceaa0098a1c9278ef526119c5097311eac4bcf57484c52" dependencies = [ "ahash", - "epaint 0.26.1", + "epaint", "nohash-hasher", ] @@ -1802,7 +1838,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d14beb118bc4d114bb875f14d1d437736be7010939cedf60c9ee002d7d02d09f" dependencies = [ "duplicate", - "egui 0.26.1", + "egui", "paste", ] @@ -1833,19 +1869,13 @@ dependencies = [ [[package]] name = "emath" -version = "0.24.1" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a045c6c0b44b35e98513fc1e9d183ab42881ac27caccb9fa345465601f56cce4" +checksum = "2386663fafbd043f2cd14f0ded4702deb9348fb7e7bacba9c9087a31b17487f1" dependencies = [ "bytemuck", ] -[[package]] -name = "emath" -version = "0.26.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2386663fafbd043f2cd14f0ded4702deb9348fb7e7bacba9c9087a31b17487f1" - [[package]] name = "embed-resource" version = "2.4.1" @@ -1862,9 +1892,9 @@ dependencies = [ [[package]] name = "encase" -version = "0.6.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fce2eeef77fd4a293a54b62aa00ac9daebfbcda4bf8998c5a815635b004aa1c" +checksum = "95ed933078d2e659745df651f4c180511cd582e5b9414ff896e7d50d207e3103" dependencies = [ "const_panic", "encase_derive", @@ -1874,39 +1904,24 @@ dependencies = [ [[package]] name = "encase_derive" -version = "0.6.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e520cde08cbf4f7cc097f61573ec06ce467019803de8ae82fb2823fa1554a0e" +checksum = "f4ce1449c7d19eba6cc0abd231150ad81620a8dce29601d7f8d236e5d431d72a" dependencies = [ "encase_derive_impl", ] [[package]] name = "encase_derive_impl" -version = "0.6.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fe2568f851fd6144a45fa91cfed8fe5ca8fc0b56ba6797bfc1ed2771b90e37c" +checksum = "92959a9e8d13eaa13b8ae8c7b583c3bf1669ca7a8e7708a088d12587ba86effc" dependencies = [ "proc-macro2", "quote", "syn 2.0.48", ] -[[package]] -name = "epaint" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d1b9e000d21bab9b535ce78f9f7745be28b3f777f6c7223936561c5c7fefab8" -dependencies = [ - "ab_glyph", - "ahash", - "bytemuck", - "ecolor 0.24.1", - "emath 0.24.1", - "nohash-hasher", - "parking_lot", -] - [[package]] name = "epaint" version = "0.26.1" @@ -1915,8 +1930,9 @@ checksum = "36ac8c9ca960f0263856a7fbc90d7ad41280e8865a7cd3c64d3daec016bd7115" dependencies = [ "ab_glyph", "ahash", - "ecolor 0.26.1", - "emath 0.26.1", + "bytemuck", + "ecolor", + "emath", "nohash-hasher", "parking_lot", ] @@ -1929,20 +1945,21 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "erased-serde" -version = "0.3.31" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c138974f9d5e7fe373eb04df7cae98833802ae4b11c24ac7039a21d5af4b26c" +checksum = "55d05712b2d8d88102bc9868020c9e5c7a1f5527c452b9b97450a1d006140ba7" dependencies = [ "serde", ] [[package]] -name = "erased-serde" -version = "0.4.2" +name = "errno" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55d05712b2d8d88102bc9868020c9e5c7a1f5527c452b9b97450a1d006140ba7" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ - "serde", + "libc", + "windows-sys 0.52.0", ] [[package]] @@ -2028,15 +2045,6 @@ dependencies = [ "zune-inflate", ] -[[package]] -name = "fastrand" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", -] - [[package]] name = "fastrand" version = "2.0.1" @@ -2146,28 +2154,13 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" -[[package]] -name = "futures-lite" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" -dependencies = [ - "fastrand 1.9.0", - "futures-core", - "futures-io", - "memchr", - "parking", - "pin-project-lite", - "waker-fn", -] - [[package]] name = "futures-lite" version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "445ba825b27408685aaecefd65178908c36c6e96aaf6d8599419d46e624192ba" dependencies = [ - "fastrand 2.0.1", + "fastrand", "futures-core", "futures-io", "parking", @@ -2202,6 +2195,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "gethostname" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818" +dependencies = [ + "libc", + "windows-targets 0.48.5", +] + [[package]] name = "getrandom" version = "0.1.16" @@ -2270,12 +2273,6 @@ dependencies = [ "windows 0.52.0", ] -[[package]] -name = "gimli" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" - [[package]] name = "git2" version = "0.18.2" @@ -2289,11 +2286,22 @@ dependencies = [ "url", ] +[[package]] +name = "gl_generator" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" +dependencies = [ + "khronos_api", + "log", + "xml-rs", +] + [[package]] name = "glam" -version = "0.24.2" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5418c17512bdf42730f9032c74e1ae39afc408745ebb2acf72fbc4691c17945" +checksum = "151665d9be52f9bb40fc7966565d39666f2d1e69233571b71b87791c7e0528b3" dependencies = [ "bytemuck", "serde", @@ -2307,9 +2315,9 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "glow" -version = "0.12.3" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca0fe580e4b60a8ab24a868bc08e2f03cbcb20d3d676601fa909386713333728" +checksum = "bd348e04c43b32574f2de31c8bb397d96c9fcfa1371bd4ca6d8bdc464ab121b1" dependencies = [ "js-sys", "slotmap", @@ -2353,6 +2361,15 @@ dependencies = [ "serde_json", ] +[[package]] +name = "glutin_wgl_sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8098adac955faa2d31079b65dc48841251f69efd3ac25477903fc424362ead" +dependencies = [ + "gl_generator", +] + [[package]] name = "glyph_brush_layout" version = "0.2.3" @@ -2385,15 +2402,15 @@ dependencies = [ [[package]] name = "gpu-allocator" -version = "0.22.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce95f9e2e11c2c6fadfce42b5af60005db06576f231f5c92550fdded43c423e8" +checksum = "6f56f6318968d03c18e1bcf4857ff88c61157e9da8e47c5f29055d60e1228884" dependencies = [ - "backtrace", "log", + "presser", "thiserror", "winapi", - "windows 0.44.0", + "windows 0.52.0", ] [[package]] @@ -2404,7 +2421,7 @@ checksum = "cc11df1ace8e7e564511f53af41f3e42ddc95b56fd07b3f4445d2a6048bc682c" dependencies = [ "bitflags 2.4.2", "gpu-descriptor-types", - "hashbrown 0.14.3", + "hashbrown", ] [[package]] @@ -2442,12 +2459,6 @@ dependencies = [ "crunchy", ] -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - [[package]] name = "hashbrown" version = "0.14.3" @@ -2461,14 +2472,14 @@ dependencies = [ [[package]] name = "hassle-rs" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1397650ee315e8891a0df210707f0fc61771b0cc518c3023896064c5407cb3b0" +checksum = "af2a7e73e1f34c48da31fb668a907f250794837e08faa144fd24f0b8b741e890" dependencies = [ - "bitflags 1.3.2", - "com-rs", + "bitflags 2.4.2", + "com", "libc", - "libloading 0.7.4", + "libloading 0.8.1", "thiserror", "widestring", "winapi", @@ -2482,9 +2493,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hexasphere" -version = "9.1.0" +version = "10.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cb3df16a7bcb1b5bc092abd55e14f77ca70aea14445026e264586fc62889a10" +checksum = "f33ddb7f7143d9e703c072e88b98cd8b9719f174137a671429351bd2ee43c02a" dependencies = [ "constgebra", "glam", @@ -2505,6 +2516,17 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "icrate" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d3aaff8a54577104bafdf686ff18565c3b6903ca5782a2026ef06e2c7aa319" +dependencies = [ + "block2 0.3.0", + "dispatch", + "objc2 0.4.1", +] + [[package]] name = "idna" version = "0.5.0" @@ -2533,16 +2555,6 @@ dependencies = [ "tiff", ] -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", -] - [[package]] name = "indexmap" version = "2.2.2" @@ -2550,7 +2562,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "824b2ae422412366ba479e8111fd301f7b5faece8149317bb81925979a53f520" dependencies = [ "equivalent", - "hashbrown 0.14.3", + "hashbrown", ] [[package]] @@ -2579,18 +2591,6 @@ dependencies = [ "libc", ] -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - [[package]] name = "inventory" version = "0.3.15" @@ -2701,15 +2701,21 @@ dependencies = [ [[package]] name = "khronos-egl" -version = "4.1.0" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c2352bd1d0bceb871cb9d40f24360c8133c11d7486b68b5381c1dd1a32015e3" +checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76" dependencies = [ "libc", - "libloading 0.7.4", + "libloading 0.8.1", "pkg-config", ] +[[package]] +name = "khronos_api" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" + [[package]] name = "ktx2" version = "0.3.0" @@ -2733,27 +2739,24 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "leafwing-input-manager" -version = "0.11.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e0ad1622a1664b055990aac9efd90a9012b82737847e6a85d36ce38d2bf7c4" +checksum = "def515aa1461ed6ed5d55d53cea6c7149a3076c331cfea1d920682884bfaf839" dependencies = [ "bevy", "derive_more", - "fixedbitset", "itertools", "leafwing_input_manager_macros", - "multimap", - "once_cell", "serde", ] [[package]] name = "leafwing_input_manager_macros" -version = "0.11.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde8ae98d45607e4015d0b772d4a234788ebd7a41f09879f408c7f772b81e5bf" +checksum = "5d065e4f0771d9cc597e76d648da18476ad01fd50cd60ee585ee500f9cd8d696" dependencies = [ - "proc-macro-crate 2.0.2", + "proc-macro-crate 3.1.0", "proc-macro2", "quote", "syn 2.0.48", @@ -2864,6 +2867,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + [[package]] name = "lock_api" version = "0.4.11" @@ -2925,22 +2934,13 @@ checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" [[package]] name = "memmap2" -version = "0.5.10" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" +checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322" dependencies = [ "libc", ] -[[package]] -name = "memoffset" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" -dependencies = [ - "autocfg", -] - [[package]] name = "memoffset" version = "0.7.1" @@ -2952,9 +2952,9 @@ dependencies = [ [[package]] name = "metal" -version = "0.26.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "623b5e6cefd76e58f774bd3cc0c6f5c7615c58c03a97815245a25c3c9bdee318" +checksum = "c43f73953f8cbe511f021b58f18c3ce1c3d1ae13fe953293e13345bf83217f25" dependencies = [ "bitflags 2.4.2", "block", @@ -2981,38 +2981,17 @@ dependencies = [ "simd-adler32", ] -[[package]] -name = "mio" -version = "0.8.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" -dependencies = [ - "libc", - "log", - "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.48.0", -] - -[[package]] -name = "multimap" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1a5d38b9b352dbd913288736af36af41c48d61b1a8cd34bcecd727561b7d511" -dependencies = [ - "serde", -] - [[package]] name = "naga" -version = "0.13.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1ceaaa4eedaece7e4ec08c55c640ba03dbb73fb812a6570a59bcf1930d0f70e" +checksum = "8878eb410fc90853da3908aebfe61d73d26d4437ef850b70050461f939509899" dependencies = [ "bit-set", "bitflags 2.4.2", "codespan-reporting", "hexf-parse", - "indexmap 1.9.3", + "indexmap", "log", "num-traits", "pp-rs", @@ -3025,18 +3004,18 @@ dependencies = [ [[package]] name = "naga_oil" -version = "0.10.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ac54c77b3529887f9668d3dd81e955e58f252b31a333f836e3548c06460b958" +checksum = "c0ea62ae0f2787456afca7209ca180522b41f00cbe159ee369eba1e07d365cd1" dependencies = [ "bit-set", "codespan-reporting", "data-encoding", - "indexmap 1.9.3", + "indexmap", "naga", "once_cell", "regex", - "regex-syntax 0.7.5", + "regex-syntax 0.8.2", "rustc-hash", "thiserror", "tracing", @@ -3045,9 +3024,9 @@ dependencies = [ [[package]] name = "nalgebra" -version = "0.32.3" +version = "0.32.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "307ed9b18cc2423f29e83f84fd23a8e73628727990181f18641a8b5dc2ab1caa" +checksum = "4541eb06dce09c0241ebbaab7102f0a01a0c8994afed2e5d0d66775016e25ac2" dependencies = [ "approx", "glam", @@ -3073,15 +3052,30 @@ dependencies = [ [[package]] name = "ndk" -version = "0.7.0" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "451422b7e4718271c8b5b3aadf5adedba43dc76312454b387e98fae0fc951aa0" +dependencies = [ + "bitflags 1.3.2", + "jni-sys", + "ndk-sys 0.4.1+23.1.7779620", + "num_enum 0.5.11", + "raw-window-handle 0.5.2", + "thiserror", +] + +[[package]] +name = "ndk" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "451422b7e4718271c8b5b3aadf5adedba43dc76312454b387e98fae0fc951aa0" +checksum = "2076a31b7010b17a38c01907c45b945e8f11495ee4dd588309718901b1f7a5b7" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.2", "jni-sys", - "ndk-sys", - "num_enum 0.5.11", - "raw-window-handle", + "log", + "ndk-sys 0.5.0+25.2.9519653", + "num_enum 0.7.2", + "raw-window-handle 0.6.0", "thiserror", ] @@ -3101,28 +3095,23 @@ dependencies = [ ] [[package]] -name = "nix" -version = "0.24.3" +name = "ndk-sys" +version = "0.5.0+25.2.9519653" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" +checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691" dependencies = [ - "bitflags 1.3.2", - "cfg-if", - "libc", - "memoffset 0.6.5", + "jni-sys", ] [[package]] name = "nix" -version = "0.25.1" +version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4" +checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" dependencies = [ - "autocfg", "bitflags 1.3.2", "cfg-if", "libc", - "memoffset 0.6.5", ] [[package]] @@ -3134,7 +3123,7 @@ dependencies = [ "bitflags 1.3.2", "cfg-if", "libc", - "memoffset 0.7.1", + "memoffset", ] [[package]] @@ -3272,11 +3261,11 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.6.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" +checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" dependencies = [ - "num_enum_derive 0.6.1", + "num_enum_derive 0.7.2", ] [[package]] @@ -3293,9 +3282,9 @@ dependencies = [ [[package]] name = "num_enum_derive" -version = "0.6.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" +checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" dependencies = [ "proc-macro-crate 1.3.1", "proc-macro2", @@ -3330,15 +3319,31 @@ version = "0.2.0-beta.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b9834c1e95694a05a828b59f55fa2afec6288359cda67146126b3f90a55d7" +[[package]] +name = "objc-sys" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c71324e4180d0899963fc83d9d241ac39e699609fc1025a850aadac8257459" + [[package]] name = "objc2" version = "0.3.0-beta.3.patch-leaks.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e01640f9f2cb1220bbe80325e179e532cb3379ebcd1bf2279d703c19fe3a468" dependencies = [ - "block2", - "objc-sys", - "objc2-encode", + "block2 0.2.0-alpha.6", + "objc-sys 0.2.0-beta.2", + "objc2-encode 2.0.0-pre.2", +] + +[[package]] +name = "objc2" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "559c5a40fdd30eb5e344fbceacf7595a81e242529fb4e21cf5f43fb4f11ff98d" +dependencies = [ + "objc-sys 0.3.2", + "objc2-encode 3.0.0", ] [[package]] @@ -3347,9 +3352,15 @@ version = "2.0.0-pre.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abfcac41015b00a120608fdaa6938c44cb983fee294351cc4bac7638b4e50512" dependencies = [ - "objc-sys", + "objc-sys 0.2.0-beta.2", ] +[[package]] +name = "objc2-encode" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d079845b37af429bfe5dfa76e6d087d788031045b25cfc6fd898486fd9847666" + [[package]] name = "objc_exception" version = "0.1.2" @@ -3368,15 +3379,6 @@ dependencies = [ "objc", ] -[[package]] -name = "object" -version = "0.32.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" -dependencies = [ - "memchr", -] - [[package]] name = "oboe" version = "0.5.0" @@ -3384,7 +3386,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8868cc237ee02e2d9618539a23a8d228b9bb3fc2e7a5b11eed3831de77c395d0" dependencies = [ "jni 0.20.0", - "ndk", + "ndk 0.7.0", "ndk-context", "num-derive 0.3.3", "num-traits", @@ -3514,7 +3516,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", - "indexmap 2.2.2", + "indexmap", ] [[package]] @@ -3530,7 +3532,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" dependencies = [ "atomic-waker", - "fastrand 2.0.1", + "fastrand", "futures-io", ] @@ -3553,6 +3555,20 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "polling" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24f040dee2588b4963afb4e420540439d126f73fdacf4a9c486a96d840bac3c9" +dependencies = [ + "cfg-if", + "concurrent-queue", + "pin-project-lite", + "rustix", + "tracing", + "windows-sys 0.52.0", +] + [[package]] name = "pp-rs" version = "0.2.1" @@ -3568,6 +3584,12 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "presser" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa" + [[package]] name = "pretty-type-name" version = "1.0.1" @@ -3586,12 +3608,11 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "2.0.2" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" dependencies = [ - "toml_datetime", - "toml_edit 0.20.2", + "toml_edit 0.21.1", ] [[package]] @@ -3642,6 +3663,15 @@ dependencies = [ "bytemuck", ] +[[package]] +name = "quick-xml" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" +dependencies = [ + "memchr", +] + [[package]] name = "quote" version = "1.0.35" @@ -3779,6 +3809,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" +[[package]] +name = "raw-window-handle" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42a9830a0e1b9fb145ebb365b8bc4ccd75f290f98c0247deafbbe2c75cefb544" + [[package]] name = "rawpointer" version = "0.2.1" @@ -3887,12 +3923,6 @@ version = "0.6.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" -[[package]] -name = "regex-syntax" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" - [[package]] name = "regex-syntax" version = "0.8.2" @@ -3949,18 +3979,12 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" dependencies = [ - "base64 0.21.7", + "base64", "bitflags 2.4.2", "serde", "serde_derive", ] -[[package]] -name = "rustc-demangle" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" - [[package]] name = "rustc-hash" version = "1.1.0" @@ -3976,14 +4000,27 @@ dependencies = [ "semver", ] +[[package]] +name = "rustix" +version = "0.38.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +dependencies = [ + "bitflags 2.4.2", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + [[package]] name = "ruzstd" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3ffab8f9715a0d455df4bbb9d21e91135aab3cd3ca187af0cd0c3c3f868fdc" +checksum = "58c4eb8a81997cf040a091d1f7e1938aeab6749d3a0dfa73af43cdc32393483d" dependencies = [ "byteorder", - "thiserror-core", + "derive_more", "twox-hash", ] @@ -4025,9 +4062,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sctk-adwaita" -version = "0.5.4" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda4e97be1fd174ccc2aae81c8b694e803fa99b34e8fd0f057a9d70698e3ed09" +checksum = "82b2eaf3a5b264a521b988b2e73042e742df700c4f962cde845d1541adb46550" dependencies = [ "ab_glyph", "log", @@ -4109,7 +4146,7 @@ version = "0.9.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fd075d994154d4a774f95b51fb96bdc2832b0ea48425c92546073816cda1f2f" dependencies = [ - "indexmap 2.2.2", + "indexmap", "itoa", "ryu", "serde", @@ -4179,21 +4216,27 @@ dependencies = [ [[package]] name = "smithay-client-toolkit" -version = "0.16.1" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "870427e30b8f2cbe64bf43ec4b86e88fe39b0a84b3f15efd9c9c2d020bc86eb9" +checksum = "922fd3eeab3bd820d76537ce8f582b1cf951eceb5475c28500c7457d9d17f53a" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.2", "calloop", - "dlib", - "lazy_static", + "calloop-wayland-source", + "cursor-icon", + "libc", "log", "memmap2", - "nix 0.24.3", - "pkg-config", + "rustix", + "thiserror", + "wayland-backend", "wayland-client", + "wayland-csd-frame", "wayland-cursor", "wayland-protocols", + "wayland-protocols-wlr", + "wayland-scanner", + "xkeysym", ] [[package]] @@ -4211,7 +4254,7 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61addf9117b11d1f5b4bf6fe94242ba25f59d2d4b2080544b771bd647024fd00" dependencies = [ - "hashbrown 0.14.3", + "hashbrown", "num-traits", "robust", "smallvec", @@ -4228,12 +4271,11 @@ dependencies = [ [[package]] name = "spirv" -version = "0.2.0+1.5.4" +version = "0.3.0+sdk-1.3.268.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "246bfa38fe3db3f1dfc8ca5a2cdeb7348c78be2112740cc0ec8ef18b6d94f830" +checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" dependencies = [ - "bitflags 1.3.2", - "num-traits", + "bitflags 2.4.2", ] [[package]] @@ -4284,16 +4326,16 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.29.11" +version = "0.30.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd727fc423c2060f6c92d9534cef765c65a6ed3f428a03d7def74a8c4348e666" +checksum = "1fb4f3438c8f6389c864e61221cbc97e9bca98b4daf39a5beb7bea660f528bb2" dependencies = [ "cfg-if", "core-foundation-sys", "libc", "ntapi", "once_cell", - "winapi", + "windows 0.52.0", ] [[package]] @@ -4326,26 +4368,6 @@ dependencies = [ "thiserror-impl", ] -[[package]] -name = "thiserror-core" -version = "1.0.50" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c001ee18b7e5e3f62cbf58c7fe220119e68d902bb7443179c0c8aef30090e999" -dependencies = [ - "thiserror-core-impl", -] - -[[package]] -name = "thiserror-core-impl" -version = "1.0.50" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c60d69f36615a077cc7663b9cb8e42275722d23e58a7fa3d2c7f2915d09d04" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - [[package]] name = "thiserror-impl" version = "1.0.56" @@ -4380,23 +4402,23 @@ dependencies = [ [[package]] name = "tiny-skia" -version = "0.8.4" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df8493a203431061e901613751931f047d1971337153f96d0e5e363d6dbf6a67" +checksum = "83d13394d44dae3207b52a326c0c85a8bf87f1541f23b0d143811088497b09ab" dependencies = [ "arrayref", "arrayvec", "bytemuck", "cfg-if", - "png", + "log", "tiny-skia-path", ] [[package]] name = "tiny-skia-path" -version = "0.8.4" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adbfb5d3f3dd57a0e11d12f4f13d4ebbbc1b5c15b7ab0a156d030b21da5f677c" +checksum = "9c9e7fc0c2e86a30b117d0462aa261b72b7a99b7ebd7deb3a14ceda95c5bdc93" dependencies = [ "arrayref", "bytemuck", @@ -4432,9 +4454,9 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" dependencies = [ "serde", ] @@ -4445,7 +4467,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.2.2", + "indexmap", "toml_datetime", "winnow", ] @@ -4456,13 +4478,24 @@ version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" dependencies = [ - "indexmap 2.2.2", + "indexmap", "serde", "serde_spanned", "toml_datetime", "winnow", ] +[[package]] +name = "toml_edit" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + [[package]] name = "tracing" version = "0.1.40" @@ -4574,7 +4607,7 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c43148481c7b66502c48f35b8eef38b6ccdc7a9f04bd4cc294226d901ccc9bc7" dependencies = [ - "erased-serde 0.4.2", + "erased-serde", "inventory", "once_cell", "serde", @@ -4613,6 +4646,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-segmentation" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" + [[package]] name = "unicode-width" version = "0.1.11" @@ -4696,12 +4735,6 @@ dependencies = [ "libc", ] -[[package]] -name = "waker-fn" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690" - [[package]] name = "walkdir" version = "2.4.0" @@ -4791,83 +4824,129 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" [[package]] -name = "wayland-client" -version = "0.29.5" +name = "wayland-backend" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f3b068c05a039c9f755f881dc50f01732214f5685e379829759088967c46715" +checksum = "9d50fa61ce90d76474c87f5fc002828d81b32677340112b4ef08079a9d459a40" dependencies = [ - "bitflags 1.3.2", + "cc", "downcast-rs", - "libc", - "nix 0.24.3", + "rustix", "scoped-tls", - "wayland-commons", - "wayland-scanner", + "smallvec", "wayland-sys", ] [[package]] -name = "wayland-commons" -version = "0.29.5" +name = "wayland-client" +version = "0.31.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8691f134d584a33a6606d9d717b95c4fa20065605f798a3f350d78dced02a902" +checksum = "82fb96ee935c2cea6668ccb470fb7771f6215d1691746c2d896b447a00ad3f1f" dependencies = [ - "nix 0.24.3", - "once_cell", - "smallvec", - "wayland-sys", + "bitflags 2.4.2", + "rustix", + "wayland-backend", + "wayland-scanner", +] + +[[package]] +name = "wayland-csd-frame" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" +dependencies = [ + "bitflags 2.4.2", + "cursor-icon", + "wayland-backend", ] [[package]] name = "wayland-cursor" -version = "0.29.5" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6865c6b66f13d6257bef1cd40cbfe8ef2f150fb8ebbdb1e8e873455931377661" +checksum = "71ce5fa868dd13d11a0d04c5e2e65726d0897be8de247c0c5a65886e283231ba" dependencies = [ - "nix 0.24.3", + "rustix", "wayland-client", "xcursor", ] [[package]] name = "wayland-protocols" -version = "0.29.5" +version = "0.31.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b950621f9354b322ee817a23474e479b34be96c2e909c14f7bc0100e9a970bc6" +checksum = "8f81f365b8b4a97f422ac0e8737c438024b5951734506b0e1d775c73030561f4" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.2", + "wayland-backend", + "wayland-client", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-plasma" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23803551115ff9ea9bce586860c5c5a971e360825a0309264102a9495a5ff479" +dependencies = [ + "bitflags 2.4.2", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-wlr" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad1f61b76b6c2d8742e10f9ba5c3737f6530b4c243132c2a2ccc8aa96fe25cd6" +dependencies = [ + "bitflags 2.4.2", + "wayland-backend", "wayland-client", - "wayland-commons", + "wayland-protocols", "wayland-scanner", ] [[package]] name = "wayland-scanner" -version = "0.29.5" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f4303d8fa22ab852f789e75a967f0a2cdc430a607751c0499bada3e451cbd53" +checksum = "63b3a62929287001986fb58c789dce9b67604a397c15c611ad9f747300b6c283" dependencies = [ "proc-macro2", + "quick-xml", "quote", - "xml-rs", ] [[package]] name = "wayland-sys" -version = "0.29.5" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be12ce1a3c39ec7dba25594b97b42cb3195d54953ddb9d3d95a7c3902bc6e9d4" +checksum = "15a0c8eaff5216d07f226cb7a549159267f3467b289d9a2e52fd3ef5aae2b7af" dependencies = [ "dlib", - "lazy_static", + "log", + "once_cell", "pkg-config", ] [[package]] name = "web-sys" -version = "0.3.68" +version = "0.3.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96565907687f7aceb35bc5fc03770a8a0471d82e479f25832f54a0e3f4b28446" +checksum = "aa30049b1c872b72c89866d458eae9f20380ab280ffd1b1e18df2d3e2d98cfe0" dependencies = [ "js-sys", "wasm-bindgen", @@ -4885,7 +4964,7 @@ dependencies = [ "log", "ndk-context", "objc", - "raw-window-handle", + "raw-window-handle 0.5.2", "url", "web-sys", ] @@ -4898,18 +4977,19 @@ checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" [[package]] name = "wgpu" -version = "0.17.2" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "752e44d3998ef35f71830dd1ad3da513e628e2e4d4aedb0ab580f850827a0b41" +checksum = "0bfe9a310dcf2e6b85f00c46059aaeaf4184caa8e29a1ecd4b7a704c3482332d" dependencies = [ "arrayvec", "cfg-if", + "cfg_aliases", "js-sys", "log", "naga", "parking_lot", "profiling", - "raw-window-handle", + "raw-window-handle 0.6.0", "smallvec", "static_assertions", "wasm-bindgen", @@ -4922,19 +5002,22 @@ dependencies = [ [[package]] name = "wgpu-core" -version = "0.17.1" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f8a44dd301a30ceeed3c27d8c0090433d3da04d7b2a4042738095a424d12ae7" +checksum = "6b15e451d4060ada0d99a64df44e4d590213496da7c4f245572d51071e8e30ed" dependencies = [ "arrayvec", "bit-vec", "bitflags 2.4.2", + "cfg_aliases", "codespan-reporting", + "indexmap", "log", "naga", + "once_cell", "parking_lot", "profiling", - "raw-window-handle", + "raw-window-handle 0.6.0", "rustc-hash", "smallvec", "thiserror", @@ -4945,9 +5028,9 @@ dependencies = [ [[package]] name = "wgpu-hal" -version = "0.17.2" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a80bf0e3c77399bb52850cb0830af9bad073d5cfcb9dd8253bef8125c42db17" +checksum = "e3bb47856236bfafc0bc591a925eb036ac19cd987624a447ff353e7a7e7e6f72" dependencies = [ "android_system_properties", "arrayvec", @@ -4955,9 +5038,11 @@ dependencies = [ "bit-set", "bitflags 2.4.2", "block", + "cfg_aliases", "core-graphics-types", "d3d12", "glow", + "glutin_wgl_sys", "gpu-alloc", "gpu-allocator", "gpu-descriptor", @@ -4970,10 +5055,11 @@ dependencies = [ "metal", "naga", "objc", + "once_cell", "parking_lot", "profiling", "range-alloc", - "raw-window-handle", + "raw-window-handle 0.6.0", "renderdoc-sys", "rustc-hash", "smallvec", @@ -4986,9 +5072,9 @@ dependencies = [ [[package]] name = "wgpu-types" -version = "0.17.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee64d7398d0c2f9ca48922c902ef69c42d000c759f3db41e355f4a570b052b67" +checksum = "895fcbeb772bfb049eb80b2d6e47f6c9af235284e9703c96fc0218a42ffd5af2" dependencies = [ "bitflags 2.4.2", "js-sys", @@ -5051,15 +5137,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows" -version = "0.44.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e745dab35a0c4c77aa3ce42d595e13d2003d6902d6b08c9ef5fc326d08da12b" -dependencies = [ - "windows-targets 0.42.2", -] - [[package]] name = "windows" version = "0.46.0" @@ -5321,37 +5398,50 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "winit" -version = "0.28.7" +version = "0.29.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9596d90b45384f5281384ab204224876e8e8bf7d58366d9b795ad99aa9894b94" +checksum = "4c824f11941eeae66ec71111cc2674373c772f482b58939bb4066b642aa2ffcf" dependencies = [ + "ahash", "android-activity", - "bitflags 1.3.2", + "atomic-waker", + "bitflags 2.4.2", + "bytemuck", + "calloop", "cfg_aliases", "core-foundation", - "core-graphics", - "dispatch", - "instant", + "core-graphics 0.23.1", + "cursor-icon", + "icrate", + "js-sys", "libc", "log", - "mio", - "ndk", - "objc2", + "memmap2", + "ndk 0.8.0", + "ndk-sys 0.5.0+25.2.9519653", + "objc2 0.4.1", "once_cell", "orbclient", "percent-encoding", - "raw-window-handle", + "raw-window-handle 0.6.0", "redox_syscall 0.3.5", + "rustix", "sctk-adwaita", "smithay-client-toolkit", + "smol_str", + "unicode-segmentation", "wasm-bindgen", + "wasm-bindgen-futures", + "wayland-backend", "wayland-client", - "wayland-commons", "wayland-protocols", - "wayland-scanner", + "wayland-protocols-plasma", "web-sys", - "windows-sys 0.45.0", + "web-time", + "windows-sys 0.48.0", "x11-dl", + "x11rb 0.13.0", + "xkbcommon-dl", ] [[package]] @@ -5390,11 +5480,26 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1641b26d4dec61337c35a1b1aaf9e3cba8f46f0b43636c609ab0291a648040a" dependencies = [ - "gethostname", + "gethostname 0.3.0", "nix 0.26.4", "winapi", "winapi-wsapoll", - "x11rb-protocol", + "x11rb-protocol 0.12.0", +] + +[[package]] +name = "x11rb" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8f25ead8c7e4cba123243a6367da5d3990e0d3affa708ea19dce96356bd9f1a" +dependencies = [ + "as-raw-xcb-connection", + "gethostname 0.4.3", + "libc", + "libloading 0.8.1", + "once_cell", + "rustix", + "x11rb-protocol 0.13.0", ] [[package]] @@ -5406,6 +5511,12 @@ dependencies = [ "nix 0.26.4", ] +[[package]] +name = "x11rb-protocol" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e63e71c4b8bd9ffec2c963173a4dc4cbde9ee96961d4fcb4429db9929b606c34" + [[package]] name = "xcursor" version = "0.3.5" @@ -5418,6 +5529,25 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a67300977d3dc3f8034dae89778f502b6ba20b269527b3223ba59c0cf393bb8a" +[[package]] +name = "xkbcommon-dl" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" +dependencies = [ + "bitflags 2.4.2", + "dlib", + "log", + "once_cell", + "xkeysym", +] + +[[package]] +name = "xkeysym" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "054a8e68b76250b253f671d1268cb7f1ae089ec35e195b2efb2a4e9a836d0621" + [[package]] name = "xml-rs" version = "0.8.19" diff --git a/game/Cargo.toml b/game/Cargo.toml index 3c5cd27..92855fb 100644 --- a/game/Cargo.toml +++ b/game/Cargo.toml @@ -18,15 +18,15 @@ embed-resource = "2.4.1" [dependencies] # When running the game in development, use the dynamic linking feature of Bevy to speed # up compilation times. `cargo run --features bevy/dynamic_linking` will enable this. -bevy = "0.12.1" +bevy = "0.13.0" # Input abstraction layer, makes for easy input handling and rebinding. -leafwing-input-manager = "0.11.2" +leafwing-input-manager = "0.13.3" # Used for logging. This might be able to be replaced with a re-pub from bevy. tracing = "0.1.40" # The game library contains a lot of resources, logic and compoents used in the game. game_library = { path = "../game_library" } # For setting the icon on Windows, we use this, which must match the version in bevy. -winit = "0.28" +winit = "0.29.10" # Used to load our icon for the window. image = "0.24" # Random noise generation library @@ -34,11 +34,13 @@ rand = "0.8.5" # DEBUG ONLY: docking support for the inspector egui egui_dock = "0.11.2" # DEBUG ONLY: inspector for bevy -bevy-inspector-egui = "0.22.1" +bevy-inspector-egui = "0.23.2" # Particle system -bevy_hanabi = { version = "0.9.0", default-features = false, features = ["2d"] } +bevy_hanabi = { version = "0.10.0", default-features = false, features = [ + "2d", +] } # Physics engine -bevy_rapier2d = { version = "0.24.0", features = ["parallel"] } +bevy_rapier2d = { version = "0.25.0", features = ["parallel"] } # Some very strict lints. [lints.rust] diff --git a/game/src/events/menu_interaction.rs b/game/src/events/menu_interaction.rs index 7b4f0ee..2f4f46c 100644 --- a/game/src/events/menu_interaction.rs +++ b/game/src/events/menu_interaction.rs @@ -34,10 +34,10 @@ impl MenuInteraction { /// Returns the default keybinds for this action on keyboard & mouse. pub const fn default_keyboard_mouse_input(self) -> UserInput { match self { - Self::Up => UserInput::Single(InputKind::Keyboard(KeyCode::W)), - Self::Down => UserInput::Single(InputKind::Keyboard(KeyCode::S)), - Self::Select => UserInput::Single(InputKind::Keyboard(KeyCode::Space)), - Self::Back => UserInput::Single(InputKind::Keyboard(KeyCode::Escape)), + Self::Up => UserInput::Single(InputKind::PhysicalKey(KeyCode::KeyW)), + Self::Down => UserInput::Single(InputKind::PhysicalKey(KeyCode::KeyS)), + Self::Select => UserInput::Single(InputKind::PhysicalKey(KeyCode::Space)), + Self::Back => UserInput::Single(InputKind::PhysicalKey(KeyCode::Escape)), } } /// Returns the default gamepad input for this action. @@ -49,14 +49,19 @@ impl MenuInteraction { Self::Back => UserInput::Single(InputKind::GamepadButton(GamepadButtonType::South)), } } + /// Returns the variants of this enum. + #[must_use] + pub const fn variants() -> [Self; 4] { + [Self::Up, Self::Down, Self::Select, Self::Back] + } /// Returns the default input mapping for this action. pub fn default_input_map() -> InputMap { let mut input_map = InputMap::default(); for variant in Self::variants() { - input_map.insert(variant.default_keyboard_mouse_input(), variant); - input_map.insert(variant.default_gamepad_input(), variant); + input_map.insert(variant, variant.default_keyboard_mouse_input()); + input_map.insert(variant, variant.default_gamepad_input()); } input_map diff --git a/game/src/events/player_action.rs b/game/src/events/player_action.rs index 52c4011..2cccf31 100644 --- a/game/src/events/player_action.rs +++ b/game/src/events/player_action.rs @@ -35,23 +35,23 @@ pub enum PlayerAction { impl PlayerAction { /// Returns the default keybinds for this action on keyboard & mouse. - pub fn default_keyboard_mouse_input(self) -> UserInput { + pub const fn default_keyboard_mouse_input(self) -> UserInput { match self { Self::Move => UserInput::VirtualDPad(VirtualDPad::wasd()), Self::Look => UserInput::VirtualDPad(VirtualDPad::arrow_keys()), Self::CastPrimary => UserInput::Single(InputKind::Mouse(MouseButton::Left)), Self::CastSecondary => UserInput::Single(InputKind::Mouse(MouseButton::Right)), - Self::CastDefensive => UserInput::Single(InputKind::Keyboard(KeyCode::Space)), - Self::CastUltimate => UserInput::Single(InputKind::Keyboard(KeyCode::E)), - Self::ToggleAutoCast => UserInput::Single(InputKind::Keyboard(KeyCode::Q)), - Self::ToggleAutoAim => UserInput::Single(InputKind::Keyboard(KeyCode::T)), - Self::Interact => UserInput::Single(InputKind::Keyboard(KeyCode::F)), - Self::Pause => UserInput::Single(InputKind::Keyboard(KeyCode::Escape)), - Self::StatusOverlay => UserInput::Single(InputKind::Keyboard(KeyCode::Tab)), + Self::CastDefensive => UserInput::Single(InputKind::PhysicalKey(KeyCode::Space)), + Self::CastUltimate => UserInput::Single(InputKind::PhysicalKey(KeyCode::KeyE)), + Self::ToggleAutoCast => UserInput::Single(InputKind::PhysicalKey(KeyCode::KeyQ)), + Self::ToggleAutoAim => UserInput::Single(InputKind::PhysicalKey(KeyCode::KeyT)), + Self::Interact => UserInput::Single(InputKind::PhysicalKey(KeyCode::KeyF)), + Self::Pause => UserInput::Single(InputKind::PhysicalKey(KeyCode::Escape)), + Self::StatusOverlay => UserInput::Single(InputKind::PhysicalKey(KeyCode::Tab)), } } /// Returns the default gamepad input for this action. - pub fn default_gamepad_input(self) -> UserInput { + pub const fn default_gamepad_input(self) -> UserInput { match self { Self::Move => UserInput::Single(InputKind::DualAxis(DualAxis::left_stick())), Self::Look => UserInput::Single(InputKind::DualAxis(DualAxis::right_stick())), @@ -80,14 +80,31 @@ impl PlayerAction { } } } + /// Returns the variants of this enum. + #[must_use] + pub const fn variants() -> [Self; 11] { + [ + Self::Move, + Self::Look, + Self::CastPrimary, + Self::CastSecondary, + Self::CastDefensive, + Self::CastUltimate, + Self::ToggleAutoCast, + Self::ToggleAutoAim, + Self::Interact, + Self::Pause, + Self::StatusOverlay, + ] + } /// Returns the default input map for this action. pub fn default_input_map() -> InputMap { let mut input_map = InputMap::default(); for variant in Self::variants() { - input_map.insert(variant.default_keyboard_mouse_input(), variant); - input_map.insert(variant.default_gamepad_input(), variant); + input_map.insert(variant, variant.default_keyboard_mouse_input()); + input_map.insert(variant, variant.default_gamepad_input()); } input_map diff --git a/game/src/game_overlays/plugin.rs b/game/src/game_overlays/plugin.rs index 9a2674c..a21ab83 100644 --- a/game/src/game_overlays/plugin.rs +++ b/game/src/game_overlays/plugin.rs @@ -9,7 +9,7 @@ pub struct GameOverlaysPlugin; impl Plugin for GameOverlaysPlugin { fn build(&self, app: &mut App) { - app.add_state::() + app.init_state::() .add_plugins((StatusScreenPlugin, SkillBookUiPlugin)); } } diff --git a/game/src/game_overlays/skill_book.rs b/game/src/game_overlays/skill_book.rs index ffcc888..b378301 100644 --- a/game/src/game_overlays/skill_book.rs +++ b/game/src/game_overlays/skill_book.rs @@ -1,7 +1,10 @@ //! The skill book UI overlay. use bevy::prelude::*; use game_library::{ - colors, data_loader::storage::GameData, enums::Skill, font_resource::FontResource, + colors, + data_loader::storage::{GameData, StoredTextureAtlas}, + enums::Skill, + font_resource::FontResource, state::Overlay, }; @@ -16,8 +19,11 @@ impl Plugin for SkillBookUiPlugin { } /// system to change system to skill screen when pressing 'k' -fn toggle_skill_screen(mut next_overlay: ResMut>, input: Res>) { - if input.just_pressed(KeyCode::K) { +fn toggle_skill_screen( + mut next_overlay: ResMut>, + input: Res>, +) { + if input.just_pressed(KeyCode::KeyK) { next_overlay.set(Overlay::SkillScreen); } } @@ -76,7 +82,7 @@ const RIGHT_COLUMN_SKILLS: [Skill; 9] = [ fn add_skill_to_ui( font: Handle, - icon_tileset: Handle, + icon_tileset: StoredTextureAtlas, skill: Skill, commands: &mut Commands, ) -> Entity { @@ -130,9 +136,12 @@ fn add_skill_to_ui( .id(); let skill_icon = commands .spawn(AtlasImageBundle { - texture_atlas: icon_tileset, - texture_atlas_image: UiTextureAtlasImage { + texture_atlas: TextureAtlas { + layout: icon_tileset.atlas_handle.clone(), index: skill.icon_index(), + }, + image: UiImage { + texture: icon_tileset.texture_handle, ..default() }, ..default() diff --git a/game/src/game_overlays/status_screen.rs b/game/src/game_overlays/status_screen.rs index 0a007ce..9eedba4 100644 --- a/game/src/game_overlays/status_screen.rs +++ b/game/src/game_overlays/status_screen.rs @@ -87,7 +87,7 @@ fn toggle_status_screen( query: Query<&ActionState, With>, ) { if let Ok(action_state) = query.get_single() { - if action_state.just_pressed(PlayerAction::StatusOverlay) { + if action_state.just_pressed(&PlayerAction::StatusOverlay) { if *state == Overlay::Status { next_state.set(Overlay::None); } else { diff --git a/game/src/main.rs b/game/src/main.rs index ed9d5d1..b3d7e8c 100644 --- a/game/src/main.rs +++ b/game/src/main.rs @@ -82,10 +82,12 @@ fn main() { .set(LogPlugin { level: log_level, filter: log_filter.to_string(), + update_subscriber: None, }) // Add our the wgpu settings per bevy_hanabi .set(RenderPlugin { render_creation: wgpu_settings.into(), + ..default() }), ) // Add the gameplay plugins @@ -200,7 +202,7 @@ fn spawn_random_environment( }; let Some(ground) = game_data.tile_atlas.get(rnd_ground.0) else { - tracing::error!("Failed to load ground tileselt: {}", rnd_ground.0); + tracing::error!("Failed to load ground tileset: {}", rnd_ground.0); continue; }; let ground_id = rnd_ground.1; @@ -208,8 +210,11 @@ fn spawn_random_environment( let ground_transform = Transform::from_translation(ground_translation); commands.spawn(( SpriteSheetBundle { - texture_atlas: ground.clone(), - sprite: bevy::sprite::TextureAtlasSprite::new(ground_id), + atlas: TextureAtlas { + layout: ground.atlas_handle.clone(), + index: ground_id, + }, + texture: ground.texture_handle.clone(), transform: ground_transform, ..Default::default() }, @@ -258,8 +263,11 @@ fn spawn_random_environment( commands.spawn(( SpriteSheetBundle { - texture_atlas: tileset.clone(), - sprite: bevy::sprite::TextureAtlasSprite::new(tile_index), + atlas: TextureAtlas { + layout: tileset.atlas_handle.clone(), + index: tile_index, + }, + texture: tileset.texture_handle.clone(), transform: obj_transform, ..Default::default() }, diff --git a/game/src/main_menu/plugin.rs b/game/src/main_menu/plugin.rs index fb95384..d55b7f5 100644 --- a/game/src/main_menu/plugin.rs +++ b/game/src/main_menu/plugin.rs @@ -40,7 +40,7 @@ impl Plugin for MainMenuPlugin { fn build(&self, app: &mut App) { app // Add a resource to track which menu state we are in - .add_state::() + .init_state::() // Transition to the main menu when entering the main menu state (starts tracking our MenuState at Main) .add_systems(OnEnter(AppState::MainMenu), transition_to_main_menu) // Add system to update the buttons on hover, etc diff --git a/game/src/player/animation.rs b/game/src/player/animation.rs index e7585c3..79a2904 100644 --- a/game/src/player/animation.rs +++ b/game/src/player/animation.rs @@ -103,7 +103,7 @@ pub(super) fn advance_animation_timer( /// Tracks a local "frame" that goes from 0 to 3, and updates the sprite index based on the current /// state. We advance the frame every 0.1 seconds. pub fn update_avatar_animation( - mut sprite_query: Query<&mut TextureAtlasSprite, With>, + mut sprite_query: Query<(&mut TextureAtlas, &mut Sprite), With>, state: Res>, supplemental_state: Res>, facing: Res>, @@ -111,7 +111,7 @@ pub fn update_avatar_animation( frame: Res, ) { // should be just one player avatar & sprite - let Ok(mut sprite) = sprite_query.get_single_mut() else { + let Ok((mut atlas, mut sprite)) = sprite_query.get_single_mut() else { tracing::error!("update_avatar_animation: failed to get player sprite"); return; }; @@ -121,16 +121,16 @@ pub fn update_avatar_animation( match (state.get(), supplemental_state.get()) { (PlayerAnimation::Walking, PlayerAnimationSupplemental::None) => { - sprite.index = WALKING_ANIMATION[frame.get(WALKING_ANIMATION.len())]; + atlas.index = WALKING_ANIMATION[frame.get(WALKING_ANIMATION.len())]; } (PlayerAnimation::Walking, PlayerAnimationSupplemental::Casting) => { - sprite.index = CASTING_WALKING_ANIMATION[frame.get(CASTING_WALKING_ANIMATION.len())]; + atlas.index = CASTING_WALKING_ANIMATION[frame.get(CASTING_WALKING_ANIMATION.len())]; } (PlayerAnimation::Idle, PlayerAnimationSupplemental::None) => { - sprite.index = IDLE_ANIMATION[frame.get(IDLE_ANIMATION.len())]; + atlas.index = IDLE_ANIMATION[frame.get(IDLE_ANIMATION.len())]; } (PlayerAnimation::Idle, PlayerAnimationSupplemental::Casting) => { - sprite.index = CASTING_IDLE_ANIMATION[frame.get(CASTING_IDLE_ANIMATION.len())]; + atlas.index = CASTING_IDLE_ANIMATION[frame.get(CASTING_IDLE_ANIMATION.len())]; } } diff --git a/game/src/player/avatar.rs b/game/src/player/avatar.rs index aa1bcba..ac17ddb 100644 --- a/game/src/player/avatar.rs +++ b/game/src/player/avatar.rs @@ -14,6 +14,8 @@ use super::{ Player, }; +const INITIAL_SPRITE_INDEX: usize = 3; + /// `PlayerAvatar` is a marker component for the player's avatar, i.e. the entity that the player /// controls. This is used to ensure that only one player avatar is spawned at a time. It also /// lets us allow a player controller to continue to control the menu and other things without @@ -59,11 +61,11 @@ pub fn spawn_player_avatar( PlayerBundle { movement: MovementBundle::default(), sprite: SpriteSheetBundle { - texture_atlas: tileset.clone(), - sprite: TextureAtlasSprite { - index: 3, - ..default() + atlas: TextureAtlas { + layout: tileset.atlas_handle.clone(), + index: INITIAL_SPRITE_INDEX, }, + texture: tileset.texture_handle.clone(), transform: Transform { translation: Vec3::new(0.0, 0.0, 150.0), scale: Vec3::splat(0.85), diff --git a/game/src/player/menu_control.rs b/game/src/player/menu_control.rs index 2d8ec6e..78c02be 100644 --- a/game/src/player/menu_control.rs +++ b/game/src/player/menu_control.rs @@ -12,16 +12,16 @@ pub fn menu_input( mut next_overlay_state: ResMut>, ) { let action_state = query.single(); - if action_state.just_pressed(MenuInteraction::Up) { + if action_state.just_pressed(&MenuInteraction::Up) { tracing::debug!("Up (in Menu)"); } - if action_state.just_pressed(MenuInteraction::Down) { + if action_state.just_pressed(&MenuInteraction::Down) { tracing::debug!("Down (in Menu)"); } - if action_state.just_pressed(MenuInteraction::Select) { + if action_state.just_pressed(&MenuInteraction::Select) { tracing::debug!("Select (in Menu)"); } - if action_state.just_pressed(MenuInteraction::Back) { + if action_state.just_pressed(&MenuInteraction::Back) { if *menu_state == Settings::Main { next_overlay_state.set(Overlay::None); next_menu_state.set(Settings::Disabled); diff --git a/game/src/player/movement.rs b/game/src/player/movement.rs index 02bc1c8..28ee1b0 100644 --- a/game/src/player/movement.rs +++ b/game/src/player/movement.rs @@ -39,9 +39,9 @@ pub fn player_movement_controls( return; }; - if action_state.pressed(PlayerAction::Move) { + if action_state.pressed(&PlayerAction::Move) { sprite_state_next.set(PlayerAnimation::Walking); - if let Some(axis_pair) = action_state.clamped_axis_pair(PlayerAction::Move) { + if let Some(axis_pair) = action_state.clamped_axis_pair(&PlayerAction::Move) { controller.translation = Some(axis_pair.xy().normalize_or_zero() * (speed.value())); if axis_pair.x() < 0.0 { diff --git a/game/src/player/player_control.rs b/game/src/player/player_control.rs index b40a2f4..b13c582 100644 --- a/game/src/player/player_control.rs +++ b/game/src/player/player_control.rs @@ -40,7 +40,7 @@ fn player_cast_primary_spell_system( return; }; - if action_state.just_pressed(PlayerAction::CastPrimary) { + if action_state.just_pressed(&PlayerAction::CastPrimary) { // Cast a the primary spell if let Some(spell_id) = spell_choices.primary() { ew_cast_spell.send(CastSpell(spell_id)); @@ -61,7 +61,7 @@ fn player_cast_secondary_spell_system( return; }; - if action_state.just_pressed(PlayerAction::CastSecondary) { + if action_state.just_pressed(&PlayerAction::CastSecondary) { // Cast a the secondary spell if let Some(spell_id) = spell_choices.secondary() { ew_cast_spell.send(CastSpell(spell_id)); @@ -82,7 +82,7 @@ fn player_cast_defensive_spell_system( return; }; - if action_state.just_pressed(PlayerAction::CastDefensive) { + if action_state.just_pressed(&PlayerAction::CastDefensive) { // Cast a the defensive spell if let Some(spell_id) = spell_choices.tertiary() { ew_cast_spell.send(CastSpell(spell_id)); @@ -103,7 +103,7 @@ fn player_cast_ultimate_spell_system( return; }; - if action_state.just_pressed(PlayerAction::CastUltimate) { + if action_state.just_pressed(&PlayerAction::CastUltimate) { // Cast a the ultimate spell if let Some(spell_id) = spell_choices.ultimate() { ew_cast_spell.send(CastSpell(spell_id)); @@ -120,14 +120,14 @@ fn player_control_system(query: Query<&ActionState, With>) return; }; - if action_state.pressed(PlayerAction::Look) { - if let Some(axis_pair) = action_state.clamped_axis_pair(PlayerAction::Look) { + if action_state.pressed(&PlayerAction::Look) { + if let Some(axis_pair) = action_state.clamped_axis_pair(&PlayerAction::Look) { println!("Look: {axis_pair:?}"); } else { println!("Look"); } } - if action_state.just_pressed(PlayerAction::Interact) { + if action_state.just_pressed(&PlayerAction::Interact) { println!("Interact"); } } @@ -142,10 +142,10 @@ fn player_toggle_auto_system( return; }; - if action_state.just_pressed(PlayerAction::ToggleAutoCast) { + if action_state.just_pressed(&PlayerAction::ToggleAutoCast) { gameplay_settings.auto_cast = !gameplay_settings.auto_cast; } - if action_state.just_pressed(PlayerAction::ToggleAutoAim) { + if action_state.just_pressed(&PlayerAction::ToggleAutoAim) { gameplay_settings.auto_aim = !gameplay_settings.auto_aim; } } @@ -165,7 +165,7 @@ fn player_press_pause_system( return; }; - if action_state.just_pressed(PlayerAction::Pause) { + if action_state.just_pressed(&PlayerAction::Pause) { // Pause the game (automatically happens when in [`Overlay::Settings`]) and open the settings menu next_overlay_state.set(Overlay::Settings); } diff --git a/game/src/player/plugin.rs b/game/src/player/plugin.rs index 1ac68ee..7cdde10 100644 --- a/game/src/player/plugin.rs +++ b/game/src/player/plugin.rs @@ -37,9 +37,9 @@ impl Plugin for PlayerPlugin { // Remove player when leaving game .add_systems(OnExit(Game::Playing), despawn_with_tag::) // Animation stuff - .add_state::() - .add_state::() - .add_state::() + .init_state::() + .init_state::() + .init_state::() .init_resource::() .insert_resource(animation::PlayerAnimationTimer(Timer::from_seconds( 0.1, @@ -73,14 +73,14 @@ fn camera_movement( fn subtract_health( mut player_health: Query<&mut Health, With>, mut player_xp: Query<&mut Xp, With>, - keyboard_input: Res>, + keyboard_input: Res>, ) { - if keyboard_input.just_pressed(KeyCode::H) { + if keyboard_input.just_pressed(KeyCode::KeyH) { for mut health in &mut player_health { health.value -= 1; } } - if keyboard_input.just_pressed(KeyCode::X) { + if keyboard_input.just_pressed(KeyCode::KeyX) { for mut xp in &mut player_xp { xp.add(1); } diff --git a/game/src/resources/plugin.rs b/game/src/resources/plugin.rs index e58c4b8..caf2200 100644 --- a/game/src/resources/plugin.rs +++ b/game/src/resources/plugin.rs @@ -37,10 +37,10 @@ pub struct ElementalistResourcesPlugin; impl Plugin for ElementalistResourcesPlugin { fn build(&self, app: &mut App) { // The app states - app.add_state::() - .add_state::() - .add_state::() - .add_state::(); + app.init_state::() + .init_state::() + .init_state::() + .init_state::(); // Data loading plugin app.add_plugins(DataLoaderPlugin); diff --git a/game/src/settings_menu/base.rs b/game/src/settings_menu/base.rs index 3019e03..a2905a1 100644 --- a/game/src/settings_menu/base.rs +++ b/game/src/settings_menu/base.rs @@ -36,7 +36,7 @@ pub(super) fn clear_background( commands.spawn(( MaterialMesh2dBundle { mesh: meshes - .add(shape::Quad::new(Vec2::new(window.width(), window.height())).into()) + .add(Rectangle::new(window.width(), window.height())) .into(), material: materials.add(ColorMaterial::from(BACKGROUND_COLOR_50)), transform: Transform::from_xyz(0., 0., 10.), diff --git a/game/src/settings_menu/plugin.rs b/game/src/settings_menu/plugin.rs index 2806ef1..962158c 100644 --- a/game/src/settings_menu/plugin.rs +++ b/game/src/settings_menu/plugin.rs @@ -23,7 +23,7 @@ pub struct SettingsMenuPlugin; impl Plugin for SettingsMenuPlugin { fn build(&self, app: &mut App) { - app.add_state::(); + app.init_state::(); app.add_event::(); // Add system to setup the menu app.add_systems( diff --git a/game/src/spells/cast_spell.rs b/game/src/spells/cast_spell.rs index af4b114..3ceda4a 100644 --- a/game/src/spells/cast_spell.rs +++ b/game/src/spells/cast_spell.rs @@ -64,8 +64,11 @@ pub(super) fn cast_spells( acceleration: Acceleration::new(slope_vec * spell.acceleration()), }, sprite: SpriteSheetBundle { - texture_atlas: texture_atlas.clone(), - sprite: TextureAtlasSprite::new(spell.sprite_tileset_index()), + atlas: TextureAtlas { + layout: texture_atlas.atlas_handle.clone(), + index: spell.sprite_tileset_index(), + }, + texture: texture_atlas.texture_handle.clone(), transform: Transform { translation: player_transform.translation - Vec3::new(0.0, 0.0, 0.1), rotation: Quat::from_rotation_z(slope_vec.y.atan2(slope_vec.x)), diff --git a/game_library/Cargo.toml b/game_library/Cargo.toml index 9b8cb96..44489f5 100644 --- a/game_library/Cargo.toml +++ b/game_library/Cargo.toml @@ -6,18 +6,18 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -bevy = "0.12.1" -bevy-inspector-egui = "0.22.1" -bevy_hanabi = "0.9.0" +bevy = "0.13" +bevy-inspector-egui = "0.23.2" +bevy_hanabi = "0.10.0" # Local disk storage in a key-value store. Settings are stored with this. -bevy_pkv = "0.9.1" +bevy_pkv = { git = "https://github.com/johanhelsing/bevy_pkv#af0b750b1dbfc8db58dbb2bd07c5eda72e714b79" } noise = "0.8.2" serde = "1.0.197" serde_default_utils = "0.2.1" serde_yaml = "0.9.32" tracing = "0.1.40" walkdir = "2.4.0" -bevy_rapier2d = { version = "0.24.0", features = [ +bevy_rapier2d = { version = "0.25.0", features = [ "parallel", "debug-render-2d", ] } diff --git a/game_library/src/data_loader/storage.rs b/game_library/src/data_loader/storage.rs index dcd5ebc..7fab5c0 100644 --- a/game_library/src/data_loader/storage.rs +++ b/game_library/src/data_loader/storage.rs @@ -57,7 +57,7 @@ pub struct GameData { /// The spells that have been loaded into the game. pub spells: Vault, /// The tile atlases that have been loaded into the game. - pub tile_atlas: Vault>, + pub tile_atlas: Vault, /// The particles that have been loaded into the game. pub particles: Vault>, /// Loaded realm definitions @@ -65,3 +65,12 @@ pub struct GameData { /// Loaded simple objects pub simple_objects: Vault, } + +/// `TextureAtlas` has been changed in bevy 0.13 so we need to track the texture handle and the texture atlas. +#[derive(Resource, Debug, Clone, Default)] +pub struct StoredTextureAtlas { + /// The texture handle of the texture atlas layout. + pub atlas_handle: Handle, + /// The texture handle used by the atlas. + pub texture_handle: Handle, +} diff --git a/game_library/src/data_loader/tilesets.rs b/game_library/src/data_loader/tilesets.rs index 47aa53c..eb3d7c0 100644 --- a/game_library/src/data_loader/tilesets.rs +++ b/game_library/src/data_loader/tilesets.rs @@ -2,13 +2,16 @@ use bevy::prelude::*; -use super::{events::LoadedTilesetData, storage::GameData}; +use super::{ + events::LoadedTilesetData, + storage::{GameData, StoredTextureAtlas}, +}; /// Load the tilesets into the game and store a handle under the `unique_id`. #[allow(clippy::needless_pass_by_value, clippy::module_name_repetitions)] pub fn load_tilesets( mut er_tileset_df: EventReader, - mut texture_atlases: ResMut>, + mut texture_atlases: ResMut>, mut game_data: ResMut, asset_server: Res, ) { @@ -17,8 +20,7 @@ pub fn load_tilesets( let tileset = &tileset.tileset_data.data; let texture_handle = asset_server.load(&tileset.path); - let texture_atlas = TextureAtlas::from_grid( - texture_handle, + let texture_atlas = TextureAtlasLayout::from_grid( Vec2::new(tileset.tile_width, tileset.tile_height), tileset.tileset_width, tileset.tileset_height, @@ -28,8 +30,12 @@ pub fn load_tilesets( let atlas_handle = texture_atlases.add(texture_atlas); - game_data - .tile_atlas - .insert(String::from(unique_id), atlas_handle); + game_data.tile_atlas.insert( + String::from(unique_id), + StoredTextureAtlas { + atlas_handle, + texture_handle, + }, + ); } } diff --git a/game_library/src/physics/plugin.rs b/game_library/src/physics/plugin.rs index 7e78db3..d0ec3b7 100644 --- a/game_library/src/physics/plugin.rs +++ b/game_library/src/physics/plugin.rs @@ -41,7 +41,7 @@ impl Plugin for PhysicsPlugin { #[allow(clippy::needless_pass_by_value)] fn toggle_debug_rendering( mut debug_render_context: ResMut, - keyboard_input: Res>, + keyboard_input: Res>, ) { if keyboard_input.just_pressed(KeyCode::F3) { debug_render_context.enabled = !debug_render_context.enabled; diff --git a/game_library/src/progress_bar/config.rs b/game_library/src/progress_bar/config.rs index f64d150..492f97f 100644 --- a/game_library/src/progress_bar/config.rs +++ b/game_library/src/progress_bar/config.rs @@ -156,7 +156,7 @@ impl ProgressBarConfig { /// This is a [`Quad`] with the size of the progress bar. #[must_use] pub fn background_mesh(&self) -> Mesh { - shape::Quad::new(self.size).into() + Rectangle::new(self.size.x, self.size.y).into() } /// Get the mesh for the progress bar foreground. /// @@ -164,11 +164,7 @@ impl ProgressBarConfig { /// bar background scaled by the percentage. #[must_use] pub fn foreground_mesh(&self, percentage: &T) -> Mesh { - shape::Quad::new(Vec2::new( - self.size.x * percentage.percentage(), - self.size.y, - )) - .into() + Rectangle::new(self.size.x * percentage.percentage(), self.size.y).into() } /// Get the current [`BarState`] for the given percentage. #[must_use] diff --git a/game_library/src/progress_bar/plugin.rs b/game_library/src/progress_bar/plugin.rs index 3ceb2f1..f1c51a1 100644 --- a/game_library/src/progress_bar/plugin.rs +++ b/game_library/src/progress_bar/plugin.rs @@ -86,12 +86,10 @@ fn spawn_progress_bars( ) { for (entity, percentage, config) in query.iter() { // spawn progress bar - let foreground_color = materials.add(config.color(percentage).into()); - let foreground_color_moderate = - materials.add(config.color_for_state(&BarState::Moderate).into()); - let foreground_color_critical = - materials.add(config.color_for_state(&BarState::Critical).into()); - let background_color = materials.add(config.background_color().into()); + let foreground_color = materials.add(config.color(percentage)); + let foreground_color_moderate = materials.add(config.color_for_state(&BarState::Moderate)); + let foreground_color_critical = materials.add(config.color_for_state(&BarState::Critical)); + let background_color = materials.add(config.background_color()); let Ok(entity_transform) = transform_query.get(entity) else { tracing::warn!("Failed to get parent transform for progress bar"); @@ -151,40 +149,42 @@ fn update( parent_query: Query<(&T, &ProgressBarConfig, &WithProgressBar, &Children), Changed>, mut mesh_query: Query<&mut Transform>, ) { - parent_query.for_each(|(percentage, config, progress_bar, children)| { - let (_, foreground) = progress_bar.get(); - - // loop over child entity ids - for child in children { - // if this isn't the foreground entity, skip it - if *child != foreground { - continue; - } - - tracing::info!( - "Updating progress bar for entity with percentage {}", - percentage.percentage() - ); - - // grab the mutable mesh - let Ok(mut transform) = mesh_query.get_mut(*child) else { - tracing::warn!( - "Failed to get foreground mesh for progress bar Entity {foreground:?}" + parent_query + .iter() + .for_each(|(percentage, config, progress_bar, children)| { + let (_, foreground) = progress_bar.get(); + + // loop over child entity ids + for child in children { + // if this isn't the foreground entity, skip it + if *child != foreground { + continue; + } + + tracing::info!( + "Updating progress bar for entity with percentage {}", + percentage.percentage() ); - return; - }; - - // update the mesh - commands - .entity(*child) - .insert(progress_bar.get_material(config, percentage)); - // update the transform - transform.scale = Vec3::new(percentage.percentage(), 1.0, 1.0); - // update the translation.x to be the percentage of the parent's width - transform.translation.x = - config.position_translation.x + (percentage.percentage() * config.size.x / 2.0); - } - }); + + // grab the mutable mesh + let Ok(mut transform) = mesh_query.get_mut(*child) else { + tracing::warn!( + "Failed to get foreground mesh for progress bar Entity {foreground:?}" + ); + return; + }; + + // update the mesh + commands + .entity(*child) + .insert(progress_bar.get_material(config, percentage)); + // update the transform + transform.scale = Vec3::new(percentage.percentage(), 1.0, 1.0); + // update the translation.x to be the percentage of the parent's width + transform.translation.x = + config.position_translation.x + (percentage.percentage() * config.size.x / 2.0); + } + }); } #[allow(clippy::needless_pass_by_value)] From 841b49538cb2eede4a0c7ec6fcbed30aaf437175 Mon Sep 17 00:00:00 2001 From: Nick Westerhausen <2317381+nwesterhausen@users.noreply.github.com> Date: Sun, 25 Feb 2024 12:55:43 -0500 Subject: [PATCH 11/51] fix: use `$ref` for references --- game_data/_schemas/spell_data.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/game_data/_schemas/spell_data.json b/game_data/_schemas/spell_data.json index 5740f79..fb8f6a6 100644 --- a/game_data/_schemas/spell_data.json +++ b/game_data/_schemas/spell_data.json @@ -19,11 +19,11 @@ }, "talisman": { "description": "The spell talisman which creates this spell", - "ref": "https://schemas.nwest.one/games/elementalist/spell_talisman.json" + "$ref": "https://schemas.nwest.one/games/elementalist/spell_talisman.json" }, "skill": { "description": "The skill which powers this spell", - "ref": "https://schemas.nwest.one/games/elementalist/skill.json" + "$ref": "https://schemas.nwest.one/games/elementalist/skill.json" }, "castSlot": { "description": "The slot the spell can fit in", From 4118ce6ff715f3b1ebe5a73876faf5d164368ed3 Mon Sep 17 00:00:00 2001 From: Nick Westerhausen <2317381+nwesterhausen@users.noreply.github.com> Date: Sun, 25 Feb 2024 13:32:45 -0500 Subject: [PATCH 12/51] feat: update schemas --- game_data/_schemas/biome.json | 202 +++++++++++++++++----- game_data/_schemas/biome_altitude.json | 32 +++- game_data/_schemas/biome_humidity.json | 42 ++++- game_data/_schemas/biome_latitude.json | 37 ++++- game_data/_schemas/color.json | 212 ++++++++++++++++++------ game_data/_schemas/header.json | 18 +- game_data/_schemas/magic_school.json | 92 +++++++--- game_data/_schemas/particle_effect.json | 17 +- game_data/_schemas/skill.json | 51 ++++-- game_data/_schemas/spell_tag.json | 22 --- game_data/_schemas/spell_talisman.json | 24 +-- game_data/_schemas/stat.json | 137 +++++++++++++++ game_data/_schemas/stat_effect.json | 85 +++++----- 13 files changed, 740 insertions(+), 231 deletions(-) delete mode 100644 game_data/_schemas/spell_tag.json create mode 100644 game_data/_schemas/stat.json diff --git a/game_data/_schemas/biome.json b/game_data/_schemas/biome.json index 702d4bc..8035bd5 100644 --- a/game_data/_schemas/biome.json +++ b/game_data/_schemas/biome.json @@ -4,46 +4,166 @@ "title": "Elementalist Biome", "description": "The available biomes for the Elementalist game.", "type": "string", - "enum": [ - "Rainforest", - "SeasonalDeciduousRainforest", - "SeasonalSemidecidousRainforest", - "GiantRainforest", - "DeciduousForest", - "ConiferousForest", - "Taiga", - "Woodland", - "Shrubland", - "Savanna", - "Grassland", - "Tundra", - "Desert", - "Scrub", - "Bog", - "FreshwaterSwamp", - "SaltwaterSwamp", - "Saltmarsh", - "Wetland", - "LargeLake", - "RiverDelta", - "CoastalRiver", - "InlandRiver", - "Floodplain", - "UplandRiver", - "EndorheicBasin", - "OceanicIsland", - "Sea", - "DeepSea", - "SeaShelf", - "CoralReef", - "KelpForest", - "Glacier", - "IceSheet", - "Barren", - "Indoor", - "Urban", - "Cultivated", - "Forested", - "Rangeland" + "oneOf": [ + { + "const": "Rainforest", + "description": "A dense, warm, wet forest, typically found in tropical areas." + }, + { + "const": "SeasonalDeciduousRainforest", + "description": "A warm, wet forest that loses its leaves in the dry season." + }, + { + "const": "SeasonalSemidecidousRainforest", + "description": "A warm, wet forest that loses some of its leaves in the dry season." + }, + { + "const": "GiantRainforest", + "description": "A dense, warm, wet forest with very large trees." + }, + { + "const": "DeciduousForest", + "description": "A forest that loses its leaves in the winter." + }, + { + "const": "ConiferousForest", + "description": "A forest of coniferous trees." + }, + { + "const": "Taiga", + "description": "A cold forest of coniferous trees." + }, + { + "const": "Woodland", + "description": "An area of land covered with trees." + }, + { + "const": "Shrubland", + "description": "An area of land covered with shrubs." + }, + { + "const": "Savanna", + "description": "A grassy plain in tropical and subtropical regions, with few trees." + }, + { + "const": "Grassland", + "description": "A large open area of country covered with grass, especially one used for grazing." + }, + { + "const": "Tundra", + "description": "A vast, flat, treeless Arctic region of Europe, Asia, and North America in which the subsoil is permanently frozen." + }, + { + "const": "Desert", + "description": "A dry, barren area of land, especially one covered with sand, that is characteristically desolate, waterless, and without vegetation." + }, + { + "const": "Scrub", + "description": "An area covered with low-growing or stunted trees." + }, + { + "const": "Bog", + "description": "An area of wet, spongy ground with soil composed mainly of decayed vegetable matter." + }, + { + "const": "FreshwaterSwamp", + "description": "A swamp with fresh water." + }, + { + "const": "SaltwaterSwamp", + "description": "A swamp with salt water." + }, + { + "const": "Saltmarsh", + "description": "An area of coastal grassland that is regularly flooded by seawater." + }, + { + "const": "Wetland", + "description": "An area of land that is covered with a shallow layer of water during some or all of the year." + }, + { + "const": "LargeLake", + "description": "A large body of water surrounded by land." + }, + { + "const": "RiverDelta", + "description": "A landform that forms from deposition of sediment carried by a river as the flow leaves its mouth and enters slower-moving or standing water." + }, + { + "const": "CoastalRiver", + "description": "A river that flows into the sea." + }, + { + "const": "InlandRiver", + "description": "A river that flows into a lake or another river." + }, + { + "const": "Floodplain", + "description": "An area of low-lying ground adjacent to a river, formed mainly of river sediments and subject to flooding." + }, + { + "const": "UplandRiver", + "description": "A river that flows through hilly or mountainous country." + }, + { + "const": "EndorheicBasin", + "description": "A closed drainage basin that retains water and allows no outflow to other bodies of water such as rivers or oceans." + }, + { + "const": "OceanicIsland", + "description": "An island that is not part of a continent." + }, + { + "const": "Sea", + "description": "The expanse of salt water that covers most of the earth's surface and surrounds its landmasses." + }, + { + "const": "DeepSea", + "description": "The deepest part of the ocean." + }, + { + "const": "SeaShelf", + "description": "The relatively shallow (200m) area of the sea floor surrounding the continents." + }, + { + "const": "CoralReef", + "description": "A ridge of rock in the sea formed by the growth and deposit of coral." + }, + { + "const": "KelpForest", + "description": "A large underwater area with a high density of kelp." + }, + { + "const": "Glacier", + "description": "A slowly moving mass or river of ice formed by the accumulation and compaction of snow on mountains or near the poles." + }, + { + "const": "IceSheet", + "description": "A mass of glacial ice, more than 50,000 square kilometers (19,000 square miles)." + }, + { + "const": "Barren", + "description": "Too poor to produce much or any vegetation." + }, + { + "const": "Indoor", + "description": "Inside a building." + }, + { + "const": "Urban", + "description": "In, relating to, or characteristic of a city or town." + }, + { + "const": "Cultivated", + "description": "Prepared and used for raising crops." + }, + { + "const": "Forested", + "description": "Covered with trees or forests." + }, + { + "const": "Rangeland", + "description": "Land used for grazing and browsing animals." + } ] } diff --git a/game_data/_schemas/biome_altitude.json b/game_data/_schemas/biome_altitude.json index 0ffb098..2119d91 100644 --- a/game_data/_schemas/biome_altitude.json +++ b/game_data/_schemas/biome_altitude.json @@ -4,12 +4,30 @@ "title": "Elementalist Biome Altitude", "description": "The available altitudes for biomes in the Elementalist game.", "type": "string", - "enum": [ - "Alvar", - "Alpine", - "Subalpine", - "Montane", - "LowerMontane", - "Premontane" + "oneOf": [ + { + "const": "Alvar", + "description": "An alvar altitude is characterized by average temperatures less than 1.5 degrees Celsius" + }, + { + "const": "Alpine", + "description": "An alpine altitude is characterized by average temperatures within 1.5 to 3 degrees Celsius" + }, + { + "const": "Subalpine", + "description": "A subalpine altitude is characterized by average temperatures within 3 to 6 degrees Celsius" + }, + { + "const": "Montane", + "description": "A montane altitude is characterized by average temperatures within 6 to 12 degrees Celsius" + }, + { + "const": "LowerMontane", + "description": "A lower montane altitude is characterized by average temperatures within 12 to 24 degrees Celsius" + }, + { + "const": "Premontane", + "description": "A premontane altitude is characterized by average temperatures higher than 24 degrees Celsius" + } ] } diff --git a/game_data/_schemas/biome_humidity.json b/game_data/_schemas/biome_humidity.json index b42ff24..ef3471c 100644 --- a/game_data/_schemas/biome_humidity.json +++ b/game_data/_schemas/biome_humidity.json @@ -4,14 +4,38 @@ "title": "Elementalist Biome Humidity", "description": "The available humidities for biomes in the Elementalist game.", "type": "string", - "enum": [ - "Superarid", - "Perarid", - "Arid", - "Semiarid", - "Subhumid", - "Humid", - "Perhumid", - "Superhumid" + "oneOf": [ + { + "const": "Superaird", + "description": "Superarid - less than 100mm of precipitation per year." + }, + { + "const": "Perarid", + "description": "Perarid - 100-200mm of precipitation per year." + }, + { + "const": "Arid", + "description": "Arid - 200-400mm of precipitation per year." + }, + { + "const": "Semiarid", + "description": "Semiarid - 400-800mm of precipitation per year." + }, + { + "const": "Subhumid", + "description": "Subhumid - 800-1600mm of precipitation per year." + }, + { + "const": "Humid", + "description": "Humid - 1600-3200mm of precipitation per year." + }, + { + "const": "Perhumid", + "description": "Perhumid - 3200-6400mm of precipitation per year." + }, + { + "const": "Superhumid", + "description": "Superhumid - more than 6400mm of precipitation per year." + } ] } diff --git a/game_data/_schemas/biome_latitude.json b/game_data/_schemas/biome_latitude.json index d859bd4..f3d83f8 100644 --- a/game_data/_schemas/biome_latitude.json +++ b/game_data/_schemas/biome_latitude.json @@ -4,13 +4,34 @@ "title": "Elementalist Biome Latitude", "description": "The available latitudinal regions for biomes in the Elementalist game.", "type": "string", - "enum": [ - "Tropical", - "Subtropical", - "WarmTemperate", - "CoolTemperate", - "Boreal", - "Subpolar", - "Polar" + "oneOf": [ + { + "const": "Tropical", + "description": "Found closest to the equator, tropical biomes are hot and humid, with a wide variety of plant and animal life." + }, + { + "const": "Subtropical", + "description": "Slightly further from the equator, subtropical biomes are still warm and humid, but with a wider range of seasonal variation." + }, + { + "const": "WarmTemperate", + "description": "Warm temperate biomes are found in the middle latitudes, with warm summers and mild winters." + }, + { + "const": "CoolTemperate", + "description": "Cool temperate biomes are found in the higher middle latitudes, with warm summers and cold winters." + }, + { + "const": "Boreal", + "description": "Boreal biomes are found in the subarctic regions, with short, cool summers and long, cold winters." + }, + { + "const": "Subpolar", + "description": "Subpolar biomes are found in the arctic regions, with short, cool summers and long, very cold winters." + }, + { + "const": "Polar", + "description": "Polar biomes are found at the poles, with very cold temperatures year-round." + } ] } diff --git a/game_data/_schemas/color.json b/game_data/_schemas/color.json index 1e04b87..0d2512d 100644 --- a/game_data/_schemas/color.json +++ b/game_data/_schemas/color.json @@ -4,58 +4,164 @@ "title": "Elementalist Color", "description": "The supported colors for the Elementalist game. See https://nwesterhausen.github.io/elementalist/game_library/colors", "type": "string", - "enum": [ - "Rangitoto", - "CostaDelSol", - "Sushi", - "Conifer", - "Manz", - "Hampton", - "Olivine", - "Laurel", - "Nandor", - "OuterSpace", - "EbonyClay", - "Mirage", - "CloudBurst", - "SanJuan", - "SteelBlue", - "Downy", - "WaterLeaf", - "Mystic", - "Loblolly", - "RegentGray", - "PaleSky", - "BrightGray", - "LondonHue", - "SandDune", - "Bossanova", - "Jacarta", - "Revolver", - "WineBerry", - "PurpleAlternateDark", - "TawnyPort", - "ChestnutRose", - "SeaPink", - "Chalky", - "Anzac", - "Copper", - "MuleFawn", - "Terracotta", - "Mojo", - "SolidPink", - "Buccaneer", - "CocoaBrown", - "Millbrook", - "SpicyMix", - "SantaFe", - "Russett", - "Matterhorn", - "Thunder", - "DarkerThunder", - "Ferra", - "LighterSandDune", - "Mongoose", - "Kangaroo" + "oneOf": [ + { + "const": "Rangitoto", + "description": "A dark green-brown, #3f4328" + }, + { + "const": "CostaDelSol", + "description": "A deeper green, #5f7132" + }, + { + "const": "Sushi" + }, + { + "const": "Conifer" + }, + { + "const": "Manz" + }, + { + "const": "Hampton" + }, + { + "const": "Olivine" + }, + { + "const": "Laurel" + }, + { + "const": "Nandor" + }, + { + "const": "OuterSpace" + }, + { + "const": "EbonyClay" + }, + { + "const": "Mirage" + }, + { + "const": "CloudBurst" + }, + { + "const": "SanJuan" + }, + { + "const": "SteelBlue" + }, + { + "const": "Downy" + }, + { + "const": "WaterLeaf" + }, + { + "const": "Mystic" + }, + { + "const": "Loblolly" + }, + { + "const": "RegentGray" + }, + { + "const": "PaleSky" + }, + { + "const": "BrightGray" + }, + { + "const": "LondonHue" + }, + { + "const": "SandDune" + }, + { + "const": "Bossanova" + }, + { + "const": "Jacarta" + }, + { + "const": "Revolver" + }, + { + "const": "WineBerry" + }, + { + "const": "PurpleAlternateDark" + }, + { + "const": "TawnyPort" + }, + { + "const": "ChestnutRose" + }, + { + "const": "SeaPink" + }, + { + "const": "Chalky" + }, + { + "const": "Anzac" + }, + { + "const": "Copper" + }, + { + "const": "MuleFawn" + }, + { + "const": "Terracotta" + }, + { + "const": "Mojo" + }, + { + "const": "SolidPink" + }, + { + "const": "Buccaneer" + }, + { + "const": "CocoaBrown" + }, + { + "const": "Millbrook" + }, + { + "const": "SpicyMix" + }, + { + "const": "SantaFe" + }, + { + "const": "Russett" + }, + { + "const": "Matterhorn" + }, + { + "const": "Thunder" + }, + { + "const": "DarkerThunder" + }, + { + "const": "Ferra" + }, + { + "const": "LighterSandDune" + }, + { + "const": "Mongoose" + }, + { + "const": "Kangaroo" + } ] } diff --git a/game_data/_schemas/header.json b/game_data/_schemas/header.json index 8a060d9..b9d29c6 100644 --- a/game_data/_schemas/header.json +++ b/game_data/_schemas/header.json @@ -46,8 +46,22 @@ "validGameInternalVersion": { "description": "Internal version of the game that this data file is valid for. This is used to ensure that the data file is not loaded for an incompatible game version.", "type": "integer", - "enum": [1] + "oneOf": [ + { + "const": 1, + "description": "Version 0 of the game, this encompasses all of 0.x since it's the first version and there's no consideration for backwards compatibility or API stability.", + "title": "Versions 0.x of the game" + } + ] } }, - "required": ["uniqueId", "system", "author", "description", "displayVersion", "internalVersion", "validGameInternalVersion"] + "required": [ + "uniqueId", + "system", + "author", + "description", + "displayVersion", + "internalVersion", + "validGameInternalVersion" + ] } diff --git a/game_data/_schemas/magic_school.json b/game_data/_schemas/magic_school.json index c1519dd..ab20e6e 100644 --- a/game_data/_schemas/magic_school.json +++ b/game_data/_schemas/magic_school.json @@ -4,24 +4,78 @@ "title": "The schools of magic in the Elementalist game", "description": "The family of magic the spell belongs to", "type": "string", - "enum": [ - "fire", - "lightning", - "water", - "earth", - "air", - "ice", - "force", - "light", - "dark", - "arcane", - "life", - "death", - "enhancement", - "reduction", - "summoning", - "necromancy", - "polymorph", - "time" + "oneOf": [ + { + "const": "Fire", + "description": "The school of fire magic" + }, + { + "const": "Lightning", + "description": "The school of lightning magic" + }, + { + "const": "Water", + "description": "The school of water magic" + }, + { + "const": "Earth", + "description": "The school of earth magic" + }, + { + "const": "Air", + "description": "The school of air magic" + }, + { + "const": "Ice", + "description": "The school of ice magic" + }, + { + "const": "Force", + "description": "The school of force magic" + }, + { + "const": "Light", + "description": "The school of light magic" + }, + { + "const": "Dark", + "description": "The school of dark magic" + }, + { + "const": "Arcane", + "description": "The school of arcane magic" + }, + { + "const": "Life", + "description": "The school of life magic" + }, + { + "const": "Death", + "description": "The school of death magic" + }, + { + "const": "Enhancement", + "description": "The school of enhancement magic" + }, + { + "const": "Reduction", + "description": "The school of reduction magic" + }, + { + "const": "Summoning", + "description": "The school of summoning magic" + }, + { + "const": "Necromancy", + "description": "The school of necromancy magic" + }, + { + "const": "Polymorph", + "description": "The school of polymorph magic" + }, + { + "const": "Time", + "description": "The school of time magic" + } ] } diff --git a/game_data/_schemas/particle_effect.json b/game_data/_schemas/particle_effect.json index 617a142..d46c46e 100644 --- a/game_data/_schemas/particle_effect.json +++ b/game_data/_schemas/particle_effect.json @@ -38,16 +38,27 @@ "modifierType": { "description": "The type of modifier to use for the initial position", "type": "string", - "enum": ["circle"] + "enum": [ + "circle" + ] }, "radius": { "description": "The radius of the circle to spawn particles in", "type": "number" }, "shapeDimension": { - "description": "The shape dimension to use for the initial position. Volume is anywhere within the circle, Surface is only on the edge of the circle.", + "description": "The shape dimension to use for the initial position.", "type": "string", - "enum": ["volume", "surface"] + "oneOf": [ + { + "const": "volume", + "description": "Volume is anywhere within the circle" + }, + { + "const": "surface", + "description": "Surface is only on the edge of the circle" + } + ] } } }, diff --git a/game_data/_schemas/skill.json b/game_data/_schemas/skill.json index 9747c41..86174ca 100644 --- a/game_data/_schemas/skill.json +++ b/game_data/_schemas/skill.json @@ -6,63 +6,78 @@ "type": "string", "oneOf": [ { - "title": "Pyromancy is the school of fire magic.", + "title": "Fire magic", + "description": "Pyromancy is the school of fire magic.", "const": "Pyromancy" }, { - "title": "Fulgomancy is the school of lightning magic.", + "title": "Lightning magic", + "description": "Fulgomancy is the school of lightning magic.", "const": "Fulgomancy" }, { - "title": "Hydromancy is the school of water magic.", + "title": "Water magic", + "description": "Hydromancy is the school of water magic.", "const": "Hydromancy" }, { - "title": "Geomancy is the school of earth magic.", + "title": "Earth magic", + "description": "Geomancy is the school of earth magic.", "const": "Geomancy" }, { - "title": "Aeromancy is the school of air magic.", + "title": "Air magic", + "description": "Aeromancy is the school of air magic.", "const": "Aeromancy" }, { - "title": "Cryomancy is the school of ice magic.", + "title": "Ice magic", + "description": "Cryomancy is the school of ice magic.", "const": "Cryomancy" }, { - "title": "Trudomancy is the school of force magic.", + "title": "Force magic", + "description": "Trudomancy is the school of force magic.", "const": "Trudomancy" }, { - "title": "Photomancy is the school of light magic.", + "title": "Light magic", + "description": "Photomancy is the school of light magic.", "const": "Photomancy" }, { - "title": "Umbramancy is the school of dark magic.", + "title": "Dark magic", + "description": "Umbramancy is the school of dark magic.", "const": "Umbramancy" }, { - "title": "Arcanomancy is the school of arcane magic.", + "title": "Arcane magic", + "description": "Arcanomancy is the school of arcane magic.", "const": "Arcanomancy" }, { - "title": "Vitomancy is the school of life magic.", + "title": "Life magic", + "description": "Vitomancy is the school of life magic.", "const": "Vitomancy" }, { - "title": "Mortomancy is the school of death magic.", + "title": "Death magic", + "description": "Mortomancy is the school of death magic.", "const": "Mortomancy" }, { - "title": "Ampiliomancy is the school of enhancement magic.", + "title": "Enhancement magic", + "description": "Ampiliomancy is the school of enhancement magic.", "const": "Ampiliomancy" }, { - "title": "Diminiomancy is the school of reduction magic.", + "title": "Reduction magic", + "description": "Diminiomancy is the school of reduction magic.", "const": "Diminiomancy" }, { - "title": "Citomancy is the school of summoning magic.", + "title": "Summoning magic", + "description": "Citomancy is the school of summoning magic.", "const": "Citomancy" }, { @@ -70,11 +85,13 @@ "const": "Necromancy" }, { - "title": "Mutatiomancy is the school of polymorph magic.", + "title": "Polymorph magic", + "description": "Mutatiomancy is the school of polymorph magic.", "const": "Mutatiomancy" }, { - "title": "Chronomancy is the school of time magic.", + "title": "Time magic", + "description": "Chronomancy is the school of time magic.", "const": "Chronomancy" } ] diff --git a/game_data/_schemas/spell_tag.json b/game_data/_schemas/spell_tag.json deleted file mode 100644 index 2d1718e..0000000 --- a/game_data/_schemas/spell_tag.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://schemas.nwest.one/games/elementalist/spell_tag.json", - "title": "Extended Spell Properties", - "description": "Extra properties that can apply to one or more spells", - "type": "object", - "properties": { - "name": { - "description": "The name of the tag", - "type": "string" - }, - "description": { - "description": "A description of the tag", - "type": "string" - }, - "extendedDescription": { - "description": "A longer description of the tag", - "type": "string" - } - }, - "required": ["name", "description"] -} diff --git a/game_data/_schemas/spell_talisman.json b/game_data/_schemas/spell_talisman.json index 5308243..b8607be 100644 --- a/game_data/_schemas/spell_talisman.json +++ b/game_data/_schemas/spell_talisman.json @@ -66,48 +66,50 @@ ] }, "tier": { - "description": "The tier of the spell talisman. This defines the power of the spell.", + "description": "The tier of the spell talisman. This (loosely) defines the power of the spell.", "type": "string", "oneOf": [ { "const": "Mundane", - "title": "Mundane or Tier 0" + "title": "Tier 0: Mundane" }, { "const": "Common", - "title": "Common or Tier 1" + "title": "Tier 1: Common" }, { "const": "Uncommon", - "title": "Uncommon or Tier 2" + "title": "Tier 2: Uncommon" }, { "const": "Rare", - "title": "Rare or Tier 3" + "title": "Tier 3: Rare" }, { "const": "Epic", - "title": "Epic or Tier 4" + "title": "Tier 4: Epic" }, { "const": "Legendary", - "title": "Legendary or Tier 5" + "title": "Tier 5: Legendary" }, { "const": "Mythic", - "title": "Mythic or Tier 6" + "title": "Tier 6: Mythic" }, { "const": "Divine", - "title": "Divine or Tier 7 (highest)" + "title": "Tier 7 (highest): Divine" }, { "const": "Unique", - "title": "Unique tier should only be used for restricted spells that are unique to a specific character or have other requirements. It cannot be inscribed by the player." + "title": "Special tier: Unique", + "description": "Unique tier should only be used for restricted spells that are unique to a specific character or have other requirements. It cannot be inscribed by the player." }, { "const": "Astral", - "title": "Astral tier spells are a step above divine. An astral talisman is not possible in the normal game." + "title": "Special tier: Astral", + "description": "Astral tier spells are a step above divine. An astral talisman is not possible in the normal game." } ] } diff --git a/game_data/_schemas/stat.json b/game_data/_schemas/stat.json new file mode 100644 index 0000000..e6ff2b3 --- /dev/null +++ b/game_data/_schemas/stat.json @@ -0,0 +1,137 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.nwest.one/games/elementalist/stat.json", + "title": "Elementalist Entity Stat", + "description": "A statistic for an entity in the Elementalist game", + "type": "string", + "oneOf": [ + { + "const": "health", + "description": "The amount of health an entity has" + }, + { + "const": "mana", + "description": "The amount of mana an entity has" + }, + { + "const": "damageReduction", + "description": "The amount of damage reduction an entity has" + }, + { + "const": "damageResistance", + "description": "The amount of damage resistance an entity has" + }, + { + "const": "damageReflection", + "description": "The amount of damage reflection an entity has" + }, + { + "const": "damageAmplification", + "description": "The amount of damage amplification an entity has" + }, + { + "const": "criticalStrikeChance", + "description": "The chance of a critical strike" + }, + { + "const": "criticalStrikeDamage", + "description": "The amount of damage a critical strike does" + }, + { + "const": "lifeSteal", + "description": "The amount of life stolen from an attack" + }, + { + "const": "manaSteal", + "description": "The amount of mana stolen from an attack" + }, + { + "const": "movementSpeed", + "description": "The speed at which an entity moves" + }, + { + "const": "stunResistance", + "description": "The resistance to being stunned" + }, + { + "const": "healthRegeneration", + "description": "The amount of health regenerated per second" + }, + { + "const": "manaRegeneration", + "description": "The amount of mana regenerated per second" + }, + { + "const": "projectileSpeed", + "description": "The speed of a projectile" + }, + { + "const": "projectileSize", + "description": "The size of a projectile" + }, + { + "const": "projectileLifetime", + "description": "The lifetime of a projectile" + }, + { + "const": "dodgeChance", + "description": "The chance to dodge an attack" + }, + { + "const": "attackDamage", + "description": "The amount of damage an attack does" + }, + { + "const": "attackSpeed", + "description": "The speed at which an entity attacks" + }, + { + "const": "attackRange", + "description": "The range of an attack" + }, + { + "const": "physicalDamageReduction", + "description": "The amount of physical damage reduction an entity has" + }, + { + "const": "physicalDamageResistance", + "description": "The amount of physical damage resistance an entity has" + }, + { + "const": "physicalDamageReflection", + "description": "The amount of physical damage reflection an entity has" + }, + { + "const": "physicalDamageAmplification", + "description": "The amount of physical damage amplification an entity has" + }, + { + "const": "magicDamage", + "description": "The amount of magic damage an entity does" + }, + { + "const": "cooldownReduction", + "description": "The amount of cooldown reduction an entity has" + }, + { + "const": "spellRange", + "description": "The range of a spell" + }, + { + "const": "magicDamageReduction", + "description": "The amount of magic damage reduction an entity has" + }, + { + "const": "magicDamageResistance", + "description": "The amount of magic damage resistance an entity has" + }, + { + "const": "magicDamageReflection", + "description": "The amount of magic damage reflection an entity has" + }, + { + "const": "magicDamageAmplification", + "description": "The amount of magic damage amplification an entity has" + } + ] +} diff --git a/game_data/_schemas/stat_effect.json b/game_data/_schemas/stat_effect.json index 6fb0b48..a4ad9b1 100644 --- a/game_data/_schemas/stat_effect.json +++ b/game_data/_schemas/stat_effect.json @@ -26,7 +26,28 @@ "affectedEntity": { "description": "The entities affected by the effect", "type": "string", - "enum": ["any", "player", "enemy", "ally", "none"] + "oneOf": [ + { + "const": "Any", + "description": "Affects any entity type (player, enemy, ally)" + }, + { + "const": "Player", + "description": "Affects only the player" + }, + { + "const": "Enemy", + "description": "Affects only enemies" + }, + { + "const": "Ally", + "description": "Affects only allies" + }, + { + "const": "None", + "description": "Affects no entities" + } + ] }, "affectedStats": { "description": "The stats affected by the effect", @@ -36,41 +57,7 @@ "properties": { "stat": { "description": "The affected stat", - "type": "string", - "enum": [ - "health", - "mana", - "damageReduction", - "damageResistance", - "damageReflection", - "damageAmplification", - "criticalStrikeChance", - "criticalStrikeDamage", - "lifeSteal", - "manaSteal", - "movementSpeed", - "stunResistance", - "healthRegeneration", - "manaRegeneration", - "projectileSpeed", - "projectileSize", - "projectileLifetime", - "dodgeChance", - "attackDamage", - "attackSpeed", - "attackRange", - "physicalDamageReduction", - "physicalDamageResistance", - "physicalDamageReflection", - "physicalDamageAmplification", - "magicDamage", - "cooldownReduction", - "spellRange", - "magicDamageReduction", - "magicDamageResistance", - "magicDamageReflection", - "magicDamageAmplification" - ] + "$ref": "https://schemas.nwest.one/games/elementalist/stat.json" }, "amount": { "description": "The amount the stat is affected by (can be negative)", @@ -79,12 +66,32 @@ "affectType": { "description": "The type of affect the debuff has on the stat", "type": "string", - "enum": ["add", "multiply"] + "oneOf": [ + { + "const": "add", + "description": "Add the amount to the stat" + }, + { + "const": "multiply", + "description": "Multiply the stat by the amount" + } + ] } } }, - "required": ["stat", "amount", "affectType"] + "required": [ + "stat", + "amount", + "affectType" + ] } }, - "required": ["affectedEntity", "affectedStats", "name", "description", "duration", "maxStacks"] + "required": [ + "affectedEntity", + "affectedStats", + "name", + "description", + "duration", + "maxStacks" + ] } From c8e9a619007d09a2eeef85944ea92c6b5567f24b Mon Sep 17 00:00:00 2001 From: Nick Westerhausen <2317381+nwesterhausen@users.noreply.github.com> Date: Sun, 25 Feb 2024 14:48:57 -0500 Subject: [PATCH 13/51] feat: add melee, polymorph and teleport --- game_data/_schemas/spell_data.json | 67 ++++++++++++++++++++++---- game_data/_schemas/spell_talisman.json | 12 +++++ game_library/src/spells/talisman.rs | 6 +++ 3 files changed, 76 insertions(+), 9 deletions(-) diff --git a/game_data/_schemas/spell_data.json b/game_data/_schemas/spell_data.json index fb8f6a6..20a7cdb 100644 --- a/game_data/_schemas/spell_data.json +++ b/game_data/_schemas/spell_data.json @@ -28,6 +28,7 @@ "castSlot": { "description": "The slot the spell can fit in", "type": "string", + "default": "Cantrip", "oneOf": [ { "const": "Cantrip", @@ -46,6 +47,7 @@ "castType": { "description": "The type of cast the spell uses", "type": "string", + "default": "Instant", "oneOf": [ { "const": "Instant", @@ -63,47 +65,56 @@ }, "cooldown": { "description": "The time it takes to cool down after casting the spell", + "default": 0, "type": "number", "inclusiveMinimum": 0 }, "castTime": { "description": "The time it takes to cast the spell", + "default": 0, "type": "number", "inclusiveMinimum": 0 }, "manaCost": { "description": "The cost of the spell", + "default": 0, "type": "number", "inclusiveMinimum": 0 }, "range": { "description": "The range of the spell, used to determine how far it can travel", "type": "number", + "default": 100, "inclusiveMinimum": 0 }, "speed": { "description": "The speed of the spell, used to determine how quickly it travels", "type": "number", + "default": 100, "inclusiveMinimum": 0 }, "acceleration": { "description": "The acceleration of the spell, used to determine how quickly it gets up to max speed.", "type": "number", + "default": 20, "inclusiveMinimum": 0 }, "duration": { "description": "The duration of the spell, used to determine how long it lasts", "type": "number", + "default": 5, "inclusiveMinimum": 0 }, "baseDamage": { "description": "The damage of the spell, used to determine how much damage it does", "type": "number", + "default": 0, "inclusiveMinimum": 0 }, "baseHealing": { "description": "The healing of the spell, used to determine how much healing it does", "type": "number", + "default": 0, "inclusiveMinimum": 0 }, "buffs": { @@ -117,29 +128,35 @@ "radius": { "description": "The radius of the spell, used to determine how large the area of effect is", "type": "number", + "default": 0, "inclusiveMinimum": 0 }, "angle": { "description": "The angle of the spell, used to determine how wide the area of effect is", "type": "number", + "default": 0, "inclusiveMinimum": 0 }, "iconTileset": { "description": "The tileset with the icon of the spell (path in the assets folder)", - "type": "string" + "type": "string", + "default": "placeholder" }, "iconIndex": { "description": "The index of the icon in the tileset", "type": "integer", + "default": 0, "inclusiveMinimum": 0 }, "spriteTileset": { "description": "The sprite of the spell (path in the assets folder)", + "default": "placeholder", "type": "string" }, "spriteIndex": { "description": "The index of the sprite in the tileset", "type": "integer", + "default": 0, "inclusiveMinimum": 0 }, "particles": { @@ -159,17 +176,49 @@ "attachment": { "description": "The attachment point of the particle", "type": "string", - "enum": [ - "Cast", - "Projectile", - "Impact", - "Target", - "Caster", - "Ground", - "Summon" + "default": "Projectile", + "oneOf": [ + { + "const": "Cast", + "description": "Emit particles from the caster when the spell is cast." + }, + { + "const": "Projectile", + "description": "The particles emitted by the projectile." + }, + { + "const": "Impact", + "description": "The particles emitted when the spell impacts." + }, + { + "const": "Target", + "description": "The particles emitted from the target when impacted." + }, + { + "const": "Caster", + "description": "The particles emitted from the caster while casting (sustained)." + }, + { + "const": "Ground", + "description": "The particles emitted from the ground." + }, + { + "const": "Summon", + "description": "The particles emitted from the summoned entity." + } ] } } + }, + "spellTier": { + "depreciated": true, + "description": "The tier of the spell (covered by the Talisman now)", + "type": "string" + }, + "magic": { + "deprecated": true, + "description": "The magic type of the spell (defined in Skill now)", + "type": "string" } } }, diff --git a/game_data/_schemas/spell_talisman.json b/game_data/_schemas/spell_talisman.json index b8607be..63e0080 100644 --- a/game_data/_schemas/spell_talisman.json +++ b/game_data/_schemas/spell_talisman.json @@ -32,6 +32,10 @@ { "const": "OnSelf", "title": "On Self spells affect the caster." + }, + { + "const": "Melee", + "title": "Melee spells are cast at a target within melee range." } ] }, @@ -62,6 +66,14 @@ { "const": "Summon", "title": "Summon spells summon a creature to fight for the caster." + }, + { + "const": "Polymorph", + "title": "Polymorph spells change the form of the target." + }, + { + "const": "Teleport", + "title": "Teleport spells move the target to a different location." } ] }, diff --git a/game_library/src/spells/talisman.rs b/game_library/src/spells/talisman.rs index 5ddf299..444f613 100644 --- a/game_library/src/spells/talisman.rs +++ b/game_library/src/spells/talisman.rs @@ -34,6 +34,8 @@ pub enum Shaping { Touch, /// A spell with the `OnSelf` shaping affects the caster. OnSelf, + /// A spell with the `Melee` shaping acts as a melee attack. + Melee, } /// The behavior of the spell talisman. This defines the behavior of the spell. @@ -53,6 +55,10 @@ pub enum Behavior { Utility, /// A spell with the `Summon` behavior summons a creature. Summon, + /// A spell with the `Polymorph` behavior transforms the target. + Polymorph, + /// A spell with the `Teleport` behavior teleports the target. + Teleport, } /// The tier of the spell talisman. This defines the power level of the spell. From 21e07b8e3de8914bc2d6f28e8fb4ac3fe0e97dfa Mon Sep 17 00:00:00 2001 From: Nick Westerhausen <2317381+nwesterhausen@users.noreply.github.com> Date: Sun, 25 Feb 2024 14:53:16 -0500 Subject: [PATCH 14/51] feat: update spell definitions --- game_data/spells/aging_bolt.yaml | 9 +-------- game_data/spells/burning_touch.yaml | 17 +++++++---------- game_data/spells/charged_turf.yaml | 14 +++++++------- game_data/spells/death_bolt.yaml | 17 ++++++++--------- game_data/spells/death_dart.yaml | 17 ++++++++--------- game_data/spells/enhance_strength.yaml | 15 +++++++-------- game_data/spells/fire_bolt.yaml | 17 ++++++++--------- game_data/spells/fire_pillar.yaml | 15 +++++++-------- game_data/spells/fireball.yaml | 13 +++++++++---- game_data/spells/flame_burst.yaml | 15 +++++++++------ game_data/spells/flamethrower.yaml | 16 +++++++++------- game_data/spells/flash.yaml | 14 +++++++++----- game_data/spells/freeze_ray.yaml | 12 +++++++++--- game_data/spells/geyser.yaml | 13 +++++++++---- game_data/spells/gust.yaml | 12 +++++++----- game_data/spells/ice_dart.yaml | 15 +++++++-------- game_data/spells/ice_patch.yaml | 13 +++++++++---- game_data/spells/ice_pillar.yaml | 16 +++++++++------- game_data/spells/ice_spike.yaml | 15 ++++++++++----- game_data/spells/lightning_ball.yaml | 14 +++++++++----- game_data/spells/lightning_bolt.yaml | 12 +++++++----- game_data/spells/lightning_storm.yaml | 13 +++++++++---- game_data/spells/magic_mirror.yaml | 13 +++++++++---- game_data/spells/magic_missile.yaml | 12 +++++++----- game_data/spells/mana_dart.yaml | 13 ++++++++----- game_data/spells/mini_black_hole.yaml | 13 ++++++++----- game_data/spells/mud_splatter.yaml | 13 +++++++++---- game_data/spells/nature_bolt.yaml | 12 +++++++----- game_data/spells/overgrowth.yaml | 13 +++++++++---- game_data/spells/path_of_coals.yaml | 13 +++++++++---- game_data/spells/quicksand.yaml | 13 +++++++++---- game_data/spells/reduce_strength.yaml | 13 +++++++++---- game_data/spells/rock_pillar.yaml | 13 +++++++++---- game_data/spells/snares.yaml | 15 ++++++++++----- game_data/spells/spark.yaml | 18 +++++++----------- game_data/spells/stone_dart.yaml | 12 +++++++----- game_data/spells/summon_imp.yaml | 13 +++++++++---- game_data/spells/summon_undead.yaml | 14 +++++++++----- game_data/spells/tornado.yaml | 13 +++++++++---- game_data/spells/transform_into_ogre.yaml | 13 +++++++++---- game_data/spells/undead_zone.yaml | 12 +++++++++--- game_data/spells/updrafts.yaml | 15 ++++++++++----- game_data/spells/vine_whip.yaml | 16 ++++++++++------ game_data/spells/water_bolt.yaml | 15 +++++++-------- game_data/spells/water_jet.yaml | 13 +++++++++---- game_data/spells/whirlpool.yaml | 13 +++++++++---- game_data/spells/wind.yaml | 14 ++++++++++---- game_data/spells/zone_of_charm.yaml | 15 ++++++++++----- 48 files changed, 401 insertions(+), 265 deletions(-) diff --git a/game_data/spells/aging_bolt.yaml b/game_data/spells/aging_bolt.yaml index 660f63c..e40aab2 100644 --- a/game_data/spells/aging_bolt.yaml +++ b/game_data/spells/aging_bolt.yaml @@ -8,15 +8,8 @@ data: tier: Mundane manaCost: 1 castSlot: Cantrip - castTime: 0 cooldown: 2.50 - magic: time - skill: chronomancy - spellTier: 0 - flags: - - debuff - - projectile - castCategory: projectile + skill: Chronomancy castType: Instant spriteTileset: spell_projectiles spriteIndex: 11 diff --git a/game_data/spells/burning_touch.yaml b/game_data/spells/burning_touch.yaml index d283e80..4fe6404 100644 --- a/game_data/spells/burning_touch.yaml +++ b/game_data/spells/burning_touch.yaml @@ -10,16 +10,13 @@ header: data: name: Burning Touch description: Ignite a target by touch - manaCost: 0 - spellTier: 0 - castSlot: primary - castTime: 0 + castSlot: Cantrip cooldown: 2.00 - magic: fire - flags: - - touch - - instant - castType: instant - castCategory: touch + talisman: + shaping: Touch + behavior: Damage + tier: Mundane + skill: Pyromancy + castType: Instant spriteTileset: tileset/spell_icons.png spriteIndex: 0 diff --git a/game_data/spells/charged_turf.yaml b/game_data/spells/charged_turf.yaml index 79b2989..a2bac90 100644 --- a/game_data/spells/charged_turf.yaml +++ b/game_data/spells/charged_turf.yaml @@ -11,14 +11,14 @@ data: name: Charged Turf description: Create an area of electrically charged turf at the target location. manaCost: 3 - castSlot: secondary - castTime: 0 + castSlot: Slot cooldown: 6.0 - magic: lightning - spellTier: 3 - flags: - - aoe - castType: instant + talisman: + shaping: AreaOfEffect + behavior: Damage + tier: Uncommon + skill: Fulgomancy + castType: Instant castCategory: ground spriteTileset: tileset/ground_effects.png spriteIndex: 0 diff --git a/game_data/spells/death_bolt.yaml b/game_data/spells/death_bolt.yaml index 3e02cfe..cb57855 100644 --- a/game_data/spells/death_bolt.yaml +++ b/game_data/spells/death_bolt.yaml @@ -10,18 +10,17 @@ header: data: name: Death Bolt description: Launch a homing bolt of death energy at a target. - manaCost: 0 - castSlot: primary - castTime: 0 + castSlot: Cantrip cooldown: 7.5 - magic: death - spellTier: 2 + baseDamage: 3 + talisman: + shaping: Projectile + behavior: Damage + tier: Common + skill: Mortomancy spriteTileset: spell_projectiles spriteIndex: 0 - flags: - - projectile - castType: instant - castCategory: projectile + castType: Instant particles: - attachment: Projectile particleId: death-bolt diff --git a/game_data/spells/death_dart.yaml b/game_data/spells/death_dart.yaml index d0b7d7c..1b122f8 100644 --- a/game_data/spells/death_dart.yaml +++ b/game_data/spells/death_dart.yaml @@ -10,18 +10,17 @@ header: data: name: Death Dart description: Launch a dart of death energy at the target. - manaCost: 0 - castSlot: primary - castTime: 0 + castSlot: Cantrip cooldown: 7.5 - magic: death - spellTier: 0 + skill: Mortomancy spriteTileset: spell_projectiles spriteIndex: 1 - flags: - - projectile - castType: instant - castCategory: projectile + baseDamage: 1 + talisman: + shaping: Projectile + behavior: Damage + tier: Mundane + castType: Instant particles: - attachment: Projectile particleId: death-dart diff --git a/game_data/spells/enhance_strength.yaml b/game_data/spells/enhance_strength.yaml index fe9e9a3..986d255 100644 --- a/game_data/spells/enhance_strength.yaml +++ b/game_data/spells/enhance_strength.yaml @@ -11,14 +11,13 @@ data: name: Enhance Strength description: Enhance the strength of the target (typically the caster). manaCost: 2 - castSlot: secondary - castTime: 0 + castType: Instant + castSlot: Slot cooldown: .10 - magic: enhancement - spellTier: 0 - flags: - - buff - castType: instant - castCategory: onSelf spriteTileset: tileset/spell_icons.png spriteIndex: 0 + talisman: + shaping: OnSelf + behavior: Buff + tier: Mundane + skill: Ampiliomancy diff --git a/game_data/spells/fire_bolt.yaml b/game_data/spells/fire_bolt.yaml index 55a2797..95b44af 100644 --- a/game_data/spells/fire_bolt.yaml +++ b/game_data/spells/fire_bolt.yaml @@ -10,15 +10,14 @@ header: data: name: Fire Bolt description: Propel a mote of flame at your target. - manaCost: 0 - spellTier: 0 - magic: fire - castSlot: primary - castTime: 0 + castSlot: Cantrip cooldown: 1.50 spriteTileset: spell_projectiles spriteIndex: 2 - flags: - - projectile - castType: instant - castCategory: projectile + castType: Instant + talisman: + shaping: Projectile + behavior: Damage + tier: Common + baseDamage: 2 + skill: Pyromancy diff --git a/game_data/spells/fire_pillar.yaml b/game_data/spells/fire_pillar.yaml index 3abba9c..0fdb777 100644 --- a/game_data/spells/fire_pillar.yaml +++ b/game_data/spells/fire_pillar.yaml @@ -11,14 +11,13 @@ data: name: Fire Pillar description: Create a pillar of flames at the target location. manaCost: 2 - castSlot: secondary - castTime: 0 + castSlot: Slot cooldown: 3.30 - magic: fire - spellTier: 2 - flags: - - wall - castType: instant - castCategory: ground + castType: Instant spriteTileset: tileset/ground_effects.png spriteIndex: 0 + talisman: + shaping: AreaOfEffect + behavior: Utility + tier: Uncommon + skill: Pyromancy diff --git a/game_data/spells/fireball.yaml b/game_data/spells/fireball.yaml index 0a589ec..560042f 100644 --- a/game_data/spells/fireball.yaml +++ b/game_data/spells/fireball.yaml @@ -11,8 +11,13 @@ data: name: Fireball description: Launch a ball of fire that explodes on contact. manaCost: 3 - castSlot: secondary - castTime: 0 + castSlot: Slot cooldown: 5 - magic: fire - spellTier: 3 + talisman: + shaping: Projectile + behavior: Damage + tier: Uncommon + skill: Pyromancy + castType: Instant + spriteTileset: placeholder + spriteIndex: 0 diff --git a/game_data/spells/flame_burst.yaml b/game_data/spells/flame_burst.yaml index ac2b9d7..55a19dc 100644 --- a/game_data/spells/flame_burst.yaml +++ b/game_data/spells/flame_burst.yaml @@ -10,12 +10,15 @@ header: data: name: Flame Burst description: Send a cloud of flame towards your target - castSlot: secondary + castSlot: Slot spellTier: 1 manaCost: 1 - castTime: 0 cooldown: 3 - magic: fire - tags: - - cone - - aoe + talisman: + shaping: Cone + behavior: Damage + tier: Common + skill: Pyromancy + castType: Instant + spriteTileset: placeholder + spriteIndex: 0 diff --git a/game_data/spells/flamethrower.yaml b/game_data/spells/flamethrower.yaml index b0168a0..53aa9fb 100644 --- a/game_data/spells/flamethrower.yaml +++ b/game_data/spells/flamethrower.yaml @@ -10,13 +10,15 @@ header: data: name: Flamethrower description: Sustain a fiery stream of flames. - magic: fire - spellTier: 2 + talisman: + shaping: Line + behavior: Damage + tier: Uncommon + skill: Pyromancy + castType: Channel + spriteTileset: placeholder + spriteIndex: 0 cooldown: 5.00 castTime: 1.50 manaCost: 1 - castSlot: secondary - flags: - - sustained - - line - - aoe + castSlot: Slot diff --git a/game_data/spells/flash.yaml b/game_data/spells/flash.yaml index 05bf5c6..7be63b1 100644 --- a/game_data/spells/flash.yaml +++ b/game_data/spells/flash.yaml @@ -10,9 +10,13 @@ header: data: name: Flash description: Create a blinding flash of light. - manaCost: 0 - castSlot: secondary - castTime: 0 + castSlot: Slot cooldown: 3.50 - magic: light - spellTier: 0 + talisman: + shaping: AreaOfEffect + behavior: Utility + tier: Mundane + skill: Photomancy + castType: Instant + spriteTileset: placeholder + spriteIndex: 0 diff --git a/game_data/spells/freeze_ray.yaml b/game_data/spells/freeze_ray.yaml index 7470d66..992cf0d 100644 --- a/game_data/spells/freeze_ray.yaml +++ b/game_data/spells/freeze_ray.yaml @@ -10,9 +10,15 @@ header: data: name: Freeze Ray description: Launch a ray of freezing magic towards your target. + talisman: + shaping: Line + behavior: Damage + tier: Uncommon + skill: Cryomancy + castType: Cast + spriteTileset: placeholder + spriteIndex: 0 manaCost: 2 - castSlot: secondary + castSlot: Slot castTime: 5.0 cooldown: 3.00 - magic: ice - spellTier: 2 diff --git a/game_data/spells/geyser.yaml b/game_data/spells/geyser.yaml index 9799e92..8cf9948 100644 --- a/game_data/spells/geyser.yaml +++ b/game_data/spells/geyser.yaml @@ -11,9 +11,14 @@ data: name: Geyser description: Cause a geyser of scalding water to erupt. manaCost: 3 - castSlot: secondary + castSlot: Slot castTime: .15 cooldown: 5.00 - castType: cast - magic: water - spellTier: 3 + castType: Cast + talisman: + shaping: AreaOfEffect + behavior: Utility + tier: Uncommon + skill: Hydromancy + spriteTileset: placeholder + spriteIndex: 0 diff --git a/game_data/spells/gust.yaml b/game_data/spells/gust.yaml index ba61a74..dbbf196 100644 --- a/game_data/spells/gust.yaml +++ b/game_data/spells/gust.yaml @@ -10,11 +10,13 @@ header: data: name: Gust description: Shoot a gust of air at the target. - manaCost: 0 - castSlot: primary - castTime: 0 + castSlot: Cantrip cooldown: 5.0 - magic: air - spellTier: 0 spriteTileset: spell_projectiles spriteIndex: 3 + talisman: + shaping: Projectile + behavior: Damage + tier: Mundane + skill: Aeromancy + castType: Instant diff --git a/game_data/spells/ice_dart.yaml b/game_data/spells/ice_dart.yaml index 691f916..1039669 100644 --- a/game_data/spells/ice_dart.yaml +++ b/game_data/spells/ice_dart.yaml @@ -10,17 +10,16 @@ header: data: name: Ice Dart description: Shoot a dart of ice at your target. - manaCost: 0 - castSlot: primary - castTime: 0 cooldown: .33 - magic: ice - spellTier: 0 spriteTileset: spell_projectiles spriteIndex: 4 - flags: [] - castType: instant - castCategory: projectile + talisman: + shaping: Projectile + behavior: Damage + tier: Mundane + skill: Cryomancy + castSlot: Cantrip + castType: Instant particles: - attachment: Projectile particleId: ice-dart diff --git a/game_data/spells/ice_patch.yaml b/game_data/spells/ice_patch.yaml index a3226e8..6f0a876 100644 --- a/game_data/spells/ice_patch.yaml +++ b/game_data/spells/ice_patch.yaml @@ -11,9 +11,14 @@ data: name: Ice Patch description: Conjure a sheet of ice on the ground. manaCost: 3 - castSlot: secondary + castSlot: Slot castTime: .25 cooldown: 6.00 - castType: cast - magic: ice - spellTier: 3 + castType: Cast + talisman: + shaping: AreaOfEffect + behavior: Debuff + tier: Rare + skill: Cryomancy + spriteTileset: placeholder + spriteIndex: 0 diff --git a/game_data/spells/ice_pillar.yaml b/game_data/spells/ice_pillar.yaml index 858cfbd..b300249 100644 --- a/game_data/spells/ice_pillar.yaml +++ b/game_data/spells/ice_pillar.yaml @@ -10,14 +10,16 @@ header: data: name: Ice Pillar description: A frozen pillar of ice forms at a target location. - castSlot: secondary + castSlot: Slot castTime: 1 cooldown: 5 manaCost: 1 + talisman: + shaping: AreaOfEffect + behavior: Utility + tier: Uncommon + skill: Cryomancy + castType: Cast + spriteTileset: placeholder + spriteIndex: 0 spellTier: 1 - magic: ice - flags: - - target - - aoe - - ground - - wall diff --git a/game_data/spells/ice_spike.yaml b/game_data/spells/ice_spike.yaml index e86dd48..64cbd98 100644 --- a/game_data/spells/ice_spike.yaml +++ b/game_data/spells/ice_spike.yaml @@ -11,12 +11,17 @@ data: name: Ice Spike description: Launch a spike of ice at your target. manaCost: 2 - castSlot: secondary - castTime: 0 + castSlot: Slot cooldown: 5 - magic: ice - spellTier: 3 - long_description: >- + talisman: + shaping: Projectile + behavior: Damage + tier: Rare + skill: Cryomancy + castType: Instant + spriteTileset: placeholder + spriteIndex: 0 + lore: >- Launch a wickedly sharp spike of ice towards your target. In practice, the spike has such momentum to be able to go straight through your practice target. diff --git a/game_data/spells/lightning_ball.yaml b/game_data/spells/lightning_ball.yaml index 1e6a8d3..969e401 100644 --- a/game_data/spells/lightning_ball.yaml +++ b/game_data/spells/lightning_ball.yaml @@ -10,10 +10,14 @@ header: data: name: Lightning Ball description: Launch a ball of pure lightning towards a target. - manaCost: 0 - castSlot: primary - castTime: 0 + castSlot: Slot cooldown: 1.75 - magic: lightning - spellTier: 3 long_description: As the ball travels it will launch a lightning bolt at the closest target to it up to 4 times before its exhausted. + talisman: + shaping: Projectile + behavior: Damage + tier: Rare + skill: Fulgomancy + castType: Instant + spriteTileset: placeholder + spriteIndex: 0 diff --git a/game_data/spells/lightning_bolt.yaml b/game_data/spells/lightning_bolt.yaml index 4aefa03..562c74f 100644 --- a/game_data/spells/lightning_bolt.yaml +++ b/game_data/spells/lightning_bolt.yaml @@ -10,11 +10,13 @@ header: data: name: Lightning Bolt description: Shoot a bolt of lightning at a target. - manaCost: 0 - castSlot: primary - castTime: 0 + castSlot: Cantrip cooldown: 1 - magic: lightning - spellTier: 1 spriteTileset: spell_projectiles spriteIndex: 9 + talisman: + shaping: Projectile + behavior: Damage + tier: Common + skill: Fulgomancy + castType: Instant diff --git a/game_data/spells/lightning_storm.yaml b/game_data/spells/lightning_storm.yaml index a24b7f1..3659239 100644 --- a/game_data/spells/lightning_storm.yaml +++ b/game_data/spells/lightning_storm.yaml @@ -11,9 +11,14 @@ data: name: Lightning Storm description: Create a localized storm of lightning at a target location. manaCost: 2 - castSlot: secondary - castTime: 0 + castSlot: Slot cooldown: 4 - magic: lightning - spellTier: 2 long_description: Constantly has lightning coming down for a short duration. + talisman: + shaping: AreaOfEffect + behavior: Damage + tier: Uncommon + skill: Fulgomancy + castType: Instant + spriteTileset: placeholder + spriteIndex: 0 diff --git a/game_data/spells/magic_mirror.yaml b/game_data/spells/magic_mirror.yaml index dbc21fd..978025c 100644 --- a/game_data/spells/magic_mirror.yaml +++ b/game_data/spells/magic_mirror.yaml @@ -11,8 +11,13 @@ data: name: Magic Mirror description: Create a wall of arcane energy which negates magic that passes through it. manaCost: 1 - castSlot: secondary - castTime: 0 + castSlot: Slot cooldown: 4.25 - magic: arcane - spellTier: 0 + talisman: + shaping: AreaOfEffect + behavior: Utility + tier: Common + skill: Arcanomancy + castType: Instant + spriteTileset: placeholder + spriteIndex: 0 diff --git a/game_data/spells/magic_missile.yaml b/game_data/spells/magic_missile.yaml index 78c912c..0148e55 100644 --- a/game_data/spells/magic_missile.yaml +++ b/game_data/spells/magic_missile.yaml @@ -10,11 +10,13 @@ header: data: name: Magic Missile description: Shoot a magic missile at the target. - manaCost: 0 - castSlot: primary - castTime: 0 cooldown: .25 - magic: force - spellTier: 0 spriteTileset: spell_projectiles spriteIndex: 6 + talisman: + shaping: Projectile + behavior: Damage + tier: Mundane + skill: Arcanomancy + castSlot: Cantrip + castType: Instant diff --git a/game_data/spells/mana_dart.yaml b/game_data/spells/mana_dart.yaml index 5a953ac..be38723 100644 --- a/game_data/spells/mana_dart.yaml +++ b/game_data/spells/mana_dart.yaml @@ -11,11 +11,14 @@ data: name: Mana Dart description: Shoot a dart of compressed mana at the target. manaCost: 1 - castSlot: primary - castTime: 0 cooldown: .10 - magic: arcane - spellTier: 0 - long_description: It takes mana to make mana. + lore: It takes mana to make mana. spriteTileset: spell_projectiles spriteIndex: 7 + talisman: + shaping: Projectile + behavior: Damage + tier: Mundane + skill: Arcanomancy + castSlot: Cantrip + castType: Instant diff --git a/game_data/spells/mini_black_hole.yaml b/game_data/spells/mini_black_hole.yaml index 6043ab7..f2887bf 100644 --- a/game_data/spells/mini_black_hole.yaml +++ b/game_data/spells/mini_black_hole.yaml @@ -11,12 +11,15 @@ data: name: Miniature Black Hole description: Launch a magically stable, miniature black hole towards a target. manaCost: 2 - castSlot: secondary - castTime: 0 + castSlot: Slot cooldown: 5.75 - magic: dark - spellTier: 3 spriteTileset: spell_projectiles spriteIndex: 0 - long_description: + lore: As the black hole travels, the area it affects becomes larger and larger. Though magically stable, it can also affect the caster. + talisman: + shaping: Projectile + behavior: Damage + tier: Uncommon + skill: Umbramancy + castType: Instant diff --git a/game_data/spells/mud_splatter.yaml b/game_data/spells/mud_splatter.yaml index 03793a0..95c35e3 100644 --- a/game_data/spells/mud_splatter.yaml +++ b/game_data/spells/mud_splatter.yaml @@ -11,8 +11,13 @@ data: name: Mud Splatter description: Launch a bunch of mud and rocks towards the target. manaCost: 2 - castSlot: secondary - castTime: 0 cooldown: 5 - magic: earth - spellTier: 3 + talisman: + shaping: Projectile + behavior: Damage + tier: Uncommon + skill: Geomancy + castSlot: Slot + castType: Instant + spriteTileset: placeholder + spriteIndex: 0 diff --git a/game_data/spells/nature_bolt.yaml b/game_data/spells/nature_bolt.yaml index 12d187c..d3de26e 100644 --- a/game_data/spells/nature_bolt.yaml +++ b/game_data/spells/nature_bolt.yaml @@ -10,11 +10,13 @@ header: data: name: Nature Bolt description: Shoot a bundle of razor sharp leaves at the target. - manaCost: 0 - castSlot: primary - castTime: 0 cooldown: 5.0 - magic: life - spellTier: 0 spriteTileset: spell_projectiles spriteIndex: 8 + talisman: + shaping: Projectile + behavior: Damage + tier: Mundane + skill: Vitomancy + castSlot: Cantrip + castType: Instant diff --git a/game_data/spells/overgrowth.yaml b/game_data/spells/overgrowth.yaml index cb158dd..bae3d99 100644 --- a/game_data/spells/overgrowth.yaml +++ b/game_data/spells/overgrowth.yaml @@ -11,9 +11,14 @@ data: name: Overgrown description: Grow a wall of plants at the target location. manaCost: 2 - castSlot: secondary + castSlot: Slot castTime: .15 cooldown: 4.00 - castType: cast - magic: life - spellTier: 0 + castType: Cast + talisman: + shaping: AreaOfEffect + behavior: Utility + tier: Mundane + skill: Vitomancy + spriteTileset: placeholder + spriteIndex: 0 diff --git a/game_data/spells/path_of_coals.yaml b/game_data/spells/path_of_coals.yaml index 24caf4d..37f0cd4 100644 --- a/game_data/spells/path_of_coals.yaml +++ b/game_data/spells/path_of_coals.yaml @@ -11,8 +11,13 @@ data: name: Path of Coals description: Create an area of burning hot coals on the ground. manaCost: 2 - castSlot: secondary - castTime: 0 + castSlot: Slot cooldown: 2.50 - magic: fire - spellTier: 2 + talisman: + shaping: AreaOfEffect + behavior: Damage + tier: Uncommon + skill: Pyromancy + castType: Instant + spriteTileset: placeholder + spriteIndex: 0 diff --git a/game_data/spells/quicksand.yaml b/game_data/spells/quicksand.yaml index 864a8af..ff7b38b 100644 --- a/game_data/spells/quicksand.yaml +++ b/game_data/spells/quicksand.yaml @@ -11,9 +11,14 @@ data: name: Quicksand description: Create an area of quicksand at the target location. manaCost: 4 - castSlot: secondary + castSlot: Slot castTime: .15 cooldown: 8.00 - castType: cast - magic: earth - spellTier: 4 + castType: Cast + talisman: + shaping: AreaOfEffect + behavior: Debuff + tier: Rare + skill: Geomancy + spriteTileset: placeholder + spriteIndex: 0 diff --git a/game_data/spells/reduce_strength.yaml b/game_data/spells/reduce_strength.yaml index 2133307..5b41004 100644 --- a/game_data/spells/reduce_strength.yaml +++ b/game_data/spells/reduce_strength.yaml @@ -11,8 +11,13 @@ data: name: Reduce Strength description: Reduce the strength of the target. manaCost: 2 - castSlot: secondary - castTime: 0 + castSlot: Slot cooldown: 5 - magic: reduction - spellTier: 0 + talisman: + shaping: Projectile + behavior: Debuff + tier: Common + skill: Diminiomancy + castType: Instant + spriteTileset: placeholder + spriteIndex: 0 diff --git a/game_data/spells/rock_pillar.yaml b/game_data/spells/rock_pillar.yaml index 0910170..1c7f683 100644 --- a/game_data/spells/rock_pillar.yaml +++ b/game_data/spells/rock_pillar.yaml @@ -11,8 +11,13 @@ data: name: Rock Pillar description: Summon a pillar of rock at the target location. manaCost: 2 - castSlot: secondary - castTime: 0 cooldown: 2.50 - magic: earth - spellTier: 2 + talisman: + shaping: AreaOfEffect + behavior: Utility + tier: Uncommon + skill: Geomancy + castSlot: Slot + castType: Instant + spriteTileset: placeholder + spriteIndex: 0 diff --git a/game_data/spells/snares.yaml b/game_data/spells/snares.yaml index ce6e27f..b94d711 100644 --- a/game_data/spells/snares.yaml +++ b/game_data/spells/snares.yaml @@ -9,11 +9,16 @@ header: validGameInternalVersion: 1 data: name: Snares - description: Create an area of excellerated root growth, ensnaring entities that walk through. + description: Create an area of accelerated root growth, ensnaring entities that walk through. manaCost: 3 - castSlot: secondary castTime: .15 cooldown: 5.00 - castType: cast - magic: life - spellTier: 1 + talisman: + shaping: AreaOfEffect + behavior: Debuff + tier: Rare + skill: Vitomancy + castSlot: Slot + castType: Instant + spriteTileset: placeholder + spriteIndex: 0 diff --git a/game_data/spells/spark.yaml b/game_data/spells/spark.yaml index 76c6f94..ae8d694 100644 --- a/game_data/spells/spark.yaml +++ b/game_data/spells/spark.yaml @@ -10,20 +10,16 @@ header: data: name: Spark description: Shoot a spark of electricity at your target. - spellTier: 0 - magic: lightning - castSlot: primary - manaCost: 0 - castTime: 0 + castSlot: Cantrip cooldown: 2.50 - flags: - - instant - - target - - homing + talisman: + shaping: Projectile + behavior: Damage + tier: Mundane + skill: Fulgomancy spriteTileset: spell_projectiles spriteIndex: 9 - castCategory: projectile - castType: instant + castType: Instant particles: - attachment: Projectile particleId: spark diff --git a/game_data/spells/stone_dart.yaml b/game_data/spells/stone_dart.yaml index ec9c649..1b9749c 100644 --- a/game_data/spells/stone_dart.yaml +++ b/game_data/spells/stone_dart.yaml @@ -10,11 +10,13 @@ header: data: name: Stone Dart description: Shoot a dart of rock at your target. - manaCost: 0 - castSlot: primary - castTime: 0 cooldown: .33 - magic: earth - spellTier: 0 spriteTileset: spell_projectiles spriteIndex: 10 + talisman: + shaping: Projectile + behavior: Damage + tier: Mundane + skill: Geomancy + castSlot: Cantrip + castType: Instant diff --git a/game_data/spells/summon_imp.yaml b/game_data/spells/summon_imp.yaml index 18ab676..9176417 100644 --- a/game_data/spells/summon_imp.yaml +++ b/game_data/spells/summon_imp.yaml @@ -11,8 +11,13 @@ data: name: Summon Imp description: Summon an imp to fight for you. manaCost: 1 - castSlot: primary - castTime: 0 cooldown: 2 - magic: summoning - spellTier: 0 + talisman: + shaping: OnSelf + behavior: Summon + tier: Mundane + skill: Citomancy + castSlot: Cantrip + castType: Instant + spriteTileset: placeholder + spriteIndex: 0 diff --git a/game_data/spells/summon_undead.yaml b/game_data/spells/summon_undead.yaml index 9c10d22..f55b39a 100644 --- a/game_data/spells/summon_undead.yaml +++ b/game_data/spells/summon_undead.yaml @@ -10,9 +10,13 @@ header: data: name: Summon Undead (Basic) description: Summon a random basic-tier undead at a location. - manaCost: 0 - castSlot: primary - castTime: 0 cooldown: 5 - magic: necromancy - spellTier: 0 + talisman: + shaping: OnSelf + behavior: Summon + tier: Mundane + skill: Necromancy + castSlot: Cantrip + castType: Instant + spriteTileset: placeholder + spriteIndex: 0 diff --git a/game_data/spells/tornado.yaml b/game_data/spells/tornado.yaml index 6d9f45f..aadc4f5 100644 --- a/game_data/spells/tornado.yaml +++ b/game_data/spells/tornado.yaml @@ -11,9 +11,14 @@ data: name: Tornado description: Summon a tornado at the target location. manaCost: 2 - castSlot: secondary + castSlot: Slot castTime: 5.0 cooldown: 5.00 - castType: cast - magic: air - spellTier: 2 + castType: Cast + talisman: + shaping: AreaOfEffect + behavior: Damage + tier: Rare + skill: Aeromancy + spriteTileset: placeholder + spriteIndex: 0 diff --git a/game_data/spells/transform_into_ogre.yaml b/game_data/spells/transform_into_ogre.yaml index d3d2d2e..3f29128 100644 --- a/game_data/spells/transform_into_ogre.yaml +++ b/game_data/spells/transform_into_ogre.yaml @@ -11,8 +11,13 @@ data: name: Transform into Ogre description: Polymorph yourself into an ogre. manaCost: 4 - castSlot: secondary - castTime: 0 + castSlot: Slot cooldown: .20 - magic: polymorph - spellTier: 0 + talisman: + shaping: OnSelf + behavior: Buff + tier: Uncommon + skill: Mutatiomancy + castType: Instant + spriteTileset: placeholder + spriteIndex: 0 diff --git a/game_data/spells/undead_zone.yaml b/game_data/spells/undead_zone.yaml index a1f66fa..9d05420 100644 --- a/game_data/spells/undead_zone.yaml +++ b/game_data/spells/undead_zone.yaml @@ -11,8 +11,14 @@ data: name: Zone of Undeath description: Create an area with a necrotic area. Enemies that die within have a chance to turn into your undead. manaCost: 3 - castSlot: secondary castTime: 1 cooldown: 7 - magic: necromancy - spellTier: 3 + talisman: + shaping: AreaOfEffect + behavior: Debuff + tier: Uncommon + skill: Necromancy + castSlot: Slot + castType: Cast + spriteTileset: placeholder + spriteIndex: 0 diff --git a/game_data/spells/updrafts.yaml b/game_data/spells/updrafts.yaml index aee6872..4c12d0e 100644 --- a/game_data/spells/updrafts.yaml +++ b/game_data/spells/updrafts.yaml @@ -11,9 +11,14 @@ data: name: Updraft description: Create an area with a strong updraft. manaCost: 3 - castSlot: secondary - castTime: 0 cooldown: 6 - magic: air - spellTier: 3 - long_description: Entities entering the updraft area are buffeted upward and move slowly through it. Caster gets a speed boost. + lore: Entities entering the updraft area are buffeted upward and move slowly through it. Caster gets a speed boost. + talisman: + shaping: AreaOfEffect + behavior: Debuff + tier: Uncommon + skill: Aeromancy + castSlot: Slot + castType: Instant + spriteTileset: placeholder + spriteIndex: 0 diff --git a/game_data/spells/vine_whip.yaml b/game_data/spells/vine_whip.yaml index 0172f7f..2385911 100644 --- a/game_data/spells/vine_whip.yaml +++ b/game_data/spells/vine_whip.yaml @@ -10,10 +10,14 @@ header: data: name: Vine Whip description: Create a vine and whip it towards the target. - manaCost: 0 - castSlot: primary - castTime: 0 cooldown: 1.25 - magic: life - spellTier: 1 - long_description: Can be whipped up to 3 times. + lore: Can be whipped up to 3 times. + talisman: + shaping: Melee + behavior: Damage + tier: Mundane + skill: Vitomancy + castSlot: Cantrip + castType: Instant + spriteTileset: placeholder + spriteIndex: 0 diff --git a/game_data/spells/water_bolt.yaml b/game_data/spells/water_bolt.yaml index 5d19f4f..1ad54a2 100644 --- a/game_data/spells/water_bolt.yaml +++ b/game_data/spells/water_bolt.yaml @@ -10,17 +10,16 @@ header: data: name: Water Bolt description: Send a glob of water at your target. - manaCost: 0 - castSlot: primary - castTime: 0 cooldown: 2 - magic: water - spellTier: 0 spriteTileset: spell_projectiles spriteIndex: 12 - flags: [] - castType: instant - castCategory: projectile + talisman: + shaping: Projectile + behavior: Damage + tier: Mundane + skill: Hydromancy + castSlot: Cantrip + castType: Instant particles: - attachment: Projectile particleId: water-bolt diff --git a/game_data/spells/water_jet.yaml b/game_data/spells/water_jet.yaml index 3c2591c..63154d4 100644 --- a/game_data/spells/water_jet.yaml +++ b/game_data/spells/water_jet.yaml @@ -11,8 +11,13 @@ data: name: Water Jet description: Spray a powerful jet of water at your target. manaCost: 1 - castSlot: secondary - castTime: 0 cooldown: 2.50 - magic: water - spellTier: 2 + talisman: + shaping: Cone + behavior: Damage + tier: Uncommon + skill: Hydromancy + castSlot: Slot + castType: Instant + spriteTileset: placeholder + spriteIndex: 0 diff --git a/game_data/spells/whirlpool.yaml b/game_data/spells/whirlpool.yaml index fce395c..5ad4364 100644 --- a/game_data/spells/whirlpool.yaml +++ b/game_data/spells/whirlpool.yaml @@ -11,8 +11,13 @@ data: name: Whirlpool description: Create a whirlpool that pulls those stuck in it towards it center. manaCost: 3 - castSlot: defensive - castTime: 0 cooldown: 8 - magic: water - spellTier: 2 + talisman: + shaping: AreaOfEffect + behavior: Debuff + tier: Uncommon + skill: Hydromancy + castSlot: Slot + castType: Instant + spriteTileset: placeholder + spriteIndex: 0 diff --git a/game_data/spells/wind.yaml b/game_data/spells/wind.yaml index e439177..005678b 100644 --- a/game_data/spells/wind.yaml +++ b/game_data/spells/wind.yaml @@ -11,8 +11,14 @@ data: name: Wind description: Sustain a gust of wind away from the caster. manaCost: 1 - castSlot: secondary - castTime: 0 + castTime: 0.5 cooldown: 2.50 - magic: air - spellTier: 1 + talisman: + shaping: Cone + behavior: Damage + tier: Uncommon + skill: Aeromancy + castSlot: Slot + castType: Channel + spriteTileset: placeholder + spriteIndex: 0 diff --git a/game_data/spells/zone_of_charm.yaml b/game_data/spells/zone_of_charm.yaml index b1fbf99..2dc3105 100644 --- a/game_data/spells/zone_of_charm.yaml +++ b/game_data/spells/zone_of_charm.yaml @@ -11,12 +11,17 @@ data: name: Zone of Charming description: Create an area with an aura of charm magic at the target location. manaCost: 3 - castSlot: secondary + castSlot: Slot castTime: .25 cooldown: 5.00 - castType: cast - magic: arcane - spellTier: 3 - long_description: + castType: Cast + talisman: + shaping: AreaOfEffect + behavior: Debuff + tier: Rare + skill: Arcanomancy + spriteTileset: placeholder + spriteIndex: 0 + lore: Entities already in the zone when it's cast become charmed instantly, fighting for the caster. Entities entering after the zone has been created take a bit of time before becoming charmed. From 1188f7af91e4c96faa13c64d20e4aeda6bc5ca4b Mon Sep 17 00:00:00 2001 From: Nick Westerhausen <2317381+nwesterhausen@users.noreply.github.com> Date: Sun, 25 Feb 2024 15:01:29 -0500 Subject: [PATCH 15/51] fix: don't use camel case for enum serialization --- Cargo.lock | 2 +- game_library/Cargo.toml | 2 +- game_library/src/enums/cast_slot.rs | 1 - game_library/src/enums/cast_type.rs | 1 - game_library/src/enums/skill.rs | 1 - 5 files changed, 2 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2a314c2..69e0df0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2169,7 +2169,7 @@ dependencies = [ [[package]] name = "game_library" -version = "2.1.0" +version = "2.1.1" dependencies = [ "bevy", "bevy-inspector-egui", diff --git a/game_library/Cargo.toml b/game_library/Cargo.toml index 44489f5..53e1687 100644 --- a/game_library/Cargo.toml +++ b/game_library/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "game_library" -version = "2.1.0" +version = "2.1.1" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/game_library/src/enums/cast_slot.rs b/game_library/src/enums/cast_slot.rs index 10fd049..e2a8c0e 100644 --- a/game_library/src/enums/cast_slot.rs +++ b/game_library/src/enums/cast_slot.rs @@ -8,7 +8,6 @@ use serde::{Deserialize, Serialize}; #[derive( Debug, Clone, Copy, PartialEq, Eq, Hash, Component, Resource, Serialize, Deserialize, Reflect, )] -#[serde(rename_all = "camelCase")] pub enum CastSlot { /// Cantrips are typically basic attacks that don't cost mana and are a player's primary means /// of dealing damage. They are typically the most spammable spell in a player's arsenal. diff --git a/game_library/src/enums/cast_type.rs b/game_library/src/enums/cast_type.rs index b1fd19c..529aa30 100644 --- a/game_library/src/enums/cast_type.rs +++ b/game_library/src/enums/cast_type.rs @@ -8,7 +8,6 @@ use serde::{Deserialize, Serialize}; #[derive( Debug, Clone, Copy, PartialEq, Eq, Hash, Component, Resource, Serialize, Deserialize, Reflect, )] -#[serde(rename_all = "camelCase")] pub enum CastType { /// The spell is cast instantly Instant, diff --git a/game_library/src/enums/skill.rs b/game_library/src/enums/skill.rs index e9cbbf1..7222dbe 100644 --- a/game_library/src/enums/skill.rs +++ b/game_library/src/enums/skill.rs @@ -27,7 +27,6 @@ use crate::enums::MagicType; Reflect, InspectorOptions, )] -#[serde(rename_all = "camelCase")] pub enum Skill { /// Pyromancy is the school of fire magic. Pyromancy, From 7bbb74927e4f3390f71ca573d9111e1d3fdbd428 Mon Sep 17 00:00:00 2001 From: Nick Westerhausen <2317381+nwesterhausen@users.noreply.github.com> Date: Tue, 27 Feb 2024 08:43:02 -0500 Subject: [PATCH 16/51] feat: add animation system to game_library --- Cargo.lock | 4 +- game/src/game_overlays/skill_book.rs | 7 +- game_data/_schemas/animation_state.json | 65 ++++++++++ game_data/_schemas/entity_sprite.json | 17 +++ game_data/_schemas/game_system.json | 4 + game_data/_schemas/sprite.json | 21 ++++ game_data/_schemas/sprite_animation.json | 35 ++++++ game_data/sprites/player.yml | 37 ++++++ game_library/Cargo.toml | 4 +- .../src/data_loader/entity_sprites.rs | 19 +++ game_library/src/data_loader/events.rs | 10 +- game_library/src/data_loader/loader.rs | 29 ++++- game_library/src/data_loader/mod.rs | 1 + game_library/src/data_loader/plugin.rs | 9 +- game_library/src/data_loader/storage.rs | 18 ++- game_library/src/data_loader/tilesets.rs | 7 +- game_library/src/enums/game_systems.rs | 14 ++- game_library/src/images/animation.rs | 90 ++++++++++++++ game_library/src/images/animation_bundle.rs | 41 +++++++ game_library/src/images/animation_frame.rs | 54 +++++++++ game_library/src/images/animation_system.rs | 69 +++++++++++ game_library/src/images/animation_timer.rs | 112 ++++++++++++++++++ game_library/src/images/entity_sprite.rs | 108 +++++++++++++++++ game_library/src/images/mod.rs | 20 ++++ game_library/src/images/plugin.rs | 20 ++++ game_library/src/images/texture_atlas.rs | 12 ++ game_library/src/{ => images}/tileset.rs | 2 + game_library/src/lib.rs | 4 +- game_library/src/spells/mod.rs | 2 + game_library/src/spells/polymorph.rs | 53 +++++++++ 30 files changed, 849 insertions(+), 39 deletions(-) create mode 100644 game_data/_schemas/animation_state.json create mode 100644 game_data/_schemas/entity_sprite.json create mode 100644 game_data/_schemas/sprite.json create mode 100644 game_data/_schemas/sprite_animation.json create mode 100644 game_data/sprites/player.yml create mode 100644 game_library/src/data_loader/entity_sprites.rs create mode 100644 game_library/src/images/animation.rs create mode 100644 game_library/src/images/animation_bundle.rs create mode 100644 game_library/src/images/animation_frame.rs create mode 100644 game_library/src/images/animation_system.rs create mode 100644 game_library/src/images/animation_timer.rs create mode 100644 game_library/src/images/entity_sprite.rs create mode 100644 game_library/src/images/mod.rs create mode 100644 game_library/src/images/plugin.rs create mode 100644 game_library/src/images/texture_atlas.rs rename game_library/src/{ => images}/tileset.rs (98%) create mode 100644 game_library/src/spells/polymorph.rs diff --git a/Cargo.lock b/Cargo.lock index 69e0df0..1415ffe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -839,7 +839,7 @@ dependencies = [ [[package]] name = "bevy_pkv" version = "0.9.1" -source = "git+https://github.com/johanhelsing/bevy_pkv#af0b750b1dbfc8db58dbb2bd07c5eda72e714b79#af0b750b1dbfc8db58dbb2bd07c5eda72e714b79" +source = "git+https://github.com/johanhelsing/bevy_pkv?rev=af0b750b1dbfc8db58dbb2bd07c5eda72e714b79#af0b750b1dbfc8db58dbb2bd07c5eda72e714b79" dependencies = [ "bevy_ecs", "cfg_aliases", @@ -2169,7 +2169,7 @@ dependencies = [ [[package]] name = "game_library" -version = "2.1.1" +version = "2.2.0" dependencies = [ "bevy", "bevy-inspector-egui", diff --git a/game/src/game_overlays/skill_book.rs b/game/src/game_overlays/skill_book.rs index b378301..9093579 100644 --- a/game/src/game_overlays/skill_book.rs +++ b/game/src/game_overlays/skill_book.rs @@ -1,11 +1,8 @@ //! The skill book UI overlay. use bevy::prelude::*; use game_library::{ - colors, - data_loader::storage::{GameData, StoredTextureAtlas}, - enums::Skill, - font_resource::FontResource, - state::Overlay, + colors, data_loader::storage::GameData, enums::Skill, font_resource::FontResource, + images::StoredTextureAtlas, state::Overlay, }; pub struct SkillBookUiPlugin; diff --git a/game_data/_schemas/animation_state.json b/game_data/_schemas/animation_state.json new file mode 100644 index 0000000..7e2b0d0 --- /dev/null +++ b/game_data/_schemas/animation_state.json @@ -0,0 +1,65 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.nwest.one/games/elementalist/animation_state.json", + "title": "Elementalist Sprite Animation State", + "description": "An available state of an animation for an elementalist sprite", + "type": "string", + "oneOf": [ + { + "const": "Idle", + "description": "The idle animation" + }, + { + "const": "Walk", + "description": "The walking animation" + }, + { + "const": "Run", + "description": "The running animation" + }, + { + "const": "Jump", + "description": "The jumping animation" + }, + { + "const": "Cast", + "description": "The casting animation" + }, + { + "const": "Attack", + "description": "The attacking animation" + }, + { + "const": "WalkCast", + "description": "The casting animation that occurs while walking" + }, + { + "const": "WalkAttack", + "description": "The attacking animation that occurs while walking" + }, + { + "const": "RunCast", + "description": "The casting animation that occurs while running" + }, + { + "const": "RunAttack", + "description": "The attacking animation that occurs while running" + }, + { + "const": "Death", + "description": "The death animation" + }, + { + "const": "Hurt", + "description": "The hurt animation" + }, + { + "const": "Stun", + "description": "The stunned animation" + }, + { + "const": "Dead", + "description": "The dead animation (for when the character is dead)" + } + ] +} diff --git a/game_data/_schemas/entity_sprite.json b/game_data/_schemas/entity_sprite.json new file mode 100644 index 0000000..6e40cb1 --- /dev/null +++ b/game_data/_schemas/entity_sprite.json @@ -0,0 +1,17 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.nwest.one/games/elementalist/entity_sprite.json", + "title": "Elementalist Entity Sprite Schema", + "description": "Definition of an entity sprite for the Elementalist game", + "type": "object", + "properties": { + "animations": { + "title": "Animation Definitions", + "description": "Animations for the sprite", + "type": "array", + "items": { + "$ref": "https://schemas.nwest.one/games/elementalist/sprite_animation.json" + } + } + } +} diff --git a/game_data/_schemas/game_system.json b/game_data/_schemas/game_system.json index 0f3eaa1..13e739e 100644 --- a/game_data/_schemas/game_system.json +++ b/game_data/_schemas/game_system.json @@ -24,6 +24,10 @@ { "const": "SimpleObject", "title": "A simple object that can be placed in a realm" + }, + { + "const": "EntitySprite", + "title": "A sprite that can be used to represent an entity. Includes animations and other visual effects" } ] } diff --git a/game_data/_schemas/sprite.json b/game_data/_schemas/sprite.json new file mode 100644 index 0000000..5dc961d --- /dev/null +++ b/game_data/_schemas/sprite.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.nwest.one/games/elementalist/sprite.json", + "title": "Elementalist Sprite Schema", + "description": "A sprite describes the animations and appearance of a game object.", + "type": "object", + "properties": { + "header": { + "description": "Metadata about the sprite", + "$ref": "https://schemas.nwest.one/games/elementalist/header.json" + }, + "data": { + "description": "The sprite data", + "$ref": "https://schemas.nwest.one/games/elementalist/entity_sprite.json" + } + }, + "required": [ + "header", + "data" + ] +} diff --git a/game_data/_schemas/sprite_animation.json b/game_data/_schemas/sprite_animation.json new file mode 100644 index 0000000..04757ab --- /dev/null +++ b/game_data/_schemas/sprite_animation.json @@ -0,0 +1,35 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.nwest.one/games/elementalist/sprite_animation.json", + "title": "Elementalist Sprite Animation Schema", + "description": "An animation for use in a sprite sheet", + "type": "object", + "properties": { + "state": { + "title": "Animation State", + "description": "The state of animation this represents", + "$ref": "https://schemas.nwest.one/games/elementalist/animation_state.json" + }, + "tileset": { + "description": "The tileset to use for this animation, identified by its unique_id (from the tileset's header)", + "type": "string" + }, + "tileIndices": { + "description": "The indices of the tiles to use for this animation", + "type": "array", + "items": { + "type": "integer" + } + }, + "frameDuration": { + "description": "The duration of each frame in seconds", + "type": "number" + } + }, + "required": [ + "state", + "tileset", + "tileIndices", + "frameDuration" + ] +} diff --git a/game_data/sprites/player.yml b/game_data/sprites/player.yml new file mode 100644 index 0000000..4aa05e7 --- /dev/null +++ b/game_data/sprites/player.yml @@ -0,0 +1,37 @@ +# yaml-language-server: $schema=https://schemas.nwest.one/games/elementalist/sprite.json +header: + uniqueId: player-avatar + system: EntitySprite + author: Nicholas Westerhausen + description: The sprite animation details for the player's avatar + internalVersion: 1 + displayVersion: v1.0 + validGameInternalVersion: 1 +data: + animations: + - state: Idle + tileset: wizard + tileIndices: + - 3 + frameDuration: 0.1 + - state: Walk + tileset: wizard + tileIndices: + - 0 + - 1 + - 0 + - 2 + frameDuration: 0.1 + - state: Cast + tileset: wizard + tileIndices: + - 4 + frameDuration: 0.1 + - state: WalkCast + tileset: wizard + tileIndices: + - 5 + - 6 + - 7 + - 8 + frameDuration: 0.1 diff --git a/game_library/Cargo.toml b/game_library/Cargo.toml index 53e1687..ff4a294 100644 --- a/game_library/Cargo.toml +++ b/game_library/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "game_library" -version = "2.1.1" +version = "2.2.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -10,7 +10,7 @@ bevy = "0.13" bevy-inspector-egui = "0.23.2" bevy_hanabi = "0.10.0" # Local disk storage in a key-value store. Settings are stored with this. -bevy_pkv = { git = "https://github.com/johanhelsing/bevy_pkv#af0b750b1dbfc8db58dbb2bd07c5eda72e714b79" } +bevy_pkv = { git = "https://github.com/johanhelsing/bevy_pkv", rev = "af0b750b1dbfc8db58dbb2bd07c5eda72e714b79" } noise = "0.8.2" serde = "1.0.197" serde_default_utils = "0.2.1" diff --git a/game_library/src/data_loader/entity_sprites.rs b/game_library/src/data_loader/entity_sprites.rs new file mode 100644 index 0000000..1318e70 --- /dev/null +++ b/game_library/src/data_loader/entity_sprites.rs @@ -0,0 +1,19 @@ +//! Loads particles from the data files and stores them in the particle effect store. +use bevy::prelude::*; + +use super::{events::LoadedEntitySpriteData, storage::GameData}; + +/// System to load a particle effect. +pub(super) fn load_entity_sprites( + mut er_realm_df: EventReader, + mut game_data: ResMut, +) { + for data_file in er_realm_df.read() { + let unique_id = &data_file.entity_sprite_data.header.unique_id; + let entity_sprite = &data_file.entity_sprite_data.data; + + game_data + .entity_sprites + .insert(String::from(unique_id), entity_sprite.clone()); + } +} diff --git a/game_library/src/data_loader/events.rs b/game_library/src/data_loader/events.rs index efeecb9..9d4de24 100644 --- a/game_library/src/data_loader/events.rs +++ b/game_library/src/data_loader/events.rs @@ -9,7 +9,8 @@ use bevy::ecs::event::Event; use crate::{ - particle::Particle, realm_data::Realm, simple_object::SimpleObject, spells::Spell, Tileset, + images::EntitySprite, particle::Particle, realm_data::Realm, simple_object::SimpleObject, + spells::Spell, Tileset, }; use super::DataFile; @@ -48,3 +49,10 @@ pub struct LoadedSimpleObjectData { /// The realm data that was loaded. pub object_data: DataFile, } + +#[derive(Event)] +/// Event that is fired when an entity sprite is loaded. +pub struct LoadedEntitySpriteData { + /// The realm data that was loaded. + pub entity_sprite_data: DataFile, +} diff --git a/game_library/src/data_loader/loader.rs b/game_library/src/data_loader/loader.rs index eac2149..13f5b44 100644 --- a/game_library/src/data_loader/loader.rs +++ b/game_library/src/data_loader/loader.rs @@ -4,14 +4,14 @@ use std::hash::Hash; use walkdir::WalkDir; use crate::{ - data_loader::DATA_FILE_DIR, enums::GameSystem, particle::Particle, realm_data::Realm, - simple_object::SimpleObject, spells::Spell, InternalId, Tileset, + data_loader::DATA_FILE_DIR, enums::GameSystem, images::EntitySprite, particle::Particle, + realm_data::Realm, simple_object::SimpleObject, spells::Spell, InternalId, Tileset, }; use super::{ events::{ - LoadedParticleData, LoadedRealmData, LoadedSimpleObjectData, LoadedSpellData, - LoadedTilesetData, + LoadedEntitySpriteData, LoadedParticleData, LoadedRealmData, LoadedSimpleObjectData, + LoadedSpellData, LoadedTilesetData, }, header_def::{DataFile, DataFileHeader}, DataFileHeaderOnly, @@ -81,6 +81,7 @@ pub fn load_data_file_dir( mut ew_particle_df: EventWriter, mut ew_realm_df: EventWriter, mut ew_simple_object_df: EventWriter, + mut ew_entity_sprite_df: EventWriter, ) { // let start = std::time::Instant::now(); @@ -102,6 +103,7 @@ pub fn load_data_file_dir( let mut particles_read: usize = 0; let mut realms_read: usize = 0; let mut simple_objects_read: usize = 0; + let mut entity_sprites_read: usize = 0; for d in &mut possible_ingests { let filepath = d.as_str(); @@ -181,16 +183,31 @@ pub fn load_data_file_dir( ew_simple_object_df.send(LoadedSimpleObjectData { object_data }); simple_objects_read += 1; } + GameSystem::EntitySprite => { + let entity_sprite_data: DataFile = + if let Some(d) = read_data_file(filepath) { + d + } else { + tracing::debug!( + "load_data_file_dir: failed to read entity sprite data from {}", + header.unique_id + ); + continue; + }; + ew_entity_sprite_df.send(LoadedEntitySpriteData { entity_sprite_data }); + entity_sprites_read += 1; + } } } } // let duration = start.elapsed(); tracing::info!( - "loaded {} spells, {} tilesets, {} particles, {} realms, {} simple objects", + "loaded {} spells, {} tilesets, {} particles, {} realms, {} simple objects, and {} entity sprites from data files", spells_read, tilesets_read, particles_read, realms_read, - simple_objects_read + simple_objects_read, + entity_sprites_read ); } diff --git a/game_library/src/data_loader/mod.rs b/game_library/src/data_loader/mod.rs index ffdc915..08a6404 100644 --- a/game_library/src/data_loader/mod.rs +++ b/game_library/src/data_loader/mod.rs @@ -6,6 +6,7 @@ pub mod events; pub mod storage; +mod entity_sprites; mod header_def; mod loader; mod particles; diff --git a/game_library/src/data_loader/plugin.rs b/game_library/src/data_loader/plugin.rs index c98f8e9..01afe79 100644 --- a/game_library/src/data_loader/plugin.rs +++ b/game_library/src/data_loader/plugin.rs @@ -1,9 +1,10 @@ use bevy::prelude::*; use super::{ + entity_sprites::load_entity_sprites, events::{ - LoadedParticleData, LoadedRealmData, LoadedSimpleObjectData, LoadedSpellData, - LoadedTilesetData, + LoadedEntitySpriteData, LoadedParticleData, LoadedRealmData, LoadedSimpleObjectData, + LoadedSpellData, LoadedTilesetData, }, load_data_file_dir, particles::load_particle_effects, @@ -26,13 +27,15 @@ impl Plugin for DataLoaderPlugin { .add_event::() .add_event::() .add_event::() - .add_event::(); + .add_event::() + .add_event::(); // Set up the resources used and the systems to store the data app.init_resource::().add_systems( Update, ( load_tilesets, + load_entity_sprites, load_simple_objects, load_particle_effects, load_realms, diff --git a/game_library/src/data_loader/storage.rs b/game_library/src/data_loader/storage.rs index 7fab5c0..95f31dc 100644 --- a/game_library/src/data_loader/storage.rs +++ b/game_library/src/data_loader/storage.rs @@ -2,7 +2,12 @@ use bevy::{prelude::*, utils::hashbrown::HashMap}; use bevy_hanabi::EffectAsset; -use crate::{realm_data::Realm, spells::Spell, SimpleObject}; +use crate::{ + images::{EntitySprite, StoredTextureAtlas}, + realm_data::Realm, + spells::Spell, + SimpleObject, +}; /// The vault resource is a generic resource that holds data that is stored by a unique id. /// @@ -64,13 +69,6 @@ pub struct GameData { pub realms: Vault, /// Loaded simple objects pub simple_objects: Vault, -} - -/// `TextureAtlas` has been changed in bevy 0.13 so we need to track the texture handle and the texture atlas. -#[derive(Resource, Debug, Clone, Default)] -pub struct StoredTextureAtlas { - /// The texture handle of the texture atlas layout. - pub atlas_handle: Handle, - /// The texture handle used by the atlas. - pub texture_handle: Handle, + /// Loaded entity sprites + pub entity_sprites: Vault, } diff --git a/game_library/src/data_loader/tilesets.rs b/game_library/src/data_loader/tilesets.rs index eb3d7c0..d26b7de 100644 --- a/game_library/src/data_loader/tilesets.rs +++ b/game_library/src/data_loader/tilesets.rs @@ -2,10 +2,9 @@ use bevy::prelude::*; -use super::{ - events::LoadedTilesetData, - storage::{GameData, StoredTextureAtlas}, -}; +use crate::images::StoredTextureAtlas; + +use super::{events::LoadedTilesetData, storage::GameData}; /// Load the tilesets into the game and store a handle under the `unique_id`. #[allow(clippy::needless_pass_by_value, clippy::module_name_repetitions)] diff --git a/game_library/src/enums/game_systems.rs b/game_library/src/enums/game_systems.rs index 8e058a6..bb7afd2 100644 --- a/game_library/src/enums/game_systems.rs +++ b/game_library/src/enums/game_systems.rs @@ -15,6 +15,8 @@ pub enum GameSystem { Realm, /// The simple object system is responsible for loading simple objects SimpleObject, + /// Entity sprites define the sprites for entities. They reference tilesets. + EntitySprite, } /// The order in which the game systems should be loaded. @@ -30,13 +32,17 @@ pub enum GameSystem { /// - Skill perks / trees /// - Monsters #[allow(dead_code)] -pub const ORDERED: [GameSystem; 5] = [ +pub const ORDERED: [GameSystem; 6] = [ + // Tilesets have no dependencies GameSystem::Tileset, + // Particles have no dependencies + GameSystem::Particle, // Simple objects can reference tilesets GameSystem::SimpleObject, + // Entity sprites reference tilesets + GameSystem::EntitySprite, + // Spells reference tilesets and particle effects + GameSystem::Spell, // Realms reference simple objects and tilesets GameSystem::Realm, - GameSystem::Particle, - // Spells reference tilesets - GameSystem::Spell, ]; diff --git a/game_library/src/images/animation.rs b/game_library/src/images/animation.rs new file mode 100644 index 0000000..04a219f --- /dev/null +++ b/game_library/src/images/animation.rs @@ -0,0 +1,90 @@ +//! Animation definitions for entity sprites. +use bevy::prelude::*; +use serde::{Deserialize, Serialize}; +use std::hash::Hash; + +/// The different animation states for an entity sprite. +/// +/// Not every entity sprite will have all of these states. Any left undefined in the basic definition will +/// fall back to the default state (idle). +#[derive( + Debug, + Clone, + Copy, + PartialEq, + Eq, + Hash, + Reflect, + Serialize, + Deserialize, + Component, + Resource, + Default, +)] +pub enum Animation { + /// The default state, typically standing still. + #[default] + Idle, + /// The walking state. + Walk, + /// The running state. + Run, + /// The jumping state. + Jump, + /// The spell-casting state. + Cast, + /// The melee attack state. + Attack, + /// A dying state + Death, + /// A state for getting hurt + Hurt, + /// A state for being stunned + Stun, + /// A state for being dead. + Dead, + // Combinations for walk + other + /// The walking and spell-casting state. + WalkCast, + /// The walking and melee attack state. + WalkAttack, + // Combinations for run + other + /// The running and spell-casting state. + RunCast, + /// The running and melee attack state. + RunAttack, +} + +/// An animation definition for an entity sprite. +#[derive(Debug, Clone, PartialEq, Reflect, Serialize, Deserialize, Component, Resource)] +#[serde(rename_all = "camelCase")] +#[allow(clippy::module_name_repetitions)] +pub struct AnimationDefinition { + /// The animation state. + pub state: Animation, + /// The tileset to use for the animation (by unique_id) + pub tileset: String, + /// The tile indices for the animation. + pub tile_indices: Vec, + /// The duration of each frame in the animation. + pub frame_duration: f32, +} + +impl Hash for AnimationDefinition { + fn hash(&self, state: &mut H) { + self.state.hash(state); + self.tileset.hash(state); + self.tile_indices.hash(state); + } +} + +impl Default for AnimationDefinition { + fn default() -> Self { + Self { + state: Animation::Idle, + tileset: String::from("placeholder"), + tile_indices: vec![0], + frame_duration: 0.0, + } + } +} diff --git a/game_library/src/images/animation_bundle.rs b/game_library/src/images/animation_bundle.rs new file mode 100644 index 0000000..a43f73a --- /dev/null +++ b/game_library/src/images/animation_bundle.rs @@ -0,0 +1,41 @@ +//! Bundle with all the components needed to create an animation. +use bevy::prelude::*; + +use super::{Animation, AnimationFrame, AnimationTimer}; + +/// Component to hold the `unique_id` of the entity sprite. +#[derive(Debug, Clone, PartialEq, Eq, Hash, Component)] +pub struct EntitySpriteId { + /// The `unique_id` of the entity sprite. + pub unique_id: String, +} + +/// Bundle with all the components needed to create an animation. +#[derive(Debug, Clone, Bundle)] +pub struct AnimationBundle { + /// The entity sprite `unique_id`. + pub entity_sprite_id: EntitySpriteId, + /// The current animation of the sprite. + pub current_animation: Animation, + /// The current frame of the animation. + pub animation_frame: AnimationFrame, + /// The timer that will be used to update the animation. + pub animation_timer: AnimationTimer, +} + +impl AnimationBundle { + /// Create a new animation bundle. + #[must_use] + pub fn new(entity_sprite_id: &str) -> Self { + let mut timer = AnimationTimer::new(1.0); + timer.pause(); + Self { + entity_sprite_id: EntitySpriteId { + unique_id: entity_sprite_id.to_string(), + }, + current_animation: Animation::Idle, + animation_frame: AnimationFrame::new(1), + animation_timer: timer, + } + } +} diff --git a/game_library/src/images/animation_frame.rs b/game_library/src/images/animation_frame.rs new file mode 100644 index 0000000..772202f --- /dev/null +++ b/game_library/src/images/animation_frame.rs @@ -0,0 +1,54 @@ +//! Component for tracking the current frame of an animation. +use bevy::prelude::*; + +/// The frame of the animation that the sprite is currently on. +/// +/// This is used to track the current frame of an animation, and to advance the frame. +#[derive(Debug, Resource, Clone, Copy, PartialEq, Eq, Hash, Component)] +pub struct AnimationFrame { + /// The current frame of the animation. + pub frame: usize, + /// The maximum number of frames in the animation. + max: usize, +} + +impl AnimationFrame { + /// Create a new animation frame tracker. + #[must_use] + pub const fn new(max: usize) -> Self { + Self { frame: 0, max } + } + + /// Update the maximum number of frames in the animation. + /// + /// This will reset the current frame to 0. + pub fn update_max(&mut self, max: usize) { + self.max = max; + self.reset(); + } + + /// Get the maximum number of frames in the animation. + #[must_use] + pub const fn max(self) -> usize { + self.max + } + + /// Resets the frame to 0. + pub fn reset(&mut self) { + self.frame = 0; + } + /// Advances the frame by 1, wrapping around to 0 after hitting `MAX`. + pub fn next(&mut self) { + self.frame = (self.frame + 1) % self.max; + } + /// Give the frame in the context of an animation's length. + #[must_use] + pub const fn get(self, length: usize) -> usize { + self.frame % length + } + /// Returns true if the frame is at the end of the animation. + #[must_use] + pub const fn is_fin(self) -> bool { + self.frame == self.max - 1 + } +} diff --git a/game_library/src/images/animation_system.rs b/game_library/src/images/animation_system.rs new file mode 100644 index 0000000..5795199 --- /dev/null +++ b/game_library/src/images/animation_system.rs @@ -0,0 +1,69 @@ +//! System that handles the animation of entities with a `Sprite` component. +//! +//! This has to regard the `Animation` component and the `AnimationDefinition` component. +use bevy::prelude::*; + +use crate::data_loader::storage::GameData; + +use super::{Animation, AnimationFrame, AnimationTimer, EntitySpriteId}; + +/// System that handles the animation of entities with the `AnimatedSpriteBundle` component. +#[allow(clippy::needless_pass_by_value)] +pub(super) fn animate_sprites( + time: Res