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

229 lines
14 KiB
C#
Raw Permalink 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.

using System.Collections.Generic;
namespace TKS
{
/// <summary>스킬 수치가 레벨(lv_scale)·★5(패시브 배율)로 커지는 방식.</summary>
public enum SkillScale
{
/// <summary>값 × 계수(비율·가산 · 기획서 §5 「수치 × (1 + lv_scale·(lv−1))」).</summary>
Value,
/// <summary>배율(×k)은 1 을 넘는 몫만 키운다: 1 + (k − 1) × 계수 (×2 가 Lv5 에 ×2.8 이 되지 않게).</summary>
Mult,
/// <summary>횟수 = 반올림(값 × 계수).</summary>
Count,
/// <summary>켜고 끄는 값·턴·반경·확률(커지지 않음).</summary>
Fixed
}
/// <summary>
/// effect_key 처리기 목록(2026-11-10 #1112 · PD 엑셀 「장수 목록」 새 기획 · 표 = skill_effects.csv 효과 1줄 = 키 · 대상 · 조건 · 지속 · p1~p3).
/// 이 표는 「처리기의 뜻 + 레벨 계수가 붙는 칸」이고 수치는 전부 skill_effects.csv(SkillInfoDb)에서 온다(C45). 표에 없는 키 = 임포트 오류.
/// 보물 진영 효과(range_mult · splash_radius_mult · side_crit_pct)도 같은 질의(SkillMods)를 탄다.
/// </summary>
public static class SkillKeys
{
// ── 능력치(상시 · 대상·조건 칸)
public const string AtkPct = "atk_pct";
public const string AtkRatio = "atk_ratio";
public const string DmgPct = "dmg_pct";
public const string DmgTakenPct = "dmg_taken_pct";
public const string DmgTakenRangedPct = "dmg_taken_ranged_pct";
public const string DmgTakenFromArcherPct = "dmg_taken_from_archer_pct";
public const string CritChance = "crit_chance";
public const string CritDmgPct = "crit_dmg_pct";
public const string CritAlways = "crit_always";
public const string CounterTakenPct = "counter_taken_pct";
public const string CounterDmgPct = "counter_dmg_pct";
public const string CounterLifesteal = "counter_lifesteal";
public const string Lifesteal = "lifesteal";
public const string HpMaxPct = "hp_max_pct";
public const string SlingDistPct = "sling_dist_pct";
public const string RangeMult = "range_mult";
public const string SplashRadiusMult = "splash_radius_mult";
public const string SplashAllyRatio = "splash_ally_ratio";
public const string MeleePenaltyOff = "melee_penalty_off";
public const string MatchupFloor = "matchup_floor";
public const string KnockbackTakenPct = "knockback_taken_pct";
public const string PushMult = "push_mult";
public const string SelfBounceMult = "self_bounce_mult";
public const string KillStackAtk = "kill_stack_atk";
public const string AtkMissingHp = "atk_missing_hp";
public const string AtkPerAllyRange = "atk_per_ally_range";
public const string OnAllyDeathAtk = "on_ally_death_atk";
public const string DashDmgPct = "dash_dmg_pct";
public const string DmgPerHit = "dmg_per_hit";
public const string FirstHitBonus = "first_hit_bonus";
public const string SkillPowerLowHp = "skill_power_low_hp";
public const string SkillHpCost = "skill_hp_cost";
public const string LowHpTaken = "low_hp_taken";
public const string UnusedMoveDr = "unused_move_dr";
public const string RegenPct = "regen_pct";
public const string HealOnActionEnd = "heal_on_action_end";
public const string HealOnKill = "heal_on_kill";
public const string KillReaction = "kill_reaction";
public const string ReactionAtkStack = "reaction_atk_stack";
public const string MoveBank = "move_bank";
public const string TerrainImmune = "terrain_immune";
public const string Revive = "revive";
public const string NegateHits = "negate_hits";
public const string DrainAura = "drain_aura";
public const string Guard = "guard";
public const string GuardCounter = "guard_counter";
public const string GuardRadiusMult = "guard_radius_mult";
public const string GuardDr = "guard_dr";
public const string AxeAura = "axe_aura";
public const string ZoneSlow = "zone_slow";
public const string OnAttackedStun = "on_attacked_stun";
public const string OnAttackedConfuse = "on_attacked_confuse";
public const string MultiMaleStun = "multi_male_stun";
public const string TurnEndHeal = "turn_end_heal";
public const string TurnEndHealLowest = "turn_end_heal_lowest";
public const string TurnEndCleanse = "turn_end_cleanse";
public const string TurnStartHealRange = "turn_start_heal_range";
public const string DeathBanner = "death_banner";
public const string Hot = "hot";
public const string HealCleanse = "heal_cleanse";
public const string AllyHitHeal = "ally_hit_heal";
public const string AllyHitBuff = "ally_hit_buff";
public const string AllyHitWarp = "ally_hit_warp";
public const string AllyHitReaction = "ally_hit_reaction";
public const string ActionEndSacrifice = "action_end_sacrifice";
public const string PushContinue = "push_continue";
public const string PushedAllyAtkAdd = "pushed_ally_atk_add";
public const string SelfPushedMult = "self_pushed_mult";
public const string GimmickMult = "gimmick_mult";
public const string Zombie = "zombie";
public const string DoubleHitStun = "double_hit_stun";
public const string KillInRangeReward = "kill_in_range_reward";
public const string Invuln = "invuln";
public const string DamageToAtk = "damage_to_atk";
// ── 명중 시 상태 이상(공격자 효과 · 조건 칸 · p3 = 확률)
public const string HitStun = "hit_stun";
public const string HitBleed = "hit_bleed";
public const string HitPoison = "hit_poison";
public const string PoisonStack = "poison_stack";
public const string HitBurn = "hit_burn";
public const string HitConfuse = "hit_confuse";
public const string HitPush = "hit_push";
// ── 다음 행동(장착 중) 이동·공격 변형
public const string ExtraAction = "extra_action";
public const string ReactionOnHit = "reaction_on_hit";
public const string ReactionOnKill = "reaction_on_kill";
public const string ReactionOnTerrain = "reaction_on_terrain";
public const string PassAllies = "pass_allies";
public const string PierceThrough = "pierce_through";
public const string SwapOnHit = "swap_on_hit";
public const string DragBack = "drag_back";
public const string AimPush = "aim_push";
public const string ReturnOnHit = "return_on_hit";
public const string ReturnAlways = "return_always";
public const string ReturnAim = "return_aim";
public const string WallBounce = "wall_bounce";
public const string Rampage = "rampage";
public const string RepeatAction = "repeat_action";
// ── 원거리 특수 사격(장착 중)
public const string ArrowPassAllies = "arrow_pass_allies";
public const string ShotGiant = "shot_giant";
public const string ShotPierce = "shot_pierce";
public const string ShotBlast = "shot_blast";
public const string ShotFan = "shot_fan";
public const string Multishot = "multishot";
public const string ShotRicochet = "shot_ricochet";
public const string ShotSingle = "shot_single";
public const string ShotWhirl = "shot_whirl";
public const string ShotBarricade = "shot_barricade";
public const string ShotFirewall = "shot_firewall";
public const string ShotAsArcher = "shot_as_archer";
public const string FireZone = "fire_zone";
public const string ZoneBurn = "zone_burn";
public const string ZoneHitsAllies = "zone_hits_allies";
public const string PoisonZone = "poison_zone";
public const string SplashHeal = "splash_heal";
public const string SplashHealLowest = "splash_heal_lowest";
// ── 즉시 발동
public const string AoeStrike = "aoe_strike";
public const string AoeDrain = "aoe_drain";
public const string Volley = "volley";
public const string CharmPull = "charm_pull";
public const string HealAtk = "heal_atk";
public const string HealSelfPct = "heal_self_pct";
public const string Cleanse = "cleanse";
public const string Teleport = "teleport";
public const string GrantReaction = "grant_reaction";
public class Info
{
public SkillScale Mode;
/// <summary>레벨·★ 계수가 붙는 칸(0 = p1 · 1 = p2 · 2 = p3).</summary>
public int Idx;
/// <summary>p2 도 같은 계수(이동 % · 공격 % 두 값).</summary>
public bool Both;
}
static Info I(SkillScale m, int idx = 0, bool both = false)
{
return new Info { Mode = m, Idx = idx, Both = both };
}
static readonly Info Fix = new Info { Mode = SkillScale.Fixed };
public static readonly Dictionary<string, Info> All = new Dictionary<string, Info>
{
{ AtkPct, I(SkillScale.Value) }, { AtkRatio, I(SkillScale.Mult) }, { DmgPct, I(SkillScale.Value) },
{ DmgTakenPct, I(SkillScale.Value) }, { DmgTakenRangedPct, I(SkillScale.Value) }, { DmgTakenFromArcherPct, I(SkillScale.Value) },
{ CritChance, I(SkillScale.Value) }, { CritDmgPct, I(SkillScale.Value) }, { CritAlways, Fix },
{ CounterTakenPct, I(SkillScale.Value) }, { CounterDmgPct, I(SkillScale.Value) }, { CounterLifesteal, I(SkillScale.Value) },
{ Lifesteal, I(SkillScale.Value) }, { HpMaxPct, I(SkillScale.Value) }, { SlingDistPct, I(SkillScale.Value) },
{ RangeMult, I(SkillScale.Mult) }, { SplashRadiusMult, I(SkillScale.Mult) }, { SplashAllyRatio, Fix },
{ MeleePenaltyOff, Fix }, { MatchupFloor, Fix }, { KnockbackTakenPct, Fix }, { PushMult, I(SkillScale.Mult) },
{ SelfBounceMult, Fix }, { KillStackAtk, I(SkillScale.Value) }, { AtkMissingHp, I(SkillScale.Value) },
{ AtkPerAllyRange, I(SkillScale.Value) }, { OnAllyDeathAtk, I(SkillScale.Value) }, { DashDmgPct, I(SkillScale.Value) },
{ DmgPerHit, I(SkillScale.Value) }, { FirstHitBonus, I(SkillScale.Value) }, { SkillPowerLowHp, I(SkillScale.Value) },
{ SkillHpCost, Fix }, { LowHpTaken, Fix }, { UnusedMoveDr, I(SkillScale.Value) }, { RegenPct, I(SkillScale.Value) },
{ HealOnActionEnd, I(SkillScale.Value) }, { HealOnKill, I(SkillScale.Value) }, { KillReaction, Fix },
{ ReactionAtkStack, I(SkillScale.Value) }, { MoveBank, Fix }, { TerrainImmune, Fix }, { Revive, Fix }, { NegateHits, Fix },
{ DrainAura, I(SkillScale.Value) }, { Guard, Fix }, { GuardCounter, Fix }, { GuardRadiusMult, I(SkillScale.Mult) },
{ GuardDr, I(SkillScale.Value) }, { AxeAura, I(SkillScale.Value, 1) }, { ZoneSlow, I(SkillScale.Value) },
{ OnAttackedStun, Fix }, { OnAttackedConfuse, Fix }, { MultiMaleStun, Fix }, { TurnEndHeal, I(SkillScale.Value, 1) },
{ TurnEndHealLowest, I(SkillScale.Value, 1) }, { TurnEndCleanse, Fix }, { TurnStartHealRange, I(SkillScale.Value) },
{ DeathBanner, Fix }, { Hot, I(SkillScale.Value) }, { HealCleanse, Fix }, { AllyHitHeal, I(SkillScale.Value) },
{ AllyHitBuff, I(SkillScale.Value, 0, true) }, { AllyHitWarp, Fix }, { AllyHitReaction, Fix }, { ActionEndSacrifice, Fix },
{ PushContinue, Fix }, { PushedAllyAtkAdd, I(SkillScale.Value) }, { SelfPushedMult, I(SkillScale.Mult) },
{ GimmickMult, I(SkillScale.Mult) }, { Zombie, Fix }, { DoubleHitStun, Fix }, { KillInRangeReward, Fix },
{ Invuln, Fix }, { DamageToAtk, Fix },
{ HitStun, Fix }, { HitBleed, I(SkillScale.Value, 1) }, { HitPoison, I(SkillScale.Value, 1) }, { PoisonStack, Fix },
{ HitBurn, I(SkillScale.Value, 1) }, { HitConfuse, Fix }, { HitPush, I(SkillScale.Value) },
{ ExtraAction, Fix }, { ReactionOnHit, Fix }, { ReactionOnKill, Fix }, { ReactionOnTerrain, Fix }, { PassAllies, Fix },
{ PierceThrough, Fix }, { SwapOnHit, Fix }, { DragBack, Fix }, { AimPush, Fix }, { ReturnOnHit, Fix }, { ReturnAlways, Fix },
{ ReturnAim, Fix }, { WallBounce, Fix }, { Rampage, Fix }, { RepeatAction, Fix },
{ ArrowPassAllies, Fix }, { ShotGiant, I(SkillScale.Mult, 1) }, { ShotPierce, I(SkillScale.Mult) }, { ShotBlast, I(SkillScale.Mult, 1) },
{ ShotFan, Fix }, { Multishot, Fix }, { ShotRicochet, I(SkillScale.Value, 1) }, { ShotSingle, Fix }, { ShotWhirl, Fix },
{ ShotBarricade, Fix }, { ShotFirewall, I(SkillScale.Mult, 2) }, { ShotAsArcher, Fix }, { FireZone, Fix }, { ZoneBurn, I(SkillScale.Value, 1) }, { ZoneHitsAllies, Fix }, { PoisonZone, Fix },
{ SplashHeal, I(SkillScale.Value) }, { SplashHealLowest, I(SkillScale.Value) },
{ AoeStrike, I(SkillScale.Mult, 1) }, { AoeDrain, I(SkillScale.Mult) }, { Volley, I(SkillScale.Mult) }, { CharmPull, Fix },
{ HealAtk, I(SkillScale.Value) }, { HealSelfPct, I(SkillScale.Value) }, { Cleanse, Fix }, { Teleport, Fix }, { GrantReaction, Fix },
};
public static bool Known(string key)
{
return key != null && All.ContainsKey(key);
}
/// <summary>레벨·★ 계수 factor 를 적용한 값.</summary>
public static float Apply(SkillScale mode, float p, float factor)
{
switch (mode)
{
case SkillScale.Value: return p * factor;
case SkillScale.Mult: return p > 0f ? 1f + (p - 1f) * factor : p;
case SkillScale.Count: return UnityEngine.Mathf.Floor(p * factor + 0.5f);
}
return p;
}
}
}