use super::{Mode, Player};
use crate::sim::{Event, Intent, Terrain, Tuning};
const BONK: (f32, f32) = (60.0, 90.0);
impl Player {
pub(super) fn super_dash(
&mut self,
level: &dyn Terrain,
i: &Intent,
t: &Tuning,
ev: &mut Vec<Event>,
) {
let fresh = i.super_dash && !self.was_super;
self.was_super = i.super_dash;
if !t.super_dash {
return;
}
match self.mode {
Mode::Normal | Mode::Climb if fresh => {
let wall = if self.mode == Mode::Climb {
self.facing
} else {
self.wall_slide
};
if !self.grounded && wall == 0 {
return;
}
let wall = if self.grounded { 0 } else { wall };
self.mode = Mode::SuperCharge { t: 0.0, wall };
self.vx = 0.0;
self.vy = 0.0;
self.stop_jump();
}
Mode::SuperCharge { t: charged, wall } => {
self.vx = 0.0;
if wall != 0 {
self.vy = 0.0;
}
let lost = if wall == 0 {
!self.grounded
} else {
!self.wall(level, wall)
};
if lost {
self.mode = Mode::Normal;
} else if !i.super_dash && charged >= t.super_charge {
let dir = if wall != 0 { -wall } else { self.facing };
self.facing = dir;
self.mode = Mode::SuperDash { dir };
self.vx = dir as f32 * t.super_speed;
ev.push(Event::SuperDashStarted { dir });
} else if !i.super_dash {
self.mode = Mode::Normal;
}
}
Mode::SuperDash { dir } => {
if fresh || i.jump_pressed {
self.mode = Mode::Normal;
self.vx = dir as f32 * t.super_cancel_speed;
self.buffer = 0.0;
ev.push(Event::SuperDashEnded { bonk: false });
} else {
self.vx = dir as f32 * t.super_speed;
self.vy = 0.0;
}
}
_ => {}
}
}
pub(super) fn super_bonk(&mut self, dir: i32, ev: &mut Vec<Event>) {
self.mode = Mode::Normal;
self.vx = -dir as f32 * BONK.0;
self.vy = -BONK.1;
ev.push(Event::SuperDashEnded { bonk: true });
}
}