forked from Clones/Controlify
explosion rumble
This commit is contained in:
@ -244,7 +244,7 @@ public class Controlify implements ControlifyApi {
|
||||
|
||||
private void onControllerDisconnect(int jid) {
|
||||
Controller.CONTROLLERS.values().stream().filter(controller -> controller.joystickId() == jid).findAny().ifPresent(controller -> {
|
||||
Controller.CONTROLLERS.remove(controller.uid(), controller);
|
||||
Controller.remove(controller);
|
||||
|
||||
setCurrentController(Controller.CONTROLLERS.values().stream().findFirst().orElse(null));
|
||||
LOGGER.info("Controller disconnected: " + controller.name());
|
||||
|
@ -67,7 +67,7 @@ public interface Controller<S extends ControllerState, C extends ControllerConfi
|
||||
}
|
||||
|
||||
static void remove(Controller<?, ?> controller) {
|
||||
CONTROLLERS.remove(controller.uid());
|
||||
CONTROLLERS.remove(controller.uid(), controller);
|
||||
controller.close();
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@ import dev.isxander.controlify.api.ControlifyApi;
|
||||
import dev.isxander.controlify.rumble.ContinuousRumbleEffect;
|
||||
import dev.isxander.controlify.rumble.RumbleSource;
|
||||
import dev.isxander.controlify.rumble.RumbleState;
|
||||
import dev.isxander.controlify.utils.Easings;
|
||||
import net.minecraft.client.multiplayer.MultiPlayerGameMode;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
@ -54,8 +55,8 @@ public class MultiPlayerGameModeMixin {
|
||||
private void startRumble(BlockState state) {
|
||||
ContinuousRumbleEffect effect = new ContinuousRumbleEffect(tick ->
|
||||
new RumbleState(
|
||||
0.02f + Math.min(1, state.getBlock().defaultDestroyTime() / 20f) * 0.25f,
|
||||
0.15f
|
||||
0.02f + Easings.easeInQuad(Math.min(1, state.getBlock().defaultDestroyTime() / 20f)) * 0.25f,
|
||||
0.01f
|
||||
)
|
||||
){
|
||||
@Override
|
||||
|
@ -0,0 +1,42 @@
|
||||
package dev.isxander.controlify.mixins.feature.rumble.explosion;
|
||||
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import dev.isxander.controlify.api.ControlifyApi;
|
||||
import dev.isxander.controlify.rumble.BasicRumbleEffect;
|
||||
import dev.isxander.controlify.rumble.RumbleSource;
|
||||
import dev.isxander.controlify.rumble.RumbleState;
|
||||
import dev.isxander.controlify.utils.Easings;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientPacketListener;
|
||||
import net.minecraft.network.protocol.game.ClientboundExplodePacket;
|
||||
import net.minecraft.world.level.Explosion;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
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(ClientPacketListener.class)
|
||||
public class ClientPacketListenerMixin {
|
||||
@Shadow @Final private Minecraft minecraft;
|
||||
|
||||
@Inject(method = "handleExplosion", at = @At("RETURN"))
|
||||
private void onClientExplosion(ClientboundExplodePacket packet, CallbackInfo ci) {
|
||||
float distanceSqr = Math.max(
|
||||
(float)minecraft.player.distanceToSqr(packet.getX(), packet.getY(), packet.getZ())
|
||||
- packet.getPower() * packet.getPower(), // power is explosion radius
|
||||
0f);
|
||||
float maxDistanceSqr = 4096f; // client only receives explosion packets within 64 blocks
|
||||
|
||||
float magnitude = 1f - Easings.easeOutQuad(distanceSqr / maxDistanceSqr);
|
||||
|
||||
ControlifyApi.get().currentController().rumbleManager().play(
|
||||
RumbleSource.EXPLOSION,
|
||||
BasicRumbleEffect.join(
|
||||
BasicRumbleEffect.constant(magnitude, magnitude, 4), // initial boom
|
||||
BasicRumbleEffect.byTime(t -> new RumbleState(0f, magnitude - t*magnitude), 20) // explosion
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package dev.isxander.controlify.mixins.feature.rumble.explosion;
|
||||
|
||||
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
|
||||
import dev.isxander.controlify.api.ControlifyApi;
|
||||
import dev.isxander.controlify.rumble.BasicRumbleEffect;
|
||||
import dev.isxander.controlify.rumble.RumbleSource;
|
||||
import dev.isxander.controlify.rumble.RumbleState;
|
||||
import net.minecraft.world.entity.LightningBolt;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
|
||||
@Mixin(LightningBolt.class)
|
||||
public class LightningBoltMixin {
|
||||
@ModifyExpressionValue(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;isClientSide()Z"))
|
||||
private boolean onLightningStrike(boolean client) {
|
||||
if (client) {
|
||||
ControlifyApi.get().currentController().rumbleManager().play(
|
||||
RumbleSource.EXPLOSION,
|
||||
BasicRumbleEffect.join(
|
||||
BasicRumbleEffect.constant(1f, 0.2f, 6), // initial boom
|
||||
BasicRumbleEffect.byTime(t -> new RumbleState(0f, 1 - t*0.2f), 10) // explosion
|
||||
)
|
||||
);
|
||||
}
|
||||
return client;
|
||||
}
|
||||
}
|
@ -15,6 +15,7 @@ public class RumbleSource {
|
||||
USE_ITEM = register("use_item"),
|
||||
ITEM_BREAK = register("item_break"),
|
||||
GUI = register("gui"),
|
||||
EXPLOSION = register("explosion"),
|
||||
GLOBAL_EVENT = register("global_event");
|
||||
|
||||
private final ResourceLocation id;
|
||||
|
Reference in New Issue
Block a user