diff --git a/src/main/java/com/simibubi/create/content/equipment/armor/DivingHelmetItem.java b/src/main/java/com/simibubi/create/content/equipment/armor/DivingHelmetItem.java index a322c418bc..7f334c0752 100644 --- a/src/main/java/com/simibubi/create/content/equipment/armor/DivingHelmetItem.java +++ b/src/main/java/com/simibubi/create/content/equipment/armor/DivingHelmetItem.java @@ -68,7 +68,7 @@ public static ItemStack getWornItem(Entity entity) { return stack; } - public static void breatheUnderwater(LivingEntity entity) { + public static boolean breatheUnderwater(LivingEntity entity) { // LivingEntity entity = event.getEntityLiving(); Level world = entity.level(); boolean second = world.getGameTime() % 20 == 0; @@ -79,19 +79,19 @@ public static void breatheUnderwater(LivingEntity entity) { ItemStack helmet = getWornItem(entity); if (helmet.isEmpty()) - return; + return false; boolean lavaDiving = entity.isInLava(); if (!helmet.getItem().isFireResistant() && lavaDiving) - return; + return false; if (!entity.isEyeInFluid(AllFluidTags.DIVING_FLUIDS.tag) && !lavaDiving) - return; + return false; if (entity instanceof Player player && (player.isSpectator() || player.isCreative())) - return; + return false; List backtanks = BacktankUtil.getAllWithAir(entity); if (backtanks.isEmpty()) - return; + return false; if (lavaDiving) { if (entity instanceof ServerPlayer sp) @@ -99,7 +99,7 @@ public static void breatheUnderwater(LivingEntity entity) { if (backtanks.stream() .noneMatch(backtank -> backtank.getItem() .isFireResistant())) - return; + return false; } float visualBacktankAir = 0f; @@ -114,12 +114,11 @@ public static void breatheUnderwater(LivingEntity entity) { BacktankUtil.consumeAir(entity, backtanks.get(0), 1); if (lavaDiving) - return; + return false; if (entity instanceof ServerPlayer sp) AllAdvancements.DIVING_SUIT.awardTo(sp); - event.setCanBreathe(true); - event.setCanRefillAir(true); + return true; } } diff --git a/src/main/java/com/simibubi/create/content/equipment/armor/RemainingAirOverlay.java b/src/main/java/com/simibubi/create/content/equipment/armor/RemainingAirOverlay.java index 60a2368936..5a99850716 100644 --- a/src/main/java/com/simibubi/create/content/equipment/armor/RemainingAirOverlay.java +++ b/src/main/java/com/simibubi/create/content/equipment/armor/RemainingAirOverlay.java @@ -10,10 +10,12 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.player.LocalPlayer; +import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; import net.minecraft.util.StringUtil; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.GameType; +import net.minecraft.world.level.material.FluidState; public class RemainingAirOverlay { public static void render(GuiGraphics graphics, int width, int height) { @@ -29,7 +31,23 @@ public static void render(GuiGraphics graphics, int width, int height) { if (!player.getCustomData() .contains("VisualBacktankAir")) return; - if (!player.canDrownInFluidType(player.getEyeInFluidType()) && !player.isInLava()) + + //Code from Entity#updateFluidOnEyes + double breatheY = player.getEyeY() - 0.11111111F; + BlockPos blockPos = BlockPos.containing(player.getX(), breatheY, player.getZ()); + FluidState fluidState = player.level().getFluidState(blockPos); + double fluidMaxY = blockPos.getY() + fluidState.getHeight(player.level(), blockPos); + + boolean canDrown = false; + if(fluidMaxY > breatheY) { + if(fluidState.is(FluidTags.WATER)) { + canDrown = true; + } else if(fluidState.getFluidType() != null) { + canDrown = fluidState.getFluidType().canDrownIn(player); + } + } + + if (!canDrown && !player.isInLava()) return; int timeLeft = player.getCustomData() diff --git a/src/main/java/com/simibubi/create/content/logistics/vault/ItemVaultBlockEntity.java b/src/main/java/com/simibubi/create/content/logistics/vault/ItemVaultBlockEntity.java index 8595373016..7bf805b72b 100644 --- a/src/main/java/com/simibubi/create/content/logistics/vault/ItemVaultBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/vault/ItemVaultBlockEntity.java @@ -4,6 +4,10 @@ import java.util.List; import java.util.Set; +import com.simibubi.create.content.redstone.thresholdSwitch.ThresholdSwitchBlockEntity; + +import io.github.fabricators_of_create.porting_lib.block.NeighborChangeListeningBlock; + import org.jetbrains.annotations.Nullable; import com.simibubi.create.AllBlockEntityTypes; @@ -161,17 +165,28 @@ private static void updateComaratorsInner(Level level, Block provokingBlock, Blo return; } + //Will ignore modded comparator-like blocks that don't use Porting Lib + //Not really fixable without removing the optimisation BlockState blockstate = level.getBlockState(updatePos); - blockstate.onNeighborChange(level, updatePos, provokingPos); + updateComparatorAt(level, blockstate, updatePos, provokingBlock, provokingPos); if (blockstate.isRedstoneConductor(level, updatePos)) { updatePos.move(direction); blockstate = level.getBlockState(updatePos); - if (blockstate.getWeakChanges(level, updatePos)) { + //Porting Lib doesn't update here, in contrast to Forge + if (blockstate.is(Blocks.COMPARATOR)) { level.neighborChanged(blockstate, updatePos, provokingBlock, provokingPos, false); } } } + private static void updateComparatorAt(Level level, BlockState blockstate, BlockPos updatePos, Block provokingBlock, BlockPos provokingPos) { + if (blockstate.is(Blocks.COMPARATOR)) { + level.neighborChanged(blockstate, updatePos, provokingBlock, provokingPos, false); + } else if (blockstate.getBlock() instanceof NeighborChangeListeningBlock listener) { + listener.onNeighborChange(blockstate, level, updatePos, provokingPos); + } + } + @Override public void tick() { super.tick(); diff --git a/src/main/java/com/simibubi/create/foundation/events/CommonEvents.java b/src/main/java/com/simibubi/create/foundation/events/CommonEvents.java index 441979c564..24b973856e 100644 --- a/src/main/java/com/simibubi/create/foundation/events/CommonEvents.java +++ b/src/main/java/com/simibubi/create/foundation/events/CommonEvents.java @@ -274,7 +274,6 @@ public static void register() { LivingEntityEvents.KNOCKBACK_STRENGTH.register(ExtendoGripItem::attacksByExtendoGripHaveMoreKnockback); LivingEntityEvents.TICK.register(ExtendoGripItem::holdingExtendoGripIncreasesRange); LivingEntityEvents.TICK.register(DivingBootsItem::accellerateDescentUnderwater); - LivingEntityEvents.TICK.register(DivingHelmetItem::breatheUnderwater); LivingEntityEvents.DROPS.register(CrushingWheelBlockEntity::handleCrushedMobDrops); LivingEntityEvents.LOOTING_LEVEL.register(CrushingWheelBlockEntity::crushingIsFortunate); LivingEntityEvents.DROPS.register(DeployerFakePlayer::deployerCollectsDropsFromKilledEntities); diff --git a/src/main/java/com/simibubi/create/foundation/mixin/fabric/LivingEntityMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/fabric/LivingEntityMixin.java new file mode 100644 index 0000000000..71954d487d --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/mixin/fabric/LivingEntityMixin.java @@ -0,0 +1,18 @@ +package com.simibubi.create.foundation.mixin.fabric; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; + +import com.simibubi.create.content.equipment.armor.DivingHelmetItem; + +import net.minecraft.world.entity.LivingEntity; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(LivingEntity.class) +public class LivingEntityMixin { + @ModifyExpressionValue(method = "baseTick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;isEyeInFluid(Lnet/minecraft/tags/TagKey;)Z")) + private boolean breatheUnderWater(boolean original) { + return original && !DivingHelmetItem.breatheUnderwater((LivingEntity)(Object) this); + } +} diff --git a/src/main/resources/create.mixins.json b/src/main/resources/create.mixins.json index 58a6e4450a..0dd8316812 100644 --- a/src/main/resources/create.mixins.json +++ b/src/main/resources/create.mixins.json @@ -49,6 +49,7 @@ "fabric.BlockableEventLoopAccessor", "fabric.EntityAccessor", "fabric.EntityMixin", + "fabric.LivingEntityMixin", "fabric.ServerGamePacketListenerImplAccessor", "fabric.SortedArraySetAccessor", "fabric.TagAppenderAccessor",