Search in sources :

Example 1 with BlockStateChangeImpl

use of me.botsko.prism.events.BlockStateChangeImpl in project Prism-Bukkit by prism.

the class BlockAction method handleBanners.

private ChangeResultImpl handleBanners(Block block, BlockActionData blockActionData, BlockState originalBlock) {
    block.setType(getMaterial());
    BlockState state = block.getState();
    final BannerActionData actionData = (BannerActionData) blockActionData;
    setBlockRotatable(state, actionData);
    state = block.getState();
    if (!actionData.patterns.isEmpty()) {
        final Banner banner = (Banner) state;
        List<Pattern> patternsList = new ArrayList<>();
        actionData.patterns.forEach((s, s2) -> {
            PatternType type = PatternType.valueOf(s);
            DyeColor color = DyeColor.valueOf(s2.toUpperCase());
            Pattern p = new Pattern(color, type);
            patternsList.add(p);
        });
        banner.setPatterns(patternsList);
        banner.update();
    }
    BlockStateChangeImpl stateChange = new BlockStateChangeImpl(originalBlock, state);
    return new ChangeResultImpl(ChangeResultType.APPLIED, stateChange);
}
Also used : PatternType(org.bukkit.block.banner.PatternType) Pattern(org.bukkit.block.banner.Pattern) BlockState(org.bukkit.block.BlockState) BlockStateChangeImpl(me.botsko.prism.events.BlockStateChangeImpl) Banner(org.bukkit.block.Banner) ArrayList(java.util.ArrayList) DyeColor(org.bukkit.DyeColor) ChangeResultImpl(me.botsko.prism.appliers.ChangeResultImpl)

Example 2 with BlockStateChangeImpl

use of me.botsko.prism.events.BlockStateChangeImpl in project Prism-Bukkit by prism.

the class BlockAction method placeBlock.

ChangeResult placeBlock(Player player, PrismParameters parameters, boolean isPreview, Block block, boolean isDeferred) {
    BlockStateChangeImpl stateChange;
    // Ensure block action is allowed to place a block here.
    // (essentially liquid/air).
    final boolean cancelIfBadPlace = !getActionType().requiresHandler(BlockChangeAction.class) && !getActionType().requiresHandler(PrismRollbackAction.class) && !parameters.hasFlag(Flag.OVERWRITE);
    if (cancelIfBadPlace && !Utilities.isAcceptableForBlockPlace(block.getType())) {
        Prism.debug("Block skipped due to being unacceptable for block place: " + block.getType().name());
        return new ChangeResultImpl(ChangeResultType.SKIPPED, null);
    }
    // On the blacklist (except an undo)
    if ((Prism.getIllegalBlocks().contains(getMaterial()) && !parameters.getProcessType().equals(PrismProcessType.UNDO)) && !parameters.hasFlag(Flag.OVERWRITE)) {
        Prism.debug("Block skipped because it's not allowed to be placed unless its an UNDO: " + getMaterial().toString());
        return new ChangeResultImpl(ChangeResultType.SKIPPED, null);
    }
    // If we're not in a preview, actually apply this block
    // Capture the block before we change it
    final BlockState originalBlock = block.getState();
    if (!isPreview) {
        return handleApply(block, originalBlock, parameters, cancelIfBadPlace);
    } else {
        // Otherwise, save the state so we can cancel if needed
        // Note: we save the original state as both old/new so we can re-use
        // blockStateChanges
        stateChange = new BlockStateChangeImpl(originalBlock, originalBlock);
        // Preview it
        EntityUtils.sendBlockChange(player, block.getLocation(), getBlockData());
        // Send preview to shared players
        for (final CommandSender sharedPlayer : parameters.getSharedPlayers()) {
            if (sharedPlayer instanceof Player) {
                EntityUtils.sendBlockChange((Player) sharedPlayer, block.getLocation(), getBlockData());
            }
        }
        return new ChangeResultImpl(ChangeResultType.APPLIED, stateChange);
    }
}
Also used : Player(org.bukkit.entity.Player) BlockState(org.bukkit.block.BlockState) BlockStateChangeImpl(me.botsko.prism.events.BlockStateChangeImpl) CommandSender(org.bukkit.command.CommandSender) ChangeResultImpl(me.botsko.prism.appliers.ChangeResultImpl)

Example 3 with BlockStateChangeImpl

use of me.botsko.prism.events.BlockStateChangeImpl in project Prism-Bukkit by prism.

the class BlockAction method handleSkulls.

@NotNull
private ChangeResultImpl handleSkulls(final Block block, BlockActionData blockActionData, final BlockState originalBlock) {
    block.setType(getMaterial());
    BlockState state = block.getState();
    final SkullActionData s = (SkullActionData) blockActionData;
    setBlockRotatable(state, s);
    state = block.getState();
    if (!s.owner.isEmpty()) {
        final Skull skull = (Skull) state;
        skull.setOwningPlayer(Bukkit.getOfflinePlayer(EntityUtils.uuidOf((s.owner))));
    }
    BlockStateChangeImpl stateChange = new BlockStateChangeImpl(originalBlock, state);
    return new ChangeResultImpl(ChangeResultType.APPLIED, stateChange);
}
Also used : BlockState(org.bukkit.block.BlockState) BlockStateChangeImpl(me.botsko.prism.events.BlockStateChangeImpl) Skull(org.bukkit.block.Skull) ChangeResultImpl(me.botsko.prism.appliers.ChangeResultImpl) NotNull(org.jetbrains.annotations.NotNull)

