use std::sync::Arc; use pumpkin_data::block_properties::{BlockProperties, RespawnAnchorLikeProperties}; use pumpkin_data::dimension::Dimension; use pumpkin_data::item::Item; use pumpkin_data::sound::{Sound, SoundCategory}; use pumpkin_data::translation; use pumpkin_macros::pumpkin_block; use pumpkin_world::world::BlockFlags; use crate::block::registry::BlockActionResult; use crate::block::{BlockBehaviour, NormalUseArgs, UseWithItemArgs}; use crate::entity::EntityBase; #[pumpkin_block("minecraft:respawn_anchor")] pub struct RespawnAnchorBlock; impl BlockBehaviour for RespawnAnchorBlock { fn use_with_item(&self, args: UseWithItemArgs<'_>) -> BlockActionResult { if args.item_stack.item.id != Item::GLOWSTONE.id { return BlockActionResult::Pass; } let state_id = args.world.get_block_state_id(args.position); let mut props = RespawnAnchorLikeProperties::from_state_id(state_id, args.block); if props.charges >= 4 { return BlockActionResult::Pass; } props.charges += 1; args.world.set_block_state( args.position, props.to_state_id(args.block), BlockFlags::NOTIFY_ALL, ); args.item_stack .decrement_unless_creative(args.player.gamemode.load(), 1); args.world.play_sound( Sound::BlockRespawnAnchorCharge, SoundCategory::Blocks, &args.position.to_f64(), ); BlockActionResult::Success } fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult { let state_id = args.world.get_block_state_id(args.position); let props = RespawnAnchorLikeProperties::from_state_id(state_id, args.block); if args.world.dimension != Dimension::THE_NETHER { args.world .break_block(args.position, None, BlockFlags::SKIP_DROPS); let center_pos = args.position.to_centered_f64(); args.world .explode(center_pos, 5.0, crate::world::ExplosionInteraction::Block); return BlockActionResult::SuccessServer; } if props.charges == 0 { let player = Arc::clone(args.player); tokio::spawn(async move { player .send_system_message(&pumpkin_macros::translate_cross!( translation::java::BLOCK_MINECRAFT_BED_NO_SLEEP, translation::bedrock::TILE_BED_NOSLEEP )) .await; }); return BlockActionResult::SuccessServer; } let player = Arc::clone(args.player); let world = Arc::clone(args.world); let pos = *args.position; tokio::spawn(async move { if player .set_respawn_point( world.dimension.clone(), pos, player.get_entity().yaw.load(), player.get_entity().pitch.load(), false, ) .await { world.play_sound( Sound::BlockRespawnAnchorSetSpawn, SoundCategory::Blocks, &pos.to_f64(), ); player .send_system_message(&pumpkin_macros::translate_cross!( translation::java::BLOCK_MINECRAFT_SET_SPAWN, translation::bedrock::TILE_BED_RESPAWNSET )) .await; } }); BlockActionResult::SuccessServer } }