package com.thebrokenrail.energonrelics.mixin; import com.thebrokenrail.energonrelics.block.forcefield.util.BeamBlock; import net.minecraft.block.Block; import net.minecraft.entity.Entity; import net.minecraft.nbt.CompoundTag; import net.minecraft.server.MinecraftServer; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Box; import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.util.function.Predicate; @Mixin(Entity.class) public abstract class MixinEntity { @Shadow public abstract Box getBoundingBox(); @Shadow public abstract World getEntityWorld(); @Shadow public abstract MinecraftServer getServer(); @Unique private boolean isTouching(Predicate test) { if (getServer() == null || getServer().getThread() == Thread.currentThread()) { Box box = getBoundingBox(); int i = MathHelper.floor(box.minX); int j = MathHelper.ceil(box.maxX); int k = MathHelper.floor(box.minY); int l = MathHelper.ceil(box.maxY); int m = MathHelper.floor(box.minZ); int n = MathHelper.ceil(box.maxZ); for (int p = i; p < j; ++p) { for (int q = k; q < l; ++q) { for (int r = m; r < n; ++r) { BlockPos pos = new BlockPos(p, q, r); if (test.test(getEntityWorld().getBlockState(pos).getBlock())) { return true; } } } } } return false; } @Unique private boolean saving = false; @Inject(at = @At("HEAD"), method = "hasNoGravity", cancellable = true) public void hasNoGravity(CallbackInfoReturnable info) { if (isTouching(block -> block instanceof BeamBlock) && !saving) { info.setReturnValue(true); } } @Inject(at = @At("HEAD"), method = "toTag") public void tagTagHead(CompoundTag tag, CallbackInfoReturnable info) { saving = true; } @Inject(at = @At("RETURN"), method = "toTag") public void tagTagReturn(CompoundTag tag, CallbackInfoReturnable info) { saving = false; } }