Example 4 with BlockStateChangeImpl

use of me.botsko.prism.events.BlockStateChangeImpl in project Prism-Bukkit by prism.

the class Utilities method checkForWaterlogged.

private static ArrayList<BlockStateChangeImpl> checkForWaterlogged(final Location loc, int radius) {
    final ArrayList<BlockStateChangeImpl> blockStateChanges = new ArrayList<>();
    if (loc != null && radius > 0) {
        final int x1 = loc.getBlockX();
        final int y1 = loc.getBlockY();
        final int z1 = loc.getBlockZ();
        final World world = loc.getWorld();
        for (int x = x1 - radius; x <= x1 + radius; x++) {
            for (int y = y1 - radius; y <= y1 + radius; y++) {
                for (int z = z1 - radius; z <= z1 + radius; z++) {
                    Location testLocation = new Location(world, x, y, z);
                    final Block b = testLocation.getBlock();
                    if (b.getType().equals(Material.AIR)) {
                        continue;
                    }
                    BlockData data = testLocation.getBlock().getBlockData();
                    if (data instanceof Waterlogged) {
                        final BlockState originalBlock = testLocation.getBlock().getState();
                        BlockData modified = testLocation.getBlock().getBlockData();
                        ((Waterlogged) modified).setWaterlogged(false);
                        testLocation.getBlock().setBlockData(modified);
                        final BlockState newBlock = testLocation.getBlock().getState();
                        blockStateChanges.add(new BlockStateChangeImpl(originalBlock, newBlock));
                    }
                }
            }
        }
    }
    return blockStateChanges;
}
Also used : BlockState(org.bukkit.block.BlockState) BlockStateChangeImpl(me.botsko.prism.events.BlockStateChangeImpl) ArrayList(java.util.ArrayList) Block(org.bukkit.block.Block) Waterlogged(org.bukkit.block.data.Waterlogged) World(org.bukkit.World) BlockData(org.bukkit.block.data.BlockData) Location(org.bukkit.Location)

Example 5 with BlockStateChangeImpl

use of me.botsko.prism.events.BlockStateChangeImpl in project Prism-Bukkit by prism.

the class BlockAction method handleApply.

/**
 * The BlockState object is modified by this method.
 *
 * @param block            Block
 * @param originalBlock    BlockState
 * @param parameters       QueryParameters
 * @param cancelIfBadPlace cancelIfBadPlace
 * @return ChangeResult.
 */
