From ae75e48c01be50177406bb80cafa322240b4b9a6 Mon Sep 17 00:00:00 2001 From: Christian Knaapen Date: Sun, 22 Jan 2023 03:29:37 +0100 Subject: [PATCH] Added sounds and renewing randomizer bag at right times. Added text with instruction under actionbar while placing/breaking. --- .../render/BlockPreviews.java | 13 +- .../render/RenderHandler.java | 52 ++++++-- .../systems/BuilderChain.java | 118 ++++++++++++------ .../systems/ServerBlockPlacer.java | 2 +- .../utilities/BlockEntry.java | 2 +- 5 files changed, 127 insertions(+), 60 deletions(-) diff --git a/src/main/java/nl/requios/effortlessbuilding/render/BlockPreviews.java b/src/main/java/nl/requios/effortlessbuilding/render/BlockPreviews.java index 51a3170..903043e 100644 --- a/src/main/java/nl/requios/effortlessbuilding/render/BlockPreviews.java +++ b/src/main/java/nl/requios/effortlessbuilding/render/BlockPreviews.java @@ -1,5 +1,6 @@ package nl.requios.effortlessbuilding.render; +import net.minecraft.network.chat.Component; import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundSource; import net.minecraft.world.level.block.SoundType; @@ -72,7 +73,7 @@ public class BlockPreviews { if (blocks.size() == 0) return; - var coordinates = blocks.stream().map(block -> block.blockPos).toList(); + var coordinates = EffortlessBuildingClient.BUILDER_CHAIN.getCoordinates(); //Dont fade out the outline if we are still determining where to place //Every outline with same ID will not fade out (because it gets replaced) @@ -131,7 +132,8 @@ public class BlockPreviews { dimensions = dimensions.substring(0, dimensions.length() - 1); if (dimensions.length() > 1) dimensions += ")"; - EffortlessBuilding.log(player, blocks.size() + " blocks " + dimensions, true); + String msg = blocks.size() + " blocks " + dimensions; + EffortlessBuilding.log(player, msg, true); } } @@ -187,9 +189,6 @@ public class BlockPreviews { var blockPos = blockEntry.blockPos; var blockState = blockEntry.blockState; - if (breaking) { - blockState = Minecraft.getInstance().level.getBlockState(blockPos); - } float scale = 0.5f; float alpha = 0.7f; @@ -252,7 +251,7 @@ public class BlockPreviews { if (!ClientConfig.visuals.showBlockPreviews.get()) return; if (blocks.size() <= 1 || blocks.size() > ClientConfig.visuals.maxBlockPreviews.get()) return; - placedBlocksList.add(new PlacedBlocksEntry(ClientEvents.ticksInGame, false, blocks)); + placedBlocksList.add(new PlacedBlocksEntry(ClientEvents.ticksInGame, false, new ArrayList<>(blocks))); CreateClient.OUTLINER.keep(blocks.get(0).blockPos, CommonConfig.visuals.appearAnimationLength.get()); } @@ -261,7 +260,7 @@ public class BlockPreviews { if (!ClientConfig.visuals.showBlockPreviews.get()) return; if (blocks.size() <= 1 || blocks.size() > ClientConfig.visuals.maxBlockPreviews.get()) return; - placedBlocksList.add(new PlacedBlocksEntry(ClientEvents.ticksInGame, true, blocks)); + placedBlocksList.add(new PlacedBlocksEntry(ClientEvents.ticksInGame, true, new ArrayList<>(blocks))); CreateClient.OUTLINER.keep(blocks.get(0).blockPos, CommonConfig.visuals.breakAnimationLength.get()); } diff --git a/src/main/java/nl/requios/effortlessbuilding/render/RenderHandler.java b/src/main/java/nl/requios/effortlessbuilding/render/RenderHandler.java index 42513da..4406095 100644 --- a/src/main/java/nl/requios/effortlessbuilding/render/RenderHandler.java +++ b/src/main/java/nl/requios/effortlessbuilding/render/RenderHandler.java @@ -1,29 +1,24 @@ package nl.requios.effortlessbuilding.render; +import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.BufferBuilder; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.blaze3d.vertex.VertexConsumer; +import net.minecraft.ChatFormatting; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; +import net.minecraft.network.chat.Component; import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.phys.BlockHitResult; -import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.client.event.RenderGuiEvent; import net.minecraftforge.client.event.RenderLevelStageEvent; -import net.minecraftforge.event.TickEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod.EventBusSubscriber; -import nl.requios.effortlessbuilding.ClientEvents; import nl.requios.effortlessbuilding.EffortlessBuildingClient; -import nl.requios.effortlessbuilding.buildmode.BuildModeEnum; import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; -import nl.requios.effortlessbuilding.compatibility.CompatHelper; -import nl.requios.effortlessbuilding.utilities.SurvivalHelper; +import nl.requios.effortlessbuilding.systems.BuilderChain; /*** * Main render class for Effortless Building @@ -51,6 +46,43 @@ public class RenderHandler { ModifierRenderer.render(ms, buffer, modifierSettings); ms.popPose(); + + renderSubText(ms); + } + + @SubscribeEvent + public static void onRenderGuiEvent(RenderGuiEvent event) { + renderSubText(event.getPoseStack()); + } + + private static final ChatFormatting highlightColor = ChatFormatting.BLUE; + private static final ChatFormatting normalColor = ChatFormatting.WHITE; + private static final Component placingText = Component.literal( + normalColor + "Left-click to " + highlightColor + "cancel, " + + normalColor + "Right-click to " + highlightColor + "place"); + + private static final Component breakingText = Component.literal( + normalColor + "Left-click to " + highlightColor + "break, " + + normalColor + "Right-click to " + highlightColor + "cancel"); + + private static void renderSubText(PoseStack ms) { + var state = EffortlessBuildingClient.BUILDER_CHAIN.getState(); + if (state == BuilderChain.State.IDLE) return; + + var text = state == BuilderChain.State.PLACING ? placingText : breakingText; + + int screenWidth = Minecraft.getInstance().getWindow().getGuiScaledWidth(); + int screenHeight = Minecraft.getInstance().getWindow().getGuiScaledHeight(); + var font = Minecraft.getInstance().font; + + ms.pushPose(); + ms.translate((double)(screenWidth / 2), (double)(screenHeight - 54), 0.0D); + RenderSystem.enableBlend(); + RenderSystem.defaultBlendFunc(); + int l = font.width(text); + font.drawShadow(ms, text, (float)(-l / 2), -4.0F, 0xffffffff); + RenderSystem.disableBlend(); + ms.popPose(); } protected static VertexConsumer beginLines(MultiBufferSource.BufferSource renderTypeBuffer) { diff --git a/src/main/java/nl/requios/effortlessbuilding/systems/BuilderChain.java b/src/main/java/nl/requios/effortlessbuilding/systems/BuilderChain.java index abdd86c..c848459 100644 --- a/src/main/java/nl/requios/effortlessbuilding/systems/BuilderChain.java +++ b/src/main/java/nl/requios/effortlessbuilding/systems/BuilderChain.java @@ -5,10 +5,12 @@ import net.minecraft.client.player.LocalPlayer; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.sounds.SoundEvent; +import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.level.block.Block; @@ -21,14 +23,12 @@ import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import nl.requios.effortlessbuilding.ClientEvents; import nl.requios.effortlessbuilding.EffortlessBuildingClient; -import nl.requios.effortlessbuilding.buildmodifier.BuildModifiers; import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.compatibility.CompatHelper; import nl.requios.effortlessbuilding.item.AbstractRandomizerBagItem; import nl.requios.effortlessbuilding.network.PacketHandler; import nl.requios.effortlessbuilding.network.ServerBreakBlocksPacket; import nl.requios.effortlessbuilding.network.ServerPlaceBlocksPacket; -import nl.requios.effortlessbuilding.render.BlockPreviews; import nl.requios.effortlessbuilding.utilities.BlockEntry; import nl.requios.effortlessbuilding.utilities.ReachHelper; import nl.requios.effortlessbuilding.utilities.SurvivalHelper; @@ -43,7 +43,9 @@ import java.util.List; public class BuilderChain { private final List blocks = new ArrayList<>(); + private final List coordinates = new ArrayList<>(); private int soundTime = 0; + private Item previousHeldItem; public enum State { IDLE, @@ -81,6 +83,7 @@ public class BuilderChain { if (!blocks.isEmpty()) { EffortlessBuildingClient.BLOCK_PREVIEWS.onBlocksPlaced(blocks); + playSoundIfFurtherThanNormal(player, blocks.get(0), false); PacketHandler.INSTANCE.sendToServer(new ServerPlaceBlocksPacket(blocks)); } } @@ -111,12 +114,14 @@ public class BuilderChain { if (!blocks.isEmpty()) { EffortlessBuildingClient.BLOCK_PREVIEWS.onBlocksBroken(blocks); + playSoundIfFurtherThanNormal(player, blocks.get(0), true); PacketHandler.INSTANCE.sendToServer(new ServerBreakBlocksPacket(blocks)); } } } public void onTick() { + var previousCoordinates = new ArrayList<>(coordinates); blocks.clear(); var mc = Minecraft.getInstance(); @@ -127,6 +132,7 @@ public class BuilderChain { var itemStack = player.getItemInHand(InteractionHand.MAIN_HAND); boolean blockInHand = CompatHelper.isItemBlockProxy(itemStack); + //Cancel placing as soon as we aren't holding a block anymore // if (!blockInHand && state == State.PLACING) { // state = State.IDLE; // } @@ -144,33 +150,46 @@ public class BuilderChain { EffortlessBuildingClient.BUILD_MODES.findCoordinates(blocks, player, buildMode); EffortlessBuildingClient.BUILD_MODIFIERS.findCoordinates(blocks, player, modifierSettings); - if (blockInHand && state != State.BREAKING) - findBlockStates(player, itemStack); + removeDuplicateCoordinates(); - //Check if they are different -// if (!BuildModifiers.compareCoordinates(previousCoordinates, newCoordinates)) { -// -// //Renew randomness of randomizer bag -// AbstractRandomizerBagItem.renewRandomness(); -// -// //Play sound (max once every tick) -// if (blocks.size() > 1 && blockStates.size() > 1 && soundTime < ClientEvents.ticksInGame) { -// soundTime = ClientEvents.ticksInGame; -// -// var firstBlockState = blocks.get(0).blockState; -// if (firstBlockState != null) { -// SoundType soundType = firstBlockState.getBlock().getSoundType(firstBlockState, player.level, -// blocks.get(0).blockPos, player); -// SoundEvent soundEvent = state == BuilderChain.State.BREAKING ? soundType.getBreakSound() : soundType.getPlaceSound(); -// player.level.playSound(player, player.blockPosition(), soundEvent, SoundSource.BLOCKS, 0.3f, 0.8f); -// } -// } -// } + coordinates.clear(); + for (BlockEntry blockEntry : blocks) { + coordinates.add(blockEntry.blockPos); + } + + findBlockStates(player, itemStack); + + //Check if any changes are made + if (previousHeldItem != itemStack.getItem() || !previousCoordinates.equals(coordinates)) { + onBlocksChanged(player); + } + + previousHeldItem = itemStack.getItem(); + } + + private void onBlocksChanged(Player player) { + + //Renew randomness of randomizer bag + AbstractRandomizerBagItem.renewRandomness(); + + //Play sound (max once every tick) + if (blocks.size() > 1 && soundTime < ClientEvents.ticksInGame) { + soundTime = ClientEvents.ticksInGame; + + var firstBlockState = blocks.get(0).blockState; + if (firstBlockState != null) { + SoundType soundType = firstBlockState.getBlock().getSoundType(firstBlockState, player.level, blocks.get(0).blockPos, player); + SoundEvent soundEvent = state == BuilderChain.State.BREAKING ? soundType.getBreakSound() : soundType.getPlaceSound(); + player.level.playSound(player, player.blockPosition(), soundEvent, SoundSource.BLOCKS, 0.3f, 0.8f); + } + } } public void cancel() { + if (state == State.IDLE) return; state = State.IDLE; EffortlessBuildingClient.BUILD_MODES.onCancel(); + Minecraft.getInstance().player.playSound(SoundEvents.UI_TOAST_OUT, 4, 1); } private BlockEntry findStartPosition(Player player, BlockHitResult lookingAt) { @@ -210,7 +229,28 @@ public class BuilderChain { return blockEntry; } - private void findBlockStates(LocalPlayer player, ItemStack itemStack) { + private void removeDuplicateCoordinates() { + for (int i = 0; i < blocks.size(); i++) { + BlockEntry blockEntry = blocks.get(i); + for (int j = i + 1; j < blocks.size(); j++) { + BlockEntry blockEntry2 = blocks.get(j); + if (blockEntry.blockPos.equals(blockEntry2.blockPos)) { + blocks.remove(j); + j--; + } + } + } + } + + private void findBlockStates(Player player, ItemStack itemStack) { + + if (state == State.BREAKING) { + for (BlockEntry blockEntry : blocks) { + blockEntry.blockState = Minecraft.getInstance().level.getBlockState(blockEntry.blockPos); + } + return; + } + if (itemStack.getItem() instanceof BlockItem) { for (BlockEntry blockEntry : blocks) { @@ -219,6 +259,7 @@ public class BuilderChain { } else if (CompatHelper.isItemBlockProxy(itemStack, false)) { + AbstractRandomizerBagItem.resetRandomness(); for (BlockEntry blockEntry : blocks) { ItemStack itemBlockStack = CompatHelper.getItemBlockFromStack(itemStack); if (itemBlockStack == null || itemBlockStack.isEmpty()) continue; @@ -234,26 +275,17 @@ public class BuilderChain { return block.getStateForPlacement(new BlockPlaceContext(player, hand, blockItemStack, blockHitResult)); } - private void playPlacingSoundIfFurtherThanNormal(Player player, Vec3 location, BlockItem blockItem) { + private void playSoundIfFurtherThanNormal(Player player, BlockEntry blockEntry, boolean breaking) { - if ((location.subtract(player.getEyePosition(1f))).lengthSqr() > 25f) { - BlockPos blockPos = new BlockPos(location); - BlockState state = blockItem.getBlock().defaultBlockState(); - SoundType soundType = state.getBlock().getSoundType(state, player.level, blockPos, player); - player.level.playSound(player, player.blockPosition(), soundType.getPlaceSound(), SoundSource.BLOCKS, - 0.4f, soundType.getPitch()); - } - } + if (Minecraft.getInstance().hitResult != null && Minecraft.getInstance().hitResult.getType() == HitResult.Type.BLOCK) + return; - private void playBreakingSoundIfFurtherThanNormal(Player player, Vec3 location) { + if (blockEntry == null || blockEntry.blockState == null) + return; - if ((location.subtract(player.getEyePosition(1f))).lengthSqr() > 25f) { - BlockPos blockPos = new BlockPos(location); - BlockState state = player.level.getBlockState(blockPos); - SoundType soundtype = state.getBlock().getSoundType(state, player.level, blockPos, player); - player.level.playSound(player, player.blockPosition(), soundtype.getBreakSound(), SoundSource.BLOCKS, - 0.4f, soundtype.getPitch()); - } + SoundType soundType = blockEntry.blockState.getBlock().getSoundType(blockEntry.blockState, player.level, blockEntry.blockPos, player); + SoundEvent soundEvent = breaking ? soundType.getBreakSound() : soundType.getPlaceSound(); + player.level.playSound(player, player.blockPosition(), soundEvent, SoundSource.BLOCKS, 0.6f, soundType.getPitch()); } private void swingHand(Player player, InteractionHand hand) { @@ -267,4 +299,8 @@ public class BuilderChain { public List getBlocks() { return blocks; } + + public List getCoordinates() { + return coordinates; + } } diff --git a/src/main/java/nl/requios/effortlessbuilding/systems/ServerBlockPlacer.java b/src/main/java/nl/requios/effortlessbuilding/systems/ServerBlockPlacer.java index 6754f9e..c1d39df 100644 --- a/src/main/java/nl/requios/effortlessbuilding/systems/ServerBlockPlacer.java +++ b/src/main/java/nl/requios/effortlessbuilding/systems/ServerBlockPlacer.java @@ -45,7 +45,7 @@ public class ServerBlockPlacer { if (!world.isLoaded(block.blockPos) || world.isEmptyBlock(block.blockPos)) return; isPlacingOrBreakingBlocks = true; - BlockHelper.destroyBlockAs(world, block.blockPos, player, player.getMainHandItem(), 1.0f, stack -> { + BlockHelper.destroyBlockAs(world, block.blockPos, player, player.getMainHandItem(), 0f, stack -> { if (!player.isCreative()) { ItemHandlerHelper.giveItemToPlayer(player, stack); } diff --git a/src/main/java/nl/requios/effortlessbuilding/utilities/BlockEntry.java b/src/main/java/nl/requios/effortlessbuilding/utilities/BlockEntry.java index c24a6d9..6d0c40e 100644 --- a/src/main/java/nl/requios/effortlessbuilding/utilities/BlockEntry.java +++ b/src/main/java/nl/requios/effortlessbuilding/utilities/BlockEntry.java @@ -8,6 +8,7 @@ import net.minecraft.world.level.block.Rotation; import net.minecraft.world.level.block.state.BlockState; import java.util.BitSet; +import java.util.Objects; public class BlockEntry { public final BlockPos blockPos; @@ -56,5 +57,4 @@ public class BlockEntry { block.itemStack = buf.readItem(); return block; } - }