finally render fluids

This commit is contained in:
Robin 2024-06-30 20:07:37 +02:00
parent 2a2d257f01
commit 054cddd246
9 changed files with 163 additions and 38 deletions

View File

@ -11,5 +11,6 @@ Other Licenses:
- client - client
- renderer - renderer
- EnvStorageRenderer.java = Blu's License of Common Sense - EnvStorageRenderer.java = Blu's License of Common Sense
- RenderUtils.java = LGPL-3.0
- utils - utils
- MouseUtils.java = MIT - MouseUtils.java = MIT

View File

@ -80,7 +80,8 @@ spotless {
// Originally, this was from Kaupenjoe's repo, and was licensed by BluSunrize as the original code was from her, so we exclude it to not add our License Header // Originally, this was from Kaupenjoe's repo, and was licensed by BluSunrize as the original code was from her, so we exclude it to not add our License Header
targetExclude( targetExclude(
"src/main/java/robaertschi/environmenttech/client/renderer/EnvStorageRenderer.java", "src/main/java/robaertschi/environmenttech/client/renderer/EnvStorageRenderer.java",
"src/main/java/robaertschi/environmenttech/utils/MouseUtils.java" "src/main/java/robaertschi/environmenttech/utils/MouseUtils.java",
"src/main/java/robaertschi/environmenttech/client/RenderUtils.java"
) )
importOrder("lombok", "java|javax", "", "net.minecraft", "com.mojang", "robaertschi", "\\#") importOrder("lombok", "java|javax", "", "net.minecraft", "com.mojang", "robaertschi", "\\#")
removeUnusedImports() removeUnusedImports()

View File

@ -7,17 +7,22 @@ import net.minecraft.client.renderer.ItemBlockRenderTypes;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.inventory.InventoryMenu; import net.minecraft.world.inventory.InventoryMenu;
import net.minecraft.world.phys.Vec3;
import net.neoforged.neoforge.client.extensions.common.IClientFluidTypeExtensions; import net.neoforged.neoforge.client.extensions.common.IClientFluidTypeExtensions;
import net.neoforged.neoforge.fluids.FluidStack; import net.neoforged.neoforge.fluids.FluidStack;
import org.joml.Vector3f; import org.joml.Vector3f;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
/**
* This file is from <a href="https://github.com/DaRealTurtyWurty/DynamicFluidTanks/blob/forge/src/main/java/dev/turtywurty/dynamicfluidtanks/client/renderer/FluidTankBERenderer.java">here</a>.
* So all credits go to TurtyWurty. The code is under the LGPL-3.0, the conformation you can see <a href="https://github.com/DaRealTurtyWurty/DynamicFluidTanks/blob/forge/gradle.properties">here</a> on the mod_license line.
* But the repo does not contain a LICENSE file, so it is not clear.
* @author TurtyWurty
*/
public class RenderUtils { public class RenderUtils {
public static void vertex(VertexConsumer consumer, public static void vertex(VertexConsumer consumer,
PoseStack stack, PoseStack stack,
float x, float y, float z, float x, float y, float z,
@ -61,13 +66,11 @@ public class RenderUtils {
public static void cuboid( public static void cuboid(
VertexConsumer consumer, VertexConsumer consumer,
PoseStack stack, PoseStack stack,
BlockPos fromPos,
Vector3f start, Vector3f end, Vector3f start, Vector3f end,
TextureAtlasSprite sprite, TextureAtlasSprite sprite,
int packedLight, int color int packedLight, int color
) { ) {
var relativeStart = Vec3.atLowerCornerWithOffset(fromPos, -start.x(), -start.y(), -start.z());
float width = end.x() - start.x(); float width = end.x() - start.x();
float height = end.y() - start.y(); float height = end.y() - start.y();
@ -79,7 +82,12 @@ public class RenderUtils {
float v1 = sprite.getV1(); float v1 = sprite.getV1();
stack.pushPose(); stack.pushPose();
stack.translate(-relativeStart.x(), -relativeStart.y(), -relativeStart.z()); // log.info("x: {}, y: {}, z: {}", -relativeStart.x(), -relativeStart.y(), -relativeStart.z());
// stack.translate(-relativeStart.x(), -relativeStart.y(), -relativeStart.z());
// stack.translate(relativeStart.x(), relativeStart.y(), relativeStart.z());
// System.out.println("Width " + width + " height " + height + " depth " + depth);
// System.out.println("start " + start + " end " + end + " relativeStart " + relativeStart);
// Front // Front
quad(consumer, stack, packedLight, color, 0, 0, 0, width, height, 0, u0, v0, u1, v1); quad(consumer, stack, packedLight, color, 0, 0, 0, width, height, 0, u0, v0, u1, v1);
@ -112,15 +120,15 @@ public class RenderUtils {
long amount, long amount,
long capacity, long capacity,
Vector3f start, Vector3f start,
Vector3f end, Vector3f end
BlockPos blockPos
) { ) {
TextureAtlasSprite sprite = Minecraft.getInstance().getTextureAtlas(InventoryMenu.BLOCK_ATLAS).apply(stillTexture); TextureAtlasSprite sprite = Minecraft.getInstance().getTextureAtlas(InventoryMenu.BLOCK_ATLAS).apply(stillTexture);
VertexConsumer consumer = bufferSource.getBuffer(renderType); VertexConsumer consumer = bufferSource.getBuffer(renderType);
float percent = ((float) amount / (float) capacity); float percent = ((float) amount / (float) capacity);
end.y = start.y() + (percent * (end.y() - start.y())); float newY = start.y() + (percent * (end.y() - start.y()));
Vector3f newEnd = new Vector3f(end.x(), newY, end.z());
cuboid(consumer, poseStack, blockPos, start, end, sprite, packedLight, tintColor); cuboid(consumer, poseStack, start, newEnd, sprite, packedLight, tintColor);
} }
public static void renderFluidBox(FluidStack fluidStack, public static void renderFluidBox(FluidStack fluidStack,
@ -130,15 +138,14 @@ public class RenderUtils {
long amount, long amount,
long capacity, long capacity,
Vector3f start, Vector3f start,
Vector3f end, Vector3f end
BlockPos blockPos
) { ) {
IClientFluidTypeExtensions extensions = IClientFluidTypeExtensions.of(fluidStack.getFluid()); IClientFluidTypeExtensions extensions = IClientFluidTypeExtensions.of(fluidStack.getFluid());
ResourceLocation stillTexture = extensions.getStillTexture(); ResourceLocation stillTexture = extensions.getStillTexture();
int tintColor = extensions.getTintColor(fluidStack); int tintColor = extensions.getTintColor(fluidStack);
RenderType renderType = ItemBlockRenderTypes.getRenderLayer(fluidStack.getFluid().defaultFluidState()); RenderType renderType = ItemBlockRenderTypes.getRenderLayer(fluidStack.getFluid().defaultFluidState());
renderFluidBox( renderFluidBox(
stack, bufferSource, packedLight, renderType, stillTexture, tintColor, amount, capacity, start, end, blockPos stack, bufferSource, packedLight, renderType, stillTexture, tintColor, amount, capacity, start, end
); );
} }
} }

View File

@ -6,7 +6,11 @@
*/ */
package robaertschi.environmenttech.command; package robaertschi.environmenttech.command;
import net.neoforged.neoforge.server.command.EnumArgument;
import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.arguments.coordinates.BlockPosArgument;
import net.minecraft.commands.arguments.coordinates.WorldCoordinates;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
@ -16,6 +20,8 @@ import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.LongArgumentType; import com.mojang.brigadier.arguments.LongArgumentType;
import robaertschi.environmenttech.data.attachments.ETAttachments; import robaertschi.environmenttech.data.attachments.ETAttachments;
import robaertschi.environmenttech.data.capabilities.ETCapabilities;
import robaertschi.environmenttech.data.capabilities.EnvType;
import static net.minecraft.commands.Commands.*; import static net.minecraft.commands.Commands.*;
@ -48,6 +54,19 @@ public class EnvironmenttechCommand {
return 1; return 1;
})) }))
.then(literal("set_env").then(argument("pos", BlockPosArgument.blockPos()).then(argument("env_type", EnumArgument.enumArgument(EnvType.class)).then(argument("amount", LongArgumentType.longArg(0)).executes(
context -> {
WorldCoordinates pos = context.getArgument("pos", WorldCoordinates.class);
EnvType type = context.getArgument("env_type", EnvType.class);
long amount = context.getArgument("amount", Long.class);
var cap = context.getSource().getPlayerOrException().level().getCapability(ETCapabilities.ENV_STORAGE_BLOCK, pos.getBlockPos(context.getSource()), type);
if (cap != null) {
cap.receiveEnv(amount, false);
}
return 1;
}
)))))
); );
} }
} }

