mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Some changes to DamageSources + various code qual changes
This commit is contained in:
@ -152,6 +152,8 @@ pub enum BuffEffect {
|
|||||||
rate: f32,
|
rate: f32,
|
||||||
accumulated: f32,
|
accumulated: f32,
|
||||||
kind: ModifierKind,
|
kind: ModifierKind,
|
||||||
|
// TODO: Change hud/mod.rs to account for over time changes???
|
||||||
|
instance: u64,
|
||||||
},
|
},
|
||||||
/// Periodically consume entity energy
|
/// Periodically consume entity energy
|
||||||
EnergyChangeOverTime {
|
EnergyChangeOverTime {
|
||||||
@ -234,12 +236,14 @@ impl Buff {
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
// Normalized nonlinear scaling
|
// Normalized nonlinear scaling
|
||||||
let nn_scaling = |a| a / (a + 0.5);
|
let nn_scaling = |a| a / (a + 0.5);
|
||||||
|
let instance = rand::random();
|
||||||
let (effects, time) = match kind {
|
let (effects, time) = match kind {
|
||||||
BuffKind::Bleeding => (
|
BuffKind::Bleeding => (
|
||||||
vec![BuffEffect::HealthChangeOverTime {
|
vec![BuffEffect::HealthChangeOverTime {
|
||||||
rate: -data.strength,
|
rate: -data.strength,
|
||||||
accumulated: 0.0,
|
accumulated: 0.0,
|
||||||
kind: ModifierKind::Additive,
|
kind: ModifierKind::Additive,
|
||||||
|
instance,
|
||||||
}],
|
}],
|
||||||
data.duration,
|
data.duration,
|
||||||
),
|
),
|
||||||
@ -248,6 +252,7 @@ impl Buff {
|
|||||||
rate: data.strength,
|
rate: data.strength,
|
||||||
accumulated: 0.0,
|
accumulated: 0.0,
|
||||||
kind: ModifierKind::Additive,
|
kind: ModifierKind::Additive,
|
||||||
|
instance,
|
||||||
}],
|
}],
|
||||||
data.duration,
|
data.duration,
|
||||||
),
|
),
|
||||||
@ -256,6 +261,7 @@ impl Buff {
|
|||||||
rate: data.strength,
|
rate: data.strength,
|
||||||
accumulated: 0.0,
|
accumulated: 0.0,
|
||||||
kind: ModifierKind::Fractional,
|
kind: ModifierKind::Fractional,
|
||||||
|
instance,
|
||||||
}],
|
}],
|
||||||
data.duration,
|
data.duration,
|
||||||
),
|
),
|
||||||
@ -271,6 +277,7 @@ impl Buff {
|
|||||||
rate: -1.0,
|
rate: -1.0,
|
||||||
accumulated: 0.0,
|
accumulated: 0.0,
|
||||||
kind: ModifierKind::Additive,
|
kind: ModifierKind::Additive,
|
||||||
|
instance,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
data.duration,
|
data.duration,
|
||||||
@ -304,6 +311,7 @@ impl Buff {
|
|||||||
rate: -data.strength,
|
rate: -data.strength,
|
||||||
accumulated: 0.0,
|
accumulated: 0.0,
|
||||||
kind: ModifierKind::Additive,
|
kind: ModifierKind::Additive,
|
||||||
|
instance,
|
||||||
}],
|
}],
|
||||||
data.duration,
|
data.duration,
|
||||||
),
|
),
|
||||||
@ -322,6 +330,7 @@ impl Buff {
|
|||||||
rate: -data.strength * 4.0,
|
rate: -data.strength * 4.0,
|
||||||
accumulated: 0.0,
|
accumulated: 0.0,
|
||||||
kind: ModifierKind::Additive,
|
kind: ModifierKind::Additive,
|
||||||
|
instance,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
data.duration,
|
data.duration,
|
||||||
@ -333,6 +342,7 @@ impl Buff {
|
|||||||
rate: data.strength * 10.0,
|
rate: data.strength * 10.0,
|
||||||
accumulated: 0.0,
|
accumulated: 0.0,
|
||||||
kind: ModifierKind::Additive,
|
kind: ModifierKind::Additive,
|
||||||
|
instance,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
data.duration,
|
data.duration,
|
||||||
|
@ -27,9 +27,6 @@ pub struct HealthChange {
|
|||||||
/// The crit multiplier (None if it isn't a crit)
|
/// The crit multiplier (None if it isn't a crit)
|
||||||
pub crit_mult: Option<f32>,
|
pub crit_mult: Option<f32>,
|
||||||
/// A random ID, used to group up health changes
|
/// A random ID, used to group up health changes
|
||||||
// Note: Two or more changes could have the same instance number, if they
|
|
||||||
// came from the same attack (for example - the extra damage caused by
|
|
||||||
// slashing weapons)
|
|
||||||
pub instance: u64,
|
pub instance: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::{combat::DamageContributor, comp, uid::Uid};
|
use crate::{combat::DamageContributor, comp, uid::Uid, DamageSource};
|
||||||
use comp::{beam, item::Reagent, poise::PoiseState, skillset::SkillGroupKind, UtteranceKind};
|
use comp::{beam, item::Reagent, poise::PoiseState, skillset::SkillGroupKind, UtteranceKind};
|
||||||
use hashbrown::HashSet;
|
use hashbrown::HashSet;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -11,6 +11,7 @@ pub struct DamageInfo {
|
|||||||
pub target: Uid,
|
pub target: Uid,
|
||||||
pub by: Option<DamageContributor>,
|
pub by: Option<DamageContributor>,
|
||||||
pub instance: u64,
|
pub instance: u64,
|
||||||
|
pub cause: Option<DamageSource>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An outcome represents the final result of an instantaneous event. It implies
|
/// An outcome represents the final result of an instantaneous event. It implies
|
||||||
|
@ -241,6 +241,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
rate,
|
rate,
|
||||||
accumulated,
|
accumulated,
|
||||||
kind,
|
kind,
|
||||||
|
instance,
|
||||||
} => {
|
} => {
|
||||||
*accumulated += *rate * dt;
|
*accumulated += *rate * dt;
|
||||||
// Apply health change only once per second, per health, or
|
// Apply health change only once per second, per health, or
|
||||||
@ -248,7 +249,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
if accumulated.abs() > rate.abs().min(1.0)
|
if accumulated.abs() > rate.abs().min(1.0)
|
||||||
|| buff.time.map_or(false, |dur| dur == Duration::default())
|
|| buff.time.map_or(false, |dur| dur == Duration::default())
|
||||||
{
|
{
|
||||||
let (cause, by) = if *accumulated < 0.0 {
|
let (cause, by) = if *accumulated != 0.0 {
|
||||||
(Some(DamageSource::Buff(buff.kind)), buff_owner)
|
(Some(DamageSource::Buff(buff.kind)), buff_owner)
|
||||||
} else {
|
} else {
|
||||||
(None, None)
|
(None, None)
|
||||||
@ -275,7 +276,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
cause,
|
cause,
|
||||||
time: *read_data.time,
|
time: *read_data.time,
|
||||||
crit_mult: None,
|
crit_mult: None,
|
||||||
instance: rand::random(),
|
instance: *instance,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
*accumulated = 0.0;
|
*accumulated = 0.0;
|
||||||
|
@ -86,6 +86,7 @@ pub fn handle_health_change(server: &Server, entity: EcsEntity, change: HealthCh
|
|||||||
target: *uid,
|
target: *uid,
|
||||||
crit_mult: change.crit_mult,
|
crit_mult: change.crit_mult,
|
||||||
instance: change.instance,
|
instance: change.instance,
|
||||||
|
cause: change.cause,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -126,7 +126,6 @@ pub trait StateExt {
|
|||||||
) -> Result<(), specs::error::WrongGeneration>;
|
) -> Result<(), specs::error::WrongGeneration>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Check if this is ok
|
|
||||||
impl StateExt for State {
|
impl StateExt for State {
|
||||||
fn apply_effect(&self, entity: EcsEntity, effects: Effect, source: Option<Uid>) {
|
fn apply_effect(&self, entity: EcsEntity, effects: Effect, source: Option<Uid>) {
|
||||||
let msm = self.ecs().read_resource::<MaterialStatManifest>();
|
let msm = self.ecs().read_resource::<MaterialStatManifest>();
|
||||||
|
@ -7,7 +7,6 @@ use common_ecs::{Job, Origin, Phase, System};
|
|||||||
use specs::{Entities, Join, Read, ReadStorage, WriteStorage};
|
use specs::{Entities, Join, Read, ReadStorage, WriteStorage};
|
||||||
|
|
||||||
// How long floaters last (in seconds)
|
// How long floaters last (in seconds)
|
||||||
// Remove the accumulate times later
|
|
||||||
pub const HP_SHOWTIME: f32 = 3.0;
|
pub const HP_SHOWTIME: f32 = 3.0;
|
||||||
pub const CRIT_SHOWTIME: f32 = 0.7;
|
pub const CRIT_SHOWTIME: f32 = 0.7;
|
||||||
pub const MY_HP_SHOWTIME: f32 = 2.5;
|
pub const MY_HP_SHOWTIME: f32 = 2.5;
|
||||||
@ -34,7 +33,6 @@ impl<'a> System<'a> for Sys {
|
|||||||
(entities, my_entity, dt, pos, healths, mut hp_floater_lists): Self::SystemData,
|
(entities, my_entity, dt, pos, healths, mut hp_floater_lists): Self::SystemData,
|
||||||
) {
|
) {
|
||||||
// Add hp floater lists to all entities with health and a position
|
// Add hp floater lists to all entities with health and a position
|
||||||
// Note: necessary in order to know last_hp
|
|
||||||
for entity in (&entities, &healths, &pos, !&hp_floater_lists)
|
for entity in (&entities, &healths, &pos, !&hp_floater_lists)
|
||||||
.join()
|
.join()
|
||||||
.map(|(e, _, _, _)| e)
|
.map(|(e, _, _, _)| e)
|
||||||
@ -71,13 +69,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Maintain existing floaters
|
// Maintain existing floaters
|
||||||
for (
|
for (entity, HpFloaterList { floaters, .. }) in (&entities, &mut hp_floater_lists).join() {
|
||||||
entity,
|
|
||||||
HpFloaterList {
|
|
||||||
ref mut floaters, ..
|
|
||||||
},
|
|
||||||
) in (&entities, &mut hp_floater_lists).join()
|
|
||||||
{
|
|
||||||
for mut floater in floaters.iter_mut() {
|
for mut floater in floaters.iter_mut() {
|
||||||
// Increment timer
|
// Increment timer
|
||||||
floater.timer += dt.0;
|
floater.timer += dt.0;
|
||||||
|
@ -1412,6 +1412,20 @@ impl Hud {
|
|||||||
.filter(|fl| !fl.floaters.is_empty()),
|
.filter(|fl| !fl.floaters.is_empty()),
|
||||||
healths.get(me),
|
healths.get(me),
|
||||||
) {
|
) {
|
||||||
|
// TODO: Change both font_col closures to account for healing
|
||||||
|
let player_font_col = |hp_damage: f32, crit: bool| {
|
||||||
|
if hp_damage < 0.0 {
|
||||||
|
if crit {
|
||||||
|
// TODO: Temporary color for crits
|
||||||
|
Rgb::new(1.0, 0.9, 0.0)
|
||||||
|
} else {
|
||||||
|
Rgb::new(1.0, 0.1, 0.0)
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Rgb::new(0.1, 1.0, 0.1)
|
||||||
|
}
|
||||||
|
};
|
||||||
if global_state.settings.interface.sct_player_batch {
|
if global_state.settings.interface.sct_player_batch {
|
||||||
let number_speed = 100.0; // Player Batched Numbers Speed
|
let number_speed = 100.0; // Player Batched Numbers Speed
|
||||||
let player_sct_bg_id = player_sct_bg_id_walker.next(
|
let player_sct_bg_id = player_sct_bg_id_walker.next(
|
||||||
@ -1459,7 +1473,6 @@ impl Hud {
|
|||||||
damage_floaters.last().map_or((false, 1.0), |f| {
|
damage_floaters.last().map_or((false, 1.0), |f| {
|
||||||
(f.info.crit_mult.is_some(), f.info.crit_mult.unwrap_or(1.0))
|
(f.info.crit_mult.is_some(), f.info.crit_mult.unwrap_or(1.0))
|
||||||
});
|
});
|
||||||
|
|
||||||
// Increase font size based on fraction of maximum health
|
// Increase font size based on fraction of maximum health
|
||||||
// "flashes" by having a larger size in the first 100ms
|
// "flashes" by having a larger size in the first 100ms
|
||||||
let font_size = 30
|
let font_size = 30
|
||||||
@ -1475,6 +1488,7 @@ impl Hud {
|
|||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
let font_col = player_font_col(hp_damage, crit);
|
||||||
// Timer sets the widget offset
|
// Timer sets the widget offset
|
||||||
let y = timer as f64 * number_speed * -1.0;
|
let y = timer as f64 * number_speed * -1.0;
|
||||||
// Timer sets text transparency
|
// Timer sets text transparency
|
||||||
@ -1494,11 +1508,7 @@ impl Hud {
|
|||||||
.font_size(font_size)
|
.font_size(font_size)
|
||||||
.font_id(self.fonts.cyri.conrod_id)
|
.font_id(self.fonts.cyri.conrod_id)
|
||||||
.color(if hp_damage < 0.0 {
|
.color(if hp_damage < 0.0 {
|
||||||
if crit {
|
Color::Rgba(font_col.r, font_col.g, font_col.b, hp_fade)
|
||||||
Color::Rgba(1.0, 0.9, 0.1, hp_fade)
|
|
||||||
} else {
|
|
||||||
Color::Rgba(1.0, 0.1, 0.0, hp_fade)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
Color::Rgba(0.0, 0.0, 0.0, 0.0)
|
Color::Rgba(0.0, 0.0, 0.0, 0.0)
|
||||||
})
|
})
|
||||||
@ -1550,8 +1560,6 @@ impl Hud {
|
|||||||
|
|
||||||
// Increase font size based on fraction of maximum health
|
// Increase font size based on fraction of maximum health
|
||||||
// "flashes" by having a larger size in the first 100ms
|
// "flashes" by having a larger size in the first 100ms
|
||||||
// TODO: Could have it so that crits not only fade away but decrease in
|
|
||||||
// size?
|
|
||||||
let font_size = 30
|
let font_size = 30
|
||||||
+ (max_hp_frac * 10.0 * if crit { 1.25 * crit_mult } else { 1.0 })
|
+ (max_hp_frac * 10.0 * if crit { 1.25 * crit_mult } else { 1.0 })
|
||||||
as u32
|
as u32
|
||||||
@ -1565,6 +1573,7 @@ impl Hud {
|
|||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
let font_col = player_font_col(floater.info.amount, crit);
|
||||||
// Timer sets the widget offset
|
// Timer sets the widget offset
|
||||||
let y = if floater.info.amount < 0.0 {
|
let y = if floater.info.amount < 0.0 {
|
||||||
floater.timer as f64
|
floater.timer as f64
|
||||||
@ -1597,16 +1606,7 @@ impl Hud {
|
|||||||
Text::new(&hp_dmg_text)
|
Text::new(&hp_dmg_text)
|
||||||
.font_size(font_size)
|
.font_size(font_size)
|
||||||
.font_id(self.fonts.cyri.conrod_id)
|
.font_id(self.fonts.cyri.conrod_id)
|
||||||
.color(if floater.info.amount < 0.0 {
|
.color(Color::Rgba(font_col.r, font_col.g, font_col.b, hp_fade))
|
||||||
// TODO: example
|
|
||||||
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.1, 1.0, 0.1, hp_fade)
|
|
||||||
})
|
|
||||||
.x_y(x, y)
|
.x_y(x, y)
|
||||||
.set(player_sct_id, ui_widgets);
|
.set(player_sct_id, ui_widgets);
|
||||||
}
|
}
|
||||||
@ -2249,13 +2249,19 @@ impl Hud {
|
|||||||
];
|
];
|
||||||
// Largest value that select the first color is 40, then it shifts colors
|
// Largest value that select the first color is 40, then it shifts colors
|
||||||
// every 5
|
// every 5
|
||||||
let font_col = |font_size: u32, crit: bool| {
|
// TODO: Change to account for healing/damage here; handle different DamageSources differently???
|
||||||
|
// TODO: Change both font_col closures to account for healing
|
||||||
|
let font_col = |hp_damage: f32, font_size: u32, crit: bool| {
|
||||||
|
if hp_damage < 0.0 {
|
||||||
if crit {
|
if crit {
|
||||||
// TODO: Temporary color for crits
|
// TODO: Temporary color for crits
|
||||||
Rgb::new(1.0, 0.9, 0.0)
|
Rgb::new(1.0, 0.9, 0.0)
|
||||||
} else {
|
} else {
|
||||||
DAMAGE_COLORS[(font_size.saturating_sub(36) / 5).min(5) as usize]
|
DAMAGE_COLORS[(font_size.saturating_sub(36) / 5).min(5) as usize]
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
Rgb::new(0.1, 1.0, 0.1)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if global_state.settings.interface.sct_damage_batch {
|
if global_state.settings.interface.sct_damage_batch {
|
||||||
@ -2313,9 +2319,7 @@ impl Hud {
|
|||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
// TODO: Currently, this and the font size don't look too great with
|
let font_col = font_col(hp_damage, font_size, crit);
|
||||||
// batched numbers
|
|
||||||
let font_col = font_col(font_size, crit);
|
|
||||||
// Timer sets the widget offset
|
// Timer sets the widget offset
|
||||||
let y = (timer as f64 / crate::ecs::sys::floater::HP_SHOWTIME as f64
|
let y = (timer as f64 / crate::ecs::sys::floater::HP_SHOWTIME as f64
|
||||||
* number_speed)
|
* number_speed)
|
||||||
@ -2334,11 +2338,7 @@ impl Hud {
|
|||||||
.font_size(font_size)
|
.font_size(font_size)
|
||||||
.font_id(self.fonts.cyri.conrod_id)
|
.font_id(self.fonts.cyri.conrod_id)
|
||||||
.x_y(0.0, y)
|
.x_y(0.0, y)
|
||||||
.color(if hp_damage < 0.0 {
|
.color(Color::Rgba(font_col.r, font_col.g, font_col.b, fade))
|
||||||
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)
|
.position_ingame(ingame_pos)
|
||||||
.set(sct_id, ui_widgets);
|
.set(sct_id, ui_widgets);
|
||||||
}
|
}
|
||||||
@ -2391,7 +2391,7 @@ impl Hud {
|
|||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
let font_col = font_col(font_size, crit);
|
let font_col = font_col(floater.info.amount, font_size, crit);
|
||||||
// Timer sets the widget offset
|
// Timer sets the widget offset
|
||||||
// TODO: Keep working on this
|
// TODO: Keep working on this
|
||||||
let y = if crit {
|
let y = if crit {
|
||||||
@ -4583,8 +4583,7 @@ impl Hud {
|
|||||||
},
|
},
|
||||||
None => hit_me,
|
None => hit_me,
|
||||||
} {
|
} {
|
||||||
// Group up damage from the same tick, with the same instance number and
|
// Group up damage from the same tick and instance number
|
||||||
// crit value
|
|
||||||
for floater in floater_list.floaters.iter_mut().rev() {
|
for floater in floater_list.floaters.iter_mut().rev() {
|
||||||
if floater.timer > 0.0 {
|
if floater.timer > 0.0 {
|
||||||
break;
|
break;
|
||||||
@ -4596,9 +4595,10 @@ impl Hud {
|
|||||||
== info.crit_mult.is_some())
|
== info.crit_mult.is_some())
|
||||||
{
|
{
|
||||||
floater.info.amount += info.amount;
|
floater.info.amount += info.amount;
|
||||||
floater.info.crit_mult = match info.crit_mult {
|
floater.info.crit_mult = if info.crit_mult.is_some() {
|
||||||
Some(_) => info.crit_mult,
|
info.crit_mult
|
||||||
None => floater.info.crit_mult,
|
} else {
|
||||||
|
floater.info.crit_mult
|
||||||
};
|
};
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -726,7 +726,6 @@ impl<'a> Widget for Interface<'a> {
|
|||||||
O Incoming Damage Accumulation Duration: 0s ----I----2s
|
O Incoming Damage Accumulation Duration: 0s ----I----2s
|
||||||
O Batch incoming Numbers
|
O Batch incoming Numbers
|
||||||
O Round Damage Numbers
|
O Round Damage Numbers
|
||||||
TODO: Do something like https://gitlab.com/veloren/veloren/-/issues/836
|
|
||||||
*/
|
*/
|
||||||
// SCT/ Scrolling Combat Text
|
// SCT/ Scrolling Combat Text
|
||||||
Text::new(
|
Text::new(
|
||||||
|
Reference in New Issue
Block a user