diff --git a/src/main/java/net/blf02/immersivemc/client/immersive/AbstractImmersive.java b/src/main/java/net/blf02/immersivemc/client/immersive/AbstractImmersive.java index 394e260f..6ff246b2 100644 --- a/src/main/java/net/blf02/immersivemc/client/immersive/AbstractImmersive.java +++ b/src/main/java/net/blf02/immersivemc/client/immersive/AbstractImmersive.java @@ -49,6 +49,14 @@ public AbstractImmersive(int maxImmersives) { protected abstract boolean enabledInConfig(); + /** + * Initializes an `info` instance after it's constructed. + * Useful for immersives that have non-changing hitboxes/positions. + * + * @param info Info instance that should be initialized + */ + protected abstract void initInfo(I info); + public abstract void handleRightClick(AbstractImmersiveInfo info, PlayerEntity player, int closest, Hand hand); @@ -60,6 +68,10 @@ public void onRemove(I info) {} public void tick(I info, boolean isInVR) { if (enabledInConfig()) { + if (!info.initCompleted) { + initInfo(info); + info.initCompleted = true; + } doTick(info, isInVR); } } diff --git a/src/main/java/net/blf02/immersivemc/client/immersive/BackpackImmersive.java b/src/main/java/net/blf02/immersivemc/client/immersive/BackpackImmersive.java index c342c406..f89932f4 100644 --- a/src/main/java/net/blf02/immersivemc/client/immersive/BackpackImmersive.java +++ b/src/main/java/net/blf02/immersivemc/client/immersive/BackpackImmersive.java @@ -183,6 +183,11 @@ protected boolean enabledInConfig() { return ActiveConfig.useBackpack; } + @Override + protected void initInfo(BackpackInfo info) { + // NOOP. Backpack moves constantly, so we need to update things for it every tick. + } + @Override public void handleRightClick(AbstractImmersiveInfo info, PlayerEntity player, int closest, Hand hand) {} diff --git a/src/main/java/net/blf02/immersivemc/client/immersive/ImmersiveAnvil.java b/src/main/java/net/blf02/immersivemc/client/immersive/ImmersiveAnvil.java index d2a379d2..41d91ca4 100644 --- a/src/main/java/net/blf02/immersivemc/client/immersive/ImmersiveAnvil.java +++ b/src/main/java/net/blf02/immersivemc/client/immersive/ImmersiveAnvil.java @@ -34,17 +34,14 @@ public ImmersiveAnvil() { } @Override - protected void doTick(AnvilInfo info, boolean isInVR) { - super.doTick(info, isInVR); + protected void initInfo(AnvilInfo info) { + setHitboxes(info); + } + + protected void setHitboxes(AnvilInfo info) { Objects.requireNonNull(Minecraft.getInstance().player); Objects.requireNonNull(Minecraft.getInstance().level); - if (info.anvilPos != null && - Minecraft.getInstance().player.distanceToSqr(Vector3d.atCenterOf(info.anvilPos)) > - CommonConstants.distanceSquaredToRemoveImmersive) { - info.remove(); - } - BlockState anvil = Minecraft.getInstance().level.getBlockState(info.anvilPos); info.isReallyAnvil = isAnvil(anvil); Direction facing; @@ -76,6 +73,33 @@ protected void doTick(AnvilInfo info, boolean isInVR) { info.setHitbox(1, createHitbox(middle, hitboxSize)); info.setHitbox(2, createHitbox(right, hitboxSize)); + info.lastDir = facing; + } + + @Override + protected void doTick(AnvilInfo info, boolean isInVR) { + super.doTick(info, isInVR); + + Objects.requireNonNull(Minecraft.getInstance().player); + if (info.anvilPos != null && + Minecraft.getInstance().player.distanceToSqr(Vector3d.atCenterOf(info.anvilPos)) > + CommonConstants.distanceSquaredToRemoveImmersive) { + info.remove(); + } + + Objects.requireNonNull(Minecraft.getInstance().level); + Direction facing; + if (info.isReallyAnvil) { + BlockState anvil = Minecraft.getInstance().level.getBlockState(info.anvilPos); + facing = anvil.getValue(AnvilBlock.FACING); // "faces" long way towards the right + } else { + facing = getForwardFromPlayer(Minecraft.getInstance().player).getCounterClockWise(); + } + + if (facing != info.lastDir) { + setHitboxes(info); + } + } @Override diff --git a/src/main/java/net/blf02/immersivemc/client/immersive/ImmersiveBrewing.java b/src/main/java/net/blf02/immersivemc/client/immersive/ImmersiveBrewing.java index 8c95cf56..57278d18 100644 --- a/src/main/java/net/blf02/immersivemc/client/immersive/ImmersiveBrewing.java +++ b/src/main/java/net/blf02/immersivemc/client/immersive/ImmersiveBrewing.java @@ -14,6 +14,8 @@ import net.minecraft.util.Hand; import net.minecraft.util.math.vector.Vector3d; +import java.util.Objects; + public class ImmersiveBrewing extends AbstractTileEntityImmersive { protected static final ImmersiveBrewing singleton = new ImmersiveBrewing(); @@ -48,8 +50,13 @@ public boolean shouldRender(BrewingInfo info, boolean isInVR) { } @Override - protected void doTick(BrewingInfo info, boolean isInVR) { - super.doTick(info, isInVR); + protected void initInfo(BrewingInfo info) { + setHitboxes(info); + } + + protected void setHitboxes(BrewingInfo info) { + Objects.requireNonNull(Minecraft.getInstance().player); + BrewingStandTileEntity stand = info.getTileEntity(); Direction forward = getForwardFromPlayer(Minecraft.getInstance().player); Vector3d pos = getDirectlyInFront(forward, stand.getBlockPos()); @@ -88,6 +95,18 @@ protected void doTick(BrewingInfo info, boolean isInVR) { info.setHitbox(2, createHitbox(posRightBottle, hitboxSize)); info.setHitbox(3, createHitbox(posIngredient, hitboxSize)); info.setHitbox(4, createHitbox(posFuel, hitboxSize)); + + info.lastDir = forward; + } + + @Override + protected void doTick(BrewingInfo info, boolean isInVR) { + super.doTick(info, isInVR); + + Direction forward = getForwardFromPlayer(Minecraft.getInstance().player); + if (forward != info.lastDir) { + setHitboxes(info); + } } @Override diff --git a/src/main/java/net/blf02/immersivemc/client/immersive/ImmersiveChest.java b/src/main/java/net/blf02/immersivemc/client/immersive/ImmersiveChest.java index 17b58f2e..9ebda486 100644 --- a/src/main/java/net/blf02/immersivemc/client/immersive/ImmersiveChest.java +++ b/src/main/java/net/blf02/immersivemc/client/immersive/ImmersiveChest.java @@ -287,6 +287,11 @@ public void onRemove(ChestInfo info) { } } + @Override + protected void initInfo(ChestInfo info) { + // NOOP since a chest in a double chest can be broken at any time + } + public static void openChest(ChestInfo info) { info.isOpen = !info.isOpen; Network.INSTANCE.sendToServer(new ChestOpenPacket(info.getBlockPosition(), info.isOpen)); diff --git a/src/main/java/net/blf02/immersivemc/client/immersive/ImmersiveCrafting.java b/src/main/java/net/blf02/immersivemc/client/immersive/ImmersiveCrafting.java index fe4bc8bd..0999ae06 100644 --- a/src/main/java/net/blf02/immersivemc/client/immersive/ImmersiveCrafting.java +++ b/src/main/java/net/blf02/immersivemc/client/immersive/ImmersiveCrafting.java @@ -34,15 +34,12 @@ public ImmersiveCrafting() { } @Override - protected void doTick(CraftingInfo info, boolean isInVR) { - super.doTick(info, isInVR); - Objects.requireNonNull(Minecraft.getInstance().player); + protected void initInfo(CraftingInfo info) { + setHitboxes(info); + } - if (info.tablePos != null && - Minecraft.getInstance().player.distanceToSqr(Vector3d.atCenterOf(info.tablePos)) > - CommonConstants.distanceSquaredToRemoveImmersive) { - info.remove(); - } + protected void setHitboxes(CraftingInfo info) { + Objects.requireNonNull(Minecraft.getInstance().player); Direction forward = getForwardFromPlayer(Minecraft.getInstance().player); Vector3d pos = getTopCenterOfBlock(info.tablePos); @@ -78,6 +75,25 @@ protected void doTick(CraftingInfo info, boolean isInVR) { info.resultPosition = info.getPosition(4).add(0, 0.5, 0); info.resultHitbox = createHitbox(info.resultPosition, hitboxSize * 3); + info.lastDir = forward; + } + + @Override + protected void doTick(CraftingInfo info, boolean isInVR) { + super.doTick(info, isInVR); + Objects.requireNonNull(Minecraft.getInstance().player); + + if (info.tablePos != null && + Minecraft.getInstance().player.distanceToSqr(Vector3d.atCenterOf(info.tablePos)) > + CommonConstants.distanceSquaredToRemoveImmersive) { + info.remove(); + } + + Direction forward = getForwardFromPlayer(Minecraft.getInstance().player); + if (info.lastDir != forward) { + setHitboxes(info); + } + } @Override diff --git a/src/main/java/net/blf02/immersivemc/client/immersive/ImmersiveETable.java b/src/main/java/net/blf02/immersivemc/client/immersive/ImmersiveETable.java index ec3e8df4..7dd27580 100644 --- a/src/main/java/net/blf02/immersivemc/client/immersive/ImmersiveETable.java +++ b/src/main/java/net/blf02/immersivemc/client/immersive/ImmersiveETable.java @@ -176,4 +176,9 @@ public void trackObject(BlockPos pos) { protected Vector3d getYDiffFromOffset(EnchantingInfo info, int slot) { return new Vector3d(0, this.yOffsets[info.yOffsetPositions[slot]], 0); } + + @Override + protected void initInfo(EnchantingInfo info) { + // NOOP: Changes based on the items moving up and down to look cool + } } diff --git a/src/main/java/net/blf02/immersivemc/client/immersive/ImmersiveFurnace.java b/src/main/java/net/blf02/immersivemc/client/immersive/ImmersiveFurnace.java index 7ee19fb7..67e346c0 100644 --- a/src/main/java/net/blf02/immersivemc/client/immersive/ImmersiveFurnace.java +++ b/src/main/java/net/blf02/immersivemc/client/immersive/ImmersiveFurnace.java @@ -107,8 +107,6 @@ protected void render(ImmersiveFurnaceInfo info, MatrixStack stack, boolean isIn renderItem(info.items[2], stack, info.getPosition(2), size, info.forward, info.getHibtox(2), true); } - - } @Override @@ -124,4 +122,8 @@ public void handleRightClick(AbstractImmersiveInfo info, PlayerEntity player, in )); } + @Override + protected void initInfo(ImmersiveFurnaceInfo info) { + // NOOP: Some hitboxes and positions can change if autoCenterFurnace is on + } } diff --git a/src/main/java/net/blf02/immersivemc/client/immersive/ImmersiveJukebox.java b/src/main/java/net/blf02/immersivemc/client/immersive/ImmersiveJukebox.java index ce0fd59e..4dd5b512 100644 --- a/src/main/java/net/blf02/immersivemc/client/immersive/ImmersiveJukebox.java +++ b/src/main/java/net/blf02/immersivemc/client/immersive/ImmersiveJukebox.java @@ -25,16 +25,13 @@ public static ImmersiveJukebox getSingleton() { } @Override - protected void doTick(JukeboxInfo info, boolean isInVR) { - super.doTick(info, isInVR); - + protected void initInfo(JukeboxInfo info) { Vector3d topCenter = getTopCenterOfBlock(info.getTileEntity().getBlockPos()); info.setPosition(0, topCenter); // North and south AxisAlignedBB hitbox = createHitbox(topCenter, 1f/16f); hitbox = hitbox.inflate(0, 0, 0.25); // Rectangular hitbox that covers disc slot info.setHitbox(0, hitbox); - } @Override @@ -64,7 +61,6 @@ public int getTickTime() { public boolean shouldRender(JukeboxInfo info, boolean isInVR) { return info.getTileEntity().getLevel() != null && info.getTileEntity().getLevel().getBlockState(info.getTileEntity().getBlockPos().relative(Direction.UP)).isAir() && - info.readyToRender() && - isInVR; + info.readyToRender(); } } diff --git a/src/main/java/net/blf02/immersivemc/client/immersive/ImmersiveRepeater.java b/src/main/java/net/blf02/immersivemc/client/immersive/ImmersiveRepeater.java index f62702b8..953d0091 100644 --- a/src/main/java/net/blf02/immersivemc/client/immersive/ImmersiveRepeater.java +++ b/src/main/java/net/blf02/immersivemc/client/immersive/ImmersiveRepeater.java @@ -20,6 +20,7 @@ import net.minecraft.util.math.vector.Vector3d; import net.minecraft.world.World; +import java.util.Objects; import java.util.Optional; public class ImmersiveRepeater extends AbstractImmersive { @@ -31,15 +32,9 @@ public ImmersiveRepeater() { } @Override - protected void doTick(RepeaterInfo info, boolean isInVR) { - super.doTick(info, isInVR); - - if (!(Minecraft.getInstance().level.getBlockState(info.getBlockPosition()).getBlock() instanceof RepeaterBlock)) { - info.remove(); - return; - } - - BlockState state = Minecraft.getInstance().player.level.getBlockState(info.getBlockPosition()); + protected void initInfo(RepeaterInfo info) { + Objects.requireNonNull(Minecraft.getInstance().level); + BlockState state = Minecraft.getInstance().level.getBlockState(info.getBlockPosition()); Direction facing = state.getValue(HorizontalBlock.FACING); Direction forwardDir = facing.getOpposite(); @@ -54,8 +49,19 @@ protected void doTick(RepeaterInfo info, boolean isInVR) { for (int i = 0; i <= 3; i++) { info.setHitbox(i, createHitbox(info.getPosition(i), 1f/14f).inflate(0, 1d/16d, 0)); } + } + + @Override + protected void doTick(RepeaterInfo info, boolean isInVR) { + super.doTick(info, isInVR); + + if (!(Minecraft.getInstance().level.getBlockState(info.getBlockPosition()).getBlock() instanceof RepeaterBlock)) { + info.remove(); + return; + } if (isInVR) { + BlockState state = Minecraft.getInstance().level.getBlockState(info.getBlockPosition()); for (int c = 0; c <= 1; c++) { Vector3d pos = VRPlugin.API.getVRPlayer(Minecraft.getInstance().player).getController(c).position(); Optional hit = Util.getClosestIntersect(pos, info.getAllHitboxes(), info.getAllPositions()); diff --git a/src/main/java/net/blf02/immersivemc/client/immersive/info/AbstractImmersiveInfo.java b/src/main/java/net/blf02/immersivemc/client/immersive/info/AbstractImmersiveInfo.java index 43d1642e..b543e224 100644 --- a/src/main/java/net/blf02/immersivemc/client/immersive/info/AbstractImmersiveInfo.java +++ b/src/main/java/net/blf02/immersivemc/client/immersive/info/AbstractImmersiveInfo.java @@ -9,6 +9,7 @@ public abstract class AbstractImmersiveInfo { protected int ticksLeft; protected int countdown = 10; // Used for transitions for the items public int ticksActive = 0; + public boolean initCompleted = false; public AbstractImmersiveInfo(int ticksToExist) { this.ticksLeft = ticksToExist; diff --git a/src/main/java/net/blf02/immersivemc/client/immersive/info/AnvilInfo.java b/src/main/java/net/blf02/immersivemc/client/immersive/info/AnvilInfo.java index 8b82448a..b914ffef 100644 --- a/src/main/java/net/blf02/immersivemc/client/immersive/info/AnvilInfo.java +++ b/src/main/java/net/blf02/immersivemc/client/immersive/info/AnvilInfo.java @@ -15,6 +15,7 @@ public class AnvilInfo extends AbstractImmersiveInfo { protected Vector3d[] positions = new Vector3d[3]; public Vector3d textPos = null; + public Direction lastDir = null; public AnvilInfo(BlockPos pos, int ticksToExist) { super(ticksToExist); diff --git a/src/main/java/net/blf02/immersivemc/client/immersive/info/BrewingInfo.java b/src/main/java/net/blf02/immersivemc/client/immersive/info/BrewingInfo.java index 7e21c665..c5f6e429 100644 --- a/src/main/java/net/blf02/immersivemc/client/immersive/info/BrewingInfo.java +++ b/src/main/java/net/blf02/immersivemc/client/immersive/info/BrewingInfo.java @@ -1,6 +1,7 @@ package net.blf02.immersivemc.client.immersive.info; import net.minecraft.tileentity.BrewingStandTileEntity; +import net.minecraft.util.Direction; import net.minecraft.util.math.AxisAlignedBB; public class BrewingInfo extends AbstractTileEntityImmersiveInfo { @@ -9,6 +10,8 @@ public class BrewingInfo extends AbstractTileEntityImmersiveInfo