107 lines
6.3 KiB
C#
107 lines
6.3 KiB
C#
// ─────────────────────────────────────────────────────────────────────────────
|
||
// WLPartSkillText.cs — 파츠 스킬 표시 문구(장비 화면 · 스킬 상세 · 도감) (PD 지시 #879 · 기획 v2 18 · 19장)
|
||
// 문구의 숫자 = 레벨표 행(FR 원본) 그대로 + 설정 환산(거리 m). 등급 → 단계 = WLPartSkill.json tierLevel/tierMult.
|
||
// ─────────────────────────────────────────────────────────────────────────────
|
||
|
||
using System.Text;
|
||
using UnityEngine;
|
||
using WL.Equip;
|
||
|
||
namespace WL.PartSkill
|
||
{
|
||
public static class WLPartSkillText
|
||
{
|
||
public static string AttrName(string attr)
|
||
{
|
||
switch (attr)
|
||
{
|
||
case "attack": return "공격";
|
||
case "defense": return "방어";
|
||
case "passive": return "패시브";
|
||
case "weapon": return "무기 시너지";
|
||
}
|
||
return "";
|
||
}
|
||
|
||
public static string PartName(eFREquipmentType p) { return WLEquipTables.SlotName(p); }
|
||
|
||
static string N(float v) { return Mathf.Abs(v - Mathf.Round(v)) < 0.01f ? Mathf.Round(v).ToString("0") : v.ToString("0.#"); }
|
||
|
||
/// <summary>단계 1행 요약 — 「개수 4 · 피해 90% · 범위 2.1m · 쿨 7초」(패시브 = 값).</summary>
|
||
public static string LevelSummary(WLPartSkillDef d, int level, float mult) { return LevelSummary(d, level, mult, 99); }
|
||
|
||
/// <param name="maxParts">항목 수 상한(장비 팝업 한 줄용 · #881)</param>
|
||
public static string LevelSummary(WLPartSkillDef d, int level, float mult, int maxParts)
|
||
{
|
||
if (d == null) return "";
|
||
var S = WLPartSkillData.S;
|
||
if (d.kind == WLPartKind.Passive)
|
||
{
|
||
var p = WLPartSkillData.Passive(d.lvId, Mathf.Max(1, level));
|
||
if (p == null) return "";
|
||
string s = "+" + N(p.v0 * mult) + "%";
|
||
if (p.v1 > 0f) s += " · +" + N(p.v1 * mult) + "%";
|
||
if (d.behavior == "regen") s = (d.v1 > 0f ? N(d.v1) : "5") + "초마다 " + N(p.v0 * mult) + "% 회복";
|
||
return s;
|
||
}
|
||
var r = WLPartSkillData.Level(d.lvSrc, d.lvId, Mathf.Max(1, level));
|
||
if (r == null) return "";
|
||
var sb = new StringBuilder();
|
||
int parts = 0;
|
||
System.Action<string> add = x => { if (parts >= maxParts) return; if (sb.Length > 0) sb.Append(" · "); sb.Append(x); parts++; };
|
||
if (r.count > 1f) add("개수 " + N(r.count));
|
||
if (r.dmgPct > 0f && d.behavior != "heal_heart") add("피해 " + N(r.dmgPct * mult) + "%");
|
||
if (r.Has("Heal")) add("회복 " + N(r.Eff("Heal", "Percent", 0f) * mult) + "%");
|
||
float hit = r.hitRange > 0f ? r.hitRange : r.splash;
|
||
if (hit > 0f && d.behavior != "blades" && d.behavior != "homing") add("범위 " + Mathf.Max(S.minRadius, hit * S.distanceScale).ToString("0.0") + "m");
|
||
if (r.Has("Stun")) add("기절 " + N(r.Eff("Stun", "Duration", 0f)) + "초");
|
||
if (r.Has("Daze")) add("감속 " + N(r.Eff("Daze", "DecreaseMovePercentage", 0f)) + "%");
|
||
if (r.Has("Invincible")) add("무적 " + N(r.Eff("Invincible", "Duration", 0f)) + "초");
|
||
if (r.Has("DotDamageAddiction")) add("지속 피해 " + N(r.Eff("DotDamageAddiction", "DamagePercentage", 0f)) + "%");
|
||
if (r.duration < 0f) add("상시");
|
||
else if (r.cool > 0f) add("쿨 " + N(r.cool) + "초");
|
||
return sb.ToString();
|
||
}
|
||
|
||
/// <summary>등급(1~7) 행 문구 — 「Lv3 · 개수 3 · 피해 60%」 · 불멸 · 신화 = 「Lv5 수치 × 1.2」.</summary>
|
||
public static string TierRow(WLPartSkillDef d, int tier) { return TierRow(d, tier, 99); }
|
||
|
||
public static string TierRow(WLPartSkillDef d, int tier, int maxParts)
|
||
{
|
||
int lv = WLPartSkillData.TierLevel(tier);
|
||
float m = WLPartSkillData.TierMult(tier);
|
||
if (lv <= 0) return "닫힘";
|
||
if (m > 1.0001f) return "Lv" + lv + " 수치 × " + m.ToString("0.0#");
|
||
return "Lv" + lv + " · " + LevelSummary(d, lv, 1f, maxParts);
|
||
}
|
||
|
||
/// <summary>시너지 조건 · 상태 한 줄.</summary>
|
||
public static string SynergyLine(WLPartSlot s, bool rich)
|
||
{
|
||
if (s == null || s.def == null) return "";
|
||
var d = s.def; var S = WLPartSkillData.S;
|
||
int need = S.synergyLevel;
|
||
if (!string.IsNullOrEmpty(d.combineKey))
|
||
{
|
||
var other = WLPartSkillData.Def(d.combineKey);
|
||
string on = s.synergy ? (rich ? "<color=#FFD24A>★ 시너지 [정령왕]</color>" : "★ 시너지 [정령왕]") : "둘 다 " + need + "단계면 [정령왕]";
|
||
return d.name + " " + s.level + " + " + (other != null ? other.name : "?") + " " + s.synPartnerLevel + " = " + on;
|
||
}
|
||
if (string.IsNullOrEmpty(d.synKey)) return "";
|
||
var p = WLPartSkillData.Def(d.synKey);
|
||
string pn = p != null ? p.name + "(" + PartName(p.part) + ")" : "?";
|
||
if (d.kind == WLPartKind.WeaponSyn)
|
||
{
|
||
// #895 무기와 무관 — 장착 장비 조건(짝 패시브 [+ req_key])만
|
||
string cond = pn + " " + s.synPartnerLevel;
|
||
if (!string.IsNullOrEmpty(d.reqKey)) { var q = WLPartSkillData.Def(d.reqKey); cond += " + " + (q != null ? q.name + "(" + PartName(q.part) + ")" : d.reqKey); }
|
||
if (s.synergy) return cond + " = " + (rich ? "<color=#FFD24A>★ 무기 시너지 [" + d.synName + "]</color>" : "★ 무기 시너지 [" + d.synName + "]");
|
||
return cond + " · " + need + "단계면 무기 시너지 [" + d.synName + "] (무기 무관)";
|
||
}
|
||
string head = d.name + " " + s.level + " + " + pn + " " + s.synPartnerLevel;
|
||
if (s.synergy) return head + " = " + (rich ? "<color=#FFD24A>★ 시너지 [" + d.synName + "]</color>" : "★ 시너지 [" + d.synName + "]");
|
||
return head + " · 둘 다 " + need + "단계면 시너지";
|
||
}
|
||
}
|
||
}
|