diff --git a/src/ai/dummy.rs b/src/ai/dummy.rs deleted file mode 100644 index dd172a5..0000000 --- a/src/ai/dummy.rs +++ /dev/null @@ -1,32 +0,0 @@ -//! Dummy enemy module that does nothing - -use super::*; - -use crate::{GROUP_ATTACK, GROUP_ENEMY, GROUP_FRIENDLY, GROUP_INTERACTIVE, GROUP_STATIC, combat::Health, meters}; - -/// Dummy enemy. Has [Health] component and no AI logic -#[derive(Component, Clone, Copy, PartialEq, Eq, Debug, Default, Reflect)] -#[reflect(Component, Clone, PartialEq, Debug, Default)] -#[require(Health)] -pub struct Dummy; - -impl Dummy { - /// Constructs [Dummy] bundle without sprite - pub fn bundle(position: Vec2, health: f32) -> impl Bundle { - ( - // Basic - Dummy, - Health::new(health), - - // World - Transform::from_xyz(position.x, position.y, 0.), - - // Collision - Collider::cuboid(meters(0.5), meters(0.5)), - CollisionGroups::new( - GROUP_ENEMY, - GROUP_STATIC | GROUP_INTERACTIVE | GROUP_FRIENDLY | GROUP_ATTACK, - ), - ) - } -} diff --git a/src/ai/mod.rs b/src/ai/mod.rs deleted file mode 100644 index 535002d..0000000 --- a/src/ai/mod.rs +++ /dev/null @@ -1,6 +0,0 @@ -//! Enemy AI module - -use bevy::prelude::*; -use bevy_rapier2d::prelude::*; - -pub mod dummy; diff --git a/src/anim/sprite.rs b/src/anim/sprite.rs index 14053fc..385ae7f 100644 --- a/src/anim/sprite.rs +++ b/src/anim/sprite.rs @@ -5,8 +5,6 @@ use std::{collections::HashMap, time::Duration}; use bevy::prelude::*; use bevy_ecs::system::EntityEntryCommands; -type SpriteCommands<'a> = EntityEntryCommands<'a, Sprite>; - /// Data for [AnimatedSprite] #[derive(Clone, PartialEq, Debug, Default, Reflect)] #[reflect(Clone, PartialEq, Debug, Default)] @@ -21,7 +19,6 @@ pub struct AnimationData { impl AnimationData { /// Construct new [AnimationData] from given [Handle] - #[inline(always)] pub fn new(image: Handle, frames: Handle, duration_multiplier: f32) -> Self { Self { image, frames, duration_multiplier } } @@ -36,41 +33,36 @@ pub struct AnimatedSprite { current: Option, timer: Timer, duration: Duration, - backwards: bool, } impl AnimatedSprite { /// Constructs new AnimatedSprite - #[inline(always)] pub fn new(data: HashMap, duration: Duration) -> Self { let timer = Timer::new(duration, TimerMode::Once); - Self { data, current: None, timer, duration, backwards: false } + Self { data, current: None, timer, duration } } /// Add new animation to sprite - #[inline(always)] pub fn add(&mut self, data: AnimationData, label: String) { self.data.insert(label, data); } /// Sets internal duration - #[inline(always)] pub fn set_duration(&mut self, duration: Duration) { self.duration = duration; } - fn play_inner( + /// Finds animation by its label and returns it if started playing + pub fn play( &mut self, label: &str, mode: TimerMode, - mut sprite: SpriteCommands, - backwards: bool, + mut sprite: EntityEntryCommands, ) -> Option<&AnimationData> { self.data.get(label).map(|data| { self.current = Some(data.clone()); self.timer = Timer::new(self.duration.mul_f32(data.duration_multiplier), mode); - self.backwards = backwards; let sprite_image = data.image.clone(); let layout = data.frames.clone(); @@ -83,55 +75,15 @@ impl AnimatedSprite { data }) } - - /// Finds animation by its label, plays it and returns it if started playing - #[inline(always)] - pub fn play( - &mut self, - label: &str, - mode: TimerMode, - sprite: SpriteCommands, - ) -> Option<&AnimationData> { - self.play_inner(label, mode, sprite, false) - } - - /// Same as [play](AnimatedSprite::play), but animation plays from the end to the beginning - #[inline(always)] - pub fn play_backwards( - &mut self, - label: &str, - mode: TimerMode, - sprite: SpriteCommands, - ) -> Option<&AnimationData> { - self.play_inner(label, mode, sprite, true) - } - - /// Stops the animation - #[inline(always)] - pub fn stop(&mut self) { - self.current = None; - self.timer.reset(); - } /// Updates animation timer - #[inline(always)] pub fn tick(&mut self, dt: Duration) { self.timer.tick(dt); } - /// Returns inner [Timer::fraction] or [Timer::fraction_remaining] if playing backwards - #[inline(always)] + /// Returns inner [Timer::fraction] pub fn fraction(&self) -> f32 { - match self.backwards { - true => self.timer.fraction_remaining(), - false => self.timer.fraction(), - } - } - - /// Returns [Timer::mode] - #[inline(always)] - pub fn mode(&self) -> TimerMode { - self.timer.mode() + self.timer.fraction() } } @@ -155,7 +107,7 @@ pub fn update_animated_sprites( let max_frames = atlas.len() as f32; - let current_frame = (max_frames * animation.fraction()).min(max_frames - 1.) as usize; + let current_frame = (max_frames * animation.fraction()) as usize; if let Some(atlas) = &mut sprite.texture_atlas { atlas.index = current_frame; diff --git a/src/combat/attack.rs b/src/combat/attack.rs index 9146905..95ead23 100644 --- a/src/combat/attack.rs +++ b/src/combat/attack.rs @@ -5,7 +5,7 @@ use std::time::Duration; use bevy::prelude::*; use bevy_rapier2d::prelude::*; -use crate::{GROUP_ATTACK, GROUP_INTERACTIVE, GROUP_STATIC, combat::Health}; +use crate::{GROUP_ATTACK, GROUP_INTERACTIVE, GROUP_STATIC}; /// Contains logic for attack-related calculations #[derive(Component, Clone, Debug, Reflect)] @@ -27,7 +27,6 @@ pub struct AttackAreaOrigin; impl AttackArea { /// Constructs new attack area - #[inline(always)] pub fn new(accuracy: f32, damage: f32, duration: Duration, half_area: Vec2) -> Self { let max_distance = ((half_area.x * 2.).powi(2) + half_area.y.powi(2)).sqrt(); Self { @@ -59,9 +58,6 @@ impl AttackArea { GROUP_STATIC | GROUP_INTERACTIVE | affinity, ), Collider::cuboid(half_area.x, half_area.y), - ActiveCollisionTypes::all(), - Sleeping::disabled(), - ActiveEvents::COLLISION_EVENTS, // AttackAreaOrigin Children::spawn(( @@ -74,19 +70,11 @@ impl AttackArea { } /// Updates timer and returns true if attack has ended - #[inline(always)] pub fn tick(&mut self, dt: Duration) -> bool { self.timer.tick(dt).is_finished() } - /// Calls [Timer::almost_finish] - #[inline(always)] - pub fn almost_finish(&mut self) { - self.timer.almost_finish(); - } - /// Returns damage for given distance to origin - #[inline(always)] pub fn damage(&self, distance_to_origin: f32) -> f32 { let distance_ratio = 1. - distance_to_origin.min(self.max_distance) / self.max_distance; let total_multiplier = self.accuracy * distance_ratio; @@ -94,42 +82,11 @@ impl AttackArea { } } -fn apply_attack( - commands: &mut Commands, - areas: &mut Query<(Entity, &mut AttackArea)>, - healths: &mut Query<&mut Health>, - first: &Entity, - second: &Entity, -) -> bool { - if let Ok((area_id, mut area)) = areas.get_mut(*first) && - let Ok(mut health) = healths.get_mut(*second) { - health.apply(area.damage(0.), commands.entity(*second)); - info!("{area_id} hit {second}, health: {}", health.to_string()); - area.almost_finish(); - return true; - } - false -} - -/// System that applies attacks and despawns timed out [AttackArea]s -pub fn update_attack_areas( - mut commands: Commands, - time: Res