Project_WL/Assets/WL/Combat/Reaction/WLSkillHitFeel.cs

96 lines
5.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ─────────────────────────────────────────────────────────────────────────────
// WLSkillHitFeel.cs — 스킬별 피격 반응 덮어쓰기(밀림 · 넉백 · 경직) (#915 · 2026-10-17)
//
// PD 원문: 「검 각성 공격에 적중 된 적은 경직 상태로 살짝만 밀리게 해줘(현재는 밀리는 거리 때문에 가장자리에 있는 적이 밀려나 맞지 않을 수 있음)」
// ■ 그 스킬(맞힌 투사체의 SkillListTableData.e_Skill)에 맞은 몹만:
// · 피격 밀기(MobStagger #903 mobHitPushDistance) 거리 × pushScale
// · 원본 넉백(능력치 AttackKnockBack → Actor.KnockBack) 거리 × knockbackScale(MobKnockbackScale 이 몹 넉백 배율 대신 쓴다)
// · 경직 = max(등급별 경직, staggerSeconds)
// ■ 값 = Resources/WL/WLSkillHitFeel.json (C45) · 끄기 = enabled 0 · RuntimeDisabled(프로브 전후 비교용)
// 🔴 Debug.LogError 금지(원본 팝업).
// ─────────────────────────────────────────────────────────────────────────────
using System.Collections.Generic;
using UnityEngine;
using WL.Combat.Core;
namespace WL.Combat.Reaction
{
[System.Serializable]
public class WLSkillHitFeelRule
{
public string skill = ""; // eEffect 이름(원본 스킬 클래스)
public float pushScale = 1f; // 피격 밀기 거리 배율
public float pushMeters; // #974 > 0 = 피격 밀기 거리 고정(m · pushScale 대신) — PD 「0.2m 정도 넉백」
public float knockbackScale = 1f; // 원본 넉백 거리 배율(몹 넉백 배율 대신)
public float staggerSeconds; // 경직 최소 시간(0 = 등급별 그대로)
}
[System.Serializable]
public class WLSkillHitFeelJson
{
public int enabled = 1;
public WLSkillHitFeelRule[] rules = new WLSkillHitFeelRule[0];
public string note = "";
}
public static class WLSkillHitFeel
{
public const string ResourcesPath = "WL/WLSkillHitFeel";
public static bool RuntimeDisabled;
public static string LastLog = "";
static WLSkillHitFeelJson s_cfg;
static readonly Dictionary<int, WLSkillHitFeelRule> s_rules = new Dictionary<int, WLSkillHitFeelRule>();
static WLSkillHitFeelJson Cfg
{
get
{
if (s_cfg != null) return s_cfg;
s_cfg = new WLSkillHitFeelJson(); s_rules.Clear();
var ta = Resources.Load<TextAsset>(ResourcesPath);
if (ta == null) { LastLog = "설정 없음 " + ResourcesPath; return s_cfg; }
try { JsonUtility.FromJsonOverwrite(ta.text, s_cfg); } catch (System.Exception ex) { LastLog = "설정 파싱 실패 — " + ex.Message; }
if (s_cfg.rules != null)
foreach (var r in s_cfg.rules)
{
eEffect ef;
if (r != null && System.Enum.TryParse(r.skill, out ef)) s_rules[(int)ef]= r;
else LastLog = "스킬 이름 없음 " + (r != null ? r.skill : "null");
}
return s_cfg;
}
}
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
static void Reset() { s_cfg = null; s_rules.Clear(); RuntimeDisabled = false; }
/// <summary>#918 원본 Actor 피해 처리의 넉백 훅 1줄 — 이 피해를 낸 스킬 규칙의 knockbackScale 이 0 이하면 원본 넉백을 아예 시작하지 않는다
/// (넉백 거리 배율은 시작된 뒤에 줄이므로 0 이어도 맞을 때마다 첫 프레임만큼(약 0.07 m) 밀렸다 · 연타 8 회면 약 0.5 m).</summary>
public static bool SkipKnockback(DamageInfo d)
{
if (RuntimeDisabled || d == null) return false;
var c = Cfg;
if (c.enabled == 0 || s_rules.Count == 0) return false;
var pd = d.Beater_pd; var s = pd != null ? pd.m_SkillListTableData : null;
if (s == null) return false;
WLSkillHitFeelRule r;
if (!s_rules.TryGetValue((int)s.e_Skill, out r) || r.knockbackScale > 0f) return false;
KnockbackSkipped++;
return true;
}
public static int KnockbackSkipped;
/// <summary>이 피격을 낸 스킬의 규칙(없으면 null).</summary>
public static WLSkillHitFeelRule For(in HitConfirmedEvent e)
{
if (RuntimeDisabled) return null;
var c = Cfg;
if (c.enabled == 0 || s_rules.Count == 0) return null;
var pd = e.projectile; var s = pd != null ? pd.m_SkillListTableData : null;
if (s == null) return null;
WLSkillHitFeelRule r;
return s_rules.TryGetValue((int)s.e_Skill, out r) ? r : null;
}
}
}