View File

@ -10,18 +10,18 @@ import lombok.extern.slf4j.Slf4j;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.phys.shapes.BooleanOp;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.block.*; import net.minecraft.world.level.block.*;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.shapes.BooleanOp;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import com.mojang.serialization.MapCodec; import com.mojang.serialization.MapCodec;

View File

@ -11,11 +11,16 @@ import lombok.Getter;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.HolderLookup; import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ClientGamePacketListener;
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.ChunkAccess;
@ -30,6 +35,11 @@ import static robaertschi.environmenttech.ET.MODID;
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
public class EnvDistributorBlockEntity extends BlockEntity implements ITickableBlockEntity { public class EnvDistributorBlockEntity extends BlockEntity implements ITickableBlockEntity {
public static final int TICKS_PER_PROCESS_TICK = 20; // 1 Minute
public static final int REDUCE_PER_PROCESS_TICK = 5;
private int ticksBetweenProcessTick = 0;
public static final String ENV_TAG = "Env"; public static final String ENV_TAG = "Env";
private final EnvStorage envStorage = new EnvStorage(EnvType.Chunk, 64) { private final EnvStorage envStorage = new EnvStorage(EnvType.Chunk, 64) {
@Override @Override
@ -37,7 +47,15 @@ public class EnvDistributorBlockEntity extends BlockEntity implements ITickableB
EnvDistributorBlockEntity.this.setChanged(); EnvDistributorBlockEntity.this.setChanged();
assert level != null; assert level != null;
if (!level.isClientSide()) { if (!level.isClientSide()) {
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3); level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), Block.UPDATE_ALL);
}
}
@Override
public void setEnvStored(long env) {
super.setEnvStored(env);
if (level != null && !level.isClientSide()) {
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), Block.UPDATE_ALL);
} }
} }
}; };
@ -63,11 +81,39 @@ public class EnvDistributorBlockEntity extends BlockEntity implements ITickableB
@Override @Override
public void serverTick(ServerLevel level, BlockPos blockPos, BlockState blockState) { public void serverTick(ServerLevel level, BlockPos blockPos, BlockState blockState) {
if (envStorage.getEnvStored() > 0) {
ChunkAccess chunk = level.getChunk(blockPos); if (ticksBetweenProcessTick < TICKS_PER_PROCESS_TICK) {
long value = Math.min(5, envStorage.getEnvStored()); ticksBetweenProcessTick++;
chunk.setData(ETAttachments.ENV, chunk.getData(ETAttachments.ENV) + value); return;
envStorage.setEnvStored(envStorage.getEnvStored() - value); } else {
ticksBetweenProcessTick = 0;
} }
if (envStorage.getEnvStored() > 0) {
// ES = 1
long amount = REDUCE_PER_PROCESS_TICK;
// 1 - 5 = -4
long result = envStorage.getEnvStored() - amount;
if ( result < 0 ) {
// -4 + 5 = 1
amount = result + amount;
}
ChunkAccess chunk = level.getChunk(blockPos);
chunk.setData(ETAttachments.ENV, chunk.getData(ETAttachments.ENV) + amount);
envStorage.setEnvStored(envStorage.getEnvStored() - amount);
}
}
@Nullable
@Override
public Packet<ClientGamePacketListener> getUpdatePacket() {
return ClientboundBlockEntityDataPacket.create(this);
}
@Override
public @NotNull CompoundTag getUpdateTag(HolderLookup.Provider registries) {
return saveWithoutMetadata(registries);
} }
} }

