Skip to content

Commit

Permalink
Add radio broadcasting sounds
Browse files Browse the repository at this point in the history
- Added Radio Transceiver/Loudspeaker
- Server emitters can be authoritative over sound networks
  • Loading branch information
FoundationGames committed Jul 21, 2023
1 parent 5d8a2a5 commit 7f5fbe8
Show file tree
Hide file tree
Showing 42 changed files with 1,231 additions and 77 deletions.
2 changes: 0 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ version = "${project.mod_version}+${project.minecraft_version}"
group = project.maven_group

repositories {
maven { url = "https://server.bbkr.space/artifactory/libs-release" }
maven { url = "https://storage.googleapis.com/devan-maven/" }
maven { url "https://api.modrinth.com/maven" }
}

Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ loader_version=0.14.21
#Fabric api
fabric_version=0.84.0+1.20.1

mod_version = 1.0.0-beta.1
mod_version = 1.0.0-beta.2
maven_group = io.github.foundationgames
archives_base_name = phonos

Expand Down
13 changes: 12 additions & 1 deletion src/main/java/io/github/foundationgames/phonos/Phonos.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import io.github.foundationgames.phonos.item.ItemGroupQueue;
import io.github.foundationgames.phonos.item.PhonosItems;
import io.github.foundationgames.phonos.network.PayloadPackets;
import io.github.foundationgames.phonos.radio.RadioDevice;
import io.github.foundationgames.phonos.radio.RadioStorage;
import io.github.foundationgames.phonos.sound.SoundStorage;
import io.github.foundationgames.phonos.sound.emitter.SoundEmitter;
import io.github.foundationgames.phonos.sound.emitter.SoundEmitterStorage;
Expand Down Expand Up @@ -41,7 +43,8 @@ public void onInitialize() {
SoundDataTypes.init();
InputPlugPoint.init();

ServerLifecycleEvents.SERVER_STARTED.register(e -> {
ServerLifecycleEvents.SERVER_STARTING.register(e -> {
RadioStorage.serverReset();
SoundStorage.serverReset();
SoundEmitterStorage.serverReset();
});
Expand All @@ -51,12 +54,20 @@ public void onInitialize() {
if (be instanceof SoundEmitter p) {
SoundEmitterStorage.getInstance(world).addEmitter(p);
}
if (be instanceof RadioDevice.Receiver rec) {
rec.setAndUpdateChannel(rec.getChannel());
}
});
ServerBlockEntityEvents.BLOCK_ENTITY_UNLOAD.register((be, world) -> {
if (be instanceof SoundEmitter p) {
SoundEmitterStorage.getInstance(world).removeEmitter(p);
}
if (be instanceof RadioDevice.Receiver rec) {
rec.removeReceiver();
}
});

RadioStorage.init();
}

public static Identifier id(String path) {
Expand Down
16 changes: 15 additions & 1 deletion src/main/java/io/github/foundationgames/phonos/PhonosClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@
import io.github.foundationgames.jsonem.JsonEM;
import io.github.foundationgames.phonos.block.PhonosBlocks;
import io.github.foundationgames.phonos.client.render.block.CableOutputBlockEntityRenderer;
import io.github.foundationgames.phonos.client.render.block.RadioLoudspeakerBlockEntityRenderer;
import io.github.foundationgames.phonos.client.render.block.RadioTransceiverBlockEntityRenderer;
import io.github.foundationgames.phonos.item.AudioCableItem;
import io.github.foundationgames.phonos.item.PhonosItems;
import io.github.foundationgames.phonos.network.ClientPayloadPackets;
import io.github.foundationgames.phonos.radio.RadioDevice;
import io.github.foundationgames.phonos.radio.RadioStorage;
import io.github.foundationgames.phonos.sound.ClientSoundStorage;
import io.github.foundationgames.phonos.sound.SoundStorage;
import io.github.foundationgames.phonos.sound.emitter.SoundEmitter;
import io.github.foundationgames.phonos.sound.emitter.SoundEmitterStorage;
import io.github.foundationgames.phonos.util.PhonosUtil;
import io.github.foundationgames.phonos.world.sound.data.SoundDataTypes;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientBlockEntityEvents;
Expand All @@ -35,10 +38,14 @@ public void onInitializeClient() {
JsonEM.registerModelLayer(AUDIO_CABLE_END_LAYER);

BlockRenderLayerMap.INSTANCE.putBlock(PhonosBlocks.ELECTRONIC_NOTE_BLOCK, RenderLayer.getCutout());
BlockRenderLayerMap.INSTANCE.putBlock(PhonosBlocks.RADIO_TRANSCEIVER, RenderLayer.getCutout());
BlockRenderLayerMap.INSTANCE.putBlock(PhonosBlocks.RADIO_LOUDSPEAKER, RenderLayer.getCutout());

BlockEntityRendererFactories.register(PhonosBlocks.ELECTRONIC_NOTE_BLOCK_ENTITY, CableOutputBlockEntityRenderer::new);
BlockEntityRendererFactories.register(PhonosBlocks.ELECTRONIC_JUKEBOX_ENTITY, CableOutputBlockEntityRenderer::new);
BlockEntityRendererFactories.register(PhonosBlocks.CONNECTION_HUB_ENTITY, CableOutputBlockEntityRenderer::new);
BlockEntityRendererFactories.register(PhonosBlocks.RADIO_TRANSCEIVER_ENTITY, RadioTransceiverBlockEntityRenderer::new);
BlockEntityRendererFactories.register(PhonosBlocks.RADIO_LOUDSPEAKER_ENTITY, RadioLoudspeakerBlockEntityRenderer::new);

ColorProviderRegistry.BLOCK.register((state, world, pos, tintIndex) ->
world != null && pos != null && state != null ?
Expand All @@ -55,6 +62,7 @@ public void onInitializeClient() {

ClientEntityEvents.ENTITY_LOAD.register((entity, world) -> {
if (entity == MinecraftClient.getInstance().player) {
RadioStorage.clientReset();
SoundStorage.clientReset();
SoundEmitterStorage.clientReset();
}
Expand All @@ -66,11 +74,17 @@ public void onInitializeClient() {
if (be instanceof SoundEmitter p) {
SoundEmitterStorage.getInstance(world).addEmitter(p);
}
if (be instanceof RadioDevice.Receiver rec) {
rec.setAndUpdateChannel(rec.getChannel());
}
});
ClientBlockEntityEvents.BLOCK_ENTITY_UNLOAD.register((be, world) -> {
if (be instanceof SoundEmitter p) {
SoundEmitterStorage.getInstance(world).removeEmitter(p);
}
if (be instanceof RadioDevice.Receiver rec) {
rec.removeReceiver();
}
});

//ScreenRegistry.<RadioJukeboxGuiDescription, RadioJukeboxScreen>register(Phonos.RADIO_JUKEBOX_HANDLER, (gui, inventory, title) -> new RadioJukeboxScreen(gui, inventory.player));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package io.github.foundationgames.phonos.block;

import io.github.foundationgames.phonos.world.sound.block.SoundDataHandler;
import io.github.foundationgames.phonos.world.sound.data.NoteBlockSoundData;
import io.github.foundationgames.phonos.world.sound.data.SoundData;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.HorizontalFacingBlock;
import net.minecraft.client.MinecraftClient;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.state.StateManager;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;

public class AbstractLoudspeakerBlock extends HorizontalFacingBlock implements SoundDataHandler {
public AbstractLoudspeakerBlock(Settings settings) {
super(settings);

setDefaultState(getDefaultState().with(FACING, Direction.NORTH));
}

@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder);
builder.add(FACING);
}

@Nullable
@Override
public BlockState getPlacementState(ItemPlacementContext ctx) {
return getDefaultState().with(FACING, ctx.getHorizontalPlayerFacing().getOpposite());
}

@Override
public void receiveSound(BlockState state, World world, BlockPos pos, SoundData sound) {
if (!world.isClient()) {
return;
}

if (MinecraftClient.getInstance().player.getPos().squaredDistanceTo(pos.getX(), pos.getY(), pos.getZ()) > 5000) {
return;
}

if (sound instanceof NoteBlockSoundData noteData) {
double note = noteData.note / 24D;
if (!world.getBlockState(pos.up()).isSideSolidFullSquare(world, pos.up(), Direction.DOWN)) {
world.addParticle(ParticleTypes.NOTE,
pos.getX() + 0.5, pos.getY() + 1.1, pos.getZ() + 0.5,
note, 0, 0);
} else {
var facing = state.get(FACING);
for (var dir : Direction.Type.HORIZONTAL) if (dir != facing.getOpposite()) {
if (!world.getBlockState(pos.offset(dir)).isSideSolidFullSquare(world, pos.offset(dir), dir.getOpposite())) {
world.addParticle(ParticleTypes.NOTE,
pos.getX() + 0.5 + dir.getVector().getX() * 0.6,
pos.getY() + 0.35,
pos.getZ() + 0.5 + dir.getVector().getZ() * 0.6,
note, 0, 0);
}
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,18 +52,18 @@ public ActionResult useMusicDisc(World world, BlockPos pos, BlockState state, It
@Override
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
var side = hit.getSide();
if (side == Direction.UP) {
var stack = player.getStackInHand(hand);
if (!state.get(HAS_RECORD) && stack.getItem() instanceof MusicDiscItem) {
return this.useMusicDisc(world, pos, state, stack, player);
}

return super.onUse(state, world, pos, player, hand, hit);
}
if (side == Direction.DOWN) {
return ActionResult.PASS;
}

var stack = player.getStackInHand(hand);
if (!state.get(HAS_RECORD) && stack.getItem() instanceof MusicDiscItem) {
return this.useMusicDisc(world, pos, state, stack, player);
} else if (side == Direction.UP) {
return super.onUse(state, world, pos, player, hand, hit);
}

if (player.canModifyBlocks()) {
if (!world.isClient() && world.getBlockEntity(pos) instanceof ElectronicJukeboxBlockEntity be) {
if (!PhonosUtil.holdingAudioCable(player) && be.outputs.tryRemoveConnection(world, hit, !player.isCreative())) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package io.github.foundationgames.phonos.block;

import io.github.foundationgames.phonos.block.entity.ElectronicJukeboxBlockEntity;
import io.github.foundationgames.phonos.block.entity.ElectronicNoteBlockEntity;
import io.github.foundationgames.phonos.sound.SoundStorage;
import io.github.foundationgames.phonos.sound.emitter.SoundEmitterTree;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,10 @@
import io.github.foundationgames.phonos.util.PhonosUtil;
import io.github.foundationgames.phonos.world.sound.block.BlockConnectionLayout;
import io.github.foundationgames.phonos.world.sound.block.InputBlock;
import io.github.foundationgames.phonos.world.sound.block.SoundDataHandler;
import io.github.foundationgames.phonos.world.sound.data.NoteBlockSoundData;
import io.github.foundationgames.phonos.world.sound.data.SoundData;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.HorizontalFacingBlock;
import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.item.ItemUsageContext;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.state.StateManager;
import net.minecraft.state.property.BooleanProperty;
import net.minecraft.util.ActionResult;
Expand All @@ -23,9 +16,8 @@
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;

public class LoudspeakerBlock extends HorizontalFacingBlock implements SoundDataHandler, InputBlock {
public class LoudspeakerBlock extends AbstractLoudspeakerBlock implements InputBlock {
public static final BooleanProperty[] INPUTS = BlockProperties.pluggableInputs(4);

public final BlockConnectionLayout inputLayout = new BlockConnectionLayout()
Expand All @@ -37,13 +29,13 @@ public class LoudspeakerBlock extends HorizontalFacingBlock implements SoundData
public LoudspeakerBlock(Settings settings) {
super(settings);

setDefaultState(BlockProperties.withAll(getDefaultState(), INPUTS, false).with(FACING, Direction.NORTH));
setDefaultState(BlockProperties.withAll(getDefaultState(), INPUTS, false));
}

@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder);
builder.add(FACING);

builder.add(INPUTS);
}

Expand All @@ -60,12 +52,6 @@ public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEnt
return ActionResult.success(hit.getSide().equals(state.get(FACING).getOpposite()));
}

@Nullable
@Override
public BlockState getPlacementState(ItemPlacementContext ctx) {
return getDefaultState().with(FACING, ctx.getHorizontalPlayerFacing().getOpposite());
}

@Override
public boolean canInputConnect(ItemUsageContext ctx) {
var world = ctx.getWorld();
Expand All @@ -92,37 +78,6 @@ public Direction getRotation(BlockState state) {
return state.get(FACING);
}

@Override
public void receiveSound(BlockState state, World world, BlockPos pos, SoundData sound) {
if (!world.isClient()) {
return;
}

if (MinecraftClient.getInstance().player.getPos().squaredDistanceTo(pos.getX(), pos.getY(), pos.getZ()) > 5000) {
return;
}

if (sound instanceof NoteBlockSoundData noteData) {
double note = noteData.note / 24D;
if (!world.getBlockState(pos.up()).isSolidBlock(world, pos.up())) {
world.addParticle(ParticleTypes.NOTE,
pos.getX() + 0.5, pos.getY() + 1.1, pos.getZ() + 0.5,
note, 0, 0);
} else {
var facing = state.get(FACING);
for (var dir : Direction.Type.HORIZONTAL) if (dir != facing.getOpposite()) {
if (!world.getBlockState(pos.offset(dir)).isSolidBlock(world, pos.offset(dir))) {
world.addParticle(ParticleTypes.NOTE,
pos.getX() + 0.5 + dir.getVector().getX() * 0.6,
pos.getY() + 0.35,
pos.getZ() + 0.5 + dir.getVector().getZ() * 0.6,
note, 0, 0);
}
}
}
}
}

@Override
public boolean isInputPluggedIn(int inputIndex, BlockState state, World world, BlockPos pos) {
inputIndex = MathHelper.clamp(inputIndex, 0, 3);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package io.github.foundationgames.phonos.block;

import io.github.foundationgames.phonos.Phonos;
import io.github.foundationgames.phonos.block.entity.ConnectionHubBlockEntity;
import io.github.foundationgames.phonos.block.entity.ElectronicJukeboxBlockEntity;
import io.github.foundationgames.phonos.block.entity.ElectronicNoteBlockEntity;
import io.github.foundationgames.phonos.block.entity.*;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import net.minecraft.block.Block;
import net.minecraft.block.Blocks;
Expand All @@ -18,6 +16,8 @@ public class PhonosBlocks {
public static final Block ELECTRONIC_NOTE_BLOCK = register(new ElectronicNoteBlock(FabricBlockSettings.copy(Blocks.NOTE_BLOCK)), "electronic_note_block");
public static final Block ELECTRONIC_JUKEBOX = register(new ElectronicJukeboxBlock(FabricBlockSettings.copy(Blocks.JUKEBOX)), "electronic_jukebox");
public static final Block CONNECTION_HUB = register(new ConnectionHubBlock(FabricBlockSettings.copy(Blocks.OAK_PLANKS)), "connection_hub");
public static final Block RADIO_TRANSCEIVER = register(new RadioTransceiverBlock(FabricBlockSettings.copy(Blocks.OAK_SLAB)), "radio_transceiver");
public static final Block RADIO_LOUDSPEAKER = register(new RadioLoudspeakerBlock(FabricBlockSettings.copy(Blocks.NOTE_BLOCK)), "radio_loudspeaker");

public static BlockEntityType<ElectronicNoteBlockEntity> ELECTRONIC_NOTE_BLOCK_ENTITY = Registry.register(
Registries.BLOCK_ENTITY_TYPE, Phonos.id("electronic_note_block"),
Expand All @@ -28,6 +28,12 @@ public class PhonosBlocks {
public static BlockEntityType<ConnectionHubBlockEntity> CONNECTION_HUB_ENTITY = Registry.register(
Registries.BLOCK_ENTITY_TYPE, Phonos.id("connection_hub"),
BlockEntityType.Builder.create(ConnectionHubBlockEntity::new, CONNECTION_HUB).build(null));
public static BlockEntityType<RadioTransceiverBlockEntity> RADIO_TRANSCEIVER_ENTITY = Registry.register(
Registries.BLOCK_ENTITY_TYPE, Phonos.id("radio_transceiver"),
BlockEntityType.Builder.create(RadioTransceiverBlockEntity::new, RADIO_TRANSCEIVER).build(null));
public static BlockEntityType<RadioLoudspeakerBlockEntity> RADIO_LOUDSPEAKER_ENTITY = Registry.register(
Registries.BLOCK_ENTITY_TYPE, Phonos.id("radio_loudspeaker"),
BlockEntityType.Builder.create(RadioLoudspeakerBlockEntity::new, RADIO_LOUDSPEAKER).build(null));

private static Block register(Block block, String name) {
var item = Registry.register(Registries.ITEM, Phonos.id(name), new BlockItem(block, new Item.Settings()));
Expand Down
Loading

0 comments on commit 7f5fbe8

Please sign in to comment.