From 372eff2a023e006c8c6345150b0e96a93b6b7a9e Mon Sep 17 00:00:00 2001 From: Sam Date: Sat, 24 Apr 2021 00:11:41 -0400 Subject: [PATCH] Initial SCT implementation to display blocks. --- common/src/combat.rs | 2 + common/src/outcome.rs | 1 + common/systems/src/beam.rs | 1 + common/systems/src/melee.rs | 4 +- common/systems/src/projectile.rs | 1 + common/systems/src/shockwave.rs | 1 + server/src/events/entity_manipulation.rs | 3 + voxygen/src/audio/sfx/mod.rs | 2 +- voxygen/src/hud/mod.rs | 134 +++++++++++++++++++---- voxygen/src/scene/particle.rs | 2 +- 10 files changed, 125 insertions(+), 26 deletions(-) diff --git a/common/src/combat.rs b/common/src/combat.rs index f761f9d751..b79c837e1e 100644 --- a/common/src/combat.rs +++ b/common/src/combat.rs @@ -61,6 +61,7 @@ pub struct AttackerInfo<'a> { #[cfg(not(target_arch = "wasm32"))] pub struct TargetInfo<'a> { pub entity: EcsEntity, + pub uid: Uid, pub inventory: Option<&'a Inventory>, pub stats: Option<&'a Stats>, pub health: Option<&'a Health>, @@ -135,6 +136,7 @@ impl Attack { emit_outcome(Outcome::Block { parry, pos: target.pos, + uid: target.uid, }); if parry { 1.0 diff --git a/common/src/outcome.rs b/common/src/outcome.rs index 2801f3a3c9..1125094511 100644 --- a/common/src/outcome.rs +++ b/common/src/outcome.rs @@ -62,6 +62,7 @@ pub enum Outcome { Block { pos: Vec3, parry: bool, + uid: Uid, }, } diff --git a/common/systems/src/beam.rs b/common/systems/src/beam.rs index 594f9ecbe5..5c0aa482c7 100644 --- a/common/systems/src/beam.rs +++ b/common/systems/src/beam.rs @@ -185,6 +185,7 @@ impl<'a> System<'a> for Sys { let target_info = TargetInfo { entity: target, + uid: *uid_b, inventory: read_data.inventories.get(target), stats: read_data.stats.get(target), health: read_data.healths.get(target), diff --git a/common/systems/src/melee.rs b/common/systems/src/melee.rs index 998a67986f..abb5aa703d 100644 --- a/common/systems/src/melee.rs +++ b/common/systems/src/melee.rs @@ -87,11 +87,12 @@ impl<'a> System<'a> for Sys { } // Go through all other entities - for (target, pos_b, health_b, body_b) in ( + for (target, pos_b, health_b, body_b, uid_b) in ( &read_data.entities, &read_data.positions, &read_data.healths, &read_data.bodies, + &read_data.uids, ) .join() { @@ -143,6 +144,7 @@ impl<'a> System<'a> for Sys { let target_info = TargetInfo { entity: target, + uid: *uid_b, inventory: read_data.inventories.get(target), stats: read_data.stats.get(target), health: read_data.healths.get(target), diff --git a/common/systems/src/projectile.rs b/common/systems/src/projectile.rs index b054377cff..9d7839b8f4 100644 --- a/common/systems/src/projectile.rs +++ b/common/systems/src/projectile.rs @@ -128,6 +128,7 @@ impl<'a> System<'a> for Sys { let target_info = TargetInfo { entity: target, + uid: other, inventory: read_data.inventories.get(target), stats: read_data.stats.get(target), health: read_data.healths.get(target), diff --git a/common/systems/src/shockwave.rs b/common/systems/src/shockwave.rs index 3e86f4c98e..0c6e1131c8 100644 --- a/common/systems/src/shockwave.rs +++ b/common/systems/src/shockwave.rs @@ -190,6 +190,7 @@ impl<'a> System<'a> for Sys { let target_info = TargetInfo { entity: target, + uid: *uid_b, inventory: read_data.inventories.get(target), stats: read_data.stats.get(target), health: read_data.healths.get(target), diff --git a/server/src/events/entity_manipulation.rs b/server/src/events/entity_manipulation.rs index 8ab17c7bbd..1151f79638 100644 --- a/server/src/events/entity_manipulation.rs +++ b/server/src/events/entity_manipulation.rs @@ -682,6 +682,7 @@ pub fn handle_explosion(server: &Server, pos: Vec3, explosion: Explosion, o stats_b_maybe, ori_b_maybe, char_state_b_maybe, + uid_b, ), ) in ( &ecs.entities(), @@ -693,6 +694,7 @@ pub fn handle_explosion(server: &Server, pos: Vec3, explosion: Explosion, o ecs.read_storage::().maybe(), ecs.read_storage::().maybe(), ecs.read_storage::().maybe(), + &ecs.read_storage::(), ), ) .join() @@ -736,6 +738,7 @@ pub fn handle_explosion(server: &Server, pos: Vec3, explosion: Explosion, o let target_info = combat::TargetInfo { entity: entity_b, + uid: *uid_b, inventory: inventory_b_maybe, stats: stats_b_maybe, health: Some(health_b), diff --git a/voxygen/src/audio/sfx/mod.rs b/voxygen/src/audio/sfx/mod.rs index 2ada3b1cf1..dd955da89d 100644 --- a/voxygen/src/audio/sfx/mod.rs +++ b/voxygen/src/audio/sfx/mod.rs @@ -416,7 +416,7 @@ impl SfxMgr { ][rand::thread_rng().gen_range(1..4)]; audio.play_sfx(file_ref, *pos, None); }, - Outcome::Block { pos, parry } => { + Outcome::Block { pos, parry, .. } => { // TODO: Get audio for blocking and parrying let file_ref_block = vec![ "voxygen.audio.sfx.character.block_1", diff --git a/voxygen/src/hud/mod.rs b/voxygen/src/hud/mod.rs index f96a46586f..3056b4d332 100644 --- a/voxygen/src/hud/mod.rs +++ b/voxygen/src/hud/mod.rs @@ -329,6 +329,11 @@ pub struct ComboFloater { pub timer: f64, } +pub struct BlockFloater { + pub owner: Uid, + pub timer: f32, +} + pub struct DebugInfo { pub tps: f64, pub frame_time: Duration, @@ -739,6 +744,13 @@ impl PromptDialogSettings { } } +pub struct Floaters { + pub exp_floaters: Vec, + pub skill_point_displays: Vec, + pub combo_floaters: VecDeque, + pub block_floaters: Vec, +} + pub struct Hud { ui: Ui, ids: Ids, @@ -765,9 +777,7 @@ pub struct Hud { hotbar: hotbar::State, events: Vec, crosshair_opacity: f32, - exp_floaters: Vec, - skill_point_displays: Vec, - combo_floaters: VecDeque, + floaters: Floaters, } impl Hud { @@ -878,9 +888,12 @@ impl Hud { hotbar: hotbar_state, events: Vec::new(), crosshair_opacity: 0.0, - exp_floaters: Vec::new(), - skill_point_displays: Vec::new(), - combo_floaters: VecDeque::new(), + floaters: Floaters { + exp_floaters: Vec::new(), + skill_point_displays: Vec::new(), + combo_floaters: VecDeque::new(), + block_floaters: Vec::new(), + }, } } @@ -1174,9 +1187,18 @@ impl Hud { } } // EXP Numbers - self.exp_floaters.retain(|f| f.timer > 0_f32); + self.floaters + .exp_floaters + .iter_mut() + .for_each(|f| f.timer -= dt.as_secs_f32()); + self.floaters.exp_floaters.retain(|f| f.timer > 0_f32); if let Some(uid) = uids.get(me) { - for floater in self.exp_floaters.iter_mut().filter(|f| f.owner == *uid) { + for floater in self + .floaters + .exp_floaters + .iter_mut() + .filter(|f| f.owner == *uid) + { let number_speed = 50.0; // Number Speed for Single EXP let player_sct_bg_id = player_sct_bg_id_walker.next( &mut self.ids.player_sct_bgs, @@ -1221,13 +1243,19 @@ impl Hud { ) .set(player_sct_id, ui_widgets); } - floater.timer -= dt.as_secs_f32(); } } // Skill points - self.skill_point_displays.retain(|d| d.timer > 0_f32); + self.floaters + .skill_point_displays + .iter_mut() + .for_each(|f| f.timer -= dt.as_secs_f32()); + self.floaters + .skill_point_displays + .retain(|d| d.timer > 0_f32); if let Some(uid) = uids.get(me) { if let Some(display) = self + .floaters .skill_point_displays .iter_mut() .find(|d| d.owner == *uid) @@ -1311,8 +1339,58 @@ impl Hud { .left_from(self.ids.player_rank_up_txt_1_bg, 5.0) .color(Some(Color::Rgba(1.0, 1.0, 1.0, fade))) .set(self.ids.player_rank_up_icon, ui_widgets); + } + } + // Scrolling Combat Text for Parrying an attack + self.floaters + .block_floaters + .iter_mut() + .for_each(|f| f.timer -= dt.as_secs_f32()); + self.floaters.block_floaters.retain(|f| f.timer > 0_f32); + if let Some(uid) = uids.get(me) { + use inline_tweak::tweak; + for floater in self + .floaters + .block_floaters + .iter_mut() + .filter(|f| f.owner == *uid) + { + let number_speed = 50.0; + let player_sct_bg_id = player_sct_bg_id_walker.next( + &mut self.ids.player_sct_bgs, + &mut ui_widgets.widget_id_generator(), + ); + let player_sct_id = player_sct_id_walker.next( + &mut self.ids.player_scts, + &mut ui_widgets.widget_id_generator(), + ); + let font_size = 30; + let y = floater.timer as f64 * number_speed; // Timer sets the widget offset + // text transparency + let fade = if floater.timer < 0.25 { + floater.timer as f32 / 0.25 + } else { + 1.0 + }; - display.timer -= dt.as_secs_f32(); + Text::new("Blocked") + .font_size(font_size) + .font_id(self.fonts.cyri.conrod_id) + .color(Color::Rgba(0.0, 0.0, 0.0, fade)) + .x_y( + ui_widgets.win_w * (tweak!(0.0)), + ui_widgets.win_h * (tweak!(-0.3)) + y - tweak!(3.0), + ) + .set(player_sct_bg_id, ui_widgets); + Text::new("Blocked") + .font_size(font_size) + .font_id(self.fonts.cyri.conrod_id) + .color(Color::Rgba(tweak!(0.9), tweak!(0.85), tweak!(0.2), fade)) + .x_y( + ui_widgets.win_w * (tweak!(0.0)), + ui_widgets.win_h * (tweak!(-0.3)) + y, + ) + .set(player_sct_id, ui_widgets); } } } @@ -2273,12 +2351,14 @@ impl Hud { let ability_map = ecs.fetch::(); let bodies = ecs.read_storage::(); // Combo floater stuffs - for combo_floater in self.combo_floaters.iter_mut() { - combo_floater.timer -= dt.as_secs_f64(); - } - self.combo_floaters.retain(|f| f.timer > 0_f64); + self.floaters + .combo_floaters + .iter_mut() + .for_each(|f| f.timer -= dt.as_secs_f64()); + self.floaters.combo_floaters.retain(|f| f.timer > 0_f64); let combo = if let Some(uid) = ecs.read_storage::().get(entity) { - self.combo_floaters + self.floaters + .combo_floaters .iter() .find(|c| c.owner == *uid) .copied() @@ -3425,7 +3505,7 @@ impl Hud { pub fn handle_outcome(&mut self, outcome: &Outcome) { match outcome { - Outcome::ExpChange { uid, exp } => self.exp_floaters.push(ExpFloater { + Outcome::ExpChange { uid, exp } => self.floaters.exp_floaters.push(ExpFloater { owner: *uid, exp_change: *exp, timer: 4.0, @@ -3436,17 +3516,25 @@ impl Hud { skill_tree, total_points, .. - } => self.skill_point_displays.push(SkillPointGain { + } => self.floaters.skill_point_displays.push(SkillPointGain { owner: *uid, skill_tree: *skill_tree, total_points: *total_points, timer: 5.0, }), - Outcome::ComboChange { uid, combo } => self.combo_floaters.push_front(ComboFloater { - owner: *uid, - combo: *combo, - timer: comp::combo::COMBO_DECAY_START, - }), + Outcome::ComboChange { uid, combo } => { + self.floaters.combo_floaters.push_front(ComboFloater { + owner: *uid, + combo: *combo, + timer: comp::combo::COMBO_DECAY_START, + }) + }, + Outcome::Block { uid, parry, .. } if *parry => { + self.floaters.block_floaters.push(BlockFloater { + owner: *uid, + timer: 1.0, + }) + }, _ => {}, } } diff --git a/voxygen/src/scene/particle.rs b/voxygen/src/scene/particle.rs index 9fafde5e5f..c9a349d96e 100644 --- a/voxygen/src/scene/particle.rs +++ b/voxygen/src/scene/particle.rs @@ -203,7 +203,7 @@ impl ParticleMgr { }); } }, - Outcome::Block { pos, parry } => { + Outcome::Block { pos, parry, .. } => { if *parry { self.particles.resize_with(self.particles.len() + 10, || { Particle::new(