Skip to content

Commit

Permalink
Added satellite radio and audio uploading/streaming
Browse files Browse the repository at this point in the history
- Adjusted multi source sound weighting
- Fixed custom note block sounds
  • Loading branch information
FoundationGames committed Jul 27, 2023
1 parent 7f5fbe8 commit 5f3df26
Show file tree
Hide file tree
Showing 37 changed files with 1,477 additions and 105 deletions.
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.2
mod_version = 1.0.0-beta.3
maven_group = io.github.foundationgames
archives_base_name = phonos

Expand Down
36 changes: 36 additions & 0 deletions src/main/java/io/github/foundationgames/phonos/Phonos.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,35 @@
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.custom.ServerCustomAudio;
import io.github.foundationgames.phonos.sound.emitter.SoundEmitter;
import io.github.foundationgames.phonos.sound.emitter.SoundEmitterStorage;
import io.github.foundationgames.phonos.sound.stream.ServerOutgoingStreamHandler;
import io.github.foundationgames.phonos.util.PhonosUtil;
import io.github.foundationgames.phonos.world.sound.InputPlugPoint;
import io.github.foundationgames.phonos.world.sound.data.SoundDataTypes;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerBlockEntityEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup;
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.util.Identifier;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.IOException;
import java.nio.file.Files;

