using System.Collections.Generic;
namespace TKS
{
/// 스킬 수치가 레벨(lv_scale)·★5(패시브 배율)로 커지는 방식.
public enum SkillScale
{
/// 값 × 계수(비율·가산·거리·반경 · 기획서 §5 「수치 × (1 + lv_scale·(lv−1))」).
Value,
/// 배율(×k)은 1 을 넘는 몫만 키운다: 1 + (k − 1) × 계수 (×2 가 Lv5 에 ×2.8 이 되지 않게).
Mult,
/// 횟수 = 반올림(값 × 계수).
Count,
/// 켜고 끄는 값·치환 값(커지지 않음).
Fixed
}
///
/// effect_key 55종 처리기 목록(시스템 기획 §5 · skills.csv · 51 + 영웅 52명 확장 4 · PD #1096) — 키 이름 · 레벨 계수 적용 방식 · 같은 편 전원에게 걸리는가.
/// 기령 제외로 pushed_ally_attack_on_push(대장군)는 표에서 쓰지 않지만 처리기는 남긴다.
/// 이 표는 「처리기의 뜻」이고 수치는 전부 skills.csv(SkillInfoDb)에서 온다(C45). 표에 없는 키는 임포터가 오류로 막는다.
/// p 규약: 키가 여럿이면 p1~p3 = 키 순서 · 키 하나면 p1 = 값 · p2/p3 = 그 키의 조건·보조값(desc_ko [ ] 메모).
///
public static class SkillKeys
{
public const string SlingDistPct = "sling_dist_pct";
public const string PushMult = "push_mult";
public const string SelfBounceMult = "self_bounce_mult";
public const string ExtraMoveCount = "extra_move_count";
public const string ExtraMoveAttack = "extra_move_attack";
public const string OverwatchRadiusMult = "overwatch_radius_mult";
public const string OverwatchUnlimited = "overwatch_unlimited";
public const string OverwatchRadiusAdd = "overwatch_radius_add";
public const string OverwatchCount = "overwatch_count";
public const string OverwatchDmgMult = "overwatch_dmg_mult";
public const string CounterRatio = "counter_ratio";
public const string CounterTakenPct = "counter_taken_pct";
public const string PierceNoCounter = "pierce_no_counter";
public const string PierceReturnOnMiss = "pierce_return_on_miss";
public const string PierceKnockbackMult = "pierce_knockback_mult";
public const string PierceDmgPctPerHit = "pierce_dmg_pct_per_hit";
public const string PierceRepeat = "pierce_repeat";
public const string PierceDmgMult = "pierce_dmg_mult";
public const string ArrowCritAlways = "arrow_crit_always";
public const string ArrowPassAllies = "arrow_pass_allies";
public const string RangeMult = "range_mult";
public const string RangeAdd = "range_add";
public const string MeleePenaltyOff = "melee_penalty_off";
public const string SplashRadiusMult = "splash_radius_mult";
public const string SplashRatio = "splash_ratio";
public const string SplashAllyRatio = "splash_ally_ratio";
public const string MatchupFloor = "matchup_floor";
public const string DmgPct = "dmg_pct";
public const string DmgPctHpBelow = "dmg_pct_hp_below";
public const string DmgPctTurn1 = "dmg_pct_turn1";
public const string DmgVsGeneralMult = "dmg_vs_general_mult";
public const string DmgTakenPct = "dmg_taken_pct";
public const string DmgTakenAura = "dmg_taken_aura";
public const string DmgTakenFromArcherPct = "dmg_taken_from_archer_pct";
public const string PushedAllyAttackPct = "pushed_ally_attack_pct";
public const string PushedAllyAttackCount = "pushed_ally_attack_count";
public const string KnockbackTakenPct = "knockback_taken_pct";
public const string HpMaxPct = "hp_max_pct";
public const string HealOnOverwatchKill = "heal_on_overwatch_kill";
public const string HpCostAtk = "hp_cost_atk";
public const string AoePushFear = "aoe_push_fear";
public const string EnemyAggroAdd = "enemy_aggro_add";
public const string EnemyAggroOffTurn = "enemy_aggro_off_turn";
public const string TeamDmgTakenPctTurn = "team_dmg_taken_pct_turn";
public const string GuardShare = "guard_share";
public const string Teleport = "teleport";
public const string OnAllyDeathAtk = "on_ally_death_atk";
public const string TeamAtkPctFull = "team_atk_pct_full";
public const string SpearHitTwo = "spear_hit_two";
public const string PushedAllyAttackOnPush = "pushed_ally_attack_on_push";
public const string TeamRangeAdd = "team_range_add";
// 영웅 52명 확장(PD #1096 · 기획서 §5 끝) — 신규 4종
public const string TeamDmgPctTurn = "team_dmg_pct_turn";
public const string CooldownAdd = "cooldown_add";
public const string Charm = "charm";
public const string HealSelfPct = "heal_self_pct";
public class Info
{
public SkillScale Main;
/// p2(키 하나인 행의 보조값)도 같은 계수로 키우는가(절대 가산 · 최대치 · 충돌 추가 피해).
public bool ScaleA2;
/// 같은 편 전원에게 걸리는 효과(주인 = 같은 편 · 살아 있을 때).
public bool Team;
}
static Info I(SkillScale m, bool a2 = false, bool team = false)
{
return new Info { Main = m, ScaleA2 = a2, Team = team };
}
public static readonly Dictionary All = new Dictionary
{
{ SlingDistPct, I(SkillScale.Value, true) }, // p1 비율 · p2 절대 가산 · p3 1 = 아군 전원
{ PushMult, I(SkillScale.Mult, true) }, // p2 = 밀린 적이 벽·유닛에 닿으면 추가 피해 비율(고순)
{ SelfBounceMult, I(SkillScale.Value) },
{ ExtraMoveCount, I(SkillScale.Count) },
{ ExtraMoveAttack, I(SkillScale.Fixed) },
{ OverwatchRadiusMult, I(SkillScale.Mult) },
{ OverwatchUnlimited, I(SkillScale.Fixed) },
{ OverwatchRadiusAdd, I(SkillScale.Value) },
{ OverwatchCount, I(SkillScale.Count) },
{ OverwatchDmgMult, I(SkillScale.Mult) },
{ CounterRatio, I(SkillScale.Value) }, // p2 1 = 밀렸을 때만
{ CounterTakenPct, I(SkillScale.Value) },
{ PierceNoCounter, I(SkillScale.Fixed) },
{ PierceReturnOnMiss, I(SkillScale.Fixed) },
{ PierceKnockbackMult, I(SkillScale.Mult) },
{ PierceDmgPctPerHit, I(SkillScale.Value, true) }, // p2 = 최대
{ PierceRepeat, I(SkillScale.Count) },
{ PierceDmgMult, I(SkillScale.Mult) }, // p2 = 최소 관통 수(키 하나일 때)
{ ArrowCritAlways, I(SkillScale.Fixed) },
{ ArrowPassAllies, I(SkillScale.Fixed) },
{ RangeMult, I(SkillScale.Mult) },
{ RangeAdd, I(SkillScale.Value) },
{ MeleePenaltyOff, I(SkillScale.Fixed) },
{ SplashRadiusMult, I(SkillScale.Mult) },
{ SplashRatio, I(SkillScale.Value) },
{ SplashAllyRatio, I(SkillScale.Value) },
{ MatchupFloor, I(SkillScale.Fixed) },
{ DmgPct, I(SkillScale.Value) },
{ DmgPctHpBelow, I(SkillScale.Value) }, // p2 = HP 임계
{ DmgPctTurn1, I(SkillScale.Value) },
{ DmgVsGeneralMult, I(SkillScale.Mult) }, // p2 1 = 보스만 · 0 = 무장 전체
{ DmgTakenPct, I(SkillScale.Value) },
{ DmgTakenAura, I(SkillScale.Value, false, true) }, // p2 = 반경
{ DmgTakenFromArcherPct, I(SkillScale.Value) },
{ PushedAllyAttackPct, I(SkillScale.Value, false, true) },
{ PushedAllyAttackCount, I(SkillScale.Count) },
{ KnockbackTakenPct, I(SkillScale.Value) },
{ HpMaxPct, I(SkillScale.Value) },
{ HealOnOverwatchKill, I(SkillScale.Value) },
{ HpCostAtk, I(SkillScale.Value) }, // p2 = HP 소모(커지지 않음)
{ AoePushFear, I(SkillScale.Value) }, // p2 = 반경
{ EnemyAggroAdd, I(SkillScale.Value) },
{ EnemyAggroOffTurn, I(SkillScale.Fixed) },
{ TeamDmgTakenPctTurn, I(SkillScale.Value, false, true) },
{ GuardShare, I(SkillScale.Value) }, // p2 = 반경
{ Teleport, I(SkillScale.Value) }, // p1 = 반경(0 = 슬링 목표점)
{ OnAllyDeathAtk, I(SkillScale.Value) },
{ TeamAtkPctFull, I(SkillScale.Value, false, true) }, // p2 = 출전 인원 조건
{ SpearHitTwo, I(SkillScale.Count) },
{ PushedAllyAttackOnPush, I(SkillScale.Count) },
{ TeamRangeAdd, I(SkillScale.Value, false, true) }, // 대상 = 궁병·책사
{ TeamDmgPctTurn, I(SkillScale.Value, false, true) }, // 즉시 = 이번 아군 턴 아군 전원 가하는 피해 %
{ CooldownAdd, I(SkillScale.Count) }, // p2 1 = 아군 전원 · 0 = 자기만 · 쿨 최소 1
{ Charm, I(SkillScale.Fixed) }, // p1 반경 · p2 적 턴 수 · 대상 = 무장 우선
{ HealSelfPct, I(SkillScale.Value) },
};
public static bool Known(string key)
{
return key != null && All.ContainsKey(key);
}
/// 레벨·★ 계수 factor 를 적용한 값.
public static float Apply(SkillScale mode, float p, float factor)
{
switch (mode)
{
case SkillScale.Value: return p * factor;
case SkillScale.Mult: return 1f + (p - 1f) * factor;
case SkillScale.Count: return UnityEngine.Mathf.Floor(p * factor + 0.5f);
}
return p;
}
}
}