151 lines
4.0 KiB
Rust
151 lines
4.0 KiB
Rust
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<Box<dyn StructurePieceBase>> {
|
|
// 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<PieceWeight>,
|
|
last_piece_type: &mut Option<StrongholdPieceType>,
|
|
_has_portal_room: &mut bool,
|
|
|
|
collector: &mut StructurePiecesCollector,
|
|
pieces_to_process: &mut Vec<Box<dyn StructurePieceBase>>,
|
|
) {
|
|
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<dyn StructurePieceBase> {
|
|
Box::new((*self).clone())
|
|
}
|
|
}
|