Search in sources :

Example 1 with BlockDamageEvent

use of org.bukkit.event.block.BlockDamageEvent in project Glowstone by GlowstoneMC.

the class DiggingHandler method handle.

@Override
public void handle(GlowSession session, DiggingMessage message) {
    GlowPlayer player = session.getPlayer();
    GlowWorld world = player.getWorld();
    EventFactory eventFactory = EventFactory.getInstance();
    GlowBlock block = world.getBlockAt(message.getX(), message.getY(), message.getZ());
    BlockFace face = BlockPlacementHandler.convertFace(message.getFace());
    ItemStack holding = player.getItemInHand();
    if (block.getRelative(face).getType() == Material.FIRE) {
        block.getRelative(face).breakNaturally();
        // returns to avoid breaking block in creative
        return;
    }
    boolean blockBroken = false;
    boolean revert = false;
    Material material = block.getType();
    switch(message.getState()) {
        case START_DIGGING:
            if (block.equals(player.getDigging()) || block.isLiquid()) {
                return;
            }
            // call interact event
            Action action = Action.LEFT_CLICK_BLOCK;
            Block eventBlock = block;
            if (player.getLocation().distanceSquared(block.getLocation()) > 36 || ExtraMaterialTags.AIR_VARIANTS.isTagged(material)) {
                action = Action.LEFT_CLICK_AIR;
                eventBlock = null;
            }
            PlayerInteractEvent interactEvent = eventFactory.onPlayerInteract(player, action, EquipmentSlot.HAND, eventBlock, face);
            // attempt to use item in hand, that is, dig up the block
            if (!BlockPlacementHandler.selectResult(interactEvent.useItemInHand(), true)) {
                // the event was cancelled, get out of here
                revert = true;
            } else if (player.getGameMode() != GameMode.SPECTATOR) {
                player.setDigging(null);
                // emit damage event - cancel by default if holding a sword
                boolean instaBreak = player.getGameMode() == GameMode.CREATIVE || block.getMaterialValues().getHardness() == 0;
                BlockDamageEvent damageEvent = new BlockDamageEvent(player, block, player.getItemInHand(), instaBreak);
                if (player.getGameMode() == GameMode.CREATIVE && holding != null && EnchantmentTarget.WEAPON.includes(holding.getType())) {
                    damageEvent.setCancelled(true);
                }
                eventFactory.callEvent(damageEvent);
                // follow orders
                if (damageEvent.isCancelled()) {
                    revert = true;
                } else {
                    // in creative, break even if denied in the event, or the block
                    // can never be broken (client does not send DONE_DIGGING).
                    blockBroken = damageEvent.getInstaBreak();
                    if (!blockBroken) {
                        // TODO: add a delay here based on hardness
                        player.setDigging(block);
                    }
                }
            }
            break;
        case DiggingMessage.CANCEL_DIGGING:
            player.setDigging(null);
            break;
        case DiggingMessage.FINISH_DIGGING:
            // untrusted)
            break;
        case DiggingMessage.STATE_DROP_ITEM:
            player.dropItemInHand(false);
            return;
        case DiggingMessage.STATE_DROP_ITEMSTACK:
            player.dropItemInHand(true);
            return;
        case DiggingMessage.STATE_SHOT_ARROW_FINISH_EATING:
            final ItemStack usageItem = player.getUsageItem();
            if (usageItem != null) {
                if (Objects.equals(usageItem, holding)) {
                    ItemType type = ItemTable.instance().getItem(usageItem.getType());
                    if (type != null && type instanceof ItemTimedUsage) {
                        ((ItemTimedUsage) type).endUse(player, usageItem);
                    } else {
                    // todo: inform the player that this item cannot be consumed/used
                    }
                } else {
                // todo: verification against malicious clients
                // todo: inform player their item is wrong
                }
            }
            return;
        case DiggingMessage.SWAP_ITEM_IN_HAND:
            ItemStack main = player.getInventory().getItemInMainHand();
            ItemStack off = player.getInventory().getItemInOffHand();
            PlayerSwapHandItemsEvent event = EventFactory.getInstance().callEvent(new PlayerSwapHandItemsEvent(player, off, main));
            if (!event.isCancelled()) {
                player.getInventory().setItemInOffHand(main);
                player.getInventory().setItemInMainHand(off);
                player.updateInventory();
            }
            return;
        default:
            return;
    }
    if (blockBroken && !revert) {
        // fire the block break event
        BlockBreakEvent breakEvent = eventFactory.callEvent(new BlockBreakEvent(block, player));
        if (breakEvent.isCancelled()) {
            BlockPlacementHandler.revert(player, block);
            return;
        }
        MaterialData data = block.getState().getData();
        if (ExtraMaterialTags.BISECTED_BLOCKS.isTagged(material)) {
            if (block.getRelative(BlockFace.DOWN).getType() == material) {
                block = block.getRelative(BlockFace.DOWN);
            }
        }
        BlockType blockType = ItemTable.instance().getBlock(material);
        if (blockType != null) {
            blockType.blockDestroy(player, block, face);
        }
        // destroy the block
        if (!block.isEmpty() && !block.isLiquid() && (player.getGameMode() != GameMode.CREATIVE || blockType instanceof BlockContainer) && world.getGameRuleMap().getBoolean(GameRules.DO_TILE_DROPS)) {
            Collection<ItemStack> drops = blockType.getDrops(block, holding);
            if (blockType instanceof BlockContainer && player.getGameMode() == GameMode.CREATIVE) {
                drops = ((BlockContainer) blockType).getContentDrops(block);
            }
            for (ItemStack drop : drops) {
                GlowItem item = world.dropItemNaturally(block.getLocation(), drop);
                item.setPickupDelay(30);
                item.setBias(player);
            }
        }
        player.addExhaustion(0.005f);
        // STEP_SOUND actually is the block break particles
        world.playEffectExceptTo(block.getLocation(), Effect.STEP_SOUND, block.getType().getId(), 64, player);
        GlowBlockState state = block.getState();
        block.setType(Material.AIR);
        if (blockType != null) {
            blockType.afterDestroy(player, block, face, state);
        }
    } else if (revert) {
        // replace the block that wasn't really dug
        BlockPlacementHandler.revert(player, block);
    } else if (!ExtraMaterialTags.AIR_VARIANTS.isTagged(material)) {
        BlockType blockType = ItemTable.instance().getBlock(material);
        blockType.leftClickBlock(player, block, holding);
    }
}
Also used : ItemTimedUsage(net.glowstone.block.itemtype.ItemTimedUsage) Action(org.bukkit.event.block.Action) GlowPlayer(net.glowstone.entity.GlowPlayer) BlockFace(org.bukkit.block.BlockFace) BlockContainer(net.glowstone.block.blocktype.BlockContainer) GlowBlockState(net.glowstone.block.GlowBlockState) PlayerInteractEvent(org.bukkit.event.player.PlayerInteractEvent) ItemType(net.glowstone.block.itemtype.ItemType) EventFactory(net.glowstone.EventFactory) Material(org.bukkit.Material) GlowItem(net.glowstone.entity.objects.GlowItem) GlowBlock(net.glowstone.block.GlowBlock) BlockType(net.glowstone.block.blocktype.BlockType) BlockDamageEvent(org.bukkit.event.block.BlockDamageEvent) GlowWorld(net.glowstone.GlowWorld) GlowBlock(net.glowstone.block.GlowBlock) Block(org.bukkit.block.Block) BlockBreakEvent(org.bukkit.event.block.BlockBreakEvent) MaterialData(org.bukkit.material.MaterialData) ItemStack(org.bukkit.inventory.ItemStack) PlayerSwapHandItemsEvent(org.bukkit.event.player.PlayerSwapHandItemsEvent)

