From 5b0ba2ef31583ac1739ae2602ff1981c263bed5b Mon Sep 17 00:00:00 2001 From: thedarkcolour <30441001+thedarkcolour@users.noreply.github.com> Date: Sat, 8 Jun 2024 16:47:49 -0700 Subject: [PATCH] Fluids in barrels and crucibles now affect mobs --- .../exdeorum/block/AbstractCrucibleBlock.java | 13 +++- .../exdeorum/block/BarrelBlock.java | 20 ++++-- .../exdeorum/block/ETankBlock.java | 71 +++++++++++++++++++ .../exdeorum/block/WitchWaterBlock.java | 11 ++- .../AbstractCrucibleBlockEntity.java | 3 +- .../blockentity/BarrelBlockEntity.java | 3 +- .../blockentity/ETankBlockEntity.java | 33 +++++++++ .../exdeorum/client/ter/BarrelRenderer.java | 7 +- .../exdeorum/client/ter/CrucibleRenderer.java | 7 +- .../exdeorum/item/PorcelainMilkBucket.java | 11 --- 10 files changed, 153 insertions(+), 26 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 a3e62813..2e9775c1 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); } @@ -57,4 +62,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 90d59021..86ad56b8 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; @@ -26,6 +28,7 @@ import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityTicker; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.shapes.BooleanOp; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.Shapes; @@ -34,11 +37,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) { @@ -87,4 +93,10 @@ 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); + } } 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..2189c73c --- /dev/null +++ b/src/main/java/thedarkcolour/exdeorum/block/ETankBlock.java @@ -0,0 +1,71 @@ +/* + * 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.block; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.Fluids; +import net.minecraftforge.common.ForgeMod; +import net.minecraftforge.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(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 && ForgeMod.MILK.isPresent() && fluidType == ForgeMod.MILK.get()) { + living.curePotionEffects(new ItemStack(Items.MILK_BUCKET)); + } + } +} diff --git a/src/main/java/thedarkcolour/exdeorum/block/WitchWaterBlock.java b/src/main/java/thedarkcolour/exdeorum/block/WitchWaterBlock.java index 2ecf496c..bd82d0fc 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()) { @@ -70,7 +77,7 @@ public class WitchWaterBlock extends LiquidBlock { zombieVillager.setTradeOffers(villager.getOffers().createTag()); zombieVillager.setVillagerXp(villager.getVillagerXp()); - net.minecraftforge.event.ForgeEventFactory.onLivingConvert(villager, zombieVillager); + ForgeEventFactory.onLivingConvert(villager, zombieVillager); villager.discard(); } diff --git a/src/main/java/thedarkcolour/exdeorum/blockentity/AbstractCrucibleBlockEntity.java b/src/main/java/thedarkcolour/exdeorum/blockentity/AbstractCrucibleBlockEntity.java index dbf284b3..b10ea88c 100644 --- a/src/main/java/thedarkcolour/exdeorum/blockentity/AbstractCrucibleBlockEntity.java +++ b/src/main/java/thedarkcolour/exdeorum/blockentity/AbstractCrucibleBlockEntity.java @@ -63,7 +63,7 @@ import java.util.HashMap; import java.util.function.Consumer; @SuppressWarnings("deprecation") -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); @@ -248,6 +248,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 750f3acc..157ef687 100644 --- a/src/main/java/thedarkcolour/exdeorum/blockentity/BarrelBlockEntity.java +++ b/src/main/java/thedarkcolour/exdeorum/blockentity/BarrelBlockEntity.java @@ -67,7 +67,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; @@ -209,6 +209,7 @@ public class BarrelBlockEntity extends EBlockEntity { this.item.setStackInSlot(0, item); } + @Override public IFluidTank 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..3faf2a9c --- /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.minecraftforge.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 007ca501..1d9eb69c 100644 --- a/src/main/java/thedarkcolour/exdeorum/client/ter/BarrelRenderer.java +++ b/src/main/java/thedarkcolour/exdeorum/client/ter/BarrelRenderer.java @@ -36,6 +36,7 @@ import net.minecraft.world.item.ItemDisplayContext; import net.minecraftforge.client.model.data.ModelData; import net.minecraftforge.common.capabilities.ForgeCapabilities; import thedarkcolour.exdeorum.ExDeorum; +import thedarkcolour.exdeorum.block.BarrelBlock; import thedarkcolour.exdeorum.blockentity.BarrelBlockEntity; import thedarkcolour.exdeorum.client.RenderUtil; @@ -81,7 +82,7 @@ public class BarrelRenderer implements BlockEntityRenderer { var level = 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; @@ -98,7 +99,7 @@ public class BarrelRenderer implements BlockEntityRenderer { } if (barrel.transparent) { - RenderUtil.renderFluidCuboid(buffers, stack, level, pos, 1 / 16f, y, 2.0f, light, r, g, b, fluid); + RenderUtil.renderFluidCuboid(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); } @@ -129,7 +130,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, BarrelBlock.BARREL_FLUID_TOP); } } } diff --git a/src/main/java/thedarkcolour/exdeorum/client/ter/CrucibleRenderer.java b/src/main/java/thedarkcolour/exdeorum/client/ter/CrucibleRenderer.java index 485f7a7a..cf4922d5 100644 --- a/src/main/java/thedarkcolour/exdeorum/client/ter/CrucibleRenderer.java +++ b/src/main/java/thedarkcolour/exdeorum/client/ter/CrucibleRenderer.java @@ -24,6 +24,7 @@ import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; import net.minecraft.util.Mth; import net.minecraftforge.common.capabilities.ForgeCapabilities; +import thedarkcolour.exdeorum.block.AbstractCrucibleBlock; import thedarkcolour.exdeorum.blockentity.AbstractCrucibleBlockEntity; import thedarkcolour.exdeorum.client.RenderUtil; @@ -46,14 +47,14 @@ public class CrucibleRenderer implements BlockEntityRenderer> 16) & 0xff; int g = (color >> 8) & 0xff; int b = color & 0xff; if (crucible.transparent) { - RenderUtil.renderFluidCuboid(buffers, stack, level, pos, 4 / 16f, y, 2.0f, light, r, g, b, fluid); + RenderUtil.renderFluidCuboid(buffers, stack, level, pos, AbstractCrucibleBlock.CRUCIBLE_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); } @@ -72,7 +73,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, AbstractCrucibleBlock.CRUCIBLE_FLUID_TOP); } } }); diff --git a/src/main/java/thedarkcolour/exdeorum/item/PorcelainMilkBucket.java b/src/main/java/thedarkcolour/exdeorum/item/PorcelainMilkBucket.java index 1fbc762c..cd67c590 100644 --- a/src/main/java/thedarkcolour/exdeorum/item/PorcelainMilkBucket.java +++ b/src/main/java/thedarkcolour/exdeorum/item/PorcelainMilkBucket.java @@ -51,15 +51,4 @@ public class PorcelainMilkBucket extends MilkBucketItem { public @Nullable ICapabilityProvider initCapabilities(ItemStack stack, @Nullable CompoundTag nbt) { return new PorcelainBucket.CapabilityProvider(stack); } - - private static class CapabilityProvider extends PorcelainBucket.CapabilityProvider { - public CapabilityProvider(@NotNull ItemStack container) { - super(container); - } - - @Override - public boolean isFluidValid(int tank, @NotNull FluidStack stack) { - return ForgeMod.MILK.isPresent(); - } - } }