스킬 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:
parent
0b2f56f271
commit
296732370c
|
|
@ -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),,
|
||||
|
|
|
|||
|
|
|
@ -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
|
||||
|
|
|
|||
|
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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,16 +249,30 @@ 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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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 },
|
||||
|
|
|
|||
|
|
@ -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,13 +1402,21 @@ 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)))
|
||||
{
|
||||
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, Mathf.RoundToInt(h.E.P), h.E.Get(1, 0.02f), max);
|
||||
NoteHit(h);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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, "부딪힌 유닛은 밀려난다");
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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` 가 스프라이트 불투명도도 낮춤).
|
||||
|
|
|
|||
Loading…
Reference in New Issue