From 76293f5e7077ed8b4eb2ca40b3c9f7e4355ce5b5 Mon Sep 17 00:00:00 2001 From: thedarkcolour <30441001+thedarkcolour@users.noreply.github.com> Date: Wed, 12 Jun 2024 12:03:23 -0700 Subject: [PATCH] Fluids in barrels and crucibles now affect mobs --- .../exdeorum/block/AbstractCrucibleBlock.java | 13 ++++- .../exdeorum/block/BarrelBlock.java | 19 +++++-- .../exdeorum/block/ETankBlock.java | 53 +++++++++++++++++++ .../exdeorum/block/WitchWaterBlock.java | 9 +++- .../AbstractCrucibleBlockEntity.java | 3 +- .../blockentity/BarrelBlockEntity.java | 3 +- .../blockentity/ETankBlockEntity.java | 33 ++++++++++++ .../exdeorum/client/ter/BarrelRenderer.java | 7 +-- .../exdeorum/client/ter/CrucibleRenderer.java | 5 +- 9 files changed, 132 insertions(+), 13 deletions(-) create mode 100644 src/main/java/thedarkcolour/exdeorum/block/ETankBlock.java create mode 100644 src/main/java/thedarkcolour/exdeorum/blockentity/ETankBlockEntity.java diff --git a/src/main/java/thedarkcolour/exdeorum/block/AbstractCrucibleBlock.java b/src/main/java/thedarkcolour/exdeorum/block/AbstractCrucibleBlock.java index 3cdf38cd..5084f39a 100644 --- a/src/main/java/thedarkcolour/exdeorum/block/AbstractCrucibleBlock.java +++ b/src/main/java/thedarkcolour/exdeorum/block/AbstractCrucibleBlock.java @@ -19,6 +19,8 @@ package thedarkcolour.exdeorum.block; import net.minecraft.core.BlockPos; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.Entity; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; @@ -33,7 +35,10 @@ import thedarkcolour.exdeorum.registry.EBlockEntities; import java.util.function.Supplier; -public abstract class AbstractCrucibleBlock extends EBlock { +public abstract class AbstractCrucibleBlock extends ETankBlock { + public static final float CRUCIBLE_FLUID_BOTTOM = 4.0f / 16f; + public static final float CRUCIBLE_FLUID_TOP = 14.0f / 16f; + public AbstractCrucibleBlock(Properties properties, Supplier> blockEntityType) { super(properties, blockEntityType); } @@ -58,4 +63,10 @@ public abstract class AbstractCrucibleBlock extends EBlock { public BlockEntityTicker getTicker(Level level, BlockState pState, BlockEntityType type) { return (type == EBlockEntities.WATER_CRUCIBLE.get() || type == EBlockEntities.LAVA_CRUCIBLE.get()) ? (BlockEntityTicker) new AbstractCrucibleBlockEntity.Ticker() : null; } + + @Override + protected boolean isEntityInFluid(Level level, BlockPos pos, Entity entity, float fillRatio) { + var fluidTop = Mth.lerp(fillRatio, CRUCIBLE_FLUID_BOTTOM, CRUCIBLE_FLUID_TOP); + return entity.getY() < pos.getY() + fluidTop && entity.getBoundingBox().maxY > pos.getY() + CRUCIBLE_FLUID_BOTTOM; + } } diff --git a/src/main/java/thedarkcolour/exdeorum/block/BarrelBlock.java b/src/main/java/thedarkcolour/exdeorum/block/BarrelBlock.java index cda9b841..dd7e8a8e 100644 --- a/src/main/java/thedarkcolour/exdeorum/block/BarrelBlock.java +++ b/src/main/java/thedarkcolour/exdeorum/block/BarrelBlock.java @@ -19,6 +19,8 @@ package thedarkcolour.exdeorum.block; import net.minecraft.core.BlockPos; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.Entity; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; @@ -34,11 +36,14 @@ import org.jetbrains.annotations.Nullable; import thedarkcolour.exdeorum.blockentity.BarrelBlockEntity; import thedarkcolour.exdeorum.registry.EBlockEntities; -public class BarrelBlock extends EBlock { +public class BarrelBlock extends ETankBlock { + public static final float BARREL_FLUID_BOTTOM = 1f / 16f; + public static final float BARREL_FLUID_TOP = 14f / 16f; + public static final VoxelShape SHAPE = Shapes.join( - box(1, 0, 1, 15, 16, 15), - box(2, 1, 2, 14, 16, 14), - BooleanOp.ONLY_FIRST + box(1, 0, 1, 15, 16, 15), + box(2, 1, 2, 14, 16, 14), + BooleanOp.ONLY_FIRST ); public BarrelBlock(Properties properties) { @@ -88,6 +93,12 @@ public class BarrelBlock extends EBlock { } } + @Override + protected boolean isEntityInFluid(Level level, BlockPos pos, Entity entity, float fillRatio) { + var fluidTop = Mth.lerp(fillRatio, BARREL_FLUID_BOTTOM, BARREL_FLUID_TOP); + return entity.getBoundingBox().intersects(pos.getX() + 0.125, pos.getY() + BARREL_FLUID_BOTTOM, pos.getZ() + 0.125, pos.getX() + 0.875, pos.getY() + fluidTop, pos.getZ() + 0.875); + } + @Override public int getLightEmission(BlockState state, BlockGetter level, BlockPos pos) { var lightManager = level.getAuxLightManager(pos); diff --git a/src/main/java/thedarkcolour/exdeorum/block/ETankBlock.java b/src/main/java/thedarkcolour/exdeorum/block/ETankBlock.java new file mode 100644 index 00000000..ee26311d --- /dev/null +++ b/src/main/java/thedarkcolour/exdeorum/block/ETankBlock.java @@ -0,0 +1,53 @@ +package thedarkcolour.exdeorum.block; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.Fluids; +import net.neoforged.neoforge.common.EffectCures; +import net.neoforged.neoforge.common.NeoForgeMod; +import net.neoforged.neoforge.fluids.FluidStack; +import thedarkcolour.exdeorum.blockentity.ETankBlockEntity; +import thedarkcolour.exdeorum.registry.EFluids; + +import java.util.function.Supplier; + +// Base class for blocks that hold fluids (crucible, barrel) +public abstract class ETankBlock extends EBlock { + public ETankBlock(BlockBehaviour.Properties properties, Supplier> blockEntityType) { + super(properties, blockEntityType); + } + + @Override + public void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) { + if (!level.isClientSide && level.getBlockEntity(pos) instanceof ETankBlockEntity blockEntity) { + var tank = blockEntity.getTank(); + var fluid = tank.getFluid(); + + if (!fluid.isEmpty() && isEntityInFluid(level, pos, entity, (float) fluid.getAmount() / tank.getCapacity())) { + entityInFluidLogic(level, entity, fluid); + } + } + } + + protected abstract boolean isEntityInFluid(Level level, BlockPos pos, Entity entity, float fillRatio); + + // Only call this on the server + public static void entityInFluidLogic(Level level, Entity entity, FluidStack fluid) { + var fluidType = fluid.getFluid(); + + if (fluidType == Fluids.LAVA) { + entity.lavaHurt(); + } else if (fluidType == EFluids.WITCH_WATER.get()) { + WitchWaterBlock.witchWaterEntityEffects(level, entity); + } else if (fluidType.getFluidType().canExtinguish(entity)) { + entity.extinguishFire(); + } else if (entity instanceof LivingEntity living && NeoForgeMod.MILK.isBound() && fluidType == NeoForgeMod.MILK.get()) { + living.removeEffectsCuredBy(EffectCures.MILK); + } + } +} diff --git a/src/main/java/thedarkcolour/exdeorum/block/WitchWaterBlock.java b/src/main/java/thedarkcolour/exdeorum/block/WitchWaterBlock.java index 771b5e94..f14fd17d 100644 --- a/src/main/java/thedarkcolour/exdeorum/block/WitchWaterBlock.java +++ b/src/main/java/thedarkcolour/exdeorum/block/WitchWaterBlock.java @@ -49,7 +49,14 @@ public class WitchWaterBlock extends LiquidBlock { @Override public void entityInside(BlockState pState, Level level, BlockPos pPos, Entity entity) { - if (!level.isClientSide && entity.isAlive()) { + if (!level.isClientSide) { + witchWaterEntityEffects(level, entity); + } + } + + // Only call on server + public static void witchWaterEntityEffects(Level level, Entity entity) { + if (entity.isAlive()) { var entityType = entity.getType(); if (EConfig.SERVER.allowWitchWaterEntityConversion.get()) { diff --git a/src/main/java/thedarkcolour/exdeorum/blockentity/AbstractCrucibleBlockEntity.java b/src/main/java/thedarkcolour/exdeorum/blockentity/AbstractCrucibleBlockEntity.java index 6da3571e..988c1949 100644 --- a/src/main/java/thedarkcolour/exdeorum/blockentity/AbstractCrucibleBlockEntity.java +++ b/src/main/java/thedarkcolour/exdeorum/blockentity/AbstractCrucibleBlockEntity.java @@ -58,7 +58,7 @@ import thedarkcolour.exdeorum.registry.EItems; import java.util.HashMap; import java.util.function.Consumer; -public abstract class AbstractCrucibleBlockEntity extends EBlockEntity { +public abstract class AbstractCrucibleBlockEntity extends ETankBlockEntity { public static final Lazy> MELT_OVERRIDES = Lazy.concurrentOf(() -> { var map = new HashMap(); addMeltOverrides(map); @@ -244,6 +244,7 @@ public abstract class AbstractCrucibleBlockEntity extends EBlockEntity { return this.solids; } + @Override public FluidTank getTank() { return this.tank; } diff --git a/src/main/java/thedarkcolour/exdeorum/blockentity/BarrelBlockEntity.java b/src/main/java/thedarkcolour/exdeorum/blockentity/BarrelBlockEntity.java index 8f9f10e1..4f6812ab 100644 --- a/src/main/java/thedarkcolour/exdeorum/blockentity/BarrelBlockEntity.java +++ b/src/main/java/thedarkcolour/exdeorum/blockentity/BarrelBlockEntity.java @@ -66,7 +66,7 @@ import thedarkcolour.exdeorum.recipe.barrel.FluidTransformationRecipe; import thedarkcolour.exdeorum.registry.EBlockEntities; import thedarkcolour.exdeorum.registry.ESounds; -public class BarrelBlockEntity extends EBlockEntity { +public class BarrelBlockEntity extends ETankBlockEntity { private static final int MOSS_SPREAD_RANGE = 2; private static final int MAX_CAPACITY = 1000; @@ -203,6 +203,7 @@ public class BarrelBlockEntity extends EBlockEntity { this.item.setStackInSlot(0, item); } + @Override public FluidTank getTank() { return this.tank; } diff --git a/src/main/java/thedarkcolour/exdeorum/blockentity/ETankBlockEntity.java b/src/main/java/thedarkcolour/exdeorum/blockentity/ETankBlockEntity.java new file mode 100644 index 00000000..9727ab59 --- /dev/null +++ b/src/main/java/thedarkcolour/exdeorum/blockentity/ETankBlockEntity.java @@ -0,0 +1,33 @@ +/* + * Ex Deorum + * Copyright (c) 2024 thedarkcolour + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package thedarkcolour.exdeorum.blockentity; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.neoforged.neoforge.fluids.IFluidTank; + +// Base class for blocks that hold fluids (crucible, barrel) +public abstract class ETankBlockEntity extends EBlockEntity { + public ETankBlockEntity(BlockEntityType type, BlockPos pos, BlockState state) { + super(type, pos, state); + } + + public abstract IFluidTank getTank(); +} diff --git a/src/main/java/thedarkcolour/exdeorum/client/ter/BarrelRenderer.java b/src/main/java/thedarkcolour/exdeorum/client/ter/BarrelRenderer.java index 6da8935c..f0d00380 100644 --- a/src/main/java/thedarkcolour/exdeorum/client/ter/BarrelRenderer.java +++ b/src/main/java/thedarkcolour/exdeorum/client/ter/BarrelRenderer.java @@ -35,6 +35,7 @@ import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.ItemDisplayContext; import net.neoforged.neoforge.client.model.data.ModelData; import thedarkcolour.exdeorum.ExDeorum; +import thedarkcolour.exdeorum.block.BarrelBlock; import thedarkcolour.exdeorum.blockentity.BarrelBlockEntity; import thedarkcolour.exdeorum.client.RenderUtil; import thedarkcolour.exdeorum.config.EConfig; @@ -84,7 +85,7 @@ public class BarrelRenderer implements BlockEntityRenderer { var level = Objects.requireNonNull(barrel.getLevel()); var pos = barrel.getBlockPos(); var percentage = fluidStack.getAmount() / 1000.0f; - var y = Mth.lerp(percentage, 1.0f, 14.0f) / 16f; + var y = Mth.lerp(percentage, BarrelBlock.BARREL_FLUID_BOTTOM, BarrelBlock.BARREL_FLUID_TOP); var inputFluidColor = RenderUtil.getFluidColor(fluid, level, pos); // Split into RGB components var r = (inputFluidColor >> 16) & 0xff; @@ -101,7 +102,7 @@ public class BarrelRenderer implements BlockEntityRenderer { } if (barrel.transparent) { - RenderUtil.renderFluidCube(buffers, stack, level, pos, 1 / 16f, y, 2.0f, light, r, g, b, fluid); + RenderUtil.renderFluidCube(buffers, stack, level, pos, BarrelBlock.BARREL_FLUID_BOTTOM, y, 2.0f, light, r, g, b, fluid); } else { RenderUtil.renderFlatFluidSprite(buffers, stack, level, pos, y, 2.0f, light, r, g, b, fluid); } @@ -131,7 +132,7 @@ public class BarrelRenderer implements BlockEntityRenderer { g = (int) Mth.lerp(compostProgress, g, 169); // default green is b = (int) Mth.lerp(compostProgress, b, 109); // default green is - RenderUtil.renderFlatSpriteLerp(builder, stack, barrel.compost / 1000.0f, r, g, b, sprite, light, 2.0f, 1.0f, 14.0f); + RenderUtil.renderFlatSpriteLerp(builder, stack, barrel.compost / 1000.0f, r, g, b, sprite, light, 2.0f, BarrelBlock.BARREL_FLUID_BOTTOM * 16f, BarrelBlock.BARREL_FLUID_TOP * 16f); } } } diff --git a/src/main/java/thedarkcolour/exdeorum/client/ter/CrucibleRenderer.java b/src/main/java/thedarkcolour/exdeorum/client/ter/CrucibleRenderer.java index 36a588a7..b99d49e0 100644 --- a/src/main/java/thedarkcolour/exdeorum/client/ter/CrucibleRenderer.java +++ b/src/main/java/thedarkcolour/exdeorum/client/ter/CrucibleRenderer.java @@ -23,6 +23,7 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; import net.minecraft.util.Mth; +import thedarkcolour.exdeorum.block.AbstractCrucibleBlock; import thedarkcolour.exdeorum.blockentity.AbstractCrucibleBlockEntity; import thedarkcolour.exdeorum.client.RenderUtil; @@ -45,7 +46,7 @@ public class CrucibleRenderer implements BlockEntityRenderer> 16) & 0xff, (color >> 8) & 0xff, color & 0xff, fluid); } @@ -62,7 +63,7 @@ public class CrucibleRenderer implements BlockEntityRenderer> 16) & 0xff, (color >> 8) & 0xff, color & 0xff, light, 2.0f, 4.0f, 14.0f); + face.renderFlatSpriteLerp(buffers, stack, solids, (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff, light, 2.0f, AbstractCrucibleBlock.CRUCIBLE_FLUID_BOTTOM * 16f, AbstractCrucibleBlock.CRUCIBLE_FLUID_TOP * 16f); } }