Address review - addendum

- `BlockFloater`s and `ComboFloater`s don't store the owner anymore,
  `ExpFloater` still does, however the field is used to prevent
  accumulating old floaters with new ones. This change also makes it so
  that if the client changes entity, they keep the old entity's
  floaters.
- The `combo_floaters` field is now `combo_floater` plus it now uses an
  Option<ExpFloater>.
- Changed `handle_health_change` to change the health even if the entity
  does not have a `Pos` or `Uid`, now uses `emit_now`combo_floater` plus
  it now uses an Option<ExpFloater>.
- Changed `handle_health_change` to change the health even if the entity
  does not have a `Pos` or `Uid`, now uses `emit_now`
- Changed some comments
This commit is contained in:
Socksonme 2022-06-15 17:14:50 +03:00
parent 2c5fd06d0b
commit f6189a61f2
3 changed files with 190 additions and 191 deletions

View File

@ -66,25 +66,26 @@ pub fn handle_poise(server: &Server, entity: EcsEntity, change: comp::PoiseChang
pub fn handle_health_change(server: &Server, entity: EcsEntity, change: HealthChange) { pub fn handle_health_change(server: &Server, entity: EcsEntity, change: HealthChange) {
let ecs = &server.state.ecs(); let ecs = &server.state.ecs();
if let (Some(pos), Some(uid), Some(mut health)) = ( if let Some(mut health) = ecs.write_storage::<Health>().get_mut(entity) {
ecs.read_storage::<Pos>().get(entity),
ecs.read_storage::<Uid>().get(entity),
ecs.write_storage::<Health>().get_mut(entity),
) {
let outcomes = ecs.write_resource::<EventBus<Outcome>>();
let mut outcomes_emitter = outcomes.emitter();
// If the change amount was not zero // If the change amount was not zero
if health.change_by(change) { let changed = health.change_by(change);
outcomes_emitter.emit(Outcome::HealthChange { if let (Some(pos), Some(uid)) = (
pos: pos.0, ecs.read_storage::<Pos>().get(entity),
info: HealthChangeInfo { ecs.read_storage::<Uid>().get(entity),
amount: change.amount, ) {
by: change.by, if changed {
target: *uid, let outcomes = ecs.write_resource::<EventBus<Outcome>>();
crit: change.crit, outcomes.emit_now(Outcome::HealthChange {
instance: change.instance, pos: pos.0,
}, info: HealthChangeInfo {
}); amount: change.amount,
by: change.by,
target: *uid,
crit: change.crit,
instance: change.instance,
},
});
}
} }
} }
// This if statement filters out anything under 5 damage, for DOT ticks // This if statement filters out anything under 5 damage, for DOT ticks

View File

@ -451,6 +451,7 @@ pub struct BuffInfo {
} }
pub struct ExpFloater { pub struct ExpFloater {
pub owner: Uid,
pub exp_change: u32, pub exp_change: u32,
pub timer: f32, pub timer: f32,
pub jump_timer: f32, pub jump_timer: f32,
@ -459,7 +460,6 @@ pub struct ExpFloater {
} }
pub struct SkillPointGain { pub struct SkillPointGain {
pub owner: Uid,
pub skill_tree: SkillGroupKind, pub skill_tree: SkillGroupKind,
pub total_points: u16, pub total_points: u16,
pub timer: f32, pub timer: f32,
@ -467,13 +467,11 @@ pub struct SkillPointGain {
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct ComboFloater { pub struct ComboFloater {
pub owner: Uid,
pub combo: u32, pub combo: u32,
pub timer: f64, pub timer: f64,
} }
pub struct BlockFloater { pub struct BlockFloater {
pub owner: Uid,
pub timer: f32, pub timer: f32,
} }
@ -1001,7 +999,7 @@ impl PromptDialogSettings {
pub struct Floaters { pub struct Floaters {
pub exp_floaters: Vec<ExpFloater>, pub exp_floaters: Vec<ExpFloater>,
pub skill_point_displays: Vec<SkillPointGain>, pub skill_point_displays: Vec<SkillPointGain>,
pub combo_floaters: VecDeque<ComboFloater>, pub combo_floater: Option<ComboFloater>,
pub block_floaters: Vec<BlockFloater>, pub block_floaters: Vec<BlockFloater>,
} }
@ -1213,7 +1211,7 @@ impl Hud {
floaters: Floaters { floaters: Floaters {
exp_floaters: Vec::new(), exp_floaters: Vec::new(),
skill_point_displays: Vec::new(), skill_point_displays: Vec::new(),
combo_floaters: VecDeque::new(), combo_floater: None,
block_floaters: Vec::new(), block_floaters: Vec::new(),
}, },
map_drag: Vec2::zero(), map_drag: Vec2::zero(),
@ -1520,7 +1518,6 @@ impl Hud {
f.timer -= dt.as_secs_f32(); f.timer -= dt.as_secs_f32();
f.jump_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); self.floaters.exp_floaters.retain(|f| f.timer > 0.0);
for floater in self.floaters.exp_floaters.iter_mut() { for floater in self.floaters.exp_floaters.iter_mut() {
let number_speed = 50.0; // Number Speed for Single EXP let number_speed = 50.0; // Number Speed for Single EXP
@ -1598,149 +1595,136 @@ impl Hud {
self.floaters self.floaters
.skill_point_displays .skill_point_displays
.retain(|d| d.timer > 0_f32); .retain(|d| d.timer > 0_f32);
if let Some(uid) = uids.get(me) { if let Some(display) = self.floaters.skill_point_displays.iter_mut().next() {
if let Some(display) = self let fade = if display.timer < 3.0 {
.floaters display.timer * 0.33
.skill_point_displays } else if display.timer < 2.0 {
.iter_mut() display.timer * 0.33 * 0.1
.find(|d| d.owner == *uid) } else {
{ 1.0
let fade = if display.timer < 3.0 { };
display.timer * 0.33 // Background image
} else if display.timer < 2.0 { let offset = if display.timer < 2.0 {
display.timer * 0.33 * 0.1 300.0 - (display.timer as f64 - 2.0) * -300.0
} else { } else {
1.0 300.0
}; };
// Background image Image::new(self.imgs.level_up)
let offset = if display.timer < 2.0 { .w_h(328.0, 126.0)
300.0 - (display.timer as f64 - 2.0) * -300.0 .mid_top_with_margin_on(ui_widgets.window, offset)
} else { .graphics_for(ui_widgets.window)
300.0
};
Image::new(self.imgs.level_up)
.w_h(328.0, 126.0)
.mid_top_with_margin_on(ui_widgets.window, offset)
.graphics_for(ui_widgets.window)
.color(Some(Color::Rgba(1.0, 1.0, 1.0, fade)))
.set(self.ids.player_rank_up, ui_widgets);
// Rank Number
let rank = display.total_points;
let fontsize = match rank {
1..=99 => (20, 8.0),
100..=999 => (18, 9.0),
1000..=9999 => (17, 10.0),
_ => (14, 12.0),
};
Text::new(&format!("{}", rank))
.font_size(fontsize.0)
.font_id(self.fonts.cyri.conrod_id)
.color(Color::Rgba(1.0, 1.0, 1.0, fade))
.mid_top_with_margin_on(self.ids.player_rank_up, fontsize.1)
.set(self.ids.player_rank_up_txt_number, ui_widgets);
// Static "New Rank!" text
Text::new(i18n.get("hud.rank_up"))
.font_size(40)
.font_id(self.fonts.cyri.conrod_id)
.color(Color::Rgba(0.0, 0.0, 0.0, fade))
.mid_bottom_with_margin_on(self.ids.player_rank_up, 20.0)
.set(self.ids.player_rank_up_txt_0_bg, ui_widgets);
Text::new(i18n.get("hud.rank_up"))
.font_size(40)
.font_id(self.fonts.cyri.conrod_id)
.color(Color::Rgba(1.0, 1.0, 1.0, fade))
.bottom_left_with_margins_on(self.ids.player_rank_up_txt_0_bg, 2.0, 2.0)
.set(self.ids.player_rank_up_txt_0, ui_widgets);
// Variable skilltree text
let skill = match display.skill_tree {
General => i18n.get("common.weapons.general"),
Weapon(ToolKind::Hammer) => i18n.get("common.weapons.hammer"),
Weapon(ToolKind::Axe) => i18n.get("common.weapons.axe"),
Weapon(ToolKind::Sword) => i18n.get("common.weapons.sword"),
Weapon(ToolKind::Sceptre) => i18n.get("common.weapons.sceptre"),
Weapon(ToolKind::Bow) => i18n.get("common.weapons.bow"),
Weapon(ToolKind::Staff) => i18n.get("common.weapons.staff"),
Weapon(ToolKind::Pick) => i18n.get("common.tool.mining"),
_ => "Unknown",
};
Text::new(skill)
.font_size(20)
.font_id(self.fonts.cyri.conrod_id)
.color(Color::Rgba(0.0, 0.0, 0.0, fade))
.mid_top_with_margin_on(self.ids.player_rank_up, 45.0)
.set(self.ids.player_rank_up_txt_1_bg, ui_widgets);
Text::new(skill)
.font_size(20)
.font_id(self.fonts.cyri.conrod_id)
.color(Color::Rgba(1.0, 1.0, 1.0, fade))
.bottom_left_with_margins_on(self.ids.player_rank_up_txt_1_bg, 2.0, 2.0)
.set(self.ids.player_rank_up_txt_1, ui_widgets);
// Variable skilltree icon
use crate::hud::SkillGroupKind::{General, Weapon};
Image::new(match display.skill_tree {
General => self.imgs.swords_crossed,
Weapon(ToolKind::Hammer) => self.imgs.hammer,
Weapon(ToolKind::Axe) => self.imgs.axe,
Weapon(ToolKind::Sword) => self.imgs.sword,
Weapon(ToolKind::Sceptre) => self.imgs.sceptre,
Weapon(ToolKind::Bow) => self.imgs.bow,
Weapon(ToolKind::Staff) => self.imgs.staff,
Weapon(ToolKind::Pick) => self.imgs.mining,
_ => self.imgs.swords_crossed,
})
.w_h(20.0, 20.0)
.left_from(self.ids.player_rank_up_txt_1_bg, 5.0)
.color(Some(Color::Rgba(1.0, 1.0, 1.0, fade))) .color(Some(Color::Rgba(1.0, 1.0, 1.0, fade)))
.set(self.ids.player_rank_up_icon, ui_widgets); .set(self.ids.player_rank_up, ui_widgets);
} // Rank Number
let rank = display.total_points;
let fontsize = match rank {
1..=99 => (20, 8.0),
100..=999 => (18, 9.0),
1000..=9999 => (17, 10.0),
_ => (14, 12.0),
};
Text::new(&format!("{}", rank))
.font_size(fontsize.0)
.font_id(self.fonts.cyri.conrod_id)
.color(Color::Rgba(1.0, 1.0, 1.0, fade))
.mid_top_with_margin_on(self.ids.player_rank_up, fontsize.1)
.set(self.ids.player_rank_up_txt_number, ui_widgets);
// Static "New Rank!" text
Text::new(i18n.get("hud.rank_up"))
.font_size(40)
.font_id(self.fonts.cyri.conrod_id)
.color(Color::Rgba(0.0, 0.0, 0.0, fade))
.mid_bottom_with_margin_on(self.ids.player_rank_up, 20.0)
.set(self.ids.player_rank_up_txt_0_bg, ui_widgets);
Text::new(i18n.get("hud.rank_up"))
.font_size(40)
.font_id(self.fonts.cyri.conrod_id)
.color(Color::Rgba(1.0, 1.0, 1.0, fade))
.bottom_left_with_margins_on(self.ids.player_rank_up_txt_0_bg, 2.0, 2.0)
.set(self.ids.player_rank_up_txt_0, ui_widgets);
// Variable skilltree text
let skill = match display.skill_tree {
General => i18n.get("common.weapons.general"),
Weapon(ToolKind::Hammer) => i18n.get("common.weapons.hammer"),
Weapon(ToolKind::Axe) => i18n.get("common.weapons.axe"),
Weapon(ToolKind::Sword) => i18n.get("common.weapons.sword"),
Weapon(ToolKind::Sceptre) => i18n.get("common.weapons.sceptre"),
Weapon(ToolKind::Bow) => i18n.get("common.weapons.bow"),
Weapon(ToolKind::Staff) => i18n.get("common.weapons.staff"),
Weapon(ToolKind::Pick) => i18n.get("common.tool.mining"),
_ => "Unknown",
};
Text::new(skill)
.font_size(20)
.font_id(self.fonts.cyri.conrod_id)
.color(Color::Rgba(0.0, 0.0, 0.0, fade))
.mid_top_with_margin_on(self.ids.player_rank_up, 45.0)
.set(self.ids.player_rank_up_txt_1_bg, ui_widgets);
Text::new(skill)
.font_size(20)
.font_id(self.fonts.cyri.conrod_id)
.color(Color::Rgba(1.0, 1.0, 1.0, fade))
.bottom_left_with_margins_on(self.ids.player_rank_up_txt_1_bg, 2.0, 2.0)
.set(self.ids.player_rank_up_txt_1, ui_widgets);
// Variable skilltree icon
use crate::hud::SkillGroupKind::{General, Weapon};
Image::new(match display.skill_tree {
General => self.imgs.swords_crossed,
Weapon(ToolKind::Hammer) => self.imgs.hammer,
Weapon(ToolKind::Axe) => self.imgs.axe,
Weapon(ToolKind::Sword) => self.imgs.sword,
Weapon(ToolKind::Sceptre) => self.imgs.sceptre,
Weapon(ToolKind::Bow) => self.imgs.bow,
Weapon(ToolKind::Staff) => self.imgs.staff,
Weapon(ToolKind::Pick) => self.imgs.mining,
_ => self.imgs.swords_crossed,
})
.w_h(20.0, 20.0)
.left_from(self.ids.player_rank_up_txt_1_bg, 5.0)
.color(Some(Color::Rgba(1.0, 1.0, 1.0, fade)))
.set(self.ids.player_rank_up_icon, ui_widgets);
} }
// Scrolling Combat Text for Parrying an attack // Scrolling Combat Text for Parrying an attack
self.floaters self.floaters
.block_floaters .block_floaters
.iter_mut() .iter_mut()
.for_each(|f| f.timer -= dt.as_secs_f32()); .for_each(|f| f.timer -= dt.as_secs_f32());
self.floaters.block_floaters.retain(|f| f.timer > 0_f32); self.floaters.block_floaters.retain(|f| f.timer > 0_f32);
if let Some(uid) = uids.get(me) { for floater in self.floaters.block_floaters.iter_mut() {
for floater in self let number_speed = 50.0;
.floaters let player_sct_bg_id = player_sct_bg_id_walker.next(
.block_floaters &mut self.ids.player_sct_bgs,
.iter_mut() &mut ui_widgets.widget_id_generator(),
.filter(|f| f.owner == *uid) );
{ let player_sct_id = player_sct_id_walker.next(
let number_speed = 50.0; &mut self.ids.player_scts,
let player_sct_bg_id = player_sct_bg_id_walker.next( &mut ui_widgets.widget_id_generator(),
&mut self.ids.player_sct_bgs, );
&mut ui_widgets.widget_id_generator(), let font_size = 30;
); let y = floater.timer as f64 * number_speed; // Timer sets the widget offset
let player_sct_id = player_sct_id_walker.next( // text transparency
&mut self.ids.player_scts, let fade = if floater.timer < 0.25 {
&mut ui_widgets.widget_id_generator(), floater.timer / 0.25
); } else {
let font_size = 30; 1.0
let y = floater.timer as f64 * number_speed; // Timer sets the widget offset };
// text transparency
let fade = if floater.timer < 0.25 {
floater.timer / 0.25
} else {
1.0
};
Text::new(i18n.get("hud.sct.block")) Text::new(i18n.get("hud.sct.block"))
.font_size(font_size) .font_size(font_size)
.font_id(self.fonts.cyri.conrod_id) .font_id(self.fonts.cyri.conrod_id)
.color(Color::Rgba(0.0, 0.0, 0.0, fade)) .color(Color::Rgba(0.0, 0.0, 0.0, fade))
.x_y( .x_y(
ui_widgets.win_w * (0.0), ui_widgets.win_w * (0.0),
ui_widgets.win_h * (-0.3) + y - 3.0, ui_widgets.win_h * (-0.3) + y - 3.0,
) )
.set(player_sct_bg_id, ui_widgets); .set(player_sct_bg_id, ui_widgets);
Text::new(i18n.get("hud.sct.block")) Text::new(i18n.get("hud.sct.block"))
.font_size(font_size) .font_size(font_size)
.font_id(self.fonts.cyri.conrod_id) .font_id(self.fonts.cyri.conrod_id)
.color(Color::Rgba(0.69, 0.82, 0.88, fade)) .color(Color::Rgba(0.69, 0.82, 0.88, fade))
.x_y(ui_widgets.win_w * 0.0, ui_widgets.win_h * -0.3 + y) .x_y(ui_widgets.win_w * 0.0, ui_widgets.win_h * -0.3 + y)
.set(player_sct_id, ui_widgets); .set(player_sct_id, ui_widgets);
}
} }
} }
@ -2699,20 +2683,12 @@ impl Hud {
let bodies = ecs.read_storage::<comp::Body>(); let bodies = ecs.read_storage::<comp::Body>();
let poises = ecs.read_storage::<comp::Poise>(); let poises = ecs.read_storage::<comp::Poise>();
// Combo floater stuffs // Combo floater stuffs
self.floaters self.floaters.combo_floater = self.floaters.combo_floater.map(|mut f| {
.combo_floaters f.timer -= dt.as_secs_f64();
.iter_mut() f
.for_each(|f| f.timer -= dt.as_secs_f64()); });
self.floaters.combo_floaters.retain(|f| f.timer > 0_f64); self.floaters.combo_floater.filter(|f| f.timer > 0_f64);
let combo = if let Some(uid) = ecs.read_storage::<Uid>().get(entity) { let combo = self.floaters.combo_floater;
self.floaters
.combo_floaters
.iter()
.find(|c| c.owner == *uid)
.copied()
} else {
None
};
if let ( if let (
Some(health), Some(health),
@ -4353,12 +4329,15 @@ impl Hud {
Some(floater) Some(floater)
if floater.timer if floater.timer
> (EXP_FLOATER_LIFETIME - EXP_ACCUMULATION_DURATION) > (EXP_FLOATER_LIFETIME - EXP_ACCUMULATION_DURATION)
&& global_state.settings.interface.accum_experience => && global_state.settings.interface.accum_experience
&& floater.owner == *uid =>
{ {
floater.jump_timer = 0.0; floater.jump_timer = 0.0;
floater.exp_change += *exp; floater.exp_change += *exp;
}, },
_ => self.floaters.exp_floaters.push(ExpFloater { _ => self.floaters.exp_floaters.push(ExpFloater {
// Store the owner as to not accumulate old experience floaters
owner: *uid,
exp_change: *exp, exp_change: *exp,
timer: EXP_FLOATER_LIFETIME, timer: EXP_FLOATER_LIFETIME,
jump_timer: 0.0, jump_timer: 0.0,
@ -4373,24 +4352,41 @@ impl Hud {
skill_tree, skill_tree,
total_points, total_points,
.. ..
} => self.floaters.skill_point_displays.push(SkillPointGain { } => {
owner: *uid, let ecs = client.state().ecs();
skill_tree: *skill_tree, let uids = ecs.read_storage::<Uid>();
total_points: *total_points, let me = client.entity();
timer: 5.0,
}), if uids.get(me).map_or(false, |me| *me == *uid) {
self.floaters.skill_point_displays.push(SkillPointGain {
skill_tree: *skill_tree,
total_points: *total_points,
timer: 5.0,
});
}
},
Outcome::ComboChange { uid, combo } => { Outcome::ComboChange { uid, combo } => {
self.floaters.combo_floaters.push_front(ComboFloater { let ecs = client.state().ecs();
owner: *uid, let uids = ecs.read_storage::<Uid>();
combo: *combo, let me = client.entity();
timer: comp::combo::COMBO_DECAY_START,
}) if uids.get(me).map_or(false, |me| *me == *uid) {
self.floaters.combo_floater = Some(ComboFloater {
combo: *combo,
timer: comp::combo::COMBO_DECAY_START,
});
}
}, },
Outcome::Block { uid, parry, .. } if *parry => { Outcome::Block { uid, parry, .. } if *parry => {
self.floaters.block_floaters.push(BlockFloater { let ecs = client.state().ecs();
owner: *uid, let uids = ecs.read_storage::<Uid>();
timer: 1.0, let me = client.entity();
})
if uids.get(me).map_or(false, |me| *me == *uid) {
self.floaters
.block_floaters
.push(BlockFloater { timer: 1.0 });
}
}, },
Outcome::HealthChange { info, .. } => { Outcome::HealthChange { info, .. } => {
let ecs = client.state().ecs(); let ecs = client.state().ecs();

View File

@ -716,9 +716,11 @@ impl<'a> Widget for Interface<'a> {
/*Scrolling Combat text /*Scrolling Combat text
O Show Damage Numbers O Show Damage Numbers
O Damage Accumulation Duration: 0s ----I----2s Damage Accumulation Duration:
O Show incoming Damage -- //TODO: add this back [0s ----I----2s]
O Incoming Damage Accumulation Duration: 0s ----I----2s O Show incoming Damage
Incoming Damage Accumulation Duration:
[0s ----I----2s]
O Round Damage Numbers O Round Damage Numbers
*/ */
// SCT/ Scrolling Combat Text // SCT/ Scrolling Combat Text