223 lines
12 KiB
Rust
223 lines
12 KiB
Rust
use std::pin::Pin;
|
|
|
|
use crate::entity::player::Player;
|
|
use crate::item::{ItemBehaviour, ItemMetadata};
|
|
use crate::server::Server;
|
|
use pumpkin_data::BlockDirection;
|
|
use pumpkin_data::block_properties::BlockProperties;
|
|
use pumpkin_data::block_properties::{OakDoorLikeProperties, PaleOakWoodLikeProperties};
|
|
use pumpkin_data::item_stack::ItemStack;
|
|
use pumpkin_data::tag::Taggable;
|
|
use pumpkin_data::{Block, tag};
|
|
use pumpkin_util::GameMode;
|
|
use pumpkin_util::math::position::BlockPos;
|
|
use pumpkin_util::math::vector3::Vector3;
|
|
use pumpkin_world::world::BlockFlags;
|
|
|
|
pub struct AxeItem;
|
|
|
|
impl ItemMetadata for AxeItem {
|
|
fn ids() -> Box<[u16]> {
|
|
tag::Item::MINECRAFT_AXES.1.to_vec().into_boxed_slice()
|
|
}
|
|
}
|
|
|
|
impl ItemBehaviour for AxeItem {
|
|
fn use_on_block<'a>(
|
|
&'a self,
|
|
item: &'a mut ItemStack,
|
|
player: &'a Player,
|
|
location: BlockPos,
|
|
_face: BlockDirection,
|
|
_cursor_pos: Vector3<f32>,
|
|
block: &'a Block,
|
|
_server: &'a Server,
|
|
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
|
|
Box::pin(async move {
|
|
// I tried to follow mojang order of doing things.
|
|
let world = player.world();
|
|
let replacement_block = try_use_axe(block);
|
|
// First we try to strip the block. by getting his equivalent and applying it the axis.
|
|
|
|
// If there is a strip equivalent.
|
|
let changed = if replacement_block != 0 {
|
|
let new_block = &Block::from_id(replacement_block);
|
|
let new_state_id = if block.has_tag(&tag::Block::MINECRAFT_LOGS) {
|
|
let log_information = world.get_block_state_id(&location);
|
|
let log_props =
|
|
PaleOakWoodLikeProperties::from_state_id(log_information, block);
|
|
// create new properties for the new log.
|
|
let mut new_log_properties = PaleOakWoodLikeProperties::default(new_block);
|
|
new_log_properties.axis = log_props.axis;
|
|
|
|
// create new properties for the new log.
|
|
|
|
// Set old axis to the new log.
|
|
new_log_properties.axis = log_props.axis;
|
|
new_log_properties.to_state_id(new_block)
|
|
}
|
|
// Let's check if It's a door
|
|
else if block.has_tag(&tag::Block::MINECRAFT_DOORS) {
|
|
// get block state of the old log.
|
|
let door_information = world.get_block_state_id(&location);
|
|
// get the log properties
|
|
let door_props = OakDoorLikeProperties::from_state_id(door_information, block);
|
|
// create new properties for the new log.
|
|
let mut new_door_properties = OakDoorLikeProperties::default(new_block);
|
|
// Set old axis to the new log.
|
|
new_door_properties.facing = door_props.facing;
|
|
new_door_properties.open = door_props.open;
|
|
new_door_properties.half = door_props.half;
|
|
new_door_properties.hinge = door_props.hinge;
|
|
new_door_properties.powered = door_props.powered;
|
|
new_door_properties.to_state_id(new_block)
|
|
} else {
|
|
new_block.default_state.id
|
|
};
|
|
// TODO Implements trapdoors when It's implemented
|
|
world
|
|
.set_block_state(&location, new_state_id, BlockFlags::NOTIFY_ALL)
|
|
.await;
|
|
true
|
|
} else {
|
|
false
|
|
};
|
|
|
|
if changed && player.gamemode.load() != GameMode::Creative {
|
|
// TODO: Handle DamageResult::Broken to broadcast item break and update player slot.
|
|
let _ = item.damage_item(1);
|
|
}
|
|
})
|
|
}
|
|
|
|
fn as_any(&self) -> &dyn std::any::Any {
|
|
self
|
|
}
|
|
}
|
|
fn try_use_axe(block: &Block) -> u16 {
|
|
// Trying to get the strip equivalent
|
|
let block_id = get_stripped_equivalent(block);
|
|
if block_id != 0 {
|
|
return block_id;
|
|
}
|
|
// Else decrease the level of oxidation
|
|
let block_id = get_deoxidized_equivalent(block);
|
|
if block_id != 0 {
|
|
return block_id;
|
|
}
|
|
// Else unwax the block
|
|
get_unwaxed_equivalent(block)
|
|
}
|
|
|
|
fn get_stripped_equivalent(block: &Block) -> u16 {
|
|
match block.id {
|
|
id if id == Block::OAK_LOG.id => Block::STRIPPED_OAK_LOG.id,
|
|
id if id == Block::SPRUCE_LOG.id => Block::STRIPPED_SPRUCE_LOG.id,
|
|
id if id == Block::BIRCH_LOG.id => Block::STRIPPED_BIRCH_LOG.id,
|
|
id if id == Block::JUNGLE_LOG.id => Block::STRIPPED_JUNGLE_LOG.id,
|
|
id if id == Block::ACACIA_LOG.id => Block::STRIPPED_ACACIA_LOG.id,
|
|
id if id == Block::DARK_OAK_LOG.id => Block::STRIPPED_DARK_OAK_LOG.id,
|
|
id if id == Block::MANGROVE_LOG.id => Block::STRIPPED_MANGROVE_LOG.id,
|
|
id if id == Block::CHERRY_LOG.id => Block::STRIPPED_CHERRY_LOG.id,
|
|
id if id == Block::PALE_OAK_LOG.id => Block::STRIPPED_PALE_OAK_LOG.id,
|
|
|
|
id if id == Block::OAK_WOOD.id => Block::STRIPPED_OAK_WOOD.id,
|
|
id if id == Block::SPRUCE_WOOD.id => Block::STRIPPED_SPRUCE_WOOD.id,
|
|
id if id == Block::BIRCH_WOOD.id => Block::STRIPPED_BIRCH_WOOD.id,
|
|
id if id == Block::JUNGLE_WOOD.id => Block::STRIPPED_JUNGLE_WOOD.id,
|
|
id if id == Block::ACACIA_WOOD.id => Block::STRIPPED_ACACIA_WOOD.id,
|
|
id if id == Block::DARK_OAK_WOOD.id => Block::STRIPPED_DARK_OAK_WOOD.id,
|
|
id if id == Block::MANGROVE_WOOD.id => Block::STRIPPED_MANGROVE_WOOD.id,
|
|
id if id == Block::CHERRY_WOOD.id => Block::STRIPPED_CHERRY_WOOD.id,
|
|
id if id == Block::PALE_OAK_WOOD.id => Block::STRIPPED_PALE_OAK_WOOD.id,
|
|
_ => 0,
|
|
}
|
|
}
|
|
|
|
fn get_deoxidized_equivalent(block: &Block) -> u16 {
|
|
match block.id {
|
|
id if id == Block::OXIDIZED_COPPER.id => Block::WEATHERED_COPPER.id,
|
|
id if id == Block::WEATHERED_COPPER.id => Block::EXPOSED_COPPER.id,
|
|
id if id == Block::EXPOSED_COPPER.id => Block::COPPER_BLOCK.id,
|
|
id if id == Block::OXIDIZED_CHISELED_COPPER.id => Block::WEATHERED_CHISELED_COPPER.id,
|
|
id if id == Block::WEATHERED_CHISELED_COPPER.id => Block::EXPOSED_CHISELED_COPPER.id,
|
|
id if id == Block::EXPOSED_CHISELED_COPPER.id => Block::CHISELED_COPPER.id,
|
|
id if id == Block::OXIDIZED_COPPER_GRATE.id => Block::WEATHERED_COPPER_GRATE.id,
|
|
id if id == Block::WEATHERED_COPPER_GRATE.id => Block::EXPOSED_COPPER_GRATE.id,
|
|
id if id == Block::EXPOSED_COPPER_GRATE.id => Block::COPPER_GRATE.id,
|
|
id if id == Block::OXIDIZED_CUT_COPPER.id => Block::WEATHERED_CUT_COPPER.id,
|
|
id if id == Block::WEATHERED_CUT_COPPER.id => Block::EXPOSED_CUT_COPPER.id,
|
|
id if id == Block::EXPOSED_CUT_COPPER.id => Block::CUT_COPPER.id,
|
|
id if id == Block::OXIDIZED_CUT_COPPER_STAIRS.id => Block::WEATHERED_CUT_COPPER_STAIRS.id,
|
|
id if id == Block::WEATHERED_CUT_COPPER_STAIRS.id => Block::EXPOSED_CUT_COPPER_STAIRS.id,
|
|
id if id == Block::EXPOSED_CUT_COPPER_STAIRS.id => Block::CUT_COPPER_STAIRS.id,
|
|
id if id == Block::OXIDIZED_CUT_COPPER_SLAB.id => Block::WEATHERED_CUT_COPPER_SLAB.id,
|
|
id if id == Block::WEATHERED_CUT_COPPER_SLAB.id => Block::EXPOSED_CUT_COPPER_SLAB.id,
|
|
id if id == Block::EXPOSED_CUT_COPPER_SLAB.id => Block::CUT_COPPER_SLAB.id,
|
|
id if id == Block::OXIDIZED_COPPER_BULB.id => Block::WEATHERED_COPPER_BULB.id,
|
|
id if id == Block::WEATHERED_COPPER_BULB.id => Block::EXPOSED_COPPER_BULB.id,
|
|
id if id == Block::EXPOSED_COPPER_BULB.id => Block::COPPER_BULB.id,
|
|
id if id == Block::OXIDIZED_COPPER_DOOR.id => Block::WEATHERED_COPPER_DOOR.id,
|
|
id if id == Block::WEATHERED_COPPER_DOOR.id => Block::EXPOSED_COPPER_DOOR.id,
|
|
id if id == Block::EXPOSED_COPPER_DOOR.id => Block::COPPER_DOOR.id,
|
|
id if id == Block::OXIDIZED_COPPER_TRAPDOOR.id => Block::WEATHERED_COPPER_TRAPDOOR.id,
|
|
id if id == Block::WEATHERED_COPPER_TRAPDOOR.id => Block::EXPOSED_COPPER_TRAPDOOR.id,
|
|
id if id == Block::EXPOSED_COPPER_TRAPDOOR.id => Block::COPPER_TRAPDOOR.id,
|
|
_ => 0,
|
|
}
|
|
}
|
|
|
|
fn get_unwaxed_equivalent(block: &Block) -> u16 {
|
|
match &block.id {
|
|
id if id == &Block::WAXED_OXIDIZED_COPPER.id => Block::OXIDIZED_COPPER.id,
|
|
id if id == &Block::WAXED_WEATHERED_COPPER.id => Block::WEATHERED_COPPER.id,
|
|
id if id == &Block::WAXED_EXPOSED_COPPER.id => Block::EXPOSED_COPPER.id,
|
|
id if id == &Block::WAXED_COPPER_BLOCK.id => Block::COPPER_BLOCK.id,
|
|
id if id == &Block::WAXED_OXIDIZED_CHISELED_COPPER.id => Block::OXIDIZED_CHISELED_COPPER.id,
|
|
id if id == &Block::WAXED_WEATHERED_CHISELED_COPPER.id => {
|
|
Block::WEATHERED_CHISELED_COPPER.id
|
|
}
|
|
id if id == &Block::WAXED_EXPOSED_CHISELED_COPPER.id => Block::EXPOSED_CHISELED_COPPER.id,
|
|
id if id == &Block::WAXED_CHISELED_COPPER.id => Block::CHISELED_COPPER.id,
|
|
id if id == &Block::WAXED_COPPER_GRATE.id => Block::COPPER_GRATE.id,
|
|
id if id == &Block::WAXED_OXIDIZED_COPPER_GRATE.id => Block::OXIDIZED_COPPER_GRATE.id,
|
|
id if id == &Block::WAXED_WEATHERED_COPPER_GRATE.id => Block::WEATHERED_COPPER_GRATE.id,
|
|
id if id == &Block::WAXED_EXPOSED_COPPER_GRATE.id => Block::EXPOSED_COPPER_GRATE.id,
|
|
id if id == &Block::WAXED_OXIDIZED_CUT_COPPER.id => Block::OXIDIZED_CUT_COPPER.id,
|
|
id if id == &Block::WAXED_WEATHERED_CUT_COPPER.id => Block::WEATHERED_CUT_COPPER.id,
|
|
id if id == &Block::WAXED_EXPOSED_CUT_COPPER.id => Block::EXPOSED_CUT_COPPER.id,
|
|
id if id == &Block::WAXED_CUT_COPPER.id => Block::CUT_COPPER.id,
|
|
id if id == &Block::WAXED_OXIDIZED_CUT_COPPER_STAIRS.id => {
|
|
Block::OXIDIZED_CUT_COPPER_STAIRS.id
|
|
}
|
|
id if id == &Block::WAXED_WEATHERED_CUT_COPPER_STAIRS.id => {
|
|
Block::WEATHERED_CUT_COPPER_STAIRS.id
|
|
}
|
|
id if id == &Block::WAXED_EXPOSED_CUT_COPPER_STAIRS.id => {
|
|
Block::EXPOSED_CUT_COPPER_STAIRS.id
|
|
}
|
|
id if id == &Block::WAXED_CUT_COPPER_STAIRS.id => Block::CUT_COPPER_STAIRS.id,
|
|
id if id == &Block::WAXED_OXIDIZED_CUT_COPPER_SLAB.id => Block::OXIDIZED_CUT_COPPER_SLAB.id,
|
|
id if id == &Block::WAXED_WEATHERED_CUT_COPPER_SLAB.id => {
|
|
Block::WEATHERED_CUT_COPPER_SLAB.id
|
|
}
|
|
id if id == &Block::WAXED_EXPOSED_CUT_COPPER_SLAB.id => Block::EXPOSED_CUT_COPPER_SLAB.id,
|
|
id if id == &Block::WAXED_CUT_COPPER_SLAB.id => Block::CUT_COPPER_SLAB.id,
|
|
id if id == &Block::WAXED_OXIDIZED_COPPER_BULB.id => Block::OXIDIZED_COPPER_BULB.id,
|
|
id if id == &Block::WAXED_WEATHERED_COPPER_BULB.id => Block::WEATHERED_COPPER_BULB.id,
|
|
id if id == &Block::WAXED_EXPOSED_COPPER_BULB.id => Block::EXPOSED_COPPER_BULB.id,
|
|
id if id == &Block::WAXED_COPPER_BULB.id => Block::COPPER_BULB.id,
|
|
id if id == &Block::WAXED_OXIDIZED_COPPER_DOOR.id => Block::OXIDIZED_COPPER_DOOR.id,
|
|
id if id == &Block::WAXED_WEATHERED_COPPER_DOOR.id => Block::WEATHERED_COPPER_DOOR.id,
|
|
id if id == &Block::WAXED_EXPOSED_COPPER_DOOR.id => Block::EXPOSED_COPPER_DOOR.id,
|
|
id if id == &Block::WAXED_COPPER_DOOR.id => Block::COPPER_DOOR.id,
|
|
id if id == &Block::WAXED_OXIDIZED_COPPER_TRAPDOOR.id => Block::OXIDIZED_COPPER_TRAPDOOR.id,
|
|
id if id == &Block::WAXED_WEATHERED_COPPER_TRAPDOOR.id => {
|
|
Block::WEATHERED_COPPER_TRAPDOOR.id
|
|
}
|
|
id if id == &Block::WAXED_EXPOSED_COPPER_TRAPDOOR.id => Block::EXPOSED_COPPER_TRAPDOOR.id,
|
|
id if id == &Block::WAXED_COPPER_TRAPDOOR.id => Block::COPPER_TRAPDOOR.id,
|
|
_ => 0,
|
|
}
|
|
}
|