Skip to content

Commit

Permalink
add very very very rough sound block
Browse files Browse the repository at this point in the history
  • Loading branch information
afamiliarquiet authored and HamaIndustries committed Nov 27, 2024
1 parent 3c56390 commit 0588b99
Show file tree
Hide file tree
Showing 16 changed files with 614 additions and 16 deletions.
23 changes: 7 additions & 16 deletions src/main/java/dev/hephaestus/glowcase/Glowcase.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,8 @@

import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import dev.hephaestus.glowcase.block.HyperlinkBlock;
import dev.hephaestus.glowcase.block.ItemAcceptorBlock;
import dev.hephaestus.glowcase.block.ItemDisplayBlock;
import dev.hephaestus.glowcase.block.OutlineBlock;
import dev.hephaestus.glowcase.block.ParticleDisplayBlock;
import dev.hephaestus.glowcase.block.PopupBlock;
import dev.hephaestus.glowcase.block.SpriteBlock;
import dev.hephaestus.glowcase.block.TextBlock;
import dev.hephaestus.glowcase.block.entity.HyperlinkBlockEntity;
import dev.hephaestus.glowcase.block.entity.ItemAcceptorBlockEntity;
import dev.hephaestus.glowcase.block.entity.ItemDisplayBlockEntity;
import dev.hephaestus.glowcase.block.entity.OutlineBlockEntity;
import dev.hephaestus.glowcase.block.entity.ParticleDisplayBlockEntity;
import dev.hephaestus.glowcase.block.entity.PopupBlockEntity;
import dev.hephaestus.glowcase.block.entity.SpriteBlockEntity;
import dev.hephaestus.glowcase.block.entity.TextBlockEntity;
import dev.hephaestus.glowcase.block.*;
import dev.hephaestus.glowcase.block.entity.*;
import dev.hephaestus.glowcase.compat.PolydexCompatibility;
import dev.hephaestus.glowcase.item.LockItem;
import net.fabricmc.api.ModInitializer;
Expand Down Expand Up @@ -57,6 +43,10 @@ public class Glowcase implements ModInitializer {
public static final Supplier<BlockItem> PARTICLE_DISPLAY_ITEM = registerItem("particle_display", () -> new BlockItem(PARTICLE_DISPLAY.get(), new Item.Settings()));
public static final Supplier<BlockEntityType<ParticleDisplayBlockEntity>> PARTICLE_DISPLAY_BLOCK_ENTITY = registerBlockEntity("particle_display", () -> BlockEntityType.Builder.create(ParticleDisplayBlockEntity::new, PARTICLE_DISPLAY.get()).build(null));

public static final Supplier<SoundPlayerBlock> SOUND_BLOCK = registerBlock("sound_block", SoundPlayerBlock::new);
public static final Supplier<BlockItem> SOUND_BLOCK_ITEM = registerItem("sound_block", () -> new BlockItem(SOUND_BLOCK.get(), new Item.Settings()));
public static final Supplier<BlockEntityType<SoundPlayerBlockEntity>> SOUND_BLOCK_ENTITY = registerBlockEntity("particle_display", () -> BlockEntityType.Builder.create(SoundPlayerBlockEntity::new, SOUND_BLOCK.get()).build(null));

public static final Supplier<TextBlock> TEXT_BLOCK = registerBlock("text_block", TextBlock::new);
public static final Supplier<BlockItem> TEXT_BLOCK_ITEM = registerItem("text_block", () -> new BlockItem(TEXT_BLOCK.get(), new Item.Settings()));
public static final Supplier<BlockEntityType<TextBlockEntity>> TEXT_BLOCK_ENTITY = registerBlockEntity("text_block", () -> BlockEntityType.Builder.create(TextBlockEntity::new, TEXT_BLOCK.get()).build(null));
Expand Down Expand Up @@ -87,6 +77,7 @@ public class Glowcase implements ModInitializer {
entries.add(SPRITE_BLOCK_ITEM.get());
entries.add(OUTLINE_BLOCK_ITEM.get());
entries.add(PARTICLE_DISPLAY_ITEM.get());
entries.add(SOUND_BLOCK_ITEM.get());
entries.add(ITEM_DISPLAY_BLOCK_ITEM.get());
entries.add(ITEM_ACCEPTOR_BLOCK_ITEM.get());
entries.add(HYPERLINK_BLOCK_ITEM.get());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ public void openParticleDisplayBlockEditScreen(BlockPos pos) {
//No-op
}

public void openSoundBlockEditScreen(BlockPos pos) {
//No-op
}

public void openItemAcceptorBlockEditScreen(BlockPos pos) {
//No-op
}
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/dev/hephaestus/glowcase/GlowcaseNetworking.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import dev.hephaestus.glowcase.packet.C2SEditOutlineBlock;
import dev.hephaestus.glowcase.packet.C2SEditParticleDisplayBlock;
import dev.hephaestus.glowcase.packet.C2SEditPopupBlock;
import dev.hephaestus.glowcase.packet.C2SEditSoundBlock;
import dev.hephaestus.glowcase.packet.C2SEditSpriteBlock;
import dev.hephaestus.glowcase.packet.C2SEditTextBlock;
import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;
Expand All @@ -20,6 +21,7 @@ public static void init() {
PayloadTypeRegistry.playC2S().register(C2SEditSpriteBlock.ID, C2SEditSpriteBlock.PACKET_CODEC);
PayloadTypeRegistry.playC2S().register(C2SEditOutlineBlock.ID, C2SEditOutlineBlock.PACKET_CODEC);
PayloadTypeRegistry.playC2S().register(C2SEditParticleDisplayBlock.ID, C2SEditParticleDisplayBlock.PACKET_CODEC);
PayloadTypeRegistry.playC2S().register(C2SEditSoundBlock.ID, C2SEditSoundBlock.PACKET_CODEC);
PayloadTypeRegistry.playC2S().register(C2SEditItemAcceptorBlock.ID, C2SEditItemAcceptorBlock.PACKET_CODEC);

ServerPlayNetworking.registerGlobalReceiver(C2SEditHyperlinkBlock.ID, C2SEditHyperlinkBlock::receive);
Expand All @@ -29,6 +31,7 @@ public static void init() {
ServerPlayNetworking.registerGlobalReceiver(C2SEditSpriteBlock.ID, C2SEditSpriteBlock::receive);
ServerPlayNetworking.registerGlobalReceiver(C2SEditOutlineBlock.ID, C2SEditOutlineBlock::receive);
ServerPlayNetworking.registerGlobalReceiver(C2SEditParticleDisplayBlock.ID, C2SEditParticleDisplayBlock::receive);
ServerPlayNetworking.registerGlobalReceiver(C2SEditSoundBlock.ID, C2SEditSoundBlock::receive);
ServerPlayNetworking.registerGlobalReceiver(C2SEditItemAcceptorBlock.ID, C2SEditItemAcceptorBlock::receive);
}
}
55 changes: 55 additions & 0 deletions src/main/java/dev/hephaestus/glowcase/block/SoundPlayerBlock.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package dev.hephaestus.glowcase.block;

import dev.hephaestus.glowcase.Glowcase;
import dev.hephaestus.glowcase.block.entity.SoundPlayerBlockEntity;
import net.minecraft.block.BlockEntityProvider;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityTicker;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.tooltip.TooltipType;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.util.Hand;
import net.minecraft.util.ItemActionResult;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;

import java.util.List;

public class SoundPlayerBlock extends GlowcaseBlock implements BlockEntityProvider {
@Nullable
@Override
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(World world, BlockState state, BlockEntityType<T> type) {
if (!world.isClient()) return null;
return checkType(type, Glowcase.SOUND_BLOCK_ENTITY.get(), SoundPlayerBlockEntity::clientTick);
}

@Override
protected ItemActionResult onUseWithItem(ItemStack stack, BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
if (!(world.getBlockEntity(pos) instanceof SoundPlayerBlockEntity)) return ItemActionResult.CONSUME;

if (world.isClient && player.getStackInHand(hand).isIn(Glowcase.ITEM_TAG) && canEditGlowcase(player, pos)) {
Glowcase.proxy.openSoundBlockEditScreen(pos);
}

return ItemActionResult.SUCCESS;
}

@Nullable
@Override
public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
return new SoundPlayerBlockEntity(pos, state);
}

@Override
public void appendTooltip(ItemStack stack, Item.TooltipContext context, List<Text> tooltip, TooltipType options) {
tooltip.add(Text.translatable("block.glowcase.sound_block.tooltip.0").formatted(Formatting.GRAY));
tooltip.add(Text.translatable("block.glowcase.generic.tooltip").formatted(Formatting.DARK_GRAY));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
package dev.hephaestus.glowcase.block.entity;

import com.mojang.logging.LogUtils;
import dev.hephaestus.glowcase.Glowcase;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.client.sound.AbstractSoundInstance;
import net.minecraft.client.sound.PositionedSoundInstance;
import net.minecraft.client.sound.SoundInstance;
import net.minecraft.client.sound.TickableSoundInstance;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtElement;
import net.minecraft.nbt.NbtOps;
import net.minecraft.network.listener.ClientPlayPacketListener;
import net.minecraft.network.packet.Packet;
import net.minecraft.registry.RegistryOps;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;

public class SoundPlayerBlockEntity extends BlockEntity {
private static final Logger LOGGER = LogUtils.getLogger();

public Identifier soundId = SoundEvents.ENTITY_CAT_PURREOW.getId();
public SoundCategory category = SoundCategory.BLOCKS;
public float volume = 1;
public float pitch = 1;
public int repeatDelay = 0;
public float distance = 16;
public boolean relative = false;
public Vec3d soundPosition;

private AbstractSoundInstance nowPlaying = null;

public SoundPlayerBlockEntity(BlockPos pos, BlockState state) {
super(Glowcase.SOUND_BLOCK_ENTITY.get(), pos, state);
this.soundPosition = pos.toCenterPos();
// this.soundX = pos.getX();
// this.soundY = pos.getY();
// this.soundZ = pos.getZ();
}

public void cycleCategory() {
switch (this.category) {
case SoundCategory.MASTER -> this.category = SoundCategory.MUSIC;
case SoundCategory.MUSIC -> this.category = SoundCategory.RECORDS;
case SoundCategory.RECORDS -> this.category = SoundCategory.WEATHER;
case SoundCategory.WEATHER -> this.category = SoundCategory.BLOCKS;
case SoundCategory.BLOCKS -> this.category = SoundCategory.HOSTILE;
case SoundCategory.HOSTILE -> this.category = SoundCategory.NEUTRAL;
case SoundCategory.NEUTRAL -> this.category = SoundCategory.PLAYERS;
case SoundCategory.PLAYERS -> this.category = SoundCategory.AMBIENT;
case SoundCategory.AMBIENT -> this.category = SoundCategory.VOICE;
case SoundCategory.VOICE -> this.category = SoundCategory.MASTER;
}
}

@Override
protected void writeNbt(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup) {
super.writeNbt(tag, registryLookup);

RegistryOps<NbtElement> ops = registryLookup.getOps(NbtOps.INSTANCE);
Identifier.CODEC.encodeStart(ops, this.soundId)
.resultOrPartial(LOGGER::error)
.ifPresent(result -> tag.put("sound", result));
tag.putString("category", this.category.toString());
tag.putFloat("volume", this.volume);
tag.putFloat("pitch", this.pitch);
tag.putInt("repeatDelay", this.repeatDelay);
tag.putFloat("distance", this.distance);
tag.putBoolean("relative", this.relative);
Vec3d.CODEC.encodeStart(ops, this.soundPosition)
.resultOrPartial(LOGGER::error)
.ifPresent(result -> tag.put("soundPosition", result));
}

@Override
protected void readNbt(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup) {
super.readNbt(tag, registryLookup);

RegistryOps<NbtElement> ops = registryLookup.getOps(NbtOps.INSTANCE);
if (tag.contains("sound"))
Identifier.CODEC.parse(ops, tag.get("sound"))
.resultOrPartial(LOGGER::error)
.ifPresent(result -> this.soundId = result);
this.category = SoundCategory.valueOf(tag.getString("category"));
this.volume = tag.getFloat("volume");
this.pitch = tag.getFloat("pitch");
this.repeatDelay = tag.getInt("repeatDelay");
this.distance = tag.getFloat("distance");
this.relative = tag.getBoolean("relative");
if (tag.contains("soundPosition"))
Vec3d.CODEC.parse(ops, tag.get("soundPosition"))
.resultOrPartial(LOGGER::error)
.ifPresent(result -> this.soundPosition = result);
}

// standard blockentity boilerplate

public void dispatch() {
if (world instanceof ServerWorld sworld) sworld.getChunkManager().markForUpdate(pos);
}

@Override
public NbtCompound toInitialChunkDataNbt(RegistryWrapper.WrapperLookup registryLookup) {
return createNbt(registryLookup);
}

@Nullable
@Override
public Packet<ClientPlayPacketListener> toUpdatePacket() {
return super.toUpdatePacket();
}

public static void clientTick(World world, BlockPos pos, BlockState state, SoundPlayerBlockEntity entity) {
MinecraftClient mc = MinecraftClient.getInstance();
if (mc.player instanceof ClientPlayerEntity player) {
// if (entity.sound == null) return;
//
// RegistryWrapper.WrapperLookup lookup = world.getRegistryManager();
// RegistryKey<SoundEvent> key = RegistryKey.of(RegistryKeys.SOUND_EVENT, entity.sound);
//
// Optional<RegistryEntry.Reference<SoundEvent>> optionalSound =
// lookup.getWrapperOrThrow(RegistryKeys.SOUND_EVENT).getOptional(key);
// if (optionalSound.isEmpty()) return;
//
// player.playSoundToPlayer(optionalSound.get().value(), SoundCategory.BLOCKS, 1, 1);

// TODO: check if any of the other properties changed beyond id. need an equals check or something
if (entity.nowPlaying == null || !entity.nowPlaying.getId().equals(entity.soundId) || (entity.nowPlaying instanceof TickableSoundInstance tickable && tickable.isDone())) {
// AbstractSoundInstance sound = new PositionedSoundLoop(
// entity.sound, SoundCategory.BLOCKS,
// 1, 1,
// SoundInstance.createRandom(),
// true, 0,
// SoundInstance.AttenuationType.LINEAR,
// pos.getX(), pos.getY(), pos.getZ(),
// false
// );
// change xyz to 000 when switching to relative (and back to blockpos for absolute)
// AbstractSoundInstance sound = new PositionedSoundLoop(
// entity.soundId, SoundCategory.BLOCKS,
// 1, 1,
// 0,
// 16,
// false,
// pos.getX(), pos.getY(), pos.getZ(),
// player
// );
AbstractSoundInstance sound = new PositionedSoundLoop(
entity.soundId, entity.category,
entity.volume, entity.pitch, entity.repeatDelay,
entity.distance,
entity.relative,
entity.soundPosition,
player,
entity.getPos()
);

LOGGER.info("playing sound");
// WeightedSoundSet sounds = mc.getSoundManager().get(entity.sound);
// if (sounds != null) {
// sounds.getSound(SoundInstance.createRandom());
//
// }
mc.getSoundManager().stop(entity.nowPlaying);
mc.getSoundManager().play(sound);
//if (mc.player.clientWorld.isPosLoaded(pos))
entity.nowPlaying = sound;
}
}
}

public static class PositionedSoundLoop extends PositionedSoundInstance implements TickableSoundInstance {
private final PlayerEntity player;
private final BlockPos soundBlockPos;

private final float squaredDistance;

private boolean done;

public PositionedSoundLoop(Identifier id, SoundCategory category, float volume, float pitch, int repeatDelay, float distance, boolean relative, Vec3d pos, PlayerEntity player, BlockPos soundBlockPos) {
super(
id, category,
volume, pitch,
SoundInstance.createRandom(),
true, repeatDelay,
AttenuationType.LINEAR,
pos.x, pos.y, pos.z,
relative
);
this.player = player;
this.soundBlockPos = soundBlockPos;
this.squaredDistance = distance * distance;
this.done = false;
}

// public PositionedSoundLoop(Identifier id, SoundCategory category, float volume, float pitch, Random random, boolean repeat, int repeatDelay, AttenuationType attenuationType, double x, double y, double z, boolean relative) {
// super(id, category, volume, pitch, random, repeat, repeatDelay, attenuationType, x, y, z, relative);
// }

@Override
public boolean isDone() {
return this.done;
}

public void setDone() {
this.done = true;
}

@Override
public void tick() {
// stops track-stacking when reloading the block
if (!canPlay()) {
setDone();
}
}

@Override
public boolean canPlay() {
return this.player.squaredDistanceTo(this.soundBlockPos.toCenterPos()) <= this.squaredDistance;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import dev.hephaestus.glowcase.client.render.block.entity.OutlineBlockEntityRenderer;
import dev.hephaestus.glowcase.client.render.block.entity.ParticleDisplayBlockEntityRenderer;
import dev.hephaestus.glowcase.client.render.block.entity.PopupBlockEntityRenderer;
import dev.hephaestus.glowcase.client.render.block.entity.SoundPlayerBlockEntityRenderer;
import dev.hephaestus.glowcase.client.render.block.entity.SpriteBlockEntityRenderer;
import dev.hephaestus.glowcase.client.render.block.entity.TextBlockEntityRenderer;
import net.fabricmc.api.ClientModInitializer;
Expand All @@ -27,6 +28,7 @@ public void onInitializeClient() {
BlockEntityRendererFactories.register(Glowcase.SPRITE_BLOCK_ENTITY.get(), SpriteBlockEntityRenderer::new);
BlockEntityRendererFactories.register(Glowcase.OUTLINE_BLOCK_ENTITY.get(), OutlineBlockEntityRenderer::new);
BlockEntityRendererFactories.register(Glowcase.PARTICLE_DISPLAY_BLOCK_ENTITY.get(), ParticleDisplayBlockEntityRenderer::new);
BlockEntityRendererFactories.register(Glowcase.SOUND_BLOCK_ENTITY.get(), SoundPlayerBlockEntityRenderer::new);
BlockEntityRendererFactories.register(Glowcase.ITEM_ACCEPTOR_BLOCK_ENTITY.get(), ItemAcceptorBlockEntityRenderer::new);

WorldRenderEvents.AFTER_TRANSLUCENT.register(BakedBlockEntityRenderer.Manager::render);
Expand Down
Loading

0 comments on commit 0588b99

Please sign in to comment.