Slider for accumulated damage duration

This commit is contained in:
socksonme 2022-04-19 19:37:28 +03:00 committed by Socksonme
parent 5360a7c93e
commit 5533d139bc
6 changed files with 174 additions and 27 deletions

View File

@ -11,7 +11,6 @@ use specs::{Entities, Join, Read, ReadStorage, WriteStorage};
pub const HP_SHOWTIME: f32 = 3.0;
pub const CRIT_SHOWTIME: f32 = 0.7;
pub const MY_HP_SHOWTIME: f32 = 2.5;
pub const HP_ACCUMULATETIME: f32 = 1.0;
#[derive(Default)]
pub struct Sys;

View File

@ -58,7 +58,6 @@ use crate::{
ecs::{
comp as vcomp,
comp::{HpFloater, HpFloaterList},
sys::floater,
},
game_input::GameInput,
hud::{img_ids::ImgsRot, prompt_dialog::DialogOutcomeEvent},
@ -1433,7 +1432,6 @@ impl Hud {
let hp_damage: f32 =
damage_floaters.iter().map(|fl| fl.info.amount).sum();
// .fold(0.0, |acc, f| f.info.amount.min(0.0) + acc);
let hp_dmg_text = if global_state.settings.interface.sct_damage_rounding
&& hp_damage.abs() > 1.0
{
@ -1538,9 +1536,23 @@ impl Hud {
};
let crit = floater.info.crit_mult.is_some();
let crit_mult = floater.info.crit_mult.unwrap_or(1.0);
// Timer sets text transparency
let hp_fade = if crit {
((crate::ecs::sys::floater::CRIT_SHOWTIME - floater.timer) * 0.75) + 0.5
} else {
((crate::ecs::sys::floater::MY_HP_SHOWTIME - floater.timer) * 0.25)
+ 0.2
};
// Skip floater if fade is less than or equal to 0.0
if hp_fade <= 0.0 {
continue;
}
// Increase font size based on fraction of maximum health
// "flashes" by having a larger size in the first 100ms
// TODO: example
// TODO: Could have it so that crits not only fade away but decrease in
// size?
let font_size = 30
+ (max_hp_frac * 10.0 * if crit { 1.25 * crit_mult } else { 1.0 })
as u32
@ -1584,13 +1596,6 @@ impl Hud {
} else {
(floater.rand as f64 - 0.5) * 0.2 * ui_widgets.win_w
};
// Timer sets text transparency
let hp_fade = if crit {
((crate::ecs::sys::floater::CRIT_SHOWTIME - floater.timer) * 0.75) + 0.5
} else {
((crate::ecs::sys::floater::MY_HP_SHOWTIME - floater.timer) * 0.25)
+ 0.2
};
Text::new(&hp_dmg_text)
.font_size(font_size)
.font_id(self.fonts.cyri.conrod_id)
@ -2277,6 +2282,7 @@ impl Hud {
let hp_damage: f32 =
damage_floaters.iter().map(|fl| fl.info.amount).sum();
let hp_dmg_text = if global_state.settings.interface.sct_damage_rounding
&& hp_damage.abs() > 1.0
{
format!("{:.0}", hp_damage.abs())
} else {
@ -2358,6 +2364,7 @@ impl Hud {
health.map_or(1.0, |h| h.maximum()),
) / health.map_or(1.0, |h| h.maximum());
let hp_dmg_text = if global_state.settings.interface.sct_damage_rounding
&& floater.info.amount.abs() > 1.0
{
format!("{:.0}", floater.info.amount.abs())
} else {
@ -2365,6 +2372,18 @@ impl Hud {
};
let crit = floater.info.crit_mult.is_some();
let crit_mult = floater.info.crit_mult.unwrap_or(1.0);
// Timer sets text transparency
let fade = if crit {
((crate::ecs::sys::floater::CRIT_SHOWTIME - floater.timer) * 0.75)
+ 0.5
} else {
((crate::ecs::sys::floater::HP_SHOWTIME - floater.timer) * 0.25)
+ 0.2
};
// Skip floater if fade is less than or equal to 0.0
if fade <= 0.0 {
continue;
}
// Increase font size based on fraction of maximum health
// "flashes" by having a larger size in the first 100ms
let font_size = 30
@ -2402,14 +2421,7 @@ impl Hud {
* (floater.rand as f64 - 0.5).signum())
};
// Timer sets text transparency
let fade = if crit {
((crate::ecs::sys::floater::CRIT_SHOWTIME - floater.timer) * 0.75)
+ 0.5
} else {
((crate::ecs::sys::floater::HP_SHOWTIME - floater.timer) * 0.25)
+ 0.2
};
Text::new(&hp_dmg_text)
.font_size(font_size)
.font_id(self.fonts.cyri.conrod_id)
@ -4518,7 +4530,12 @@ impl Hud {
pub fn camera_clamp(&mut self, camera_clamp: bool) { self.show.camera_clamp = camera_clamp; }
pub fn handle_outcome(&mut self, outcome: &Outcome, client: &Client) {
pub fn handle_outcome(
&mut self,
outcome: &Outcome,
client: &Client,
global_state: &GlobalState,
) {
match outcome {
Outcome::ExpChange { uid, exp, xp_pools } => {
self.floaters.exp_floaters.push(ExpFloater {
@ -4605,7 +4622,11 @@ impl Hud {
Some(f)
// TODO: Change later so it's based on options
// TODO: Might have to discuss whether or not to create a new floater or every crit
if f.timer < floater::HP_ACCUMULATETIME && !f.info.crit_mult.is_some() =>
if (if hit_me {
f.timer < global_state.settings.interface.sct_inc_dmg_accum_duration
} else {
f.timer < global_state.settings.interface.sct_dmg_accum_duration
} && f.info.crit_mult.is_none()) =>
{
f.jump_timer = 0.0;
f.info.amount += info.amount;

View File

@ -88,6 +88,12 @@ widget_ids! {
sct_batch_inc_radio,
sct_round_dmg_text,
sct_round_dmg_radio,
sct_dmg_accum_duration_slider,
sct_dmg_accum_duration_text,
sct_dmg_accum_duration_value,
sct_inc_dmg_accum_duration_slider,
sct_inc_dmg_accum_duration_text,
sct_inc_dmg_accum_duration_value,
//
speech_bubble_text,
speech_bubble_self_text,
@ -714,13 +720,15 @@ impl<'a> Widget for Interface<'a> {
O Show Damage Numbers
O Show single Damage Numbers
// 0 to ??? seconds
O Damage Accumulation Duration: 0s ----I----5s
O Show batched dealt Damage
O Show incoming Damage
O Batch incoming Numbers
// 0 to ??? seconds
O Incoming Damage Accumulation Duration: 0s ----I----5s
O Batch incoming Numbers
O Round Damage Numbers
TODO: Do something like https://gitlab.com/veloren/veloren/-/issues/836
TODO: Scrollbar::x_axis for duration
Number Display Duration: 1s ----I----5s
*/
// SCT/ Scrolling Combat Text
Text::new(
@ -758,6 +766,13 @@ impl<'a> Widget for Interface<'a> {
.color(TEXT_COLOR)
.set(state.ids.sct_show_text, ui);
if self.global_state.settings.interface.sct {
let sct_dmg_accum_duration =
self.global_state.settings.interface.sct_dmg_accum_duration;
let sct_inc_dmg_accum_duration = self
.global_state
.settings
.interface
.sct_inc_dmg_accum_duration;
// Toggle single damage numbers
let show_sct_damage_batch = !ToggleButton::new(
!self.global_state.settings.interface.sct_damage_batch,
@ -780,6 +795,45 @@ impl<'a> Widget for Interface<'a> {
.graphics_for(state.ids.sct_single_dmg_radio)
.color(TEXT_COLOR)
.set(state.ids.sct_single_dmg_text, ui);
if !show_sct_damage_batch {
Text::new(
self.localized_strings
.get("hud.settings.sct_dmg_accum_duration"),
)
.down_from(state.ids.sct_single_dmg_radio, 8.0)
.right_from(state.ids.sct_single_dmg_radio, 10.0)
.font_size(self.fonts.cyri.scale(14))
.font_id(self.fonts.cyri.conrod_id)
.color(TEXT_COLOR)
.set(state.ids.sct_dmg_accum_duration_text, ui);
if let Some(new_val) = ImageSlider::continuous(
sct_dmg_accum_duration,
0.0,
2.0,
self.imgs.slider_indicator,
self.imgs.slider,
)
.w_h(104.0, 22.0)
.down_from(state.ids.sct_dmg_accum_duration_text, 8.0)
.track_breadth(12.0)
.slider_length(10.0)
.pad_track((5.0, 5.0))
.set(state.ids.sct_dmg_accum_duration_slider, ui)
{
events.push(SctDamageAccumDuration(new_val));
}
Text::new(&format!("{:.2}", sct_dmg_accum_duration,))
.right_from(state.ids.sct_dmg_accum_duration_slider, 8.0)
.font_size(self.fonts.cyri.scale(14))
.graphics_for(state.ids.sct_dmg_accum_duration_slider)
.font_id(self.fonts.cyri.conrod_id)
.color(TEXT_COLOR)
.set(state.ids.sct_dmg_accum_duration_value, ui);
}
// Toggle Batched Damage
let show_sct_damage_batch = ToggleButton::new(
show_sct_damage_batch,
@ -787,7 +841,17 @@ impl<'a> Widget for Interface<'a> {
self.imgs.checkbox_checked,
)
.w_h(18.0, 18.0)
.down_from(state.ids.sct_single_dmg_radio, 8.0)
.down_from(
if show_sct_damage_batch {
state.ids.sct_single_dmg_radio
} else {
state.ids.sct_dmg_accum_duration_slider
},
8.0,
)
.and_if(!show_sct_damage_batch, |tb| {
tb.left_from(state.ids.sct_dmg_accum_duration_slider, 10.0)
})
.hover_images(self.imgs.checkbox_mo, self.imgs.checkbox_checked_mo)
.press_images(self.imgs.checkbox_press, self.imgs.checkbox_checked)
.set(state.ids.sct_show_batch_radio, ui);
@ -797,6 +861,7 @@ impl<'a> Widget for Interface<'a> {
!self.global_state.settings.interface.sct_damage_batch,
))
}
Text::new(self.localized_strings.get("hud.settings.cumulated_damage"))
.right_from(state.ids.sct_show_batch_radio, 10.0)
.font_size(self.fonts.cyri.scale(14))
@ -823,6 +888,45 @@ impl<'a> Widget for Interface<'a> {
.graphics_for(state.ids.sct_inc_dmg_radio)
.color(TEXT_COLOR)
.set(state.ids.sct_inc_dmg_text, ui);
if !show_sct_player_batch {
Text::new(
self.localized_strings
.get("hud.settings.sct_inc_dmg_accum_duration"),
)
.down_from(state.ids.sct_inc_dmg_radio, 8.0)
.right_from(state.ids.sct_inc_dmg_radio, 10.0)
.font_size(self.fonts.cyri.scale(14))
.font_id(self.fonts.cyri.conrod_id)
.color(TEXT_COLOR)
.set(state.ids.sct_inc_dmg_accum_duration_text, ui);
if let Some(new_val) = ImageSlider::continuous(
sct_inc_dmg_accum_duration,
0.0,
2.0,
self.imgs.slider_indicator,
self.imgs.slider,
)
.w_h(104.0, 22.0)
.down_from(state.ids.sct_inc_dmg_accum_duration_text, 8.0)
.track_breadth(12.0)
.slider_length(10.0)
.pad_track((5.0, 5.0))
.set(state.ids.sct_inc_dmg_accum_duration_slider, ui)
{
events.push(SctIncomingDamageAccumDuration(new_val));
}
Text::new(&format!("{:.2}", sct_inc_dmg_accum_duration,))
.right_from(state.ids.sct_inc_dmg_accum_duration_slider, 8.0)
.font_size(self.fonts.cyri.scale(14))
.graphics_for(state.ids.sct_inc_dmg_accum_duration_slider)
.font_id(self.fonts.cyri.conrod_id)
.color(TEXT_COLOR)
.set(state.ids.sct_inc_dmg_accum_duration_value, ui);
}
// Toggle Batched Incoming Damage
let show_sct_player_batch = ToggleButton::new(
show_sct_player_batch,
@ -830,7 +934,17 @@ impl<'a> Widget for Interface<'a> {
self.imgs.checkbox_checked,
)
.w_h(18.0, 18.0)
.down_from(state.ids.sct_inc_dmg_radio, 8.0)
.down_from(
if show_sct_player_batch {
state.ids.sct_inc_dmg_radio
} else {
state.ids.sct_inc_dmg_accum_duration_slider
},
8.0,
)
.and_if(!show_sct_player_batch, |tb| {
tb.left_from(state.ids.sct_inc_dmg_accum_duration_slider, 10.0)
})
.hover_images(self.imgs.checkbox_mo, self.imgs.checkbox_checked_mo)
.press_images(self.imgs.checkbox_press, self.imgs.checkbox_checked)
.set(state.ids.sct_batch_inc_radio, ui);

View File

@ -1579,7 +1579,8 @@ impl PlayState for SessionState {
for outcome in outcomes {
self.scene
.handle_outcome(&outcome, &scene_data, &mut global_state.audio);
self.hud.handle_outcome(&outcome, scene_data.client);
self.hud
.handle_outcome(&outcome, scene_data.client, &global_state);
}
}
}

View File

@ -99,6 +99,8 @@ pub enum Interface {
SctPlayerBatch(bool),
SctDamageBatch(bool),
SctRoundDamage(bool),
SctDamageAccumDuration(f32),
SctIncomingDamageAccumDuration(f32),
SpeechBubbleSelf(bool),
SpeechBubbleDarkMode(bool),
SpeechBubbleIcon(bool),
@ -467,6 +469,12 @@ impl SettingsChange {
Interface::SctRoundDamage(sct_round_damage) => {
settings.interface.sct_damage_rounding = sct_round_damage;
},
Interface::SctDamageAccumDuration(sct_dmg_accum_duration) => {
settings.interface.sct_dmg_accum_duration = sct_dmg_accum_duration;
},
Interface::SctIncomingDamageAccumDuration(sct_inc_dmg_accum_duration) => {
settings.interface.sct_inc_dmg_accum_duration = sct_inc_dmg_accum_duration;
},
Interface::SpeechBubbleSelf(sbdm) => {
settings.interface.speech_bubble_self = sbdm;
},

View File

@ -18,6 +18,8 @@ pub struct InterfaceSettings {
pub sct_player_batch: bool,
pub sct_damage_batch: bool,
pub sct_damage_rounding: bool,
pub sct_dmg_accum_duration: f32,
pub sct_inc_dmg_accum_duration: f32,
pub speech_bubble_self: bool,
pub speech_bubble_dark_mode: bool,
pub speech_bubble_icon: bool,
@ -59,6 +61,8 @@ impl Default for InterfaceSettings {
sct_player_batch: false,
sct_damage_batch: false,
sct_damage_rounding: false,
sct_dmg_accum_duration: 1.0,
sct_inc_dmg_accum_duration: 1.0,
speech_bubble_self: true,
speech_bubble_dark_mode: false,
speech_bubble_icon: true,