cn.nukkit.block.BlockNoteblock 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.blockentity.BlockEntity;
import cn.nukkit.blockentity.BlockEntityMusic;
import cn.nukkit.event.player.PlayerInteractEvent.Action;
import cn.nukkit.item.Item;
import cn.nukkit.item.ItemTool;
import cn.nukkit.level.Level;
import cn.nukkit.level.Sound;
import cn.nukkit.level.vibration.VibrationEvent;
import cn.nukkit.level.vibration.VibrationType;
import cn.nukkit.math.BlockFace;
import cn.nukkit.network.protocol.BlockEventPacket;
import cn.nukkit.network.protocol.LevelSoundEventPacket;
import cn.nukkit.utils.BlockColor;
import cn.nukkit.utils.RedstoneComponent;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* @author Snake1999
* @since 2016/1/17
*/
@PowerNukkitDifference(info = "Implements RedstoneComponent.", since = "1.4.0.0-PN")
@PowerNukkitDifference(since = "1.4.0.0-PN", info = "Implements BlockEntityHolder only in PowerNukkit")
public class BlockNoteblock extends BlockSolid implements RedstoneComponent, BlockEntityHolder {
public BlockNoteblock() {
// Does nothing
}
@Override
public String getName() {
return "Note Block";
}
@Override
public int getId() {
return NOTEBLOCK;
}
@Override
public int getToolType() {
return ItemTool.TYPE_AXE;
}
@Since("1.4.0.0-PN")
@PowerNukkitOnly
@Nonnull
@Override
public Class extends BlockEntityMusic> getBlockEntityClass() {
return BlockEntityMusic.class;
}
@PowerNukkitOnly
@Since("1.4.0.0-PN")
@Nonnull
@Override
public String getBlockEntityType() {
return BlockEntity.MUSIC;
}
@Override
public double getHardness() {
return 0.8D;
}
@Override
public double getResistance() {
return 4D;
}
@Override
public boolean canBeActivated() {
return true;
}
@Override
public boolean place(@Nonnull Item item, @Nonnull Block block, @Nonnull Block target, @Nonnull BlockFace face, double fx, double fy, double fz, @Nullable Player player) {
return BlockEntityHolder.setBlockAndCreateEntity(this) != null;
}
@Since("1.4.0.0-PN")
@PowerNukkitOnly
@Override
public int onTouch(@Nullable Player player, Action action) {
if (action == Action.LEFT_CLICK_BLOCK && (player == null || (!player.isCreative() && !player.isSpectator()))) {
this.emitSound(player);
}
return super.onTouch(player, action);
}
public int getStrength() {
BlockEntityMusic blockEntity = this.getBlockEntity();
return blockEntity != null ? blockEntity.getPitch() : 0;
}
public void increaseStrength() {
getOrCreateBlockEntity().changePitch();
}
public Instrument getInstrument() {
switch (this.down().getId()) {
case GOLD_BLOCK:
return Instrument.GLOCKENSPIEL;
case CLAY_BLOCK:
case HONEYCOMB_BLOCK:
return Instrument.FLUTE;
case PACKED_ICE:
return Instrument.CHIME;
case WOOL:
return Instrument.GUITAR;
case BONE_BLOCK:
return Instrument.XYLOPHONE;
case IRON_BLOCK:
return Instrument.VIBRAPHONE;
case SOUL_SAND:
return Instrument.COW_BELL;
case PUMPKIN:
return Instrument.DIDGERIDOO;
case EMERALD_BLOCK:
return Instrument.SQUARE_WAVE;
case HAY_BALE:
return Instrument.BANJO;
case GLOWSTONE:
return Instrument.ELECTRIC_PIANO;
case LOG:
case LOG2:
case PLANKS:
case DOUBLE_WOODEN_SLAB:
case WOODEN_SLAB:
case OAK_STAIRS:
case SPRUCE_STAIRS:
case BIRCH_STAIRS:
case JUNGLE_STAIRS:
case ACACIA_WOOD_STAIRS:
case DARK_OAK_WOOD_STAIRS:
case CRIMSON_STAIRS:
case WARPED_STAIRS:
case FENCE:
case FENCE_GATE:
case FENCE_GATE_SPRUCE:
case FENCE_GATE_BIRCH:
case FENCE_GATE_JUNGLE:
case FENCE_GATE_DARK_OAK:
case FENCE_GATE_ACACIA:
case CRIMSON_FENCE_GATE:
case WARPED_FENCE_GATE:
case OAK_DOOR_BLOCK:
case SPRUCE_DOOR_BLOCK:
case BIRCH_DOOR_BLOCK:
case JUNGLE_DOOR_BLOCK:
case ACACIA_DOOR_BLOCK:
case DARK_OAK_DOOR_BLOCK:
case CRIMSON_DOOR_BLOCK:
case WARPED_DOOR_BLOCK:
case WOODEN_PRESSURE_PLATE:
case TRAPDOOR:
case SIGN_POST:
case WALL_SIGN:
case NOTEBLOCK:
case BOOKSHELF:
case CHEST:
case TRAPPED_CHEST:
case CRAFTING_TABLE:
case JUKEBOX:
case BROWN_MUSHROOM_BLOCK:
case RED_MUSHROOM_BLOCK:
case DAYLIGHT_DETECTOR:
case DAYLIGHT_DETECTOR_INVERTED:
case STANDING_BANNER:
case WALL_BANNER:
return Instrument.BASS;
case SAND:
case GRAVEL:
case CONCRETE_POWDER:
return Instrument.DRUM;
case GLASS:
case GLASS_PANE:
case STAINED_GLASS_PANE:
case STAINED_GLASS:
case BEACON:
case SEA_LANTERN:
return Instrument.STICKS;
case STONE:
case SANDSTONE:
case RED_SANDSTONE:
case COBBLESTONE:
case MOSSY_COBBLESTONE:
case BRICKS_BLOCK:
case STONEBRICK:
case NETHER_BRICK_BLOCK:
case RED_NETHER_BRICK:
case QUARTZ_BLOCK:
case DOUBLE_STONE_SLAB:
case STONE_SLAB:
case DOUBLE_RED_SANDSTONE_SLAB:
case RED_SANDSTONE_SLAB:
case STONE_STAIRS:
case BRICK_STAIRS:
case STONE_BRICK_STAIRS:
case NETHER_BRICKS_STAIRS:
case SANDSTONE_STAIRS:
case QUARTZ_STAIRS:
case RED_SANDSTONE_STAIRS:
case PURPUR_STAIRS:
case COBBLE_WALL:
case NETHER_BRICK_FENCE:
case BEDROCK:
case GOLD_ORE:
case IRON_ORE:
case COAL_ORE:
case LAPIS_ORE:
case DIAMOND_ORE:
case REDSTONE_ORE:
case LIT_REDSTONE_ORE:
case EMERALD_ORE:
case DROPPER:
case DISPENSER:
case FURNACE:
case LIT_FURNACE:
case OBSIDIAN:
case GLOWING_OBSIDIAN:
case MOB_SPAWNER:
case STONE_PRESSURE_PLATE:
case NETHERRACK:
case QUARTZ_ORE:
case ENCHANTING_TABLE:
case END_PORTAL_FRAME:
case END_STONE:
case END_BRICKS:
case ENDER_CHEST:
case STAINED_TERRACOTTA:
case TERRACOTTA:
case PRISMARINE:
case COAL_BLOCK:
case PURPUR_BLOCK:
case MAGMA:
case CONCRETE:
case STONECUTTER:
case OBSERVER:
case CRIMSON_NYLIUM:
case WARPED_NYLIUM:
return Instrument.BASS_DRUM;
default:
return Instrument.PIANO;
}
}
public void emitSound() {
emitSound(null);
}
@PowerNukkitXOnly
@Since("1.19.21-r4")
public void emitSound(@Nullable Player player) {
if (this.up().getId() != AIR) return;
this.level.getVibrationManager().callVibrationEvent(new VibrationEvent(player != null ? player : this, this.add(0.5, 0.5, 0.5).clone(), VibrationType.BLOCK_CHANGE));
Instrument instrument = this.getInstrument();
this.level.addLevelSoundEvent(this, LevelSoundEventPacket.SOUND_NOTE, instrument.ordinal() << 8 | this.getStrength());
BlockEventPacket pk = new BlockEventPacket();
pk.x = this.getFloorX();
pk.y = this.getFloorY();
pk.z = this.getFloorZ();
pk.case1 = instrument.ordinal();
pk.case2 = this.getStrength();
this.getLevel().addChunkPacket(this.getFloorX() >> 4, this.getFloorZ() >> 4, pk);
}
@Override
public boolean onActivate(@Nonnull Item item, @Nullable Player player) {
this.increaseStrength();
this.emitSound(player);
return true;
}
@Override
@PowerNukkitDifference(info = "Using new method for checking if powered", since = "1.4.0.0-PN")
public int onUpdate(int type) {
if (type == Level.BLOCK_UPDATE_REDSTONE) {
// We can't use getOrCreateBlockEntity(), because the update method is called on block place,
// before the "real" BlockEntity is set. That means, if we'd use the other method here,
// it would create two BlockEntities.
BlockEntityMusic music = getBlockEntity();
if (music == null)
return 0;
if (this.isGettingPower()) {
if (!music.isPowered()) {
this.emitSound();
}
music.setPowered(true);
} else {
music.setPowered(false);
}
}
return super.onUpdate(type);
}
public enum Instrument {
PIANO(Sound.NOTE_HARP),
BASS_DRUM(Sound.NOTE_BD),
DRUM(Sound.NOTE_SNARE),
STICKS(Sound.NOTE_HAT),
BASS(Sound.NOTE_BASS),
GLOCKENSPIEL(Sound.NOTE_BELL),
FLUTE(Sound.NOTE_FLUTE),
CHIME(Sound.NOTE_CHIME),
GUITAR(Sound.NOTE_GUITAR),
XYLOPHONE(Sound.NOTE_XYLOPHONE),
VIBRAPHONE(Sound.NOTE_IRON_XYLOPHONE),
COW_BELL(Sound.NOTE_COW_BELL),
DIDGERIDOO(Sound.NOTE_DIDGERIDOO),
SQUARE_WAVE(Sound.NOTE_BIT),
BANJO(Sound.NOTE_BANJO),
ELECTRIC_PIANO(Sound.NOTE_PLING);
private final Sound sound;
Instrument(Sound sound) {
this.sound = sound;
}
public Sound getSound() {
return sound;
}
}
@Override
public BlockColor getColor() {
return BlockColor.WOOD_BLOCK_COLOR;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy