mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Addressed comments, health and damage floaters are now separated
Enemy healing probably needs to be discussed as it doesn't show up as of now and the way crits are handled also needs to be discussed
This commit is contained in:
parent
94f193fbe0
commit
ce95680df9
@ -11,7 +11,7 @@ use crate::{
|
||||
Player, Poise, PoiseChange, SkillSet, Stats,
|
||||
},
|
||||
event::ServerEvent,
|
||||
outcome::{DamageInfo, Outcome},
|
||||
outcome::Outcome,
|
||||
states::utils::StageSection,
|
||||
uid::{Uid, UidAllocator},
|
||||
util::Dir,
|
||||
@ -240,7 +240,6 @@ impl Attack {
|
||||
accumulated_damage += applied_damage;
|
||||
|
||||
if change.amount.abs() > Health::HEALTH_EPSILON {
|
||||
|
||||
emit(ServerEvent::HealthChange {
|
||||
entity: target.entity,
|
||||
change,
|
||||
@ -258,7 +257,7 @@ impl Attack {
|
||||
by: attacker.map(|x| x.into()),
|
||||
cause: Some(damage.damage.source),
|
||||
time,
|
||||
crit: None,
|
||||
crit: Some(is_crit),
|
||||
};
|
||||
emit(ServerEvent::HealthChange {
|
||||
entity: target.entity,
|
||||
|
@ -24,7 +24,8 @@ pub struct HealthChange {
|
||||
pub cause: Option<DamageSource>,
|
||||
/// The time that the health change occurred at
|
||||
pub time: Time,
|
||||
/// Whether or not the health change was caused by a crit (None if it couldn't have been a crit)
|
||||
/// Whether or not the health change was caused by a crit (None if it
|
||||
/// couldn't have been a crit)
|
||||
pub crit: Option<bool>,
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::{comp, uid::Uid, combat::DamageContributor};
|
||||
use crate::{combat::DamageContributor, comp, uid::Uid};
|
||||
use comp::{beam, item::Reagent, poise::PoiseState, skillset::SkillGroupKind, UtteranceKind};
|
||||
use hashbrown::HashSet;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
@ -77,20 +77,21 @@ pub fn handle_health_change(server: &Server, entity: EcsEntity, change: HealthCh
|
||||
if let Some(agent) = ecs.write_storage::<Agent>().get_mut(entity) {
|
||||
agent.inbox.push_front(AgentEvent::Hurt);
|
||||
}
|
||||
dbg!("hit");
|
||||
dbg!(change);
|
||||
// TODO: This will currently fuck up with healing
|
||||
if let (Some(pos), Some(uid)) = (ecs.read_storage::<Pos>().get(entity), ecs.read_storage::<Uid>().get(entity)) {
|
||||
dbg!(change.amount);
|
||||
outcomes.push(Outcome::Damage{
|
||||
pos: pos.0,
|
||||
info: DamageInfo {
|
||||
amount: change.amount,
|
||||
crit: change.crit,
|
||||
by: change.by,
|
||||
target: *uid,
|
||||
}
|
||||
});
|
||||
if let (Some(pos), Some(uid)) = (
|
||||
ecs.read_storage::<Pos>().get(entity),
|
||||
ecs.read_storage::<Uid>().get(entity),
|
||||
) {
|
||||
if change.amount.abs() > Health::HEALTH_EPSILON {
|
||||
outcomes.push(Outcome::Damage {
|
||||
pos: pos.0,
|
||||
info: DamageInfo {
|
||||
amount: change.amount,
|
||||
crit: change.crit,
|
||||
by: change.by,
|
||||
target: *uid,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -95,8 +95,8 @@ use common::{
|
||||
item::{ItemDefinitionId, ItemKind, ToolKind},
|
||||
object,
|
||||
poise::PoiseState,
|
||||
quadruped_low, quadruped_medium, quadruped_small, Body, CharacterAbilityType,
|
||||
InventoryUpdateEvent, UtteranceKind, Health,
|
||||
quadruped_low, quadruped_medium, quadruped_small, Body, CharacterAbilityType, Health,
|
||||
InventoryUpdateEvent, UtteranceKind,
|
||||
},
|
||||
outcome::Outcome,
|
||||
terrain::{BlockKind, TerrainChunk},
|
||||
|
@ -16,9 +16,7 @@ pub struct HpFloater {
|
||||
pub struct HpFloaterList {
|
||||
// Order oldest to newest
|
||||
pub floaters: Vec<HpFloater>,
|
||||
// Keep from spawning more floaters from same hp change
|
||||
// Note: this can't detect a change if equivalent healing and damage take place simultaneously
|
||||
pub last_hp: f32,
|
||||
|
||||
// The time since you last damaged this entity
|
||||
// Used to display nametags outside normal range if this time is below a certain value
|
||||
pub time_since_last_dmg_by_me: Option<f32>,
|
||||
|
@ -34,18 +34,18 @@ impl<'a> System<'a> for Sys {
|
||||
) {
|
||||
// Add hp floater lists to all entities with health and a position
|
||||
// Note: necessary in order to know last_hp
|
||||
for (entity, last_hp) in (&entities, &healths, &pos, !&hp_floater_lists)
|
||||
for entity in (&entities, &healths, &pos, !&hp_floater_lists)
|
||||
.join()
|
||||
.map(|(e, h, _, _)| (e, h.current()))
|
||||
.map(|(e, _, _, _)| e)
|
||||
.collect::<Vec<_>>()
|
||||
{
|
||||
let _ = hp_floater_lists.insert(entity, HpFloaterList {
|
||||
floaters: Vec::new(),
|
||||
last_hp,
|
||||
time_since_last_dmg_by_me: None,
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: avoid join??
|
||||
for hp_floater_list in (&mut hp_floater_lists).join() {
|
||||
// Increment timer for time since last damaged by me
|
||||
hp_floater_list
|
||||
@ -74,9 +74,7 @@ impl<'a> System<'a> for Sys {
|
||||
for (
|
||||
entity,
|
||||
HpFloaterList {
|
||||
ref mut floaters,
|
||||
ref last_hp,
|
||||
..
|
||||
ref mut floaters, ..
|
||||
},
|
||||
) in (&entities, &mut hp_floater_lists).join()
|
||||
{
|
||||
@ -92,7 +90,7 @@ impl<'a> System<'a> for Sys {
|
||||
} else {
|
||||
MY_HP_SHOWTIME
|
||||
}
|
||||
|| last_hp.abs() < Health::HEALTH_EPSILON
|
||||
//|| last_hp.abs() < Health::HEALTH_EPSILON;
|
||||
}) {
|
||||
floaters.clear();
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ use common::{
|
||||
loot_owner::LootOwnerKind,
|
||||
pet::is_mountable,
|
||||
skillset::{skills::Skill, SkillGroupKind},
|
||||
BuffData, BuffKind, Item, MapMarkerChange,
|
||||
BuffData, BuffKind, Health, Item, MapMarkerChange,
|
||||
},
|
||||
consts::MAX_PICKUP_RANGE,
|
||||
link::Is,
|
||||
@ -1422,61 +1422,69 @@ impl Hud {
|
||||
&mut ui_widgets.widget_id_generator(),
|
||||
);
|
||||
|
||||
// Calculate total change
|
||||
// Ignores healing
|
||||
let hp_damage: f32 = floaters.iter().map(|f| f.info.amount.min(0.0)).sum();
|
||||
// Because only the Damage HpFloaters are batched
|
||||
// and would result in the wrong timers/crit info being used
|
||||
let damage_floaters: Vec<&HpFloater> =
|
||||
floaters.iter().filter(|f| f.info.amount < 0.0).collect();
|
||||
|
||||
// .fold(0.0, |acc, f| f.info.amount.min(0.0) + acc);
|
||||
let hp_dmg_rounded_abs = hp_damage.round().abs() as u32;
|
||||
let max_hp_frac = hp_damage.abs() as f32 / health.maximum() as f32;
|
||||
let timer = floaters
|
||||
.last()
|
||||
.expect("There must be at least one floater")
|
||||
.timer;
|
||||
let crit = floaters
|
||||
.last()
|
||||
.expect("There must be at least one floater")
|
||||
.info
|
||||
.crit
|
||||
.map_or(false, |c| c);
|
||||
// Increase font size based on fraction of maximum health
|
||||
// "flashes" by having a larger size in the first 100ms
|
||||
let font_size = 30
|
||||
+ ((max_hp_frac * 10.0) as u32) * 3 * if crit { 2 } else { 1 }
|
||||
+ if timer < 0.1 {
|
||||
FLASH_MAX * (((1.0 - timer / 0.1) * 10.0) as u32)
|
||||
} else {
|
||||
0
|
||||
};
|
||||
// Timer sets the widget offset
|
||||
let y = timer as f64 * number_speed * -1.0;
|
||||
// Timer sets text transparency
|
||||
let hp_fade =
|
||||
((crate::ecs::sys::floater::MY_HP_SHOWTIME - timer) * 0.25) + 0.2;
|
||||
Text::new(&format!("{}", hp_dmg_rounded_abs))
|
||||
.font_size(font_size)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(if hp_damage < 0.0 {
|
||||
Color::Rgba(0.0, 0.0, 0.0, hp_fade)
|
||||
} else {
|
||||
Color::Rgba(0.0, 0.0, 0.0, 0.0)
|
||||
})
|
||||
.mid_bottom_with_margin_on(ui_widgets.window, 297.0 + y)
|
||||
.set(player_sct_bg_id, ui_widgets);
|
||||
Text::new(&format!("{}", hp_dmg_rounded_abs))
|
||||
.font_size(font_size)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(if hp_damage < 0.0 {
|
||||
if crit {
|
||||
Color::Rgba(1.0, 0.9, 0.1, hp_fade)
|
||||
if !damage_floaters.is_empty() {
|
||||
// Calculate total change
|
||||
// Ignores healing
|
||||
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_rounded_abs = hp_damage.round().abs() as u32;
|
||||
let max_hp_frac = hp_damage.abs() / health.maximum();
|
||||
|
||||
let timer = damage_floaters
|
||||
.last()
|
||||
.expect("There must be at least one floater")
|
||||
.timer;
|
||||
let crit = damage_floaters
|
||||
.last()
|
||||
.and_then(|f| f.info.crit)
|
||||
.unwrap_or(false);
|
||||
|
||||
// Increase font size based on fraction of maximum health
|
||||
// "flashes" by having a larger size in the first 100ms
|
||||
let font_size = 30
|
||||
+ ((max_hp_frac * 10.0) as u32) * 3 * if crit { 2 } else { 1 }
|
||||
+ if timer < 0.1 {
|
||||
FLASH_MAX * (((1.0 - timer / 0.1) * 10.0) as u32)
|
||||
} else {
|
||||
Color::Rgba(1.0, 0.1, 0.0, hp_fade)
|
||||
}
|
||||
} else {
|
||||
Color::Rgba(0.0, 0.0, 0.0, 0.0)
|
||||
})
|
||||
.mid_bottom_with_margin_on(ui_widgets.window, 300.0 + y)
|
||||
.set(player_sct_id, ui_widgets);
|
||||
0
|
||||
};
|
||||
// Timer sets the widget offset
|
||||
let y = timer as f64 * number_speed * -1.0;
|
||||
// Timer sets text transparency
|
||||
let hp_fade =
|
||||
((crate::ecs::sys::floater::MY_HP_SHOWTIME - timer) * 0.25) + 0.2;
|
||||
Text::new(&format!("{}", hp_dmg_rounded_abs))
|
||||
.font_size(font_size)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(if hp_damage < 0.0 {
|
||||
Color::Rgba(0.0, 0.0, 0.0, hp_fade)
|
||||
} else {
|
||||
Color::Rgba(0.0, 0.0, 0.0, 0.0)
|
||||
})
|
||||
.mid_bottom_with_margin_on(ui_widgets.window, 297.0 + y)
|
||||
.set(player_sct_bg_id, ui_widgets);
|
||||
Text::new(&format!("{}", hp_dmg_rounded_abs))
|
||||
.font_size(font_size)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(if hp_damage < 0.0 {
|
||||
if crit {
|
||||
Color::Rgba(1.0, 0.9, 0.1, hp_fade)
|
||||
} else {
|
||||
Color::Rgba(1.0, 0.1, 0.0, hp_fade)
|
||||
}
|
||||
} else {
|
||||
Color::Rgba(0.0, 0.0, 0.0, 0.0)
|
||||
})
|
||||
.mid_bottom_with_margin_on(ui_widgets.window, 300.0 + y)
|
||||
.set(player_sct_id, ui_widgets);
|
||||
}
|
||||
};
|
||||
for floater in floaters {
|
||||
// Healing always single numbers so just skip damage when in batch mode
|
||||
@ -1495,16 +1503,13 @@ impl Hud {
|
||||
&mut self.ids.player_scts,
|
||||
&mut ui_widgets.widget_id_generator(),
|
||||
);
|
||||
let max_hp_frac =
|
||||
floater.info.amount.abs() as f32 / health.maximum() as f32;
|
||||
let max_hp_frac = floater.info.amount.abs() / health.maximum();
|
||||
let crit = floater.info.crit.map_or(false, |c| c);
|
||||
// Increase font size based on fraction of maximum health
|
||||
// "flashes" by having a larger size in the first 100ms
|
||||
// TODO: example
|
||||
let font_size = 30
|
||||
+ ((max_hp_frac * 10.0) as u32)
|
||||
* 3
|
||||
* if crit { 2 } else { 1 }
|
||||
+ ((max_hp_frac * 10.0) as u32) * 3 * if crit { 2 } else { 1 }
|
||||
+ if floater.timer < 0.1 {
|
||||
// TODO: Maybe change font size wrt crits here?
|
||||
FLASH_MAX * (((1.0 - floater.timer / 0.1) * 10.0) as u32)
|
||||
@ -1618,7 +1623,7 @@ impl Hud {
|
||||
//let fade = ((4.0 - floater.timer as f32) * 0.25) + 0.2; // Timer sets
|
||||
// text transparency
|
||||
let fade = if floater.timer < 1.0 {
|
||||
floater.timer as f32
|
||||
floater.timer
|
||||
} else {
|
||||
1.0
|
||||
};
|
||||
@ -1680,9 +1685,9 @@ impl Hud {
|
||||
.find(|d| d.owner == *uid)
|
||||
{
|
||||
let fade = if display.timer < 3.0 {
|
||||
display.timer as f32 * 0.33
|
||||
display.timer * 0.33
|
||||
} else if display.timer < 2.0 {
|
||||
display.timer as f32 * 0.33 * 0.1
|
||||
display.timer * 0.33 * 0.1
|
||||
} else {
|
||||
1.0
|
||||
};
|
||||
@ -1794,7 +1799,7 @@ impl Hud {
|
||||
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
|
||||
floater.timer / 0.25
|
||||
} else {
|
||||
1.0
|
||||
};
|
||||
@ -2244,91 +2249,94 @@ impl Hud {
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: Might have to change something here as well
|
||||
if global_state.settings.interface.sct_damage_batch {
|
||||
let number_speed = 50.0; // Damage 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
|
||||
.next(&mut self.ids.sct_bgs, &mut ui_widgets.widget_id_generator());
|
||||
// Calculate total change
|
||||
// Ignores healing
|
||||
let hp_damage = floaters.iter().fold(0.0, |acc, f| {
|
||||
if f.info.amount < 0.0 {
|
||||
acc + f.info.amount
|
||||
} else {
|
||||
acc
|
||||
}
|
||||
});
|
||||
let hp_dmg_rounded_abs = hp_damage.round().abs();
|
||||
let max_hp_frac = hp_damage.abs() / health.map_or(1.0, |h| h.maximum());
|
||||
let timer = floaters
|
||||
.last()
|
||||
.expect("There must be at least one floater")
|
||||
.timer;
|
||||
let crit = floaters
|
||||
.last()
|
||||
.expect("There must be at least one floater")
|
||||
.info
|
||||
.crit
|
||||
.map_or(false, |c| c);
|
||||
// Increase font size based on fraction of maximum health
|
||||
// "flashes" by having a larger size in the first 100ms
|
||||
let font_size = 30
|
||||
+ ((max_hp_frac * 10.0) as u32) * 3 * if crit { 2 } else { 1 }
|
||||
+ if timer < 0.1 {
|
||||
FLASH_MAX * (((1.0 - timer / 0.1) * 10.0) as u32)
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let font_col = font_col(font_size, crit);
|
||||
// Timer sets the widget offset
|
||||
let y = (timer as f64 / crate::ecs::sys::floater::HP_SHOWTIME as f64
|
||||
* number_speed)
|
||||
+ 100.0;
|
||||
// Timer sets text transparency
|
||||
let fade = ((crate::ecs::sys::floater::HP_SHOWTIME - timer) * 0.25) + 0.2;
|
||||
if hp_damage.abs() < 1.0 {
|
||||
// Damage and heal below 10/10 are shown as decimals
|
||||
Text::new(&format!("{}", hp_damage.abs()))
|
||||
.font_size(font_size)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(Color::Rgba(0.0, 0.0, 0.0, fade))
|
||||
.x_y(0.0, y - 3.0)
|
||||
.position_ingame(ingame_pos)
|
||||
.set(sct_bg_id, ui_widgets);
|
||||
Text::new(&format!("{}", hp_damage.abs()))
|
||||
.font_size(font_size)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.x_y(0.0, y)
|
||||
.color(if hp_damage < 0.0 {
|
||||
Color::Rgba(font_col.r, font_col.g, font_col.b, fade)
|
||||
} else {
|
||||
Color::Rgba(0.1, 1.0, 0.1, fade)
|
||||
})
|
||||
.position_ingame(ingame_pos)
|
||||
.set(sct_id, ui_widgets);
|
||||
} else {
|
||||
// Damage and heal above 10/10 are shown rounded
|
||||
Text::new(&format!("{}", hp_dmg_rounded_abs))
|
||||
.font_size(font_size)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(Color::Rgba(0.0, 0.0, 0.0, fade))
|
||||
.x_y(0.0, y - 3.0)
|
||||
.position_ingame(ingame_pos)
|
||||
.set(sct_bg_id, ui_widgets);
|
||||
|
||||
Text::new(&format!("{}", hp_dmg_rounded_abs))
|
||||
.font_size(font_size)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.x_y(0.0, y)
|
||||
.color(if hp_damage < 0.0 {
|
||||
Color::Rgba(font_col.r, font_col.g, font_col.b, fade)
|
||||
let damage_floaters: Vec<&HpFloater> =
|
||||
floaters.iter().filter(|f| f.info.amount < 0.0).collect();
|
||||
|
||||
if !damage_floaters.is_empty() {
|
||||
// Calculate total change
|
||||
// Ignores healing
|
||||
let hp_damage: f32 =
|
||||
damage_floaters.iter().map(|fl| fl.info.amount).sum();
|
||||
let hp_dmg_rounded_abs = hp_damage.round().abs();
|
||||
let max_hp_frac = hp_damage.abs() / health.map_or(1.0, |h| h.maximum());
|
||||
let timer = damage_floaters
|
||||
.last()
|
||||
.expect("There must be at least one floater")
|
||||
.timer;
|
||||
let crit = damage_floaters
|
||||
.last()
|
||||
.and_then(|f| f.info.crit)
|
||||
.unwrap_or(false);
|
||||
|
||||
// Increase font size based on fraction of maximum health
|
||||
// "flashes" by having a larger size in the first 100ms
|
||||
let font_size = 30
|
||||
+ ((max_hp_frac * 10.0) as u32) * 3 * if crit { 2 } else { 1 }
|
||||
+ if timer < 0.1 {
|
||||
FLASH_MAX * (((1.0 - timer / 0.1) * 10.0) as u32)
|
||||
} else {
|
||||
Color::Rgba(0.1, 1.0, 0.1, fade)
|
||||
})
|
||||
.position_ingame(ingame_pos)
|
||||
.set(sct_id, ui_widgets);
|
||||
};
|
||||
0
|
||||
};
|
||||
let font_col = font_col(font_size, crit);
|
||||
// Timer sets the widget offset
|
||||
let y = (timer as f64 / crate::ecs::sys::floater::HP_SHOWTIME as f64
|
||||
* number_speed)
|
||||
+ 100.0;
|
||||
// Timer sets text transparency
|
||||
let fade =
|
||||
((crate::ecs::sys::floater::HP_SHOWTIME - timer) * 0.25) + 0.2;
|
||||
// TODO: Can the Healing variant even be reached as healing is ignored?
|
||||
if hp_damage.abs() < 1.0 {
|
||||
// Damage and heal below 10/10 are shown as decimals
|
||||
Text::new(&format!("{}", hp_damage.abs()))
|
||||
.font_size(font_size)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(Color::Rgba(0.0, 0.0, 0.0, fade))
|
||||
.x_y(0.0, y - 3.0)
|
||||
.position_ingame(ingame_pos)
|
||||
.set(sct_bg_id, ui_widgets);
|
||||
Text::new(&format!("{}", hp_damage.abs()))
|
||||
.font_size(font_size)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.x_y(0.0, y)
|
||||
.color(if hp_damage < 0.0 {
|
||||
Color::Rgba(font_col.r, font_col.g, font_col.b, fade)
|
||||
} else {
|
||||
Color::Rgba(0.1, 1.0, 0.1, fade)
|
||||
})
|
||||
.position_ingame(ingame_pos)
|
||||
.set(sct_id, ui_widgets);
|
||||
} else {
|
||||
// Damage and heal above 10/10 are shown rounded
|
||||
Text::new(&format!("{}", hp_dmg_rounded_abs))
|
||||
.font_size(font_size)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(Color::Rgba(0.0, 0.0, 0.0, fade))
|
||||
.x_y(0.0, y - 3.0)
|
||||
.position_ingame(ingame_pos)
|
||||
.set(sct_bg_id, ui_widgets);
|
||||
|
||||
Text::new(&format!("{}", hp_dmg_rounded_abs))
|
||||
.font_size(font_size)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.x_y(0.0, y)
|
||||
.color(if hp_damage < 0.0 {
|
||||
Color::Rgba(font_col.r, font_col.g, font_col.b, fade)
|
||||
} else {
|
||||
Color::Rgba(0.1, 1.0, 0.1, fade)
|
||||
})
|
||||
.position_ingame(ingame_pos)
|
||||
.set(sct_id, ui_widgets);
|
||||
};
|
||||
}
|
||||
} else {
|
||||
for floater in floaters {
|
||||
let number_speed = 250.0; // Single Numbers Speed
|
||||
@ -2337,15 +2345,13 @@ impl Hud {
|
||||
let sct_bg_id = sct_bg_walker
|
||||
.next(&mut self.ids.sct_bgs, &mut ui_widgets.widget_id_generator());
|
||||
// Calculate total change
|
||||
let max_hp_frac = floater.info.amount.abs() as f32
|
||||
/ health.map_or(1.0, |h| h.maximum() as f32);
|
||||
let max_hp_frac =
|
||||
floater.info.amount.abs() / health.map_or(1.0, |h| h.maximum());
|
||||
let crit = floater.info.crit.map_or(false, |c| c);
|
||||
// Increase font size based on fraction of maximum health
|
||||
// "flashes" by having a larger size in the first 100ms
|
||||
let font_size = 30
|
||||
+ ((max_hp_frac * 10.0) as u32)
|
||||
* 3
|
||||
* if crit { 2 } else { 1 }
|
||||
+ ((max_hp_frac * 10.0) as u32) * 3 * if crit { 2 } else { 1 }
|
||||
+ if floater.timer < 0.1 {
|
||||
FLASH_MAX * (((1.0 - floater.timer / 0.1) * 10.0) as u32)
|
||||
} else {
|
||||
@ -4550,12 +4556,21 @@ impl Hud {
|
||||
}
|
||||
hit_me || by_me
|
||||
},
|
||||
None => {
|
||||
hit_me
|
||||
},
|
||||
None => hit_me,
|
||||
} {
|
||||
// TODO: This will currently fuck up with healing
|
||||
let last_floater = floater_list.floaters.last_mut();
|
||||
let last_floater = if info.amount < Health::HEALTH_EPSILON {
|
||||
floater_list
|
||||
.floaters
|
||||
.iter_mut()
|
||||
.rev()
|
||||
.find(|f| f.info.amount < Health::HEALTH_EPSILON)
|
||||
} else {
|
||||
floater_list
|
||||
.floaters
|
||||
.iter_mut()
|
||||
.rev()
|
||||
.find(|f| f.info.amount > Health::HEALTH_EPSILON)
|
||||
};
|
||||
match last_floater {
|
||||
Some(f) if f.timer < floater::HP_ACCUMULATETIME => {
|
||||
//TODO: Add "jumping" animation on floater when it changes its
|
||||
|
Loading…
Reference in New Issue
Block a user