public class Phonos implements ModInitializer {
public static final Logger LOG = LogManager.getLogger("phonos");

public static final ItemGroupQueue PHONOS_ITEMS = new ItemGroupQueue(id("phonos"));

public static final Identifier STREAMED_SOUND = Phonos.id("streamed");

@Override
public void onInitialize() {
Registry.register(Registries.ITEM_GROUP, PHONOS_ITEMS.id, FabricItemGroup.builder()
Expand All @@ -47,8 +56,35 @@ public void onInitialize() {
RadioStorage.serverReset();
SoundStorage.serverReset();
SoundEmitterStorage.serverReset();
ServerOutgoingStreamHandler.reset();
});

ServerLifecycleEvents.SERVER_STARTED.register(e -> {
ServerCustomAudio.reset();
try {
var path = PhonosUtil.getCustomSoundFolder(e);
if (!Files.exists(path)) Files.createDirectory(path);

ServerCustomAudio.load(path);
} catch (IOException ex) {
Phonos.LOG.error("Error loading custom audio files", ex);
}
});
ServerLifecycleEvents.SERVER_STOPPED.register(e -> {
try {
var path = PhonosUtil.getCustomSoundFolder(e);
if (!Files.exists(path)) Files.createDirectory(path);

ServerCustomAudio.save(path);
} catch (IOException ex) {
Phonos.LOG.error("Error saving custom audio files", ex);
}
});
ServerPlayConnectionEvents.DISCONNECT.register((handler, server) ->
ServerCustomAudio.onPlayerDisconnect(handler.getPlayer()));

ServerTickEvents.END_WORLD_TICK.register(world -> SoundStorage.getInstance(world).tick(world));
ServerTickEvents.START_SERVER_TICK.register(ServerOutgoingStreamHandler::tick);

ServerBlockEntityEvents.BLOCK_ENTITY_LOAD.register((be, world) -> {
if (be instanceof SoundEmitter p) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,17 @@
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.custom.ClientCustomAudioUploader;
import io.github.foundationgames.phonos.sound.emitter.SoundEmitter;
import io.github.foundationgames.phonos.sound.emitter.SoundEmitterStorage;
import io.github.foundationgames.phonos.sound.stream.ClientIncomingStreamHandler;
import io.github.foundationgames.phonos.util.PhonosUtil;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientBlockEntityEvents;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientEntityEvents;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents;
import net.fabricmc.fabric.api.client.rendering.v1.ColorProviderRegistry;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.RenderLayer;
Expand All @@ -46,6 +49,7 @@ public void onInitializeClient() {
BlockEntityRendererFactories.register(PhonosBlocks.CONNECTION_HUB_ENTITY, CableOutputBlockEntityRenderer::new);
BlockEntityRendererFactories.register(PhonosBlocks.RADIO_TRANSCEIVER_ENTITY, RadioTransceiverBlockEntityRenderer::new);
BlockEntityRendererFactories.register(PhonosBlocks.RADIO_LOUDSPEAKER_ENTITY, RadioLoudspeakerBlockEntityRenderer::new);
BlockEntityRendererFactories.register(PhonosBlocks.SATELLITE_STATION_ENTITY, CableOutputBlockEntityRenderer::new);

ColorProviderRegistry.BLOCK.register((state, world, pos, tintIndex) ->
world != null && pos != null && state != null ?
Expand All @@ -68,6 +72,11 @@ public void onInitializeClient() {
}
});

ClientPlayConnectionEvents.JOIN.register((handler, sender, client) -> {
ClientIncomingStreamHandler.reset();
ClientCustomAudioUploader.reset();
});

ClientTickEvents.END_WORLD_TICK.register(world -> SoundStorage.getInstance(world).tick(world));

ClientBlockEntityEvents.BLOCK_ENTITY_LOAD.register((be, world) -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityTicker;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.block.entity.SkullBlockEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemUsageContext;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.sound.SoundEvent;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
Expand Down Expand Up @@ -77,9 +80,15 @@ private void emitNote(BlockState state, World world, BlockPos pos) {
var instrument = state.get(INSTRUMENT);
int note = state.get(NOTE);
float pitch = instrument.shouldSpawnNoteParticles() ? getNotePitch(note) : 1;
var sound = instrument.getSound();

if (instrument.hasCustomSound() && world.getBlockEntity(pos.up()) instanceof SkullBlockEntity skull) {
sound = RegistryEntry.of(SoundEvent.of(skull.getNoteBlockSound()));
}

if (instrument.isNotBaseBlock() || world.getBlockState(pos.up()).isAir()) {
SoundStorage.getInstance(world).play(world,
NoteBlockSoundData.create(id, instrument.getSound(), 2, pitch, instrument, note),
NoteBlockSoundData.create(id, sound, 2, pitch, instrument, note),
new SoundEmitterTree(id));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public class PhonosBlocks {
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 final Block SATELLITE_STATION = register(new SatelliteStationBlock(FabricBlockSettings.copy(Blocks.OAK_SLAB)), "satellite_station");

public static BlockEntityType<ElectronicNoteBlockEntity> ELECTRONIC_NOTE_BLOCK_ENTITY = Registry.register(
Registries.BLOCK_ENTITY_TYPE, Phonos.id("electronic_note_block"),
Expand All @@ -34,6 +35,9 @@ public class PhonosBlocks {
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));
public static BlockEntityType<SatelliteStationBlockEntity> SATELLITE_STATION_ENTITY = Registry.register(
Registries.BLOCK_ENTITY_TYPE, Phonos.id("satellite_station"),
BlockEntityType.Builder.create(SatelliteStationBlockEntity::new, SATELLITE_STATION).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
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package io.github.foundationgames.phonos.block;

import io.github.foundationgames.phonos.block.entity.SatelliteStationBlockEntity;
import io.github.foundationgames.phonos.network.PayloadPackets;
import io.github.foundationgames.phonos.util.PhonosUtil;
import net.minecraft.block.*;
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.ItemPlacementContext;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.state.StateManager;
import net.minecraft.state.property.BooleanProperty;
import net.minecraft.state.property.Properties;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;

public class SatelliteStationBlock extends HorizontalFacingBlock implements BlockEntityProvider {
private static final VoxelShape SHAPE = createCuboidShape(0, 0, 0, 16, 7, 16);
private static final BooleanProperty POWERED = Properties.POWERED;

public SatelliteStationBlock(Settings settings) {
super(settings);
setDefaultState(getDefaultState().with(FACING, Direction.NORTH).with(POWERED, false));
}

@Override
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
var side = hit.getSide();
var facing = state.get(FACING);

if (side == Direction.DOWN || side == Direction.UP) {
return ActionResult.PASS;
}

if (player.canModifyBlocks() && world.getBlockEntity(pos) instanceof SatelliteStationBlockEntity be) {
if (!world.isClient()) {
if (PhonosUtil.holdingAudioCable(player)) {
return ActionResult.PASS;
}

if (side != facing) {
if (be.outputs.tryRemoveConnection(world, hit, !player.isCreative())) {
be.sync();
return ActionResult.SUCCESS;
}
} else {
if (player instanceof ServerPlayerEntity sPlayer) {
PayloadPackets.sendOpenSatelliteStationScreen(sPlayer, pos);
}

return ActionResult.CONSUME;
}
} else if (side == facing) {
return ActionResult.SUCCESS;
}
}

return super.onUse(state, world, pos, player, hand, hit);
}

public void neighborUpdate(BlockState state, World world, BlockPos pos, Block sourceBlock, BlockPos sourcePos, boolean notify) {
boolean powered = world.isReceivingRedstonePower(pos);
if (powered != state.get(POWERED)) {
if (!world.isClient() && world.getBlockEntity(pos) instanceof SatelliteStationBlockEntity be) {
if (powered) {
be.play();
} else {
be.stop();
}
}

world.setBlockState(pos, state.with(POWERED, powered), 3);
}
}

@Override
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
if (!newState.isOf(this) && world.getBlockEntity(pos) instanceof SatelliteStationBlockEntity be) {
be.onDestroyed();
}

super.onStateReplaced(state, world, pos, newState, moved);
}

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

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

builder.add(FACING, POWERED);
}

@Override
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return SHAPE;
}

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

@Nullable
@Override
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(World world, BlockState state, BlockEntityType<T> type) {
return PhonosUtil.blockEntityTicker(type, PhonosBlocks.SATELLITE_STATION_ENTITY);
}
}
Loading

0 comments on commit 5f3df26

Please sign in to comment.