Aggregations

EventFactory (net.glowstone.EventFactory)1 GlowWorld (net.glowstone.GlowWorld)1 GlowBlock (net.glowstone.block.GlowBlock)1 GlowBlockState (net.glowstone.block.GlowBlockState)1 BlockContainer (net.glowstone.block.blocktype.BlockContainer)1 BlockType (net.glowstone.block.blocktype.BlockType)1 ItemTimedUsage (net.glowstone.block.itemtype.ItemTimedUsage)1 ItemType (net.glowstone.block.itemtype.ItemType)1 GlowPlayer (net.glowstone.entity.GlowPlayer)1 GlowItem (net.glowstone.entity.objects.GlowItem)1 Material (org.bukkit.Material)1 Block (org.bukkit.block.Block)1 BlockFace (org.bukkit.block.BlockFace)1 Action (org.bukkit.event.block.Action)1 BlockBreakEvent (org.bukkit.event.block.BlockBreakEvent)1 BlockDamageEvent (org.bukkit.event.block.BlockDamageEvent)1 PlayerInteractEvent (org.bukkit.event.player.PlayerInteractEvent)1 PlayerSwapHandItemsEvent (org.bukkit.event.player.PlayerSwapHandItemsEvent)1 ItemStack (org.bukkit.inventory.ItemStack)1 MaterialData (org.bukkit.material.MaterialData)1