View File

@ -1,26 +1,62 @@
/*
* EnvironmentTech Copyright (C) 2024 Robin Bärtschi
* This program comes with ABSOLUTELY NO WARRANTY; for details open the file LICENSE at the root of the source code.
* This is free software, and you are welcome to redistribute it
* under certain conditions; read the LICENSE file at the root of the source code for details.
*/
package robaertschi.environmenttech.level.block.entity.renderer; package robaertschi.environmenttech.level.block.entity.renderer;
import com.mojang.blaze3d.vertex.PoseStack; import lombok.extern.slf4j.Slf4j;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import robaertschi.environmenttech.level.block.entity.EnvDistributorBlockEntity;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
import net.neoforged.neoforge.fluids.FluidStack;
import org.joml.Vector3f;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import net.minecraft.world.phys.Vec3;
import com.mojang.blaze3d.vertex.PoseStack;
import robaertschi.environmenttech.client.RenderUtils;
import robaertschi.environmenttech.level.block.entity.EnvDistributorBlockEntity;
import robaertschi.environmenttech.level.fluid.ETFluids;
@Slf4j
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
public class EnvDistributorRenderer implements BlockEntityRenderer<EnvDistributorBlockEntity> { public class EnvDistributorRenderer implements BlockEntityRenderer<EnvDistributorBlockEntity> {
private static final FluidStack ENV_STACK = new FluidStack(ETFluids.ENV_STILL, 1);
@SuppressWarnings("unused") @SuppressWarnings("unused")
public EnvDistributorRenderer(BlockEntityRendererProvider.Context context) {} public EnvDistributorRenderer(BlockEntityRendererProvider.Context context) {
}
@Override @Override
public void render(EnvDistributorBlockEntity blockEntity, float partialTick, PoseStack poseStack, MultiBufferSource bufferSource, int packedLight, int packedOverlay) { public void render(EnvDistributorBlockEntity blockEntity, float partialTick, PoseStack poseStack, MultiBufferSource bufferSource, int packedLight, int packedOverlay) {
poseStack.pushPose();
poseStack.translate(0, 5, 0);
final float pixel = 1f / 16f;
poseStack.translate(pixel + 0.01f, pixel, pixel + 0.01f);
if (blockEntity.getEnvStorage().getEnvStored() <= 0) {
return;
}
poseStack.popPose(); RenderUtils.renderFluidBox(
ENV_STACK, poseStack, bufferSource, packedLight, blockEntity.getEnvStorage().getEnvStored(), blockEntity.getEnvStorage().getMaxEnv(),
new Vector3f(0f, 0f, 0f), new Vector3f(pixel * 14 - 0.02f, pixel * 5, pixel * 14 - 0.02f)
);
}
@Override
public boolean shouldRender(EnvDistributorBlockEntity blockEntity, Vec3 cameraPos) {
return true;
}
@Override
public boolean shouldRenderOffScreen(EnvDistributorBlockEntity blockEntity) {
return true;
} }
} }

