mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Combo counter now uses outcomes.
This commit is contained in:
parent
c29cb037e7
commit
940b4b5de7
@ -2,6 +2,8 @@ use serde::{Deserialize, Serialize};
|
||||
use specs::{Component, DerefFlaggedStorage};
|
||||
use specs_idvs::IdvStorage;
|
||||
|
||||
pub const COMBO_DECAY_START: f64 = 5.0; // seconds
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Combo {
|
||||
counter: u32,
|
||||
@ -24,14 +26,14 @@ impl Combo {
|
||||
|
||||
pub fn reset(&mut self) { self.counter = 0; }
|
||||
|
||||
pub fn increase_by(&mut self, amount: u32, time: f64) {
|
||||
self.counter = self.counter.saturating_add(amount);
|
||||
pub fn change_by(&mut self, amount: i32, time: f64) {
|
||||
if amount > 0 {
|
||||
self.counter = self.counter.saturating_add(amount as u32);
|
||||
} else {
|
||||
self.counter = self.counter.saturating_sub(amount.abs() as u32);
|
||||
}
|
||||
self.last_increase = time;
|
||||
}
|
||||
|
||||
pub fn decrease_by(&mut self, amount: u32) {
|
||||
self.counter = self.counter.saturating_sub(amount);
|
||||
}
|
||||
}
|
||||
|
||||
impl Component for Combo {
|
||||
|
@ -37,16 +37,20 @@ pub enum Outcome {
|
||||
// TODO: Access ECS to get position from Uid to conserve bandwidth
|
||||
pos: Vec3<f32>,
|
||||
},
|
||||
ComboChange {
|
||||
uid: Uid,
|
||||
combo: u32,
|
||||
},
|
||||
}
|
||||
|
||||
impl Outcome {
|
||||
pub fn get_pos(&self) -> Option<Vec3<f32>> {
|
||||
match self {
|
||||
Outcome::Explosion { pos, .. } => Some(*pos),
|
||||
Outcome::ProjectileShot { pos, .. } => Some(*pos),
|
||||
Outcome::Beam { pos, .. } => Some(*pos),
|
||||
Outcome::ExpChange { .. } => None,
|
||||
Outcome::SkillPointGain { pos, .. } => Some(*pos),
|
||||
Outcome::Explosion { pos, .. }
|
||||
| Outcome::ProjectileShot { pos, .. }
|
||||
| Outcome::Beam { pos, .. }
|
||||
| Outcome::SkillPointGain { pos, .. } => Some(*pos),
|
||||
Outcome::ExpChange { .. } | Outcome::ComboChange { .. } => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
use common::{
|
||||
comp::{
|
||||
self,
|
||||
skills::{GeneralSkill, Skill},
|
||||
Body, CharacterState, Combo, Energy, EnergyChange, EnergySource, Health, Poise,
|
||||
PoiseChange, PoiseSource, Pos, Stats,
|
||||
@ -18,7 +19,6 @@ use vek::Vec3;
|
||||
|
||||
const ENERGY_REGEN_ACCEL: f32 = 10.0;
|
||||
const POISE_REGEN_ACCEL: f32 = 2.0;
|
||||
const COMBO_DECAY_START: f64 = 5.0; // seconds
|
||||
|
||||
#[derive(SystemData)]
|
||||
pub struct ReadData<'a> {
|
||||
@ -264,7 +264,9 @@ impl<'a> System<'a> for Sys {
|
||||
|
||||
// Decay combo
|
||||
for (_, mut combo) in (&read_data.entities, &mut combos).join() {
|
||||
if combo.counter() > 0 && read_data.time.0 - combo.last_increase() > COMBO_DECAY_START {
|
||||
if combo.counter() > 0
|
||||
&& read_data.time.0 - combo.last_increase() > comp::combo::COMBO_DECAY_START
|
||||
{
|
||||
combo.reset();
|
||||
}
|
||||
}
|
||||
|
@ -895,11 +895,14 @@ fn handle_exp_gain(
|
||||
pub fn handle_combo_change(server: &Server, entity: EcsEntity, change: i32) {
|
||||
let ecs = &server.state.ecs();
|
||||
if let Some(mut combo) = ecs.write_storage::<comp::Combo>().get_mut(entity) {
|
||||
if change > 0 {
|
||||
let time = ecs.read_resource::<Time>();
|
||||
combo.increase_by(change as u32, time.0);
|
||||
} else {
|
||||
combo.decrease_by(change.abs() as u32);
|
||||
let time = ecs.read_resource::<Time>();
|
||||
let mut outcomes = ecs.write_resource::<Vec<Outcome>>();
|
||||
combo.change_by(change, time.0);
|
||||
if let Some(uid) = ecs.read_storage::<Uid>().get(entity) {
|
||||
outcomes.push(Outcome::ComboChange {
|
||||
uid: *uid,
|
||||
combo: combo.counter(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -364,7 +364,7 @@ impl SfxMgr {
|
||||
audio.play_sfx(file_ref, *pos, None);
|
||||
},
|
||||
},
|
||||
Outcome::ExpChange { .. } => {},
|
||||
Outcome::ExpChange { .. } | Outcome::ComboChange { .. } => {},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,6 @@ use crate::{
|
||||
GlobalState,
|
||||
};
|
||||
use client::Client;
|
||||
use common::resources::Time;
|
||||
use common::{
|
||||
combat,
|
||||
comp::{
|
||||
@ -309,6 +308,13 @@ pub struct SkillPointGain {
|
||||
pub timer: f32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct ComboFloater {
|
||||
pub owner: Uid,
|
||||
pub combo: u32,
|
||||
pub timer: f64,
|
||||
}
|
||||
|
||||
pub struct DebugInfo {
|
||||
pub tps: f64,
|
||||
pub frame_time: Duration,
|
||||
@ -732,6 +738,7 @@ pub struct Hud {
|
||||
crosshair_opacity: f32,
|
||||
exp_floaters: Vec<ExpFloater>,
|
||||
skill_point_displays: Vec<SkillPointGain>,
|
||||
combo_floaters: VecDeque<ComboFloater>,
|
||||
}
|
||||
|
||||
impl Hud {
|
||||
@ -840,6 +847,7 @@ impl Hud {
|
||||
crosshair_opacity: 0.0,
|
||||
exp_floaters: Vec::new(),
|
||||
skill_point_displays: Vec::new(),
|
||||
combo_floaters: VecDeque::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -887,7 +895,7 @@ impl Hud {
|
||||
let items = ecs.read_storage::<comp::Item>();
|
||||
let inventories = ecs.read_storage::<comp::Inventory>();
|
||||
let msm = ecs.read_resource::<MaterialStatManifest>();
|
||||
let entities = ecs.entities();
|
||||
let entities = ecs.entities();
|
||||
let me = client.entity();
|
||||
|
||||
if (client.pending_trade().is_some() && !self.show.trade)
|
||||
@ -2158,8 +2166,19 @@ impl Hud {
|
||||
let controllers = ecs.read_storage::<comp::Controller>();
|
||||
let ability_map = ecs.fetch::<comp::item::tool::AbilityMap>();
|
||||
let bodies = ecs.read_storage::<comp::Body>();
|
||||
let combos = ecs.read_storage::<comp::Combo>();
|
||||
let time = ecs.read_resource::<Time>();
|
||||
// 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);
|
||||
let combo = if let Some(uid) = ecs.read_storage::<Uid>().get(entity) {
|
||||
self.combo_floaters
|
||||
.iter()
|
||||
.find(|c| c.owner == *uid)
|
||||
.copied()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
if let (
|
||||
Some(health),
|
||||
@ -2167,16 +2186,12 @@ impl Hud {
|
||||
Some(energy),
|
||||
Some(_character_state),
|
||||
Some(_controller),
|
||||
Some(combo),
|
||||
time,
|
||||
) = (
|
||||
healths.get(entity),
|
||||
inventories.get(entity),
|
||||
energies.get(entity),
|
||||
character_states.get(entity),
|
||||
controllers.get(entity).map(|c| &c.inputs),
|
||||
combos.get(entity),
|
||||
time,
|
||||
) {
|
||||
Skillbar::new(
|
||||
global_state,
|
||||
@ -2196,8 +2211,7 @@ impl Hud {
|
||||
i18n,
|
||||
&ability_map,
|
||||
&msm,
|
||||
&combo,
|
||||
&time,
|
||||
combo,
|
||||
)
|
||||
.set(self.ids.skillbar, ui_widgets);
|
||||
}
|
||||
@ -3211,6 +3225,11 @@ impl Hud {
|
||||
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,
|
||||
}),
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ use super::{
|
||||
STAMINA_COLOR, TEXT_COLOR, UI_HIGHLIGHT_0,
|
||||
};
|
||||
use crate::{
|
||||
hud::ComboFloater,
|
||||
i18n::Localization,
|
||||
ui::{
|
||||
fonts::Fonts,
|
||||
@ -15,16 +16,14 @@ use crate::{
|
||||
window::GameInput,
|
||||
GlobalState,
|
||||
};
|
||||
use common::{
|
||||
comp::{
|
||||
inventory::slot::EquipSlot,
|
||||
item::{
|
||||
tool::{AbilityMap, Tool, ToolKind},
|
||||
Hands, Item, ItemKind, MaterialStatManifest,
|
||||
},
|
||||
Combo, Energy, Health, Inventory,
|
||||
use common::comp::{
|
||||
self,
|
||||
inventory::slot::EquipSlot,
|
||||
item::{
|
||||
tool::{AbilityMap, Tool, ToolKind},
|
||||
Hands, Item, ItemKind, MaterialStatManifest,
|
||||
},
|
||||
resources::Time,
|
||||
Energy, Health, Inventory,
|
||||
};
|
||||
use conrod_core::{
|
||||
color,
|
||||
@ -149,8 +148,7 @@ pub struct Skillbar<'a> {
|
||||
common: widget::CommonBuilder,
|
||||
ability_map: &'a AbilityMap,
|
||||
msm: &'a MaterialStatManifest,
|
||||
combo: &'a Combo,
|
||||
time: &'a Time,
|
||||
combo: Option<ComboFloater>,
|
||||
}
|
||||
|
||||
impl<'a> Skillbar<'a> {
|
||||
@ -173,8 +171,7 @@ impl<'a> Skillbar<'a> {
|
||||
localized_strings: &'a Localization,
|
||||
ability_map: &'a AbilityMap,
|
||||
msm: &'a MaterialStatManifest,
|
||||
combo: &'a Combo,
|
||||
time: &'a Time,
|
||||
combo: Option<ComboFloater>,
|
||||
) -> Self {
|
||||
Self {
|
||||
global_state,
|
||||
@ -196,7 +193,6 @@ impl<'a> Skillbar<'a> {
|
||||
ability_map,
|
||||
msm,
|
||||
combo,
|
||||
time,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -925,49 +921,50 @@ impl<'a> Widget for Skillbar<'a> {
|
||||
.set(state.ids.m2_ico, ui);
|
||||
|
||||
// Combo Counter
|
||||
if self.combo.counter() > 0 {
|
||||
let combo_txt = format!("{} Combo", self.combo.counter());
|
||||
let combo_cnt = self.combo.counter() as f32;
|
||||
let time_since_last_update = self.combo.last_increase() - self.time.0 as f64;
|
||||
let fnt_col = Color::Rgba(
|
||||
// White -> Yellow -> Red text color gradient depending on count
|
||||
(1.0 - combo_cnt / (combo_cnt + tweak!(1.0))).max(0.79),
|
||||
(1.0 - combo_cnt / (combo_cnt + tweak!(80.0))).max(0.19),
|
||||
(1.0 - combo_cnt / (combo_cnt + tweak!(5.0))).max(0.17),
|
||||
(time_since_last_update - 8.0).min(1.0) as f32,
|
||||
);
|
||||
|
||||
let fnt_size = ((14.0 + self.combo.counter() as f32 * tweak!(0.5)).min(tweak!(20.0)))
|
||||
as u32
|
||||
+ if (time_since_last_update - 12.0) < 1.0 {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
}; // Increase size for higher counts, "flash" on update by increasing the font size by 2
|
||||
println!("{}", time_since_last_update); // REMOVE THIS
|
||||
Rectangle::fill_with([10.0, 10.0], color::TRANSPARENT)
|
||||
.middle_of(ui.window)
|
||||
.set(state.ids.combo_align, ui);
|
||||
Text::new(combo_txt.as_str())
|
||||
.mid_bottom_with_margin_on(
|
||||
state.ids.combo_align,
|
||||
tweak!(-350.0) + time_since_last_update * tweak!(4.0) - 8.0,
|
||||
)
|
||||
.font_size(self.fonts.cyri.scale(fnt_size))
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(Color::Rgba(
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
if let Some(combo) = self.combo {
|
||||
if combo.combo > 0 {
|
||||
let combo_txt = format!("{} Combo", combo.combo);
|
||||
let combo_cnt = combo.combo as f32;
|
||||
let time_since_last_update = comp::combo::COMBO_DECAY_START - combo.timer;
|
||||
let fnt_col = Color::Rgba(
|
||||
// White -> Yellow -> Red text color gradient depending on count
|
||||
(1.0 - combo_cnt / (combo_cnt + tweak!(1.0))).max(0.79),
|
||||
(1.0 - combo_cnt / (combo_cnt + tweak!(80.0))).max(0.19),
|
||||
(1.0 - combo_cnt / (combo_cnt + tweak!(5.0))).max(0.17),
|
||||
(time_since_last_update - 8.0).min(1.0) as f32,
|
||||
))
|
||||
.set(state.ids.combo_bg, ui);
|
||||
Text::new(combo_txt.as_str())
|
||||
.bottom_right_with_margins_on(state.ids.combo_bg, 1.0, 1.0)
|
||||
.font_size(self.fonts.cyri.scale(fnt_size))
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(fnt_col)
|
||||
.set(state.ids.combo, ui);
|
||||
);
|
||||
|
||||
let fnt_size = ((14.0 + combo.timer as f32 * tweak!(0.5)).min(tweak!(20.0))) as u32
|
||||
+ if (time_since_last_update - 12.0) < 1.0 {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
}; // Increase size for higher counts, "flash" on update by increasing the font size by 2
|
||||
//dbg!(combo); // Delete this before merging
|
||||
Rectangle::fill_with([10.0, 10.0], color::TRANSPARENT)
|
||||
.middle_of(ui.window)
|
||||
.set(state.ids.combo_align, ui);
|
||||
Text::new(combo_txt.as_str())
|
||||
.mid_bottom_with_margin_on(
|
||||
state.ids.combo_align,
|
||||
tweak!(-350.0) + time_since_last_update * tweak!(4.0) - 8.0,
|
||||
)
|
||||
.font_size(self.fonts.cyri.scale(fnt_size))
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(Color::Rgba(
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
(time_since_last_update - 8.0).min(1.0) as f32,
|
||||
))
|
||||
.set(state.ids.combo_bg, ui);
|
||||
Text::new(combo_txt.as_str())
|
||||
.bottom_right_with_margins_on(state.ids.combo_bg, 1.0, 1.0)
|
||||
.font_size(self.fonts.cyri.scale(fnt_size))
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(fnt_col)
|
||||
.set(state.ids.combo, ui);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user