From 3b39eaab0bc8dcd8232eb7c1cb0db390bb539d8a Mon Sep 17 00:00:00 2001 From: Nithin Muthukumar Date: Wed, 31 Aug 2022 03:26:49 -0400 Subject: [PATCH] stat and attack update --- src/ai/simple_ai.rs | 1 + src/attack.rs | 4 +++- src/buffs.rs | 37 +++++++++++++++++++++++++++++-------- src/enemy/mod.rs | 11 +++++++---- src/enviro/arrow_trap.rs | 7 +++++-- src/player/inventory.rs | 2 +- src/player/mod.rs | 26 ++++++++++++++++++++------ src/player/prefab.rs | 11 +++++++++-- src/ui/attack_indicator.rs | 21 +++++---------------- src/weapon.rs | 18 ++++++++++++++---- 10 files changed, 94 insertions(+), 44 deletions(-) diff --git a/src/ai/simple_ai.rs b/src/ai/simple_ai.rs index 7c96dcf..61fd95d 100644 --- a/src/ai/simple_ai.rs +++ b/src/ai/simple_ai.rs @@ -96,6 +96,7 @@ fn attack_action( attack_writer.send(AttackEvent { grid_positions, cell_type: CellType::Player(*actor), + damage: 69 }); attack_indicator.hidden = true; diff --git a/src/attack.rs b/src/attack.rs index ad95f8c..02843aa 100644 --- a/src/attack.rs +++ b/src/attack.rs @@ -57,6 +57,7 @@ pub struct AttackEvent { pub grid_positions: Vec, /// target cell type to hit pub cell_type: CellType, + pub damage: u32 } pub struct AttackPlugin; @@ -75,6 +76,7 @@ fn process_attack( for AttackEvent { grid_positions, cell_type, + damage } in events.iter() { for grid_position in grid_positions.iter() { @@ -86,7 +88,7 @@ fn process_attack( match cell_entity { CellType::Enemy(entity) => { - writer.send(DamageEnemyEvent { entity: *entity }); + writer.send(DamageEnemyEvent { entity: *entity, damage: *damage}); }, CellType::Player(entity) => { info!("player hit!"); diff --git a/src/buffs.rs b/src/buffs.rs index c7e003d..6041562 100644 --- a/src/buffs.rs +++ b/src/buffs.rs @@ -2,6 +2,7 @@ use std::time::Duration; use bevy::prelude::*; use bevy_bobs::component::health::Health; +use serde::Deserialize; //Types of effects //Overtime ticking effect ex. Poison @@ -24,26 +25,46 @@ impl Modifier{ } #[derive(Clone,Copy)] pub struct ModifiedStats{ - health: Health, - armor: i32, - speed: i32, - damage: i32, - crit: f32 + pub health: Health, + pub armor: i32, + pub speed: i32, + pub damage: u32, + pub crit: f32 } impl ModifiedStats { } +#[derive(Deserialize,Copy,Clone)] +pub struct StatsPrefab { + max_health: u32, + armor: i32, + speed: i32, + damage: u32, + crit: f32, +} + #[derive(Component)] pub struct Stats { health: Health, armor: i32, speed: i32, - damage: i32, + damage: u32, crit: f32, modifiers: Vec } impl Stats{ - pub fn apply_modifiers(self)->ModifiedStats{ + pub fn new(prefab:StatsPrefab)->Self{ + Self{ + health: Health::new(prefab.max_health), + armor: prefab.armor, + speed: prefab.speed, + damage: prefab.damage, + crit: prefab.crit, + modifiers: Vec::new() + } + + } + pub fn apply_modifiers(&self)->ModifiedStats{ let mut m_stats = ModifiedStats{ health: self.health, armor: self.armor, @@ -51,7 +72,7 @@ impl Stats{ damage: self.damage, crit: self.crit }; - for modifier in self.modifiers{ + for modifier in self.modifiers.iter(){ modifier.apply(m_stats); } return m_stats; diff --git a/src/enemy/mod.rs b/src/enemy/mod.rs index a49840b..3161e83 100644 --- a/src/enemy/mod.rs +++ b/src/enemy/mod.rs @@ -33,7 +33,7 @@ use crate::{ spritesheet_constants::SpriteIndex, ui::{attack_animation::SpawnAttackAnimEvent, attack_indicator::AttackIndicator}, utils::{some_or_continue, Dir}, - weapon::CurrentWeapon, + weapon::{CurrentWeapon, WeaponPrefab}, }; #[derive(Component)] @@ -48,6 +48,7 @@ pub struct SpawnEnemyEvent { pub struct DamageEnemyEvent { pub entity: Entity, + pub damage: u32 } pub struct EnemyPlugin; @@ -69,6 +70,7 @@ fn spawn( mut events: EventReader, asset_sheet: Res, prefab_lib: Res>, + weapon_lib: Res> ) { for SpawnEnemyEvent { spawn_pos, @@ -96,7 +98,8 @@ fn spawn( .insert(GridEntity::new(*spawn_pos, CellType::Enemy(id))) .insert(Movement::new()) .insert(AttackIndicator::default()) - .insert(CurrentWeapon(prefab.weapon_id.to_owned())) + .insert(CurrentWeapon(weapon_lib.get(&prefab.weapon_id.to_owned()).unwrap().clone())) + .insert(Enemy) .insert(Health::new(prefab.health)) .insert(DropTable::new(prefab.drops.clone())); @@ -136,10 +139,10 @@ fn take_damage( mut query: Query<(&mut Health, Option<&DropTable>, &GridEntity)>, mut writer: EventWriter, ) { - for DamageEnemyEvent { entity } in events.iter() { + for DamageEnemyEvent { entity, damage } in events.iter() { let (mut health, droptable, grid_entity) = query.get_mut(*entity).unwrap(); - health.take(1); + health.take(*damage); if health.is_zero() { cmd.entity(*entity).despawn_recursive(); diff --git a/src/enviro/arrow_trap.rs b/src/enviro/arrow_trap.rs index 8a6b118..8e5b649 100644 --- a/src/enviro/arrow_trap.rs +++ b/src/enviro/arrow_trap.rs @@ -1,4 +1,5 @@ use bevy::prelude::*; +use bevy_bobs::prefab::PrefabLib; use bevy_ecs_ldtk::{prelude::FieldValue, EntityInstance}; use iyes_loopless::prelude::*; @@ -11,7 +12,7 @@ use crate::{ map::ldtk_to_bevy, ui::{attack_indicator::AttackIndicator, projectile::SpawnProjectileEvent}, utils::{to_rotation, Dir}, - weapon::CurrentWeapon, + weapon::{CurrentWeapon, WeaponPrefab}, }; // how many turns between each attack @@ -56,6 +57,7 @@ fn ai( writer.send(AttackEvent { grid_positions, cell_type: CellType::Player(entity), + damage: 69 }); projectile_writer.send(SpawnProjectileEvent { @@ -80,6 +82,7 @@ fn spawn_from_ldtk( mut cmd: Commands, query: Query<(Entity, &EntityInstance), Added>, asset_sheet: Res, + weapon_lib: Res> ) { for (entity, entity_instance) in query.iter().filter(|(_, t)| t.identifier == "ArrowTrap") { // TODO this code is sorta cringe @@ -117,7 +120,7 @@ fn spawn_from_ldtk( }) .insert(ArrowTrap::new(dir)) .insert(AttackIndicator { dir, ..default() }) - .insert(CurrentWeapon("arrow_trap".into())) + .insert(CurrentWeapon(weapon_lib.get("arrow_trap").unwrap().clone())) .insert(GridEntity { pos: grid_coords, value: CellType::Wall, diff --git a/src/player/inventory.rs b/src/player/inventory.rs index 994b1d1..0c8b55d 100644 --- a/src/player/inventory.rs +++ b/src/player/inventory.rs @@ -7,7 +7,7 @@ pub struct Inventory { pub armor: PrefabId, pub ability: PrefabId, pub slots: Vec, - capactiy: u32, + capacity: u32, } impl Inventory {} diff --git a/src/player/mod.rs b/src/player/mod.rs index e9c855b..64ec264 100644 --- a/src/player/mod.rs +++ b/src/player/mod.rs @@ -30,7 +30,9 @@ use crate::{ floating_text::FloatingText, move_indicator::MoveIndicator, }, utils::{cardinal_dirs, ok_or_return, some_or_continue, Dir}, - weapon::CurrentWeapon, + weapon::{CurrentWeapon, WeaponPrefab, Damage}, + buffs::Stats + }; #[derive(Component)] @@ -96,7 +98,8 @@ fn spawn( mut cmd: Commands, mut events: EventReader, asset_sheet: Res, - prefab_lib: Res>, + player_lib: Res>, + weapon_lib: Res> ) { for SpawnPlayerEvent { spawn_pos, @@ -117,7 +120,8 @@ fn spawn( (KeyCode::E, PlayerAction::Interact), ]); - let prefab = some_or_continue!(prefab_lib.get(prefab_id)); + let prefab = some_or_continue!(player_lib.get(prefab_id)); + let weapon_prefab = weapon_lib.get(&prefab.default_weapon.to_owned()); let id = cmd.spawn().id(); @@ -136,13 +140,13 @@ fn spawn( }) .insert(Player) .insert(GridEntity::new(*spawn_pos, CellType::Player(id))) - .insert(Health::new(prefab.health)) + .insert(Stats::new(prefab.base_stats)) .insert_bundle(InputManagerBundle:: { action_state: ActionState::default(), input_map, }) .insert(CameraFollow) - .insert(CurrentWeapon(prefab.default_weapon.to_owned())) + .insert(CurrentWeapon(weapon_lib.get(&prefab.default_weapon.to_owned()).unwrap().clone())) .insert(Movement::new()); // ui related @@ -154,6 +158,7 @@ fn spawn( // offset: Vec2::new(0., 8.), // ..default() // }); + } } @@ -250,6 +255,8 @@ fn attack_controller( &mut AttackIndicator, &GridEntity, &ActionState, + &Stats, + &CurrentWeapon ), With, >, @@ -257,7 +264,7 @@ fn attack_controller( mut anim_writer: EventWriter, mut player_moved: EventWriter, ) { - let (entity, mut attack_indicator, grid_entity, action_state) = + let (entity, mut attack_indicator, grid_entity, action_state, stats, weapon) = ok_or_return!(query.get_single_mut()); if action_state.just_pressed(PlayerAction::Up) { @@ -293,10 +300,17 @@ fn attack_controller( spawn_pos: *pos, }); } + + //calculate damage + + + writer.send(AttackEvent { grid_positions, cell_type: CellType::Enemy(entity), + damage: stats.apply_modifiers().damage+weapon.damage.value() + }); player_moved.send(PlayerMovedEvent); diff --git a/src/player/prefab.rs b/src/player/prefab.rs index 3a35f0a..9c1233e 100644 --- a/src/player/prefab.rs +++ b/src/player/prefab.rs @@ -3,6 +3,7 @@ use bevy_bobs::prefab::{PrefabId, PrefabLib}; use serde::Deserialize; use crate::spritesheet_constants::SpriteIndex; +use crate::buffs::StatsPrefab; #[derive(Deserialize, Component)] pub enum Class { @@ -13,12 +14,12 @@ pub enum Class { #[derive(Deserialize)] pub struct PlayerPrefab { - pub health: u32, pub class: Class, pub sprite_index: SpriteIndex, pub default_weapon: PrefabId, pub default_ability: PrefabId, pub default_armor: PrefabId, + pub base_stats: StatsPrefab } pub struct PrefabPlugin; @@ -32,12 +33,18 @@ impl Plugin for PrefabPlugin { const RON_STRING: &str = r#" { "samurai": ( - health: 10, class: Samurai, sprite_index: Player, default_weapon: "hammer", default_ability: "", default_armor: "", + base_stats: ( + max_health: 10, + armor: 2, + speed: 1, + damage: 2, + crit: 0.5 + ) ) } "#; diff --git a/src/ui/attack_indicator.rs b/src/ui/attack_indicator.rs index f401c4c..488c990 100644 --- a/src/ui/attack_indicator.rs +++ b/src/ui/attack_indicator.rs @@ -45,20 +45,10 @@ pub struct AttackIndicatorPlugin; impl Plugin for AttackIndicatorPlugin { fn build(&self, app: &mut App) { app.add_system(spawn) - .add_system(sync_attack_pattern) - .add_system(render); + .add_system(sync_attack_pattern); } } -fn render(query: Query<(&AttackIndicator, &GridEntity)>) { - for (attack_indicator, grid_position) in &query { - let pos: Vec = attack_indicator - .get_pattern() - .iter() - .map(|v| *v + grid_position.pos) - .collect(); - } -} fn spawn( mut cmd: Commands, @@ -69,7 +59,7 @@ fn spawn( >, child_query: Query<&AttackIndicatorRoot>, ) { - for (entity, attack_indictor, children) in &query { + for (entity, attack_indicator, children) in &query { // despawn existing if let Some(children) = children { for child in children.iter() { @@ -82,7 +72,7 @@ fn spawn( } } - if attack_indictor.hidden { + if attack_indicator.hidden { continue; } @@ -97,7 +87,7 @@ fn spawn( cmd.entity(entity).push_children(&[root]); // spawn children - for offset in attack_indictor + for offset in attack_indicator .get_pattern() .iter() .map(|v| v.as_vec2().extend(0.) * (TILE_SIZE as f32)) @@ -126,7 +116,6 @@ fn sync_attack_pattern( prefabs: Res>, ) { for (cur_weapon, mut attack_indicator) in &mut query { - let prefab = prefabs.get(&cur_weapon).unwrap(); - attack_indicator.pattern = prefab.attack_pattern; + attack_indicator.pattern = cur_weapon.attack_pattern; } } diff --git a/src/weapon.rs b/src/weapon.rs index 0fb9695..fd6a67a 100644 --- a/src/weapon.rs +++ b/src/weapon.rs @@ -4,21 +4,31 @@ use serde::Deserialize; use crate::attack::AttackPattern; -#[derive(Deserialize)] +#[derive(Deserialize,Clone)] pub enum Damage { Fixed(u32), Range(u32, u32), } +impl Damage{ + pub fn value(&self)->u32{ + match &self{ + Damage::Fixed(x) => *x, + Damage::Range(x,y) => (x+y)/2 -#[derive(Deserialize)] + + } + } +} + +#[derive(Deserialize,Clone)] pub struct WeaponPrefab { pub display_name: Option, pub attack_pattern: AttackPattern, pub damage: Damage, } -#[derive(Component, Deref, DerefMut)] -pub struct CurrentWeapon(pub PrefabId); +#[derive(Component,Deref,DerefMut)] +pub struct CurrentWeapon(pub WeaponPrefab); const RON_STRING: &str = r#" {