View File

@ -1,17 +1,25 @@
/*
* EnvironmentTech Copyright (C) 2024 Robin Bärtschi
* This program comes with ABSOLUTELY NO WARRANTY; for details open the file LICENSE at the root of the source code.
* This is free software, and you are welcome to redistribute it
* under certain conditions; read the LICENSE file at the root of the source code for details.
*/
package robaertschi.environmenttech.level.fluid; package robaertschi.environmenttech.level.fluid;
import net.minecraft.MethodsReturnNonnullByDefault; import java.util.function.Consumer;
import net.minecraft.resources.ResourceLocation; import javax.annotation.ParametersAreNonnullByDefault;
import net.neoforged.bus.api.IEventBus; import net.neoforged.bus.api.IEventBus;
import net.neoforged.neoforge.client.extensions.common.IClientFluidTypeExtensions; import net.neoforged.neoforge.client.extensions.common.IClientFluidTypeExtensions;
import net.neoforged.neoforge.fluids.FluidType; import net.neoforged.neoforge.fluids.FluidType;
import net.neoforged.neoforge.registries.DeferredHolder; import net.neoforged.neoforge.registries.DeferredHolder;
import net.neoforged.neoforge.registries.DeferredRegister; import net.neoforged.neoforge.registries.DeferredRegister;
import net.neoforged.neoforge.registries.NeoForgeRegistries; import net.neoforged.neoforge.registries.NeoForgeRegistries;
import robaertschi.environmenttech.client.renderer.EnvStorageRenderer;
import javax.annotation.ParametersAreNonnullByDefault; import net.minecraft.MethodsReturnNonnullByDefault;
import java.util.function.Consumer; import net.minecraft.resources.ResourceLocation;
import robaertschi.environmenttech.client.renderer.EnvStorageRenderer;
import static robaertschi.environmenttech.ET.MODID; import static robaertschi.environmenttech.ET.MODID;

View File

@ -1,12 +1,19 @@
/*
* EnvironmentTech Copyright (C) 2024 Robin Bärtschi
* This program comes with ABSOLUTELY NO WARRANTY; for details open the file LICENSE at the root of the source code.
* This is free software, and you are welcome to redistribute it
* under certain conditions; read the LICENSE file at the root of the source code for details.
*/
package robaertschi.environmenttech.level.fluid; package robaertschi.environmenttech.level.fluid;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.world.level.material.Fluid;
import net.neoforged.bus.api.IEventBus; import net.neoforged.bus.api.IEventBus;
import net.neoforged.neoforge.fluids.BaseFlowingFluid; import net.neoforged.neoforge.fluids.BaseFlowingFluid;
import net.neoforged.neoforge.registries.DeferredHolder; import net.neoforged.neoforge.registries.DeferredHolder;
import net.neoforged.neoforge.registries.DeferredRegister; import net.neoforged.neoforge.registries.DeferredRegister;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.world.level.material.Fluid;
import static robaertschi.environmenttech.ET.MODID; import static robaertschi.environmenttech.ET.MODID;
public class ETFluids { public class ETFluids {