Better number popup behavior (fixes #163)
This commit is contained in:
parent
7caff84e04
commit
b3007c10e3
|
@ -13,20 +13,15 @@ pub struct NumberPopup {
|
|||
pub prev_x: i32,
|
||||
pub prev_y: i32,
|
||||
counter: u16,
|
||||
throttle: u16,
|
||||
value_display: i16,
|
||||
}
|
||||
|
||||
impl NumberPopup {
|
||||
pub fn new() -> NumberPopup {
|
||||
NumberPopup { value: 0, x: 0, y: 0, prev_x: 0, prev_y: 0, counter: 0, throttle: 0, value_display: 0 }
|
||||
NumberPopup { value: 0, x: 0, y: 0, prev_x: 0, prev_y: 0, counter: 0, value_display: 0 }
|
||||
}
|
||||
|
||||
pub fn set_value(&mut self, value: i16) {
|
||||
if self.counter > 32 {
|
||||
self.counter = 32;
|
||||
}
|
||||
|
||||
self.value = value;
|
||||
}
|
||||
|
||||
|
@ -34,32 +29,24 @@ impl NumberPopup {
|
|||
self.set_value(self.value + value);
|
||||
}
|
||||
|
||||
pub fn set_value_throttled(&mut self, value: i16) {
|
||||
self.throttle = 16;
|
||||
self.set_value(value);
|
||||
}
|
||||
|
||||
pub fn add_value_throttled(&mut self, value: i16) {
|
||||
self.set_value_throttled(self.value + value);
|
||||
pub fn update_displayed_value(&mut self) {
|
||||
if self.counter > 32 {
|
||||
self.counter = 32;
|
||||
}
|
||||
self.value_display += self.value;
|
||||
self.value = 0;
|
||||
}
|
||||
}
|
||||
|
||||
impl GameEntity<()> for NumberPopup {
|
||||
fn tick(&mut self, _state: &mut SharedGameState, _custom: ()) -> GameResult<()> {
|
||||
if self.throttle > 0 {
|
||||
self.throttle = self.throttle.saturating_sub(1);
|
||||
}
|
||||
|
||||
if self.value == 0 || self.throttle > 0 {
|
||||
if self.value_display == 0 {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
self.value_display = self.value;
|
||||
|
||||
self.counter += 1;
|
||||
if self.counter == 80 {
|
||||
self.counter = 0;
|
||||
self.value = 0;
|
||||
self.value_display = 0;
|
||||
}
|
||||
|
||||
|
@ -81,7 +68,8 @@ impl GameEntity<()> for NumberPopup {
|
|||
|
||||
let (frame_x, frame_y) = frame.xy_interpolated(state.frame_time);
|
||||
let x = interpolate_fix9_scale(self.prev_x, self.x, state.frame_time) - frame_x;
|
||||
let y = interpolate_fix9_scale(self.prev_y, self.y, state.frame_time) - frame_y - y_offset;
|
||||
let y = interpolate_fix9_scale(self.prev_y, self.y, state.frame_time) - frame_y - y_offset
|
||||
- 3.0f32; // This is supposed to be -4, but for some reason -3 looks more accurate
|
||||
|
||||
let n = format!("{:+}", self.value_display);
|
||||
|
||||
|
|
|
@ -100,6 +100,9 @@ impl GameEntity<([&mut Player; 2], &NPCList, &mut Stage, &BulletManager, &mut Fl
|
|||
for part in &mut self.parts {
|
||||
if part.shock > 0 {
|
||||
part.shock -= 1;
|
||||
} else if part.npc_flags.show_damage() && part.popup.value != 0 {
|
||||
// I don't know where the best place to put this is, but let's try putting it here
|
||||
part.popup.update_displayed_value();
|
||||
}
|
||||
part.popup.x = part.x;
|
||||
part.popup.y = part.y;
|
||||
|
|
|
@ -625,6 +625,10 @@ impl GameEntity<([&mut Player; 2], &NPCList, &mut Stage, &mut BulletManager, &mu
|
|||
_ => Ok(()),
|
||||
}?;
|
||||
|
||||
// I don't know where the best place to put this is, but let's try putting it here
|
||||
if self.shock == 0 && self.npc_flags.show_damage() && self.popup.value != 0 {
|
||||
self.popup.update_displayed_value();
|
||||
}
|
||||
self.popup.x = self.x;
|
||||
self.popup.y = self.y;
|
||||
self.popup.tick(state, ())?;
|
||||
|
|
|
@ -332,6 +332,9 @@ impl NPCList {
|
|||
state.set_flag(npc.flag_num as usize, true);
|
||||
|
||||
if npc.npc_flags.show_damage() {
|
||||
if npc.popup.value != 0 {
|
||||
npc.popup.update_displayed_value();
|
||||
}
|
||||
if vanish {
|
||||
npc.vanish(state);
|
||||
}
|
||||
|
|
|
@ -108,14 +108,13 @@ pub struct Player {
|
|||
pub air: u16,
|
||||
pub skin: Box<dyn PlayerSkin>,
|
||||
pub controller: Box<dyn PlayerController>,
|
||||
pub popup: NumberPopup,
|
||||
pub damage_popup: NumberPopup,
|
||||
pub exp_popup: NumberPopup,
|
||||
strafe_up: bool,
|
||||
weapon_offset_y: i8,
|
||||
splash: bool,
|
||||
tick: u8,
|
||||
booster_switch: BoosterSwitch,
|
||||
damage_counter: u16,
|
||||
damage_taken: i16,
|
||||
pub anim_num: u16,
|
||||
anim_counter: u16,
|
||||
anim_rect: Rect<u16>,
|
||||
|
@ -167,10 +166,9 @@ impl Player {
|
|||
air: 0,
|
||||
skin,
|
||||
controller: Box::new(DummyPlayerController::new()),
|
||||
popup: NumberPopup::new(),
|
||||
damage_popup: NumberPopup::new(),
|
||||
exp_popup: NumberPopup::new(),
|
||||
strafe_up: false,
|
||||
damage_counter: 0,
|
||||
damage_taken: 0,
|
||||
anim_num: 0,
|
||||
anim_counter: 0,
|
||||
anim_rect: constants.player.frames_right[0],
|
||||
|
@ -896,11 +894,8 @@ impl Player {
|
|||
self.controller.set_rumble(rumble_intensity, rumble_intensity, 20);
|
||||
|
||||
self.damage = self.damage.saturating_add(final_hp as u16);
|
||||
if self.popup.value > 0 {
|
||||
self.popup.set_value(-(self.damage as i16));
|
||||
} else {
|
||||
self.popup.add_value(-(self.damage as i16));
|
||||
}
|
||||
self.damage_popup.add_value(-(self.damage as i16));
|
||||
self.damage_popup.update_displayed_value();
|
||||
|
||||
if self.life == 0 {
|
||||
state.sound_manager.play_sfx(17);
|
||||
|
@ -937,9 +932,9 @@ impl GameEntity<&NPCList> for Player {
|
|||
fn tick(&mut self, state: &mut SharedGameState, npc_list: &NPCList) -> GameResult {
|
||||
if !self.cond.alive() {
|
||||
if self.life == 0 {
|
||||
self.popup.x = self.x;
|
||||
self.popup.y = self.y - self.display_bounds.top as i32 + 0x1000;
|
||||
self.popup.tick(state, ())?;
|
||||
self.damage_popup.x = self.x;
|
||||
self.damage_popup.y = self.y - self.display_bounds.top as i32 + 0x1000;
|
||||
self.damage_popup.tick(state, ())?;
|
||||
}
|
||||
|
||||
return Ok(());
|
||||
|
@ -949,18 +944,14 @@ impl GameEntity<&NPCList> for Player {
|
|||
self.shock_counter = 0;
|
||||
}
|
||||
|
||||
if self.damage_counter != 0 {
|
||||
self.damage_counter -= 1;
|
||||
}
|
||||
|
||||
if self.xp_counter != 0 {
|
||||
self.xp_counter -= 1;
|
||||
}
|
||||
|
||||
if self.shock_counter != 0 {
|
||||
self.shock_counter -= 1;
|
||||
} else if self.damage_taken != 0 {
|
||||
self.damage_taken = 0;
|
||||
} else if self.exp_popup.value != 0 {
|
||||
self.exp_popup.update_displayed_value();
|
||||
}
|
||||
|
||||
match (self.control_mode, state.settings.noclip) {
|
||||
|
@ -969,9 +960,12 @@ impl GameEntity<&NPCList> for Player {
|
|||
(ControlMode::IronHead, _) => self.tick_ironhead(state)?,
|
||||
}
|
||||
|
||||
self.popup.x = self.x;
|
||||
self.popup.y = self.y - self.display_bounds.top as i32 + 0x1000;
|
||||
self.popup.tick(state, ())?;
|
||||
self.damage_popup.x = self.x;
|
||||
self.damage_popup.y = self.y - self.display_bounds.top as i32 + 0x1000;
|
||||
self.damage_popup.tick(state, ())?;
|
||||
self.exp_popup.x = self.x;
|
||||
self.exp_popup.y = self.y - self.display_bounds.top as i32 + 0x1000;
|
||||
self.exp_popup.tick(state, ())?;
|
||||
|
||||
self.cond.set_increase_acceleration(false);
|
||||
self.tick_animation(state);
|
||||
|
|
|
@ -287,16 +287,8 @@ impl Player {
|
|||
inventory.add_xp(npc.exp, self, state);
|
||||
|
||||
if let Some(weapon) = inventory.get_current_weapon() {
|
||||
if weapon.wtype == WeaponType::Spur {
|
||||
npc.exp = 0;
|
||||
} else {
|
||||
if self.shock_counter == 0 {
|
||||
if self.popup.value > 0 {
|
||||
self.popup.add_value(npc.exp as i16);
|
||||
} else {
|
||||
self.popup.set_value(npc.exp as i16);
|
||||
}
|
||||
}
|
||||
if weapon.wtype != WeaponType::Spur {
|
||||
self.exp_popup.add_value(npc.exp as i16);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1197,7 +1197,7 @@ impl GameScene {
|
|||
}
|
||||
|
||||
if npc.npc_flags.show_damage() {
|
||||
npc.popup.add_value_throttled(-bullet.damage);
|
||||
npc.popup.add_value(-bullet.damage);
|
||||
}
|
||||
}
|
||||
} else if !bullet.weapon_flags.no_proj_dissipation()
|
||||
|
@ -1261,6 +1261,7 @@ impl GameScene {
|
|||
}
|
||||
|
||||
if npc.npc_flags.shootable() {
|
||||
let shock = npc.shock;
|
||||
if npc.cond.damage_boss() {
|
||||
idx = 0;
|
||||
npc = unsafe { self.boss.parts.get_unchecked_mut(0) };
|
||||
|
@ -1268,10 +1269,6 @@ impl GameScene {
|
|||
|
||||
npc.life = (npc.life as i32).saturating_sub(bullet.damage as i32).clamp(0, u16::MAX as i32) as u16;
|
||||
|
||||
if npc.npc_flags.show_damage() {
|
||||
npc.popup.add_value(-bullet.damage);
|
||||
}
|
||||
|
||||
if npc.life == 0 {
|
||||
npc.life = npc.id;
|
||||
|
||||
|
@ -1295,7 +1292,7 @@ impl GameScene {
|
|||
npc.cond.set_alive(false);
|
||||
}
|
||||
} else {
|
||||
if npc.shock < 14 {
|
||||
if shock < 14 {
|
||||
for _ in 0..3 {
|
||||
state.create_caret(bullet.x, bullet.y, CaretType::HurtParticles, Direction::Left);
|
||||
}
|
||||
|
@ -1303,6 +1300,9 @@ impl GameScene {
|
|||
}
|
||||
|
||||
npc.shock = 8;
|
||||
if npc.npc_flags.show_damage() {
|
||||
npc.popup.add_value(-bullet.damage);
|
||||
}
|
||||
|
||||
npc = unsafe { self.boss.parts.get_unchecked_mut(i) };
|
||||
npc.shock = 8;
|
||||
|
@ -1919,12 +1919,16 @@ impl Scene for GameScene {
|
|||
self.frame.prev_y = self.frame.y;
|
||||
self.player1.prev_x = self.player1.x;
|
||||
self.player1.prev_y = self.player1.y;
|
||||
self.player1.popup.prev_x = self.player1.popup.x;
|
||||
self.player1.popup.prev_y = self.player1.popup.y;
|
||||
self.player1.damage_popup.prev_x = self.player1.damage_popup.x;
|
||||
self.player1.damage_popup.prev_y = self.player1.damage_popup.y;
|
||||
self.player1.exp_popup.prev_x = self.player1.exp_popup.x;
|
||||
self.player1.exp_popup.prev_y = self.player1.exp_popup.y;
|
||||
self.player2.prev_x = self.player2.x;
|
||||
self.player2.prev_y = self.player2.y;
|
||||
self.player2.popup.prev_x = self.player2.popup.x;
|
||||
self.player2.popup.prev_y = self.player2.popup.y;
|
||||
self.player2.damage_popup.prev_x = self.player2.damage_popup.x;
|
||||
self.player2.damage_popup.prev_y = self.player2.damage_popup.y;
|
||||
self.player2.exp_popup.prev_x = self.player2.exp_popup.x;
|
||||
self.player2.exp_popup.prev_y = self.player2.exp_popup.y;
|
||||
|
||||
for npc in self.npc_list.iter_alive() {
|
||||
npc.prev_x = npc.x;
|
||||
|
@ -2010,8 +2014,10 @@ impl Scene for GameScene {
|
|||
self.water_renderer.draw(state, ctx, &self.frame, WaterLayer::Front)?;
|
||||
|
||||
self.draw_carets(state, ctx)?;
|
||||
self.player1.popup.draw(state, ctx, &self.frame)?;
|
||||
self.player2.popup.draw(state, ctx, &self.frame)?;
|
||||
self.player1.exp_popup.draw(state, ctx, &self.frame)?;
|
||||
self.player1.damage_popup.draw(state, ctx, &self.frame)?;
|
||||
self.player2.exp_popup.draw(state, ctx, &self.frame)?;
|
||||
self.player2.damage_popup.draw(state, ctx, &self.frame)?;
|
||||
self.draw_npc_popup(state, ctx)?;
|
||||
self.draw_boss_popup(state, ctx)?;
|
||||
|
||||
|
|
Loading…
Reference in New Issue