diff --git a/common/src/main/java/org/vivecraft/client_vr/extensions/BoatExtension.java b/common/src/main/java/org/vivecraft/client_vr/extensions/BoatExtension.java new file mode 100644 index 000000000..c7d6a96c0 --- /dev/null +++ b/common/src/main/java/org/vivecraft/client_vr/extensions/BoatExtension.java @@ -0,0 +1,8 @@ +package org.vivecraft.client_vr.extensions; + +import net.minecraft.world.phys.Vec3; + +public interface BoatExtension { + + Vec3[] vivecraft$getPaddleAngles(); +} 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 ad2eee10a..a52e0c2cc 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 @@ -60,7 +60,11 @@ public boolean isNotched() { } public boolean isCharged() { - return Util.getMillis() - this.startDrawTime >= MAX_DRAW_MILLIS; + if (!ClientNetworking.SERVER_WANTS_DATA) { + return Util.getMillis() - this.startDrawTime >= MAX_DRAW_MILLIS; + } else { + return false; + } } public static boolean isBow(ItemStack itemStack) { diff --git a/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/RowTracker.java b/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/RowTracker.java index 755cae7ba..b330f7668 100644 --- a/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/RowTracker.java +++ b/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/RowTracker.java @@ -2,24 +2,23 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.player.LocalPlayer; -import net.minecraft.core.BlockPos; import net.minecraft.util.Mth; import net.minecraft.world.entity.vehicle.Boat; import net.minecraft.world.phys.Vec3; import org.joml.Quaternionf; import org.joml.Vector3f; import org.vivecraft.client_vr.ClientDataHolderVR; +import org.vivecraft.client_vr.provider.ControllerType; import org.vivecraft.common.utils.MathUtils; public class RowTracker extends Tracker { - private static final double TRANSMISSION_EFFICIENCY = 0.9D; + private static final double TRANSMISSION_EFFICIENCY = 1.0D; public double[] forces = new double[]{0.0D, 0.0D}; - public float LOar; - public float ROar; - public float FOar; - private final Vec3[] lastUWPs = new Vec3[2]; + public Vec3[] paddleAngles = new Vec3[]{null, null}; + public boolean[] paddleInWater = new boolean[]{false, false}; + private int[] hands = new int[2]; public RowTracker(Minecraft mc, ClientDataHolderVR dh) { super(mc, dh); @@ -45,64 +44,51 @@ public boolean isActive(LocalPlayer player) { } public boolean isRowing() { - return this.ROar + this.LOar + this.FOar > 0.0F; + return this.paddleAngles[0] != null || this.paddleAngles[1] != null; } @Override public void reset(LocalPlayer player) { - this.LOar = 0.0F; - this.ROar = 0.0F; - this.FOar = 0.0F; + this.forces[0] = 0.0D; + this.forces[1] = 0.0D; + this.paddleAngles[0] = null; + this.paddleAngles[1] = null; + this.paddleInWater[0] = false; + this.paddleInWater[1] = false; } @Override public void doProcess(LocalPlayer player) { - float c0Move = this.dh.vr.controllerHistory[0].averageSpeed(0.5D); - float c1Move = this.dh.vr.controllerHistory[1].averageSpeed(0.5D); - - final float minSpeed = 0.5F; - final float maxSpeed = 2.0F; - - this.ROar = Math.max(c0Move - minSpeed, 0.0F); - this.LOar = Math.max(c1Move - minSpeed, 0.0F); - - this.FOar = this.ROar > 0.0F && this.LOar > 0.0F ? (this.ROar + this.LOar) / 2.0F : 0.0F; - - if (this.FOar > maxSpeed) { - this.FOar = maxSpeed; - } - - if (this.ROar > maxSpeed) { - this.ROar = maxSpeed; - } - - if (this.LOar > maxSpeed) { - this.LOar = maxSpeed; - } - - // TODO: Backwards paddlin' - } - - public void doProcessFinaltransmithastofixthis(LocalPlayer player) { Boat boat = (Boat) player.getVehicle(); Quaternionf boatRot = new Quaternionf().rotationYXZ( Mth.DEG_TO_RAD * -(boat.getYRot() % 360.0F), Mth.DEG_TO_RAD * boat.getXRot(), 0.0F).normalize(); + Vector3f hand0 = boatRot.transformInverse(MathUtils.subtractToVector3f(this.getAbsArmPos(0), boat.position())); + Vector3f hand1 = boatRot.transformInverse(MathUtils.subtractToVector3f(this.getAbsArmPos(1), boat.position())); + if (hand0.x > hand1.x) { + hands[0] = 0; + hands[1] = 1; + } else { + hands[0] = 1; + hands[1] = 0; + } + for (int paddle = 0; paddle <= 1; paddle++) { - if (this.isPaddleUnderWater(paddle, boat)) { - Vec3 arm2Pad = this.getArmToPaddleVector(paddle, boat); + Vec3 arm2Pad = this.getArmToPaddleVector(paddle, hands[paddle], boat); + this.paddleAngles[paddle] = MathUtils.toMcVec3(boatRot.transformInverse(new Vector3f((float) arm2Pad.x, (float) arm2Pad.y, (float) arm2Pad.z))); + + boolean inWater; + if (this.isPaddleUnderWater(paddle, hands[paddle], boat)) { + inWater = true; + Vec3 attach = this.getAttachmentPoint(paddle, boat); - Vec3 underWaterPoint = attach.add(arm2Pad.normalize()).subtract(boat.position()); + Vec3 underWaterPoint = attach.add(arm2Pad.normalize()); if (this.lastUWPs[paddle] != null) { Vector3f forceVector = MathUtils.subtractToVector3f(this.lastUWPs[paddle], underWaterPoint); // intentionally reverse - forceVector = forceVector.sub( - (float) boat.getDeltaMovement().x, - (float) boat.getDeltaMovement().y, - (float) boat.getDeltaMovement().z); Vector3f forward = boatRot.transform(MathUtils.FORWARD, new Vector3f()); @@ -118,15 +104,35 @@ public void doProcessFinaltransmithastofixthis(LocalPlayer player) { this.lastUWPs[paddle] = underWaterPoint; } else { + inWater = false; + this.forces[paddle] = 0.0D; this.lastUWPs[paddle] = null; } + + if (inWater) { + if (!this.paddleInWater[paddle]) { + this.dh.vr.triggerHapticPulse(ControllerType.values()[hands[paddle]], 0.05F, 100.0F, 0.8F); + } else { + float strength = (float) (Math.abs(this.forces[paddle]) / 0.1D); + if (strength > 0.05F) { + strength = strength * 0.7F + 0.3F; + this.dh.vr.triggerHapticPulse(ControllerType.values()[hands[paddle]], 0.05F, 100.0F, strength); + } + } + } else { + if (this.paddleInWater[paddle]) { + this.dh.vr.triggerHapticPulse(ControllerType.values()[hands[paddle]], 0.05F, 100.0F, 0.2F); + } + } + + this.paddleInWater[paddle] = inWater; } } - private Vec3 getArmToPaddleVector(int paddle, Boat boat) { + private Vec3 getArmToPaddleVector(int paddle, int hand, Boat boat) { Vec3 attachAbs = this.getAttachmentPoint(paddle, boat); - Vec3 armAbs = this.getAbsArmPos(paddle == 0 ? 1 : 0); + Vec3 armAbs = this.getAbsArmPos(hand); return attachAbs.subtract(armAbs); } @@ -146,10 +152,10 @@ private Vec3 getAbsArmPos(int side) { return this.dh.vrPlayer.roomOrigin.add(arm.x, arm.y, arm.z); } - private boolean isPaddleUnderWater(int paddle, Boat boat) { + private boolean isPaddleUnderWater(int paddle, int hand, Boat boat) { Vec3 attachAbs = this.getAttachmentPoint(paddle, boat); - Vec3 armToPaddle = this.getArmToPaddleVector(paddle, boat).normalize(); - BlockPos blockPos = new BlockPos(attachAbs.add(armToPaddle)); - return boat.level.getBlockState(blockPos).getMaterial().isLiquid(); + Vec3 armToPaddle = this.getArmToPaddleVector(paddle, hand, boat).normalize(); + Vec3 blockPos = attachAbs.add(armToPaddle); + return blockPos.subtract(boat.position()).y < 0.2F; } } diff --git a/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/SwimTracker.java b/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/SwimTracker.java index 3df513d1c..03125e799 100644 --- a/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/SwimTracker.java +++ b/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/SwimTracker.java @@ -2,15 +2,17 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.player.LocalPlayer; +import net.minecraft.tags.FluidTags; import net.minecraft.world.phys.Vec3; import org.joml.Vector3f; import org.vivecraft.client_vr.ClientDataHolderVR; +import org.vivecraft.client_vr.settings.AutoCalibration; import org.vivecraft.common.utils.MathUtils; public class SwimTracker extends Tracker { - private static final float FRICTION = 0.9F; - private static final float RISE_SPEED = 0.005F; - private static final float SWIM_SPEED = 1.3F; + private static final float FRICTION = 0.85F; + private static final float RISE_SPEED = 0.0015F; + private static final float SWIM_SPEED = 1.0F; private Vector3f motion = new Vector3f(); private double lastDist; @@ -67,6 +69,10 @@ public void doProcess(LocalPlayer player) { this.motion = this.motion.add(velocity); } + if (player.getFluidHeight(FluidTags.WATER) > AutoCalibration.getPlayerHeight() - 0.1F) { + this.motion = this.motion.add(0.0f, RISE_SPEED, 0.0f); + } + this.lastDist = distance; player.setSwimming(this.motion.length() > 0.3D); player.setSprinting(this.motion.length() > 1.0D); 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 190887be4..7dcb7c939 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 @@ -49,11 +49,11 @@ public void reset(LocalPlayer player) { } public double getVehicleFloor(Entity vehicle, double original) { -// if (vehicle instanceof AbstractHorse) { - return original; // horses are fine. -// } else { -// return vehicle.getY(); -// } + if (vehicle instanceof Boat) { + return original + 0.6f; + } else { + return original; + } } public static Vector3f getSteeringDirection(LocalPlayer player) { diff --git a/common/src/main/java/org/vivecraft/mixin/client_vr/model/BoatModelMixin.java b/common/src/main/java/org/vivecraft/mixin/client_vr/model/BoatModelMixin.java new file mode 100644 index 000000000..5fc3126f8 --- /dev/null +++ b/common/src/main/java/org/vivecraft/mixin/client_vr/model/BoatModelMixin.java @@ -0,0 +1,25 @@ +package org.vivecraft.mixin.client_vr.model; + +import net.minecraft.client.model.BoatModel; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.world.entity.vehicle.Boat; +import net.minecraft.world.phys.Vec3; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; +import org.vivecraft.client_vr.extensions.BoatExtension; + +@Mixin(BoatModel.class) +public abstract class BoatModelMixin { + @Inject(at = @At(value = "HEAD"), method = "animatePaddle(Lnet/minecraft/world/entity/vehicle/Boat;ILnet/minecraft/client/model/geom/ModelPart;F)V", locals = LocalCapture.CAPTURE_FAILHARD, cancellable = true) + private static void vivecraft$animatePaddle(Boat boat, int paddle, ModelPart mp, float f, CallbackInfo ci) { + Vec3 paddleAngle = ((BoatExtension) boat).vivecraft$getPaddleAngles()[paddle]; + if (paddleAngle != null) { + mp.xRot = (float) Math.atan2(paddleAngle.y, Math.sqrt(paddleAngle.x * paddleAngle.x + paddleAngle.z * paddleAngle.z)); + mp.yRot = (float) Math.atan2(paddleAngle.z, paddleAngle.x); + ci.cancel(); + } + } +} diff --git a/common/src/main/java/org/vivecraft/mixin/client_vr/world/BoatMixin.java b/common/src/main/java/org/vivecraft/mixin/client_vr/world/BoatMixin.java index ffdd7a729..4c7219ef0 100644 --- a/common/src/main/java/org/vivecraft/mixin/client_vr/world/BoatMixin.java +++ b/common/src/main/java/org/vivecraft/mixin/client_vr/world/BoatMixin.java @@ -6,16 +6,20 @@ import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.vehicle.Boat; import net.minecraft.world.level.Level; +import net.minecraft.world.phys.Vec3; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.ModifyVariable; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.vivecraft.client_vr.ClientDataHolderVR; import org.vivecraft.client_vr.VRState; +import org.vivecraft.client_vr.extensions.BoatExtension; import org.vivecraft.client_vr.settings.VRSettings; @Mixin(Boat.class) -public abstract class BoatMixin extends Entity { +public abstract class BoatMixin extends Entity implements BoatExtension { @Shadow private float deltaRotation; @@ -26,11 +30,16 @@ public abstract class BoatMixin extends Entity { @Shadow private boolean inputUp; + @Shadow + public abstract void setPaddleState(boolean pLeft, boolean pRight); + + public Vec3[] paddleAngles = new Vec3[]{null, null}; + public BoatMixin(EntityType entityType, Level level) { super(entityType, level); } - @ModifyExpressionValue(method = "controlBoat", at = @At(value = "CONSTANT", args = "floatValue=1F", ordinal = 0)) + @ModifyExpressionValue(method = "controlBoatq", at = @At(value = "CONSTANT", args = "floatValue=1F", ordinal = 0)) private float vivecraft$inputLeft(float leftInput) { return VRState.VR_RUNNING ? Minecraft.getInstance().player.input.leftImpulse : leftInput; } @@ -89,36 +98,30 @@ public BoatMixin(EntityType entityType, Level level) { } else if (dataHolder.rowTracker.isRowing()) { // roomscale rowing - this.deltaRotation += dataHolder.rowTracker.LOar / 1.5F; - this.deltaRotation -= dataHolder.rowTracker.ROar / 1.5F; - - /* this.deltaRotation += dataHolder.rowTracker.forces[0] * 50; this.deltaRotation -= dataHolder.rowTracker.forces[1] * 50; - */ - if (this.deltaRotation < 0F) { - this.inputLeft = true; - } - if (this.deltaRotation > 0F) { - this.inputRight = true; - } - - // clamp to vanilla speed - acceleration = Math.min(0.04F, 0.06F * dataHolder.rowTracker.FOar); - if (acceleration > 0F) { - this.inputUp = true; - } - - /* acceleration = (float) (dataHolder.rowTracker.forces[0] + dataHolder.rowTracker.forces[1]); - if (acceleration > 0.005F) { - this.inputUp = true; - } - */ + this.inputLeft = dataHolder.rowTracker.paddleInWater[0] && !dataHolder.rowTracker.paddleInWater[1]; + this.inputRight = dataHolder.rowTracker.paddleInWater[1] && !dataHolder.rowTracker.paddleInWater[0]; + this.inputUp = dataHolder.rowTracker.paddleInWater[0] || dataHolder.rowTracker.paddleInWater[1]; + + this.paddleAngles[0] = dataHolder.rowTracker.paddleAngles[0]; + this.paddleAngles[1] = dataHolder.rowTracker.paddleAngles[1]; } } return acceleration; } + + @Inject(at = @At(value = "HEAD"), method = "tick()V") + private void vivecraft$clearPaddleAngles(CallbackInfo ci) { + this.paddleAngles[0] = null; + this.paddleAngles[1] = null; + } + + @Override + public Vec3[] vivecraft$getPaddleAngles() { + return this.paddleAngles; + } } diff --git a/common/src/main/java/org/vivecraft/mixin/server/ServerPlayerMixin.java b/common/src/main/java/org/vivecraft/mixin/server/ServerPlayerMixin.java index 91324faaf..353c3c193 100644 --- a/common/src/main/java/org/vivecraft/mixin/server/ServerPlayerMixin.java +++ b/common/src/main/java/org/vivecraft/mixin/server/ServerPlayerMixin.java @@ -20,6 +20,7 @@ import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.projectile.AbstractArrow; +import net.minecraft.world.item.BowItem; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.item.alchemy.PotionUtils; @@ -110,6 +111,19 @@ protected ServerPlayerMixin(EntityType entityType, Level } } + @Override + public void releaseUsingItem() { + ServerVivePlayer serverVivePlayer = vivecraft$getVivePlayer(); + if (serverVivePlayer != null && serverVivePlayer.isVR()) { + if (serverVivePlayer.draw > 0.0F) { + if (!this.useItem.isEmpty()) { + this.useItemRemaining = Math.max(this.useItem.getUseDuration() - (int) (BowItem.MAX_DRAW_DURATION * serverVivePlayer.draw), 0); + } + } + } + super.releaseUsingItem(); + } + /** * inject into {@link Player#attack} */ diff --git a/common/src/main/java/org/vivecraft/mixin/world/entity/projectile/ProjectileMixin.java b/common/src/main/java/org/vivecraft/mixin/world/entity/projectile/ProjectileMixin.java index 84e9f7432..ffb3959dd 100644 --- a/common/src/main/java/org/vivecraft/mixin/world/entity/projectile/ProjectileMixin.java +++ b/common/src/main/java/org/vivecraft/mixin/world/entity/projectile/ProjectileMixin.java @@ -4,9 +4,7 @@ import com.llamalad7.mixinextras.sugar.ref.LocalRef; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.projectile.AbstractArrow; import net.minecraft.world.entity.projectile.Projectile; -import net.minecraft.world.entity.projectile.ThrownTrident; import net.minecraft.world.phys.Vec3; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -27,13 +25,6 @@ public class ProjectileMixin { // aim direction direction.set(serverVivePlayer.getAimDir()); - - if (projectile instanceof AbstractArrow && !(projectile instanceof ThrownTrident) && - !serverVivePlayer.isSeated() && serverVivePlayer.draw > 0.0F) - { - // modify velocity based on draw range - return velocity * serverVivePlayer.draw; - } } } return velocity; diff --git a/common/src/main/resources/vivecraft.mixins.json b/common/src/main/resources/vivecraft.mixins.json index 9fa99a819..1e7675692 100644 --- a/common/src/main/resources/vivecraft.mixins.json +++ b/common/src/main/resources/vivecraft.mixins.json @@ -56,6 +56,7 @@ "client_vr.gui.screens.inventory.CreativeModeInventoryScreenVRMixin", "client_vr.gui.screens.inventory.SignEditScreenVRMixin", "client_vr.lwjgl.OpenVRMixin", + "client_vr.model.BoatModelMixin", "client_vr.multiplayer.ClientPacketListenerVRMixin", "client_vr.multiplayer.MultiPlayerGameModeVRMixin", "client_vr.particle.ItemPickupParticleVRMixin",