1
0
forked from Clones/Controlify

🎮📳 Controller Vibration! (#38)

This commit is contained in:
Xander
2023-04-04 17:17:01 +01:00
committed by GitHub
parent 2bf7cf4792
commit ebbc549e32
32 changed files with 686 additions and 42 deletions

View File

@ -7,7 +7,7 @@ import org.spongepowered.asm.mixin.gen.Accessor;
import java.util.List;
@Mixin(KeyBindingRegistryImpl.class)
@Mixin(value = KeyBindingRegistryImpl.class, remap = false)
public interface KeyBindingRegistryImplAccessor {
@Accessor("MODDED_KEY_BINDINGS")
static List<KeyMapping> getCustomKeys() {

View File

@ -28,13 +28,13 @@ public abstract class MinecraftMixin {
@ModifyExpressionValue(method = "<init>", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/packs/resources/ReloadableResourceManager;createReload(Ljava/util/concurrent/Executor;Ljava/util/concurrent/Executor;Ljava/util/concurrent/CompletableFuture;Ljava/util/List;)Lnet/minecraft/server/packs/resources/ReloadInstance;"))
private ReloadInstance onInputInitialized(ReloadInstance resourceReload) {
// Controllers need to be initialized extremely late due to the data-driven nature of controllers.
resourceReload.done().thenRun(() -> Controlify.instance().initializeControllers());
resourceReload.done().thenRun(() -> Controlify.instance().initializeControlify());
return resourceReload;
}
@Inject(method = "<init>", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/KeyboardHandler;setup(J)V", shift = At.Shift.AFTER))
private void onInputInitialized(CallbackInfo ci) {
Controlify.instance().initializeControlify();
Controlify.instance().preInitialiseControlify();
}
@Inject(method = "runTick", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MouseHandler;turnPlayer()V"))

View File

@ -0,0 +1,31 @@
package dev.isxander.controlify.mixins.feature.rumble.damage;
import dev.isxander.controlify.api.ControlifyApi;
import dev.isxander.controlify.rumble.RumbleEffect;
import net.minecraft.client.player.LocalPlayer;
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;
@Mixin(LocalPlayer.class)
public class LocalPlayerMixin {
@Inject(method = "hurtTo", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/LocalPlayer;setHealth(F)V", ordinal = 1))
private void onClientHurt(float health, CallbackInfo ci) {
// LivingEntity#hurt is server-side only, so we do it here
doRumble();
}
@Inject(method = "hurtTo", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/LocalPlayer;setHealth(F)V", ordinal = 0))
private void onClientHealthUpdate(float health, CallbackInfo ci) {
// for some reason fall damage calls hurtTo after the health has been updated at some point
// this is called when hurtTo is set to the same health as the player already has
doRumble();
}
private void doRumble() {
ControlifyApi.get().currentController().rumbleManager().play(
RumbleEffect.constant(0.5f, 0f, 5)
);
}
}

View File

@ -0,0 +1,46 @@
package dev.isxander.controlify.mixins.feature.rumble.sounds;
import dev.isxander.controlify.api.ControlifyApi;
import dev.isxander.controlify.rumble.RumbleEffect;
import dev.isxander.controlify.rumble.RumbleState;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.LevelEvent;
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;
@Mixin(LevelRenderer.class)
public class LevelRendererMixin {
@Inject(method = "levelEvent", at = @At("HEAD"))
private void onLevelEvent(int eventId, BlockPos pos, int data, CallbackInfo ci) {
switch (eventId) {
case LevelEvent.SOUND_ANVIL_USED -> rumble(
RumbleEffect.join(
RumbleEffect.constant(1f, 0.5f, 2),
RumbleEffect.empty(5)
).repeat(3)
);
}
}
@Inject(method = "globalLevelEvent", at = @At("HEAD"))
private void onGlobalLevelEvent(int eventId, BlockPos pos, int data, CallbackInfo ci) {
switch (eventId) {
case LevelEvent.SOUND_DRAGON_DEATH -> rumble(
RumbleEffect.join(
RumbleEffect.constant(1f, 1f, 194),
RumbleEffect.byTime(t -> {
float easeOutQuad = 1 - (1 - t) * (1 - t);
return new RumbleState(1 - easeOutQuad, 1 - easeOutQuad);
}, 63)
)
);
}
}
private void rumble(RumbleEffect effect) {
ControlifyApi.get().currentController().rumbleManager().play(effect);
}
}

View File

@ -0,0 +1,23 @@
package dev.isxander.controlify.mixins.feature.rumble.useitem;
import dev.isxander.controlify.api.ControlifyApi;
import dev.isxander.controlify.rumble.RumbleEffect;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.ItemStack;
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.callback.CallbackInfo;
@Mixin(LivingEntity.class)
public abstract class LivingEntityMixin {
@Shadow public abstract int getUseItemRemainingTicks();
@Inject(method = "updateUsingItem", at = @At("HEAD"))
protected void onUpdateUsingItem(ItemStack stack, CallbackInfo ci) {
}
}

View File

@ -0,0 +1,29 @@
package dev.isxander.controlify.mixins.feature.rumble.useitem;
import dev.isxander.controlify.api.ControlifyApi;
import dev.isxander.controlify.rumble.RumbleEffect;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.util.Mth;
import net.minecraft.world.item.ItemStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(LocalPlayer.class)
public abstract class LocalPlayerMixin extends LivingEntityMixin {
@Override
protected void onUpdateUsingItem(ItemStack stack, CallbackInfo ci) {
switch (stack.getUseAnimation()) {
case BOW, CROSSBOW, SPEAR -> {
var magnitude = Mth.clamp((stack.getUseDuration() - getUseItemRemainingTicks()) / 20f, 0f, 1f) * 0.5f;
playRumble(RumbleEffect.constant(magnitude * 0.3f, magnitude, 1));
}
case BLOCK, SPYGLASS -> playRumble(RumbleEffect.constant(0f, 0.1f, 1));
case EAT, DRINK -> playRumble(RumbleEffect.constant(0.05f, 0.1f, 1));
case TOOT_HORN -> playRumble(RumbleEffect.constant(1f, 0.25f, 1));
}
}
private void playRumble(RumbleEffect effect) {
ControlifyApi.get().currentController().rumbleManager().play(effect);
}
}