@NotNull
private ChangeResult handleApply(final Block block, final BlockState originalBlock, final PrismParameters parameters, final boolean cancelIfBadPlace) {
    BlockState state = block.getState();
    // So this will ensure the head of the bed is broken when removing the bed during rollback.
    if (MaterialTag.BEDS.isTagged(state.getType())) {
        state = Utilities.getSiblingForDoubleLengthBlock(state).getState();
    }
    switch(getMaterial()) {
        case LILY_PAD:
            // If restoring a lily pad, check that block below is water.
            // Be sure it's set to stationary water so the lily pad will stay
            final Block below = block.getRelative(BlockFace.DOWN);
            if (below.getType().equals(WATER) || below.getType().equals(AIR)) {
                below.setType(WATER);
            } else {
                // Prism.debug("Lilypad skipped because no water exists below.");
                return new ChangeResultImpl(ChangeResultType.SKIPPED, null);
            }
            break;
        case NETHER_PORTAL:
            // Only way to restore a nether portal is to set it on fire.
            final Block obsidian = Utilities.getFirstBlockOfMaterialBelow(OBSIDIAN, block.getLocation());
            if (obsidian != null) {
                final Block above = obsidian.getRelative(BlockFace.UP);
                if (!(above.getType() == NETHER_PORTAL)) {
                    above.setType(FIRE);
                    return new ChangeResultImpl(ChangeResultType.APPLIED, null);
                }
            }
            break;
        case JUKEBOX:
            setBlockData(Bukkit.createBlockData(JUKEBOX));
            break;
        default:
            break;
    }
    state.setType(getMaterial());
    state.setBlockData(getBlockData());
    state.update(true);
    BlockState newState = block.getState();
    BlockActionData blockActionData = getActionData();
    if (blockActionData != null) {
        if ((getMaterial() == PLAYER_HEAD || getMaterial() == PLAYER_WALL_HEAD) && blockActionData instanceof SkullActionData) {
            return handleSkulls(block, blockActionData, originalBlock);
        }
        if (Tag.BANNERS.isTagged(getMaterial()) && blockActionData instanceof BannerActionData) {
            return handleBanners(block, blockActionData, originalBlock);
        }
        if (getMaterial() == SPAWNER && blockActionData instanceof SpawnerActionData) {
            final SpawnerActionData s = (SpawnerActionData) blockActionData;
            // Set spawner data
            ((CreatureSpawner) newState).setDelay(s.getDelay());
            ((CreatureSpawner) newState).setSpawnedType(s.getEntityType());
        }
        if (getMaterial() == COMMAND_BLOCK && blockActionData instanceof CommandActionData) {
            final CommandActionData c = (CommandActionData) blockActionData;
            ((CommandBlock) newState).setCommand(c.command);
        }
        if (newState instanceof Nameable && blockActionData.customName != null && !blockActionData.customName.equals("")) {
            ((Nameable) newState).setCustomName(blockActionData.customName);
        }
        if (parameters.getProcessType() == PrismProcessType.ROLLBACK && Tag.SIGNS.isTagged(getMaterial()) && blockActionData instanceof SignActionData) {
            final SignActionData s = (SignActionData) blockActionData;
            // https://snowy-evening.com/botsko/prism/455/
            if (newState instanceof Sign) {
                if (s.lines != null) {
                    for (int i = 0; i < s.lines.length; ++i) {
                        ((Sign) newState).setLine(i, s.lines[i]);
                    }
                }
            }
        }
    } else {
        Prism.debug("BlockAction Data was null with " + parameters.toString());
    }
    // -----------------------------
    // Sibling logic marker
    // If the material is a crop that needs soil, we must restore the soil
    // This may need to go before setting the block, but I prefer the BlockUtil logic to use materials.
    BlockState sibling = null;
    if (Utilities.materialRequiresSoil(getMaterial())) {
        sibling = block.getRelative(BlockFace.DOWN).getState();
        if (cancelIfBadPlace && !MaterialTag.SOIL_CANDIDATES.isTagged(sibling.getType())) {
            Prism.debug(parameters.getProcessType().name() + " skipped due to lack of soil for " + getMaterial().name());
            return new ChangeResultImpl(ChangeResultType.SKIPPED, null);
        }
        sibling.setType(FARMLAND);
    }
    // Chest sides can be broken independently, ignore them
    if (newState.getType() != CHEST && newState.getType() != TRAPPED_CHEST) {
        final Block s = Utilities.getSiblingForDoubleLengthBlock(state);
        if (s != null) {
            sibling = s.getState();
            if (cancelIfBadPlace && !Utilities.isAcceptableForBlockPlace(sibling.getType())) {
                Prism.debug(parameters.getProcessType().name() + " skipped due to lack of wrong sibling type for " + getMaterial().name());
                return new ChangeResultImpl(ChangeResultType.SKIPPED, null);
            }
            sibling.setType(block.getType());
            BlockData siblingData = getBlockData().clone();
            if (siblingData instanceof Bed) {
                // We always log the foot
                ((Bed) siblingData).setPart(Part.HEAD);
            } else if (siblingData instanceof Bisected) {
                // We always log the bottom
                ((Bisected) siblingData).setHalf(Half.TOP);
            }
            sibling.setBlockData(siblingData);
        }
    }
    boolean physics = !parameters.hasFlag(Flag.NO_PHYS);
    newState.update(true, physics);
    if (sibling != null) {
        sibling.update(true, physics);
    }
    return new ChangeResultImpl(ChangeResultType.APPLIED, new BlockStateChangeImpl(originalBlock, state));
}
Also used : Bed(org.bukkit.block.data.type.Bed) CommandBlock(org.bukkit.block.CommandBlock) CreatureSpawner(org.bukkit.block.CreatureSpawner) Nameable(org.bukkit.Nameable) BlockState(org.bukkit.block.BlockState) BlockStateChangeImpl(me.botsko.prism.events.BlockStateChangeImpl) Block(org.bukkit.block.Block) CommandBlock(org.bukkit.block.CommandBlock) Sign(org.bukkit.block.Sign) ChangeResultImpl(me.botsko.prism.appliers.ChangeResultImpl) BlockData(org.bukkit.block.data.BlockData) Bisected(org.bukkit.block.data.Bisected) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

BlockStateChangeImpl (me.botsko.prism.events.BlockStateChangeImpl)7 BlockState (org.bukkit.block.BlockState)7 ChangeResultImpl (me.botsko.prism.appliers.ChangeResultImpl)5 ArrayList (java.util.ArrayList)3 Block (org.bukkit.block.Block)3 Location (org.bukkit.Location)2 World (org.bukkit.World)2 BlockData (org.bukkit.block.data.BlockData)2 CommandSender (org.bukkit.command.CommandSender)2 Player (org.bukkit.entity.Player)2 NotNull (org.jetbrains.annotations.NotNull)2 BlockStateChange (me.botsko.prism.api.BlockStateChange)1 DyeColor (org.bukkit.DyeColor)1 Nameable (org.bukkit.Nameable)1 Banner (org.bukkit.block.Banner)1 CommandBlock (org.bukkit.block.CommandBlock)1 CreatureSpawner (org.bukkit.block.CreatureSpawner)1 Sign (org.bukkit.block.Sign)1 Skull (org.bukkit.block.Skull)1 Pattern (org.bukkit.block.banner.Pattern)1