use std::mem;
use crate::catch::performance::CatchPerformance;
#[derive(Clone, Debug, Default, PartialEq)]
pub struct CatchDifficultyAttributes {
pub stars: f64,
pub ar: f64,
pub n_fruits: u32,
pub n_droplets: u32,
pub n_tiny_droplets: u32,
pub is_convert: bool,
}
impl CatchDifficultyAttributes {
pub const fn max_combo(&self) -> u32 {
self.n_fruits + self.n_droplets
}
pub const fn is_convert(&self) -> bool {
self.is_convert
}
pub fn performance<'a>(self) -> CatchPerformance<'a> {
self.into()
}
pub(crate) fn set_object_count(&mut self, count: &ObjectCount) {
self.n_fruits = count.fruits;
self.n_droplets = count.droplets;
self.n_tiny_droplets = count.tiny_droplets;
}
pub(crate) fn add_object_count(&mut self, count: GradualObjectCount) {
if count.fruit {
self.n_fruits += 1;
} else {
self.n_droplets += 1;
}
self.n_tiny_droplets += count.tiny_droplets;
}
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct CatchPerformanceAttributes {
pub difficulty: CatchDifficultyAttributes,
pub pp: f64,
}
impl CatchPerformanceAttributes {
pub const fn stars(&self) -> f64 {
self.difficulty.stars
}
pub const fn pp(&self) -> f64 {
self.pp
}
pub const fn max_combo(&self) -> u32 {
self.difficulty.max_combo()
}
pub const fn is_convert(&self) -> bool {
self.difficulty.is_convert
}
pub fn performance<'a>(self) -> CatchPerformance<'a> {
self.difficulty.into()
}
}
impl From<CatchPerformanceAttributes> for CatchDifficultyAttributes {
fn from(attributes: CatchPerformanceAttributes) -> Self {
attributes.difficulty
}
}
#[derive(Clone, Default)]
pub struct ObjectCount {
fruits: u32,
droplets: u32,
tiny_droplets: u32,
}
#[derive(Copy, Clone, Default)]
pub struct GradualObjectCount {
fruit: bool,
tiny_droplets: u32,
}
pub enum ObjectCountBuilder {
Regular {
count: ObjectCount,
take: usize,
},
Gradual {
count: GradualObjectCount,
all: Vec<GradualObjectCount>,
},
}
impl ObjectCountBuilder {
pub fn new_regular(take: usize) -> Self {
Self::Regular {
count: ObjectCount::default(),
take,
}
}
pub fn new_gradual() -> Self {
Self::Gradual {
count: GradualObjectCount::default(),
all: Vec::with_capacity(512),
}
}
pub fn into_regular(self) -> ObjectCount {
if let Self::Regular { count, .. } = self {
count
} else {
unreachable!()
}
}
pub fn into_gradual(self) -> Vec<GradualObjectCount> {
if let Self::Gradual { all, .. } = self {
all
} else {
unreachable!()
}
}
pub fn record_fruit(&mut self) {
match self {
Self::Regular { count, take } => {
if *take > 0 {
*take -= 1;
count.fruits += 1;
}
}
Self::Gradual { count, all } => {
count.fruit = true;
all.push(mem::take(count));
}
}
}
pub fn record_droplet(&mut self) {
match self {
Self::Regular { count, take } => {
if *take > 0 {
*take -= 1;
count.droplets += 1;
}
}
Self::Gradual { count, all } => all.push(mem::take(count)),
}
}
pub fn record_tiny_droplets(&mut self, n: u32) {
match self {
Self::Regular { count, take } => {
if *take > 0 {
count.tiny_droplets += n;
}
}
Self::Gradual { count, .. } => count.tiny_droplets += n,
}
}
}