using System;
using UnityEngine;
using Animancer;
using BaseGames.Combat;
using BaseGames.Feedback;
namespace BaseGames.Player
{
///
/// 武器数据 SO(纯数据,不含 Prefab 引用)。
/// 每个攻击方向对应一个 DamageSourceSO 和 ClipTransition。
/// HitBox 直接挂载在 Player Prefab 上(架构 05_PlayerModule §7)。
///
[CreateAssetMenu(menuName = "BaseGames/Player/Weapon")]
public class WeaponSO : ScriptableObject
{
[Header("基础信息")]
public string weaponId; // 全局唯一 ID,如 "Weapon_SkyBlade"
public string displayName; // 显示名,如 "天裂刃"
public Sprite icon;
public WeaponType weaponType;
[Header("地面连击序列(任意段数)")]
[Tooltip("每个元素对应一段连击,支持任意段数,无需修改代码。")]
public ComboStepConfig[] groundComboSteps =
{
new ComboStepConfig
{
hitBoxEnter = 0.3f, hitBoxExit = 0.6f,
comboInputOpen = 0.3f,
cancelWindowOpen = 0.5f,
recoveryTime = 0.05f,
comboTimeout = 0.25f,
}
};
[Header("空中攻击序列")]
[Tooltip("空中攻击连击序列,通常只需 1 段。")]
public ComboStepConfig[] airComboSteps =
{
new ComboStepConfig { hitBoxEnter = 0.1f, hitBoxExit = 0.8f, recoveryTime = 0.05f }
};
[Header("上劈(固定单段)")]
public ComboStepConfig upStep = new ComboStepConfig { hitBoxEnter = 0.2f, hitBoxExit = 0.7f, recoveryTime = 0.05f };
[Header("下劈(固定单段)")]
public ComboStepConfig downStep = new ComboStepConfig { hitBoxEnter = 0.1f, hitBoxExit = 0.9f, recoveryTime = 0.05f };
[Header("HitBox Prefab")]
[Tooltip("武器专属 HitBox Prefab,内含 WeaponHitBoxInstance。\nWeaponManager 在切换武器时实例化于 [WeaponSocket] 下,武器卸下时销毁。\n命名规范:Assets/Prefabs/Weapons/WPN_{weaponId}_HitBox.prefab")]
public GameObject hitBoxPrefab;
[Header("武器特效")]
public WeaponVFXConfig vfxConfig;
[Header("战斗参数")]
[Tooltip("命中确认时增加的灵力值(覆盖 PlayerCombat 默认值 10)")]
[Min(0)]
public int soulPowerGain = 10;
[Tooltip("命中敌人时的打击力度反馈档位(影响摄像机震屏和控制器振动强度)。")]
public HitWeight hitWeight = HitWeight.Medium;
// ── 查询 API ──────────────────────────────────────────────────────────
/// 取指定方向、指定段的完整配置,越界自动取最后一个。
public ComboStepConfig GetDirStep(AttackDirection dir, int index = 0)
{
if (dir == AttackDirection.Up) return upStep;
if (dir == AttackDirection.Down) return downStep;
var arr = dir switch
{
AttackDirection.Ground => groundComboSteps,
AttackDirection.Air => airComboSteps,
_ => groundComboSteps,
};
if (arr == null || arr.Length == 0)
return new ComboStepConfig { hitBoxEnter = 0.3f, hitBoxExit = 0.6f, recoveryTime = 0.05f, comboTimeout = 0.25f };
int idx = index < arr.Length ? index : arr.Length - 1;
return arr[idx];
}
/// 取指定方向第 0 段的 DamageSource(供 EnableWeaponHitBox 使用)。
public DamageSourceSO GetSourceByDir(AttackDirection dir) => GetDirStep(dir, 0).damageSource;
// ── 地面连击便捷方法 ──────────────────────────────────────────────────
public ComboStepConfig GetGroundStep(int index) => GetDirStep(AttackDirection.Ground, index);
public ClipTransition GetClipByCombo(int index) => GetGroundStep(index).clip;
/// 地面连击最大段数。
public int GroundComboCount => groundComboSteps?.Length ?? 0;
}
/// 单段攻击的完整配置:动画、伤害、HitBox 时间、连击窗口、攻速缩放参数。
[System.Serializable]
public struct ComboStepConfig
{
[Header("动画 & 伤害")]
public ClipTransition clip;
public DamageSourceSO damageSource;
[Header("HitBox 激活窗口(归一化 0-1)")]
[Tooltip("HitBox 开启时间点")]
[UnityEngine.Range(0f, 1f)] public float hitBoxEnter;
[Tooltip("HitBox 关闭时间点")]
[UnityEngine.Range(0f, 1f)] public float hitBoxExit;
[Header("连击输入窗口(归一化 0-1,0 = 从动画开始就可输入)")]
[Tooltip("从此时间点起接受下一段连击输入(0 = 动画开始即可)")]
[UnityEngine.Range(0f, 1f)] public float comboInputOpen;
[Tooltip("从此时间点起停止接受连击输入(0 = 持续到动画结束)")]
[UnityEngine.Range(0f, 1f)] public float comboInputClose;
[Header("取消窗口(归一化 0-1,0 = 仅在动画结束后恢复期内开放)")]
[Tooltip("从此时间点起允许跳跃/冲刺打断")]
[UnityEngine.Range(0f, 1f)] public float cancelWindowOpen;
[Header("时间(秒,受攻速倍率缩放)")]
[Tooltip("动画结束后的硬直时间,期间跳跃/冲刺无法打断")]
[UnityEngine.Min(0f)] public float recoveryTime;
[Tooltip("硬直结束后等待连击输入的时间,超时返回 Idle(0 = 立即返回)")]
[UnityEngine.Min(0f)] public float comboTimeout;
[Header("HitBox 绑定(留空 = 使用该方向的默认 HitBox)")]
[Tooltip("对应 Prefab 中 HitBox 组件的 Id 字段。\n留空 = 使用方向默认 HitBox;\n非空 = 精确激活该 Id 的 HitBox,可视化编辑其 Collider2D 即为本段的判定形状。")]
public string hitBoxId;
}
// ── 武器类型枚举(架构 05 §7)──────────────────────────────────────────────
public enum WeaponType
{
TianHun, // 天魂:裂空刃(高频轻击)
DiHun, // 地魂:地震锤(低频重击,范围大)
MingHun, // 命魂:命镰(穿透,直线斩)
Custom, // 护符替换或未来扩展武器
}
// ── 武器特效配置([Serializable] 内嵌,架构 05 §7)────────────────────────
[Serializable]
public class WeaponVFXConfig
{
[Tooltip("切换到此武器时播放的特效预设 ID(对应 IFeedbackPlayer.TriggerPreset)")]
public string onEquipPresetId;
[Tooltip("武器挥斩拖尾 Prefab(null = 不显示拖尾)")]
public GameObject weaponTrailPrefab;
public Color trailColor = Color.white;
}
}