use crate::gdobj::{GDValue, Group};
const LCG_MULTIPLIER: u64 = 214013;
const LCG_CONSTANT: u64 = 2531011;
#[inline(always)]
pub fn next_seed(seed: u64) -> u64 {
seed.wrapping_mul(LCG_MULTIPLIER).wrapping_add(LCG_CONSTANT)
}
#[inline(always)]
pub fn next_seed_mut(seed: &mut u64) {
*seed = seed.wrapping_mul(LCG_MULTIPLIER).wrapping_add(LCG_CONSTANT);
}
#[inline(always)]
pub fn fast_rand_bits(seed: u64) -> u64 {
(next_seed(seed) >> 16) & 0x7fff
}
#[inline(always)]
pub fn fast_rand_bits_norm(seed: u64) -> f64 {
fast_rand_bits(seed) as f64 / 32767.0
}
#[inline(always)]
pub fn check_seed_random(seed: u64, chance: f64) -> bool {
fast_rand_bits_norm(seed) < chance
}
pub fn check_seed_advanced_random(seed: u64, probabilities: &GDValue) -> Option<Group> {
let prob_list;
if let GDValue::ProbabilitiesList(probs) = probabilities {
prob_list = probs;
} else {
return None;
}
if prob_list.is_empty() {
return None;
}
if prob_list.len() == 1 {
return Some(Group::Regular(prob_list[0].0));
}
let total_chance: i32 = prob_list.iter().map(|(_, chance)| chance).sum();
let threshold = fast_rand_bits_norm(seed) * total_chance as f64;
let mut cumulative_chance = 0;
let mut chosen_group = prob_list.last().unwrap().0;
for (group, chance) in prob_list.iter() {
cumulative_chance += chance;
if cumulative_chance as f64 >= threshold {
chosen_group = *group;
break;
}
}
Some(Group::Regular(chosen_group))
}