1
0
forked from Clones/Controlify

Support for analog boat movement.

This commit is contained in:
isXander
2023-06-15 18:16:59 +01:00
parent 3f820e1c01
commit f7cf37f201
5 changed files with 114 additions and 1 deletions

View File

@ -0,0 +1,5 @@
package dev.isxander.controlify.fixes.boatfix;
public interface AnalogBoatInput {
void setAnalogInput(float forward, float right);
}

View File

@ -0,0 +1,69 @@
package dev.isxander.controlify.mixins.feature.fixes.boatfix;
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import dev.isxander.controlify.fixes.boatfix.AnalogBoatInput;
import net.minecraft.world.entity.vehicle.Boat;
import org.objectweb.asm.Opcodes;
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.ModifyVariable;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(Boat.class)
public abstract class BoatMixin implements AnalogBoatInput {
@Shadow private float deltaRotation;
@Shadow private boolean inputLeft;
@Shadow private boolean inputRight;
@Shadow private boolean inputUp;
@Shadow private boolean inputDown;
@Unique private float analogForward;
@Unique private float analogRight;
@Unique private boolean usingAnalogInput;
@Inject(method = "controlBoat", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/vehicle/Boat;getYRot()F", ordinal = 0))
private void rotateBoatAnalog(CallbackInfo ci) {
if (usingAnalogInput)
this.deltaRotation += analogRight;
}
@ModifyVariable(method = "controlBoat", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/vehicle/Boat;setYRot(F)V", shift = At.Shift.AFTER), ordinal = 0)
private float forwardBoatAnalog(float forwardVelocity) {
if (!usingAnalogInput)
return forwardVelocity;
float velocity = analogForward > 0 ? analogForward * 0.04f : analogForward * 0.005f;
return forwardVelocity + velocity;
}
@ModifyExpressionValue(method = "controlBoat", at = {
@At(value = "FIELD", target = "Lnet/minecraft/world/entity/vehicle/Boat;inputLeft:Z", opcode = Opcodes.GETFIELD, ordinal = 0),
@At(value = "FIELD", target = "Lnet/minecraft/world/entity/vehicle/Boat;inputRight:Z", opcode = Opcodes.GETFIELD, ordinal = 0),
@At(value = "FIELD", target = "Lnet/minecraft/world/entity/vehicle/Boat;inputUp:Z", opcode = Opcodes.GETFIELD, ordinal = 1),
@At(value = "FIELD", target = "Lnet/minecraft/world/entity/vehicle/Boat;inputDown:Z", opcode = Opcodes.GETFIELD, ordinal = 1)
})
private boolean shouldDoDigitalInput(boolean original) {
return !usingAnalogInput && original;
}
@Override
public void setAnalogInput(float forward, float right) {
this.usingAnalogInput = true;
this.analogForward = forward;
this.analogRight = right;
this.inputLeft = right < 0;
this.inputRight = right > 0;
this.inputUp = forward > 0;
this.inputDown = forward < 0;
}
@Inject(method = "setInput", at = @At("HEAD"))
private void onUseDigitalInput(boolean pressingLeft, boolean pressingRight, boolean pressingForward, boolean pressingBack, CallbackInfo ci) {
this.usingAnalogInput = false;
}
}

View File

@ -0,0 +1,37 @@
package dev.isxander.controlify.mixins.feature.fixes.boatfix;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import dev.isxander.controlify.Controlify;
import dev.isxander.controlify.InputMode;
import dev.isxander.controlify.api.ControlifyApi;
import dev.isxander.controlify.controller.Controller;
import dev.isxander.controlify.fixes.boatfix.AnalogBoatInput;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.world.entity.vehicle.Boat;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import java.util.Optional;
@Mixin(LocalPlayer.class)
public class LocalPlayerMixin {
@WrapOperation(method = "rideTick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/vehicle/Boat;setInput(ZZZZ)V"))
private void useAnalogInput(Boat boat, boolean pressingLeft, boolean pressingRight, boolean pressingForward, boolean pressingBack, Operation<Void> original) {
if (ControlifyApi.get().currentInputMode() == InputMode.CONTROLLER && !Controlify.instance().config().globalSettings().keyboardMovement) {
Optional<Controller<?, ?>> controllerOpt = ControlifyApi.get().getCurrentController();
if (controllerOpt.isPresent()) {
var controller = controllerOpt.get();
((AnalogBoatInput) boat).setAnalogInput(
controller.bindings().WALK_FORWARD.state() - controller.bindings().WALK_BACKWARD.state(),
controller.bindings().WALK_RIGHT.state() - controller.bindings().WALK_LEFT.state()
);
return;
}
}
original.call(boat, pressingLeft, pressingRight, pressingForward, pressingBack);
}
}