diff --git a/gradle.properties b/gradle.properties index afaa8f8..4a78c15 100644 --- a/gradle.properties +++ b/gradle.properties @@ -36,7 +36,7 @@ mod_name=Cog Works Engineering # The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default. mod_license=PolyFormPerimeter-1.0 # The mod version. See https://semver.org/ -mod_version=0.4.1 +mod_version=0.4.2 # The group ID for the mod. It is only important when publishing as an artifact to a Maven repository. # This should match the base package used for the mod sources. # See https://maven.apache.org/guides/mini/guide-naming-conventions.html diff --git a/src/main/java/org/darkar/cog_works/CogWorks.java b/src/main/java/org/darkar/cog_works/CogWorks.java index 804e355..66bd206 100644 --- a/src/main/java/org/darkar/cog_works/CogWorks.java +++ b/src/main/java/org/darkar/cog_works/CogWorks.java @@ -9,6 +9,7 @@ import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent; import net.neoforged.neoforge.common.NeoForge; import net.neoforged.neoforge.event.server.ServerStartingEvent; +import org.darkar.cog_works.net.NetworkHandler; import org.slf4j.Logger; // The value here should match an entry in the META-INF/neoforge.mods.toml file @@ -31,6 +32,9 @@ public CogWorks(IEventBus modEventBus, ModContainer modContainer) { // Register the commonSetup method for modloading modEventBus.addListener(this::commonSetup); + + // Initialize Network Handling + modEventBus.addListener(NetworkHandler::onPayloadHandlersRegister); // Initialize mod registries Registry.initialize(modEventBus); diff --git a/src/main/java/org/darkar/cog_works/item/ProspectingPickItem.java b/src/main/java/org/darkar/cog_works/item/ProspectingPickItem.java index 603838f..ef4f5c6 100644 --- a/src/main/java/org/darkar/cog_works/item/ProspectingPickItem.java +++ b/src/main/java/org/darkar/cog_works/item/ProspectingPickItem.java @@ -2,8 +2,10 @@ import net.minecraft.client.renderer.BlockEntityWithoutLevelRenderer; import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; import net.minecraft.tags.BlockTags; import net.minecraft.tags.TagKey; import net.minecraft.world.InteractionHand; @@ -17,9 +19,11 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.LevelChunk; import net.neoforged.neoforge.common.extensions.IItemExtension; +import net.neoforged.neoforge.network.PacketDistributor; import org.darkar.cog_works.item.component.IsDiggingSample; import org.darkar.cog_works.item.renderer.ProspectingPickItemRenderer; import org.darkar.cog_works.level.chunk.attachment.ChunkSampleSiteMap; +import org.darkar.cog_works.net.payload.client.ClientSampleSiteMapUpdatePayload; import org.darkar.cog_works.utils.enums.SampleSiteRegion; import software.bernie.geckolib.animatable.GeoItem; import software.bernie.geckolib.animatable.SingletonGeoAnimatable; @@ -103,7 +107,7 @@ public boolean canAttackBlock(BlockState pState, Level pLevel, BlockPos pPos, Pl return false; } - public void handleLeftClickBlock(Player player, Level level, BlockPos pos) { + public void handleLeftClickBlock(Player player, Level level, BlockPos pos, Direction face) { if (level instanceof ServerLevel serverLevel) { BlockState blockState = serverLevel.getBlockState(pos); @@ -155,8 +159,13 @@ public void handleLeftClickBlock(Player player, Level level, BlockPos pos) { chunkSampleSiteMap = new ChunkSampleSiteMap(pos, chunkSampleSiteMap.deepPos(), surfaceSiteState, - chunkSampleSiteMap.deepState()); + chunkSampleSiteMap.deepState(), + face, chunkSampleSiteMap.deepFace()); chunk.setData(CHUNK_SAMPLE_SITE_MAP, chunkSampleSiteMap); + PacketDistributor.sendToPlayer((ServerPlayer) player, new ClientSampleSiteMapUpdatePayload( + chunkSampleSiteMap.surfacePos(), chunkSampleSiteMap.deepPos(), + chunkSampleSiteMap.surfaceState(), chunkSampleSiteMap.deepState(), + chunkSampleSiteMap.surfaceFace(), chunkSampleSiteMap.deepFace())); } case DEEP -> { @@ -180,8 +189,13 @@ public void handleLeftClickBlock(Player player, Level level, BlockPos pos) { triggerAnim(player, GeoItem.getOrAssignId(itemStack, serverLevel), "dig_sample_controller", "dig_sample"); chunkSampleSiteMap = new ChunkSampleSiteMap(chunkSampleSiteMap.surfacePos(), pos, - chunkSampleSiteMap.surfaceState(), deepSiteState); + chunkSampleSiteMap.surfaceState(), deepSiteState, + chunkSampleSiteMap.surfaceFace(), face); chunk.setData(CHUNK_SAMPLE_SITE_MAP, chunkSampleSiteMap); + PacketDistributor.sendToPlayer((ServerPlayer) player, new ClientSampleSiteMapUpdatePayload( + chunkSampleSiteMap.surfacePos(), chunkSampleSiteMap.deepPos(), + chunkSampleSiteMap.surfaceState(), chunkSampleSiteMap.deepState(), + chunkSampleSiteMap.surfaceFace(), chunkSampleSiteMap.deepFace())); } } diff --git a/src/main/java/org/darkar/cog_works/item/events/ItemEvents.java b/src/main/java/org/darkar/cog_works/item/events/ItemEvents.java index f2615e3..83b9b8f 100644 --- a/src/main/java/org/darkar/cog_works/item/events/ItemEvents.java +++ b/src/main/java/org/darkar/cog_works/item/events/ItemEvents.java @@ -1,6 +1,7 @@ package org.darkar.cog_works.item.events; import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; @@ -23,6 +24,7 @@ public static void onPlayerLeftClickBlock(PlayerInteractEvent.LeftClickBlock eve Level level = event.getLevel(); Player player = event.getEntity(); BlockPos pos = event.getPos(); + Direction face = event.getFace(); LogicalSide side = event.getSide(); PlayerInteractEvent.LeftClickBlock.Action action = event.getAction(); @@ -31,7 +33,7 @@ public static void onPlayerLeftClickBlock(PlayerInteractEvent.LeftClickBlock eve if (item instanceof ProspectingPickItem) { if (side.isServer()) { if(!player.isCreative() && action == PlayerInteractEvent.LeftClickBlock.Action.START) { - if(!event.isCanceled()) ((ProspectingPickItem) item).handleLeftClickBlock(player, level, pos); + if(!event.isCanceled()) ((ProspectingPickItem) item).handleLeftClickBlock(player, level, pos, face); event.setCanceled(true); } return; diff --git a/src/main/java/org/darkar/cog_works/level/chunk/attachment/ChunkSampleSiteMap.java b/src/main/java/org/darkar/cog_works/level/chunk/attachment/ChunkSampleSiteMap.java index 04801f4..57ef750 100644 --- a/src/main/java/org/darkar/cog_works/level/chunk/attachment/ChunkSampleSiteMap.java +++ b/src/main/java/org/darkar/cog_works/level/chunk/attachment/ChunkSampleSiteMap.java @@ -2,20 +2,40 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; +import io.netty.buffer.ByteBuf; import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; -public record ChunkSampleSiteMap(BlockPos surfacePos, BlockPos deepPos, BlockState surfaceState, BlockState deepState) { +public record ChunkSampleSiteMap(BlockPos surfacePos, BlockPos deepPos, BlockState surfaceState, BlockState deepState + , Direction surfaceFace, Direction deepFace) { public static final ChunkSampleSiteMap DEFAULT = - new ChunkSampleSiteMap(BlockPos.ZERO, BlockPos.ZERO, Blocks.AIR.defaultBlockState(), Blocks.AIR.defaultBlockState()); + new ChunkSampleSiteMap(BlockPos.ZERO, BlockPos.ZERO, Blocks.AIR.defaultBlockState(), + Blocks.AIR.defaultBlockState(), Direction.NORTH, Direction.NORTH); public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( BlockPos.CODEC.fieldOf("surfacePos").forGetter(ChunkSampleSiteMap::surfacePos), BlockPos.CODEC.fieldOf("deepPos").forGetter(ChunkSampleSiteMap::deepPos), BlockState.CODEC.fieldOf("surfaceState").forGetter(ChunkSampleSiteMap::surfaceState), - BlockState.CODEC.fieldOf("deepState").forGetter(ChunkSampleSiteMap::deepState) + BlockState.CODEC.fieldOf("deepState").forGetter(ChunkSampleSiteMap::deepState), + Direction.CODEC.fieldOf("surfaceFace").forGetter(ChunkSampleSiteMap::surfaceFace), + Direction.CODEC.fieldOf("deepFace").forGetter(ChunkSampleSiteMap::deepFace) ).apply(instance, ChunkSampleSiteMap::new) ); + + @SuppressWarnings("deprecation") + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + BlockPos.STREAM_CODEC, ChunkSampleSiteMap::surfacePos, + BlockPos.STREAM_CODEC, ChunkSampleSiteMap::deepPos, + ByteBufCodecs.idMapper(Block.BLOCK_STATE_REGISTRY), ChunkSampleSiteMap::surfaceState, + ByteBufCodecs.idMapper(Block.BLOCK_STATE_REGISTRY), ChunkSampleSiteMap::deepState, + Direction.STREAM_CODEC, ChunkSampleSiteMap::surfaceFace, + Direction.STREAM_CODEC, ChunkSampleSiteMap::deepFace, + ChunkSampleSiteMap::new + ); } diff --git a/src/main/java/org/darkar/cog_works/level/events/ClientLevelEvents.java b/src/main/java/org/darkar/cog_works/level/events/ClientLevelEvents.java new file mode 100644 index 0000000..900857a --- /dev/null +++ b/src/main/java/org/darkar/cog_works/level/events/ClientLevelEvents.java @@ -0,0 +1,32 @@ +package org.darkar.cog_works.level.events; + +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.Camera; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.culling.Frustum; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.client.event.RenderLevelStageEvent; +import org.darkar.cog_works.level.renderer.SampleSiteRenderBehaviour; + +import static org.darkar.cog_works.CogWorks.MOD_ID; + +@EventBusSubscriber(modid = MOD_ID, value = Dist.CLIENT) +public class ClientLevelEvents { + + @SubscribeEvent + public static void onRenderLevelStage(final RenderLevelStageEvent event) { + RenderLevelStageEvent.Stage stage = event.getStage(); + Minecraft minecraft = Minecraft.getInstance(); + if (stage == RenderLevelStageEvent.Stage.AFTER_PARTICLES) { + if (minecraft.player != null) { + Frustum frustum = event.getFrustum(); + PoseStack poseStack = event.getPoseStack(); + Camera camera = event.getCamera(); + SampleSiteRenderBehaviour.render(frustum, poseStack, camera); + + } + } + } +} diff --git a/src/main/java/org/darkar/cog_works/level/events/LevelEvents.java b/src/main/java/org/darkar/cog_works/level/events/LevelEvents.java new file mode 100644 index 0000000..e7a9bf2 --- /dev/null +++ b/src/main/java/org/darkar/cog_works/level/events/LevelEvents.java @@ -0,0 +1,34 @@ +package org.darkar.cog_works.level.events; + +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.chunk.LevelChunk; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.event.level.ChunkWatchEvent; +import net.neoforged.neoforge.network.PacketDistributor; +import org.darkar.cog_works.level.chunk.attachment.ChunkSampleSiteMap; +import org.darkar.cog_works.net.payload.client.ClientSampleSiteMapUpdatePayload; + +import static org.darkar.cog_works.CogWorks.MOD_ID; +import static org.darkar.cog_works.Registry.DataAttachments.CHUNK_SAMPLE_SITE_MAP; + +@EventBusSubscriber(modid = MOD_ID) +public class LevelEvents { + + @SubscribeEvent + public static void onChunkSent(final ChunkWatchEvent.Sent event) { + LevelChunk chunk = event.getChunk(); + ServerLevel serverLevel = event.getLevel(); + ChunkPos pos = chunk.getPos(); + if (chunk.hasAttachments() && chunk.hasData(CHUNK_SAMPLE_SITE_MAP)) { + ChunkSampleSiteMap chunkSampleSiteMap = chunk.getData(CHUNK_SAMPLE_SITE_MAP); + ClientSampleSiteMapUpdatePayload payload = new ClientSampleSiteMapUpdatePayload( + chunkSampleSiteMap.surfacePos(), chunkSampleSiteMap.deepPos(), chunkSampleSiteMap.surfaceState(), + chunkSampleSiteMap.deepState(), chunkSampleSiteMap.surfaceFace(), chunkSampleSiteMap.deepFace() + ); + PacketDistributor.sendToPlayersTrackingChunk(serverLevel, pos, payload); + } + } + +} diff --git a/src/main/java/org/darkar/cog_works/level/events/RenderEvents.java b/src/main/java/org/darkar/cog_works/level/events/RenderEvents.java deleted file mode 100644 index d1929af..0000000 --- a/src/main/java/org/darkar/cog_works/level/events/RenderEvents.java +++ /dev/null @@ -1,121 +0,0 @@ -package org.darkar.cog_works.level.events; - -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexConsumer; -import com.mojang.math.Axis; -import net.minecraft.client.Camera; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.LightTexture; -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.RenderBuffers; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.culling.Frustum; -import net.minecraft.client.renderer.texture.OverlayTexture; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.tags.BlockTags; -import net.minecraft.world.inventory.InventoryMenu; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.AABB; -import net.minecraft.world.phys.BlockHitResult; -import net.minecraft.world.phys.HitResult; -import net.minecraft.world.phys.Vec3; -import net.neoforged.api.distmarker.Dist; -import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.fml.common.EventBusSubscriber; -import net.neoforged.neoforge.client.NeoForgeRenderTypes; -import net.neoforged.neoforge.client.event.RenderLevelStageEvent; -import org.darkar.cog_works.item.ProspectingPickItem; -import org.joml.Matrix4f; - -import static org.darkar.cog_works.CogWorks.MOD_ID; - -@EventBusSubscriber(modid = MOD_ID, value = Dist.CLIENT) -public class RenderEvents { - - private static final ResourceLocation SAMPLE_SITE_TEXTURE_KEY = - new ResourceLocation(MOD_ID, "block/sample_stone_site"); - - @SubscribeEvent - public static void onRenderLevelStage(final RenderLevelStageEvent event) { - RenderLevelStageEvent.Stage stage = event.getStage(); - Minecraft minecraft = Minecraft.getInstance(); - if (stage == RenderLevelStageEvent.Stage.AFTER_PARTICLES) { - - if (minecraft.player != null) { - Frustum frustum = event.getFrustum(); - PoseStack poseStack = event.getPoseStack(); - ItemStack stack = minecraft.player.getMainHandItem(); - if (stack.getItem() instanceof ProspectingPickItem && minecraft.hitResult != null) { - HitResult hitResult = minecraft.hitResult; - if (hitResult.getType() == HitResult.Type.BLOCK) { - BlockHitResult blockHit = (BlockHitResult) hitResult; - BlockPos hitPos = blockHit.getBlockPos(); - BlockState blockState = minecraft.level.getBlockState(hitPos); - Direction face = blockHit.getDirection(); - if(blockState.is(BlockTags.STONE_ORE_REPLACEABLES)) { - boolean isVisible = frustum.isVisible(new AABB(hitPos)); - if(isVisible) { - RenderBuffers buffers = minecraft.renderBuffers(); - MultiBufferSource.BufferSource source = buffers.bufferSource(); - Camera cam = minecraft.gameRenderer.getMainCamera(); - Vec3 camPos = cam.getPosition(); - Vec3 offset = Vec3.atLowerCornerOf(hitPos).subtract(camPos); - RenderType bufferType = NeoForgeRenderTypes.TRANSLUCENT_ON_PARTICLES_TARGET.get(); - poseStack.pushPose(); - poseStack.translate(offset.x, offset.y, offset.z); - poseStack.translate(.5F, .5F, .5F); - switch (face) { - case UP -> poseStack.mulPose(Axis.XP.rotationDegrees(90F)); - case DOWN -> poseStack.mulPose(Axis.XN.rotationDegrees(90F)); - default -> poseStack.mulPose(Axis.YN.rotationDegrees((face.toYRot() + 180F) % 360F)); - } - poseStack.translate(-.5F, -.5F, -.5F); - VertexConsumer textureConsumer = source.getBuffer(bufferType); - TextureAtlasSprite texture = - minecraft.getTextureAtlas(InventoryMenu.BLOCK_ATLAS).apply(SAMPLE_SITE_TEXTURE_KEY); - - Matrix4f quadMatrix = poseStack.last().pose(); - textureConsumer.vertex(quadMatrix, 0, 1, -0.01F) - .color(255, 255, 255, 255) - .uv(texture.getU0(), texture.getV0()) - .overlayCoords(OverlayTexture.NO_OVERLAY) - .uv2(LightTexture.FULL_BRIGHT) - .normal(poseStack.last(), 0, 0, -1) - .endVertex(); - textureConsumer.vertex(quadMatrix, 1, 1, -0.01F) - .color(255, 255, 255, 255) - .uv(texture.getU0(), texture.getV1()) - .overlayCoords(OverlayTexture.NO_OVERLAY) - .uv2(LightTexture.FULL_BRIGHT) - .normal(poseStack.last(), 0, 0, -1) - .endVertex(); - textureConsumer.vertex(quadMatrix, 1, 0, -0.01F) - .color(255, 255, 255, 255) - .uv(texture.getU1(), texture.getV1()) - .overlayCoords(OverlayTexture.NO_OVERLAY) - .uv2(LightTexture.FULL_BRIGHT) - .normal(poseStack.last(), 0, 0, -1) - .endVertex(); - textureConsumer.vertex(quadMatrix, 0, 0, -0.01F) - .color(255, 255, 255, 255) - .uv(texture.getU1(), texture.getV0()) - .overlayCoords(OverlayTexture.NO_OVERLAY) - .uv2(LightTexture.FULL_BRIGHT) - .normal(poseStack.last(), 0, 0, -1) - .endVertex(); - source.endBatch(bufferType); - poseStack.popPose(); - } - } - } - } - - } - } - } -} - diff --git a/src/main/java/org/darkar/cog_works/level/renderer/SampleSiteRenderBehaviour.java b/src/main/java/org/darkar/cog_works/level/renderer/SampleSiteRenderBehaviour.java new file mode 100644 index 0000000..bf04a2d --- /dev/null +++ b/src/main/java/org/darkar/cog_works/level/renderer/SampleSiteRenderBehaviour.java @@ -0,0 +1,105 @@ +package org.darkar.cog_works.level.renderer; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import com.mojang.math.Axis; +import net.minecraft.client.Camera; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.player.LocalPlayer; +import net.minecraft.client.renderer.LightTexture; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderBuffers; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.culling.Frustum; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.inventory.InventoryMenu; +import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; +import net.neoforged.neoforge.client.NeoForgeRenderTypes; +import org.darkar.cog_works.level.chunk.attachment.ChunkSampleSiteMap; +import org.darkar.cog_works.utils.World; +import org.joml.Matrix4f; + +import java.util.List; + +import static org.darkar.cog_works.CogWorks.MOD_ID; +import static org.darkar.cog_works.Registry.DataAttachments.CHUNK_SAMPLE_SITE_MAP; + +public class SampleSiteRenderBehaviour { + + private static final ResourceLocation SAMPLE_SITE_TEXTURE_KEY = new ResourceLocation(MOD_ID, + "block/sample_stone_site"); + + public static void render(Frustum frustum, PoseStack poseStack, Camera cam) { + Minecraft minecraft = Minecraft.getInstance(); + ClientLevel level = minecraft.level; + LocalPlayer player = minecraft.player; + + BlockPos currentPos = player.getOnPos(); + LevelChunk chunk = level.getChunkAt(currentPos); + + List nearbyChunks = World.getNearbyChunks(chunk, 2); + RenderBuffers buffers = minecraft.renderBuffers(); + MultiBufferSource.BufferSource source = buffers.bufferSource(); + Vec3 camPos = cam.getPosition(); + RenderType bufferType = NeoForgeRenderTypes.TRANSLUCENT_ON_PARTICLES_TARGET.get(); + + nearbyChunks.stream().filter( + nearbyChunk -> nearbyChunk.hasAttachments() && nearbyChunk.hasData(CHUNK_SAMPLE_SITE_MAP)).forEach( + nearbyChunk -> { + + ChunkSampleSiteMap chunkSampleSiteMap = nearbyChunk.getData(CHUNK_SAMPLE_SITE_MAP); + boolean isSurfaceVisible = frustum.isVisible(new AABB(chunkSampleSiteMap.surfacePos())); + boolean isDeepVisible = frustum.isVisible(new AABB(chunkSampleSiteMap.deepPos())); + if (!isSurfaceVisible && !isDeepVisible) { + return; + } + + BlockPos pos = isSurfaceVisible ? chunkSampleSiteMap.surfacePos() : chunkSampleSiteMap.deepPos(); + Direction face = isSurfaceVisible ? chunkSampleSiteMap.surfaceFace() : chunkSampleSiteMap.deepFace(); + Vec3 offset = Vec3.atLowerCornerOf(pos).subtract(camPos); + + poseStack.pushPose(); + poseStack.translate(offset.x, offset.y, offset.z); + poseStack.translate(.5F, .5F, .5F); + switch (face) { + case UP -> poseStack.mulPose(Axis.XP.rotationDegrees(90F)); + case DOWN -> poseStack.mulPose(Axis.XN.rotationDegrees(90F)); + default -> poseStack.mulPose(Axis.YN.rotationDegrees((face.toYRot() + 180F) % 360F)); + } + poseStack.translate(-.5F, -.5F, -.5F); + VertexConsumer textureConsumer = source.getBuffer(bufferType); + TextureAtlasSprite texture = minecraft.getTextureAtlas(InventoryMenu.BLOCK_ATLAS).apply( + SAMPLE_SITE_TEXTURE_KEY); + + Matrix4f quadMatrix = poseStack.last().pose(); + textureConsumer.vertex(quadMatrix, 0, 1, -0.01F).color(255, 255, 255, 255).uv(texture.getU0(), + texture.getV0()) + .overlayCoords(OverlayTexture.NO_OVERLAY).uv2(LightTexture.FULL_BRIGHT).normal( + poseStack.last(), 0, 0, -1).endVertex(); + textureConsumer.vertex(quadMatrix, 1, 1, -0.01F).color(255, 255, 255, 255).uv(texture.getU0(), + texture.getV1()) + .overlayCoords(OverlayTexture.NO_OVERLAY).uv2(LightTexture.FULL_BRIGHT).normal( + poseStack.last(), 0, 0, -1).endVertex(); + textureConsumer.vertex(quadMatrix, 1, 0, -0.01F).color(255, 255, 255, 255).uv(texture.getU1(), + texture.getV1()) + .overlayCoords(OverlayTexture.NO_OVERLAY).uv2(LightTexture.FULL_BRIGHT).normal( + poseStack.last(), 0, 0, -1).endVertex(); + textureConsumer.vertex(quadMatrix, 0, 0, -0.01F).color(255, 255, 255, 255).uv(texture.getU1(), + texture.getV0()) + .overlayCoords(OverlayTexture.NO_OVERLAY).uv2(LightTexture.FULL_BRIGHT).normal( + poseStack.last(), 0, 0, -1).endVertex(); + source.endBatch(bufferType); + poseStack.popPose(); + }); + + + } + +} diff --git a/src/main/java/org/darkar/cog_works/net/NetworkHandler.java b/src/main/java/org/darkar/cog_works/net/NetworkHandler.java new file mode 100644 index 0000000..4c39a8d --- /dev/null +++ b/src/main/java/org/darkar/cog_works/net/NetworkHandler.java @@ -0,0 +1,24 @@ +package org.darkar.cog_works.net; + +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent; +import net.neoforged.neoforge.network.registration.HandlerThread; +import net.neoforged.neoforge.network.registration.PayloadRegistrar; +import org.darkar.cog_works.net.payload.client.ClientSampleSiteMapUpdatePayload; + + +public class NetworkHandler { + + private static final String PROTOCOL_VERSION = "1"; + + @SubscribeEvent + public static void onPayloadHandlersRegister(final RegisterPayloadHandlersEvent event) { + final PayloadRegistrar registrar = event.registrar(PROTOCOL_VERSION); + registrar.executesOn(HandlerThread.NETWORK) + .playToClient( + ClientSampleSiteMapUpdatePayload.TYPE, + ClientSampleSiteMapUpdatePayload.STREAM_CODEC, + ClientSampleSiteMapUpdatePayload::handle + ); + } +} diff --git a/src/main/java/org/darkar/cog_works/net/payload/client/ClientSampleSiteMapUpdatePayload.java b/src/main/java/org/darkar/cog_works/net/payload/client/ClientSampleSiteMapUpdatePayload.java new file mode 100644 index 0000000..33e7180 --- /dev/null +++ b/src/main/java/org/darkar/cog_works/net/payload/client/ClientSampleSiteMapUpdatePayload.java @@ -0,0 +1,64 @@ +package org.darkar.cog_works.net.payload.client; + +import io.netty.buffer.ByteBuf; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.neoforged.fml.loading.FMLEnvironment; +import net.neoforged.neoforge.network.handling.IPayloadContext; +import org.darkar.cog_works.level.chunk.attachment.ChunkSampleSiteMap; + +import static org.darkar.cog_works.CogWorks.MOD_ID; +import static org.darkar.cog_works.Registry.DataAttachments.CHUNK_SAMPLE_SITE_MAP; + +public record ClientSampleSiteMapUpdatePayload(BlockPos surfacePos, BlockPos deepPos, BlockState surfaceState, + BlockState deepState, Direction surfaceFace, + Direction deepFace) implements CustomPacketPayload +{ + + public static final CustomPacketPayload.Type TYPE = + new CustomPacketPayload.Type<>(new ResourceLocation(MOD_ID, "update_chunk_sample_site_map")); + + @SuppressWarnings("deprecation") + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + BlockPos.STREAM_CODEC, ClientSampleSiteMapUpdatePayload::surfacePos, BlockPos.STREAM_CODEC, + ClientSampleSiteMapUpdatePayload::deepPos, ByteBufCodecs.idMapper(Block.BLOCK_STATE_REGISTRY), + ClientSampleSiteMapUpdatePayload::surfaceState, ByteBufCodecs.idMapper(Block.BLOCK_STATE_REGISTRY), + ClientSampleSiteMapUpdatePayload::deepState, Direction.STREAM_CODEC, + ClientSampleSiteMapUpdatePayload::surfaceFace, Direction.STREAM_CODEC, + ClientSampleSiteMapUpdatePayload::deepFace, ClientSampleSiteMapUpdatePayload::new); + + public static void handle(final ClientSampleSiteMapUpdatePayload data, final IPayloadContext ctx) { + + ctx.enqueueWork(() -> { + if (FMLEnvironment.dist.isClient()) { + Player player = ctx.player(); + Level level = player.level(); + BlockPos surfacePos = data.surfacePos(); + BlockPos deepPos = data.deepPos(); + BlockState surfaceState = data.surfaceState(); + BlockState deepState = data.deepState(); + Direction surfaceFace = data.surfaceFace(); + Direction deepFace = data.deepFace(); + + level.getChunk(surfacePos).setData(CHUNK_SAMPLE_SITE_MAP, + new ChunkSampleSiteMap(surfacePos, deepPos, surfaceState, deepState, + surfaceFace, deepFace)); + + } + }); + + } + + @Override + public Type type() { + return TYPE; + } +} diff --git a/src/main/java/org/darkar/cog_works/utils/World.java b/src/main/java/org/darkar/cog_works/utils/World.java new file mode 100644 index 0000000..a1288f7 --- /dev/null +++ b/src/main/java/org/darkar/cog_works/utils/World.java @@ -0,0 +1,32 @@ +package org.darkar.cog_works.utils; + +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.chunk.LevelChunk; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; + +public class World { + + public static List getNearbyChunks(LevelChunk chunk) { + return getNearbyChunks(chunk, 8); + } + + public static List getNearbyChunks(LevelChunk chunk, int radius) { + List chunks = new ArrayList<>(); + chunks.add(chunk); + Level level = chunk.getLevel(); + ChunkPos chunkPos = chunk.getPos(); + + Stream chunkPosStream = ChunkPos.rangeClosed(chunkPos, radius); + + chunkPosStream.filter((pos) -> !chunkPos.equals(pos)).forEach(pos -> { + LevelChunk nearbyChunk = level.getChunk(pos.x, pos.z); + chunks.add(nearbyChunk); + }); + + return chunks; + } +}