use std::fmt;
use std::fmt::Write;
use twgame_core::twsnap;
#[derive(Clone, Debug)]
pub struct Jump {
used_jump_input: bool,
all_air_jumps_used: bool,
infinite_jumps: bool,
last_refill_jumps: bool,
total_air_jumps: i32,
num_jumps: u8,
}
impl Default for Jump {
fn default() -> Self {
Self {
used_jump_input: false,
all_air_jumps_used: false,
infinite_jumps: false,
last_refill_jumps: false,
total_air_jumps: 0,
num_jumps: 2,
}
}
}
pub enum JumpType {
GroundJump,
AirJump,
}
impl Jump {
pub fn format_save(&self, f: &mut String) -> fmt::Result {
let mut jumped = self.used_jump_input as i32;
jumped |= (self.all_air_jumps_used as i32) << 1;
let jumped_total = self.total_air_jumps;
let jumps = self.num_jumps;
write!(f, "\t{jumped}\t{jumped_total}\t{jumps}")
}
pub fn load(&mut self, tee_info: &mut std::str::Split<char>) {
let jumped = tee_info.next().unwrap().parse::<i32>().unwrap();
self.used_jump_input = (jumped & 1) != 0;
self.all_air_jumps_used = (jumped & 2) != 0;
self.total_air_jumps = tee_info.next().unwrap().parse::<i32>().unwrap();
self.num_jumps = tee_info.next().unwrap().parse::<u8>().unwrap();
}
pub fn load_infinite_jumps(&mut self, tee_info: &mut std::str::Split<char>) {
self.infinite_jumps = tee_info.next().unwrap().parse::<i32>().unwrap() != 0;
}
pub fn on_jump(&mut self, grounded: bool) -> Option<JumpType> {
if !self.used_jump_input {
if grounded && (!self.all_air_jumps_used || self.num_jumps != 0) {
if self.num_jumps <= 1 || self.num_jumps == 255 {
self.all_air_jumps_used = true;
}
self.used_jump_input = true;
self.total_air_jumps = 0;
return Some(JumpType::GroundJump);
} else if !self.all_air_jumps_used {
self.used_jump_input = true;
if !self.infinite_jumps {
self.all_air_jumps_used = true;
}
self.total_air_jumps += 1;
return Some(JumpType::AirJump);
}
}
None
}
pub fn on_no_jump(&mut self) {
self.used_jump_input = false;
}
pub fn on_ground(&mut self) {
self.total_air_jumps = 0;
self.all_air_jumps_used = false;
}
pub fn wall_jump(&mut self) {
self.all_air_jumps_used = false;
self.used_jump_input = true;
if self.num_jumps >= 2 {
self.total_air_jumps = self.num_jumps as i32 - 2;
} else {
self.total_air_jumps = 0;
}
}
pub fn snap(&self, tee: &mut twsnap::items::Tee) {
let mut jump_flags = twsnap::flags::JumpFlags::empty();
if self.used_jump_input {
jump_flags.insert(twsnap::flags::JumpFlags::USED_JUMP_INPUT);
}
if self.all_air_jumps_used {
jump_flags.insert(twsnap::flags::JumpFlags::ALL_AIR_JUMPS_USED);
}
tee.jumped = jump_flags;
tee.jumped_total = self.total_air_jumps;
tee.jumps = self.num_jumps as i32;
}
pub fn set_num_jumps(&mut self, num_jumps: u8) {
self.num_jumps = num_jumps;
}
pub fn set_infinite_jumps(&mut self, enabled: bool) {
self.infinite_jumps = enabled;
}
pub fn post_core_tick(&mut self) {
if self.num_jumps == 255 || self.num_jumps < 2 {
self.all_air_jumps_used = true;
} else if self.num_jumps == 1 && (self.all_air_jumps_used || self.used_jump_input)
{
self.all_air_jumps_used = true;
} else if self.total_air_jumps < self.num_jumps as i32 - 1 && self.all_air_jumps_used {
self.all_air_jumps_used = false;
self.used_jump_input = true; }
if self.infinite_jumps && self.all_air_jumps_used {
self.all_air_jumps_used = false;
self.used_jump_input = true;
}
}
pub fn has_infinite_jumps(&self) -> bool {
self.infinite_jumps
}
pub fn on_no_double_jump_refresher(&mut self) {
self.last_refill_jumps = false;
}
pub fn refresh_double_jump(&mut self) {
if !self.last_refill_jumps {
self.last_refill_jumps = true;
self.total_air_jumps = 0;
self.used_jump_input = false;
self.all_air_jumps_used = false;
}
}
}