use pumpkin_data::Block; use pumpkin_util::{ BlockDirection, math::block_box::BlockBox, random::{RandomGenerator, RandomImpl}, }; use crate::{ ProtoChunk, generation::structure::{ piece::StructurePieceType, structures::{ StructurePiece, StructurePieceBase, StructurePiecesCollector, stronghold::{ EntranceType, PieceWeight, StoneBrickRandomizer, StrongholdPiece, StrongholdPieceType, }, }, }, }; #[derive(Clone)] pub struct RightTurnPiece { pub piece: StrongholdPiece, } impl RightTurnPiece { pub fn create( collector: &mut StructurePiecesCollector, random: &mut impl RandomImpl, x: i32, y: i32, z: i32, orientation: BlockDirection, chain_length: u32, ) -> Option> { // 5x5x5 box let bounding_box = BlockBox::rotated(x, y, z, -1, -1, 0, 5, 5, 5, &orientation); if !StrongholdPiece::is_in_bounds(&bounding_box) || collector.get_intersecting(&bounding_box).is_some() { return None; } let mut piece = StrongholdPiece::new( StructurePieceType::StrongholdRightTurn, chain_length, bounding_box, ); piece.piece.set_facing(Some(orientation)); piece.entry_door = EntranceType::get_random(random); Some(Box::new(Self { piece })) } } impl StructurePieceBase for RightTurnPiece { fn get_structure_piece(&self) -> &StructurePiece { &self.piece.piece } fn get_structure_piece_mut(&mut self) -> &mut StructurePiece { &mut self.piece.piece } fn fill_openings( &self, start: &StructurePiece, random: &mut RandomGenerator, weights: &mut Vec, last_piece_type: &mut Option, _has_portal_room: &mut bool, collector: &mut StructurePiecesCollector, pieces_to_process: &mut Vec>, ) { let facing = self.piece.piece.facing.unwrap_or(BlockDirection::North); if facing == BlockDirection::North || facing == BlockDirection::East { self.piece.fill_se_opening( start, collector, random, weights, last_piece_type, 1, 1, pieces_to_process, ); } else { self.piece.fill_nw_opening( start, collector, random, weights, last_piece_type, 1, 1, pieces_to_process, ); } } fn place( &mut self, chunk: &mut ProtoChunk, random: &mut RandomGenerator, _seed: i64, chunk_box: &BlockBox, ) { let randomizer = StoneBrickRandomizer; let box_limit = *chunk_box; let p = &self.piece; let inner = &p.piece; // 1. 5x5x5 Outline (Using randomizer) inner.fill_outline_random( 0, 0, 0, 4, 4, 4, &randomizer, chunk, true, random, &box_limit, ); // 2. Entrance (Z=0) p.generate_entrance(chunk, &box_limit, self.piece.entry_door, 1, 1, 0); // 3. Exit logic based on Facing let air = Block::AIR.default_state; let facing = inner.facing.unwrap_or(BlockDirection::North); if facing == BlockDirection::North || facing == BlockDirection::East { // Exit on X=4 wall inner.fill_with_outline(chunk, &box_limit, false, 4, 1, 1, 4, 3, 3, air, air); } else { inner.fill_with_outline(chunk, &box_limit, false, 0, 1, 1, 0, 3, 3, air, air); } } fn clone_box(&self) -> Box { Box::new((*self).clone()) } }