package dev.isxander.controlify.server; import dev.isxander.controlify.rumble.*; import dev.isxander.controlify.utils.Easings; import dev.isxander.controlify.utils.Log; import net.fabricmc.fabric.api.networking.v1.FabricPacket; import net.fabricmc.fabric.api.networking.v1.PacketType; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.phys.Vec3; import org.joml.Vector3f; public record OriginVibrationPacket(Vector3f origin, float effectRange, int duration, RumbleState state, RumbleSource source) implements FabricPacket { public static final PacketType TYPE = PacketType.create(new ResourceLocation("controlify", "vibrate_from_origin"), OriginVibrationPacket::new); public OriginVibrationPacket(FriendlyByteBuf buf) { this(buf.readVector3f(), buf.readFloat(), buf.readVarInt(), readState(buf), RumbleSource.get(buf.readResourceLocation())); } @Override public void write(FriendlyByteBuf buf) { buf.writeVector3f(origin); buf.writeFloat(effectRange); buf.writeVarInt(duration); int high = (int)(state.strong() * 32767.0F); int low = (int)(state.weak() * 32767.0F); buf.writeInt((high << 16) | (low & 0xFFFF)); buf.writeResourceLocation(source.id()); } @Override public PacketType getType() { return TYPE; } public RumbleEffect createEffect() { var originVec3 = new Vec3(origin); return ContinuousRumbleEffect.builder() .constant(state) .inWorld(() -> originVec3, 0, 1, effectRange, Easings::easeInSine) .timeout(duration) .build(); } public static RumbleState readState(FriendlyByteBuf buf) { int packed = buf.readInt(); float strong = (short)(packed >> 16) / 32767.0F; float weak = (short)packed / 32767.0F; return new RumbleState(strong, weak); } }