From 76e62cd7393b780e550678f43aba1c98cb7a4809 Mon Sep 17 00:00:00 2001 From: RB007 <36972202+RoosterBooster007@users.noreply.github.com> Date: Wed, 18 Mar 2026 03:10:52 -0400 Subject: [PATCH] feat: glowstone feature (#1878) --- pumpkin-codegen/src/configured_feature.rs | 6 +- .../generation/feature/configured_features.rs | 3 + .../feature/features/glowstone_blob.rs | 66 ++++++++++++++++++- 3 files changed, 70 insertions(+), 5 deletions(-) diff --git a/pumpkin-codegen/src/configured_feature.rs b/pumpkin-codegen/src/configured_feature.rs index 99964207a..4233ef3da 100644 --- a/pumpkin-codegen/src/configured_feature.rs +++ b/pumpkin-codegen/src/configured_feature.rs @@ -487,6 +487,9 @@ pub fn value_to_configured_feature(v: &Value) -> TokenStream { ) } } + "minecraft:glowstone_blob" => { + quote! { ConfiguredFeature::GlowstoneBlob(crate::generation::feature::features::glowstone_blob::GlowstoneBlobFeature {}) } + } // All TODO/empty features "minecraft:fossil" => { @@ -507,9 +510,6 @@ pub fn value_to_configured_feature(v: &Value) -> TokenStream { "minecraft:ice_spike" => { quote! { ConfiguredFeature::IceSpike(crate::generation::feature::features::ice_spike::IceSpikeFeature {}) } } - "minecraft:glowstone_blob" => { - quote! { ConfiguredFeature::GlowstoneBlob(crate::generation::feature::features::glowstone_blob::GlowstoneBlobFeature {}) } - } "minecraft:freeze_top_layer" => { quote! { ConfiguredFeature::FreezeTopLayer(crate::generation::feature::features::freeze_top_layer::FreezeTopLayerFeature {}) } } diff --git a/pumpkin-world/src/generation/feature/configured_features.rs b/pumpkin-world/src/generation/feature/configured_features.rs index 5a2353546..9c2ee0bf1 100644 --- a/pumpkin-world/src/generation/feature/configured_features.rs +++ b/pumpkin-world/src/generation/feature/configured_features.rs @@ -321,6 +321,9 @@ impl ConfiguredFeature { Self::MonsterRoom(feature) => { feature.generate(chunk, min_y, height, feature_name, random, pos) } + Self::GlowstoneBlob(feature) => { + feature.generate(chunk, min_y, height, feature_name, random, pos) + } _ => false, // TODO } } diff --git a/pumpkin-world/src/generation/feature/features/glowstone_blob.rs b/pumpkin-world/src/generation/feature/features/glowstone_blob.rs index 453804d9d..3f6cfc2cf 100644 --- a/pumpkin-world/src/generation/feature/features/glowstone_blob.rs +++ b/pumpkin-world/src/generation/feature/features/glowstone_blob.rs @@ -1,3 +1,65 @@ -pub struct GlowstoneBlobFeature { - // TODO +use pumpkin_data::{Block, BlockDirection}; +use pumpkin_util::{ + math::position::BlockPos, + random::{RandomGenerator, RandomImpl}, +}; + +use crate::generation::proto_chunk::GenerationCache; + +pub struct GlowstoneBlobFeature {} + +impl GlowstoneBlobFeature { + pub fn generate( + &self, + chunk: &mut T, + _min_y: i8, + _height: u16, + _feature: &str, + random: &mut RandomGenerator, + pos: BlockPos, + ) -> bool { + if !chunk.is_air(&pos.0) { + return false; + } + + let above_id = GenerationCache::get_block_state(chunk, &pos.up().0).to_block_id(); + if above_id != Block::NETHERRACK.id + && above_id != Block::BASALT.id + && above_id != Block::BLACKSTONE.id + { + return false; + } + + chunk.set_block_state(&pos.0, Block::GLOWSTONE.default_state); + + for _ in 0..1500 { + let place_pos = pos.add( + random.next_bounded_i32(8) - random.next_bounded_i32(8), + -random.next_bounded_i32(12), + random.next_bounded_i32(8) - random.next_bounded_i32(8), + ); + + if chunk.is_air(&place_pos.0) { + let mut neighbours = 0u8; + + for dir in BlockDirection::all() { + let neighbor = place_pos.0.add(&dir.to_offset()); + if GenerationCache::get_block_state(chunk, &neighbor).to_block_id() + == Block::GLOWSTONE.id + { + neighbours += 1; + } + if neighbours > 1 { + break; + } + } + + if neighbours == 1 { + chunk.set_block_state(&place_pos.0, Block::GLOWSTONE.default_state); + } + } + } + + true + } }