chore: surface rules: parse some block/states directly

This commit is contained in:
Alexander Medvedev 2026-04-01 23:21:52 +02:00
parent c15ebf181d
commit ed15c00307
9 changed files with 54 additions and 40 deletions

View File

@ -373,7 +373,7 @@ impl ToTokens for BlockPropertyStruct {
for (key, value) in props { for (key, value) in props {
match *key { match *key {
#(#from_props_values),*, #(#from_props_values),*,
_ => {}, // _ => {}, //
} }
} }
block_props block_props

View File

@ -859,7 +859,10 @@ fn value_to_rule_test(v: &Value) -> TokenStream {
"minecraft:always_true" | "" => quote! { RuleTest::AlwaysTrue }, "minecraft:always_true" | "" => quote! { RuleTest::AlwaysTrue },
"minecraft:block_match" => { "minecraft:block_match" => {
let block = v["block"].as_str().unwrap_or("minecraft:stone"); let block = v["block"].as_str().unwrap_or("minecraft:stone");
quote! { RuleTest::BlockMatch(BlockMatchRuleTest { block: #block.to_string() }) } let name_stripped = block.strip_prefix("minecraft:").unwrap_or(block);
let block_ident =
quote::format_ident!("{}", name_stripped.to_uppercase().replace([':', '-'], "_"));
quote! { RuleTest::BlockMatch(BlockMatchRuleTest { block: pumpkin_data::Block::#block_ident }) }
} }
"minecraft:blockstate_match" => { "minecraft:blockstate_match" => {
let state = value_to_block_state(&v["block_state"]); let state = value_to_block_state(&v["block_state"]);
@ -872,7 +875,10 @@ fn value_to_rule_test(v: &Value) -> TokenStream {
"minecraft:random_block_match" => { "minecraft:random_block_match" => {
let block = v["block"].as_str().unwrap_or("minecraft:stone"); let block = v["block"].as_str().unwrap_or("minecraft:stone");
let prob = v["probability"].as_f64().unwrap_or(0.5) as f32; let prob = v["probability"].as_f64().unwrap_or(0.5) as f32;
quote! { RuleTest::RandomBlockMatch(RandomBlockMatchRuleTest { block: #block.to_string(), probability: #prob }) } let name_stripped = block.strip_prefix("minecraft:").unwrap_or(block);
let block_ident =
quote::format_ident!("{}", block.to_uppercase().replace([':', '-'], "_"));
quote! { RuleTest::RandomBlockMatch(RandomBlockMatchRuleTest { block: pumpkin_data::Block::#block_ident, probability: #prob }) }
} }
"minecraft:random_blockstate_match" => { "minecraft:random_blockstate_match" => {
let state = value_to_block_state(&v["block_state"]); let state = value_to_block_state(&v["block_state"]);
@ -1271,17 +1277,19 @@ fn value_to_placement_modifier_cf(v: &Value) -> TokenStream {
let positions = v["positions"] let positions = v["positions"]
.as_array() .as_array()
.map(|arr| { .map(|arr| {
arr.iter().map(|p| { arr.iter()
let coords = p.as_array().unwrap(); .map(|p| {
let x = coords[0].as_i64().unwrap_or(0) as i32; let coords = p.as_array().unwrap();
let y = coords[1].as_i64().unwrap_or(0) as i32; let x = coords[0].as_i64().unwrap_or(0) as i32;
let z = coords[2].as_i64().unwrap_or(0) as i32; let y = coords[1].as_i64().unwrap_or(0) as i32;
quote! { BlockPos::new(#x, #y, #z) } let z = coords[2].as_i64().unwrap_or(0) as i32;
}).collect::<Vec<_>>() quote! { BlockPos::new(#x, #y, #z) }
})
.collect::<Vec<_>>()
}) })
.unwrap_or_default(); .unwrap_or_default();
quote! { PlacementModifier::FixedPlacement(vec![#(#positions),*]) } quote! { PlacementModifier::FixedPlacement(vec![#(#positions),*]) }
}, }
"minecraft:heightmap" => { "minecraft:heightmap" => {
let hm = crate::placed_feature::value_to_height_map( let hm = crate::placed_feature::value_to_height_map(
v["heightmap"].as_str().unwrap_or("MOTION_BLOCKING"), v["heightmap"].as_str().unwrap_or("MOTION_BLOCKING"),

View File

@ -112,17 +112,19 @@ fn value_to_placement_modifier(v: &Value) -> TokenStream {
let positions = v["positions"] let positions = v["positions"]
.as_array() .as_array()
.map(|arr| { .map(|arr| {
arr.iter().map(|p| { arr.iter()
let coords = p.as_array().unwrap(); .map(|p| {
let x = coords[0].as_i64().unwrap_or(0) as i32; let coords = p.as_array().unwrap();
let y = coords[1].as_i64().unwrap_or(0) as i32; let x = coords[0].as_i64().unwrap_or(0) as i32;
let z = coords[2].as_i64().unwrap_or(0) as i32; let y = coords[1].as_i64().unwrap_or(0) as i32;
quote! { BlockPos::new(#x, #y, #z) } let z = coords[2].as_i64().unwrap_or(0) as i32;
}).collect::<Vec<_>>() quote! { BlockPos::new(#x, #y, #z) }
})
.collect::<Vec<_>>()
}) })
.unwrap_or_default(); .unwrap_or_default();
quote! { PlacementModifier::FixedPlacement(vec![#(#positions),*]) } quote! { PlacementModifier::FixedPlacement(vec![#(#positions),*]) }
}, }
"minecraft:heightmap" => { "minecraft:heightmap" => {
let heightmap = let heightmap =
value_to_height_map(v["heightmap"].as_str().unwrap_or("MOTION_BLOCKING")); value_to_height_map(v["heightmap"].as_str().unwrap_or("MOTION_BLOCKING"));

View File

@ -2614,7 +2614,8 @@ fn build_configured_features() -> std::collections::HashMap<String, ConfiguredFe
BlockStateCodec { BlockStateCodec {
name: &pumpkin_data::Block::GRASS_BLOCK, name: &pumpkin_data::Block::GRASS_BLOCK,
properties: Some(props), properties: Some(props),
}.get_state() }
.get_state()
}, },
}), }),
}], }],
@ -6746,7 +6747,7 @@ fn build_configured_features() -> std::collections::HashMap<String, ConfiguredFe
discard_chance_on_air_exposure: 0f32, discard_chance_on_air_exposure: 0f32,
targets: vec![OreTarget { targets: vec![OreTarget {
target: RuleTest::BlockMatch(BlockMatchRuleTest { target: RuleTest::BlockMatch(BlockMatchRuleTest {
block: "minecraft:netherrack".to_string(), block: pumpkin_data::Block::NETHERRACK,
}), }),
state: pumpkin_data::Block::BLACKSTONE.default_state, state: pumpkin_data::Block::BLACKSTONE.default_state,
}], }],
@ -7055,7 +7056,7 @@ fn build_configured_features() -> std::collections::HashMap<String, ConfiguredFe
discard_chance_on_air_exposure: 0f32, discard_chance_on_air_exposure: 0f32,
targets: vec![OreTarget { targets: vec![OreTarget {
target: RuleTest::BlockMatch(BlockMatchRuleTest { target: RuleTest::BlockMatch(BlockMatchRuleTest {
block: "minecraft:netherrack".to_string(), block: pumpkin_data::Block::NETHERRACK,
}), }),
state: pumpkin_data::Block::GRAVEL.default_state, state: pumpkin_data::Block::GRAVEL.default_state,
}], }],
@ -7181,7 +7182,7 @@ fn build_configured_features() -> std::collections::HashMap<String, ConfiguredFe
discard_chance_on_air_exposure: 0f32, discard_chance_on_air_exposure: 0f32,
targets: vec![OreTarget { targets: vec![OreTarget {
target: RuleTest::BlockMatch(BlockMatchRuleTest { target: RuleTest::BlockMatch(BlockMatchRuleTest {
block: "minecraft:netherrack".to_string(), block: pumpkin_data::Block::NETHERRACK,
}), }),
state: pumpkin_data::Block::MAGMA_BLOCK.default_state, state: pumpkin_data::Block::MAGMA_BLOCK.default_state,
}], }],
@ -7194,7 +7195,7 @@ fn build_configured_features() -> std::collections::HashMap<String, ConfiguredFe
discard_chance_on_air_exposure: 0f32, discard_chance_on_air_exposure: 0f32,
targets: vec![OreTarget { targets: vec![OreTarget {
target: RuleTest::BlockMatch(BlockMatchRuleTest { target: RuleTest::BlockMatch(BlockMatchRuleTest {
block: "minecraft:netherrack".to_string(), block: pumpkin_data::Block::NETHERRACK,
}), }),
state: pumpkin_data::Block::NETHER_GOLD_ORE.default_state, state: pumpkin_data::Block::NETHER_GOLD_ORE.default_state,
}], }],
@ -7207,7 +7208,7 @@ fn build_configured_features() -> std::collections::HashMap<String, ConfiguredFe
discard_chance_on_air_exposure: 0f32, discard_chance_on_air_exposure: 0f32,
targets: vec![OreTarget { targets: vec![OreTarget {
target: RuleTest::BlockMatch(BlockMatchRuleTest { target: RuleTest::BlockMatch(BlockMatchRuleTest {
block: "minecraft:netherrack".to_string(), block: pumpkin_data::Block::NETHERRACK,
}), }),
state: pumpkin_data::Block::NETHER_QUARTZ_ORE.default_state, state: pumpkin_data::Block::NETHER_QUARTZ_ORE.default_state,
}], }],
@ -7257,7 +7258,7 @@ fn build_configured_features() -> std::collections::HashMap<String, ConfiguredFe
discard_chance_on_air_exposure: 0f32, discard_chance_on_air_exposure: 0f32,
targets: vec![OreTarget { targets: vec![OreTarget {
target: RuleTest::BlockMatch(BlockMatchRuleTest { target: RuleTest::BlockMatch(BlockMatchRuleTest {
block: "minecraft:netherrack".to_string(), block: pumpkin_data::Block::NETHERRACK,
}), }),
state: pumpkin_data::Block::SOUL_SAND.default_state, state: pumpkin_data::Block::SOUL_SAND.default_state,
}], }],

View File

@ -841,7 +841,7 @@ fn build_placed_features() -> std::collections::HashMap<String, PlacedFeature> {
PlacedFeature { PlacedFeature {
feature: Feature::Named("end_platform".to_string()), feature: Feature::Named("end_platform".to_string()),
placement: vec![ placement: vec![
PlacementModifier::FixedPlacement(vec![BlockPos::new(100, 50, 0)]), PlacementModifier::FixedPlacement(vec![BlockPos::new(100i32, 49i32, 0i32)]),
PlacementModifier::Biome(BiomePlacementModifier), PlacementModifier::Biome(BiomePlacementModifier),
], ],
}, },

View File

@ -1,13 +1,14 @@
use pumpkin_data::Block;
use crate::block::RawBlockState; use crate::block::RawBlockState;
pub struct BlockMatchRuleTest { pub struct BlockMatchRuleTest {
// This should be a Block codec, so this is wrong pub block: Block,
pub block: String,
} }
impl BlockMatchRuleTest { impl BlockMatchRuleTest {
#[must_use] #[must_use]
pub fn test(&self, state: RawBlockState) -> bool { pub fn test(&self, state: RawBlockState) -> bool {
state.to_block().name == self.block.strip_prefix("minecraft:").unwrap_or(&self.block) state.to_block().name == self.block.name
} }
} }

View File

@ -1,12 +1,14 @@
use crate::block::{BlockStateCodec, RawBlockState}; use pumpkin_data::BlockState;
use crate::block::RawBlockState;
pub struct BlockStateMatchRuleTest { pub struct BlockStateMatchRuleTest {
pub block_state: BlockStateCodec, pub block_state: BlockState,
} }
impl BlockStateMatchRuleTest { impl BlockStateMatchRuleTest {
#[must_use] #[must_use]
pub fn test(&self, state: RawBlockState) -> bool { pub fn test(&self, state: RawBlockState) -> bool {
state.0 == self.block_state.get_state_id() state.0 == self.block_state.id
} }
} }

View File

@ -1,16 +1,15 @@
use pumpkin_data::Block;
use pumpkin_util::random::{RandomGenerator, RandomImpl}; use pumpkin_util::random::{RandomGenerator, RandomImpl};
use crate::block::RawBlockState; use crate::block::RawBlockState;
pub struct RandomBlockMatchRuleTest { pub struct RandomBlockMatchRuleTest {
// This should be a Block codec, so this is wrong pub block: Block,
pub block: String,
pub probability: f32, pub probability: f32,
} }
impl RandomBlockMatchRuleTest { impl RandomBlockMatchRuleTest {
pub fn test(&self, state: RawBlockState, random: &mut RandomGenerator) -> bool { pub fn test(&self, state: RawBlockState, random: &mut RandomGenerator) -> bool {
state.to_block().name == self.block.strip_prefix("minecraft:").unwrap_or(&self.block) state.to_block().name == self.block.name && random.next_f32() < self.probability
&& random.next_f32() < self.probability
} }
} }

View File

@ -1,14 +1,15 @@
use pumpkin_data::BlockState;
use pumpkin_util::random::{RandomGenerator, RandomImpl}; use pumpkin_util::random::{RandomGenerator, RandomImpl};
use crate::block::{BlockStateCodec, RawBlockState}; use crate::block::RawBlockState;
pub struct RandomBlockStateMatchRuleTest { pub struct RandomBlockStateMatchRuleTest {
pub block_state: BlockStateCodec, pub block_state: BlockState,
pub probability: f32, pub probability: f32,
} }
impl RandomBlockStateMatchRuleTest { impl RandomBlockStateMatchRuleTest {
pub fn test(&self, state: RawBlockState, random: &mut RandomGenerator) -> bool { pub fn test(&self, state: RawBlockState, random: &mut RandomGenerator) -> bool {
state.0 == self.block_state.get_state_id() && random.next_f32() < self.probability state.0 == self.block_state.id && random.next_f32() < self.probability
} }
} }