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);
}
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);
}
}
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);
}
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;
}
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));
}
Aggregations