Skip to content

Commit

Permalink
feat: add fluid rendering to multiblocks
Browse files Browse the repository at this point in the history
includes a refactor of services to have separate client services

Closes #156
  • Loading branch information
klikli-dev committed Dec 27, 2023
1 parent 69a146f commit 6ae19a8
Show file tree
Hide file tree
Showing 32 changed files with 536 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import net.minecraft.core.Vec3i;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Rotation;
import org.jetbrains.annotations.Nullable;
Expand All @@ -26,7 +27,7 @@
* do not create your own implementation of this, as it'll not be compatible with
* all the features in the mod.
*/
public interface Multiblock {
public interface Multiblock extends BlockAndTintGetter {

// ================================================================================================
// Builder methods
Expand Down Expand Up @@ -75,6 +76,11 @@ public interface Multiblock {
*/
ResourceLocation getType();

/**
* Sets the level the multiblock should use for e.g registry access
*/
void setLevel(Level level);

/**
* Places the multiblock at the given position with the given rotation.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,18 @@
import com.klikli_dev.modonomicon.api.multiblock.Multiblock;
import com.mojang.datafixers.util.Pair;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Vec3i;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.ColorResolver;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Rotation;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.lighting.LevelLightEngine;
import net.minecraft.world.level.material.FluidState;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;
import java.util.Collections;
Expand All @@ -32,6 +39,11 @@ public ResourceLocation getType() {
return TYPE;
}

@Override
public void setLevel(Level level) {

}

@Override
public Multiblock offset(int x, int y, int z) {
return this;
Expand Down Expand Up @@ -107,4 +119,44 @@ public void toNetwork(FriendlyByteBuf buffer) {

}

@Override
public float getShade(Direction direction, boolean shade) {
return 0;
}

@Override
public LevelLightEngine getLightEngine() {
return null;
}

@Override
public int getBlockTint(BlockPos blockPos, ColorResolver colorResolver) {
return 0;
}

@Nullable
@Override
public BlockEntity getBlockEntity(BlockPos pos) {
return null;
}

@Override
public BlockState getBlockState(BlockPos pos) {
return null;
}

@Override
public FluidState getFluidState(BlockPos pos) {
return null;
}

@Override
public int getHeight() {
return 0;
}

@Override
public int getMinBuildHeight() {
return 0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.klikli_dev.modonomicon.book.error.BookErrorManager;
import com.klikli_dev.modonomicon.client.gui.book.*;
import com.klikli_dev.modonomicon.data.BookDataManager;
import com.klikli_dev.modonomicon.platform.ClientServices;
import com.klikli_dev.modonomicon.platform.Services;
import net.minecraft.client.Minecraft;
import net.minecraft.resources.ResourceLocation;
Expand Down Expand Up @@ -184,7 +185,7 @@ public void openEntry(ResourceLocation bookId, @Nullable ResourceLocation catego
this.currentContentScreen = this.currentCategoryScreen.openEntry(entry);
} else {
//we are clearing the gui layers above, so we have to restore here if we do not call openentry
Services.GUI.pushGuiLayer(this.currentContentScreen);
ClientServices.GUI.pushGuiLayer(this.currentContentScreen);
}

//we don't need to manually check for the current page because the content screen will do that for us
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import com.klikli_dev.modonomicon.events.ModonomiconEvents;
import com.klikli_dev.modonomicon.networking.BookEntryReadMessage;
import com.klikli_dev.modonomicon.networking.SaveCategoryStateMessage;
import com.klikli_dev.modonomicon.platform.ClientServices;
import com.klikli_dev.modonomicon.platform.Services;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.ChatFormatting;
Expand Down Expand Up @@ -75,7 +76,7 @@ public float getYOffset() {
}

public void render(GuiGraphics guiGraphics, int pMouseX, int pMouseY, float pPartialTick) {
if (Services.CLIENT_CONFIG.enableSmoothZoom()) {
if (ClientServices.CLIENT_CONFIG.enableSmoothZoom()) {
float diff = this.targetZoom - this.currentZoom;
this.currentZoom = this.currentZoom + Math.min(pPartialTick * (2 / 3f), 1) * diff;
} else
Expand Down Expand Up @@ -154,7 +155,7 @@ public BookContentScreen openEntry(BookEntry entry) {
this.openEntry = entry.getId();

var bookContentScreen = new BookContentScreen(this.bookOverviewScreen, entry);
Services.GUI.pushGuiLayer(bookContentScreen);
ClientServices.GUI.pushGuiLayer(bookContentScreen);

return bookContentScreen;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import com.klikli_dev.modonomicon.integration.ModonomiconJeiIntegration;
import com.klikli_dev.modonomicon.networking.ClickCommandLinkMessage;
import com.klikli_dev.modonomicon.networking.SaveEntryStateMessage;
import com.klikli_dev.modonomicon.platform.ClientServices;
import com.klikli_dev.modonomicon.platform.Services;
import com.klikli_dev.modonomicon.platform.services.FluidHelper;
import com.klikli_dev.modonomicon.util.ItemStackUtil;
Expand Down Expand Up @@ -273,7 +274,7 @@ public void renderFluidStack(GuiGraphics guiGraphics, int x, int y, int mouseX,

guiGraphics.pose().pushPose();
guiGraphics.pose().translate(x, y, 0);
Services.FLUID.drawFluid(guiGraphics, 18, 18, stack, capacity);
ClientServices.FLUID.drawFluid(guiGraphics, 18, 18, stack, capacity);
guiGraphics.pose().popPose();

if (this.isMouseInRelativeRange(mouseX, mouseY, x, y, 18, 18)) {
Expand Down Expand Up @@ -518,13 +519,11 @@ public void onClose() {
this.simulateEscClosing = false;
} else {
Services.NETWORK.sendToServer(new SaveEntryStateMessage(this.entry,
Services.CLIENT_CONFIG.storeLastOpenPageWhenClosingEntry() ? this.openPagesIndex : 0));
ClientServices.CLIENT_CONFIG.storeLastOpenPageWhenClosingEntry() ? this.openPagesIndex : 0));

this.parentScreen.getCurrentCategoryScreen().onCloseEntry(this);

Services.GUI.popGuiLayer(); //instead of super.onClose() to restore our parent screen


ClientServices.GUI.popGuiLayer(); //instead of super.onClose() to restore our parent screen
}
}

Expand Down Expand Up @@ -661,7 +660,7 @@ public List<Component> getTooltipFromItem(ItemStack pItemStack) {
}

public List<Component> getTooltipFromFluid(FluidHolder fluidStack) {
var tooltip = Services.FLUID.getTooltip(fluidStack, FluidHolder.BUCKET_VOLUME, this.minecraft.options.advancedItemTooltips ? TooltipFlag.Default.ADVANCED : TooltipFlag.Default.NORMAL, FluidHelper.TooltipMode.SHOW_AMOUNT_AND_CAPACITY);
var tooltip = ClientServices.FLUID.getTooltip(fluidStack, FluidHolder.BUCKET_VOLUME, this.minecraft.options.advancedItemTooltips ? TooltipFlag.Default.ADVANCED : TooltipFlag.Default.NORMAL, FluidHelper.TooltipMode.SHOW_AMOUNT_AND_CAPACITY);

if (this.isHoveringItemLink) {
tooltip.add(Component.literal(""));
Expand Down Expand Up @@ -742,7 +741,7 @@ public boolean handleComponentClicked(@Nullable Style pStyle) {
}

if (!ModonomiconJeiIntegration.get().isJEIRecipesGuiOpen()) {
Services.GUI.pushGuiLayer(this);
ClientServices.GUI.pushGuiLayer(this);
}

//TODO: Consider adding logic to restore content screen after JEI gui close
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.klikli_dev.modonomicon.networking.ClickReadAllButtonMessage;
import com.klikli_dev.modonomicon.networking.SaveBookStateMessage;
import com.klikli_dev.modonomicon.networking.SyncBookUnlockStatesMessage;
import com.klikli_dev.modonomicon.platform.ClientServices;
import com.klikli_dev.modonomicon.platform.Services;
import com.klikli_dev.modonomicon.util.GuiGraphicsExt;
import com.mojang.blaze3d.systems.RenderSystem;
Expand Down Expand Up @@ -361,7 +362,7 @@ protected void init() {
}

protected void onSearchButtonClick(SearchButton button) {
Services.GUI.pushGuiLayer(new BookSearchScreen(this));
ClientServices.GUI.pushGuiLayer(new BookSearchScreen(this));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* SPDX-FileCopyrightText: 2022 Authors of Patchouli
* SPDX-FileCopyrightText: 2023 klikli-dev
*
* SPDX-License-Identifier: MIT
*/

package com.klikli_dev.modonomicon.client.render;

import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import net.minecraft.core.BlockPos;

public record FluidBlockVertexConsumer(VertexConsumer prior, PoseStack pose, BlockPos pos) implements VertexConsumer {

@Override
public VertexConsumer vertex(double x, double y, double z) {
final float dx = this.pos.getX() & 15;
final float dy = this.pos.getY() & 15;
final float dz = this.pos.getZ() & 15;
return this.prior.vertex(this.pose.last().pose(), (float) x - dx, (float) y - dy, (float) z - dz);
}

@Override
public VertexConsumer color(int r, int g, int b, int a) {
return this.prior.color(r, g, b, a);
}

@Override
public VertexConsumer uv(float u, float v) {
return this.prior.uv(u, v);
}

@Override
public VertexConsumer overlayCoords(int u, int v) {
return this.prior.overlayCoords(u, v);
}

@Override
public VertexConsumer uv2(int u, int v) {
return this.prior.uv2(u, v);
}

@Override
public VertexConsumer normal(float x, float y, float z) {
return this.prior.normal(this.pose.last().normal(), x, y, z);
}

@Override
public void endVertex() {
this.prior.endVertex();
}

@Override
public void defaultColor(int r, int g, int b, int a) {
this.prior.defaultColor(r, g, b, a);
}

@Override
public void unsetDefaultColor() {
this.prior.unsetDefaultColor();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
import com.klikli_dev.modonomicon.multiblock.AbstractMultiblock;
import com.klikli_dev.modonomicon.multiblock.matcher.DisplayOnlyMatcher;
import com.klikli_dev.modonomicon.multiblock.matcher.Matchers;
import com.klikli_dev.modonomicon.platform.ClientServices;
import com.klikli_dev.modonomicon.platform.Services;
import com.klikli_dev.modonomicon.util.GuiGraphicsExt;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
Expand Down Expand Up @@ -210,7 +212,7 @@ public static void onClientTick(Minecraft mc) {
}
}

public static void renderMultiblock(Level world, PoseStack ms) {
public static void renderMultiblock(Level level, PoseStack ms) {
Minecraft mc = Minecraft.getInstance();
if (!isAnchored) {
facingRotation = getRotation(mc.player);
Expand All @@ -228,6 +230,8 @@ public static void renderMultiblock(Level world, PoseStack ms) {
facingRotation = Rotation.NONE;
}

multiblock.setLevel(level);

EntityRenderDispatcher erd = mc.getEntityRenderDispatcher();
double renderPosX = erd.camera.getPosition().x();
double renderPosY = erd.camera.getPosition().y();
Expand All @@ -248,7 +252,7 @@ public static void renderMultiblock(Level world, PoseStack ms) {
lookingState = null;
lookingPos = checkPos;

Pair<BlockPos, Collection<Multiblock.SimulateResult>> sim = multiblock.simulate(world, getStartPos(), getFacingRotation(), true, false);
Pair<BlockPos, Collection<Multiblock.SimulateResult>> sim = multiblock.simulate(level, getStartPos(), getFacingRotation(), true, false);
for (Multiblock.SimulateResult r : sim.getSecond()) {
float alpha = 0.3F;
if (r.getWorldPosition().equals(checkPos)) {
Expand All @@ -262,9 +266,9 @@ public static void renderMultiblock(Level world, PoseStack ms) {
blocks++;
}

if (!r.test(world, facingRotation)) {
if (!r.test(level, facingRotation)) {
BlockState renderState = r.getStateMatcher().getDisplayedState(ClientTicks.ticks).rotate(facingRotation);
renderBlock(world, renderState, r.getWorldPosition(), air, alpha, ms);
renderBlock(level, renderState, r.getWorldPosition(), multiblock, air, alpha, ms);

if (renderState.getBlock() instanceof EntityBlock eb) {
var be = blockEntityCache.computeIfAbsent(r.getWorldPosition().immutable(), p -> eb.newBlockEntity(p, renderState));
Expand Down Expand Up @@ -308,7 +312,7 @@ public static void renderMultiblock(Level world, PoseStack ms) {
}
}

public static void renderBlock(Level world, BlockState state, BlockPos pos, boolean isAir, float alpha, PoseStack ms) {
public static void renderBlock(Level world, BlockState state, BlockPos pos, Multiblock multiblock, boolean isAir, float alpha, PoseStack ms) {
if (pos != null) {
ms.pushPose();
ms.translate(pos.getX(), pos.getY(), pos.getZ());
Expand All @@ -322,7 +326,9 @@ public static void renderBlock(Level world, BlockState state, BlockPos pos, bool
state = Blocks.RED_CONCRETE.defaultBlockState();
}

Minecraft.getInstance().getBlockRenderer().renderSingleBlock(state, ms, buffers, 0xF000F0, OverlayTexture.NO_OVERLAY);
ClientServices.MULTIBLOCK.renderBlock(state, pos, multiblock, ms, buffers, world.getRandom());

// Minecraft.getInstance().getBlockRenderer().renderSingleBlock(state, ms, buffers, 0xF000F0, OverlayTexture.NO_OVERLAY);

ms.popPose();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
import com.klikli_dev.modonomicon.client.gui.book.BookContentScreen;
import com.klikli_dev.modonomicon.client.gui.book.button.VisualizeButton;
import com.klikli_dev.modonomicon.client.render.MultiblockPreviewRenderer;
import com.klikli_dev.modonomicon.multiblock.AbstractMultiblock;
import com.klikli_dev.modonomicon.platform.ClientServices;
import com.klikli_dev.modonomicon.platform.Services;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.datafixers.util.Pair;
Expand All @@ -29,6 +32,7 @@
import net.minecraft.core.BlockPos;
import net.minecraft.core.Vec3i;
import net.minecraft.network.chat.Style;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.block.EntityBlock;
import net.minecraft.world.level.block.Rotation;
import net.minecraft.world.level.block.entity.BlockEntity;
Expand All @@ -42,6 +46,7 @@

public class BookMultiblockPageRenderer extends BookPageRenderer<BookMultiblockPage> implements PageWithTextRenderer {

private static final RandomSource randomSource = RandomSource.createNewThreadLocalInstance();
private final Map<BlockPos, BlockEntity> blockEntityCache = new HashMap<>();
private final Set<BlockEntity> erroredBlockEntities = Collections.newSetFromMap(new WeakHashMap<>());

Expand Down Expand Up @@ -70,6 +75,8 @@ private void renderMultiblock(GuiGraphics guiGraphics) {
var pos = BlockPos.ZERO;
var facingRotation = Rotation.NONE;

this.page.getMultiblock().setLevel(level);

if (this.page.getMultiblock().isSymmetrical()) {
facingRotation = Rotation.NONE;
}
Expand Down Expand Up @@ -180,7 +187,7 @@ private void renderBlock(MultiBufferSource.BufferSource buffers, ClientLevel lev
ps.pushPose();
ps.translate(pos.getX(), pos.getY(), pos.getZ());

Minecraft.getInstance().getBlockRenderer().renderSingleBlock(state, ps, buffers, 0xF000F0, OverlayTexture.NO_OVERLAY);
ClientServices.MULTIBLOCK.renderBlock(state, pos, this.page.getMultiblock(), ps, buffers, randomSource);

ps.popPose();
}
Expand Down
Loading

0 comments on commit 6ae19a8

Please sign in to comment.