2026-10-18 15:09:05 +00:00
|
|
|
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
|
|
|
|
// 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; // 피격 밀기 거리 배율
|
2026-10-23 13:08:59 +00:00
|
|
|
|
public float pushMeters; // #974 > 0 = 피격 밀기 거리 고정(m · pushScale 대신) — PD 「0.2m 정도 넉백」
|
2026-10-18 15:09:05 +00:00
|
|
|
|
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;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|