package com.freeexile.arpg import android.content.Context import android.os.Build import android.os.VibrationEffect import android.os.Vibrator import android.os.VibratorManager /** * High-performance Android vibration engine providing combat impact and UI feedback * using Android VibrationEffect and VibratorManager APIs. */ class HapticFeedbackManager(private val context: Context) { private val vibrator: Vibrator? by lazy { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { val vibratorManager = context.getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as? VibratorManager vibratorManager?.defaultVibrator } else { @Suppress("DEPRECATION") context.getSystemService(Context.VIBRATOR_SERVICE) as? Vibrator } } fun triggerHaptic(type: String) { val vib = vibrator ?: return if (!vib.hasVibrator()) return val normalizedType = type.lowercase().trim() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { when (normalizedType) { "heavy", "combat_heavy", "critical_hit" -> { vib.vibrate(VibrationEffect.createPredefined(VibrationEffect.EFFECT_HEAVY_CLICK)) } "medium", "combat_medium", "normal_hit" -> { vib.vibrate(VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK)) } "light", "combat_light" -> { vib.vibrate(VibrationEffect.createPredefined(VibrationEffect.EFFECT_TICK)) } "rigid", "shield_block", "parry" -> { vib.vibrate(VibrationEffect.createPredefined(VibrationEffect.EFFECT_DOUBLE_CLICK)) } "soft", "evade", "dodge" -> { vib.vibrate(VibrationEffect.createOneShot(20, 80)) } "success", "quest_complete", "item_upgrade" -> { val timings = longArrayOf(0, 30, 60, 45) val amplitudes = intArrayOf(0, 120, 0, 200) vib.vibrate(VibrationEffect.createWaveform(timings, amplitudes, -1)) } "warning", "low_life", "bleed" -> { val timings = longArrayOf(0, 50, 100, 50) val amplitudes = intArrayOf(0, 180, 0, 180) vib.vibrate(VibrationEffect.createWaveform(timings, amplitudes, -1)) } "error", "out_of_mana", "skill_cooldown" -> { val timings = longArrayOf(0, 80, 80, 80) val amplitudes = intArrayOf(0, 255, 0, 255) vib.vibrate(VibrationEffect.createWaveform(timings, amplitudes, -1)) } "selection", "inventory_slot", "gem_socket" -> { vib.vibrate(VibrationEffect.createPredefined(VibrationEffect.EFFECT_TICK)) } else -> { vib.vibrate(VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK)) } } } else { // Fallback for API 26-28 val duration = when (normalizedType) { "heavy", "critical_hit" -> 60L "medium" -> 35L "light" -> 15L "rigid" -> 45L "soft" -> 20L else -> 30L } val amplitude = when (normalizedType) { "heavy" -> 255 "medium" -> 160 "light" -> 80 else -> 128 } vib.vibrate(VibrationEffect.createOneShot(duration, amplitude)) } } }