mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Address review
- Change hp_pulse to not be framerate dependent - Change some of the HpFloater checks to be inside the find() function - Remove unnecessary join - Add back option for showing incoming damage + add option for experience accumulation - Change `ExpFloater`s to not store the owner, as they are only shown for the player (will have to see if the implementation is correct so that it may be applied to the other floaters) - Rename `Outcome::Damage` to `Outcome::HealthChange` and `DamageInfo` to `HealthChangeInfo` - Update some outdated comments/documentation
This commit is contained in:
parent
8feaea5cdf
commit
2c5fd06d0b
@ -26,6 +26,7 @@
|
||||
"hud.settings.toggle_bar_experience": "Toggle Experience Bar",
|
||||
"hud.settings.scrolling_combat_text": "Scrolling Combat Text",
|
||||
"hud.settings.damage_accumulation_duration": "Damage Accumulation Duration",
|
||||
"hud.settings.incoming_damage": "Incoming Damage",
|
||||
"hud.settings.incoming_damage_accumulation_duration": "Incoming Damage Accumulation Duration",
|
||||
"hud.settings.round_damage": "Round Damage",
|
||||
"hud.settings.speech_bubble": "Speech Bubble",
|
||||
@ -34,6 +35,8 @@
|
||||
"hud.settings.speech_bubble_icon": "Speech Bubble Icon",
|
||||
"hud.settings.energybar_numbers": "Energybar Numbers",
|
||||
"hud.settings.always_show_bars": "Always show Energybars",
|
||||
"hud.settings.experience_numbers": "Experience Numbers",
|
||||
"hud.settings.accumulate_experience": "Accumulate Experience Numbers",
|
||||
"hud.settings.values": "Values",
|
||||
"hud.settings.percentages": "Percentages",
|
||||
"hud.settings.chat": "Chat",
|
||||
|
@ -157,6 +157,7 @@ impl Health {
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
/// Returns a boolean if the delta was not zero.
|
||||
pub fn change_by(&mut self, change: HealthChange) -> bool {
|
||||
let prev_health = i64::from(self.current);
|
||||
self.current = (((self.current() + change.amount).clamp(0.0, f32::from(Self::MAX_HEALTH))
|
||||
@ -185,7 +186,7 @@ impl Health {
|
||||
(change.time.0 - last_damage_time.0) < DAMAGE_CONTRIB_PRUNE_SECS
|
||||
});
|
||||
}
|
||||
delta.abs() > (Self::HEALTH_EPSILON * Self::SCALING_FACTOR_FLOAT) as i64
|
||||
delta != 0
|
||||
}
|
||||
|
||||
pub fn damage_contributions(&self) -> impl Iterator<Item = (&DamageContributor, &u64)> {
|
||||
|
@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize};
|
||||
use vek::*;
|
||||
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
|
||||
pub struct DamageInfo {
|
||||
pub struct HealthChangeInfo {
|
||||
pub amount: f32,
|
||||
pub crit: bool,
|
||||
pub target: Uid,
|
||||
@ -67,9 +67,9 @@ pub enum Outcome {
|
||||
pos: Vec3<f32>,
|
||||
body: comp::Body,
|
||||
},
|
||||
Damage {
|
||||
HealthChange {
|
||||
pos: Vec3<f32>,
|
||||
info: DamageInfo,
|
||||
info: HealthChangeInfo,
|
||||
},
|
||||
Death {
|
||||
pos: Vec3<f32>,
|
||||
@ -106,7 +106,7 @@ impl Outcome {
|
||||
| Outcome::Beam { pos, .. }
|
||||
| Outcome::SkillPointGain { pos, .. }
|
||||
| Outcome::SummonedCreature { pos, .. }
|
||||
| Outcome::Damage { pos, .. }
|
||||
| Outcome::HealthChange { pos, .. }
|
||||
| Outcome::Death { pos, .. }
|
||||
| Outcome::Block { pos, .. }
|
||||
| Outcome::PoiseChange { pos, .. }
|
||||
|
@ -23,7 +23,7 @@ use common::{
|
||||
Player, Poise, Pos, SkillSet, Stats,
|
||||
},
|
||||
event::{EventBus, ServerEvent},
|
||||
outcome::{DamageInfo, Outcome},
|
||||
outcome::{HealthChangeInfo, Outcome},
|
||||
resources::Time,
|
||||
rtsim::RtSimEntity,
|
||||
terrain::{Block, BlockKind, TerrainGrid},
|
||||
@ -66,22 +66,18 @@ pub fn handle_poise(server: &Server, entity: EcsEntity, change: comp::PoiseChang
|
||||
|
||||
pub fn handle_health_change(server: &Server, entity: EcsEntity, change: HealthChange) {
|
||||
let ecs = &server.state.ecs();
|
||||
let outcomes = ecs.write_resource::<EventBus<Outcome>>();
|
||||
let mut outcomes_emitter = outcomes.emitter();
|
||||
let mut changed = false;
|
||||
if let Some(mut health) = ecs.write_storage::<Health>().get_mut(entity) {
|
||||
changed = health.change_by(change);
|
||||
}
|
||||
if let (Some(pos), Some(uid)) = (
|
||||
if let (Some(pos), Some(uid), Some(mut health)) = (
|
||||
ecs.read_storage::<Pos>().get(entity),
|
||||
ecs.read_storage::<Uid>().get(entity),
|
||||
ecs.write_storage::<Health>().get_mut(entity),
|
||||
) {
|
||||
// If the absolute health change amount was greater than the health epsilon,
|
||||
// push a new Damage outcome
|
||||
if changed {
|
||||
outcomes_emitter.emit(Outcome::Damage {
|
||||
let outcomes = ecs.write_resource::<EventBus<Outcome>>();
|
||||
let mut outcomes_emitter = outcomes.emitter();
|
||||
// If the change amount was not zero
|
||||
if health.change_by(change) {
|
||||
outcomes_emitter.emit(Outcome::HealthChange {
|
||||
pos: pos.0,
|
||||
info: DamageInfo {
|
||||
info: HealthChangeInfo {
|
||||
amount: change.amount,
|
||||
by: change.by,
|
||||
target: *uid,
|
||||
|
@ -514,7 +514,7 @@ impl SfxMgr {
|
||||
false,
|
||||
);
|
||||
},
|
||||
Outcome::Damage { pos, info, .. } => {
|
||||
Outcome::HealthChange { pos, info, .. } => {
|
||||
// Don't emit sound effects from positive damage (healing)
|
||||
if info.amount < Health::HEALTH_EPSILON {
|
||||
let sfx_trigger_item = triggers.get_key_value(&SfxEvent::Damage);
|
||||
|
@ -1,4 +1,4 @@
|
||||
use common::{comp::Ori, outcome::DamageInfo};
|
||||
use common::{comp::Ori, outcome::HealthChangeInfo};
|
||||
use specs::Component;
|
||||
use specs_idvs::IdvStorage;
|
||||
use vek::*;
|
||||
@ -10,7 +10,7 @@ pub struct HpFloater {
|
||||
pub timer: f32,
|
||||
// Used for the "jumping" animation of the HpFloater whenever it changes it's value
|
||||
pub jump_timer: f32,
|
||||
pub info: DamageInfo,
|
||||
pub info: HealthChangeInfo,
|
||||
// Used for randomly offsetting
|
||||
pub rand: f32,
|
||||
}
|
||||
|
@ -44,14 +44,6 @@ impl<'a> System<'a> for Sys {
|
||||
});
|
||||
}
|
||||
|
||||
for hp_floater_list in (&mut hp_floater_lists).join() {
|
||||
// Increment timer for time since last damaged by me
|
||||
hp_floater_list
|
||||
.time_since_last_dmg_by_me
|
||||
.as_mut()
|
||||
.map(|t| *t += dt.0);
|
||||
}
|
||||
|
||||
// Remove floater lists on entities without health or without position
|
||||
for entity in (&entities, !&healths, &hp_floater_lists)
|
||||
.join()
|
||||
@ -69,15 +61,21 @@ impl<'a> System<'a> for Sys {
|
||||
}
|
||||
|
||||
// Maintain existing floaters
|
||||
for (entity, HpFloaterList { floaters, .. }) in (&entities, &mut hp_floater_lists).join() {
|
||||
for mut floater in floaters.iter_mut() {
|
||||
for (entity, hp_floater_list) in (&entities, &mut hp_floater_lists).join() {
|
||||
// Increment timer for time since last damaged by me
|
||||
hp_floater_list
|
||||
.time_since_last_dmg_by_me
|
||||
.as_mut()
|
||||
.map(|t| *t += dt.0);
|
||||
|
||||
for mut floater in hp_floater_list.floaters.iter_mut() {
|
||||
// Increment timer
|
||||
floater.timer += dt.0;
|
||||
floater.jump_timer += dt.0;
|
||||
}
|
||||
|
||||
// Clear floaters if newest floater is past show time
|
||||
if floaters.last().map_or(false, |f| {
|
||||
if hp_floater_list.floaters.last().map_or(false, |f| {
|
||||
f.timer
|
||||
> if Some(entity) != my_entity.0 {
|
||||
HP_SHOWTIME
|
||||
@ -85,7 +83,7 @@ impl<'a> System<'a> for Sys {
|
||||
MY_HP_SHOWTIME
|
||||
}
|
||||
}) {
|
||||
floaters.clear();
|
||||
hp_floater_list.floaters.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -451,7 +451,6 @@ pub struct BuffInfo {
|
||||
}
|
||||
|
||||
pub struct ExpFloater {
|
||||
pub owner: Uid,
|
||||
pub exp_change: u32,
|
||||
pub timer: f32,
|
||||
pub jump_timer: f32,
|
||||
@ -1331,9 +1330,7 @@ impl Hud {
|
||||
if let Some(health) = healths.get(me) {
|
||||
// Hurt Frame
|
||||
let hp_percentage = health.current() / health.maximum() * 100.0;
|
||||
self.hp_pulse += (dt.as_secs_f32() * 10.0 / hp_percentage)
|
||||
.min(0.07)
|
||||
.max(0.02);
|
||||
self.hp_pulse += dt.as_secs_f32() * 10.0 / hp_percentage.max(3.0).min(7.0);
|
||||
if hp_percentage < 10.0 && !health.is_dead {
|
||||
let hurt_fade = (self.hp_pulse).sin() * 0.5 + 0.6; //Animation timer
|
||||
Image::new(self.imgs.hurt_bg)
|
||||
@ -1425,7 +1422,7 @@ impl Hud {
|
||||
};
|
||||
|
||||
for floater in floaters {
|
||||
let number_speed = 50.0; // Player Heal Speed
|
||||
let number_speed = 50.0; // Player number speed
|
||||
let player_sct_bg_id = player_sct_bg_id_walker.next(
|
||||
&mut self.ids.player_sct_bgs,
|
||||
&mut ui_widgets.widget_id_generator(),
|
||||
@ -1523,82 +1520,76 @@ impl Hud {
|
||||
f.timer -= dt.as_secs_f32();
|
||||
f.jump_timer += dt.as_secs_f32();
|
||||
});
|
||||
// TODO:Change the other floaters as well if this is the right method
|
||||
self.floaters.exp_floaters.retain(|f| f.timer > 0.0);
|
||||
if let Some(uid) = uids.get(me) {
|
||||
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,
|
||||
&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 player_sct_icon_id = player_sct_id_walker.next(
|
||||
&mut self.ids.player_scts,
|
||||
&mut ui_widgets.widget_id_generator(),
|
||||
);*/
|
||||
// Increase font size based on fraction of maximum Experience
|
||||
// "flashes" by having a larger size in the first 100ms
|
||||
let font_size_xp = 30
|
||||
+ ((floater.exp_change as f32 / 300.0).min(1.0) * 50.0) as u32
|
||||
+ if floater.jump_timer < 0.1 {
|
||||
FLASH_MAX * (((1.0 - floater.jump_timer * 10.0) * 10.0) as u32)
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let y = floater.timer as f64 * number_speed; // Timer sets the widget offset
|
||||
//let fade = ((4.0 - floater.timer as f32) * 0.25) + 0.2; // Timer sets
|
||||
// text transparency
|
||||
let fade = floater.timer.min(1.0);
|
||||
for floater in self.floaters.exp_floaters.iter_mut() {
|
||||
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,
|
||||
&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 player_sct_icon_id = player_sct_id_walker.next(
|
||||
&mut self.ids.player_scts,
|
||||
&mut ui_widgets.widget_id_generator(),
|
||||
);*/
|
||||
// Increase font size based on fraction of maximum Experience
|
||||
// "flashes" by having a larger size in the first 100ms
|
||||
let font_size_xp = 30
|
||||
+ ((floater.exp_change as f32 / 300.0).min(1.0) * 50.0) as u32
|
||||
+ if floater.jump_timer < 0.1 {
|
||||
FLASH_MAX * (((1.0 - floater.jump_timer * 10.0) * 10.0) as u32)
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let y = floater.timer as f64 * number_speed; // Timer sets the widget offset
|
||||
//let fade = ((4.0 - floater.timer as f32) * 0.25) + 0.2; // Timer sets
|
||||
// text transparency
|
||||
let fade = floater.timer.min(1.0);
|
||||
|
||||
if floater.exp_change > 0 {
|
||||
let xp_pool = &floater.xp_pools;
|
||||
// Don't show 0 Exp
|
||||
let exp_string = &i18n
|
||||
.get("hud.sct.experience")
|
||||
.replace("{amount}", &floater.exp_change.max(1).to_string());
|
||||
Text::new(exp_string)
|
||||
.font_size(font_size_xp)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(Color::Rgba(0.0, 0.0, 0.0, fade))
|
||||
.x_y(
|
||||
ui_widgets.win_w * (0.5 * floater.rand_offset.0 as f64 - 0.25),
|
||||
ui_widgets.win_h * (0.15 * floater.rand_offset.1 as f64) + y
|
||||
- 3.0,
|
||||
)
|
||||
.set(player_sct_bg_id, ui_widgets);
|
||||
Text::new(exp_string)
|
||||
.font_size(font_size_xp)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(
|
||||
if xp_pool.contains(&SkillGroupKind::Weapon(ToolKind::Pick)) {
|
||||
Color::Rgba(0.18, 0.32, 0.9, fade)
|
||||
} else {
|
||||
Color::Rgba(0.59, 0.41, 0.67, fade)
|
||||
},
|
||||
)
|
||||
.x_y(
|
||||
ui_widgets.win_w * (0.5 * floater.rand_offset.0 as f64 - 0.25),
|
||||
ui_widgets.win_h * (0.15 * floater.rand_offset.1 as f64) + y,
|
||||
)
|
||||
.set(player_sct_id, ui_widgets);
|
||||
// Exp Source Image (TODO: fix widget id crash)
|
||||
/*if xp_pool.contains(&SkillGroupKind::Weapon(ToolKind::Pick)) {
|
||||
Image::new(self.imgs.pickaxe_ico)
|
||||
.w_h(font_size_xp as f64, font_size_xp as f64)
|
||||
.left_from(player_sct_id, 5.0)
|
||||
.set(player_sct_icon_id, ui_widgets);
|
||||
}*/
|
||||
}
|
||||
if floater.exp_change > 0 {
|
||||
let xp_pool = &floater.xp_pools;
|
||||
// Don't show 0 Exp
|
||||
let exp_string = &i18n
|
||||
.get("hud.sct.experience")
|
||||
.replace("{amount}", &floater.exp_change.max(1).to_string());
|
||||
Text::new(exp_string)
|
||||
.font_size(font_size_xp)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(Color::Rgba(0.0, 0.0, 0.0, fade))
|
||||
.x_y(
|
||||
ui_widgets.win_w * (0.5 * floater.rand_offset.0 as f64 - 0.25),
|
||||
ui_widgets.win_h * (0.15 * floater.rand_offset.1 as f64) + y - 3.0,
|
||||
)
|
||||
.set(player_sct_bg_id, ui_widgets);
|
||||
Text::new(exp_string)
|
||||
.font_size(font_size_xp)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(
|
||||
if xp_pool.contains(&SkillGroupKind::Weapon(ToolKind::Pick)) {
|
||||
Color::Rgba(0.18, 0.32, 0.9, fade)
|
||||
} else {
|
||||
Color::Rgba(0.59, 0.41, 0.67, fade)
|
||||
},
|
||||
)
|
||||
.x_y(
|
||||
ui_widgets.win_w * (0.5 * floater.rand_offset.0 as f64 - 0.25),
|
||||
ui_widgets.win_h * (0.15 * floater.rand_offset.1 as f64) + y,
|
||||
)
|
||||
.set(player_sct_id, ui_widgets);
|
||||
// Exp Source Image (TODO: fix widget id crash)
|
||||
/*if xp_pool.contains(&SkillGroupKind::Weapon(ToolKind::Pick)) {
|
||||
Image::new(self.imgs.pickaxe_ico)
|
||||
.w_h(font_size_xp as f64, font_size_xp as f64)
|
||||
.left_from(player_sct_id, 5.0)
|
||||
.set(player_sct_icon_id, ui_widgets);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
// Skill points
|
||||
self.floaters
|
||||
.skill_point_displays
|
||||
@ -2172,7 +2163,7 @@ impl Hud {
|
||||
};
|
||||
|
||||
for floater in floaters {
|
||||
let number_speed = 250.0; // Single Numbers Speed
|
||||
let number_speed = 250.0; // Enemy number speed
|
||||
let sct_id = sct_walker
|
||||
.next(&mut self.ids.scts, &mut ui_widgets.widget_id_generator());
|
||||
let sct_bg_id = sct_bg_walker
|
||||
@ -4353,22 +4344,28 @@ impl Hud {
|
||||
let interface = &global_state.settings.interface;
|
||||
match outcome {
|
||||
Outcome::ExpChange { uid, exp, xp_pools } => {
|
||||
match self.floaters.exp_floaters.last_mut() {
|
||||
Some(floater)
|
||||
if floater.timer > (EXP_FLOATER_LIFETIME - EXP_ACCUMULATION_DURATION)
|
||||
&& floater.owner == *uid =>
|
||||
{
|
||||
floater.jump_timer = 0.0;
|
||||
floater.exp_change += *exp;
|
||||
},
|
||||
_ => self.floaters.exp_floaters.push(ExpFloater {
|
||||
owner: *uid,
|
||||
exp_change: *exp,
|
||||
timer: EXP_FLOATER_LIFETIME,
|
||||
jump_timer: 0.0,
|
||||
rand_offset: rand::thread_rng().gen::<(f32, f32)>(),
|
||||
xp_pools: xp_pools.clone(),
|
||||
}),
|
||||
let ecs = client.state().ecs();
|
||||
let uids = ecs.read_storage::<Uid>();
|
||||
let me = client.entity();
|
||||
|
||||
if uids.get(me).map_or(false, |me| *me == *uid) {
|
||||
match self.floaters.exp_floaters.last_mut() {
|
||||
Some(floater)
|
||||
if floater.timer
|
||||
> (EXP_FLOATER_LIFETIME - EXP_ACCUMULATION_DURATION)
|
||||
&& global_state.settings.interface.accum_experience =>
|
||||
{
|
||||
floater.jump_timer = 0.0;
|
||||
floater.exp_change += *exp;
|
||||
},
|
||||
_ => self.floaters.exp_floaters.push(ExpFloater {
|
||||
exp_change: *exp,
|
||||
timer: EXP_FLOATER_LIFETIME,
|
||||
jump_timer: 0.0,
|
||||
rand_offset: rand::thread_rng().gen::<(f32, f32)>(),
|
||||
xp_pools: xp_pools.clone(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
},
|
||||
Outcome::SkillPointGain {
|
||||
@ -4395,7 +4392,7 @@ impl Hud {
|
||||
timer: 1.0,
|
||||
})
|
||||
},
|
||||
Outcome::Damage { info, .. } => {
|
||||
Outcome::HealthChange { info, .. } => {
|
||||
let ecs = client.state().ecs();
|
||||
let mut hp_floater_lists = ecs.write_storage::<vcomp::HpFloaterList>();
|
||||
let uids = ecs.read_storage::<Uid>();
|
||||
@ -4404,7 +4401,9 @@ impl Hud {
|
||||
|
||||
if let Some(entity) = ecs.entity_from_uid(info.target.0) {
|
||||
if let Some(floater_list) = hp_floater_lists.get_mut(entity) {
|
||||
let hit_me = my_uid.map_or(false, |&uid| info.target == uid);
|
||||
let hit_me = my_uid.map_or(false, |&uid| {
|
||||
(info.target == uid) && global_state.settings.interface.sct_inc_dmg
|
||||
});
|
||||
if match info.by {
|
||||
Some(by) => {
|
||||
let by_me = my_uid.map_or(false, |&uid| by.uid() == uid);
|
||||
@ -4437,26 +4436,27 @@ impl Hud {
|
||||
|
||||
// To separate healing and damage floaters alongside the crit and
|
||||
// non-crit ones
|
||||
let last_floater = floater_list.floaters.iter_mut().rev().find(|f| {
|
||||
(if info.amount < 0.0 {
|
||||
f.info.amount < 0.0
|
||||
} else {
|
||||
f.info.amount > 0.0
|
||||
}) && (hit_me
|
||||
// Ignore crit floaters if damage isn't incoming
|
||||
|| !f.info.crit)
|
||||
});
|
||||
let last_floater = if !info.crit || hit_me {
|
||||
floater_list.floaters.iter_mut().rev().find(|f| {
|
||||
(if info.amount < 0.0 {
|
||||
f.info.amount < 0.0
|
||||
} else {
|
||||
f.info.amount > 0.0
|
||||
}) && f.timer
|
||||
< if hit_me {
|
||||
interface.sct_inc_dmg_accum_duration
|
||||
} else {
|
||||
interface.sct_dmg_accum_duration
|
||||
}
|
||||
// Ignore crit floaters, unless the damage is incoming
|
||||
&& (hit_me || !f.info.crit)
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
match last_floater {
|
||||
Some(f)
|
||||
if f.timer < if hit_me {
|
||||
interface.sct_inc_dmg_accum_duration
|
||||
} else {
|
||||
interface.sct_dmg_accum_duration
|
||||
}
|
||||
// To avoid grouping up crits with non-crits
|
||||
&& (!info.crit || hit_me) =>
|
||||
{
|
||||
Some(f) => {
|
||||
f.jump_timer = 0.0;
|
||||
f.info.amount += info.amount;
|
||||
f.info.crit = info.crit;
|
||||
|
@ -82,6 +82,8 @@ widget_ids! {
|
||||
sct_dmg_accum_duration_slider,
|
||||
sct_dmg_accum_duration_text,
|
||||
sct_dmg_accum_duration_value,
|
||||
sct_show_inc_dmg_text,
|
||||
sct_show_inc_dmg_radio,
|
||||
sct_inc_dmg_accum_duration_slider,
|
||||
sct_inc_dmg_accum_duration_text,
|
||||
sct_inc_dmg_accum_duration_value,
|
||||
@ -93,6 +95,10 @@ widget_ids! {
|
||||
speech_bubble_dark_mode_button,
|
||||
speech_bubble_icon_text,
|
||||
speech_bubble_icon_button,
|
||||
//
|
||||
experience_numbers_title,
|
||||
accum_experience_text,
|
||||
accum_experience_button,
|
||||
}
|
||||
}
|
||||
|
||||
@ -710,10 +716,9 @@ impl<'a> Widget for Interface<'a> {
|
||||
/*Scrolling Combat text
|
||||
|
||||
O Show Damage Numbers
|
||||
O Damage Accumulation Duration: 0s ----I----2s
|
||||
O Show incoming Damage
|
||||
O Damage Accumulation Duration: 0s ----I----2s
|
||||
O Show incoming Damage -- //TODO: add this back
|
||||
O Incoming Damage Accumulation Duration: 0s ----I----2s
|
||||
O Batch incoming Numbers
|
||||
O Round Damage Numbers
|
||||
*/
|
||||
// SCT/ Scrolling Combat Text
|
||||
@ -796,40 +801,67 @@ impl<'a> Widget for Interface<'a> {
|
||||
.color(TEXT_COLOR)
|
||||
.set(state.ids.sct_dmg_accum_duration_value, ui);
|
||||
|
||||
Text::new(
|
||||
self.localized_strings
|
||||
.get("hud.settings.incoming_damage_accumulation_duration"),
|
||||
// Conditionally toggle incoming damage
|
||||
let show_inc_dmg = ToggleButton::new(
|
||||
self.global_state.settings.interface.sct_inc_dmg,
|
||||
self.imgs.checkbox,
|
||||
self.imgs.checkbox_checked,
|
||||
)
|
||||
.w_h(18.0, 18.0)
|
||||
.down_from(state.ids.sct_dmg_accum_duration_slider, 8.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);
|
||||
.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_inc_dmg_radio, 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));
|
||||
if self.global_state.settings.interface.sct_inc_dmg != show_inc_dmg {
|
||||
events.push(SctIncomingDamage(
|
||||
!self.global_state.settings.interface.sct_inc_dmg,
|
||||
))
|
||||
}
|
||||
|
||||
Text::new(&format!("{:.2}", sct_inc_dmg_accum_duration,))
|
||||
.right_from(state.ids.sct_inc_dmg_accum_duration_slider, 8.0)
|
||||
Text::new(self.localized_strings.get("hud.settings.incoming_damage"))
|
||||
.right_from(state.ids.sct_show_inc_dmg_radio, 10.0)
|
||||
.font_size(self.fonts.cyri.scale(14))
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.graphics_for(state.ids.sct_show_inc_dmg_radio)
|
||||
.color(TEXT_COLOR)
|
||||
.set(state.ids.sct_show_inc_dmg_text, ui);
|
||||
if self.global_state.settings.interface.sct_inc_dmg {
|
||||
Text::new(
|
||||
self.localized_strings
|
||||
.get("hud.settings.incoming_damage_accumulation_duration"),
|
||||
)
|
||||
.down_from(state.ids.sct_show_inc_dmg_radio, 8.0)
|
||||
.right_from(state.ids.sct_show_inc_dmg_radio, 10.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);
|
||||
.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);
|
||||
}
|
||||
|
||||
// Round Damage
|
||||
let show_sct_damage_rounding = ToggleButton::new(
|
||||
@ -838,7 +870,15 @@ impl<'a> Widget for Interface<'a> {
|
||||
self.imgs.checkbox_checked,
|
||||
)
|
||||
.w_h(18.0, 18.0)
|
||||
.down_from(state.ids.sct_inc_dmg_accum_duration_slider, 8.0)
|
||||
.down_from(
|
||||
if self.global_state.settings.interface.sct_inc_dmg {
|
||||
state.ids.sct_inc_dmg_accum_duration_slider
|
||||
} else {
|
||||
state.ids.sct_show_inc_dmg_radio
|
||||
},
|
||||
8.0,
|
||||
)
|
||||
.x_align_to(state.ids.sct_show_inc_dmg_radio, Align::Start)
|
||||
.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_round_dmg_radio, ui);
|
||||
@ -1072,6 +1112,46 @@ impl<'a> Widget for Interface<'a> {
|
||||
.color(TEXT_COLOR)
|
||||
.set(state.ids.always_show_bars_label, ui);
|
||||
|
||||
// Experience Numbers
|
||||
Text::new(
|
||||
self.localized_strings
|
||||
.get("hud.settings.experience_numbers"),
|
||||
)
|
||||
.down_from(state.ids.always_show_bars_button, 20.0)
|
||||
.font_size(self.fonts.cyri.scale(18))
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(TEXT_COLOR)
|
||||
.set(state.ids.experience_numbers_title, ui);
|
||||
|
||||
// Acuumulate Experience Gained
|
||||
let accum_experience = ToggleButton::new(
|
||||
self.global_state.settings.interface.accum_experience,
|
||||
self.imgs.checkbox,
|
||||
self.imgs.checkbox_checked,
|
||||
)
|
||||
.w_h(18.0, 18.0)
|
||||
.down_from(state.ids.experience_numbers_title, 8.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.accum_experience_button, ui);
|
||||
|
||||
if self.global_state.settings.interface.accum_experience != accum_experience {
|
||||
events.push(AccumExperience(
|
||||
!self.global_state.settings.interface.accum_experience,
|
||||
));
|
||||
}
|
||||
|
||||
Text::new(
|
||||
self.localized_strings
|
||||
.get("hud.settings.accumulate_experience"),
|
||||
)
|
||||
.right_from(state.ids.accum_experience_button, 10.0)
|
||||
.font_size(self.fonts.cyri.scale(14))
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.graphics_for(state.ids.accum_experience_button)
|
||||
.color(TEXT_COLOR)
|
||||
.set(state.ids.accum_experience_text, ui);
|
||||
|
||||
// Reset the interface settings to the default settings
|
||||
if Button::image(self.imgs.button)
|
||||
.w_h(RESET_BUTTONS_WIDTH, RESET_BUTTONS_HEIGHT)
|
||||
|
@ -284,7 +284,7 @@ impl ParticleMgr {
|
||||
| Outcome::ExpChange { .. }
|
||||
| Outcome::SkillPointGain { .. }
|
||||
| Outcome::ComboChange { .. }
|
||||
| Outcome::Damage { .. }
|
||||
| Outcome::HealthChange { .. }
|
||||
| Outcome::PoiseChange { .. }
|
||||
| Outcome::Utterance { .. }
|
||||
| Outcome::Glider { .. } => {},
|
||||
|
@ -98,6 +98,7 @@ pub enum Interface {
|
||||
Sct(bool),
|
||||
SctRoundDamage(bool),
|
||||
SctDamageAccumDuration(f32),
|
||||
SctIncomingDamage(bool),
|
||||
SctIncomingDamageAccumDuration(f32),
|
||||
SpeechBubbleSelf(bool),
|
||||
SpeechBubbleDarkMode(bool),
|
||||
@ -135,6 +136,7 @@ pub enum Interface {
|
||||
MapShowPeaks(bool),
|
||||
MapShowBiomes(bool),
|
||||
MapShowVoxelMap(bool),
|
||||
AccumExperience(bool),
|
||||
|
||||
ResetInterfaceSettings,
|
||||
}
|
||||
@ -464,6 +466,9 @@ impl SettingsChange {
|
||||
Interface::SctDamageAccumDuration(sct_dmg_accum_duration) => {
|
||||
settings.interface.sct_dmg_accum_duration = sct_dmg_accum_duration;
|
||||
},
|
||||
Interface::SctIncomingDamage(sct_inc_dmg_accum_duration) => {
|
||||
settings.interface.sct_inc_dmg = sct_inc_dmg_accum_duration;
|
||||
},
|
||||
Interface::SctIncomingDamageAccumDuration(sct_inc_dmg_accum_duration) => {
|
||||
settings.interface.sct_inc_dmg_accum_duration = sct_inc_dmg_accum_duration;
|
||||
},
|
||||
@ -563,6 +568,9 @@ impl SettingsChange {
|
||||
Interface::MapShowVoxelMap(map_show_voxel_map) => {
|
||||
settings.interface.map_show_voxel_map = map_show_voxel_map;
|
||||
},
|
||||
Interface::AccumExperience(accum_experience) => {
|
||||
settings.interface.accum_experience = accum_experience;
|
||||
},
|
||||
Interface::ResetInterfaceSettings => {
|
||||
// Reset Interface Settings
|
||||
let tmp = settings.interface.intro_show;
|
||||
|
@ -17,6 +17,7 @@ pub struct InterfaceSettings {
|
||||
pub sct: bool,
|
||||
pub sct_damage_rounding: bool,
|
||||
pub sct_dmg_accum_duration: f32,
|
||||
pub sct_inc_dmg: bool,
|
||||
pub sct_inc_dmg_accum_duration: f32,
|
||||
pub speech_bubble_self: bool,
|
||||
pub speech_bubble_dark_mode: bool,
|
||||
@ -45,6 +46,7 @@ pub struct InterfaceSettings {
|
||||
pub minimap_show: bool,
|
||||
pub minimap_face_north: bool,
|
||||
pub minimap_zoom: f64,
|
||||
pub accum_experience: bool,
|
||||
}
|
||||
|
||||
impl Default for InterfaceSettings {
|
||||
@ -58,6 +60,7 @@ impl Default for InterfaceSettings {
|
||||
sct: true,
|
||||
sct_damage_rounding: false,
|
||||
sct_dmg_accum_duration: 0.45,
|
||||
sct_inc_dmg: true,
|
||||
sct_inc_dmg_accum_duration: 0.45,
|
||||
speech_bubble_self: true,
|
||||
speech_bubble_dark_mode: false,
|
||||
@ -86,6 +89,7 @@ impl Default for InterfaceSettings {
|
||||
minimap_show: true,
|
||||
minimap_face_north: true,
|
||||
minimap_zoom: 160.0,
|
||||
accum_experience: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user