diff --git a/common/src/main/java/org/vivecraft/client_vr/ClientDataHolderVR.java b/common/src/main/java/org/vivecraft/client_vr/ClientDataHolderVR.java index ca3a22d36..01c567ecb 100644 --- a/common/src/main/java/org/vivecraft/client_vr/ClientDataHolderVR.java +++ b/common/src/main/java/org/vivecraft/client_vr/ClientDataHolderVR.java @@ -11,6 +11,11 @@ import org.vivecraft.client_vr.render.VRFirstPersonArmSwing; import org.vivecraft.client_vr.settings.VRSettings; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.function.BiFunction; + public class ClientDataHolderVR { public static final ModelResourceLocation THIRD_PERSON_CAMERA_MODEL = new ModelResourceLocation("vivecraft", "camcorder", ""); @@ -31,24 +36,30 @@ public class ClientDataHolderVR { public MCVR vr; public VRRenderer vrRenderer; public MenuWorldRenderer menuWorldRenderer; - public BackpackTracker backpackTracker = new BackpackTracker(Minecraft.getInstance(), this); - public BowTracker bowTracker = new BowTracker(Minecraft.getInstance(), this); - public SwimTracker swimTracker = new SwimTracker(Minecraft.getInstance(), this); - public EatingTracker autoFood = new EatingTracker(Minecraft.getInstance(), this); - public JumpTracker jumpTracker = new JumpTracker(Minecraft.getInstance(), this); - public SneakTracker sneakTracker = new SneakTracker(Minecraft.getInstance(), this); - public ClimbTracker climbTracker = new ClimbTracker(Minecraft.getInstance(), this); - public RunTracker runTracker = new RunTracker(Minecraft.getInstance(), this); - public RowTracker rowTracker = new RowTracker(Minecraft.getInstance(), this); - public TeleportTracker teleportTracker = new TeleportTracker(Minecraft.getInstance(), this); - public SwingTracker swingTracker = new SwingTracker(Minecraft.getInstance(), this); - public HorseTracker horseTracker = new HorseTracker(Minecraft.getInstance(), this); - public VehicleTracker vehicleTracker = new VehicleTracker(Minecraft.getInstance(), this); - public InteractTracker interactTracker = new InteractTracker(Minecraft.getInstance(), this); - public CrawlTracker crawlTracker = new CrawlTracker(Minecraft.getInstance(), this); - public CameraTracker cameraTracker = new CameraTracker(Minecraft.getInstance(), this); + + // list of all registered trackers + private final List trackers = new ArrayList<>(); + + // our trackers + public final BackpackTracker backpackTracker = createTracker(BackpackTracker::new); + public final BowTracker bowTracker = createTracker(BowTracker::new); + public final CameraTracker cameraTracker = createTracker(CameraTracker::new); + public final ClimbTracker climbTracker = createTracker(ClimbTracker::new); + public final CrawlTracker crawlTracker = createTracker(CrawlTracker::new); + public final EatingTracker eatingTracker = createTracker(EatingTracker::new); + public final HorseTracker horseTracker = createTracker(HorseTracker::new); + public final InteractTracker interactTracker = createTracker(InteractTracker::new); + public final JumpTracker jumpTracker = createTracker(JumpTracker::new); + public final RowTracker rowTracker = createTracker(RowTracker::new); + public final RunTracker runTracker = createTracker(RunTracker::new); + public final SneakTracker sneakTracker = createTracker(SneakTracker::new); + public final SwimTracker swimTracker = createTracker(SwimTracker::new); + public final SwingTracker swingTracker = createTracker(SwingTracker::new); + public final TeleportTracker teleportTracker = createTracker(TeleportTracker::new); + public final TelescopeTracker telescopeTracker = createTracker(TelescopeTracker::new); + public final VehicleTracker vehicleTracker = createTracker(VehicleTracker::new); + public VRSettings vrSettings; - public boolean integratedServerLaunchInProgress = false; public boolean grabScreenShot = false; public String incorrectGarbageCollector = ""; public long frameIndex = 0L; @@ -72,4 +83,35 @@ public static ClientDataHolderVR getInstance() { } return INSTANCE; } + + /** + * Creates a tracker instance, adds it to the registered list and returns it + * @param constructor Constructor to use to create the tracker instance + * @return created tracker instance + * @param Class of the tracker + */ + public T createTracker(BiFunction constructor) { + T tracker = constructor.apply(Minecraft.getInstance(), this); + registerTracker(tracker); + return tracker; + } + + /** + * registers a tracker + * @param tracker tracker to register + * @throws IllegalArgumentException if the tracker is already registered + */ + public void registerTracker(Tracker tracker) throws IllegalArgumentException{ + if (this.trackers.contains(tracker)) { + throw new IllegalArgumentException("Tracker is already added and should not be added again!"); + } + this.trackers.add(tracker); + } + + /** + * @return Unmodifiable list of the registered trackers + */ + public List getTrackers() { + return Collections.unmodifiableList(this.trackers); + } } diff --git a/common/src/main/java/org/vivecraft/client_vr/MethodHolder.java b/common/src/main/java/org/vivecraft/client_vr/MethodHolder.java index 96f4e8772..2caf9192d 100644 --- a/common/src/main/java/org/vivecraft/client_vr/MethodHolder.java +++ b/common/src/main/java/org/vivecraft/client_vr/MethodHolder.java @@ -21,7 +21,6 @@ public static boolean willBeInMenuRoom(Screen newScreen) { newScreen instanceof ReceivingLevelScreen || newScreen instanceof ProgressScreen || newScreen instanceof GenericDirtMessageScreen || - ClientDataHolderVR.getInstance().integratedServerLaunchInProgress || Minecraft.getInstance().getOverlay() != null; } } diff --git a/common/src/main/java/org/vivecraft/client_vr/VRState.java b/common/src/main/java/org/vivecraft/client_vr/VRState.java index 18324e8f7..c63caeae0 100644 --- a/common/src/main/java/org/vivecraft/client_vr/VRState.java +++ b/common/src/main/java/org/vivecraft/client_vr/VRState.java @@ -8,6 +8,7 @@ import org.vivecraft.client.gui.screens.GarbageCollectorScreen; import org.vivecraft.client.utils.TextUtils; import org.vivecraft.client_vr.gameplay.VRPlayer; +import org.vivecraft.client_vr.gameplay.trackers.Tracker; import org.vivecraft.client_vr.menuworlds.MenuWorldRenderer; import org.vivecraft.client_vr.provider.nullvr.NullVR; import org.vivecraft.client_vr.provider.openvr_lwjgl.MCOpenVR; @@ -69,22 +70,9 @@ public static void initializeVR() { RenderPassManager.setVanillaRenderPass(); dh.vrPlayer = new VRPlayer(); - dh.vrPlayer.registerTracker(dh.backpackTracker); - dh.vrPlayer.registerTracker(dh.bowTracker); - dh.vrPlayer.registerTracker(dh.climbTracker); - dh.vrPlayer.registerTracker(dh.autoFood); - dh.vrPlayer.registerTracker(dh.jumpTracker); - dh.vrPlayer.registerTracker(dh.rowTracker); - dh.vrPlayer.registerTracker(dh.runTracker); - dh.vrPlayer.registerTracker(dh.sneakTracker); - dh.vrPlayer.registerTracker(dh.swimTracker); - dh.vrPlayer.registerTracker(dh.swingTracker); - dh.vrPlayer.registerTracker(dh.interactTracker); - dh.vrPlayer.registerTracker(dh.teleportTracker); - dh.vrPlayer.registerTracker(dh.horseTracker); - dh.vrPlayer.registerTracker(dh.vehicleTracker); - dh.vrPlayer.registerTracker(dh.crawlTracker); - dh.vrPlayer.registerTracker(dh.cameraTracker); + for(Tracker t : dh.getTrackers()) { + dh.vrPlayer.registerTracker(t); + } dh.menuWorldRenderer = new MenuWorldRenderer(); diff --git a/common/src/main/java/org/vivecraft/client_vr/gameplay/VRPlayer.java b/common/src/main/java/org/vivecraft/client_vr/gameplay/VRPlayer.java index f5c791af4..1726588ea 100644 --- a/common/src/main/java/org/vivecraft/client_vr/gameplay/VRPlayer.java +++ b/common/src/main/java/org/vivecraft/client_vr/gameplay/VRPlayer.java @@ -361,7 +361,7 @@ public void rotateOriginAround(float degrees, Vec3 origin) { } } - public void tick(LocalPlayer player, Minecraft mc) { + public void tick(LocalPlayer player) { if (!((PlayerExtension) player).vivecraft$getInitFromServer()) return; if (!this.initDone) { @@ -387,23 +387,23 @@ public void tick(LocalPlayer player, Minecraft mc) { for (Tracker tracker : this.trackers) { if (tracker.getEntryPoint() == Tracker.EntryPoint.LIVING_UPDATE) { - tracker.idleTick(mc.player); + tracker.idleTick(player); - if (tracker.isActive(mc.player)) { - tracker.doProcess(mc.player); + if (tracker.isActive(player)) { + tracker.doProcess(player); } else { - tracker.reset(mc.player); + tracker.reset(player); } } } if (player.isPassenger()) { - Entity entity = mc.player.getVehicle(); + Entity entity = player.getVehicle(); if (entity instanceof AbstractHorse abstracthorse) { if (abstracthorse.isControlledByLocalInstance() && abstracthorse.isSaddled() && - !this.dh.horseTracker.isActive(mc.player)) + !this.dh.horseTracker.isActive(player)) { abstracthorse.yBodyRot = this.vrdata_world_pre.getBodyYaw(); this.dh.vehicleTracker.rotationCooldown = 10; @@ -418,6 +418,10 @@ public void tick(LocalPlayer player, Minecraft mc) { } } + public boolean isTrackerUsingItem(LocalPlayer player) { + return this.trackers.stream().anyMatch(tracker -> tracker.itemInUse(player)); + } + public void doPlayerMoveInRoom(LocalPlayer player) { if (this.roomScaleMovementDelay > 0) { diff --git a/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/BowTracker.java b/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/BowTracker.java index 1b8fe9cb1..4107c56f8 100644 --- a/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/BowTracker.java +++ b/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/BowTracker.java @@ -82,6 +82,11 @@ public static boolean isHoldingBowEither(LivingEntity entity) { return isHoldingBow(entity, InteractionHand.MAIN_HAND) || isHoldingBow(entity, InteractionHand.OFF_HAND); } + @Override + public boolean itemInUse(LocalPlayer player) { + return this.isDrawing; + } + @Override public boolean isActive(LocalPlayer player) { if (player == null) { diff --git a/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/EatingTracker.java b/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/EatingTracker.java index 0a22544f2..0c3db9821 100644 --- a/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/EatingTracker.java +++ b/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/EatingTracker.java @@ -16,17 +16,13 @@ public class EatingTracker extends Tracker { private static final float THRESHOLD = 0.25F; private static final long EAT_TIME = 2100L; - public boolean[] eating = new boolean[2]; + private final boolean[] eating = new boolean[2]; private long eatStart; public EatingTracker(Minecraft mc, ClientDataHolderVR dh) { super(mc, dh); } - public boolean isEating() { - return this.eating[0] || this.eating[1]; - } - @Override public boolean isActive(LocalPlayer player) { if (ClientDataHolderVR.getInstance().vrSettings.seated) { @@ -54,6 +50,11 @@ public boolean isActive(LocalPlayer player) { } } + @Override + public boolean itemInUse(LocalPlayer player) { + return this.eating[0] || this.eating[1]; + } + @Override public void reset(LocalPlayer player) { this.eating[0] = false; diff --git a/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/HorseTracker.java b/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/HorseTracker.java index f9e90621b..813e37ddf 100644 --- a/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/HorseTracker.java +++ b/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/HorseTracker.java @@ -51,8 +51,6 @@ public boolean isActive(LocalPlayer player) { @Override public void reset(LocalPlayer player) { - super.reset(player); - if (this.horse != null) { this.horse.setNoAi(false); } diff --git a/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/TelescopeTracker.java b/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/TelescopeTracker.java index f21fc72f4..8235ce8d3 100644 --- a/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/TelescopeTracker.java +++ b/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/TelescopeTracker.java @@ -4,6 +4,7 @@ import net.minecraft.client.player.LocalPlayer; import net.minecraft.client.resources.model.ModelResourceLocation; import net.minecraft.network.chat.contents.TranslatableContents; +import net.minecraft.world.InteractionHand; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import org.joml.Vector3f; @@ -20,17 +21,46 @@ public class TelescopeTracker extends Tracker { private static final float LENS_DOT_MAX = 0.9F; private static final float LENS_DOT_MIN = 0.75F; + private final boolean[] viewing = new boolean[2]; + public TelescopeTracker(Minecraft mc, ClientDataHolderVR dh) { super(mc, dh); } @Override public boolean isActive(LocalPlayer player) { - return false; + return player != null && + !this.dh.bowTracker.isActive(player) && + (isTelescope(player.getMainHandItem()) || isTelescope(player.getOffhandItem())); + } + + @Override + public boolean itemInUse(LocalPlayer player) { + return this.viewing[0] || this.viewing[1]; + } + + @Override + public void reset(LocalPlayer player) { + this.viewing[0] = false; + this.viewing[1] = false; } @Override public void doProcess(LocalPlayer player) { + for (int c = 0; c < 2; c++) { + if (isTelescope(player.getItemInHand(InteractionHand.values()[c]))) { + if (isViewing(c)) { + if (!this.viewing[c]) { + this.mc.gameMode.useItem(player, InteractionHand.values()[c]); + } + this.viewing[c] = true; + } else { + this.viewing[c] = false; + } + } else { + this.viewing[c] = false; + } + } } /** @@ -38,9 +68,9 @@ public void doProcess(LocalPlayer player) { * @return if the given {@code itemStack} is a telescope */ public static boolean isTelescope(ItemStack itemStack) { - return itemStack != null && (itemStack.getItem() == Items.SPYGLASS || isLegacyTelescope(itemStack) || - itemStack.is(ItemTags.VIVECRAFT_TELESCOPE) - ); + return itemStack != null && + (itemStack.is(Items.SPYGLASS) || isLegacyTelescope(itemStack) || itemStack.is(ItemTags.VIVECRAFT_TELESCOPE) + ); } // TODO: old eye of the farseer, remove this eventually diff --git a/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/Tracker.java b/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/Tracker.java index 3c69a4e9e..d081c158d 100644 --- a/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/Tracker.java +++ b/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/Tracker.java @@ -4,6 +4,8 @@ import net.minecraft.client.player.LocalPlayer; import org.vivecraft.client_vr.ClientDataHolderVR; +import javax.annotation.Nullable; + public abstract class Tracker { public Minecraft mc; public ClientDataHolderVR dh; @@ -13,15 +15,17 @@ public Tracker(Minecraft mc, ClientDataHolderVR dh) { this.dh = dh; } - public abstract boolean isActive(LocalPlayer player); + public abstract boolean isActive(@Nullable LocalPlayer player); - public abstract void doProcess(LocalPlayer player); + public abstract void doProcess(@Nullable LocalPlayer player); - public void reset(LocalPlayer player) { + public boolean itemInUse(@Nullable LocalPlayer player) { + return false; } - public void idleTick(LocalPlayer player) { - } + public void reset(@Nullable LocalPlayer player) {} + + public void idleTick(@Nullable LocalPlayer player) {} public EntryPoint getEntryPoint() { return EntryPoint.LIVING_UPDATE; diff --git a/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/VehicleTracker.java b/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/VehicleTracker.java index f77a8115e..b109504c2 100644 --- a/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/VehicleTracker.java +++ b/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/VehicleTracker.java @@ -46,7 +46,6 @@ public boolean isActive(LocalPlayer player) { public void reset(LocalPlayer player) { this.minecartStupidityCounter = 2; this.isRiding = false; - super.reset(player); } public double getVehicleFloor(Entity vehicle, double original) { diff --git a/common/src/main/java/org/vivecraft/mixin/advancements/PlayerPredicateMixin.java b/common/src/main/java/org/vivecraft/mixin/advancements/PlayerPredicateMixin.java new file mode 100644 index 000000000..d0045bbaf --- /dev/null +++ b/common/src/main/java/org/vivecraft/mixin/advancements/PlayerPredicateMixin.java @@ -0,0 +1,43 @@ +package org.vivecraft.mixin.advancements; + +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import com.llamalad7.mixinextras.sugar.Share; +import com.llamalad7.mixinextras.sugar.ref.LocalRef; +import net.minecraft.advancements.critereon.PlayerPredicate; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.item.Items; +import net.minecraft.world.phys.Vec3; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.vivecraft.common.utils.MathUtils; +import org.vivecraft.server.ServerVRPlayers; +import org.vivecraft.server.ServerVivePlayer; + +@Mixin(PlayerPredicate.class) +public class PlayerPredicateMixin { + @WrapOperation(method = "matches", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerPlayer;getEyePosition()Lnet/minecraft/world/phys/Vec3;")) + private Vec3 vivecraft$spyglassLookPosition( + ServerPlayer player, Operation original, @Share("vivePlayer") LocalRef vivePlayer) + { + if (player.getUseItem().is(Items.SPYGLASS) && ServerVRPlayers.isVRPlayer(player)) { + vivePlayer.set(ServerVRPlayers.getVivePlayer(player)); + if (!vivePlayer.get().isSeated()) { + return vivePlayer.get().getControllerPos(player.getUsedItemHand().ordinal()); + } + } + return original.call(player); + } + + @WrapOperation(method = "matches", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerPlayer;getViewVector(F)Lnet/minecraft/world/phys/Vec3;")) + private Vec3 vivecraft$spyglassLookDirection( + ServerPlayer player, float partialTick, Operation original, + @Share("vivePlayer") LocalRef vivePlayer) + { + if (vivePlayer.get() != null && !vivePlayer.get().isSeated()) { + return vivePlayer.get().getControllerVectorCustom(player.getUsedItemHand().ordinal(), MathUtils.DOWN); + } else { + return original.call(player, partialTick); + } + } +} diff --git a/common/src/main/java/org/vivecraft/mixin/client_vr/MinecraftVRMixin.java b/common/src/main/java/org/vivecraft/mixin/client_vr/MinecraftVRMixin.java index 384794193..a2e998b9d 100644 --- a/common/src/main/java/org/vivecraft/mixin/client_vr/MinecraftVRMixin.java +++ b/common/src/main/java/org/vivecraft/mixin/client_vr/MinecraftVRMixin.java @@ -699,8 +699,7 @@ public abstract class MinecraftVRMixin implements MinecraftExtension { if (!VRState.VR_RUNNING || ClientDataHolderVR.getInstance().vrSettings.seated) { return useKeyDown; } else { - return useKeyDown || ClientDataHolderVR.getInstance().bowTracker.isActive(this.player) || - ClientDataHolderVR.getInstance().autoFood.isEating(); + return useKeyDown || ClientDataHolderVR.getInstance().vrPlayer.isTrackerUsingItem(this.player); } } diff --git a/common/src/main/java/org/vivecraft/mixin/client_vr/player/LocalPlayerVRMixin.java b/common/src/main/java/org/vivecraft/mixin/client_vr/player/LocalPlayerVRMixin.java index 5973c563c..e8ba0937b 100644 --- a/common/src/main/java/org/vivecraft/mixin/client_vr/player/LocalPlayerVRMixin.java +++ b/common/src/main/java/org/vivecraft/mixin/client_vr/player/LocalPlayerVRMixin.java @@ -137,7 +137,7 @@ public abstract class LocalPlayerVRMixin extends LocalPlayer_PlayerVRMixin imple @Inject(method = "aiStep", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/AbstractClientPlayer;aiStep()V")) private void vivecraft$VRPlayerTick(CallbackInfo ci) { if (VRState.VR_RUNNING && vivecraft$isLocalPlayer(this)) { - ClientDataHolderVR.getInstance().vrPlayer.tick((LocalPlayer) (Object) this, this.minecraft); + ClientDataHolderVR.getInstance().vrPlayer.tick((LocalPlayer) (Object) this); } } diff --git a/common/src/main/resources/vivecraft.mixins.json b/common/src/main/resources/vivecraft.mixins.json index cf1870352..2ee64e20c 100644 --- a/common/src/main/resources/vivecraft.mixins.json +++ b/common/src/main/resources/vivecraft.mixins.json @@ -86,6 +86,7 @@ ], "minVersion": "0.8.4", "mixins": [ + "advancements.PlayerPredicateMixin", "server.ChunkMapAccessor", "server.MinecraftServerMixin", "server.ServerGamePacketListenerImplMixin",