use pumpkin_data::{ Block, BlockDirection, BlockId, BlockStateId, block_properties::WallTorchLikeProperties, entity::EntityType, world::WorldEvent, }; use pumpkin_world::world::BlockFlags; use crate::{ block::{BlockBehaviour, BlockMetadata, OnPlaceArgs, PlacedArgs}, entity::{ Entity, passive::{iron_golem::IronGolemEntity, snow_golem::SnowGolemEntity}, }, }; pub struct CarvedPumpkinBlock; impl BlockMetadata for CarvedPumpkinBlock { fn ids() -> Box<[BlockId]> { [BlockId::JACK_O_LANTERN, BlockId::CARVED_PUMPKIN].into() } } impl BlockBehaviour for CarvedPumpkinBlock { fn on_place(&self, args: OnPlaceArgs<'_>) -> BlockStateId { let mut props = WallTorchLikeProperties::default(args.block); props.facing = args .player .living_entity .entity .get_horizontal_facing() .opposite(); props.to_state_id(args.block) } fn placed(&self, args: PlacedArgs<'_>) { // Mojang uses some BlockPattern magic, way too complex tbh { let down_pos = args.position.down(); let upper = args.world.get_block(&down_pos); let lower = args.world.get_block(&down_pos.down()); if upper == &Block::SNOW_BLOCK && lower == &Block::SNOW_BLOCK { for i in 0..3 { let pos = args.position.down_height(i); args.world.set_block_state( &pos, Block::AIR.default_state.id, BlockFlags::NOTIFY_LISTENERS, ); args.world.sync_world_event( WorldEvent::ParticlesDestroyBlock, pos, Block::SNOW_BLOCK.default_state.id.as_u16().into(), ); } let entity = Entity::new( args.world.clone(), down_pos.down().to_centered_f64(), &EntityType::SNOW_GOLEM, ); let golem = SnowGolemEntity::new(entity); args.world.spawn_entity(golem); return; } if upper == &Block::IRON_BLOCK && lower == &Block::IRON_BLOCK { for dir in [BlockDirection::North, BlockDirection::West] { let opposite = dir.opposite(); let arm1 = down_pos.offset(dir.to_offset()); let arm2 = down_pos.offset(opposite.to_offset()); if args.world.get_block(&arm1) == &Block::IRON_BLOCK && args.world.get_block(&arm2) == &Block::IRON_BLOCK { let pattern = [*args.position, down_pos, down_pos.down(), arm1, arm2]; for p in pattern { args.world.set_block_state( &p, Block::AIR.default_state.id, BlockFlags::NOTIFY_LISTENERS, ); args.world.sync_world_event( WorldEvent::ParticlesDestroyBlock, p, Block::IRON_BLOCK.default_state.id.as_u16().into(), ); } let entity = Entity::new( args.world.clone(), down_pos.down().to_centered_f64(), &EntityType::IRON_GOLEM, ); let golem = IronGolemEntity::new(entity); args.world.spawn_entity(golem); return; } } } } } }