ThreeKingdomsSlingshot/Assets/Scripts/Runtime/Skills/SkillStatus.cs

104 lines
3.6 KiB
C#
Raw Permalink Normal View History

장수 스킬 144개 새 기획 구현(#1112 · PD 2026-11-10 엑셀 「장수 목록」) — 효과 표 skill_effects.csv(효과 1줄 · 한글 주석 열) · 이름 56개 새로 - 수치 SOT = Assets/Data/OutGame/skill_effects.csv(skill_id·key·target·cond·dur·p1~p3 + effect_ko·p1_ko~p3_ko 주석) · skills.csv effect_key = 키 목록 · heroes.csv gender(m|f) - 처리기 121종(SkillKeys) · 대상 칸(자신·같은 편·진영·반경·행동 반경) · 조건 칸(치명타·상대 상태 이상·병종·성별·턴·장착 중) · 지속 라운드 - 상태 이상 = 혼란·출혈(이동 거리 비례)·중독(중첩)·화상 + 기절(기믹 행동 불가 재사용) · 정화 · 회복·흡혈·부활·무적·무효화·호위(반격) - 재행동(유비·위연·여몽·손견·곽가·우금·맹획·감녕·고순·장합) · 치명타 확률·피해·무조건 - 이동 변형: 관통(손견·안량·손책 아군 통과) · 핀볼 튕김(손책·동탁) · 복귀(조운·손책·여포·문추·공손찬·순우경 · 하후돈 탭 지점·쓸어 감) · 위치 교환(위연) · 끌어오기(장료) · 아군 통과+탭 방향 밀치기(조조) · 반복(정보) · 난동(동탁) - 특수 사격: 거대 화살 · 직선 관통 · 폭발(화염구·독구름·운석·화살비) · 부채꼴 · 멀티샷 · 도탄 · 회오리 · 목책 · 불 장벽·불꽃·독 지대 · 궁병식 비도 · 광역 회복 - 즉시형: 광역 타격·밀기 · 흡수 · 일제 사격 · 미인계 끌어오기 · 범위 회복·정화 · 재행동 부여 · 변진 - 가상 실행(적 AI) 스킬 상태 사본(TakeState/RestoreState) · 옛 견제 스킬 확장 제거 - 테스트(고친 부분 클래스만): SkillTests 19(새로) · BattleFlowTests 42 · TacticalAITests 7 · GimmickTests 19 · OutGameTests 15 · OutGameCTests 12 전부 통과 · console error 0 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 10:00:18 +00:00
using System.Collections.Generic;
using UnityEngine;
namespace TKS
{
/// <summary>
/// 스킬 상태 이상 1기분(2026-11-10 #1112 · PD 기획 정의):
/// 혼란 = 그 유닛 차례 동안 이동 거리 × 배율(장료·육손·손권 「이동력 50 % 감소」) · 출혈 = 움직인 거리 비례 최대 HP 피해(서황 「이동 거리의 50 %에 비례」) ·
/// 중독 = 그 진영 턴 시작 + 자기 행동 끝마다 최대 HP %(가후·축융 · 가후 패시브 = 중첩) · 화상(불태우기) = 그 진영 턴 시작마다 최대 HP %(서서).
/// 기절 = 기존 지형 기믹 「행동 불가」(GimmickLayer.Stun · 다음 자기 턴을 쉼)를 그대로 쓴다.
/// 턴 수 = 그 유닛 진영의 턴 기준(자기 턴 중에 걸리면 다음 턴부터 셈).
/// </summary>
public class UnitStatus
{
public int ConfuseTurns;
public float ConfuseMult = 1f;
public int BleedTurns;
public float BleedPct;
public int PoisonTurns;
public float PoisonPct;
public int PoisonStacks;
public int BurnTurns;
public float BurnPct;
public TextMesh Badge;
public UnitStatus Copy()
{
return (UnitStatus)MemberwiseClone();
}
public bool Any
{
get { return ConfuseTurns > 0 || BleedTurns > 0 || PoisonTurns > 0 || BurnTurns > 0; }
}
public void Clear()
{
ConfuseTurns = BleedTurns = PoisonTurns = BurnTurns = PoisonStacks = 0;
ConfuseMult = 1f;
}
}
public static class SkillStatus
{
public static readonly Color TextColor = new Color(0.95f, 0.55f, 1f);
static UnitStatus Of(Unit u)
{
var sys = SkillSystem.Current;
return sys != null ? sys.StatusOf(u) : null;
}
public static bool Confused(Unit u)
{
var s = Of(u);
return s != null && s.ConfuseTurns > 0;
}
public static float ConfuseMult(Unit u)
{
var s = Of(u);
return s != null && s.ConfuseTurns > 0 ? Mathf.Clamp(s.ConfuseMult, 0.05f, 1f) : 1f;
}
public static bool Bleeding(Unit u)
{
var s = Of(u);
return s != null && s.BleedTurns > 0;
}
public static bool Poisoned(Unit u)
{
var s = Of(u);
if (s != null && s.PoisonTurns > 0) return true;
var g = GimmickLayer.Current != null ? GimmickLayer.Current.StateOf(u) : null;
return g != null && g.PoisonTurns > 0;
}
public static bool Stunned(Unit u)
{
var g = GimmickLayer.Current != null ? GimmickLayer.Current.StateOf(u) : null;
return g != null && (g.Stun > 0 || g.Skip);
}
/// <summary>상태 이상 아무것이나(스킬 상태 + 지형 기믹 중독·행동 불가).</summary>
public static bool HasAny(Unit u)
{
var s = Of(u);
return (s != null && s.Any) || Poisoned(u) || Stunned(u);
}
public static string BadgeText(UnitStatus s)
{
if (s == null) return "";
var parts = new List<string>();
if (s.ConfuseTurns > 0) parts.Add("혼란" + s.ConfuseTurns);
if (s.BleedTurns > 0) parts.Add("출혈" + s.BleedTurns);
if (s.PoisonTurns > 0) parts.Add("독" + s.PoisonTurns + (s.PoisonStacks > 1 ? "×" + s.PoisonStacks : ""));
if (s.BurnTurns > 0) parts.Add("화상" + s.BurnTurns);
return string.Join(" ", parts.ToArray());
}
}
}