cn.nukkit.block.BlockPressurePlateBase Maven / Gradle / Ivy
package cn.nukkit.block;
import cn.nukkit.Player;
import cn.nukkit.api.PowerNukkitDifference;
import cn.nukkit.api.PowerNukkitOnly;
import cn.nukkit.api.PowerNukkitXOnly;
import cn.nukkit.api.Since;
import cn.nukkit.blockproperty.BlockProperties;
import cn.nukkit.blockproperty.CommonBlockProperties;
import cn.nukkit.entity.Entity;
import cn.nukkit.event.Event;
import cn.nukkit.event.block.BlockRedstoneEvent;
import cn.nukkit.event.entity.EntityInteractEvent;
import cn.nukkit.event.player.PlayerInteractEvent;
import cn.nukkit.event.player.PlayerInteractEvent.Action;
import cn.nukkit.item.Item;
import cn.nukkit.item.ItemTool;
import cn.nukkit.level.GlobalBlockPalette;
import cn.nukkit.level.Level;
import cn.nukkit.math.AxisAlignedBB;
import cn.nukkit.math.BlockFace;
import cn.nukkit.math.SimpleAxisAlignedBB;
import cn.nukkit.network.protocol.LevelSoundEventPacket;
import cn.nukkit.utils.RedstoneComponent;
import javax.annotation.Nonnull;
import static cn.nukkit.blockproperty.CommonBlockProperties.REDSTONE_SIGNAL;
/**
* @author Snake1999
* @since 2016/1/11
*/
@PowerNukkitDifference(info = "Implements RedstoneComponent and uses methods from it.", since = "1.4.0.0-PN")
public abstract class BlockPressurePlateBase extends BlockFlowable implements RedstoneComponent {
@PowerNukkitOnly
@Since("1.4.0.0-PN")
public static final BlockProperties PROPERTIES = CommonBlockProperties.REDSTONE_SIGNAL_BLOCK_PROPERTY;
protected float onPitch;
protected float offPitch;
@Since("1.4.0.0-PN")
@PowerNukkitOnly
@Nonnull
@Override
public BlockProperties getProperties() {
return PROPERTIES;
}
protected BlockPressurePlateBase() {
this(0);
}
protected BlockPressurePlateBase(int meta) {
super(meta);
}
@Override
public boolean canPassThrough() {
return true;
}
@Override
public boolean canHarvestWithHand() {
return false;
}
@Override
public double getMinX() {
return this.x + 0.625;
}
@Override
public double getMinZ() {
return this.z + 0.625;
}
@Override
public double getMinY() {
return this.y + 0;
}
@Override
public double getMaxX() {
return this.x + 0.9375;
}
@Override
public double getMaxZ() {
return this.z + 0.9375;
}
@Override
public double getMaxY() {
return isActivated() ? this.y + 0.03125 : this.y + 0.0625;
}
@Override
public boolean isPowerSource() {
return true;
}
public boolean isActivated() {
return getRedstonePower() == 0;
}
@PowerNukkitOnly
@Override
public int getWaterloggingLevel() {
return 1;
}
@PowerNukkitXOnly
@Since("1.6.0.0-PNX")
public static boolean isSupportValid(Block block, BlockFace blockFace) {
return BlockLever.isSupportValid(block, blockFace) || block instanceof BlockFence;
}
@PowerNukkitDifference(info = "Allow to be placed on top of the walls", since = "1.3.0.0-PN")
@PowerNukkitDifference(since = "1.4.0.0-PN", info = "Fixed support logic")
@Override
public int onUpdate(int type) {
if (type == Level.BLOCK_UPDATE_NORMAL) {
if (!isSupportValid(down(), BlockFace.UP)) {
this.level.useBreakOn(this, ItemTool.getBestTool(getToolType()));
}
} else if (type == Level.BLOCK_UPDATE_SCHEDULED) {
int power = this.getRedstonePower();
if (power > 0) {
this.updateState(power);
}
}
return 0;
}
@PowerNukkitDifference(info = "Allow to be placed on top of the walls", since = "1.3.0.0-PN")
@PowerNukkitDifference(since = "1.4.0.0-PN", info = "Fixed support logic")
@Override
public boolean place(@Nonnull Item item, @Nonnull Block block, @Nonnull Block target, @Nonnull BlockFace face, double fx, double fy, double fz, Player player) {
if (!isSupportValid(down(), BlockFace.UP)) {
return false;
}
this.level.setBlock(block, this, true, true);
return true;
}
@Override
protected AxisAlignedBB recalculateCollisionBoundingBox() {
return new SimpleAxisAlignedBB(this.x + 0.125, this.y, this.z + 0.125, this.x + 0.875, this.y + 0.25, this.z + 0.875D);
}
@Override
public void onEntityCollide(Entity entity) {
if (!this.level.getServer().isRedstoneEnabled()) {
return;
}
int power = getRedstonePower();
if (power == 0) {
Event ev;
if (entity instanceof Player) {
ev = new PlayerInteractEvent((Player) entity, null, this, null, Action.PHYSICAL);
} else {
ev = new EntityInteractEvent(entity, this);
}
this.level.getServer().getPluginManager().callEvent(ev);
if (!ev.isCancelled()) {
updateState(power);
}
}
}
protected void updateState(int oldStrength) {
int strength = this.computeRedstoneStrength();
boolean wasPowered = oldStrength > 0;
boolean isPowered = strength > 0;
if (oldStrength != strength) {
this.setRedstonePower(strength);
this.level.setBlock(this, this, false, false);
updateAroundRedstone();
RedstoneComponent.updateAroundRedstone(this.getSide(BlockFace.DOWN));
if (!isPowered && wasPowered) {
this.playOffSound();
this.level.getServer().getPluginManager().callEvent(new BlockRedstoneEvent(this, 15, 0));
} else if (isPowered && !wasPowered) {
this.playOnSound();
this.level.getServer().getPluginManager().callEvent(new BlockRedstoneEvent(this, 0, 15));
}
}
if (isPowered) {
this.level.scheduleUpdate(this, 20);
}
}
@Override
public boolean onBreak(Item item) {
this.level.setBlock(this, Block.get(BlockID.AIR), true, true);
if (this.getRedstonePower() > 0) {
updateAroundRedstone();
RedstoneComponent.updateAroundRedstone(this.getSide(BlockFace.DOWN));
}
return true;
}
@Override
public int getWeakPower(BlockFace side) {
return getRedstonePower();
}
@Override
public int getStrongPower(BlockFace side) {
return side == BlockFace.UP ? this.getRedstonePower() : 0;
}
public int getRedstonePower() {
return getPropertyValue(REDSTONE_SIGNAL);
}
public void setRedstonePower(int power) {
setIntValue(REDSTONE_SIGNAL, power);
}
protected void playOnSound() {
this.level.addLevelSoundEvent(this.add(0.5, 0.1, 0.5), LevelSoundEventPacket.SOUND_POWER_ON, GlobalBlockPalette.getOrCreateRuntimeId(this.getId(), this.getDamage()));
}
protected void playOffSound() {
this.level.addLevelSoundEvent(this.add(0.5, 0.1, 0.5), LevelSoundEventPacket.SOUND_POWER_OFF, GlobalBlockPalette.getOrCreateRuntimeId(this.getId(), this.getDamage()));
}
protected abstract int computeRedstoneStrength();
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy