mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Crits now only glob with eachother, now show up like healing
Still a WIP, need to change crits to being non-floating and try implementing crits popping, need to remove some debugging stuff later
This commit is contained in:
parent
ce95680df9
commit
7a1e19d42c
@ -258,6 +258,7 @@ impl Attack {
|
||||
cause: Some(damage.damage.source),
|
||||
time,
|
||||
crit: Some(is_crit),
|
||||
crit_mult: self.crit_multiplier,
|
||||
};
|
||||
emit(ServerEvent::HealthChange {
|
||||
entity: target.entity,
|
||||
@ -356,6 +357,7 @@ impl Attack {
|
||||
cause: None,
|
||||
time,
|
||||
crit: None,
|
||||
crit_mult: self.crit_multiplier,
|
||||
};
|
||||
if change.amount.abs() > Health::HEALTH_EPSILON {
|
||||
emit(ServerEvent::HealthChange {
|
||||
@ -389,6 +391,7 @@ impl Attack {
|
||||
cause: None,
|
||||
time,
|
||||
crit: None,
|
||||
crit_mult: self.crit_multiplier,
|
||||
};
|
||||
if change.amount.abs() > Health::HEALTH_EPSILON {
|
||||
emit(ServerEvent::HealthChange {
|
||||
@ -501,6 +504,7 @@ impl Attack {
|
||||
cause: None,
|
||||
time,
|
||||
crit: None,
|
||||
crit_mult: self.crit_multiplier,
|
||||
};
|
||||
if change.amount.abs() > Health::HEALTH_EPSILON {
|
||||
emit(ServerEvent::HealthChange {
|
||||
@ -534,6 +538,7 @@ impl Attack {
|
||||
cause: None,
|
||||
time,
|
||||
crit: None,
|
||||
crit_mult: self.crit_multiplier,
|
||||
};
|
||||
if change.amount.abs() > Health::HEALTH_EPSILON {
|
||||
emit(ServerEvent::HealthChange {
|
||||
@ -847,6 +852,7 @@ impl Damage {
|
||||
cause: Some(self.source),
|
||||
time,
|
||||
crit: Some(is_crit),
|
||||
crit_mult,
|
||||
}
|
||||
},
|
||||
DamageSource::Falling => {
|
||||
@ -860,6 +866,7 @@ impl Damage {
|
||||
cause: Some(self.source),
|
||||
time,
|
||||
crit: None,
|
||||
crit_mult,
|
||||
}
|
||||
},
|
||||
DamageSource::Buff(_) | DamageSource::Other => HealthChange {
|
||||
@ -868,6 +875,7 @@ impl Damage {
|
||||
cause: Some(self.source),
|
||||
time,
|
||||
crit: None,
|
||||
crit_mult,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ pub struct HealthChange {
|
||||
/// Whether or not the health change was caused by a crit (None if it
|
||||
/// couldn't have been a crit)
|
||||
pub crit: Option<bool>,
|
||||
pub crit_mult: f32,
|
||||
}
|
||||
|
||||
impl HealthChange {
|
||||
@ -136,6 +137,7 @@ impl Health {
|
||||
by: None,
|
||||
cause: None,
|
||||
crit: None,
|
||||
crit_mult: 1.0,
|
||||
time: Time(0.0),
|
||||
},
|
||||
is_dead: false,
|
||||
@ -215,6 +217,7 @@ impl Health {
|
||||
by: None,
|
||||
cause: None,
|
||||
crit: None,
|
||||
crit_mult: 1.0,
|
||||
time: Time(0.0),
|
||||
},
|
||||
is_dead: false,
|
||||
@ -250,6 +253,7 @@ mod tests {
|
||||
by: Some(damage_contrib),
|
||||
cause: None,
|
||||
crit: None,
|
||||
crit_mult: 1.0,
|
||||
};
|
||||
|
||||
health.change_by(health_change);
|
||||
@ -276,6 +280,7 @@ mod tests {
|
||||
by: Some(damage_contrib),
|
||||
cause: None,
|
||||
crit: None,
|
||||
crit_mult: 1.0,
|
||||
};
|
||||
|
||||
health.change_by(health_change);
|
||||
@ -296,6 +301,7 @@ mod tests {
|
||||
by: Some(damage_contrib),
|
||||
cause: None,
|
||||
crit: None,
|
||||
crit_mult: 1.0,
|
||||
};
|
||||
health.change_by(health_change);
|
||||
health.change_by(health_change);
|
||||
@ -322,6 +328,7 @@ mod tests {
|
||||
by: Some(damage_contrib1),
|
||||
cause: None,
|
||||
crit: None,
|
||||
crit_mult: 1.0,
|
||||
};
|
||||
health.change_by(health_change);
|
||||
|
||||
@ -332,6 +339,7 @@ mod tests {
|
||||
by: Some(damage_contrib2),
|
||||
cause: None,
|
||||
crit: None,
|
||||
crit_mult: 1.0,
|
||||
};
|
||||
health.change_by(health_change);
|
||||
|
||||
@ -346,6 +354,7 @@ mod tests {
|
||||
by: Some(damage_contrib2),
|
||||
cause: None,
|
||||
crit: None,
|
||||
crit_mult: 1.0,
|
||||
};
|
||||
health.change_by(health_change);
|
||||
|
||||
|
@ -10,6 +10,7 @@ pub struct DamageInfo {
|
||||
pub crit: Option<bool>,
|
||||
pub target: Uid,
|
||||
pub by: Option<DamageContributor>,
|
||||
pub crit_mult: f32,
|
||||
}
|
||||
|
||||
/// An outcome represents the final result of an instantaneous event. It implies
|
||||
|
@ -275,6 +275,7 @@ impl<'a> System<'a> for Sys {
|
||||
cause,
|
||||
time: *read_data.time,
|
||||
crit: None,
|
||||
crit_mult: 1.0,
|
||||
},
|
||||
});
|
||||
*accumulated = 0.0;
|
||||
|
@ -1057,6 +1057,7 @@ fn handle_health(
|
||||
by: None,
|
||||
cause: None,
|
||||
crit: None,
|
||||
crit_mult: 1.0,
|
||||
time: *time,
|
||||
};
|
||||
health.change_by(change);
|
||||
|
@ -89,6 +89,7 @@ pub fn handle_health_change(server: &Server, entity: EcsEntity, change: HealthCh
|
||||
crit: change.crit,
|
||||
by: change.by,
|
||||
target: *uid,
|
||||
crit_mult: change.crit_mult,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
@ -8,8 +8,10 @@ use specs::{Entities, Join, Read, ReadStorage, WriteStorage};
|
||||
|
||||
// How long floaters last (in seconds)
|
||||
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;
|
||||
pub const CRIT_ACCUMULATETIME: f32 = 0.25;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Sys;
|
||||
@ -82,6 +84,10 @@ impl<'a> System<'a> for Sys {
|
||||
// Increment timer
|
||||
floater.timer += dt.0;
|
||||
}
|
||||
// // TODO: For popping effect
|
||||
// floaters.retain(|f| !f.info.crit || (f.info.crit && f.timer <
|
||||
// CRIT_SHOWTIME));
|
||||
|
||||
// Clear floaters if newest floater is past show time or health runs out
|
||||
if floaters.last().map_or(false, |f| {
|
||||
f.timer
|
||||
|
@ -1411,6 +1411,7 @@ impl Hud {
|
||||
.filter(|fl| !fl.floaters.is_empty()),
|
||||
healths.get(me),
|
||||
) {
|
||||
// TODO: Change these for crits
|
||||
if global_state.settings.interface.sct_player_batch {
|
||||
let number_speed = 100.0; // Player Batched Numbers Speed
|
||||
let player_sct_bg_id = player_sct_bg_id_walker.next(
|
||||
@ -1445,13 +1446,21 @@ impl Hud {
|
||||
.last()
|
||||
.and_then(|f| f.info.crit)
|
||||
.unwrap_or(false);
|
||||
let crit_mult =
|
||||
damage_floaters.last().map_or(1.0, |f| f.info.crit_mult);
|
||||
|
||||
// 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 * if crit { 1.5 * crit_mult } else { 1.0 })
|
||||
as u32)
|
||||
* 3
|
||||
+ if timer < 0.1 {
|
||||
FLASH_MAX * (((1.0 - timer / 0.1) * 10.0) as u32)
|
||||
FLASH_MAX
|
||||
* (((1.0 - timer / 0.1)
|
||||
* 10.0
|
||||
* if crit { 1.5 * crit_mult } else { 1.0 })
|
||||
as u32)
|
||||
} else {
|
||||
0
|
||||
};
|
||||
@ -1486,6 +1495,7 @@ impl Hud {
|
||||
.set(player_sct_id, ui_widgets);
|
||||
}
|
||||
};
|
||||
// TODO: Change these for crits
|
||||
for floater in floaters {
|
||||
// Healing always single numbers so just skip damage when in batch mode
|
||||
|
||||
@ -1509,20 +1519,33 @@ impl Hud {
|
||||
// "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
|
||||
* if crit {
|
||||
1.5 * floater.info.crit_mult
|
||||
} else {
|
||||
1.0
|
||||
}) as u32
|
||||
* 3
|
||||
+ 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)
|
||||
FLASH_MAX
|
||||
* (((1.0 - floater.timer / 0.1)
|
||||
* 10.0
|
||||
* if crit {
|
||||
1.5 * floater.info.crit_mult
|
||||
} else {
|
||||
1.0
|
||||
}) as u32)
|
||||
} else {
|
||||
0
|
||||
};
|
||||
// Timer sets the widget offset
|
||||
let y = if floater.info.amount < 0.0 {
|
||||
floater.timer as f64
|
||||
* number_speed
|
||||
* floater.info.amount.signum() as f64
|
||||
//* -1.0
|
||||
+ 300.0
|
||||
* number_speed
|
||||
* floater.info.amount.signum() as f64
|
||||
//* -1.0
|
||||
+ 300.0
|
||||
- ui_widgets.win_h * 0.5
|
||||
} else {
|
||||
floater.timer as f64
|
||||
@ -1533,10 +1556,10 @@ impl Hud {
|
||||
- ui_widgets.win_h * 0.5
|
||||
};
|
||||
// Healing is offset randomly
|
||||
let x = if floater.info.amount < 0.0 {
|
||||
let x = if floater.info.amount < 0.0 && !crit {
|
||||
0.0
|
||||
} else {
|
||||
(floater.rand as f64 - 0.5) * 0.2 * ui_widgets.win_w
|
||||
(floater.rand as f64 - 0.5).abs().max(0.2) * (floater.rand as f64 - 0.5).signum() * 0.25 * ui_widgets.win_w
|
||||
};
|
||||
// Timer sets text transparency
|
||||
let hp_fade = ((crate::ecs::sys::floater::MY_HP_SHOWTIME - floater.timer)
|
||||
@ -2211,6 +2234,8 @@ impl Hud {
|
||||
|
||||
// Colors
|
||||
// TODO: The crit colors and their names are pretty bad as it stands
|
||||
//TODO: They don't stand out enough as they should, and they fade weirdly, such
|
||||
// that they look transparent from the get-go
|
||||
const WHITE: Rgb<f32> = Rgb::new(1.0, 0.9, 0.8);
|
||||
const LIGHT_OR: Rgb<f32> = Rgb::new(1.0, 0.925, 0.749);
|
||||
const LIGHT_MED_OR: Rgb<f32> = Rgb::new(1.0, 0.85, 0.498);
|
||||
@ -2243,13 +2268,18 @@ impl Hud {
|
||||
// every 5
|
||||
let font_col = |font_size: u32, crit: bool| {
|
||||
if crit {
|
||||
CDAMAGE_COLORS[(font_size.saturating_sub(72) / 5).min(5) as usize]
|
||||
// TODO: This will probably be the way crit colours are handled (with a
|
||||
// different algo for choosing the color)
|
||||
// CDAMAGE_COLORS[(font_size.saturating_sub(72) / 5).min(5) as usize]
|
||||
|
||||
// TODO: Temporary
|
||||
Rgb::new(1.0, 0.9, 0.0)
|
||||
} else {
|
||||
DAMAGE_COLORS[(font_size.saturating_sub(36) / 5).min(5) as usize]
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: Might have to change something here as well
|
||||
// TODO: Change these for crits
|
||||
if global_state.settings.interface.sct_damage_batch {
|
||||
let number_speed = 50.0; // Damage number speed
|
||||
let sct_id = sct_walker
|
||||
@ -2275,13 +2305,21 @@ impl Hud {
|
||||
.last()
|
||||
.and_then(|f| f.info.crit)
|
||||
.unwrap_or(false);
|
||||
let crit_mult =
|
||||
damage_floaters.last().map_or(1.0, |f| f.info.crit_mult);
|
||||
|
||||
// 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 * if crit { 1.5 * crit_mult } else { 1.0 })
|
||||
as u32)
|
||||
* 3
|
||||
+ if timer < 0.1 {
|
||||
FLASH_MAX * (((1.0 - timer / 0.1) * 10.0) as u32)
|
||||
FLASH_MAX
|
||||
* (((1.0 - timer / 0.1)
|
||||
* 10.0
|
||||
* if crit { 1.5 * crit_mult } else { 1.0 })
|
||||
as u32)
|
||||
} else {
|
||||
0
|
||||
};
|
||||
@ -2351,22 +2389,55 @@ impl Hud {
|
||||
// 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
|
||||
* if crit {
|
||||
2.5 * floater.info.crit_mult
|
||||
} else {
|
||||
1.0
|
||||
}) as u32
|
||||
* 3
|
||||
+ if floater.timer < 0.1 {
|
||||
FLASH_MAX * (((1.0 - floater.timer / 0.1) * 10.0) as u32)
|
||||
FLASH_MAX
|
||||
* (((1.0 - floater.timer / 0.1)
|
||||
* 10.0
|
||||
* if crit {
|
||||
1.5 * floater.info.crit_mult
|
||||
} else {
|
||||
1.0
|
||||
}) as u32)
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let font_col = font_col(font_size, crit);
|
||||
// Timer sets the widget offset
|
||||
let y = (floater.timer as f64
|
||||
/ crate::ecs::sys::floater::HP_SHOWTIME as f64
|
||||
* number_speed)
|
||||
+ 100.0;
|
||||
// TODO: Keep working on this
|
||||
let y = if crit {
|
||||
ui_widgets.win_h * (floater.rand as f64 % 0.175)
|
||||
} else {
|
||||
(floater.timer as f64
|
||||
/ crate::ecs::sys::floater::HP_SHOWTIME as f64
|
||||
* number_speed)
|
||||
+ 100.0
|
||||
};
|
||||
|
||||
let x = if !crit {
|
||||
0.0
|
||||
} else {
|
||||
(floater.rand as f64 - 0.5).abs().max(0.2) * (floater.rand as f64 - 0.5).signum() * 0.25 * ui_widgets.win_w
|
||||
};
|
||||
|
||||
dbg!(x);
|
||||
dbg!(y);
|
||||
|
||||
// Timer sets text transparency
|
||||
let fade = ((crate::ecs::sys::floater::HP_SHOWTIME - floater.timer)
|
||||
* 0.25)
|
||||
+ 0.2;
|
||||
let fade = if crit {
|
||||
((crate::ecs::sys::floater::CRIT_SHOWTIME - floater.timer) * 0.25)
|
||||
+ 0.2
|
||||
} else {
|
||||
((crate::ecs::sys::floater::HP_SHOWTIME - floater.timer) * 0.25)
|
||||
+ 0.2
|
||||
};
|
||||
if floater.info.amount.abs() < 1.0 {
|
||||
// Damage and heal below 10/10 are shown as decimals
|
||||
Text::new(&format!("{:.0}", floater.info.amount.abs()))
|
||||
@ -2377,13 +2448,13 @@ impl Hud {
|
||||
} else {
|
||||
Color::Rgba(0.0, 0.0, 0.0, 1.0)
|
||||
})
|
||||
.x_y(0.0, y - 3.0)
|
||||
.x_y(x, y - 3.0)
|
||||
.position_ingame(ingame_pos)
|
||||
.set(sct_bg_id, ui_widgets);
|
||||
Text::new(&format!("{:.0}", floater.info.amount.abs()))
|
||||
.font_size(font_size)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.x_y(0.0, y)
|
||||
.x_y(x, y)
|
||||
.color(if floater.info.amount < 0.0 {
|
||||
Color::Rgba(font_col.r, font_col.g, font_col.b, fade)
|
||||
} else {
|
||||
@ -2401,13 +2472,13 @@ impl Hud {
|
||||
} else {
|
||||
Color::Rgba(0.0, 0.0, 0.0, 1.0)
|
||||
})
|
||||
.x_y(0.0, y - 3.0)
|
||||
.x_y(x, y - 3.0)
|
||||
.position_ingame(ingame_pos)
|
||||
.set(sct_bg_id, ui_widgets);
|
||||
Text::new(&format!("{:.1}", floater.info.amount.abs()))
|
||||
.font_size(font_size)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.x_y(0.0, y)
|
||||
.x_y(x, y)
|
||||
.color(if floater.info.amount < 0.0 {
|
||||
Color::Rgba(font_col.r, font_col.g, font_col.b, fade)
|
||||
} else {
|
||||
@ -4571,15 +4642,22 @@ impl Hud {
|
||||
.rev()
|
||||
.find(|f| f.info.amount > Health::HEALTH_EPSILON)
|
||||
};
|
||||
|
||||
match last_floater {
|
||||
Some(f) if f.timer < floater::HP_ACCUMULATETIME => {
|
||||
// TODO: Only seperate crits for anything that didn't hit the enemy?
|
||||
Some(f)
|
||||
if (info.crit.unwrap_or(false)
|
||||
&& f.timer < floater::CRIT_ACCUMULATETIME
|
||||
&& info.crit.unwrap_or(false))
|
||||
|| (f.timer < floater::HP_ACCUMULATETIME
|
||||
&& !f.info.crit.unwrap_or(false)
|
||||
&& !info.crit.unwrap_or(false)) =>
|
||||
{
|
||||
//TODO: Add "jumping" animation on floater when it changes its
|
||||
// value
|
||||
dbg!("add to floater");
|
||||
f.info.amount += info.amount;
|
||||
// Only change the crit value if it's not None
|
||||
if info.crit.is_some() {
|
||||
f.info.crit = info.crit;
|
||||
}
|
||||
f.info.crit_mult = info.crit_mult;
|
||||
},
|
||||
_ => {
|
||||
floater_list.floaters.push(HpFloater {
|
||||
|
Loading…
Reference in New Issue
Block a user