스킬 PD 결정 18건 + Fable 검토 12건 반영(#1112 · 2026-11-10)

PD 결정(바뀐 6): 미기재 지속 턴 = 1(관우·손견 출혈 · 장각·가후·축융·장로 중독 · 주유 운석·불꽃 · 불꽃 닿음 화상 3턴 = zone_burn 신설) ·
손건 화친 = 피해 없이 회복만 · 장로 망령 = 다음 자기 턴 시작에 1번 공격 후 소멸(소멸 안 되던 버그 수정) · 육손 불 장벽 = 아군도(zone_hits_allies) ·
제갈근 회오리 = 공격력 100 % 피해 · 보병 목표점 명중 추가 이동 제거(BattleFlowTests 기대값 갱신)

Fable 검토(A2·B3·C7 전부 수정): 주태 검기 미발동 · 곽가 병사 재행동 오류 · 방통 지속 회복 3회 · 조인 감속 궁·책 · 사마의 광역 배율 스킬 폭발 ·
가후 중독 1명중 1회 · 장비 연속 판정(즉시형 제외) · 조범 모든 피해 무효 · 육손 아군 전액 · 서황 창병 반작용 · 맹획 지형 판정 · 부활 타격 공격자 효과

테스트(고친 부분 클래스): SkillTests 26 · BattleFlowTests 42 · GimmickTests 19 · TacticalAITests 7 · OutGameTests 15 통과 · console error 0

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
깃 관리자 2026-11-10 20:36:58 +09:00
parent 0b2f56f271
commit 296732370c
11 changed files with 357 additions and 132 deletions

View File

@ -4,7 +4,7 @@ liubei_a,counter_taken_pct,,,1,-1,,,1턴 반격 안 받음,받는 반격 피해
liubei_p,atk_pct,camp:shu,,0,0.2,,,,공격력 증가 · 대상: 촉 진영 유닛,공격력 +비율(0.2 = +20 %),,
liubei_p,revive,,,0,1.0,1,0,HP 비율·횟수(전투당)·조건 HP 비율,쓰러지면 부활,부활 HP 비율(1.0 = 100 %),전투당 횟수,맞기 전 HP 가 이 비율 이상일 때만(0 = 조건 없음)
guanyu_a,aoe_strike,,,0,3,2.5,1,반경·공격 배율·밀기,자신 주위 적 전원 공격·밀침,반경,피해 = 공격력 × 배수(0 = 피해 없음),바깥으로 밀기 거리
guanyu_a,hit_bleed,,,0,2,0.5,1,턴(기본값)·이동 비례·확률,명중한 적 출혈(움직인 거리에 비례해 생명력 감소),출혈 턴,슬링 최대 거리만큼 움직일 때 최대 HP × 비율,확률
guanyu_a,hit_bleed,,,0,1,0.5,1,턴(미기재 → 1 · PD 결정 ④)·이동 비례·확률,명중한 적 출혈(움직인 거리에 비례해 생명력 감소),출혈 턴,슬링 최대 거리만큼 움직일 때 최대 HP × 비율,확률
guanyu_p,counter_dmg_pct,camp:shu,,0,0.5,,,,주는 반격 피해 증가 · 대상: 촉 진영 유닛,반격 피해 +비율(0.5 = +50 % · 1.0 = 2배),,
guanyu_p,counter_taken_pct,,,0,-1,,,,받는 반격 피해 증감,받는 반격 비율(−1 = 반격 안 받음 · −0.5 = 반감),,
guanyu_p,kill_stack_atk,,,0,0.1,1.0,,처치당·최대,적 처치마다 공격력 누적(전투 동안),처치 1기당 공격 +비율,최대 누적 비율,
@ -18,7 +18,7 @@ zhaoyun_a,sling_dist_pct,,,0,1.0,,,,이동(슬링) 거리 증가,이동 거리 +
zhaoyun_a,dmg_pct,,,0,0.5,,,,주는 피해 증가,피해 +비율(0.5 = +50 %),,
zhaoyun_p,counter_taken_pct,,,0,-1,,,,받는 반격 피해 증감,받는 반격 비율(−1 = 반격 안 받음 · −0.5 = 반감),,
zhaoyun_p,return_on_hit,,,0,1,0,,복귀 중 피해·쓸어 감,피해를 입히면 출발 위치로 복귀,1 = 복귀하며 경로 위 적에게도 피해,1 = 복귀 경로의 유닛을 함께 쓸어 감,
huangzhong_a,shot_giant,,,0,0.5,5.0,,화살 반지름(기본값)·공격 배율 · 사거리 무관,사거리 무관 거대 화살 — 첫 적에게 큰 피해,화살 반지름,피해 = 공격력 × 배수,
huangzhong_a,shot_giant,,,0,0.5,5.0,,화살 반지름(PD 확정)·공격 배율 · 사거리 무관,사거리 무관 거대 화살 — 첫 적에게 큰 피해,화살 반지름,피해 = 공격력 × 배수,
huangzhong_a,hit_stun,,,0,1,,,,명중한 적 기절(다음 자기 턴 행동 불가),기절 턴,,
huangzhong_p,arrow_pass_allies,,,0,1,1,,p2 1 = 장애물도 통과,화살이 아군을 통과,1 = 켬,1 = 장애물도 통과,
huangzhong_p,crit_chance,,,0,0.2,,,,치명타 확률 증가,확률 +(0.2 = +20 %p),,
@ -35,7 +35,7 @@ guanping_a,guard_radius_mult,,,2,2,,,,호위·반격 반경 배율 · 2턴 지
guanping_a,guard_dr,,,2,-0.5,,,,호위로 대신 받는 피해 감소 · 2턴 지속,받는 비율(−0.5 = 반감),,
guanping_p,counter_dmg_pct,,,0,0.5,,,,주는 반격 피해 증가,반격 피해 +비율(0.5 = +50 % · 1.0 = 2배),,
guanping_p,guard,,,0,2,1.0,,반경·대신 받는 비율,호위 — 반경 안 아군 피해를 대신 받음,호위 반경,대신 받는 비율(1.0 = 전부),
xushu_a,shot_blast,,,0,1.5,2.5,,폭발 반경(기본값 = 책사 광역)·공격 배율,투사체가 첫 적 자리에서 폭발 — 반경 안 적 전원 피해,폭발 반경,피해 = 공격력 × 배수,
xushu_a,shot_blast,,,0,1.5,2.5,,폭발 반경(PD 확정 · 책사 광역과 같게)·공격 배율,투사체가 첫 적 자리에서 폭발 — 반경 안 적 전원 피해,폭발 반경,피해 = 공격력 × 배수,
xushu_a,hit_burn,,,0,3,0.05,1,,명중한 적 화상(불태우기 · 턴 시작마다 생명력 감소),화상 턴,1회 최대 HP × 비율,확률
xushu_p,range_mult,,,0,1.5,,,,공격 사거리 배율,사거리 ×배율(1.5 = +50 %),,
xushu_p,splash_ally_ratio,,,0,0,,,,자신의 광역이 아군에게 주는 피해 비율,아군 피해 비율(0 = 아군 피해 없음),,
@ -58,7 +58,7 @@ pangtong_p,turn_end_cleanse,,,0,3,1,,반경·인원,턴 종료 시 주위 아군
jiangwei_a,heal_self_pct,,,0,0.5,,,,자신 생명력 회복,최대 HP × 비율,,
jiangwei_a,guard_radius_mult,,,3,1.5,,,,호위·반격 반경 배율 · 3턴 지속,반경 ×배율,,
jiangwei_p,counter_dmg_pct,,,0,0.5,,,,주는 반격 피해 증가,반격 피해 +비율(0.5 = +50 % · 1.0 = 2배),,
jiangwei_p,guard_counter,,,0,2,1.0,,반격 범위(기본값 = 관평 호위 2)·대신 받는 비율,호위 반격 — 반경 안 아군 피해를 대신 받고 공격자에게 반격,반격(호위) 반경,대신 받는 비율,
jiangwei_p,guard_counter,,,0,2,1.0,,반격 범위(PD 확정 · 관평 호위 2)·대신 받는 비율,호위 반격 — 반경 안 아군 피해를 대신 받고 공격자에게 반격,반격(호위) 반경,대신 받는 비율,
liufeng_a,atk_ratio,,,0,1.85,,,,이 공격의 피해 = 공격력의 배수,공격력 배수(1.8 = 180 %),,
liufeng_a,hit_confuse,,,0,1,0.5,1,턴·이동 배율·확률,명중한 적 혼란(이동 거리 감소),혼란 턴,이동 거리 배율(0.5 = 반감),확률
liufeng_p,counter_taken_pct,,vs_confused,0,-1,,,,받는 반격 피해 증감 · 조건: 상대가 혼란일 때,받는 반격 비율(−1 = 반격 안 받음 · −0.5 = 반감),,
@ -67,7 +67,7 @@ jianyong_a,ally_hit_heal,,,0,0.8,,,,자신의 공격이 아군에 맞으면 피
jianyong_a,hit_stun,,,0,1,,,,명중한 적 기절(다음 자기 턴 행동 불가),기절 턴,,
jianyong_p,heal_cleanse,,,0,1,,,,자신이 회복시킨 대상의 상태 이상 제거,1 = 켬,,
jianyong_p,on_attacked_stun,,,0,1,3,,기절 턴·재충전 턴,자신을 공격한 대상 기절(재충전),기절 턴,재충전 턴,
sunqian_a,splash_heal,,,0,0.6,,,명중 대상 주위 광역 = 회복(적 포함),책사 광역이 피해 대신 회복(적 포함),회복 = 공격력 × 배수,,
sunqian_a,splash_heal,,,0,0.6,,,명중 대상 포함 범위 안 전원 회복(적 포함) · 피해 없음(PD 결정 ⑧),책사 사격이 피해 없이 명중 대상 포함 범위 안 전원 회복(적 포함),회복 = 공격력 × 배수,,
sunqian_p,sling_dist_pct,radius:3,,0,0.3,,,,이동(슬링) 거리 증가 · 대상: 자신 주위 3 안 아군,이동 거리 +비율(1.0 = 2배),,
mizhu_a,sling_dist_pct,range,,1,0.5,,,,이동(슬링) 거리 증가 · 대상: 시전 순간 행동 반경 안 아군 · 1턴 지속,이동 거리 +비율(1.0 = 2배),,
mizhu_a,counter_taken_pct,range,,1,-0.5,,,,받는 반격 피해 증감 · 대상: 시전 순간 행동 반경 안 아군 · 1턴 지속,받는 반격 비율(−1 = 반격 안 받음 · −0.5 = 반감),,
@ -91,7 +91,7 @@ zhangliao_a,drag_back,,,0,1,,,명중 적을 출발 위치로 끌고 옴,관통
zhangliao_a,hit_confuse,,,0,1,0.5,1,,명중한 적 혼란(이동 거리 감소),혼란 턴,이동 거리 배율(0.5 = 반감),확률
zhangliao_p,atk_pct,,vs_status,0,0.5,,,,공격력 증가 · 조건: 상대가 상태 이상일 때,공격력 +비율(0.2 = +20 %),,
zhangliao_p,counter_taken_pct,,vs_status,0,-1,,,,받는 반격 피해 증감 · 조건: 상대가 상태 이상일 때,받는 반격 비율(−1 = 반격 안 받음 · −0.5 = 반감),,
xuhuang_a,axe_aura,,,3,1.2,0.8,2,도끼 반경(기본값)·공격 배율·튕김 배율,주위를 도는 도끼 — 자신을 친 근접 유닛에게 반격 피해 + 그 유닛이 더 멀리 튕김 · 3턴 지속,도끼 반경,반격 피해 = 공격력 × 배수,공격자 튕김 거리 배율
xuhuang_a,axe_aura,,,3,1.2,0.8,2,도끼 반경(PD 확정)·공격 배율·튕김 배율,주위를 도는 도끼 — 자신을 친 근접 유닛에게 반격 피해 + 그 유닛이 더 멀리 튕김 · 3턴 지속,도끼 반경,반격 피해 = 공격력 × 배수,공격자 튕김 거리 배율
xuhuang_p,hit_bleed,,,0,3,0.5,0.3,,명중한 적 출혈(움직인 거리에 비례해 생명력 감소),출혈 턴,슬링 최대 거리만큼 움직일 때 최대 HP × 비율,확률
xuhuang_p,hit_bleed,,crit,0,3,0.5,1,,명중한 적 출혈(움직인 거리에 비례해 생명력 감소) · 조건: 치명타일 때,출혈 턴,슬링 최대 거리만큼 움직일 때 최대 HP × 비율,확률
zhanghe_a,teleport,,,0,5,,,,반경 안 원하는 곳으로 이동(대상 무시 · 지점 탭),이동 반경,,
@ -110,14 +110,14 @@ simayi_a,aoe_drain,,,0,1.5,0.6,,공격 배율·피해 → 아군 회복 비율,
simayi_p,splash_radius_mult,camp:wei:strategist,,0,1.5,,,,책사 광역 범위 배율 · 대상: 위 진영 책사 유닛,광역 반경 ×배율,,
simayi_p,range_mult,,,0,1.5,,,,공격 사거리 배율,사거리 ×배율(1.5 = +50 %),,
simayi_p,drain_aura,,,0,0.3,,,,행동 반경 안 적이 입은 피해만큼 자신 회복,그 피해 × 비율 회복,,
xiahouyuan_a,shot_fan,,,0,5,3,60,발 수·연속 횟수·부채꼴 각(기본값),부채꼴 연속 사격,한 번에 쏘는 화살 수,연속 횟수,부채꼴 전체 각도(도)
xiahouyuan_p,multishot,,,0,3,30,,발 수·부채꼴 각(기본값),일반 사격이 부채꼴 여러 발(멀티샷),화살 수,부채꼴 전체 각도(도),
xiahouyuan_a,shot_fan,,,0,5,3,60,발 수·연속 횟수·부채꼴 각(PD 확정),부채꼴 연속 사격,한 번에 쏘는 화살 수,연속 횟수,부채꼴 전체 각도(도)
xiahouyuan_p,multishot,,,0,3,30,,발 수·부채꼴 각(PD 확정),일반 사격이 부채꼴 여러 발(멀티샷),화살 수,부채꼴 전체 각도(도),
guojia_a,dmg_pct,range,,2,0.3,,,,주는 피해 증가 · 대상: 시전 순간 행동 반경 안 아군 · 2턴 지속,피해 +비율(0.5 = +50 %),,
guojia_a,grant_reaction,,,0,1,,,,이미 행동한 다른 아군에게 재행동 부여(없으면 다른 아군이 행동 뒤 재행동),인원,,
guojia_p,kill_in_range_reward,,,0,1,0.3,,쿨 −턴·최대 HP 회복,자신의 행동 반경 안에서 적을 처치한 아군 보상,액티브 쿨 −턴,최대 HP × 비율 회복,
jiaxu_a,shot_blast,,,0,1.5,2.2,,독구름 반경(기본값)·공격 배율,투사체가 첫 적 자리에서 폭발 — 반경 안 적 전원 피해,폭발 반경,피해 = 공격력 × 배수,
jiaxu_a,shot_blast,,,0,1.5,2.2,,독구름 반경(PD 확정)·공격 배율,투사체가 첫 적 자리에서 폭발 — 반경 안 적 전원 피해,폭발 반경,피해 = 공격력 × 배수,
jiaxu_a,hit_poison,,,0,5,0.02,1,,명중한 적 중독(턴 시작·행동 끝마다 생명력 감소),중독 턴,1회 최대 HP × 비율(중첩 수만큼 곱),확률
jiaxu_p,hit_poison,,,0,5,0.02,1,턴(기본값 = 독계),명중한 적 중독(턴 시작·행동 끝마다 생명력 감소),중독 턴,1회 최대 HP × 비율(중첩 수만큼 곱),확률
jiaxu_p,hit_poison,,,0,1,0.02,1,턴(미기재 → 1 · PD 결정 ④),명중한 적 중독(턴 시작·행동 끝마다 생명력 감소),중독 턴,1회 최대 HP × 비율(중첩 수만큼 곱),확률
jiaxu_p,poison_stack,,,0,5,,,,중독 중첩 허용,최대 중첩,,
dianwei_a,dmg_pct,,,0,1.0,,,,주는 피해 증가,피해 +비율(0.5 = +50 %),,
dianwei_a,push_mult,,,0,2,,,,밀치는 거리 배율,밀기 ×배율(2 = 2배),,
@ -137,13 +137,14 @@ xiahouen_a,first_hit_bonus,,,0,0.5,,,,이 행동에서 처음 맞힌 대상에
xiahouen_p,hp_max_pct,,,0,0.1,,,,최대 생명력 증가,최대 HP +비율,,
sunjian_a,atk_pct,,,0,0.5,,,,공격력 증가,공격력 +비율(0.2 = +20 %),,
sunjian_a,pierce_through,,,0,1,,,1 = 아군도 통과,보병·창병도 기병처럼 적을 관통하며 경로 위 적 전원 피해,1 = 아군도 통과 · 0 = 아군 앞 정지,,
sunjian_a,hit_bleed,,,0,2,0.5,1,,명중한 적 출혈(움직인 거리에 비례해 생명력 감소),출혈 턴,슬링 최대 거리만큼 움직일 때 최대 HP × 비율,확률
sunjian_a,hit_bleed,,,0,1,0.5,1,턴(미기재 → 1 · PD 결정 ④),명중한 적 출혈(움직인 거리에 비례해 생명력 감소),출혈 턴,슬링 최대 거리만큼 움직일 때 최대 HP × 비율,확률
sunjian_a,invuln,,,1,1,,,행동 끝 뒤 1턴 피해 무효,무적 — 모든 피해 무효(행동 중이 아닌 동안) · 1턴 지속,1 = 켬,,
sunjian_p,atk_pct,camp:wu,,0,0.2,,,,공격력 증가 · 대상: 오 진영 유닛,공격력 +비율(0.2 = +20 %),,
sunjian_p,kill_reaction,,,0,1,,,턴당,적 처치 시 재행동(턴당 1회),1 = 켬,,
zhouyu_a,shot_blast,,,0,2.5,3.5,,운석 반경(기본값)·공격 배율,투사체가 첫 적 자리에서 폭발 — 반경 안 적 전원 피해,폭발 반경,피해 = 공격력 × 배수,
zhouyu_a,hit_burn,,,0,3,0.05,1,,명중한 적 화상(불태우기 · 턴 시작마다 생명력 감소),화상 턴,1회 최대 HP × 비율,확률
zhouyu_a,fire_zone,,,0,1.5,3,1.0,불꽃 반경·턴·닿을 때 공격 배율,폭발 자리에 불꽃 지대 — 닿는 적 피해 + 화상,지대 반경,유지 턴,닿을 때 피해 = 공격력 × 배수
zhouyu_a,shot_blast,,,0,2.5,3.5,,운석 반경(PD 확정)·공격 배율,투사체가 첫 적 자리에서 폭발 — 반경 안 적 전원 피해,폭발 반경,피해 = 공격력 × 배수,
zhouyu_a,hit_burn,,,0,1,0.05,1,운석 불태우기 턴(미기재 → 1 · PD 결정 ④),명중한 적 화상(불태우기 · 턴 시작마다 생명력 감소),화상 턴,1회 최대 HP × 비율,확률
zhouyu_a,fire_zone,,,0,1.5,1,1.0,불꽃 반경(PD 확정)·불꽃 유지 턴(미기재 → 1)·닿을 때 공격 배율,폭발 자리에 불꽃 지대 — 닿는 적 피해 + 화상,지대 반경,유지 턴,닿을 때 피해 = 공격력 × 배수
zhouyu_a,zone_burn,,,0,3,0.05,,불꽃에 닿으면 3턴 화상(원문),지대(불꽃)에 닿으면 거는 화상(없으면 그 스킬 hit_burn),화상 턴,1회 최대 HP × 비율,
zhouyu_p,skill_hp_cost,,,0,0.05,,,,액티브 스킬 시전 시 생명력 소모,최대 HP × 비율 소모(쓰러지지는 않음),,
zhouyu_p,skill_power_low_hp,,,0,0.1,0.1,,HP p2 잃을 때마다 스킬 위력 +p1,생명력이 낮을수록 스킬 위력 증가,단계당 스킬 위력 +비율,단계 = 잃은 HP 비율(0.1 = 10 %마다),
zhouyu_p,melee_penalty_off,,,0,1,,,,궁병·책사 근접 전투 패널티 없음,1 = 켬,,
@ -167,8 +168,8 @@ sunce_a,wall_bounce,,,0,1,,,,전장 가장자리에 닿으면 핀볼처럼 튕
sunce_p,sling_dist_pct,camp:wu,,0,0.3,,,,이동(슬링) 거리 증가 · 대상: 오 진영 유닛,이동 거리 +비율(1.0 = 2배),,
sunce_p,counter_taken_pct,,,0,-1,,,,받는 반격 피해 증감,받는 반격 비율(−1 = 반격 안 받음 · −0.5 = 반감),,
sunce_p,return_on_hit,,,0,0,0,,,피해를 입히면 출발 위치로 복귀,1 = 복귀하며 경로 위 적에게도 피해,1 = 복귀 경로의 유닛을 함께 쓸어 감,
sunce_p,dash_dmg_pct,,,0,1.0,,,최대(기본값 = 장비·여포),돌진(슬링) 거리에 비례해 공격력 증가,슬링 최대 거리로 당겼을 때 공격 +비율(최대),,
sunquan_a,shot_blast,,,0,1.5,1.8,,화살비 반경(기본값)·공격 배율,투사체가 첫 적 자리에서 폭발 — 반경 안 적 전원 피해,폭발 반경,피해 = 공격력 × 배수,
sunce_p,dash_dmg_pct,,,0,1.0,,,최대(PD 확정 · 장비·여포),돌진(슬링) 거리에 비례해 공격력 증가,슬링 최대 거리로 당겼을 때 공격 +비율(최대),,
sunquan_a,shot_blast,,,0,1.5,1.8,,화살비 반경(PD 확정)·공격 배율,투사체가 첫 적 자리에서 폭발 — 반경 안 적 전원 피해,폭발 반경,피해 = 공격력 × 배수,
sunquan_a,hit_confuse,,,0,1,0.5,1,,명중한 적 혼란(이동 거리 감소),혼란 턴,이동 거리 배율(0.5 = 반감),확률
sunquan_p,range_mult,camp:wu:archer,,0,1.5,,,,공격 사거리 배율 · 대상: 오 진영 궁병 유닛,사거리 ×배율(1.5 = +50 %),,
sunquan_p,arrow_pass_allies,,,0,1,0,,,화살이 아군을 통과,1 = 켬,1 = 장애물도 통과,
@ -181,11 +182,12 @@ lvmeng_a,reaction_on_hit,,,0,1,3,,재행동·최대,이 행동으로 적에게
lvmeng_a,reaction_on_kill,,,0,1,3,,,이 행동으로 적을 처치하면 재행동(연쇄),처치 시 재행동 수,연쇄 최대 재행동,
lvmeng_p,counter_taken_pct,,,0,-0.3,,,,받는 반격 피해 증감,받는 반격 비율(−1 = 반격 안 받음 · −0.5 = 반감),,
lvmeng_p,reaction_atk_stack,,,0,0.2,,,,이번 턴 재행동할 때마다 공격력 증가(2배씩 · 턴마다 초기화),첫 재행동 공격 +비율(다음은 2배 · 4배),,
luxun_a,shot_firewall,,,0,0.6,3,3.0,장벽 반폭(기본값)·턴·닿을 때 공격 배율,진행 방향 불 장벽(지대) — 닿는 적 피해 + 화상,장벽 반폭,유지 턴,닿을 때 피해 = 공격력 × 배수
luxun_a,shot_firewall,,,0,0.6,3,3.0,장벽 반폭(PD 확정)·턴·닿을 때 공격 배율,진행 방향 불 장벽(지대) — 닿는 적 피해 + 화상,장벽 반폭,유지 턴,닿을 때 피해 = 공격력 × 배수
luxun_a,hit_burn,,,0,3,0.05,1,,명중한 적 화상(불태우기 · 턴 시작마다 생명력 감소),화상 턴,1회 최대 HP × 비율,확률
luxun_a,zone_hits_allies,,,0,1,,,아군도 피해(PD 결정 ⑬),지대·장벽이 아군에게도 피해·화상,1 = 켬,,
luxun_p,dmg_pct,camp:wu,vs_status,0,0.5,,,,주는 피해 증가 · 대상: 오 진영 유닛 · 조건: 상대가 상태 이상일 때,피해 +비율(0.5 = +50 %),,
luxun_p,hit_confuse,,,0,1,0.5,1,,명중한 적 혼란(이동 거리 감소),혼란 턴,이동 거리 배율(0.5 = 반감),확률
sunshangxiang_a,volley,,,0,1.0,1.0,,공격 배율(기본값)·밀기(기본값),사거리 안 적 전원에게 화살 — 피해·밀침(치명타 판정),피해 = 공격력 × 배수,밀기 거리,
sunshangxiang_a,volley,,,0,1.0,1.0,,공격 배율(PD 확정)·밀기(PD 확정),사거리 안 적 전원에게 화살 — 피해·밀침(치명타 판정),피해 = 공격력 × 배수,밀기 거리,
sunshangxiang_a,hit_bleed,,crit,0,2,0.5,1,,명중한 적 출혈(움직인 거리에 비례해 생명력 감소) · 조건: 치명타일 때,출혈 턴,슬링 최대 거리만큼 움직일 때 최대 HP × 비율,확률
sunshangxiang_p,dmg_pct,,vs_male_hero,0,0.5,,,,주는 피해 증가 · 조건: 상대가 남성 영웅일 때,피해 +비율(0.5 = +50 %),,
sunshangxiang_p,melee_penalty_off,,,0,1,,,,궁병·책사 근접 전투 패널티 없음,1 = 켬,,
@ -196,10 +198,10 @@ xiaoqiao_p,ally_hit_heal,,,0,0.5,,,,자신의 공격이 아군에 맞으면 피
lingtong_a,aoe_strike,,,0,3,1.5,1,,자신 주위 적 전원 공격·밀침,반경,피해 = 공격력 × 배수(0 = 피해 없음),바깥으로 밀기 거리
lingtong_p,atk_pct,,,0,0.15,,,,공격력 증가,공격력 +비율(0.2 = +20 %),,
lingtong_p,push_mult,,,0,1.3,,,,밀치는 거리 배율,밀기 ×배율(2 = 2배),,
zhoutai_a,shot_pierce,,,0,1.8,1,1.0,검기 · 아군도 피해 · 밀기(기본값),직선 관통 사격 — 경로 위 유닛 전원(장애물 무시),피해 = 공격력 × 배수,아군 처리(0 통과 · 1 피해 · 2 회복),밀기 거리(0 = 없음)
zhoutai_a,shot_pierce,,,0,1.8,1,1.0,검기 · 아군도 피해 · 밀기(PD 확정),직선 관통 사격 — 경로 위 유닛 전원(장애물 무시),피해 = 공격력 × 배수,아군 처리(0 통과 · 1 피해 · 2 회복),밀기 거리(0 = 없음)
zhoutai_p,hit_confuse,,crit,0,1,0.5,1,,명중한 적 혼란(이동 거리 감소) · 조건: 치명타일 때,혼란 턴,이동 거리 배율(0.5 = 반감),확률
zhoutai_p,crit_always,,vs_type:spear,0,1,,,,무조건 치명타 · 조건: 상대가 창병일 때,1 = 켬,,
zhugejin_a,shot_whirl,,,0,1.0,3.0,0,회오리 반폭(기본값)·밀기(기본값)·공격 배율(피해 없음),회오리 — 직선 위 적을 진행 방향으로 크게 밀침,회오리 반폭,밀기 거리,피해 = 공격력 × 배수(0 = 없음)
zhugejin_a,shot_whirl,,,0,1.0,3.0,1.0,회오리 반폭·밀기(PD 확정)·공격 배율(PD 결정 ⑭ = 100 %),회오리 — 직선 위 적을 진행 방향으로 크게 밀침,회오리 반폭,밀기 거리,피해 = 공격력 × 배수(0 = 없음)
zhugejin_a,hit_confuse,,,0,1,0.5,1,,명중한 적 혼란(이동 거리 감소),혼란 턴,이동 거리 배율(0.5 = 반감),확률
zhugejin_p,splash_ally_ratio,,,0,0,,,,자신의 광역이 아군에게 주는 피해 비율,아군 피해 비율(0 = 아군 피해 없음),,
dongxi_a,atk_ratio,,,0,1.5,,,,이 공격의 피해 = 공격력의 배수,공격력 배수(1.8 = 180 %),,
@ -214,7 +216,7 @@ lvbu_p,matchup_floor,,,0,1.0,,,,상성 무시(불리한 상성만 무시 · 유
lvbu_p,dash_dmg_pct,,,0,1.0,,,,돌진(슬링) 거리에 비례해 공격력 증가,슬링 최대 거리로 당겼을 때 공격 +비율(최대),,
zhangjiao_a,invuln,,,1,1,,,,무적 — 모든 피해 무효(행동 중이 아닌 동안) · 1턴 지속,1 = 켬,,
zhangjiao_p,dmg_taken_from_archer_pct,,,0,-0.3,,,,적 궁병에게 받는 피해 증감,받는 피해 비율(−0.3 = 30 % 감소),,
zhangjiao_p,hit_poison,,,0,5,0.02,0.5,턴(기본값)·확률,명중한 적 중독(턴 시작·행동 끝마다 생명력 감소),중독 턴,1회 최대 HP × 비율(중첩 수만큼 곱),확률
zhangjiao_p,hit_poison,,,0,1,0.02,0.5,턴(미기재 → 1 · PD 결정 ④)·확률,명중한 적 중독(턴 시작·행동 끝마다 생명력 감소),중독 턴,1회 최대 HP × 비율(중첩 수만큼 곱),확률
huaxiong_a,dmg_pct,,,0,1.0,,,,주는 피해 증가,피해 +비율(0.5 = +50 %),,
huaxiong_a,counter_taken_pct,,,0,-1,,,,받는 반격 피해 증감,받는 반격 비율(−1 = 반격 안 받음 · −0.5 = 반감),,
huaxiong_p,atk_pct,,turn_le:3,0,0.5,,,,공격력 증가 · 조건: 전투 3턴까지,공격력 +비율(0.2 = +20 %),,
@ -231,11 +233,11 @@ gongsunzan_a,lifesteal,,,0,0.5,,,,입힌 피해만큼 회복(흡혈),입힌 피
gongsunzan_a,return_always,,,0,0,,,,공격 후 항상 출발 위치로 복귀,1 = 복귀하며 경로 위 적에게도 피해,,
gongsunzan_p,dmg_pct,,vs_type:archer,0,1.0,,,,주는 피해 증가 · 조건: 상대가 궁병일 때,피해 +비율(0.5 = +50 %),,
gongsunzan_p,heal_on_kill,,,0,0.3,,,,적 처치 시 생명력 회복,최대 HP × 비율 회복,,
dongzhuo_a,rampage,,,0,3,1.5,,돌진 초·밀치기 거리(기본값),일정 시간 직진 난동 — 닿는 유닛 전원 밀침(적 = 피해) · 가장자리 튕김 · 자신은 튕기지 않음,돌진 시간(초 · 이동 속도 × 초 = 거리),옆으로 밀치는 거리,
dongzhuo_a,rampage,,,0,3,1.5,,돌진 초·밀치기 거리(PD 확정),일정 시간 직진 난동 — 닿는 유닛 전원 밀침(적 = 피해) · 가장자리 튕김 · 자신은 튕기지 않음,돌진 시간(초 · 이동 속도 × 초 = 거리),옆으로 밀치는 거리,
dongzhuo_p,dmg_taken_pct,camp:other,,0,-0.1,,,,받는 피해 증감 · 대상: 군웅 진영 유닛,받는 피해 비율(−0.3 = 30 % 감소 · +0.15 = 15 % 증가),,
dongzhuo_p,lifesteal,,,0,0.3,0.05,,p2 = 아군 1기 줄 때마다 +,입힌 피해만큼 회복(흡혈),입힌 피해 × 비율 회복,아군 1기 줄 때마다 비율 +,
lijue_a,splash_heal_lowest,,,0,0.5,2,,광역 피해 비율·인접 반경(기본값),광역으로 준 피해만큼 인접한 가장 약한 아군 회복,광역 피해 × 비율 회복,인접 반경,
lijue_p,action_end_sacrifice,,,0,0.1,0.5,2,HP 소모·공격 %·인접 반경(기본값),행동 끝 = 생명력 소모 후 인접 아군 공격력 강화(대상 없으면 발동 안 함),HP 소모 비율(HP 10 % 이하면 소모 없이),인접 아군 공격 +비율(1턴),인접 반경
lijue_a,splash_heal_lowest,,,0,0.5,2,,광역 피해 비율·인접 반경(PD 확정),광역으로 준 피해만큼 인접한 가장 약한 아군 회복,광역 피해 × 비율 회복,인접 반경,
lijue_p,action_end_sacrifice,,,0,0.1,0.5,2,HP 소모·공격 %·인접 반경(PD 확정),행동 끝 = 생명력 소모 후 인접 아군 공격력 강화(대상 없으면 발동 안 함),HP 소모 비율(HP 10 % 이하면 소모 없이),인접 아군 공격 +비율(1턴),인접 반경
yuanshao_a,sling_dist_pct,range,,1,0.5,,,,이동(슬링) 거리 증가 · 대상: 시전 순간 행동 반경 안 아군 · 1턴 지속,이동 거리 +비율(1.0 = 2배),,
yuanshao_a,crit_dmg_pct,range,,1,0.5,,,,치명타 피해량 증가 · 대상: 시전 순간 행동 반경 안 아군 · 1턴 지속,치명타 피해 +비율(0.5 = +50 %),,
yuanshao_a,crit_chance,range,,1,0.2,,,,치명타 확률 증가 · 대상: 시전 순간 행동 반경 안 아군 · 1턴 지속,확률 +(0.2 = +20 %p),,
@ -253,7 +255,7 @@ diaochan_p,multi_male_stun,,,0,2,0.5,1,남성 수·확률·턴,한 행동으로
diaochan_p,dmg_taken_pct,,vs_male,0,-0.3,,,,받는 피해 증감 · 조건: 상대가 남성일 때,받는 피해 비율(−0.3 = 30 % 감소 · +0.15 = 15 % 증가),,
zhurong_a,shot_as_archer,,,0,1,,,,근접 병종이 궁병처럼 원거리 사격,1 = 켬,,
zhurong_a,atk_ratio,,,0,2.2,,,,이 공격의 피해 = 공격력의 배수,공격력 배수(1.8 = 180 %),,
zhurong_a,hit_poison,,,0,5,0.02,1,,명중한 적 중독(턴 시작·행동 끝마다 생명력 감소),중독 턴,1회 최대 HP × 비율(중첩 수만큼 곱),확률
zhurong_a,hit_poison,,,0,1,0.02,1,턴(미기재 → 1 · PD 결정 ④),명중한 적 중독(턴 시작·행동 끝마다 생명력 감소),중독 턴,1회 최대 HP × 비율(중첩 수만큼 곱),확률
zhurong_p,lifesteal,,,0,0.2,,,,입힌 피해만큼 회복(흡혈),입힌 피해 × 비율 회복,,
zhurong_p,counter_dmg_pct,,,0,0.5,,,,주는 반격 피해 증가,반격 피해 +비율(0.5 = +50 % · 1.0 = 2배),,
zhurong_p,terrain_immune,,,0,1,,,,지형(늪·고지) 이동 감소 무시,1 = 켬,,
@ -267,8 +269,8 @@ gaoshun_a,hit_stun,,,0,1,1,1,p2 1 = 밀린 아군·지형 피해도,명중한
gaoshun_p,push_continue,,,0,1,,,,아군·지형 오브젝트를 밀친 뒤 남은 이동 거리로 재행동,1 = 켬,,
zhanglu_a,shot_single,,,0,1,,,,책사 사격이 광역 없는 직선 투사체,1 = 켬,,
zhanglu_a,atk_ratio,,,0,2.5,,,,이 공격의 피해 = 공격력의 배수,공격력 배수(1.8 = 180 %),,
zhanglu_a,hit_poison,,,0,5,0.02,1,,명중한 적 중독(턴 시작·행동 끝마다 생명력 감소),중독 턴,1회 최대 HP × 비율(중첩 수만큼 곱),확률
zhanglu_a,poison_zone,,,0,1.0,1,,반경(기본값)·턴,명중 자리에 독 지대 — 닿는 적 중독,지대 반경,유지 턴,
zhanglu_a,hit_poison,,,0,1,0.02,1,턴(미기재 → 1 · PD 결정 ④),명중한 적 중독(턴 시작·행동 끝마다 생명력 감소),중독 턴,1회 최대 HP × 비율(중첩 수만큼 곱),확률
zhanglu_a,poison_zone,,,0,1.0,1,,반경(PD 확정)·턴,명중 자리에 독 지대 — 닿는 적 중독,지대 반경,유지 턴,
zhanglu_p,zombie,,,0,1,,,되살린 HP,처치한 적이 같은 편 망령으로 되살아나 1번 공격(조작 불가 · 다음 턴 소멸),망령 HP,,
yanbaihu_a,atk_pct,,,0,0.3,,,,공격력 증가,공격력 +비율(0.2 = +20 %),,
yanbaihu_a,crit_chance,,,0,0.15,,,,치명타 확률 증가,확률 +(0.2 = +20 %p),,

1 skill_id key target cond dur p1 p2 p3 note effect_ko p1_ko p2_ko p3_ko
4 liubei_p atk_pct camp:shu 0 0.2 공격력 증가 · 대상: 촉 진영 유닛 공격력 +비율(0.2 = +20 %)
5 liubei_p revive 0 1.0 1 0 HP 비율·횟수(전투당)·조건 HP 비율 쓰러지면 부활 부활 HP 비율(1.0 = 100 %) 전투당 횟수 맞기 전 HP 가 이 비율 이상일 때만(0 = 조건 없음)
6 guanyu_a aoe_strike 0 3 2.5 1 반경·공격 배율·밀기 자신 주위 적 전원 공격·밀침 반경 피해 = 공격력 × 배수(0 = 피해 없음) 바깥으로 밀기 거리
7 guanyu_a hit_bleed 0 2 1 0.5 1 턴(기본값)·이동 비례·확률 턴(미기재 → 1 · PD 결정 ④)·이동 비례·확률 명중한 적 출혈(움직인 거리에 비례해 생명력 감소) 출혈 턴 슬링 최대 거리만큼 움직일 때 최대 HP × 비율 확률
8 guanyu_p counter_dmg_pct camp:shu 0 0.5 주는 반격 피해 증가 · 대상: 촉 진영 유닛 반격 피해 +비율(0.5 = +50 % · 1.0 = 2배)
9 guanyu_p counter_taken_pct 0 -1 받는 반격 피해 증감 받는 반격 비율(−1 = 반격 안 받음 · −0.5 = 반감)
10 guanyu_p kill_stack_atk 0 0.1 1.0 처치당·최대 적 처치마다 공격력 누적(전투 동안) 처치 1기당 공격 +비율 최대 누적 비율
18 zhaoyun_a dmg_pct 0 0.5 주는 피해 증가 피해 +비율(0.5 = +50 %)
19 zhaoyun_p counter_taken_pct 0 -1 받는 반격 피해 증감 받는 반격 비율(−1 = 반격 안 받음 · −0.5 = 반감)
20 zhaoyun_p return_on_hit 0 1 0 복귀 중 피해·쓸어 감 피해를 입히면 출발 위치로 복귀 1 = 복귀하며 경로 위 적에게도 피해 1 = 복귀 경로의 유닛을 함께 쓸어 감
21 huangzhong_a shot_giant 0 0.5 5.0 화살 반지름(기본값)·공격 배율 · 사거리 무관 화살 반지름(PD 확정)·공격 배율 · 사거리 무관 사거리 무관 거대 화살 — 첫 적에게 큰 피해 화살 반지름 피해 = 공격력 × 배수
22 huangzhong_a hit_stun 0 1 명중한 적 기절(다음 자기 턴 행동 불가) 기절 턴
23 huangzhong_p arrow_pass_allies 0 1 1 p2 1 = 장애물도 통과 화살이 아군을 통과 1 = 켬 1 = 장애물도 통과
24 huangzhong_p crit_chance 0 0.2 치명타 확률 증가 확률 +(0.2 = +20 %p)
35 guanping_a guard_dr 2 -0.5 호위로 대신 받는 피해 감소 · 2턴 지속 받는 비율(−0.5 = 반감)
36 guanping_p counter_dmg_pct 0 0.5 주는 반격 피해 증가 반격 피해 +비율(0.5 = +50 % · 1.0 = 2배)
37 guanping_p guard 0 2 1.0 반경·대신 받는 비율 호위 — 반경 안 아군 피해를 대신 받음 호위 반경 대신 받는 비율(1.0 = 전부)
38 xushu_a shot_blast 0 1.5 2.5 폭발 반경(기본값 = 책사 광역)·공격 배율 폭발 반경(PD 확정 · 책사 광역과 같게)·공격 배율 투사체가 첫 적 자리에서 폭발 — 반경 안 적 전원 피해 폭발 반경 피해 = 공격력 × 배수
39 xushu_a hit_burn 0 3 0.05 1 명중한 적 화상(불태우기 · 턴 시작마다 생명력 감소) 화상 턴 1회 최대 HP × 비율 확률
40 xushu_p range_mult 0 1.5 공격 사거리 배율 사거리 ×배율(1.5 = +50 %)
41 xushu_p splash_ally_ratio 0 0 자신의 광역이 아군에게 주는 피해 비율 아군 피해 비율(0 = 아군 피해 없음)
58 jiangwei_a heal_self_pct 0 0.5 자신 생명력 회복 최대 HP × 비율
59 jiangwei_a guard_radius_mult 3 1.5 호위·반격 반경 배율 · 3턴 지속 반경 ×배율
60 jiangwei_p counter_dmg_pct 0 0.5 주는 반격 피해 증가 반격 피해 +비율(0.5 = +50 % · 1.0 = 2배)
61 jiangwei_p guard_counter 0 2 1.0 반격 범위(기본값 = 관평 호위 2)·대신 받는 비율 반격 범위(PD 확정 · 관평 호위 2)·대신 받는 비율 호위 반격 — 반경 안 아군 피해를 대신 받고 공격자에게 반격 반격(호위) 반경 대신 받는 비율
62 liufeng_a atk_ratio 0 1.85 이 공격의 피해 = 공격력의 배수 공격력 배수(1.8 = 180 %)
63 liufeng_a hit_confuse 0 1 0.5 1 턴·이동 배율·확률 명중한 적 혼란(이동 거리 감소) 혼란 턴 이동 거리 배율(0.5 = 반감) 확률
64 liufeng_p counter_taken_pct vs_confused 0 -1 받는 반격 피해 증감 · 조건: 상대가 혼란일 때 받는 반격 비율(−1 = 반격 안 받음 · −0.5 = 반감)
67 jianyong_a hit_stun 0 1 명중한 적 기절(다음 자기 턴 행동 불가) 기절 턴
68 jianyong_p heal_cleanse 0 1 자신이 회복시킨 대상의 상태 이상 제거 1 = 켬
69 jianyong_p on_attacked_stun 0 1 3 기절 턴·재충전 턴 자신을 공격한 대상 기절(재충전) 기절 턴 재충전 턴
70 sunqian_a splash_heal 0 0.6 명중 대상 주위 광역 = 회복(적 포함) 명중 대상 포함 범위 안 전원 회복(적 포함) · 피해 없음(PD 결정 ⑧) 책사 광역이 피해 대신 회복(적 포함) 책사 사격이 피해 없이 명중 대상 포함 범위 안 전원 회복(적 포함) 회복 = 공격력 × 배수
71 sunqian_p sling_dist_pct radius:3 0 0.3 이동(슬링) 거리 증가 · 대상: 자신 주위 3 안 아군 이동 거리 +비율(1.0 = 2배)
72 mizhu_a sling_dist_pct range 1 0.5 이동(슬링) 거리 증가 · 대상: 시전 순간 행동 반경 안 아군 · 1턴 지속 이동 거리 +비율(1.0 = 2배)
73 mizhu_a counter_taken_pct range 1 -0.5 받는 반격 피해 증감 · 대상: 시전 순간 행동 반경 안 아군 · 1턴 지속 받는 반격 비율(−1 = 반격 안 받음 · −0.5 = 반감)
91 zhangliao_a hit_confuse 0 1 0.5 1 명중한 적 혼란(이동 거리 감소) 혼란 턴 이동 거리 배율(0.5 = 반감) 확률
92 zhangliao_p atk_pct vs_status 0 0.5 공격력 증가 · 조건: 상대가 상태 이상일 때 공격력 +비율(0.2 = +20 %)
93 zhangliao_p counter_taken_pct vs_status 0 -1 받는 반격 피해 증감 · 조건: 상대가 상태 이상일 때 받는 반격 비율(−1 = 반격 안 받음 · −0.5 = 반감)
94 xuhuang_a axe_aura 3 1.2 0.8 2 도끼 반경(기본값)·공격 배율·튕김 배율 도끼 반경(PD 확정)·공격 배율·튕김 배율 주위를 도는 도끼 — 자신을 친 근접 유닛에게 반격 피해 + 그 유닛이 더 멀리 튕김 · 3턴 지속 도끼 반경 반격 피해 = 공격력 × 배수 공격자 튕김 거리 배율
95 xuhuang_p hit_bleed 0 3 0.5 0.3 명중한 적 출혈(움직인 거리에 비례해 생명력 감소) 출혈 턴 슬링 최대 거리만큼 움직일 때 최대 HP × 비율 확률
96 xuhuang_p hit_bleed crit 0 3 0.5 1 명중한 적 출혈(움직인 거리에 비례해 생명력 감소) · 조건: 치명타일 때 출혈 턴 슬링 최대 거리만큼 움직일 때 최대 HP × 비율 확률
97 zhanghe_a teleport 0 5 반경 안 원하는 곳으로 이동(대상 무시 · 지점 탭) 이동 반경
110 simayi_p splash_radius_mult camp:wei:strategist 0 1.5 책사 광역 범위 배율 · 대상: 위 진영 책사 유닛 광역 반경 ×배율
111 simayi_p range_mult 0 1.5 공격 사거리 배율 사거리 ×배율(1.5 = +50 %)
112 simayi_p drain_aura 0 0.3 행동 반경 안 적이 입은 피해만큼 자신 회복 그 피해 × 비율 회복
113 xiahouyuan_a shot_fan 0 5 3 60 발 수·연속 횟수·부채꼴 각(기본값) 발 수·연속 횟수·부채꼴 각(PD 확정) 부채꼴 연속 사격 한 번에 쏘는 화살 수 연속 횟수 부채꼴 전체 각도(도)
114 xiahouyuan_p multishot 0 3 30 발 수·부채꼴 각(기본값) 발 수·부채꼴 각(PD 확정) 일반 사격이 부채꼴 여러 발(멀티샷) 화살 수 부채꼴 전체 각도(도)
115 guojia_a dmg_pct range 2 0.3 주는 피해 증가 · 대상: 시전 순간 행동 반경 안 아군 · 2턴 지속 피해 +비율(0.5 = +50 %)
116 guojia_a grant_reaction 0 1 이미 행동한 다른 아군에게 재행동 부여(없으면 다른 아군이 행동 뒤 재행동) 인원
117 guojia_p kill_in_range_reward 0 1 0.3 쿨 −턴·최대 HP 회복 자신의 행동 반경 안에서 적을 처치한 아군 보상 액티브 쿨 −턴 최대 HP × 비율 회복
118 jiaxu_a shot_blast 0 1.5 2.2 독구름 반경(기본값)·공격 배율 독구름 반경(PD 확정)·공격 배율 투사체가 첫 적 자리에서 폭발 — 반경 안 적 전원 피해 폭발 반경 피해 = 공격력 × 배수
119 jiaxu_a hit_poison 0 5 0.02 1 명중한 적 중독(턴 시작·행동 끝마다 생명력 감소) 중독 턴 1회 최대 HP × 비율(중첩 수만큼 곱) 확률
120 jiaxu_p hit_poison 0 5 1 0.02 1 턴(기본값 = 독계) 턴(미기재 → 1 · PD 결정 ④) 명중한 적 중독(턴 시작·행동 끝마다 생명력 감소) 중독 턴 1회 최대 HP × 비율(중첩 수만큼 곱) 확률
121 jiaxu_p poison_stack 0 5 중독 중첩 허용 최대 중첩
122 dianwei_a dmg_pct 0 1.0 주는 피해 증가 피해 +비율(0.5 = +50 %)
123 dianwei_a push_mult 0 2 밀치는 거리 배율 밀기 ×배율(2 = 2배)
137 xiahouen_p hp_max_pct 0 0.1 최대 생명력 증가 최대 HP +비율
138 sunjian_a atk_pct 0 0.5 공격력 증가 공격력 +비율(0.2 = +20 %)
139 sunjian_a pierce_through 0 1 1 = 아군도 통과 보병·창병도 기병처럼 적을 관통하며 경로 위 적 전원 피해 1 = 아군도 통과 · 0 = 아군 앞 정지
140 sunjian_a hit_bleed 0 2 1 0.5 1 턴(미기재 → 1 · PD 결정 ④) 명중한 적 출혈(움직인 거리에 비례해 생명력 감소) 출혈 턴 슬링 최대 거리만큼 움직일 때 최대 HP × 비율 확률
141 sunjian_a invuln 1 1 행동 끝 뒤 1턴 피해 무효 무적 — 모든 피해 무효(행동 중이 아닌 동안) · 1턴 지속 1 = 켬
142 sunjian_p atk_pct camp:wu 0 0.2 공격력 증가 · 대상: 오 진영 유닛 공격력 +비율(0.2 = +20 %)
143 sunjian_p kill_reaction 0 1 턴당 적 처치 시 재행동(턴당 1회) 1 = 켬
144 zhouyu_a shot_blast 0 2.5 3.5 운석 반경(기본값)·공격 배율 운석 반경(PD 확정)·공격 배율 투사체가 첫 적 자리에서 폭발 — 반경 안 적 전원 피해 폭발 반경 피해 = 공격력 × 배수
145 zhouyu_a hit_burn 0 3 1 0.05 1 운석 불태우기 턴(미기재 → 1 · PD 결정 ④) 명중한 적 화상(불태우기 · 턴 시작마다 생명력 감소) 화상 턴 1회 최대 HP × 비율 확률
146 zhouyu_a fire_zone 0 1.5 3 1 1.0 불꽃 반경·턴·닿을 때 공격 배율 불꽃 반경(PD 확정)·불꽃 유지 턴(미기재 → 1)·닿을 때 공격 배율 폭발 자리에 불꽃 지대 — 닿는 적 피해 + 화상 지대 반경 유지 턴 닿을 때 피해 = 공격력 × 배수
147 zhouyu_a zone_burn 0 3 0.05 불꽃에 닿으면 3턴 화상(원문) 지대(불꽃)에 닿으면 거는 화상(없으면 그 스킬 hit_burn) 화상 턴 1회 최대 HP × 비율
148 zhouyu_p skill_hp_cost 0 0.05 액티브 스킬 시전 시 생명력 소모 최대 HP × 비율 소모(쓰러지지는 않음)
149 zhouyu_p skill_power_low_hp 0 0.1 0.1 HP p2 잃을 때마다 스킬 위력 +p1 생명력이 낮을수록 스킬 위력 증가 단계당 스킬 위력 +비율 단계 = 잃은 HP 비율(0.1 = 10 %마다)
150 zhouyu_p melee_penalty_off 0 1 궁병·책사 근접 전투 패널티 없음 1 = 켬
168 sunce_p sling_dist_pct camp:wu 0 0.3 이동(슬링) 거리 증가 · 대상: 오 진영 유닛 이동 거리 +비율(1.0 = 2배)
169 sunce_p counter_taken_pct 0 -1 받는 반격 피해 증감 받는 반격 비율(−1 = 반격 안 받음 · −0.5 = 반감)
170 sunce_p return_on_hit 0 0 0 피해를 입히면 출발 위치로 복귀 1 = 복귀하며 경로 위 적에게도 피해 1 = 복귀 경로의 유닛을 함께 쓸어 감
171 sunce_p dash_dmg_pct 0 1.0 최대(기본값 = 장비·여포) 최대(PD 확정 · 장비·여포) 돌진(슬링) 거리에 비례해 공격력 증가 슬링 최대 거리로 당겼을 때 공격 +비율(최대)
172 sunquan_a shot_blast 0 1.5 1.8 화살비 반경(기본값)·공격 배율 화살비 반경(PD 확정)·공격 배율 투사체가 첫 적 자리에서 폭발 — 반경 안 적 전원 피해 폭발 반경 피해 = 공격력 × 배수
173 sunquan_a hit_confuse 0 1 0.5 1 명중한 적 혼란(이동 거리 감소) 혼란 턴 이동 거리 배율(0.5 = 반감) 확률
174 sunquan_p range_mult camp:wu:archer 0 1.5 공격 사거리 배율 · 대상: 오 진영 궁병 유닛 사거리 ×배율(1.5 = +50 %)
175 sunquan_p arrow_pass_allies 0 1 0 화살이 아군을 통과 1 = 켬 1 = 장애물도 통과
182 lvmeng_a reaction_on_kill 0 1 3 이 행동으로 적을 처치하면 재행동(연쇄) 처치 시 재행동 수 연쇄 최대 재행동
183 lvmeng_p counter_taken_pct 0 -0.3 받는 반격 피해 증감 받는 반격 비율(−1 = 반격 안 받음 · −0.5 = 반감)
184 lvmeng_p reaction_atk_stack 0 0.2 이번 턴 재행동할 때마다 공격력 증가(2배씩 · 턴마다 초기화) 첫 재행동 공격 +비율(다음은 2배 · 4배)
185 luxun_a shot_firewall 0 0.6 3 3.0 장벽 반폭(기본값)·턴·닿을 때 공격 배율 장벽 반폭(PD 확정)·턴·닿을 때 공격 배율 진행 방향 불 장벽(지대) — 닿는 적 피해 + 화상 장벽 반폭 유지 턴 닿을 때 피해 = 공격력 × 배수
186 luxun_a hit_burn 0 3 0.05 1 명중한 적 화상(불태우기 · 턴 시작마다 생명력 감소) 화상 턴 1회 최대 HP × 비율 확률
187 luxun_a zone_hits_allies 0 1 아군도 피해(PD 결정 ⑬) 지대·장벽이 아군에게도 피해·화상 1 = 켬
188 luxun_p dmg_pct camp:wu vs_status 0 0.5 주는 피해 증가 · 대상: 오 진영 유닛 · 조건: 상대가 상태 이상일 때 피해 +비율(0.5 = +50 %)
189 luxun_p hit_confuse 0 1 0.5 1 명중한 적 혼란(이동 거리 감소) 혼란 턴 이동 거리 배율(0.5 = 반감) 확률
190 sunshangxiang_a volley 0 1.0 1.0 공격 배율(기본값)·밀기(기본값) 공격 배율(PD 확정)·밀기(PD 확정) 사거리 안 적 전원에게 화살 — 피해·밀침(치명타 판정) 피해 = 공격력 × 배수 밀기 거리
191 sunshangxiang_a hit_bleed crit 0 2 0.5 1 명중한 적 출혈(움직인 거리에 비례해 생명력 감소) · 조건: 치명타일 때 출혈 턴 슬링 최대 거리만큼 움직일 때 최대 HP × 비율 확률
192 sunshangxiang_p dmg_pct vs_male_hero 0 0.5 주는 피해 증가 · 조건: 상대가 남성 영웅일 때 피해 +비율(0.5 = +50 %)
193 sunshangxiang_p melee_penalty_off 0 1 궁병·책사 근접 전투 패널티 없음 1 = 켬
198 lingtong_a aoe_strike 0 3 1.5 1 자신 주위 적 전원 공격·밀침 반경 피해 = 공격력 × 배수(0 = 피해 없음) 바깥으로 밀기 거리
199 lingtong_p atk_pct 0 0.15 공격력 증가 공격력 +비율(0.2 = +20 %)
200 lingtong_p push_mult 0 1.3 밀치는 거리 배율 밀기 ×배율(2 = 2배)
201 zhoutai_a shot_pierce 0 1.8 1 1.0 검기 · 아군도 피해 · 밀기(기본값) 검기 · 아군도 피해 · 밀기(PD 확정) 직선 관통 사격 — 경로 위 유닛 전원(장애물 무시) 피해 = 공격력 × 배수 아군 처리(0 통과 · 1 피해 · 2 회복) 밀기 거리(0 = 없음)
202 zhoutai_p hit_confuse crit 0 1 0.5 1 명중한 적 혼란(이동 거리 감소) · 조건: 치명타일 때 혼란 턴 이동 거리 배율(0.5 = 반감) 확률
203 zhoutai_p crit_always vs_type:spear 0 1 무조건 치명타 · 조건: 상대가 창병일 때 1 = 켬
204 zhugejin_a shot_whirl 0 1.0 3.0 0 1.0 회오리 반폭(기본값)·밀기(기본값)·공격 배율(피해 없음) 회오리 반폭·밀기(PD 확정)·공격 배율(PD 결정 ⑭ = 100 %) 회오리 — 직선 위 적을 진행 방향으로 크게 밀침 회오리 반폭 밀기 거리 피해 = 공격력 × 배수(0 = 없음)
205 zhugejin_a hit_confuse 0 1 0.5 1 명중한 적 혼란(이동 거리 감소) 혼란 턴 이동 거리 배율(0.5 = 반감) 확률
206 zhugejin_p splash_ally_ratio 0 0 자신의 광역이 아군에게 주는 피해 비율 아군 피해 비율(0 = 아군 피해 없음)
207 dongxi_a atk_ratio 0 1.5 이 공격의 피해 = 공격력의 배수 공격력 배수(1.8 = 180 %)
216 lvbu_p dash_dmg_pct 0 1.0 돌진(슬링) 거리에 비례해 공격력 증가 슬링 최대 거리로 당겼을 때 공격 +비율(최대)
217 zhangjiao_a invuln 1 1 무적 — 모든 피해 무효(행동 중이 아닌 동안) · 1턴 지속 1 = 켬
218 zhangjiao_p dmg_taken_from_archer_pct 0 -0.3 적 궁병에게 받는 피해 증감 받는 피해 비율(−0.3 = 30 % 감소)
219 zhangjiao_p hit_poison 0 5 1 0.02 0.5 턴(기본값)·확률 턴(미기재 → 1 · PD 결정 ④)·확률 명중한 적 중독(턴 시작·행동 끝마다 생명력 감소) 중독 턴 1회 최대 HP × 비율(중첩 수만큼 곱) 확률
220 huaxiong_a dmg_pct 0 1.0 주는 피해 증가 피해 +비율(0.5 = +50 %)
221 huaxiong_a counter_taken_pct 0 -1 받는 반격 피해 증감 받는 반격 비율(−1 = 반격 안 받음 · −0.5 = 반감)
222 huaxiong_p atk_pct turn_le:3 0 0.5 공격력 증가 · 조건: 전투 3턴까지 공격력 +비율(0.2 = +20 %)
233 gongsunzan_a return_always 0 0 공격 후 항상 출발 위치로 복귀 1 = 복귀하며 경로 위 적에게도 피해
234 gongsunzan_p dmg_pct vs_type:archer 0 1.0 주는 피해 증가 · 조건: 상대가 궁병일 때 피해 +비율(0.5 = +50 %)
235 gongsunzan_p heal_on_kill 0 0.3 적 처치 시 생명력 회복 최대 HP × 비율 회복
236 dongzhuo_a rampage 0 3 1.5 돌진 초·밀치기 거리(기본값) 돌진 초·밀치기 거리(PD 확정) 일정 시간 직진 난동 — 닿는 유닛 전원 밀침(적 = 피해) · 가장자리 튕김 · 자신은 튕기지 않음 돌진 시간(초 · 이동 속도 × 초 = 거리) 옆으로 밀치는 거리
237 dongzhuo_p dmg_taken_pct camp:other 0 -0.1 받는 피해 증감 · 대상: 군웅 진영 유닛 받는 피해 비율(−0.3 = 30 % 감소 · +0.15 = 15 % 증가)
238 dongzhuo_p lifesteal 0 0.3 0.05 p2 = 아군 1기 줄 때마다 + 입힌 피해만큼 회복(흡혈) 입힌 피해 × 비율 회복 아군 1기 줄 때마다 비율 +
239 lijue_a splash_heal_lowest 0 0.5 2 광역 피해 비율·인접 반경(기본값) 광역 피해 비율·인접 반경(PD 확정) 광역으로 준 피해만큼 인접한 가장 약한 아군 회복 광역 피해 × 비율 회복 인접 반경
240 lijue_p action_end_sacrifice 0 0.1 0.5 2 HP 소모·공격 %·인접 반경(기본값) HP 소모·공격 %·인접 반경(PD 확정) 행동 끝 = 생명력 소모 후 인접 아군 공격력 강화(대상 없으면 발동 안 함) HP 소모 비율(HP 10 % 이하면 소모 없이) 인접 아군 공격 +비율(1턴) 인접 반경
241 yuanshao_a sling_dist_pct range 1 0.5 이동(슬링) 거리 증가 · 대상: 시전 순간 행동 반경 안 아군 · 1턴 지속 이동 거리 +비율(1.0 = 2배)
242 yuanshao_a crit_dmg_pct range 1 0.5 치명타 피해량 증가 · 대상: 시전 순간 행동 반경 안 아군 · 1턴 지속 치명타 피해 +비율(0.5 = +50 %)
243 yuanshao_a crit_chance range 1 0.2 치명타 확률 증가 · 대상: 시전 순간 행동 반경 안 아군 · 1턴 지속 확률 +(0.2 = +20 %p)
255 diaochan_p dmg_taken_pct vs_male 0 -0.3 받는 피해 증감 · 조건: 상대가 남성일 때 받는 피해 비율(−0.3 = 30 % 감소 · +0.15 = 15 % 증가)
256 zhurong_a shot_as_archer 0 1 근접 병종이 궁병처럼 원거리 사격 1 = 켬
257 zhurong_a atk_ratio 0 2.2 이 공격의 피해 = 공격력의 배수 공격력 배수(1.8 = 180 %)
258 zhurong_a hit_poison 0 5 1 0.02 1 턴(미기재 → 1 · PD 결정 ④) 명중한 적 중독(턴 시작·행동 끝마다 생명력 감소) 중독 턴 1회 최대 HP × 비율(중첩 수만큼 곱) 확률
259 zhurong_p lifesteal 0 0.2 입힌 피해만큼 회복(흡혈) 입힌 피해 × 비율 회복
260 zhurong_p counter_dmg_pct 0 0.5 주는 반격 피해 증가 반격 피해 +비율(0.5 = +50 % · 1.0 = 2배)
261 zhurong_p terrain_immune 0 1 지형(늪·고지) 이동 감소 무시 1 = 켬
269 gaoshun_p push_continue 0 1 아군·지형 오브젝트를 밀친 뒤 남은 이동 거리로 재행동 1 = 켬
270 zhanglu_a shot_single 0 1 책사 사격이 광역 없는 직선 투사체 1 = 켬
271 zhanglu_a atk_ratio 0 2.5 이 공격의 피해 = 공격력의 배수 공격력 배수(1.8 = 180 %)
272 zhanglu_a hit_poison 0 5 1 0.02 1 턴(미기재 → 1 · PD 결정 ④) 명중한 적 중독(턴 시작·행동 끝마다 생명력 감소) 중독 턴 1회 최대 HP × 비율(중첩 수만큼 곱) 확률
273 zhanglu_a poison_zone 0 1.0 1 반경(기본값)·턴 반경(PD 확정)·턴 명중 자리에 독 지대 — 닿는 적 중독 지대 반경 유지 턴
274 zhanglu_p zombie 0 1 되살린 HP 처치한 적이 같은 편 망령으로 되살아나 1번 공격(조작 불가 · 다음 턴 소멸) 망령 HP
275 yanbaihu_a atk_pct 0 0.3 공격력 증가 공격력 +비율(0.2 = +20 %)
276 yanbaihu_a crit_chance 0 0.15 치명타 확률 증가 확률 +(0.2 = +20 %p)

View File

@ -71,7 +71,7 @@ xiahouen_a,xiahouen,active,청강검 발도,靑釭劍拔刀,next_action,first_hi
xiahouen_p,xiahouen,passive,보검의 광채,,always,hp_max_pct,,,,0,5,0.1,최대 생명력 +10%,0
sunjian_a,sunjian,active,강동의 호랑이,,next_action,atk_pct;pierce_through;hit_bleed;invuln,,,,3,5,0.1,다음 행동 시 공격력이 50% 증가하고 · 모든 유닛을 통과하며 공격할 수 있으며 경로 상 피격 된 모든 적에게 출혈 피해를 입힘 · 행동 종료 후 1턴간 모든 피해를 무효화함(튕겨질 순 있고 · 반격 피해는 입힐 수 있음),0
sunjian_p,sunjian,passive,파로,破虜,always,atk_pct;kill_reaction,,,,0,5,0.1,모든 오군 진영 공격력 +20% 증가하고 · 자신의 공격으로 적을 처치할 경우 재행동 기회 1회 부여(턴 당 1회),0
zhouyu_a,zhouyu,active,적벽의 불비,赤壁火雨,next_action,shot_blast;hit_burn;fire_zone,,,,4,5,0.1,다음 행동 시 명중한 대상 주위에 운석을 소환해 넓은 범위에 공격력의 350%의 피해를 입히고 · 피격 된 대상을 불태우기 상태에 빠뜨리며 · 운석이 낙하한 장소에 불꽃을 생성(닿는 적에게 즉시 공격력의 100%의 피해를 입히고 · 3턴간 유지되는 화상 효과를 입힘),0
zhouyu_a,zhouyu,active,적벽의 불비,赤壁火雨,next_action,shot_blast;hit_burn;fire_zone;zone_burn,,,,4,5,0.1,다음 행동 시 명중한 대상 주위에 운석을 소환해 넓은 범위에 공격력의 350%의 피해를 입히고 · 피격 된 대상을 불태우기 상태에 빠뜨리며 · 운석이 낙하한 장소에 불꽃을 생성(닿는 적에게 즉시 공격력의 100%의 피해를 입히고 · 3턴간 유지되는 화상 효과를 입힘),0
zhouyu_p,zhouyu,passive,대도독,大都督,always,skill_hp_cost;skill_power_low_hp;melee_penalty_off;range_mult,,,,0,5,0.1,스킬 시전 시 생명력이 5% 감소하지만 · 생명이 낮아질 때마다 스킬의 위력이 10%씩 증가하며 · 자신은 근접 유닛과의 전투에 패널티를 받지 않고 · 스킬 사거리가 50% 증가,0
huanggai_a,huanggai,active,고육계,苦肉計,instant,dmg_taken_pct;damage_to_atk;heal_on_kill,,,,3,5,0.1,즉시: 1턴간 자신의 받는 피해가 30% 감소되며 · 자신이 이번 턴에 받은 피해가 다음 턴의 공격력에 추가되며 · 적을 처치한 경우 생명력 100% 회복,0
huanggai_p,huanggai,passive,노장,老將,always,dmg_taken_pct;low_hp_taken,,,,0,5,0.1,자신의 받는 피해 -15 % · 생명력이 낮아질수록 받는 피해가 0.2%씩 증가하고 반격 피해가 1%씩 증가,0
@ -87,7 +87,7 @@ lusu_a,lusu,active,녹각진,鹿角陣,next_action,shot_barricade,,,,3,5,0.1,다
lusu_p,lusu,passive,동맹의 깃발,同盟之旗,always,atk_per_ally_range;turn_start_heal_range;death_banner,,,,0,5,0.1,자신의 행동 범위 내 아군 1기당 공격력이 5%씩 증가하고 · 매턴 시작 시 행동 범위 내 아군의 생명력을 10% 회복시킬 수 있으며 · 사망할 경우 쓰러진 장소에 5턴간 효과를 유지하는 깃발을 남겨 자신의 패시브 효과를 전장에 남김,0
lvmeng_a,lvmeng,active,백의도강,白衣渡江,next_action,reaction_on_hit;reaction_on_kill,,,,4,5,0.1,다음 행동으로 적에게 피해를 입힌 경우 · 한번 더 행동할 수 있으며 적을 처치한 경우 한번 더 행동 가능(최대 3회),0
lvmeng_p,lvmeng,passive,괄목상대,刮目相對,always,counter_taken_pct;reaction_atk_stack,,,,0,5,0.1,반격 피해를 30% 반감하며 · 매턴 재행동이 발생할 때마다 추가 공격력이 20% 부여되며 · 추가 공격력은 재행동 횟수에 비례해 2배씩 증가(20%→40%→80%) (추가 공격력은 턴마다 초기화),0
luxun_a,luxun,active,이릉의 화공,夷陵火攻,next_action,shot_firewall;hit_burn,,,,4,5,0.1,다음 행동으로 지정한 방향으로 모든 유닛에게 피해를 입히는 불 장벽을 생성해 3턴간 전장에 유지되며 · 닿는 적에게는 즉시 300%의 피해를 입히고 · 3턴간 화상 효과를 입힘,0
luxun_a,luxun,active,이릉의 화공,夷陵火攻,next_action,shot_firewall;hit_burn;zone_hits_allies,,,,4,5,0.1,다음 행동으로 지정한 방향으로 모든 유닛에게 피해를 입히는 불 장벽을 생성해 3턴간 전장에 유지되며 · 닿는 적에게는 즉시 300%의 피해를 입히고 · 3턴간 화상 효과를 입힘,0
luxun_p,luxun,passive,백면서생,白面書生,always,dmg_pct;hit_confuse,,,,0,5,0.1,모든 오군이 상태이상 효과에 걸린 적 공격 시 피해량이 50% 증가하며 · 자신의 공격에 피격 된 대상은 1턴간 혼란에 빠뜨림 (혼란 : 이동 속도 50% 감소),0
sunshangxiang_a,sunshangxiang,active,궁요희,弓腰姬,instant,volley;hit_bleed,,,,3,5,0.1,즉시: 행동 범위 내 모든 적에게 화살을 발사해 피해를 입히고 · 밀쳐내며 치명타 발생 시 2턴간 출혈 효과를 유발함,0
sunshangxiang_p,sunshangxiang,passive,효희,梟姬,always,dmg_pct;melee_penalty_off,,,,0,5,0.1,남성 영웅에 대한 피해량이 50% 증가하고 · 근접 피해 패널티를 받지 않음.(반격 피해에도 피해량 50% 증가 적용),0

1 id hero_id kind name_ko hanja trigger effect_key p1 p2 p3 cooldown lv_max lv_scale desc_ko needs_impl
71 xiahouen_p xiahouen passive 보검의 광채 always hp_max_pct 0 5 0.1 최대 생명력 +10% 0
72 sunjian_a sunjian active 강동의 호랑이 next_action atk_pct;pierce_through;hit_bleed;invuln 3 5 0.1 다음 행동 시 공격력이 50% 증가하고 · 모든 유닛을 통과하며 공격할 수 있으며 경로 상 피격 된 모든 적에게 출혈 피해를 입힘 · 행동 종료 후 1턴간 모든 피해를 무효화함(튕겨질 순 있고 · 반격 피해는 입힐 수 있음) 0
73 sunjian_p sunjian passive 파로 破虜 always atk_pct;kill_reaction 0 5 0.1 모든 오군 진영 공격력 +20% 증가하고 · 자신의 공격으로 적을 처치할 경우 재행동 기회 1회 부여(턴 당 1회) 0
74 zhouyu_a zhouyu active 적벽의 불비 赤壁火雨 next_action shot_blast;hit_burn;fire_zone shot_blast;hit_burn;fire_zone;zone_burn 4 5 0.1 다음 행동 시 명중한 대상 주위에 운석을 소환해 넓은 범위에 공격력의 350%의 피해를 입히고 · 피격 된 대상을 불태우기 상태에 빠뜨리며 · 운석이 낙하한 장소에 불꽃을 생성(닿는 적에게 즉시 공격력의 100%의 피해를 입히고 · 3턴간 유지되는 화상 효과를 입힘) 0
75 zhouyu_p zhouyu passive 대도독 大都督 always skill_hp_cost;skill_power_low_hp;melee_penalty_off;range_mult 0 5 0.1 스킬 시전 시 생명력이 5% 감소하지만 · 생명이 낮아질 때마다 스킬의 위력이 10%씩 증가하며 · 자신은 근접 유닛과의 전투에 패널티를 받지 않고 · 스킬 사거리가 50% 증가 0
76 huanggai_a huanggai active 고육계 苦肉計 instant dmg_taken_pct;damage_to_atk;heal_on_kill 3 5 0.1 즉시: 1턴간 자신의 받는 피해가 30% 감소되며 · 자신이 이번 턴에 받은 피해가 다음 턴의 공격력에 추가되며 · 적을 처치한 경우 생명력 100% 회복 0
77 huanggai_p huanggai passive 노장 老將 always dmg_taken_pct;low_hp_taken 0 5 0.1 자신의 받는 피해 -15 % · 생명력이 낮아질수록 받는 피해가 0.2%씩 증가하고 반격 피해가 1%씩 증가 0
87 lusu_p lusu passive 동맹의 깃발 同盟之旗 always atk_per_ally_range;turn_start_heal_range;death_banner 0 5 0.1 자신의 행동 범위 내 아군 1기당 공격력이 5%씩 증가하고 · 매턴 시작 시 행동 범위 내 아군의 생명력을 10% 회복시킬 수 있으며 · 사망할 경우 쓰러진 장소에 5턴간 효과를 유지하는 깃발을 남겨 자신의 패시브 효과를 전장에 남김 0
88 lvmeng_a lvmeng active 백의도강 白衣渡江 next_action reaction_on_hit;reaction_on_kill 4 5 0.1 다음 행동으로 적에게 피해를 입힌 경우 · 한번 더 행동할 수 있으며 적을 처치한 경우 한번 더 행동 가능(최대 3회) 0
89 lvmeng_p lvmeng passive 괄목상대 刮目相對 always counter_taken_pct;reaction_atk_stack 0 5 0.1 반격 피해를 30% 반감하며 · 매턴 재행동이 발생할 때마다 추가 공격력이 20% 부여되며 · 추가 공격력은 재행동 횟수에 비례해 2배씩 증가(20%→40%→80%) (추가 공격력은 턴마다 초기화) 0
90 luxun_a luxun active 이릉의 화공 夷陵火攻 next_action shot_firewall;hit_burn shot_firewall;hit_burn;zone_hits_allies 4 5 0.1 다음 행동으로 지정한 방향으로 모든 유닛에게 피해를 입히는 불 장벽을 생성해 3턴간 전장에 유지되며 · 닿는 적에게는 즉시 300%의 피해를 입히고 · 3턴간 화상 효과를 입힘 0
91 luxun_p luxun passive 백면서생 白面書生 always dmg_pct;hit_confuse 0 5 0.1 모든 오군이 상태이상 효과에 걸린 적 공격 시 피해량이 50% 증가하며 · 자신의 공격에 피격 된 대상은 1턴간 혼란에 빠뜨림 (혼란 : 이동 속도 50% 감소) 0
92 sunshangxiang_a sunshangxiang active 궁요희 弓腰姬 instant volley;hit_bleed 3 5 0.1 즉시: 행동 범위 내 모든 적에게 화살을 발사해 피해를 입히고 · 밀쳐내며 치명타 발생 시 2턴간 출혈 효과를 유발함 0
93 sunshangxiang_p sunshangxiang passive 효희 梟姬 always dmg_pct;melee_penalty_off 0 5 0.1 남성 영웅에 대한 피해량이 50% 증가하고 · 근접 피해 패널티를 받지 않음.(반격 피해에도 피해량 50% 증가 적용) 0

View File

@ -1380,7 +1380,7 @@ MonoBehaviour:
\uC801\uC5D0\uAC8C \uC989\uC2DC \uACF5\uACA9\uB825\uC758 100%\uC758 \uD53C\uD574\uB97C
\uC785\uD788\uACE0 \xB7 3\uD134\uAC04 \uC720\uC9C0\uB418\uB294 \uD654\uC0C1
\uD6A8\uACFC\uB97C \uC785\uD798)"
effectKey: shot_blast;hit_burn;fire_zone
effectKey: shot_blast;hit_burn;fire_zone;zone_burn
p1: 0
p2: 0
p3: 0
@ -1699,7 +1699,7 @@ MonoBehaviour:
\uC720\uC9C0\uB418\uBA70 \xB7 \uB2FF\uB294 \uC801\uC5D0\uAC8C\uB294 \uC989\uC2DC
300%\uC758 \uD53C\uD574\uB97C \uC785\uD788\uACE0 \xB7 3\uD134\uAC04 \uD654\uC0C1
\uD6A8\uACFC\uB97C \uC785\uD798"
effectKey: shot_firewall;hit_burn
effectKey: shot_firewall;hit_burn;zone_hits_allies
p1: 0
p2: 0
p3: 0
@ -2791,11 +2791,12 @@ MonoBehaviour:
target:
cond:
dur: 0
p1: 2
p1: 1
p2: 0.5
p3: 1
pMask: 7
note: "\uD134(\uAE30\uBCF8\uAC12)\xB7\uC774\uB3D9 \uBE44\uB840\xB7\uD655\uB960"
note: "\uD134(\uBBF8\uAE30\uC7AC \u2192 1 \xB7 PD \uACB0\uC815 \u2463)\xB7\uC774\uB3D9
\uBE44\uB840\xB7\uD655\uB960"
- skillId: guanyu_p
key: counter_dmg_pct
target: camp:shu
@ -2935,7 +2936,7 @@ MonoBehaviour:
p2: 5
p3: 0
pMask: 3
note: "\uD654\uC0B4 \uBC18\uC9C0\uB984(\uAE30\uBCF8\uAC12)\xB7\uACF5\uACA9 \uBC30\uC728
note: "\uD654\uC0B4 \uBC18\uC9C0\uB984(PD \uD655\uC815)\xB7\uACF5\uACA9 \uBC30\uC728
\xB7 \uC0AC\uAC70\uB9AC \uBB34\uAD00"
- skillId: huangzhong_a
key: hit_stun
@ -3106,8 +3107,8 @@ MonoBehaviour:
p2: 2.5
p3: 0
pMask: 3
note: "\uD3ED\uBC1C \uBC18\uACBD(\uAE30\uBCF8\uAC12 = \uCC45\uC0AC \uAD11\uC5ED)\xB7\uACF5\uACA9
\uBC30\uC728"
note: "\uD3ED\uBC1C \uBC18\uACBD(PD \uD655\uC815 \xB7 \uCC45\uC0AC \uAD11\uC5ED\uACFC
\uAC19\uAC8C)\xB7\uACF5\uACA9 \uBC30\uC728"
- skillId: xushu_a
key: hit_burn
target:
@ -3338,7 +3339,7 @@ MonoBehaviour:
p2: 1
p3: 0
pMask: 3
note: "\uBC18\uACA9 \uBC94\uC704(\uAE30\uBCF8\uAC12 = \uAD00\uD3C9 \uD638\uC704
note: "\uBC18\uACA9 \uBC94\uC704(PD \uD655\uC815 \xB7 \uAD00\uD3C9 \uD638\uC704
2)\xB7\uB300\uC2E0 \uBC1B\uB294 \uBE44\uC728"
- skillId: liufeng_a
key: atk_ratio
@ -3429,8 +3430,9 @@ MonoBehaviour:
p2: 0
p3: 0
pMask: 1
note: "\uBA85\uC911 \uB300\uC0C1 \uC8FC\uC704 \uAD11\uC5ED = \uD68C\uBCF5(\uC801
\uD3EC\uD568)"
note: "\uBA85\uC911 \uB300\uC0C1 \uD3EC\uD568 \uBC94\uC704 \uC548 \uC804\uC6D0
\uD68C\uBCF5(\uC801 \uD3EC\uD568) \xB7 \uD53C\uD574 \uC5C6\uC74C(PD \uACB0\uC815
\u2467)"
- skillId: sunqian_p
key: sling_dist_pct
target: radius:3
@ -3672,7 +3674,7 @@ MonoBehaviour:
p2: 0.8
p3: 2
pMask: 7
note: "\uB3C4\uB07C \uBC18\uACBD(\uAE30\uBCF8\uAC12)\xB7\uACF5\uACA9 \uBC30\uC728\xB7\uD295\uAE40
note: "\uB3C4\uB07C \uBC18\uACBD(PD \uD655\uC815)\xB7\uACF5\uACA9 \uBC30\uC728\xB7\uD295\uAE40
\uBC30\uC728"
- skillId: xuhuang_p
key: hit_bleed
@ -3865,7 +3867,8 @@ MonoBehaviour:
p2: 3
p3: 60
pMask: 7
note: "\uBC1C \uC218\xB7\uC5F0\uC18D \uD69F\uC218\xB7\uBD80\uCC44\uAF34 \uAC01(\uAE30\uBCF8\uAC12)"
note: "\uBC1C \uC218\xB7\uC5F0\uC18D \uD69F\uC218\xB7\uBD80\uCC44\uAF34 \uAC01(PD
\uD655\uC815)"
- skillId: xiahouyuan_p
key: multishot
target:
@ -3875,7 +3878,7 @@ MonoBehaviour:
p2: 30
p3: 0
pMask: 3
note: "\uBC1C \uC218\xB7\uBD80\uCC44\uAF34 \uAC01(\uAE30\uBCF8\uAC12)"
note: "\uBC1C \uC218\xB7\uBD80\uCC44\uAF34 \uAC01(PD \uD655\uC815)"
- skillId: guojia_a
key: dmg_pct
target: range
@ -3915,7 +3918,7 @@ MonoBehaviour:
p2: 2.2
p3: 0
pMask: 3
note: "\uB3C5\uAD6C\uB984 \uBC18\uACBD(\uAE30\uBCF8\uAC12)\xB7\uACF5\uACA9 \uBC30\uC728"
note: "\uB3C5\uAD6C\uB984 \uBC18\uACBD(PD \uD655\uC815)\xB7\uACF5\uACA9 \uBC30\uC728"
- skillId: jiaxu_a
key: hit_poison
target:
@ -3931,11 +3934,11 @@ MonoBehaviour:
target:
cond:
dur: 0
p1: 5
p1: 1
p2: 0.02
p3: 1
pMask: 7
note: "\uD134(\uAE30\uBCF8\uAC12 = \uB3C5\uACC4)"
note: "\uD134(\uBBF8\uAE30\uC7AC \u2192 1 \xB7 PD \uACB0\uC815 \u2463)"
- skillId: jiaxu_p
key: poison_stack
target:
@ -4132,11 +4135,11 @@ MonoBehaviour:
target:
cond:
dur: 0
p1: 2
p1: 1
p2: 0.5
p3: 1
pMask: 7
note:
note: "\uD134(\uBBF8\uAE30\uC7AC \u2192 1 \xB7 PD \uACB0\uC815 \u2463)"
- skillId: sunjian_a
key: invuln
target:
@ -4176,28 +4179,39 @@ MonoBehaviour:
p2: 3.5
p3: 0
pMask: 3
note: "\uC6B4\uC11D \uBC18\uACBD(\uAE30\uBCF8\uAC12)\xB7\uACF5\uACA9 \uBC30\uC728"
note: "\uC6B4\uC11D \uBC18\uACBD(PD \uD655\uC815)\xB7\uACF5\uACA9 \uBC30\uC728"
- skillId: zhouyu_a
key: hit_burn
target:
cond:
dur: 0
p1: 3
p1: 1
p2: 0.05
p3: 1
pMask: 7
note:
note: "\uC6B4\uC11D \uBD88\uD0DC\uC6B0\uAE30 \uD134(\uBBF8\uAE30\uC7AC \u2192
1 \xB7 PD \uACB0\uC815 \u2463)"
- skillId: zhouyu_a
key: fire_zone
target:
cond:
dur: 0
p1: 1.5
p2: 3
p2: 1
p3: 1
pMask: 7
note: "\uBD88\uAF43 \uBC18\uACBD\xB7\uD134\xB7\uB2FF\uC744 \uB54C \uACF5\uACA9
\uBC30\uC728"
note: "\uBD88\uAF43 \uBC18\uACBD(PD \uD655\uC815)\xB7\uBD88\uAF43 \uC720\uC9C0
\uD134(\uBBF8\uAE30\uC7AC \u2192 1)\xB7\uB2FF\uC744 \uB54C \uACF5\uACA9 \uBC30\uC728"
- skillId: zhouyu_a
key: zone_burn
target:
cond:
dur: 0
p1: 3
p2: 0.05
p3: 0
pMask: 3
note: "\uBD88\uAF43\uC5D0 \uB2FF\uC73C\uBA74 3\uD134 \uD654\uC0C1(\uC6D0\uBB38)"
- skillId: zhouyu_p
key: skill_hp_cost
target:
@ -4437,7 +4451,7 @@ MonoBehaviour:
p2: 0
p3: 0
pMask: 1
note: "\uCD5C\uB300(\uAE30\uBCF8\uAC12 = \uC7A5\uBE44\xB7\uC5EC\uD3EC)"
note: "\uCD5C\uB300(PD \uD655\uC815 \xB7 \uC7A5\uBE44\xB7\uC5EC\uD3EC)"
- skillId: sunquan_a
key: shot_blast
target:
@ -4447,7 +4461,7 @@ MonoBehaviour:
p2: 1.8
p3: 0
pMask: 3
note: "\uD654\uC0B4\uBE44 \uBC18\uACBD(\uAE30\uBCF8\uAC12)\xB7\uACF5\uACA9 \uBC30\uC728"
note: "\uD654\uC0B4\uBE44 \uBC18\uACBD(PD \uD655\uC815)\xB7\uACF5\uACA9 \uBC30\uC728"
- skillId: sunquan_a
key: hit_confuse
target:
@ -4577,8 +4591,8 @@ MonoBehaviour:
p2: 3
p3: 3
pMask: 7
note: "\uC7A5\uBCBD \uBC18\uD3ED(\uAE30\uBCF8\uAC12)\xB7\uD134\xB7\uB2FF\uC744
\uB54C \uACF5\uACA9 \uBC30\uC728"
note: "\uC7A5\uBCBD \uBC18\uD3ED(PD \uD655\uC815)\xB7\uD134\xB7\uB2FF\uC744 \uB54C
\uACF5\uACA9 \uBC30\uC728"
- skillId: luxun_a
key: hit_burn
target:
@ -4589,6 +4603,16 @@ MonoBehaviour:
p3: 1
pMask: 7
note:
- skillId: luxun_a
key: zone_hits_allies
target:
cond:
dur: 0
p1: 1
p2: 0
p3: 0
pMask: 1
note: "\uC544\uAD70\uB3C4 \uD53C\uD574(PD \uACB0\uC815 \u246C)"
- skillId: luxun_p
key: dmg_pct
target: camp:wu
@ -4618,7 +4642,7 @@ MonoBehaviour:
p2: 1
p3: 0
pMask: 3
note: "\uACF5\uACA9 \uBC30\uC728(\uAE30\uBCF8\uAC12)\xB7\uBC00\uAE30(\uAE30\uBCF8\uAC12)"
note: "\uACF5\uACA9 \uBC30\uC728(PD \uD655\uC815)\xB7\uBC00\uAE30(PD \uD655\uC815)"
- skillId: sunshangxiang_a
key: hit_bleed
target:
@ -4728,7 +4752,8 @@ MonoBehaviour:
p2: 1
p3: 1
pMask: 7
note: "\uAC80\uAE30 \xB7 \uC544\uAD70\uB3C4 \uD53C\uD574 \xB7 \uBC00\uAE30(\uAE30\uBCF8\uAC12)"
note: "\uAC80\uAE30 \xB7 \uC544\uAD70\uB3C4 \uD53C\uD574 \xB7 \uBC00\uAE30(PD
\uD655\uC815)"
- skillId: zhoutai_p
key: hit_confuse
target:
@ -4756,10 +4781,10 @@ MonoBehaviour:
dur: 0
p1: 1
p2: 3
p3: 0
p3: 1
pMask: 7
note: "\uD68C\uC624\uB9AC \uBC18\uD3ED(\uAE30\uBCF8\uAC12)\xB7\uBC00\uAE30(\uAE30\uBCF8\uAC12)\xB7\uACF5\uACA9
\uBC30\uC728(\uD53C\uD574 \uC5C6\uC74C)"
note: "\uD68C\uC624\uB9AC \uBC18\uD3ED\xB7\uBC00\uAE30(PD \uD655\uC815)\xB7\uACF5\uACA9
\uBC30\uC728(PD \uACB0\uC815 \u246D = 100 %)"
- skillId: zhugejin_a
key: hit_confuse
target:
@ -4905,11 +4930,11 @@ MonoBehaviour:
target:
cond:
dur: 0
p1: 5
p1: 1
p2: 0.02
p3: 0.5
pMask: 7
note: "\uD134(\uAE30\uBCF8\uAC12)\xB7\uD655\uB960"
note: "\uD134(\uBBF8\uAE30\uC7AC \u2192 1 \xB7 PD \uACB0\uC815 \u2463)\xB7\uD655\uB960"
- skillId: huaxiong_a
key: dmg_pct
target:
@ -5079,7 +5104,7 @@ MonoBehaviour:
p2: 1.5
p3: 0
pMask: 3
note: "\uB3CC\uC9C4 \uCD08\xB7\uBC00\uCE58\uAE30 \uAC70\uB9AC(\uAE30\uBCF8\uAC12)"
note: "\uB3CC\uC9C4 \uCD08\xB7\uBC00\uCE58\uAE30 \uAC70\uB9AC(PD \uD655\uC815)"
- skillId: dongzhuo_p
key: dmg_taken_pct
target: camp:other
@ -5109,7 +5134,8 @@ MonoBehaviour:
p2: 2
p3: 0
pMask: 3
note: "\uAD11\uC5ED \uD53C\uD574 \uBE44\uC728\xB7\uC778\uC811 \uBC18\uACBD(\uAE30\uBCF8\uAC12)"
note: "\uAD11\uC5ED \uD53C\uD574 \uBE44\uC728\xB7\uC778\uC811 \uBC18\uACBD(PD
\uD655\uC815)"
- skillId: lijue_p
key: action_end_sacrifice
target:
@ -5119,7 +5145,7 @@ MonoBehaviour:
p2: 0.5
p3: 2
pMask: 7
note: "HP \uC18C\uBAA8\xB7\uACF5\uACA9 %\xB7\uC778\uC811 \uBC18\uACBD(\uAE30\uBCF8\uAC12)"
note: "HP \uC18C\uBAA8\xB7\uACF5\uACA9 %\xB7\uC778\uC811 \uBC18\uACBD(PD \uD655\uC815)"
- skillId: yuanshao_a
key: sling_dist_pct
target: range
@ -5295,11 +5321,11 @@ MonoBehaviour:
target:
cond:
dur: 0
p1: 5
p1: 1
p2: 0.02
p3: 1
pMask: 7
note:
note: "\uD134(\uBBF8\uAE30\uC7AC \u2192 1 \xB7 PD \uACB0\uC815 \u2463)"
- skillId: zhurong_p
key: lifesteal
target:
@ -5435,11 +5461,11 @@ MonoBehaviour:
target:
cond:
dur: 0
p1: 5
p1: 1
p2: 0.02
p3: 1
pMask: 7
note:
note: "\uD134(\uBBF8\uAE30\uC7AC \u2192 1 \xB7 PD \uACB0\uC815 \u2463)"
- skillId: zhanglu_a
key: poison_zone
target:
@ -5449,7 +5475,7 @@ MonoBehaviour:
p2: 1
p3: 0
pMask: 3
note: "\uBC18\uACBD(\uAE30\uBCF8\uAC12)\xB7\uD134"
note: "\uBC18\uACBD(PD \uD655\uC815)\xB7\uD134"
- skillId: zhanglu_p
key: zombie
target:

