diff --git a/src/main/java/com/gregtechceu/gtceu/api/blockentity/PipeBlockEntity.java b/src/main/java/com/gregtechceu/gtceu/api/blockentity/PipeBlockEntity.java index 0b65acbfab5..b4772f50d2a 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/blockentity/PipeBlockEntity.java +++ b/src/main/java/com/gregtechceu/gtceu/api/blockentity/PipeBlockEntity.java @@ -255,8 +255,7 @@ public void setConnection(Direction side, boolean connected, boolean fromNeighbo if (cover != null && cover.canPipePassThrough()) return; } - connections = withSideConnection(connections, side, connected); - syncDataHolder.markClientSyncFieldDirty("connections"); + setConnections(withSideConnection(connections, side, connected)); updateNetworkConnection(side, connected); // notify neighbor of change so Auto Output updates its ticking status getLevel().neighborChanged(getBlockPos().relative(side), getPipeBlock(), getBlockPos()); diff --git a/src/main/java/com/gregtechceu/gtceu/client/ClientProxy.java b/src/main/java/com/gregtechceu/gtceu/client/ClientProxy.java index 6fc9be86508..bb9a4ee089d 100644 --- a/src/main/java/com/gregtechceu/gtceu/client/ClientProxy.java +++ b/src/main/java/com/gregtechceu/gtceu/client/ClientProxy.java @@ -13,6 +13,7 @@ import com.gregtechceu.gtceu.client.model.machine.MachineModelLoader; import com.gregtechceu.gtceu.client.model.pipe.PipeModel; import com.gregtechceu.gtceu.client.model.pipe.PipeModelLoader; +import com.gregtechceu.gtceu.client.particle.GTParticleManager; import com.gregtechceu.gtceu.client.particle.HazardParticle; import com.gregtechceu.gtceu.client.particle.MufflerParticle; import com.gregtechceu.gtceu.client.renderer.block.MaterialBlockRenderer; @@ -65,6 +66,7 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.Item; import net.minecraftforge.client.event.*; +import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.eventbus.api.EventPriority; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; @@ -99,6 +101,8 @@ public static void init() { } initializeDynamicRenders(); ModelEventHelper.initInternalAssetReloadListeners(); + + MinecraftForge.EVENT_BUS.register(GTParticleManager.INSTANCE); } @SubscribeEvent diff --git a/src/main/java/com/gregtechceu/gtceu/client/bloom/BloomRenderer.java b/src/main/java/com/gregtechceu/gtceu/client/bloom/BloomRenderer.java index 56ca88d86ec..733b646923d 100644 --- a/src/main/java/com/gregtechceu/gtceu/client/bloom/BloomRenderer.java +++ b/src/main/java/com/gregtechceu/gtceu/client/bloom/BloomRenderer.java @@ -140,9 +140,7 @@ static void processPostEffect(float partialTicks, ProfilerFiller profilerFiller) mainTarget.bindWrite(false); RenderSystem.enableBlend(); - RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, - GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, - GlStateManager.SourceFactor.ZERO, GlStateManager.DestFactor.ONE); + RenderSystem.blendFunc(GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO); BLOOM_TARGET.blitToScreen(mainTarget.viewWidth, mainTarget.viewHeight, false); BLOOM_TARGET.unbindRead(); @@ -222,6 +220,9 @@ public static boolean enabled() { private static void drawBlockBloom(Camera camera, PoseStack poseStack, Frustum frustum, Matrix4f projectionMatrix, LevelRenderer levelRenderer, ProfilerFiller profilerFiller) { + // re-setup in case someone touched-a my spaghetti + GTRenderTypes.bloom().setupRenderState(); + Vec3 camPos = camera.getPosition(); profilerFiller.push("safe_mode"); diff --git a/src/main/java/com/gregtechceu/gtceu/client/particle/GTOverheatParticle.java b/src/main/java/com/gregtechceu/gtceu/client/particle/GTOverheatParticle.java index b3e77131720..d79073594b1 100644 --- a/src/main/java/com/gregtechceu/gtceu/client/particle/GTOverheatParticle.java +++ b/src/main/java/com/gregtechceu/gtceu/client/particle/GTOverheatParticle.java @@ -1,6 +1,5 @@ package com.gregtechceu.gtceu.client.particle; -import com.gregtechceu.gtceu.api.GTValues; import com.gregtechceu.gtceu.client.bloom.EffectRenderContext; import com.gregtechceu.gtceu.client.bloom.IRenderSetup; import com.gregtechceu.gtceu.client.bloom.particle.GTBloomParticle; @@ -8,27 +7,24 @@ import com.gregtechceu.gtceu.client.util.RenderUtil; import com.gregtechceu.gtceu.common.blockentity.CableBlockEntity; +import net.minecraft.client.renderer.GameRenderer; import net.minecraft.core.BlockPos; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.world.phys.AABB; -import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; +import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.*; -import org.jetbrains.annotations.Nullable; - -import java.util.List; /** * @author brachy84 */ public class GTOverheatParticle extends GTBloomParticle { - public static final int TEMPERATURE_CUTOFF = 400; - /** * Source */ @@ -144,72 +140,60 @@ public static int getBlackBodyColor(int temperature) { private final CableBlockEntity blockEntity; - protected final int meltTemp; - protected int temperature = 293; - protected VoxelShape pipeBoxes; - protected boolean insulated; + private final int meltTemp; + private int temperature; + private final boolean insulated; + + private VoxelShape pipeShape; + private AABB pipeBounds; - protected float alpha = 0; - protected int color = blackBodyColors[0]; + private float alpha = 0.0f; + private int color = blackBodyColors[0]; - public GTOverheatParticle(CableBlockEntity blockEntity, int meltTemp, VoxelShape pipeBoxes, boolean insulated) { + public GTOverheatParticle(CableBlockEntity blockEntity, int meltTemp, boolean insulated) { super(blockEntity.getBlockPos().getX(), blockEntity.getBlockPos().getY(), blockEntity.getBlockPos().getZ()); this.blockEntity = blockEntity; this.meltTemp = meltTemp; - this.pipeBoxes = pipeBoxes; - updatePipeBoxes(pipeBoxes); + this.setTemperature(blockEntity.getTemperature()); this.insulated = insulated; + + this.pipeShape = blockEntity.getBlockState().getVisualShape(blockEntity.getLevel(), blockEntity.getBlockPos(), + CollisionContext.empty()); + this.pipeBounds = pipeShape.bounds().inflate(0.001).move(posX, posY, posZ); } public void setTemperature(int temperature) { this.temperature = temperature; - if (temperature <= 293 || temperature > meltTemp) { + if (temperature <= blockEntity.getDefaultTemp() || temperature > meltTemp) { setExpired(); return; } - if (temperature < 500) { - alpha = 0f; + if (temperature < 300) { + alpha = 0.0f; + } else if (temperature < 600) { + alpha = 0.16f * (temperature - 300f) / 300f; } else if (temperature < 1000) { - alpha = (temperature - 500f) / 500f; - alpha *= 0.8f; + alpha = 0.8f * (temperature - 500f) / 500f; } else { alpha = 0.8f; } color = getBlackBodyColor(temperature); } - public void updatePipeBoxes(VoxelShape pipeBoxes) { - List boxes = pipeBoxes.toAabbs(); - this.pipeBoxes = boxes.stream() - .map(aabb -> aabb.inflate(0.001)) - .map(Shapes::create) - .reduce(Shapes.empty(), Shapes::or) - .optimize(); - } - @Override public void onUpdate() { + // if this isn't the block entity's particle, remove both if (blockEntity.isRemoved() || !blockEntity.isParticleAlive()) { setExpired(); blockEntity.killParticle(); return; } + // update pipeShape every tick so it doesn't desync if the pipe is disconnected + pipeShape = blockEntity.getBlockState().getVisualShape(blockEntity.getLevel(), blockEntity.getBlockPos(), + CollisionContext.empty()); + pipeBounds = pipeShape.bounds().inflate(0.001).move(posX, posY, posZ); - if (temperature <= TEMPERATURE_CUTOFF || temperature > meltTemp) { - setExpired(); - return; - } - if (temperature < 500) { - alpha = 0f; - } else if (temperature < 1000) { - alpha = (temperature - 500f) / 500f; - alpha *= 0.8f; - } else { - alpha = 0.8f; - } - color = getBlackBodyColor(temperature); - - if (GTValues.RNG.nextFloat() < 0.04) { + if (temperature > 400 && blockEntity.getLevel().random.nextFloat() < 0.04f) { spawnSmoke(); } } @@ -227,8 +211,8 @@ private void spawnSmoke() { @Override public String toString() { return "GTOverheatParticle{" + - "tileEntity=" + blockEntity + - ", pipeBoxes=" + pipeBoxes + + "blockEntity=" + blockEntity + + ", pipeShape=" + pipeShape + ", insulated=" + insulated + ", alpha=" + alpha + ", color=" + color + @@ -236,26 +220,32 @@ public String toString() { } @Override - public @Nullable IRenderSetup getRenderSetup() { - return SETUP; + public boolean shouldRender(EffectRenderContext context) { + return this.shouldRenderBloomEffect(context); } @Override - public boolean shouldRender(EffectRenderContext context) { + public boolean shouldRenderBloomEffect(EffectRenderContext context) { if (this.insulated) return false; - for (AABB cuboid : pipeBoxes.toAabbs()) { - if (!context.frustum().isVisible(cuboid.move(posX, posY, posZ))) { - return false; - } - } - return true; + return context.frustum().isVisible(pipeBounds); + } + + @Override + public IRenderSetup getRenderSetup() { + return NO_BLOOM_SETUP; + } + + @Override + protected IRenderSetup getBloomRenderSetup() { + return BLOOM_SETUP; } @Override - protected @Nullable IRenderSetup getBloomRenderSetup() { - return SETUP; + public void renderParticle(PoseStack poseStack, BufferBuilder buffer, EffectRenderContext context) { + renderBloomEffect(poseStack, buffer, context); } + @Override public void renderBloomEffect(PoseStack poseStack, BufferBuilder buffer, EffectRenderContext context) { float red = ((color >> 16) & 0xFF) / 255f; float green = ((color >> 8) & 0xFF) / 255f; @@ -263,19 +253,27 @@ public void renderBloomEffect(PoseStack poseStack, BufferBuilder buffer, EffectR poseStack.pushPose(); poseStack.translate(posX, posY, posZ); - for (AABB cuboid : pipeBoxes.toAabbs()) { - RenderBufferHelper.renderColorCube(poseStack, buffer, cuboid, red, green, blue, alpha, true); - } + pipeShape.forAllBoxes((x1, y1, z1, x2, y2, z2) -> { + RenderBufferHelper.renderColorCube(poseStack, buffer, + (float) x1 - 0.001f, (float) y1 - 0.001f, (float) z1 - 0.001f, + (float) x2 + 0.001f, (float) y2 + 0.001f, (float) z2 + 0.001f, + red, green, blue, alpha, true); + }); poseStack.popPose(); } - private static final IRenderSetup SETUP = new IRenderSetup() { + private static final IRenderSetup NO_BLOOM_SETUP = new IRenderSetup() { @Override @OnlyIn(Dist.CLIENT) public void preDraw(BufferBuilder buffer) { - RenderSystem.setShaderColor(1, 1, 1, 1); RenderSystem.enableBlend(); + RenderSystem.blendFuncSeparate( + GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, + GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); + RenderSystem.setShader(GameRenderer::getPositionColorShader); + RenderSystem.setShaderColor(1, 1, 1, 1); + buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); } @@ -284,6 +282,26 @@ public void preDraw(BufferBuilder buffer) { public void postDraw(BufferBuilder buffer) { BufferUploader.drawWithShader(buffer.end()); RenderSystem.disableBlend(); + RenderSystem.defaultBlendFunc(); + } + }; + + private static final IRenderSetup BLOOM_SETUP = new IRenderSetup() { + + @Override + @OnlyIn(Dist.CLIENT) + public void preDraw(BufferBuilder buffer) { + RenderSystem.disableBlend(); + RenderSystem.setShader(GameRenderer::getPositionColorShader); + RenderSystem.setShaderColor(1, 1, 1, 1); + + buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); + } + + @Override + @OnlyIn(Dist.CLIENT) + public void postDraw(BufferBuilder buffer) { + BufferUploader.drawWithShader(buffer.end()); } }; } diff --git a/src/main/java/com/gregtechceu/gtceu/client/particle/GTParticleManager.java b/src/main/java/com/gregtechceu/gtceu/client/particle/GTParticleManager.java index cf2c5ae5380..e1a8ce45cdf 100644 --- a/src/main/java/com/gregtechceu/gtceu/client/particle/GTParticleManager.java +++ b/src/main/java/com/gregtechceu/gtceu/client/particle/GTParticleManager.java @@ -8,17 +8,14 @@ import net.minecraft.client.Camera; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.renderer.culling.Frustum; -import net.minecraft.world.entity.Entity; -import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.client.event.ClientPlayerNetworkEvent; import net.minecraftforge.client.event.CustomizeGuiOverlayEvent; import net.minecraftforge.client.event.RenderLevelStageEvent; +import net.minecraftforge.event.TickEvent; import net.minecraftforge.event.level.LevelEvent; +import net.minecraftforge.eventbus.api.EventPriority; import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; -import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.BufferBuilder; import com.mojang.blaze3d.vertex.PoseStack; @@ -31,16 +28,17 @@ /** * Singleton class responsible for managing, updating and rendering {@link GTParticle} instances. */ -@Mod.EventBusSubscriber(modid = GTCEu.MOD_ID, value = Dist.CLIENT) -public class GTParticleManager { +public final class GTParticleManager { public static final GTParticleManager INSTANCE = new GTParticleManager(); - private final Map<@Nullable IRenderSetup, ArrayDeque> depthEnabledParticles = new Object2ObjectLinkedOpenHashMap<>(); - private final Map<@Nullable IRenderSetup, ArrayDeque> depthDisabledParticles = new Object2ObjectLinkedOpenHashMap<>(); + private final Map<@Nullable IRenderSetup, Queue> depthEnabledParticles = new Object2ObjectLinkedOpenHashMap<>(); + private final Map<@Nullable IRenderSetup, Queue> depthDisabledParticles = new Object2ObjectLinkedOpenHashMap<>(); private final List newParticleQueue = new ArrayList<>(); + private GTParticleManager() {} + public void addEffect(GTParticle particles) { newParticleQueue.add(particles); } @@ -57,11 +55,11 @@ public void updateEffects() { for (GTParticle particle : newParticleQueue) { var queue = particle.shouldDisableDepth() ? this.depthDisabledParticles : this.depthEnabledParticles; - ArrayDeque particles = queue.computeIfAbsent(particle.getRenderSetup(), + Queue particles = queue.computeIfAbsent(particle.getRenderSetup(), setup -> new ArrayDeque<>()); if (particles.size() > 6000) { - particles.removeFirst().setExpired(); + particles.remove().setExpired(); } particles.add(particle); } @@ -70,10 +68,10 @@ public void updateEffects() { } } - private void updateQueue(Map<@Nullable IRenderSetup, ArrayDeque> renderQueue) { - Iterator> it = renderQueue.values().iterator(); + private void updateQueue(Map<@Nullable IRenderSetup, Queue> renderQueue) { + Iterator> it = renderQueue.values().iterator(); while (it.hasNext()) { - ArrayDeque particlesForSetup = it.next(); + Queue particlesForSetup = it.next(); Iterator particles = particlesForSetup.iterator(); while (particles.hasNext()) { @@ -105,12 +103,12 @@ public void clearAllEffects(boolean cleanNewQueue) { } this.newParticleQueue.clear(); } - for (ArrayDeque particles : this.depthEnabledParticles.values()) { + for (Queue particles : this.depthEnabledParticles.values()) { for (GTParticle particle : particles) { particle.setExpired(); } } - for (ArrayDeque particles : this.depthDisabledParticles.values()) { + for (Queue particles : this.depthDisabledParticles.values()) { for (GTParticle particle : particles) { particle.setExpired(); } @@ -119,14 +117,19 @@ public void clearAllEffects(boolean cleanNewQueue) { this.depthDisabledParticles.clear(); } - public void renderParticles(PoseStack poseStack, Camera camera, Frustum frustum, float partialTicks) { + @SubscribeEvent(priority = EventPriority.HIGH) + public void renderParticles(RenderLevelStageEvent event) { + if (event.getStage() != RenderLevelStageEvent.Stage.AFTER_PARTICLES) return; if (this.depthEnabledParticles.isEmpty() && this.depthDisabledParticles.isEmpty()) return; - EffectRenderContext instance = EffectRenderContext.getInstance() - .update(camera, frustum, partialTicks); + Camera camera = event.getCamera(); - RenderSystem.enableBlend(); - RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); + PoseStack poseStack = event.getPoseStack(); + poseStack.pushPose(); + poseStack.translate(-camera.getPosition().x, -camera.getPosition().y, -camera.getPosition().z); + + EffectRenderContext instance = EffectRenderContext.getInstance() + .update(camera, event.getFrustum(), event.getPartialTick()); if (!this.depthDisabledParticles.isEmpty()) { RenderSystem.depthMask(false); @@ -135,14 +138,14 @@ public void renderParticles(PoseStack poseStack, Camera camera, Frustum frustum, } renderParticlesInLayer(poseStack, this.depthEnabledParticles, instance); - RenderSystem.disableBlend(); + poseStack.popPose(); } private static void renderParticlesInLayer(PoseStack poseStack, - Map<@Nullable IRenderSetup, ArrayDeque> renderQueue, + Map<@Nullable IRenderSetup, Queue> renderQueue, EffectRenderContext context) { for (var entry : renderQueue.entrySet()) { - ArrayDeque particles = entry.getValue(); + Queue particles = entry.getValue(); if (particles.isEmpty()) continue; IRenderSetup handler = entry.getKey(); @@ -174,57 +177,46 @@ private static void renderParticlesInLayer(PoseStack poseStack, } @SubscribeEvent - public static void onClientLevelLoad(LevelEvent.Load event) { - if (!(event.getLevel() instanceof ClientLevel newLevel)) { + public void clientTick(TickEvent.ClientTickEvent event) { + if (event.phase != TickEvent.Phase.END || Minecraft.getInstance().isPaused()) { return; } - ClientLevel oldLevel = Minecraft.getInstance().level; - if (oldLevel != newLevel) { - INSTANCE.clearAllEffects(oldLevel != null); - } - - if (oldLevel != null) { + if (Minecraft.getInstance().level != null) { INSTANCE.updateEffects(); } } @SubscribeEvent - public static void onClientLevelUnload(ClientPlayerNetworkEvent.LoggingOut event) { - if (event.getPlayer() != null) { - INSTANCE.clearAllEffects(true); + public void onClientLevelLoad(LevelEvent.Load event) { + if (!(event.getLevel() instanceof ClientLevel newLevel)) { + return; + } + ClientLevel oldLevel = Minecraft.getInstance().level; + if (oldLevel != newLevel) { + this.clearAllEffects(oldLevel != null); } } @SubscribeEvent - public static void renderWorld(RenderLevelStageEvent event) { - if (event.getStage() == RenderLevelStageEvent.Stage.AFTER_CUTOUT_BLOCKS) { - Entity entity = Minecraft.getInstance().getCameraEntity(); - if (entity == null) { - entity = Minecraft.getInstance().player; - } - if (entity != null) { - INSTANCE.renderParticles(event.getPoseStack(), event.getCamera(), event.getFrustum(), - event.getPartialTick()); - } + public void onClientLogout(ClientPlayerNetworkEvent.LoggingOut event) { + if (event.getPlayer() != null) { + this.clearAllEffects(true); } } @SubscribeEvent - public static void debugOverlay(CustomizeGuiOverlayEvent.DebugText event) { - if (event.getLeft().size() >= 5) { - String particleTxt = event.getLeft().get(4); - particleTxt += "." + ChatFormatting.GOLD + - " PARTICLE-BACK: " + count(INSTANCE.depthEnabledParticles) + - "PARTICLE-FRONT: " + count(INSTANCE.depthDisabledParticles); - event.getLeft().set(4, particleTxt); + public void debugOverlay(CustomizeGuiOverlayEvent.DebugText event) { + List gameInfo = event.getLeft(); + if (gameInfo.size() >= 5) { + String countStatsLine = gameInfo.get(4); + countStatsLine += ". " + ChatFormatting.GOLD + + "P-BACK: " + count(this.depthEnabledParticles) + + " P-FRONT: " + count(this.depthDisabledParticles); + gameInfo.set(4, countStatsLine); } } - private static int count(Map<@Nullable IRenderSetup, ArrayDeque> renderQueue) { - int total = 0; - for (Deque queue : renderQueue.values()) { - total += queue.size(); - } - return total; + private static int count(Map<@Nullable IRenderSetup, Queue> renderQueue) { + return renderQueue.values().stream().mapToInt(Queue::size).sum(); } } diff --git a/src/main/java/com/gregtechceu/gtceu/client/renderer/machine/impl/FusionRingRender.java b/src/main/java/com/gregtechceu/gtceu/client/renderer/machine/impl/FusionRingRender.java index 3879aea58c3..6b51548a228 100644 --- a/src/main/java/com/gregtechceu/gtceu/client/renderer/machine/impl/FusionRingRender.java +++ b/src/main/java/com/gregtechceu/gtceu/client/renderer/machine/impl/FusionRingRender.java @@ -11,7 +11,6 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.ShaderInstance; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.util.Mth; @@ -125,25 +124,19 @@ private final class FusionBloomEffect implements IBloomEffect { private final FusionReactorMachine machine; - private static final BufferBuilder lightRingBuffer = new BufferBuilder(GTRenderTypes.lightRing().bufferSize()); - private static final IRenderSetup SETUP = new IRenderSetup() { @Override @OnlyIn(Dist.CLIENT) public void preDraw(BufferBuilder buffer) { - lightRingBuffer.begin(GTRenderTypes.lightRing().mode(), GTRenderTypes.lightRing().format()); + RenderSystem.setShader(GameRenderer::getPositionColorShader); + buffer.begin(VertexFormat.Mode.TRIANGLE_STRIP, DefaultVertexFormat.POSITION_COLOR); } @Override @OnlyIn(Dist.CLIENT) public void postDraw(BufferBuilder buffer) { - ShaderInstance lastShader = RenderSystem.getShader(); - RenderSystem.setShader(GameRenderer::getPositionColorShader); - - BufferUploader.drawWithShader(lightRingBuffer.end()); - - RenderSystem.setShader(() -> lastShader); + BufferUploader.drawWithShader(buffer.end()); } }; @@ -153,9 +146,7 @@ public void renderBloomEffect(PoseStack poseStack, BufferBuilder buffer, EffectR poseStack.pushPose(); poseStack.translate(pos.getX(), pos.getY(), pos.getZ()); - - FusionRingRender.this.renderLightRing(machine, context.partialTicks(), poseStack, lightRingBuffer); - + FusionRingRender.this.renderLightRing(machine, context.partialTicks(), poseStack, buffer); poseStack.popPose(); } diff --git a/src/main/java/com/gregtechceu/gtceu/common/block/CableBlock.java b/src/main/java/com/gregtechceu/gtceu/common/block/CableBlock.java index dacfeefdb21..db79322d62c 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/block/CableBlock.java +++ b/src/main/java/com/gregtechceu/gtceu/common/block/CableBlock.java @@ -55,7 +55,7 @@ public CableBlock(Properties properties, Insulation insulation, Material materia @Override public int tinted(BlockState state, @Nullable BlockAndTintGetter level, @Nullable BlockPos pos, int index) { - if (pipeType.isCable && (index == 0 || index == 2)) { + if (pipeType.isCable() && (index == 0 || index == 2)) { return 0x404040; } return super.tinted(state, level, pos, index); @@ -132,7 +132,7 @@ public void entityInside(BlockState state, Level level, BlockPos pos, Entity ent if (level.isClientSide) return; Insulation insulation = getPipeTile(level, pos).getPipeType(); - if (insulation.insulationLevel == -1 && entity instanceof LivingEntity entityLiving) { + if (!insulation.isCable() && entity instanceof LivingEntity entityLiving) { CableBlockEntity cable = (CableBlockEntity) getPipeTile(level, pos); if (cable != null && cable.getFrameMaterial().isNull() && cable.getNodeData().getLossPerBlock() > 0) { diff --git a/src/main/java/com/gregtechceu/gtceu/common/blockentity/CableBlockEntity.java b/src/main/java/com/gregtechceu/gtceu/common/blockentity/CableBlockEntity.java index ba3c179a040..c215d97225f 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/blockentity/CableBlockEntity.java +++ b/src/main/java/com/gregtechceu/gtceu/common/blockentity/CableBlockEntity.java @@ -6,10 +6,12 @@ import com.gregtechceu.gtceu.api.capability.GTCapabilityHelper; import com.gregtechceu.gtceu.api.capability.IEnergyContainer; import com.gregtechceu.gtceu.api.data.chemical.material.properties.WireProperties; +import com.gregtechceu.gtceu.api.data.tag.TagPrefix; import com.gregtechceu.gtceu.api.gui.GuiTextures; import com.gregtechceu.gtceu.api.item.tool.GTToolType; import com.gregtechceu.gtceu.api.machine.TickableSubscription; import com.gregtechceu.gtceu.api.machine.feature.IDataInfoProvider; +import com.gregtechceu.gtceu.api.sync_system.annotations.ClientFieldChangeListener; import com.gregtechceu.gtceu.api.sync_system.annotations.SaveField; import com.gregtechceu.gtceu.api.sync_system.annotations.SyncToClient; import com.gregtechceu.gtceu.client.particle.GTOverheatParticle; @@ -31,16 +33,14 @@ import net.minecraft.core.particles.ParticleTypes; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.Mth; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.util.LazyOptional; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; import lombok.Getter; import org.jetbrains.annotations.NotNull; @@ -59,7 +59,7 @@ public class CableBlockEntity extends PipeBlockEntity currentEnergyNet = new WeakReference<>(null); - @SideOnly(Side.CLIENT) + @OnlyIn(Dist.CLIENT) private GTOverheatParticle particle; private static final int meltTemp = 3000; @@ -172,7 +172,7 @@ public void onLoad() { private void subscribeHeat() { if (this.heatSubs == null) { - this.heatSubs = subscribeServerTick(this::update); + this.heatSubs = subscribeServerTick(this::updateHeat); } } @@ -243,9 +243,7 @@ public boolean isParticleAlive() { @OnlyIn(Dist.CLIENT) public void createParticle() { - particle = new GTOverheatParticle(this, meltTemp, - getPipeBlock().getShape(getBlockState(), level, getBlockPos(), CollisionContext.empty()), - getPipeType().insulationLevel >= 0); + particle = new GTOverheatParticle(this, meltTemp, getPipeType().isCable()); GTParticleManager.INSTANCE.addEffect(particle); } @@ -264,7 +262,7 @@ public void applyHeat(int amount) { } } - private boolean update() { + private boolean updateHeat() { if (heatQueue > 0) { // if received heat from overvolting or overamping, add heat setTemperature(temperature + heatQueue); @@ -281,32 +279,31 @@ private boolean update() { return false; } - if (getPipeType().insulationLevel >= 0 && temperature >= 1500 && GTValues.RNG.nextFloat() < 0.1) { + if (getPipeType().isCable() && temperature >= 1500 && GTValues.RNG.nextFloat() < 0.1f) { // insulation melted uninsulate(); return false; } - if (heatQueue == 0) { + if (heatQueue <= 0) { // otherwise cool down - setTemperature((int) (temperature - Math.pow(temperature - getDefaultTemp(), 0.35))); - } else { - heatQueue = 0; + setTemperature((int) (temperature - Math.pow(temperature - getDefaultTemp(), 0.35f))); } + heatQueue = 0; return true; } private void uninsulate() { - int temp = temperature; + int oldTemperature = temperature; setTemperature(getDefaultTemp()); - int index = getPipeType().insulationLevel; - CableBlock newBlock = GTMaterialBlocks.CABLE_BLOCKS - .get(Insulation.values()[index].tagPrefix, getPipeBlock().material) - .get(); + + TagPrefix uninsulatedPrefix = getPipeType().getUninsulated().tagPrefix; + CableBlock newBlock = GTMaterialBlocks.CABLE_BLOCKS.get(uninsulatedPrefix, getPipeBlock().material).get(); level.setBlockAndUpdate(getBlockPos(), newBlock.defaultBlockState()); + CableBlockEntity newCable = (CableBlockEntity) level.getBlockEntity(getBlockPos()); if (newCable != null) { // should never be null - newCable.setTemperature(temp); + newCable.setTemperature(oldTemperature); newCable.subscribeHeat(); for (Direction facing : GTUtil.DIRECTIONS) { if (isConnected(facing)) { @@ -323,23 +320,36 @@ public void setTemperature(int temperature) { this.temperature = temperature; syncDataHolder.markClientSyncFieldDirty("temperature"); level.getLightEngine().checkBlock(worldPosition); - if (!level.isClientSide && temperature >= meltTemp) { - var facing = Direction.UP; - float xPos = facing.getStepX() * 0.76F + worldPosition.getX() + 0.25F; - float yPos = facing.getStepY() * 0.76F + worldPosition.getY() + 0.25F; - float zPos = facing.getStepZ() * 0.76F + worldPosition.getZ() + 0.25F; - - float ySpd = facing.getStepY() * 0.1F + 0.2F + 0.1F * GTValues.RNG.nextFloat(); - float temp = GTValues.RNG.nextFloat() * 2 * (float) Math.PI; - float xSpd = (float) Math.sin(temp) * 0.1F; - float zSpd = (float) Math.cos(temp) * 0.1F; - - ((ServerLevel) level).sendParticles(ParticleTypes.SMOKE, - xPos + GTValues.RNG.nextFloat() * 0.5F, - yPos + GTValues.RNG.nextFloat() * 0.5F, - zPos + GTValues.RNG.nextFloat() * 0.5F, - 0, - xSpd, ySpd, zSpd, 1); + } + + @ClientFieldChangeListener(fieldName = "temperature") + public void onTemperatureUpdated() { + if (temperature <= getDefaultTemp()) { + if (isParticleAlive()) { + particle.setExpired(); + } + } else { + if (!isParticleAlive()) { + createParticle(); + } + particle.setTemperature(temperature); + } + + if (this.temperature >= meltTemp) { + float xPos = Direction.UP.getStepX() * 0.76f + getBlockPos().getX() + 0.25f; + float yPos = Direction.UP.getStepY() * 0.76f + getBlockPos().getY() + 0.25f; + float zPos = Direction.UP.getStepZ() * 0.76f + getBlockPos().getZ() + 0.25f; + + float horizontalDirection = level.random.nextFloat() * 2 * Mth.PI; + float xSpd = Mth.sin(horizontalDirection) * 0.1f; + float ySpd = Direction.UP.getStepY() * 0.1f + 0.2f + 0.1f * level.random.nextFloat(); + float zSpd = Mth.cos(horizontalDirection) * 0.1f; + + level.addParticle(ParticleTypes.SMOKE, + xPos + level.random.nextFloat() * 0.5f, + yPos + level.random.nextFloat() * 0.5f, + zPos + level.random.nextFloat() * 0.5f, + xSpd, ySpd, zSpd); } } @@ -360,7 +370,7 @@ public GTToolType getPipeTuneTool() { } @Override - public @NotNull List getDataInfo(PortableScannerBehavior.DisplayMode mode) { + public List getDataInfo(PortableScannerBehavior.DisplayMode mode) { List list = new ArrayList<>(); if (mode == PortableScannerBehavior.DisplayMode.SHOW_ALL || diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/GTMaterialBlocks.java b/src/main/java/com/gregtechceu/gtceu/common/data/GTMaterialBlocks.java index 4c21ff2b8a5..9d31c55a7c4 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/data/GTMaterialBlocks.java +++ b/src/main/java/com/gregtechceu/gtceu/common/data/GTMaterialBlocks.java @@ -188,7 +188,7 @@ public static void generateCableBlocks() { private static boolean allowCableBlock(Material material, Insulation insulation) { return material.hasProperty(PropertyKey.WIRE) && !insulation.tagPrefix.isIgnored(material) && - !(insulation.isCable && material.getProperty(PropertyKey.WIRE).isSuperconductor()); + !(insulation.isCable() && material.getProperty(PropertyKey.WIRE).isSuperconductor()); } private static void registerCableBlock(Material material, Insulation insulation, GTRegistrate registrate) { diff --git a/src/main/java/com/gregtechceu/gtceu/common/pipelike/cable/Insulation.java b/src/main/java/com/gregtechceu/gtceu/common/pipelike/cable/Insulation.java index fc543f04ff4..8ea7978ac6b 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/pipelike/cable/Insulation.java +++ b/src/main/java/com/gregtechceu/gtceu/common/pipelike/cable/Insulation.java @@ -19,43 +19,42 @@ public enum Insulation implements IMaterialPipeType { - WIRE_SINGLE("single_wire", 0.1875f, 1, 2, wireGtSingle, -1, false), - WIRE_DOUBLE("double_wire", 0.3125f, 2, 2, wireGtDouble, -1, false), - WIRE_QUADRUPLE("quadruple_wire", 0.4375f, 4, 3, wireGtQuadruple, -1, false), - WIRE_OCTAL("octal_wire", 0.5625f, 8, 3, wireGtOctal, -1, false), - WIRE_HEX("hex_wire", 0.8125f, 16, 3, wireGtHex, -1, false), - - CABLE_SINGLE("single_cable", 0.25f, 1, 1, cableGtSingle, 0, true), - CABLE_DOUBLE("double_cable", 0.375f, 2, 1, cableGtDouble, 1, true), - CABLE_QUADRUPLE("quadruple_cable", 0.5f, 4, 1, cableGtQuadruple, 2, true), - CABLE_OCTAL("octal_cable", 0.625f, 8, 1, cableGtOctal, 3, true), - CABLE_HEX("hex_cable", 0.875f, 16, 1, cableGtHex, 4, true); + WIRE_SINGLE("single_wire", 0.1875f, 1, 2, wireGtSingle, -1), + WIRE_DOUBLE("double_wire", 0.3125f, 2, 2, wireGtDouble, -1), + WIRE_QUADRUPLE("quadruple_wire", 0.4375f, 4, 3, wireGtQuadruple, -1), + WIRE_OCTAL("octal_wire", 0.5625f, 8, 3, wireGtOctal, -1), + WIRE_HEX("hex_wire", 0.8125f, 16, 3, wireGtHex, -1), + + CABLE_SINGLE("single_cable", 0.25f, 1, 1, cableGtSingle, 0), + CABLE_DOUBLE("double_cable", 0.375f, 2, 1, cableGtDouble, 1), + CABLE_QUADRUPLE("quadruple_cable", 0.5f, 4, 1, cableGtQuadruple, 2), + CABLE_OCTAL("octal_cable", 0.625f, 8, 1, cableGtOctal, 3), + CABLE_HEX("hex_cable", 0.875f, 16, 1, cableGtHex, 4); public static final ResourceLocation TYPE_ID = GTCEu.id("insulation"); public final String name; + @Getter public final float thickness; public final int amperage; public final int lossMultiplier; @Getter public final TagPrefix tagPrefix; public final int insulationLevel; + /// @deprecated Use {@link #isCable() Insulation.isCable()} + @Deprecated(forRemoval = true, since = "8.0.0") public final boolean isCable; - Insulation(String name, float thickness, int amperage, int lossMultiplier, TagPrefix TagPrefix, int insulated, - boolean isCable) { + Insulation(String name, float thickness, int amperage, int lossMultiplier, TagPrefix TagPrefix, + int insulationLevel) { this.name = name; this.thickness = thickness; this.amperage = amperage; this.tagPrefix = TagPrefix; - this.insulationLevel = insulated; + this.insulationLevel = insulationLevel; this.lossMultiplier = lossMultiplier; - this.isCable = isCable; - } - @Override - public float getThickness() { - return thickness; + this.isCable = insulationLevel >= 0; } @Override @@ -70,7 +69,15 @@ public WireProperties modifyProperties(WireProperties baseProperties) { } public boolean isCable() { - return ordinal() > 4; + return insulationLevel >= 0; + } + + public Insulation getUninsulated() { + if (isCable()) { + return values()[insulationLevel]; + } else { + return this; + } } @Override @@ -90,7 +97,7 @@ public PipeModel createPipeModel(PipeBlock block, Material material, GT .getBlockTexturePath(material.getMaterialIconSet(), "end", true); PipeModel model = new PipeModel(block, provider, thickness, - isCable ? GTCEu.id("block/cable/insulation_5") : side, end); + isCable() ? GTCEu.id("block/cable/insulation_5") : side, end); ResourceLocation sideSecondary = MaterialIconType.wire .getBlockTexturePath(material.getMaterialIconSet(), "side_overlay", true); @@ -103,7 +110,7 @@ public PipeModel createPipeModel(PipeBlock block, Material material, GT if (endSecondary != null && !endSecondary.equals(GTModels.BLANK_TEXTURE)) { model.setEndSecondary(endSecondary); } - if (isCable) { + if (isCable()) { model.setEndOverlay(GTCEu.id("block/cable/insulation_%s".formatted(insulationLevel))); } return model;