90 lines
2.7 KiB
Rust
90 lines
2.7 KiB
Rust
use pumpkin_util::random::{RandomGenerator, RandomImpl};
|
|
use serde::Deserialize;
|
|
|
|
use super::y_offset::YOffset;
|
|
|
|
#[derive(Deserialize)]
|
|
#[serde(tag = "type")]
|
|
pub enum HeightProvider {
|
|
#[serde(rename = "minecraft:uniform")]
|
|
Uniform(UniformHeightProvider),
|
|
#[serde(rename = "minecraft:trapezoid")]
|
|
Trapezoid(TrapezoidHeightProvider),
|
|
#[serde(rename = "minecraft:very_biased_to_bottom")]
|
|
VeryBiasedToBottom(VeryBiasedToBottomHeightProvider),
|
|
}
|
|
|
|
impl HeightProvider {
|
|
pub fn get(&self, random: &mut RandomGenerator, min_y: i8, height: u16) -> i32 {
|
|
match self {
|
|
HeightProvider::Uniform(provider) => provider.get(random, min_y, height),
|
|
HeightProvider::Trapezoid(provider) => provider.get(random, min_y, height),
|
|
HeightProvider::VeryBiasedToBottom(provider) => provider.get(random, min_y, height),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
pub struct VeryBiasedToBottomHeightProvider {
|
|
min_inclusive: YOffset,
|
|
max_inclusive: YOffset,
|
|
inner: Option<u32>,
|
|
}
|
|
|
|
impl VeryBiasedToBottomHeightProvider {
|
|
pub fn get(&self, random: &mut RandomGenerator, min_y: i8, height: u16) -> i32 {
|
|
let min = self.min_inclusive.get_y(min_y as i16, height);
|
|
let max = self.max_inclusive.get_y(min_y as i16, height);
|
|
let inner = self.inner.unwrap_or(1) as i32;
|
|
|
|
let min_rnd = random.next_inbetween_i32(min + inner, max);
|
|
let max_rnd = random.next_inbetween_i32(min, min_rnd - 1);
|
|
|
|
random.next_inbetween_i32(min, max_rnd - 1 + inner)
|
|
}
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
pub struct UniformHeightProvider {
|
|
min_inclusive: YOffset,
|
|
max_inclusive: YOffset,
|
|
}
|
|
|
|
impl UniformHeightProvider {
|
|
pub fn get(&self, random: &mut RandomGenerator, min_y: i8, height: u16) -> i32 {
|
|
let min = self.min_inclusive.get_y(min_y as i16, height);
|
|
let max = self.max_inclusive.get_y(min_y as i16, height);
|
|
|
|
random.next_inbetween_i32(min, max)
|
|
}
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
pub struct TrapezoidHeightProvider {
|
|
min_inclusive: YOffset,
|
|
max_inclusive: YOffset,
|
|
plateau: Option<i32>,
|
|
}
|
|
|
|
impl TrapezoidHeightProvider {
|
|
pub fn get(&self, random: &mut RandomGenerator, min_y: i8, height: u16) -> i32 {
|
|
let plateau = self.plateau.unwrap_or(0);
|
|
let i = self.min_inclusive.get_y(min_y as i16, height);
|
|
let j = self.max_inclusive.get_y(min_y as i16, height);
|
|
|
|
if i > j {
|
|
log::warn!("Empty height range");
|
|
return i;
|
|
}
|
|
|
|
let k = j - i;
|
|
if plateau >= k {
|
|
return random.next_inbetween_i32(i, j);
|
|
}
|
|
|
|
let l = (k - plateau) / 2;
|
|
let m = k - l;
|
|
i + random.next_inbetween_i32(0, m) + random.next_inbetween_i32(0, l)
|
|
}
|
|
}
|