mirror of
https://github.com/Pumpkin-MC/Pumpkin
synced 2025-04-15 18:45:35 +00:00
change biomes parsing (#683)
* change biomes parsing now we have more infos * add temperature_modifier * add ids
This commit is contained in:
committed by
GitHub
parent
04ae9654a2
commit
ce60881132
assets
pumpkin-data/build
pumpkin-world/src
11378
assets/biome.json
11378
assets/biome.json
File diff suppressed because it is too large
Load Diff
@ -1,26 +1,147 @@
|
||||
use heck::ToPascalCase;
|
||||
use proc_macro2::TokenStream;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use heck::ToShoutySnakeCase;
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
use quote::{format_ident, quote};
|
||||
use serde::Deserialize;
|
||||
use syn::LitInt;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct Biome {
|
||||
has_precipitation: bool,
|
||||
temperature: f32,
|
||||
downfall: f32,
|
||||
temperature_modifier: Option<TemperatureModifier>,
|
||||
//carvers: Vec<String>,
|
||||
features: Vec<Vec<String>>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum TemperatureModifier {
|
||||
None,
|
||||
Frozen,
|
||||
}
|
||||
|
||||
pub(crate) fn build() -> TokenStream {
|
||||
println!("cargo:rerun-if-changed=../assets/biome.json");
|
||||
|
||||
let biomes: Vec<String> = serde_json::from_str(include_str!("../../assets/biome.json"))
|
||||
.expect("Failed to parse biome.json");
|
||||
let biomes: HashMap<String, Biome> =
|
||||
serde_json::from_str(include_str!("../../assets/biome.json"))
|
||||
.expect("Failed to parse biome.json");
|
||||
let mut variants = TokenStream::new();
|
||||
let mut type_to_name = TokenStream::new();
|
||||
let mut name_to_type = TokenStream::new();
|
||||
let mut type_to_id = TokenStream::new();
|
||||
let mut id_to_type = TokenStream::new();
|
||||
|
||||
for (i, (name, biome)) in biomes.iter().enumerate() {
|
||||
// let full_name = format!("minecraft:{name}");
|
||||
let format_name = format_ident!("{}", name.to_shouty_snake_case());
|
||||
let has_precipitation = biome.has_precipitation;
|
||||
let temperature = biome.temperature;
|
||||
let downfall = biome.downfall;
|
||||
// let carvers = &biome.carvers;
|
||||
let features = &biome.features;
|
||||
let temperature_modifier = biome
|
||||
.temperature_modifier
|
||||
.clone()
|
||||
.unwrap_or(TemperatureModifier::None);
|
||||
let temperature_modifier = match temperature_modifier {
|
||||
TemperatureModifier::Frozen => quote! { TemperatureModifier::Frozen },
|
||||
TemperatureModifier::None => quote! { TemperatureModifier::None },
|
||||
};
|
||||
let index = LitInt::new(&i.to_string(), Span::call_site());
|
||||
|
||||
for status in biomes.iter() {
|
||||
let full_name = format!("minecraft:{status}");
|
||||
let name = format_ident!("{}", status.to_pascal_case());
|
||||
variants.extend([quote! {
|
||||
#[serde(rename = #full_name)]
|
||||
#name,
|
||||
pub const #format_name: Biome = Biome {
|
||||
index: #index,
|
||||
has_precipitation: #has_precipitation,
|
||||
temperature: #temperature,
|
||||
temperature_modifier: #temperature_modifier,
|
||||
downfall: #downfall,
|
||||
features: &[#(&[#(#features),*]),*]
|
||||
};
|
||||
}]);
|
||||
|
||||
type_to_name.extend(quote! { Self::#format_name => #name, });
|
||||
name_to_type.extend(quote! { #name => Some(Self::#format_name), });
|
||||
type_to_id.extend(quote! { Self::#format_name => #index, });
|
||||
id_to_type.extend(quote! { #index => Some(Self::#format_name), });
|
||||
}
|
||||
|
||||
quote! {
|
||||
#[derive(Clone, Deserialize, Copy, Hash, PartialEq, Eq, Debug)]
|
||||
pub enum Biome {
|
||||
use serde::{de, Deserializer};
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||
pub struct Biome {
|
||||
pub index: u8,
|
||||
pub has_precipitation: bool,
|
||||
pub temperature: f32,
|
||||
pub temperature_modifier: TemperatureModifier,
|
||||
pub downfall: f32,
|
||||
// carvers: &'static [&str],
|
||||
pub features: &'static [&'static [&'static str]]
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for Biome {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
struct BiomeVisitor;
|
||||
|
||||
impl de::Visitor<'_> for BiomeVisitor {
|
||||
type Value = Biome;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("a biome name as a string")
|
||||
}
|
||||
|
||||
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
self.visit_str(&v)
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
let biome = Biome::from_name(&value.replace("minecraft:", ""));
|
||||
|
||||
biome.ok_or_else(|| E::unknown_variant(value, &["unknown biome"]))
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.deserialize_str(BiomeVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||
pub enum TemperatureModifier {
|
||||
None,
|
||||
Frozen
|
||||
}
|
||||
|
||||
impl Biome {
|
||||
#variants
|
||||
|
||||
pub fn from_name(name: &str) -> Option<Self> {
|
||||
match name {
|
||||
#name_to_type
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn from_id(id: u16) -> Option<Self> {
|
||||
match id {
|
||||
#id_to_type
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -98,6 +98,6 @@ mod test {
|
||||
&pumpkin_util::math::vector3::Vector3 { x: -24, y: 1, z: 8 },
|
||||
&mut sampler,
|
||||
);
|
||||
assert_eq!(biome, Biome::Desert)
|
||||
assert_eq!(biome, Biome::DESERT)
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ impl GeneratorInit for SuperflatBiomeGenerator {
|
||||
impl BiomeGenerator for SuperflatBiomeGenerator {
|
||||
// TODO make generic over Biome and allow changing the Biome in the config.
|
||||
fn generate_biome(&self, _: XZBlockCoordinates) -> Biome {
|
||||
Biome::Plains
|
||||
Biome::PLAINS
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -166,7 +166,7 @@ impl<'a> ProtoChunk<'a> {
|
||||
flat_block_map: vec![ChunkBlockState::AIR; CHUNK_AREA * height as usize]
|
||||
.into_boxed_slice(),
|
||||
flat_biome_map: vec![
|
||||
Biome::Plains;
|
||||
Biome::PLAINS;
|
||||
biome_coords::from_block(CHUNK_DIM as usize)
|
||||
* biome_coords::from_block(CHUNK_DIM as usize)
|
||||
* biome_coords::from_block(height as usize)
|
||||
@ -242,7 +242,7 @@ impl<'a> ProtoChunk<'a> {
|
||||
if local_pos.y < 0
|
||||
|| local_pos.y >= biome_coords::from_block(self.noise_sampler.height() as i32)
|
||||
{
|
||||
Biome::Plains
|
||||
Biome::PLAINS
|
||||
} else {
|
||||
self.flat_biome_map[self.local_biome_pos_to_biome_index(&local_pos)]
|
||||
}
|
||||
@ -431,7 +431,7 @@ impl<'a> ProtoChunk<'a> {
|
||||
};
|
||||
|
||||
let this_biome = self.get_biome_for_terrain_gen(&Vector3::new(x, biome_y, z));
|
||||
if this_biome == Biome::ErodedBadlands {
|
||||
if this_biome == Biome::ERODED_BADLANDS {
|
||||
terrain_builder.place_badlands_pillar(
|
||||
self,
|
||||
x,
|
||||
@ -495,7 +495,7 @@ impl<'a> ProtoChunk<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
if this_biome == Biome::FrozenOcean || this_biome == Biome::DeepFrozenOcean {
|
||||
if this_biome == Biome::FROZEN_OCEAN || this_biome == Biome::DEEP_FROZEN_OCEAN {
|
||||
let min_y = estimate_surface_height(
|
||||
&mut context,
|
||||
&mut self.surface_height_estimate_sampler,
|
||||
|
@ -4,6 +4,7 @@ use pumpkin_util::{
|
||||
random::RandomDeriver,
|
||||
};
|
||||
use serde::Deserialize;
|
||||
|
||||
use terrain::SurfaceTerrainBuilder;
|
||||
|
||||
use crate::generation::{positions::chunk_pos, section_coords};
|
||||
@ -65,7 +66,7 @@ impl<'a> MaterialRuleContext<'a> {
|
||||
terrain_builder,
|
||||
fluid_height: 0,
|
||||
block_pos: Vector3::new(0, 0, 0),
|
||||
biome: Biome::Plains,
|
||||
biome: Biome::PLAINS,
|
||||
run_depth: 0,
|
||||
secondary_depth: 0.0,
|
||||
surface_noise: noise_builder.get_noise_sampler_for_id("surface"),
|
||||
|
Reference in New Issue
Block a user