View File

@ -114,7 +114,7 @@ namespace TKS
var hit = Combat.FirstUnitOnArrow(u, from, dir, range, cfg.arrowRadius, u.Faction, out travel, out g);
Vector2 center = hit != null ? hit.Position : from + dir * travel;
yield return Fx.Arrow(from, center, u.Type == UnitType.Strategist ? Fx.StrategistShotColor : Fx.ArrowColor);
float r = e.P;
float r = e.P * SkillMods.Product(u, SkillKeys.SplashRadiusMult, true); // 사마의 응시낭고·보물 광역 배율도(Fable 검토 B3)
Fx.Burst(center, r, ExplosionColor);
o.ShotHit = hit;
foreach (var t in Combat.UnitsInCircle(center, r, u, null))
@ -125,7 +125,7 @@ namespace TKS
var fz = SkillMods.First(u, SkillKeys.FireZone);
var sys = SkillSystem.Current;
if (fz != null && sys != null && sys.Of(u) != null)
sys.AddZone(sys.Of(u), center, center, fz.P, Mathf.RoundToInt(fz.Get(1, 1f)), fz.Get(2), SkillMods.First(u, SkillKeys.HitBurn), new Color(1f, 0.45f, 0.1f, 0.35f));
sys.AddZone(sys.Of(u), center, center, fz.P, Mathf.RoundToInt(fz.Get(1, 1f)), fz.Get(2), ZoneStatus(u), new Color(1f, 0.45f, 0.1f, 0.35f), SkillMods.Has(u, SkillKeys.ZoneHitsAllies));
}
/// <summary>하후연 전광 연사: 부채꼴(p3 도) p1 발 × p2 번 · 화살마다 일반 사격 규칙(첫 유닛 · 아군 오사).</summary>
@ -249,17 +249,31 @@ namespace TKS
Vector2 b = u.Position + dir * Mathf.Max(u.Radius + e.P, Combat.WallTravel(u, u.Position, dir, range));
yield return Fx.Arrow(u.Position, b, new Color(1f, 0.45f, 0.1f));
var sys = SkillSystem.Current;
bool allies = SkillMods.Has(u, SkillKeys.ZoneHitsAllies); // 육손 = 아군도(PD #1112 결정 ⑬)
SkillZone z = null;
if (sys != null && sys.Of(u) != null)
z = sys.AddZone(sys.Of(u), a, b, e.P, Mathf.RoundToInt(e.Get(1, 1f)), e.Get(2, 1f), SkillMods.First(u, SkillKeys.HitBurn), new Color(1f, 0.4f, 0.05f, 0.35f));
foreach (var t in battle.AliveUnits(u.Faction == Faction.Player ? Faction.Enemy : Faction.Player))
z = sys.AddZone(sys.Of(u), a, b, e.P, Mathf.RoundToInt(e.Get(1, 1f)), e.Get(2, 1f), ZoneStatus(u), new Color(1f, 0.4f, 0.05f, 0.35f), allies);
foreach (var t in new List<Unit>(battle.Units))
{
if (t == null || !t.IsAlive || t == u || (t.Faction == u.Faction && !allies)) continue;
if (Combat.SegmentPointDistance(a, b, t.Position) > e.P + t.Radius) continue;
if (z != null) z.Touched.Add(t);
ShotDamage(u, t, Combat.SkillDamage(cfg, u, t, e.Get(2, 1f), rng), false, o);
int dmg = Combat.SkillDamage(cfg, u, t, e.Get(2, 1f), rng); // 아군도 같은 피해(PD 결정 ⑬ · Fable 검토 C4)
ShotDamage(u, t, dmg, false, o);
if (t.Faction == u.Faction && t.IsAlive && sys != null)
{
var bs = ZoneStatus(u);
if (bs != null) sys.ApplyBurn(t, Mathf.RoundToInt(bs.P), bs.Get(1, 0.05f)); // 아군도 화상(명중 상태 이상은 적에게만 붙으므로 직접)
}
}
}
/// <summary>지대가 거는 화상 = zone_burn(주유 불꽃 3턴) · 없으면 그 스킬의 hit_burn(육손 장벽).</summary>
static SkillEffect ZoneStatus(Unit u)
{
return SkillMods.First(u, SkillKeys.ZoneBurn) ?? SkillMods.First(u, SkillKeys.HitBurn);
}
/// <summary>일반 사격 덧붙임: 하후연 삼연시(멀티샷 · 좌우 화살) · 감녕 도탄(맞은 유닛과 가까운 n 기 · 아군 포함) · 장로 독지대.</summary>
IEnumerator ExtraArrows(Unit u, ShotPlan p, ActionOutcome o)
{

View File

@ -92,7 +92,7 @@ namespace TKS
if (skills != null)
{
skills.BeginAction(u, moveOnly, o, dir, slingDist); // 예약 액티브 장착 + 발동 연출 · 돌진 거리 비율(만인지적·강동의 호걸·적토마)
if (skills.Ctx != null && (aimed - target).sqrMagnitude > 1e-4f) skills.Ctx.HitTerrain = true; // 이동 감소 지형을 지남(맹획 남만왕)
if (skills.Ctx != null && CrossesSlowTerrain(u, origin, aimed)) skills.Ctx.HitTerrain = true; // 이동 감소 지형(늪·고지)을 지남(맹획 남만왕 · 조인 철벽 감속은 제외 · Fable 검토 C6)
}
// 슬링샷 돌진 중 = 병종 돌진 포즈 1프레임 고정 · 끝나면 대기 (PD 2026-11-05 #1084)
if (u.View != null) u.View.SetCharging(true);
@ -127,7 +127,7 @@ namespace TKS
yield return RampageRoutine(u, origin, dir, o);
yield break;
}
if (!moveOnly && SkillMods.Has(u, SkillKeys.ShotAsArcher))
if (!moveOnly && (SkillMods.Has(u, SkillKeys.ShotAsArcher) || HasSpecialShot(u))) // 축융 비도 · 주태 검기(보병의 특수 사격 · Fable 검토 A1)
{
yield return ArcherRoutine(u, origin, dir, dist, target, moveOnly, o);
yield break;
@ -315,7 +315,6 @@ namespace TKS
DashEnd(u); // 슬링샷 직진 끝 = 돌진 이펙트 소멸(튕김은 반응 · PD 2026-11-10)
float remaining = Mathf.Max(0f, dist - hitDist);
bool enemy = first.Faction != u.Faction;
bool isFinal = enemy && Combat.EnemyAtPoint(u, target, cfg.finalHitTolerance) == first;
int impact = 0;
if (enemy)
@ -352,13 +351,7 @@ namespace TKS
}
if (!enemy && first.IsAlive) yield return PushedAllyAttack(first, o, u);
if (!enemy) PushContinue(u, remaining); // 고순: 아군을 밀친 뒤 남은 이동력으로 재행동
if (isFinal && u.IsAlive)
{
o.BonusMove = true;
o.BonusMoves = 1;
o.BonusAttack = false;
}
// 목표점 명중 추가 이동 = 제거(PD 2026-11-10 #1112 결정 ⑱ · 보병 특징 = 알까기·연쇄 · 재행동은 스킬로만)
}
/// <summary>고순 함진 돌파(push_continue): 아군·지형 오브젝트를 밀친 뒤 남은 이동 거리만큼 재행동 1회(슬링 상한 = 남은 거리).</summary>
@ -439,7 +432,7 @@ namespace TKS
{
bool pushedDone = false;
Fx.Run(Track(Push(first, dir, push, u, o), () => pushedDone = true));
float recoil = Reach(u, u.Position, -dir, push * cfg.spearRecoilRatio);
float recoil = Reach(u, u.Position, -dir, push * cfg.spearRecoilRatio * (enemy ? SkillMods.AxeBounce(first) : 1f)); // 서황 대부 = 창병 반작용도 ×(Fable 검토 C5)
if (recoil > 0.01f && u.IsAlive)
{
// 반작용: 벽·유닛·장애물에 닿으면 정지 · 피해 없음 · 보는 방향은 유지(밀친 쪽을 본 채 물러남)
@ -853,7 +846,7 @@ namespace TKS
if (p.Target == null) return p;
// 사거리 안이면 제자리 · 밖이면 가장자리가 사거리에 들어올 만큼만 다가간다(접근 허용 거리 상한 · 늪·고지 이동 비용 반영 PD #1097)
float need = Mathf.Clamp(hitDist - range, 0f, Reach(u, origin, dir, u.ArcherMoveAllow));
float need = Mathf.Clamp(hitDist - range, 0f, MoveReach(u, origin, dir, u.ArcherMoveAllow));
p.Approach = need > 0.01f ? Combat.FreeTravel(u, origin, dir, need, true) : 0f;
p.From = origin + dir * p.Approach;
p.To = p.From;
@ -917,7 +910,7 @@ namespace TKS
if (p == null || p.Target == null)
{
// 공격 가능 범위에 적이 없으면 목표점까지 이동 · 쏘지 않는다 (PD 2026-11-04 2차 지시 · #1087 ⑥ 유지) · 장애물 = 튕김 · 늪·고지 = 이동 비용(PD #1097)
if (p == null || p.Teleport <= 0.01f) yield return MoveOrHit(u, origin, dir, Reach(u, origin, dir, dist), o);
if (p == null || p.Teleport <= 0.01f) yield return MoveOrHit(u, origin, dir, MoveReach(u, origin, dir, dist), o);
yield break;
}
@ -954,9 +947,15 @@ namespace TKS
}
Vector2 center = p.HasSplash ? p.SplashCenter : p.To;
float healAll = SkillMods.Sum(u, SkillKeys.SplashHeal, true); // 손건 화친 = 피해 없이 회복만(PD #1112 결정 ⑧)
if (p.Hit != null)
{
if (p.Hit.Faction == u.Faction && AllyHitSpecial(u, p.Hit, p.From, o))
if (healAll > 0f)
{
var hs = SkillSystem.Current;
if (hs != null) hs.Heal(p.Hit, Mathf.RoundToInt(SkillSystem.AtkOf(u) * healAll), u);
}
else if (p.Hit.Faction == u.Faction && AllyHitSpecial(u, p.Hit, p.From, o))
{
// 아군 명중 = 회복·버프(순욱·소교·간옹·미축) · 감녕 = 아군 곁으로 이동 후 재공격 — 피해 없음
}
@ -968,15 +967,13 @@ namespace TKS
{
yield return SplashGimmicks(u, p, o); // 덤불 제거 · 수레 파괴 · 화공 불(PD #1097)
Fx.Burst(center, p.SplashRadius, Fx.SplashColor);
float heal = SkillMods.Sum(u, SkillKeys.SplashHeal, true);
if (heal > 0f)
if (healAll > 0f)
{
// 손건 화친: 광역 = 피해 대신 회복(적 포함)
int amt = Mathf.RoundToInt(SkillSystem.AtkOf(u) * heal);
// 손건 화친: 광역 = 피해 대신 회복(적 포함 · 명중 대상은 위에서 회복)
int amt = Mathf.RoundToInt(SkillSystem.AtkOf(u) * healAll);
var sys = SkillSystem.Current;
foreach (var s in p.Splash)
if (s.IsAlive && sys != null) sys.Heal(s, amt, u);
if (p.Hit != null && p.Hit.IsAlive && p.Hit.Faction == u.Faction && sys != null) sys.Heal(p.Hit, amt, u);
}
else
{

View File

@ -44,6 +44,22 @@ namespace TKS
return Gim ? Layer.CostReach(u, origin, dir, budget) : budget;
}
/// <summary>조준 경로가 지형 이동 감소(늪·고지 오르기)에 걸리는가(맹획 남만왕 재행동 · 지형 무시 유닛도 지형은 「지남」으로 봄).</summary>
static bool CrossesSlowTerrain(Unit u, Vector2 origin, Vector2 aimed)
{
if (!Gim || u == null) return false;
Vector2 d = aimed - origin;
float dist = d.magnitude;
if (dist < 0.001f) return false;
return Layer.CostReach(u, origin, d / dist, dist) < dist - 1e-3f;
}
/// <summary>자기 행동 이동(궁·책 접근·이동만) = 조인 철벽 감속 → 지형 이동 비용(Fable 검토 B2 · 근접 병종은 ReachPoint).</summary>
static float MoveReach(Unit u, Vector2 origin, Vector2 dir, float budget)
{
return Reach(u, origin, dir, SlowZoneReach(u, origin, dir, budget));
}
/// <summary>조인 철벽(zone_slow): 상대 시전자의 행동 반경(기본 슬링 거리) 안을 지나는 구간 = 이동 비용 × (1 + p1).</summary>
static float SlowZoneReach(Unit u, Vector2 origin, Vector2 dir, float budget)
{

View File

@ -138,6 +138,8 @@ namespace TKS
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";
@ -200,7 +202,7 @@ namespace TKS
{ 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 }, { PoisonZone, 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 },

View File

@ -155,8 +155,15 @@ namespace TKS
public string StatusKey;
public SkillEffect Status;
public GameObject View;
/// <summary>같은 편도 닿으면 피해·상태 이상(육손 불 장벽 · PD 2026-11-10 #1112 결정 ⑬).</summary>
public bool HitsAllies;
public readonly HashSet<Unit> Touched = new HashSet<Unit>();
public bool Affects(Unit u)
{
return u != null && (u.Faction != Faction || HitsAllies);
}
public float Distance(Vector2 p)
{
return Combat.SegmentPointDistance(A, B, p);
@ -568,6 +575,16 @@ namespace TKS
s.AtkFlatRounds = 0;
}
// 지속 회복(방통 봉추의 계) = 라운드 감소·만료 전에 — dur n 이면 n 번 회복(Fable 검토 B1)
foreach (var t in TimedEffects)
{
if (t.E.Key != SkillKeys.Hot || t.Faction != side || t.Owner == null || t.Owner.Unit == null) continue;
int amt = Mathf.RoundToInt(AtkOf(t.Owner.Unit) * t.E.P);
foreach (var u in battle.AliveUnits(side))
if (t.Targets == null ? u == t.Owner.Unit : t.Targets.Contains(u))
if (Heal(u, amt, t.Owner.Unit) > 0) any = true;
}
for (int i = TimedEffects.Count - 1; i >= 0; i--)
{
var t = TimedEffects[i];
@ -603,12 +620,14 @@ namespace TKS
if (bank != null && !s.MovedThisRound) s.Bank = Mathf.Min(Mathf.Max(0, Mathf.RoundToInt(bank.P) - 1), s.Bank + 1);
s.MovedThisRound = false;
}
if (summons.Contains(u)) gone.Add(u);
}
foreach (var z in summons)
if (z == null || z.Faction == side) gone.Add(z); // 망령(스킬 항목 없음)은 소환 목록에서 직접
foreach (var z in gone)
{
if (z != null && z.IsAlive) yield return ZombieAct(z); // 망령 = 자기 턴 시작에 1번 공격 후 소멸(PD #1112 결정 ⑩)
summons.Remove(z);
battle.RemoveUnit(z);
if (z != null) battle.RemoveUnit(z);
any = true;
}
@ -641,14 +660,6 @@ namespace TKS
float regen = SkillMods.Sum(u, SkillKeys.RegenPct, true);
if (regen > 0f && Heal(u, Mathf.RoundToInt(u.MaxHp * regen), u) > 0) any = true;
}
foreach (var t in TimedEffects)
{
if (t.E.Key != SkillKeys.Hot || t.Faction != side || t.Owner == null || t.Owner.Unit == null) continue;
int amt = Mathf.RoundToInt(AtkOf(t.Owner.Unit) * t.E.P);
foreach (var u in battle.AliveUnits(side))
if (t.Targets == null ? u == t.Owner.Unit : t.Targets.Contains(u))
if (Heal(u, amt, t.Owner.Unit) > 0) any = true;
}
foreach (var s in entries)
{
var src = s.Unit;
@ -673,7 +684,7 @@ namespace TKS
Zones.RemoveAt(i);
continue;
}
if (z.Faction == side) continue;
if (z.Faction == side && !z.HitsAllies) continue;
z.Touched.Clear();
foreach (var u in battle.AliveUnits(side))
if (z.Distance(u.Position) <= z.Radius + u.Radius * 0.5f)
@ -1003,7 +1014,8 @@ namespace TKS
if (ctx != null && ctx.ZombieFrom.Count > 0 && !Sim.Active)
foreach (var dead in ctx.ZombieFrom)
yield return ZombieRoutine(u, dead);
SpawnZombie(u, dead);
yield return null;
Ctx = null;
battle.NotifyChanged();
@ -1184,7 +1196,7 @@ namespace TKS
Text(d, "무적", SkillFx.GuardColor);
return 0;
}
if (kind != HitKind.Self && kind != HitKind.Dot && ds != null && ds.PassiveEffects != null)
if (kind != HitKind.Self && ds != null && ds.PassiveEffects != null) // 조범 처세 「어떤 피해든」 = 상태 이상·지대 피해 포함(Fable 검토 C3)
{
var ng = Find(ds.PassiveEffects, SkillKeys.NegateHits);
if (ng != null && ds.NegateUsed < Mathf.RoundToInt(ng.P))
@ -1226,7 +1238,13 @@ namespace TKS
if (ds != null && dmg > 0 && HasTimed(ds, SkillKeys.DamageToAtk)) ds.DmgTakenRound += Mathf.Min(dmg, d.Hp);
int before = d.Hp;
if (dmg >= d.Hp && TryRevive(d, ds, before)) return before;
if (dmg >= d.Hp && TryRevive(d, ds, before))
{
// 부활을 부른 타격도 준 쪽 효과(흡혈·첫 명중·연속 기절·명중 상태 이상) · 맞은 쪽 반응 — 처치는 아님(Fable 검토 C7)
if (by != null && by.Faction != d.Faction) OnDealt(by, d, before, kind, crit);
if (d.IsAlive && by != null && by.IsAlive && by.Faction != d.Faction && kind == HitKind.Attack) OnAttacked(d, by);
return before;
}
d.TakeDamage(dmg);
int dealt = before - d.Hp;
if (by != null && by.Faction != d.Faction) OnDealt(by, d, dealt, kind, crit);
@ -1384,14 +1402,22 @@ namespace TKS
ApplyBleedStatus(d, Mathf.RoundToInt(h.E.P), h.E.Get(1, 0.5f));
NoteHit(h);
}
// 중독 = 한 번 명중에 1회만(액티브·패시브가 함께 걸려도 중첩 +1 · 가장 긴 턴·큰 비율 · Fable 검토 C1)
int pTurns = 0;
float pPct = 0f;
foreach (var h in SkillMods.Get(by, SkillKeys.HitPoison, d, crit))
if (Roll(h.E.Get(2, 1f)))
{
int max = 1;
foreach (var ps in SkillMods.Get(by, SkillKeys.PoisonStack)) max = Mathf.Max(max, Mathf.RoundToInt(ps.E.P));
ApplyPoison(d, Mathf.RoundToInt(h.E.P), h.E.Get(1, 0.02f), max);
pTurns = Mathf.Max(pTurns, Mathf.RoundToInt(h.E.P));
pPct = Mathf.Max(pPct, h.E.Get(1, 0.02f));
NoteHit(h);
}
if (pTurns > 0)
{
int max = 1;
foreach (var ps in SkillMods.Get(by, SkillKeys.PoisonStack)) max = Mathf.Max(max, Mathf.RoundToInt(ps.E.P));
ApplyPoison(d, pTurns, pPct, max);
}
foreach (var h in SkillMods.Get(by, SkillKeys.HitBurn, d, crit))
if (Roll(h.E.Get(2, 1f)))
{
@ -1497,22 +1523,33 @@ namespace TKS
if (ctx != null && ctx.Actor == by && Eff(s, SkillKeys.Zombie) != null && !Sim.Active) ctx.ZombieFrom.Add(d);
}
/// <summary>장로 한중의 교주: 처치한 적이 체력 1 로 같은 편이 되어 가장 가까운 상대를 1번 공격(조작 불가) · 그 진영 다음 턴 시작에 사라짐.</summary>
IEnumerator ZombieRoutine(Unit owner, Unit dead)
/// <summary>
/// 장로 한중의 교주: 처치한 적이 체력 1 로 같은 편 망령이 된다(조작 불가 · 상대 턴 동안 공격받을 수 있음) →
/// 그 진영 다음 턴 시작(TurnBegin)에 가장 가까운 상대를 1번 공격하고 사라짐(PD 2026-11-10 #1112 결정 ⑩).
/// </summary>
void SpawnZombie(Unit owner, Unit dead)
{
if (owner == null || dead == null || battle.Board == null) yield break;
if (owner == null || dead == null || battle.Board == null) return;
var s = Of(owner);
var e = Eff(s, SkillKeys.Zombie);
var z = battle.SpawnUnit(dead.Type, owner.Faction, dead.Position, "망령 " + dead.DisplayName, 1f, 1f, false, dead.ArtId);
z.Atk = dead.Atk;
z.Hp = Mathf.Max(1, Mathf.RoundToInt(e != null ? e.P : 1f));
z.MarkActed();
summons.Add(z);
if (z.View != null) z.View.Refresh();
Text(z, "망령", SkillFx.NameColor);
if (s != null) NotePassive(s, s.Passive);
AddLog("망령 " + dead.DisplayName + " — 다음 턴 시작에 1번 공격 후 소멸");
}
/// <summary>망령의 자동 공격 1회(가장 가까운 상대 쪽으로 슬링 최대 거리까지).</summary>
IEnumerator ZombieAct(Unit z)
{
if (z == null || !z.IsAlive || battle.Board == null) yield break;
Unit foe = null;
float best = float.MaxValue;
foreach (var t in battle.AliveUnits(Other(owner.Faction)))
foreach (var t in battle.AliveUnits(Other(z.Faction)))
{
float dd = Vector2.Distance(z.Position, t.Position);
if (dd < best)
@ -1529,7 +1566,6 @@ namespace TKS
if (aim.magnitude > max) aim = aim.normalized * max;
var o = new ActionOutcome();
yield return battle.Resolver.Resolve(z, battle.Board.ClampInside(z.Position + aim, z.Radius), false, o);
z.MarkActed();
Ctx = prevCtx;
}
@ -1692,9 +1728,9 @@ namespace TKS
// ---------- 지대(주유 불꽃 · 육손 불 장벽 · 장로 독지대) ----------
public SkillZone AddZone(UnitSkills owner, Vector2 a, Vector2 b, float radius, int rounds, float ratio, SkillEffect status, Color color)
public SkillZone AddZone(UnitSkills owner, Vector2 a, Vector2 b, float radius, int rounds, float ratio, SkillEffect status, Color color, bool hitsAllies = false)
{
var z = new SkillZone { Owner = owner, Faction = owner.Unit.Faction, A = a, B = b, Radius = Mathf.Max(0.2f, radius), RoundsLeft = Mathf.Max(1, rounds), Ratio = ratio, Status = status, StatusKey = status != null ? status.Key : null };
var z = new SkillZone { Owner = owner, Faction = owner.Unit.Faction, A = a, B = b, Radius = Mathf.Max(0.2f, radius), RoundsLeft = Mathf.Max(1, rounds), Ratio = ratio, Status = status, StatusKey = status != null ? status.Key : null, HitsAllies = hitsAllies };
if (!Sim.Active)
{
var root = new GameObject("SkillZone");
@ -1722,17 +1758,17 @@ namespace TKS
/// <summary>지대 닿음: 상대 = 주인 공격력 × 배율 피해 + 지대 상태 이상(행동마다 · 턴마다 1번).</summary>
void ZoneTouch(SkillZone z, Unit u)
{
if (u == null || !u.IsAlive || u.Faction == z.Faction || !z.Touched.Add(u)) return;
if (u == null || !u.IsAlive || !z.Affects(u) || !z.Touched.Add(u)) return;
var src = z.Owner != null ? z.Owner.Unit : null;
if (z.Ratio > 0f && src != null)
{
int d = Mathf.Max(1, Mathf.RoundToInt(Combat.SkillDamage(Cfg, src, u, z.Ratio, battle.Rng)));
int d = Mathf.Max(1, Mathf.RoundToInt(Combat.SkillDamage(Cfg, src, u, z.Ratio, battle.Rng))); // 아군도 같은 피해(PD 결정 ⑬)
d = Hit(u, d, src, HitKind.Dot);
Text(u, (z.StatusKey == SkillKeys.HitPoison ? "독지대 −" : "불꽃 −") + d, new Color(1f, 0.55f, 0.25f));
}
if (z.Status != null && u.IsAlive)
{
if (z.StatusKey == SkillKeys.HitBurn) ApplyBurn(u, Mathf.RoundToInt(z.Status.P), z.Status.Get(1, 0.05f));
if (z.StatusKey == SkillKeys.HitBurn || z.StatusKey == SkillKeys.ZoneBurn) ApplyBurn(u, Mathf.RoundToInt(z.Status.P), z.Status.Get(1, 0.05f));
else if (z.StatusKey == SkillKeys.HitPoison) ApplyPoison(u, Mathf.RoundToInt(z.Status.P), z.Status.Get(1, 0.02f), 1);
}
}
@ -1750,7 +1786,7 @@ namespace TKS
foreach (var kv in segs)
{
var u = kv.Key;
if (u == null || !u.IsAlive || u.Faction == z.Faction) continue;
if (u == null || !u.IsAlive || !z.Affects(u)) continue;
var s = kv.Value;
if (SegSegDistance(new Vector2(s.x, s.y), new Vector2(s.z, s.w), z.A, z.B) <= z.Radius + u.Radius * 0.5f) ZoneTouch(z, u);
}
@ -1803,7 +1839,7 @@ namespace TKS
s.ReadyTurn = battle.TurnNumber + CooldownOf(s);
s.Casting = true;
var prevCtx = Ctx;
Ctx = new ActionCtx { Actor = u, Origin = u.Position, Seq = ++s.ActionSeq };
Ctx = new ActionCtx { Actor = u, Origin = u.Position, Seq = s.ActionSeq }; // 즉시형은 행동 번호를 올리지 않음(장비 연속 판정 · Fable 검토 C2)
var moved = new Dictionary<Unit, float>();
foreach (var e in s.ActiveEffects)
{
@ -1934,7 +1970,7 @@ namespace TKS
void AoeDrain(UnitSkills s, SkillEffect e)
{
var u = s.Unit;
float r = SkillMods.BaseReach(u);
float r = SkillMods.BaseReach(u) * SkillMods.Product(u, SkillKeys.SplashRadiusMult, true); // 응시낭고 광역 배율(Fable 검토 B3)
int total = 0;
Fx.Burst(u.Position, r, Fx.SplashColor);
foreach (var t in battle.AliveUnits(Other(u.Faction)))
@ -2019,7 +2055,7 @@ namespace TKS
var pick = pool[battle.Rng.Next(pool.Count)];
pool.Remove(pick);
if (pick.ActedThisTurn) pick.GrantReAction();
else Of(pick).ReactCredits++;
else Ensure(pick).ReactCredits++; // 스킬 없는 병사도(Fable 검토 A2)
Text(pick, "재행동", SkillFx.NameColor);
}
}

View File

@ -95,7 +95,7 @@ namespace TKS.Tests
// ---------- 보병 ----------
[UnityTest]
public IEnumerator Infantry_HitsEnemy_StopsAtContact_PushesIt_BonusMoveOnFinalHit()
public IEnumerator Infantry_HitsEnemy_StopsAtContact_PushesIt_NoBonusMove()
{
yield return Fresh();
var inf = bm.SpawnUnit(UnitType.Infantry, Faction.Player, new Vector2(0f, -3f), "보병");
@ -106,7 +106,7 @@ namespace TKS.Tests
Assert.Contains(foe, o.Attacked);
Assert.Less(foe.Hp, foe.MaxHp, "부딪힌 적을 공격");
Assert.IsTrue(o.BonusMove, "최종 목표점 명중 → 추가 이동");
Assert.IsFalse(o.BonusMove, "목표점 명중 추가 이동 = 제거(PD #1112 결정 ⑱)");
float remaining = CastContact(inf, foe); // 당긴 거리 3 − 접촉까지 거리 = 남은 힘
Assert.AreEqual(contactY - remaining * cfg.collisionSelfBounceRatio, inf.Position.y, 0.1f, "보병 자신도 반대 방향으로 튕긴다(PD #1081 · 남은 힘 × 비율)");
Assert.Contains(foe, o.Pushed, "부딪힌 유닛은 밀려난다");

View File

@ -412,6 +412,138 @@ namespace TKS.Tests
Assert.Greater(bm.Skills.StatusOf(b).BurnTurns, 0, "화상");
}
// ---------- PD 결정 반영(2026-11-10 #1112 · ⑧ ⑩ ⑬ ⑭) ----------
[UnityTest]
public IEnumerator Firewall_HitsAlliesToo()
{
yield return Fresh();
var lx = Spawn(UnitType.Strategist, Faction.Player, 0f, -5f, "육손");
Give(lx, "luxun");
var ally = Spawn(UnitType.Infantry, Faction.Player, 0f, -3f, "아군");
var foe = Spawn(UnitType.Infantry, Faction.Enemy, 0f, -1f, "적");
Begin();
int a0 = ally.Hp, f0 = foe.Hp;
var o = new ActionOutcome();
yield return ActArmed(lx, lx.Position + Vector2.up * 2f, o);
Assert.Less(foe.Hp, f0, "적 피해");
Assert.Less(ally.Hp, a0, "아군도 피해(결정 ⑬)");
Assert.Greater(bm.Skills.StatusOf(ally).BurnTurns, 0, "아군도 화상");
Assert.AreEqual(1, bm.Skills.Zones.Count, "장벽 지대");
Assert.IsTrue(bm.Skills.Zones[0].HitsAllies);
}
[UnityTest]
public IEnumerator SplashHeal_HealsTargetWithoutDamage()
{
yield return Fresh();
var sq = Spawn(UnitType.Strategist, Faction.Player, 0f, -4f, "손건");
Give(sq, "sunqian");
var foe = Spawn(UnitType.Infantry, Faction.Enemy, 0f, -1f, "적");
Begin();
foe.Hp = foe.MaxHp / 2;
int f0 = foe.Hp;
var o = new ActionOutcome();
yield return ActArmed(sq, foe.Position, o);
Assert.Greater(foe.Hp, f0, "명중 대상도 피해 없이 회복(결정 ⑧)");
Assert.AreEqual(0, o.DamageDealt);
}
[UnityTest]
public IEnumerator Whirl_DealsDamageAndPushes()
{
yield return Fresh();
var zj = Spawn(UnitType.Strategist, Faction.Player, 0f, -5f, "제갈근");
Give(zj, "zhugejin");
var foe = Spawn(UnitType.Infantry, Faction.Enemy, 0f, -2f, "적");
Begin();
int f0 = foe.Hp;
float y0 = foe.Position.y;
var o = new ActionOutcome();
yield return ActArmed(zj, zj.Position + Vector2.up * 2f, o);
Assert.Less(foe.Hp, f0, "공격력 × p3 피해(결정 ⑭)");
Assert.Greater(foe.Position.y, y0 + 0.5f, "진행 방향으로 밀림");
Assert.IsTrue(SkillStatus.Confused(foe), "혼란");
}
[UnityTest]
public IEnumerator Zombie_ActsAtNextOwnTurnThenVanishes()
{
yield return Fresh();
var zl = Spawn(UnitType.Strategist, Faction.Player, 0f, -5f, "장로");
Give(zl, "zhanglu");
var victim = Spawn(UnitType.Infantry, Faction.Enemy, 0f, -2f, "약한 적");
var other = Spawn(UnitType.Infantry, Faction.Enemy, 3f, 1f, "다른 적");
Begin();
victim.Hp = 1;
int other0 = other.Hp;
var o = new ActionOutcome();
yield return Act(zl, victim.Position, o);
Assert.IsFalse(victim.IsAlive);
Unit zombie = null;
foreach (var u in bm.Units)
if (u != null && u.IsAlive && SkillSystem.IsSummon(u)) zombie = u;
Assert.IsNotNull(zombie, "망령 생성");
Assert.AreEqual(Faction.Player, zombie.Faction);
Assert.AreEqual(other0, other.Hp, "처치 직후에는 공격하지 않음(결정 ⑩)");
yield return bm.Skills.TurnBegin(Faction.Player);
Assert.IsFalse(SkillSystem.IsSummon(zombie) && zombie != null && zombie.IsAlive, "자기 턴 시작에 1번 행동 후 소멸");
}
// ---------- Fable 검토 지적 수정(2026-11-10 · A1 · A2 · B1) ----------
[UnityTest]
public IEnumerator Infantry_SwordWave_PiercesLine()
{
yield return Fresh();
var zt = Spawn(UnitType.Infantry, Faction.Player, 0f, -5f, "주태");
Give(zt, "zhoutai");
var a = Spawn(UnitType.Infantry, Faction.Enemy, 0f, -3f, "적1");
var b = Spawn(UnitType.Infantry, Faction.Enemy, 0f, -1.5f, "적2");
Begin();
Vector2 start = zt.Position;
int a0 = a.Hp, b0 = b.Hp;
var o = new ActionOutcome();
yield return ActArmed(zt, zt.Position + Vector2.up * 2f, o);
Assert.IsTrue(o.Fired, "보병 검기 = 사격");
Assert.Less(a.Hp, a0);
Assert.Less(b.Hp, b0, "직선 위 전원");
Assert.Less(Vector2.Distance(zt.Position, start), 0.05f, "주태는 제자리");
}
[UnityTest]
public IEnumerator GrantReaction_ToSoldierWithoutSkills()
{
yield return Fresh();
var gj = Spawn(UnitType.Strategist, Faction.Player, 0f, -3f, "곽가");
var s = Give(gj, "guojia");
var soldier = Spawn(UnitType.Infantry, Faction.Player, 1.5f, -3f, "병사");
Begin();
Assert.IsNull(bm.Skills.Of(soldier), "스킬 없는 병사");
yield return bm.Skills.Instant(s);
Assert.IsTrue(bm.Skills.TakeReaction(soldier), "행동 안 한 병사 = 행동 뒤 재행동");
}
[UnityTest]
public IEnumerator Hot_HealsEveryRoundForDuration()
{
yield return Fresh();
var pt = Spawn(UnitType.Strategist, Faction.Player, 0f, -3f, "방통");
var s = Give(pt, "pangtong");
var ally = Spawn(UnitType.Infantry, Faction.Player, 1.5f, -3f, "아군");
Begin();
int rounds = Eff("pangtong_a", SkillKeys.Hot).Dur;
yield return bm.Skills.Instant(s);
int heals = 0;
for (int i = 0; i < rounds + 1; i++)
{
ally.Hp = 1;
yield return bm.Skills.TurnBegin(Faction.Player);
if (ally.Hp > 1) heals++;
}
Assert.AreEqual(rounds, heals, "지속 턴 수만큼 회복");
}
// ---------- 회복 · 정화 ----------
[UnityTest]

View File

@ -45,7 +45,7 @@ Unity.exe -projectPath <proj> -executeMethod TKS.EditorTools.ProjectSetup.AutoPl
- 전투 수치 SOT = `Assets/Resources/BalanceConfig.asset`(Inspector 조정 · 최초 시드만 `Assets/Scripts/Editor/BalanceDefaults.cs`). 코드·테스트에 수치를 직접 적지 않는다(C45).
- **아웃게임 SOT = `Assets/Data/OutGame/*.csv`(12장 · 기획 `공유/기획팀_산출물/삼국지슬링샷/tables/` 사본 · utf-8-sig · 2026-11-05 #1093 A)** — 영웅·병사(`heroes.csv` · 구 `BalanceConfig.heroes[]` 대체) · 레벨·승급·진화·장비·뽑기·보상·재화·신규 유저 초기값(`economy.csv` start_*). 고친 뒤 메뉴 `TKS/Import OutGame Data (아웃게임 데이터 임포트)`(`Editor/DataImporter` · 오류 시 자산 불변) → `Resources/OutGame/` 9 자산. 표를 바꾸면 기획 `tables/` 도 같이.
- **스킬(2026-11-10 #1112 전면 개편 · PD 엑셀 「장수 목록」 새 기획 144개)** — 수치 SOT = **`Assets/Data/OutGame/skill_effects.csv`(효과 1줄 = `skill_id · key · target · cond · dur · p1~p3` + 한글 주석 열 `effect_ko · p1_ko~p3_ko` = 밸런싱용 · 게임은 안 읽음)** · `skills.csv` = 이름·발동(next_action|instant|always)·쿨·설명 · `effect_key` = 효과 키 목록(p 칸 비움) · `heroes.csv gender`(m|f = 남성·여성 조건). 원본 = 기획 `tables/`(생성기 `_tables_t1.py` SKILL_EFFECTS · KEY_DOC 주석 사전 · 이름·설명 = `영웅_리스트_스킬.md` · 실행 뒤 `economy.csv`·`gacha.csv` 는 git 되돌림 = 생성기보다 손으로 늘린 판이 최신). 처리기 = `Runtime/Skills/`: `SkillKeys`(121종 · 레벨 계수 칸) · `SkillMods`(대상 칸 자신/allies/camp/radius/range/aura · 조건 칸 crit/vs_*/turn_le/armed · 공격·피해·치명타·반격·슬링 질의) · `SkillSystem`(쿨·예약 · 시한 효과 = 라운드(주인 진영 턴 시작마다 −1) · 피해 적용 `Hit(d, dmg, by, HitKind)` = 무적→무효화→호위→부활→흡혈·명중 상태 이상→처치 보상 · 재행동 `ReactCredits` · 즉시형 · `TurnBegin(side)` = 상대 턴 끝 회복·정화 + 중독·화상·회복·지대 · 행동 중 탭 `WaitTap`(조조·하후돈 · 테스트 `AutoTap`) · 지대 `SkillZone`) · `SkillStatus`(혼란·출혈·중독·화상 · 기절 = 기믹 `GimmickLayer.Stun` 재사용) · 특수 이동 = `ActionResolver`(관통·핀볼·복귀·교환·끌어오기·난동·반복) · 특수 사격 = `ActionResolver.Skills.cs`. 가상 실행 = `SkillSystem.TakeState/RestoreState`(Sim). 「1 m」 = 전장 1 칸 · 「행동 반경」 = 기본 슬링 거리(PD 확인 대상). 테스트 = `Tests/PlayMode/SkillTests`(효과 묶음 19). 캡처 = `-executeMethod TKS.EditorTools.DataImporter.CaptureSkills -skillDir <dir>`.
- **스킬(2026-11-10 #1112 전면 개편 · PD 엑셀 「장수 목록」 새 기획 144개)** — 수치 SOT = **`Assets/Data/OutGame/skill_effects.csv`(효과 1줄 = `skill_id · key · target · cond · dur · p1~p3` + 한글 주석 열 `effect_ko · p1_ko~p3_ko` = 밸런싱용 · 게임은 안 읽음)** · `skills.csv` = 이름·발동(next_action|instant|always)·쿨·설명 · `effect_key` = 효과 키 목록(p 칸 비움) · `heroes.csv gender`(m|f = 남성·여성 조건). 원본 = 기획 `tables/`(생성기 `_tables_t1.py` SKILL_EFFECTS · KEY_DOC 주석 사전 · 이름·설명 = `영웅_리스트_스킬.md` · 실행 뒤 `economy.csv`·`gacha.csv` 는 git 되돌림 = 생성기보다 손으로 늘린 판이 최신). 처리기 = `Runtime/Skills/`: `SkillKeys`(121종 · 레벨 계수 칸) · `SkillMods`(대상 칸 자신/allies/camp/radius/range/aura · 조건 칸 crit/vs_*/turn_le/armed · 공격·피해·치명타·반격·슬링 질의) · `SkillSystem`(쿨·예약 · 시한 효과 = 라운드(주인 진영 턴 시작마다 −1) · 피해 적용 `Hit(d, dmg, by, HitKind)` = 무적→무효화→호위→부활→흡혈·명중 상태 이상→처치 보상 · 재행동 `ReactCredits` · 즉시형 · `TurnBegin(side)` = 상대 턴 끝 회복·정화 + 중독·화상·회복·지대 · 행동 중 탭 `WaitTap`(조조·하후돈 · 테스트 `AutoTap`) · 지대 `SkillZone`) · `SkillStatus`(혼란·출혈·중독·화상 · 기절 = 기믹 `GimmickLayer.Stun` 재사용) · 특수 이동 = `ActionResolver`(관통·핀볼·복귀·교환·끌어오기·난동·반복) · 특수 사격 = `ActionResolver.Skills.cs`. 가상 실행 = `SkillSystem.TakeState/RestoreState`(Sim). PD 결정 18건(2026-11-10 · 대화로그 `2026-11-10_스킬구현.md`): 「1 m」 = 전장 1 칸 · 「행동 반경」 = 기본 슬링 거리 · 기획에 없는 지속 턴 = 1 · 출혈 = 슬링 최대 거리 이동 시 최대 HP 50 % · 망령 = 다음 자기 턴 시작에 1번 공격 후 소멸 · 육손 불 장벽 = 아군도 · 손건 화친 = 피해 없이 회복만 · 보병 목표점 추가 이동 제거. 테스트 = `Tests/PlayMode/SkillTests`(효과 묶음 26 · PD 결정·Fable 검토 반영 포함). 캡처 = `-executeMethod TKS.EditorTools.DataImporter.CaptureSkills -skillDir <dir>`.
- **아웃게임 2차(2026-11-05~06 #1093 C)** — 표 10장 추가(`training` · `training_ranks` · `patrol` · `dev_tree` · `treasures` · `treasure_sets` · `chests`(+ iron/buy 열) · `tower` · `dungeons`(+ reward_amount) · `arena`(+ 상점 키)) + `economy.csv` C 키 24 → 임포트 자산 18(A 9 + C 9 · `OutGameTables.C.cs` 검증). 코드 = `OutGame/Domestic/`(`TrainingRules` 훈련 · `PatrolRules` 순찰 · `DevRules` 개발 효과 키 → 적용 지점 · `DomesticScreen`) · `OutGame/Treasure/`(`TreasureRules` 보유·세트·강화·조건 카운터·상자 · `TreasureScreen`) · `OutGame/Arena/`(`ArenaRules` 탑·던전·투기장·적장 · `ArenaScreen`). 스탯 = §3-2 × (1 + 훈련(병종·항목)) × (1 + 보물(항목)) = `HeroRules.Compute(…, save)` · 보물 crit/range/splash = `BattleManager.SideEffectsProvider` → `SkillMods.Get` 진영 효과(`side_crit_pct` · `range_mult` · `splash_radius_mult`) · 조건 효과 카운터 = `Runtime/BattleEvents.Raise`(전투 코드 1줄씩 · 아군만) · 연무장 전투 = `BattleManager.StartMode(BattleMode)`(적 편성 · 제한 턴 · 결과 탭 = `onExit`) → `OutGameSession.OnModeEnd`. 테스트 = `Tests/PlayMode/OutGameCTests`. 캡처 = `-executeMethod TKS.EditorTools.DataImporter.CaptureC -cDir <dir>`(사본 · 10장).
- **영웅 72명(PD #1108 · 2026-11-10)** — heroes 87행(영웅 72 + 병사 15) · skills 144 · skill_effects 288 · 옛 키 체계(51+4종 · 견제·관통 배율 등)는 #1112 에서 폐기.
- **지형 기믹 레이어(PD #1097 · 2026-11-06 세션 D)** — SOT = `Assets/Data/Gimmicks/{gimmicks,stage_gimmicks,tutorial_tips}.csv`(기획 `tables/` 사본 · utf-8-sig) → 메뉴 `TKS/Import Gimmicks (기믹 임포트)`(`Editor/GimmickImporter` · 오류 시 자산 불변 · `ai_weights.csv` 도 함께) → `Resources/Gimmicks/GimmickDb`·`StageGimmickTable` · `Resources/AI/AiWeights`. 전투 시작 = `GimmickLayer.Build(stage)`(장-번호 배치 · 배경 위 · 유닛 아래 · 장애물 = 콜라이더 + `GimmickBody` · 지대 = 모양 스윕 · 강 = 늪처럼 통과하는 지대(강 안 ×p3 · 다리 구간 = 효과 없음 · 강가·다리에서 밀려 강물에 들면 빠짐 · PD 2026-11-06 개정) · 겹친 유닛은 빈 자리로). 전투 코드는 질의만: `Combat.FreeTravel`(장애물 = 벽 · 숨은 함정 정지) · `FirstUnitOnArrow`(pass/block/destroy) · `Combat.Damage`(군기 공 · 고지 근접 피격 · 안개 원거리 피격 ×p1 · 책사 광역이 그 반경 안개를 걷음) · `SkillMods.Range`(고지 사거리) · `BattleManager` 턴 시작 `TurnStart`(군기·중독·불·행동 불가). 충돌 반응·폭발·굴림·미끄러짐·지대 = `Gimmicks/ActionResolver.Gimmicks.cs`(partial). 배치 도구 = `TKS/Gimmick Painter (기믹 배치)`. 테스트 = `Tests/PlayMode/GimmickTests` · 캡처 = `-executeMethod TKS.EditorTools.GimmickImporter.Capture -gimmickDir <dir>`(사본).
@ -84,7 +84,7 @@ UI 를 새로 만들거나 고칠 때 **반드시** 이 구조를 따른다(어
- **IB(쿠로네코) 이펙트 시험(현재 기본 공격 · PD 2026-11-10 「내가 원한 비주얼은 이런게 아니야(이노센트베인 영상) → 우선 IB 이펙트를 그대로 써서 확인 · 나중에 구조에 맞게 새로 그림(화풍 통일)」)**: IB 슬링샷 발사 `UnitVisualEffectControl.ShowBoosterFX()` 와 같은 구성 — `ef_booster`(앞 빛 물결 2장 + 가시 · 0.2초 반복 맥동 · 유닛 위 · 이동 끝에 바로 지움 = IB Breaking 때 Kill) · `ef_speed_tail`(꼬리 0.6초 + 화살표 입자 · 유닛 아래 · 끝나면 꼬리가 줄며 사라짐 — `SkillVfx.Stop` 이 트레일 길이만큼 기다림) · `ef_booster_dust`(출발 먼지 1번) · 타격 `ef_normal_hit`. 원본 = `Assets/VFX/IB/`(쿠로네코 `E:\NerdNavis\Kuroneko\KuronekoClient` 에서 `Tools/wl_vfx_import.py copy … --wl <쿠로네코> --dest Assets/VFX/IB --skip-scripts` · GUID 유지 · 무수정) · 사본 = `Resources/Fx/TKS_Fx_IB_*`(`Tools/make_ib_fx_copies.cs` — IB 전용 스크립트 부품 제거 · 정렬 레이어 Default · 방향 있는 것은 감싸는 루트 + 안쪽 Z −90°(IB 정면 +Y → 이 게임 +X) · 소리 이벤트 받는 곳 `IbFxAnimEvents`(아무것도 안 함 · 없으면 재생마다 콘솔 오류)). 셰이더 = `Fingar/Additive`(더하기 섞기 · 빌트인 그대로). 2D 돌진 3차 행은 표에 `#` 주석(되돌리기). **진영색(PD 「진영 색을 입히고」)** = `TKS_Fx_IB_Booster_<진영>`(스프라이트 색의 색상만 진영색 · 채도·밝기 유지) · `TKS_Fx_IB_SpeedTail_<진영>`(꼬리 그림 `Assets/VFX/IB/_TKS/Tail_Basic02_<진영>.png` = `Tools/make_ib_camp_textures.py` · 재질 같은 폴더 · 화살표 입자 색) — 둘 다 `make_ib_fx_copies.cs` 가 `Tools/dash2d_camps.csv` 로 만듦 · 원색 사본 `TKS_Fx_IB_Booster` · `SpeedTail` 은 비교용으로 남음(표에서 안 씀). **사라지는 시점(PD 「멈춘 이후 뒤늦게 이펙트가 사라짐 · 위치 안 맞음」)** = 속도 꼬리 `f_fade` 0.12 — 멈춘 자리에서 꼬리째 흐려짐(`SkillVfxFade` 가 트레일 색 그러데이션 불투명도도 낮춤 · 전에는 0.6초 꼬리 머리가 기병 돌격 끝자리에 남아 복귀 중에도 보였음). **타격** = 현재 없음(PD 2026-11-10 「적이 피격되었을 때 히트 이펙트는 제거 · 어떤 히트 이펙트를 쓸지 알려줄게」 · IB NormalHit · BounceHit 행은 표에 `#` 주석). **기준점 `e_anchor` = dash**(빛 물결 · 꼬리 · PD 「복귀할 때 이펙트가 캐릭터보다 위쪽에 생겨 안 보임 → 유닛 바닥에」) = 위·옆으로 갈 때 몸 가운데 · 아래로 갈수록 발 쪽(곧장 아래 = 발). **흙먼지** = WL 창 돌진 흙먼지 `TKS_Fx_SpearRushDust`(0.15초마다 발밑 · PD 「복귀할 때 흙먼지가 너무 세서 뭉개짐 → WL 흙먼지로」 · IB 출발 먼지 행은 `#` 주석).
- **방향 결정 UI = IB 이식(PD 2026-11-10 「IB 와 같이 슬링샷 조작 시 방향 결정 UI 등을 그대로 이식」)**: `TKS.IbAimArrow`(IB `GameTouchArrow` 동작 · 프리팹 `Resources/Fx/TKS_Fx_IB_GameArrow` = 원본 `Assets/VFX/IB/AssetResources/Game/GameArrow` 사본) — 누르면 유닛 둘레 고리 + 퍼지는 고리 3개(3초 · 1초 간격) · 당기면 하늘색 화살표가 쏠 방향으로 돌고 당긴 세기만큼 길어짐(0.5~1.5 · 최소 당김 → 슬링샷 최대 거리) · 화살 끝이 전장 밖이면 안으로 · 놓으면 숨김. 전에 쓰던 조준선 · 당김선은 끔(`SlingshotInput.ShowPreview` · IbAimArrow 가 없을 때만 예전 선). 목표 고리 · 강조 · 궁병 화살 경로선 · 기믹 예상 궤적은 그대로. 화살표 색 = IB 공격 종류 3(하늘색) 하나.
- **여포 크기(PD 2026-11-10 「왜 여포는 다른 기병보다 작지?」)**: 말 탄 유닛은 머리 끝 상한(BalanceConfig.mountedArtMaxTop 1.3 × 표준 키)에 맞춰 줄어드는데, `dz_boss_lvbu` 의 몸 높이(`meta.json` bodyHeightPx · `art_size.csv` body_px)가 머리 깃털 끝까지 819 px 라 몸 전체가 더 줄었음 → 왕관 끝 ~ 발 718 px(front_idle 실측 · 깃털 제외 · 다른 기병의 투구 끝 기준과 같은 규칙)로 고침 → 배율 0.2381 → 0.2716(+14 %). 원본 백업 = 세션 scratchpad. **다른 PC 에서 그림을 다시 export 하면 819 로 되돌아갈 수 있음**(export 규칙 = 불투명 폭 30 % 행 — 깃털이 넓어서 안 걸러짐).
- **근접 3병종 특징 = 한 줄 정의(PD 2026-11-10 직접 지시)**: **보병** = 적을 밀치고 튕겨나며 튕기면서 다른 적을 추가로 공격(알까기 + 연쇄 · #1098 그대로 · 목표점 명중 추가 이동 1회는 유지 = PD 확인 대상) · **창병** = 적을 크게 밀치지만 자신은 적게 밀림(`spearPushRatio` 1.5 > 보병 `collisionPushRatio` 1.0 · 반작용 남은 거리 × 0.3 < 보병 자기 튕김 0.5) · **창병 대기(견제) 제거**(「유저가 인지하기 어려움」 · 목표점 명중해도 `SetOverwatch` 안 함 · HUD 「견제 반경·대기 중」 문구 삭제) · **기병** = 적을 관통해 이동 · **목표점 명중 시 제자리 복귀 제거**(「유저가 인지하기 어려움」 · `PreviewCavalryReturn` · 조준 때 복귀 영역 `ShowReturnZones` 삭제 · AI 가중치 `cav_return`·`cav_stranded` 삭제). 견제·복귀 스킬 = #1112 PD 새 기획으로 전부 재설계(견제 없음 · 복귀는 스킬 효과 `return_on_hit`·`return_always`·`return_aim` 으로만) · `SkillMods.Overwatch*` 삭제 · `BattleManager.ApplyOverwatch` · `Unit.Overwatch` 는 스킬 확장 없이 남음(대기 유닛이 없어 실행 안 됨).
- **근접 3병종 특징 = 한 줄 정의(PD 2026-11-10 직접 지시)**: **보병** = 적을 밀치고 튕겨나며 튕기면서 다른 적을 추가로 공격(알까기 + 연쇄 · #1098 그대로 · 목표점 명중 추가 이동 = 제거(PD #1112 결정 ⑱)) · **창병** = 적을 크게 밀치지만 자신은 적게 밀림(`spearPushRatio` 1.5 > 보병 `collisionPushRatio` 1.0 · 반작용 남은 거리 × 0.3 < 보병 자기 튕김 0.5) · **창병 대기(견제) 제거**(「유저가 인지하기 어려움」 · 목표점 명중해도 `SetOverwatch` 안 함 · HUD 「견제 반경·대기 중」 문구 삭제) · **기병** = 적을 관통해 이동 · **목표점 명중 시 제자리 복귀 제거**(「유저가 인지하기 어려움」 · `PreviewCavalryReturn` · 조준 때 복귀 영역 `ShowReturnZones` 삭제 · AI 가중치 `cav_return`·`cav_stranded` 삭제). 견제·복귀 스킬 = #1112 PD 새 기획으로 전부 재설계(견제 없음 · 복귀는 스킬 효과 `return_on_hit`·`return_always`·`return_aim` 으로만) · `SkillMods.Overwatch*` 삭제 · `BattleManager.ApplyOverwatch` · `Unit.Overwatch` 는 스킬 확장 없이 남음(대기 유닛이 없어 실행 안 됨).
- **IB 크기 · 캐릭터 연출(PD 2026-11-10 「IB 와 화살표 크기도 다르고 선택된 캐릭터 주위 연출도 누락」)**: 값 표 `Resources/Skills/ib_ui.csv`(`TKS.IbUi`) — IB 유닛 반지름 0.496(ExportCharacter size 8 × 0.062) 기준 배율 = 이 게임 유닛 반지름 / 0.496 → 고리 지름 = 반지름 × 5.4 · 화살표 세기 s = IB 월드 당김 × 0.6(0.5~1.5) · IB 취소 거리 0.5. **`TKS.IbUnitMarks`** = 선택한 행동 가능 아군 발밑 도는 원(`TKS_Fx_IB_TargetCircle` · IB ShowUserTurnMark) + 몸 둘레 빛(`TKS_Fx_IB_AttackReady`) · 조준 중(누름 ~ 놓음) 모든 유닛 속성 방울(`TKS_Fx_IB_Attribute_<속성>` · IB SetActiveBarrierVisualEffect · 진영 → 속성 = 표 element_*: 위 물 · 촉 나무 · 오 불 · 군·진영 없음 어둠).
- **타격감(PD 2026-11-10 「화면 흔들림 등도 IB 를 참고해서」)**: `TKS.HitFeel` + 표 `Resources/Skills/hit_feel.csv`(행동 중 유닛이 상대에게 처음 피해를 준 순간 · `SkillSystem.Hit` · 흔들림 = `CameraController.Shake`(추적 위치는 그대로 두고 흔들림만 더함) · 히트 스톱 칸 있음(현재 0)). **IB 실측**: 흔들림 함수 6종은 스킬·궁극기·기믹 이펙트 애니메이션 이벤트로만 불리고 본문이 디컴파일에서 비어 있어 값 없음 · 일반 타격·벽 튕김엔 흔들림 없음 · 히트 스톱 없음 → 표 값(hit 0.15초 · 키 10 % / 기병 0.18초 · 13 %)은 추정.
- **2D 돌진(PD 2026-11-10 「기본 공격(돌진) 이펙트가 너무 3D 느낌 → 2D 처럼」 · MSFX 혜성 행은 표에 `#` 주석으로 남김 = 되돌리기)**: **3차(현재 · PD 2026-11-10 「검기는 이전 형태가 더 나음 · 대쉬 이펙트는 캐릭터 몸을 벗어나지 않도록 · 첨부 같은 느낌으로 몸을 뒤덮는 연출을 스킬용 시험」)** = 초승달 `Head` = 1차 그림 `dash2d_crescent`(검정 외곽선 · 진영색 곱) · 대쉬 층(꼬리 0.04초 · 바람 줄기 · 알갱이 · 흙먼지) = 유닛을 따라 움직이는 Local 공간 · 몸 기준점 반경 0.45 키 안(실측 그림 경계 좌우 ±0.56 · 아래 −0.60 ~ 위 +0.59 키) · 바람 줄기 `Lines` · 알갱이 `Dots` = 유닛 위 반투명(표 `s_over` = `Head;Lines;Dots` · 유닛 아래면 몸에 다 가려 안 보임 · PD 「몸의 대쉬 효과가 왜 안 보이나」) · 꼬리 · 흙먼지 = 유닛 아래 · **기병 복귀 = 돌아서서 감**(`UnitView.TurnAround` · 복귀 방향으로 보기 + 곧장 위·아래면 좌우 반전 · 도착 뒤에도 마지막 이동 방향 PD #1082) · **몸 뒤덮는 기운(시험)** = `TKS_Fx_Aura2D_<진영>`(혜성 기운 `aura_comet_<진영>` 겹쳐 깜빡임 · 불꽃 혀 `aura_wisp` · 반짝임 = 유닛 아래 · 옅은 막 `Veil` · 앞 테 `Rim`(2차 검기 그림) = 유닛 위) · 표 키 `test_aura` · 테스트 씬 「기운 시험」 스위치(`SkillVfx.TestTravelKey` · 켜면 슬링샷 공격 돌진에 함께 · 실제 전투 = 늘 빈칸). 2차 = 외곽선 없음 · 그림 `Assets/VFX/TKS2D/`(만들기 = `python -I -X utf8 Tools/make_dash2d_textures.py` · 진영색 원본 = `Tools/dash2d_camps.csv`) → 프리팹 `Resources/Fx/TKS_Fx_Dash2D_<wei|shu|wu|other>`(검기 초승달 `Head` = 진영별 그림 `dash2d_slash_<진영>` · 유닛 위 · 반투명 꼬리 `Trail`(앞 0.7 → 0) · 흰 바람 줄기 `Lines` · 알갱이 `Dots` = 유닛 아래 · 수명 동안 투명해짐) + `TKS_Fx_Dust2D`(부드러운 반투명 흙먼지 · 모든 진영) · 다시 만들기 = `unity command … script eval --file Tools/build_dash2d.cs`(값을 바꾸면 이 파일과 프리팹을 함께). 1차(검정 외곽선 셀 그림)의 `dash2d_crescent.png` · `dash2d_highlight.png` 는 안 씀. 표 `b_flat` = 1 이면 화면 안에서 진행 방향으로만 돌림(기울기·팩 루트 회전 무시 · `SkillVfx.FlatRotation`) · 크기 단위 = 유닛 키 1(`f_scale` 1) · 끝 소멸 = `f_fade` 0.12(`SkillVfxFade` 가 스프라이트 불투명도도 낮춤).