Initial sync: 너드나비스 조직 전체 자산 (v2 §3 인벤토리 기준)
- 루트: CLAUDE.md + pm-general 에이전트
- 공유/: PD 지시 트래킹, 일일보고, 공통_업무_규칙(C1~C15 + P1~P20 + 부록 A SOT), 조직공지, 부서간 REQ
- 개발실/: CLAUDE.md(C14-4 SOT 참조 전환), 에이전트·커맨드, 코어_설계(_skeleton 제외), 프로젝트 숙지 10종, 조직공지
- 기획실/: CLAUDE.md(C14-4 SOT 참조 전환), 에이전트·스킬모듈, 밸런싱 .md, Phase 3 HOLD 공지
- memory/org/: 사용자 메모리 6종 (외부 ~/.claude/projects/*/memory/ 사본)
- setup/: Windows·macOS 셋업 스크립트
- 제외: Unity·*.xlsm·*.sqlite·settings.local.json·data/·.cache/·_skeleton/
C14-4 참조 무결성 정리: '작업 시점별 자동 환기 메모'를 공통_업무_규칙.md 부록 A(SOT)로 단일화, 개발실/기획실 CLAUDE.md는 참조 링크로 전환.
PD 지시 #7 Phase 1 착수. push는 PAT 수신 후 실행 예정.
2026-04-14 16:40:28 +00:00
|
|
|
|
# 08. 전투시스템 SOT (Single Source of Truth) v1
|
|
|
|
|
|
|
|
|
|
|
|
- 작성일: 2026-04-14
|
|
|
|
|
|
- 작성자: 개발실장 (Explore 에이전트 분석 위임)
|
|
|
|
|
|
- 목적: 기획실 밸런싱·시뮬레이터 검증을 지원하기 위해 **코드가 실제로 수행하는 전투 로직**을 SOT로 확정
|
2026-04-20 15:44:48 +00:00
|
|
|
|
- 스코프: `D:/BurningTimes/FilGoodBandits/DeckBuilding/Assets/Script/` 전수
|
Initial sync: 너드나비스 조직 전체 자산 (v2 §3 인벤토리 기준)
- 루트: CLAUDE.md + pm-general 에이전트
- 공유/: PD 지시 트래킹, 일일보고, 공통_업무_규칙(C1~C15 + P1~P20 + 부록 A SOT), 조직공지, 부서간 REQ
- 개발실/: CLAUDE.md(C14-4 SOT 참조 전환), 에이전트·커맨드, 코어_설계(_skeleton 제외), 프로젝트 숙지 10종, 조직공지
- 기획실/: CLAUDE.md(C14-4 SOT 참조 전환), 에이전트·스킬모듈, 밸런싱 .md, Phase 3 HOLD 공지
- memory/org/: 사용자 메모리 6종 (외부 ~/.claude/projects/*/memory/ 사본)
- setup/: Windows·macOS 셋업 스크립트
- 제외: Unity·*.xlsm·*.sqlite·settings.local.json·data/·.cache/·_skeleton/
C14-4 참조 무결성 정리: '작업 시점별 자동 환기 메모'를 공통_업무_규칙.md 부록 A(SOT)로 단일화, 개발실/기획실 CLAUDE.md는 참조 링크로 전환.
PD 지시 #7 Phase 1 착수. push는 PAT 수신 후 실행 예정.
2026-04-14 16:40:28 +00:00
|
|
|
|
- 원칙: 코드가 말하는 것만 기록. 추측 금지. 불확실한 항목은 **(확인 필요)** 태그 명시
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 1. 전투 시스템의 파일 맵
|
|
|
|
|
|
|
|
|
|
|
|
### 1.1 핵심 매니저 및 컨트롤러
|
|
|
|
|
|
|
|
|
|
|
|
| 파일경로 | 클래스명 | 역할 |
|
|
|
|
|
|
|---|---|---|
|
|
|
|
|
|
| `Assets/Script/InGame/Stage/MonsterNodeControler.cs` | `MonsterNodeControler` | **전투 루프 제어 중심** — 몬스터 배치, 라인 변경, 노드 종료 |
|
|
|
|
|
|
| `Assets/Script/InGame/Actor/Actor.cs` | `Actor` (기본 클래스) | 피해 계산, 회피, 크리티컬, 상태이상 (약 3,700줄) |
|
|
|
|
|
|
| `Assets/Script/InGame/Actor/PCActor.cs` | `PCActor` | 플레이어 전용 — 방어 입력, HUD 관리 |
|
|
|
|
|
|
| `Assets/Script/InGame/Actor/MobActor.cs` | `MobActor` | 몬스터 전용 — 라인 위치, 드롭 보상 |
|
|
|
|
|
|
|
|
|
|
|
|
### 1.2 핵심 데이터 타입
|
|
|
|
|
|
|
|
|
|
|
|
| 파일:라인 | 타입 | 설명 |
|
|
|
|
|
|
|---|---|---|
|
|
|
|
|
|
| `My/MyClass.cs:339` | `ProjectileData` | 발사체/공격 정보 (데미지, 크리, 특수효과) |
|
|
|
|
|
|
| `My/MyValue.cs:517` | `ActorStatInfo` | 배우 스탯 (HP, 공격력, 회피율 등) |
|
|
|
|
|
|
| `InGame/Stage/IngameStageData.cs:63` | `StageNodeData` | 노드 데이터 (몬스터 구성) |
|
|
|
|
|
|
| `Table/Tables/table_monsterlist.cs:8` | `MonsterListTableData` | 몬스터 테이블 (Normal/Boss 구분) |
|
|
|
|
|
|
|
|
|
|
|
|
### 1.3 전투 씬 진입/종료 경로
|
|
|
|
|
|
|
|
|
|
|
|
- **진입**: `MonsterNodeControler.Set(endnode, stagedata)` (`MonsterNodeControler.cs:42`)
|
|
|
|
|
|
- 몬스터 생성: `MonsterNodeControler.cs:92~118`
|
|
|
|
|
|
- 배우 초기화: `MonsterNodeControler.cs:142~168`
|
|
|
|
|
|
- 전투 시작: `MonsterNodeControler.cs:170` → `InGameInfo.Ins.BattleStart_AfterMakeMob()`
|
|
|
|
|
|
- **종료**:
|
|
|
|
|
|
- 몬스터 전멸: `Co_AllKill()` (`MonsterNodeControler.cs:334~343`)
|
|
|
|
|
|
- 라인 변경: `Co_LineChange()` (`MonsterNodeControler.cs:362~450`)
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 2. 전투 라이프사이클
|
|
|
|
|
|
|
|
|
|
|
|
### 2.1 흐름
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
1. 노드 진입: MonsterNodeControler.Set(endnode, stagedata)
|
|
|
|
|
|
2. 패턴 선택: table_MonsterPatternList (PatternID 기반)
|
|
|
|
|
|
3. 몬스터 동적 생성: Get_MakeMob_Dynamic() [cs:198~255]
|
|
|
|
|
|
- 라인(전열/중열/대기열) × 슬롯(3) = 9슬롯
|
|
|
|
|
|
- 슬롯별 근접/원거리/고유 확률 추첨
|
|
|
|
|
|
4. 배우 배치: Actor 9개 (0~8: 전열 3, 중열 3, 대기열 3)
|
|
|
|
|
|
5. 전투 루프: Actor.Update() [Actor.cs:79~111]
|
|
|
|
|
|
- AttackCoolTime 감소 → 0 도달 시 Play_Attack()
|
|
|
|
|
|
- 상태이상·카드 효과 업데이트
|
|
|
|
|
|
6. 공격 발동: Actor.Shoot_Projectile() [Actor.cs:946~1039]
|
|
|
|
|
|
7. 피해 계산: Actor.Get_Dmg(ProjectileData) [Actor.cs:521~834]
|
|
|
|
|
|
8. 라인 전멸 체크: Check_LineAllDead() [Actor.cs:480]
|
|
|
|
|
|
- 라인 변경: Co_LineChange()
|
|
|
|
|
|
- 전원 처치: Co_AllKill() → act_EndNode()
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 2.2 주요 이벤트 / 콜백
|
|
|
|
|
|
|
|
|
|
|
|
| 이벤트 | 함수 | 시점 |
|
|
|
|
|
|
|---|---|---|
|
|
|
|
|
|
| 피해 수신 | `Actor.Get_Dmg(ProjectileData)` `Actor.cs:521` | 발사체 도달 |
|
|
|
|
|
|
| 회피 판정 | `Run_AvoidStatus()` `Actor.cs:1640` | 회피 성공 |
|
|
|
|
|
|
| 크리티컬 결정 | `ProjectileData.Set()` `MyClass.cs:354` | 발사체 생성 |
|
|
|
|
|
|
| 사망 | `Actor.Set_Die(ProjectileData)` `Actor.cs:876` | HP ≤ 0 |
|
|
|
|
|
|
| 부활 | `Co_Resurrection()` `Actor.cs:926` | 부활 카드/성소 |
|
|
|
|
|
|
| 라인 변경 | `Co_LineChange()` `MonsterNodeControler.cs:362` | 라인 전멸 |
|
|
|
|
|
|
| 노드 종료 | `act_EndNode()` `MonsterNodeControler.cs:456` | 전원 처치 |
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 3. 공격/피해 계산 수식
|
|
|
|
|
|
|
|
|
|
|
|
### 3.1 기본 공격력
|
|
|
|
|
|
|
|
|
|
|
|
`MyValue.cs:800~804`
|
|
|
|
|
|
```csharp
|
|
|
|
|
|
public int Get_Damage()
|
|
|
|
|
|
{
|
|
|
|
|
|
var dmg = Random.Range((int)Get_TotalStat(eStat.Attack_Min),
|
|
|
|
|
|
(int)Get_TotalStat(eStat.Attack_Max) + 1);
|
|
|
|
|
|
return Mathf.Max(dmg, 1); // 최소 1 보장
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**Attack_Min 최종값** (`MyValue.cs:585~603`)
|
|
|
|
|
|
```csharp
|
|
|
|
|
|
case eStat.Attack_Min:
|
|
|
|
|
|
{
|
|
|
|
|
|
rtn += Get_Stat(eStat.Attack) + Get_BuffStat(eStat.Attack) - Get_DebuffStat(eStat.Attack);
|
|
|
|
|
|
|
|
|
|
|
|
// G5_AttackUpBySkillCardCount: 스킬카드 수만큼 증가
|
|
|
|
|
|
if (m_Actor.IsObtainCardSkill(cardtype))
|
|
|
|
|
|
rtn += m_Actor.Get_SkillCardCount();
|
|
|
|
|
|
|
|
|
|
|
|
// G5_FlatDamageMinMaxEqual: 최소/최대 동일화
|
|
|
|
|
|
if (m_Actor.IsObtainCardSkill(cardtype))
|
|
|
|
|
|
{
|
|
|
|
|
|
var maxdmg = Get_Stat(eStat.Attack_Max) + Get_BuffStat(eStat.Attack_Max)
|
|
|
|
|
|
- Get_DebuffStat(eStat.Attack_Max);
|
|
|
|
|
|
rtn = Mathf.Max((int)rtn, (int)maxdmg);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var mul = Get_BuffStat(eStat.DmgMul)
|
|
|
|
|
|
+ Get_BuffStat(eStat.Attack_Min_Mul)
|
|
|
|
|
|
+ Get_BuffStat(eStat.PC5_DmgMul);
|
|
|
|
|
|
return (int)(rtn + (rtn * mul));
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**기여도 순서** (카드 > 장비 > 각성 > 인장 원칙과 매핑):
|
|
|
|
|
|
1. 기본값: `ActorTableDataBase.n_AttackMin / n_AttackMax`
|
|
|
|
|
|
2. 장비: `ApplyMainStat()` / `ApplyStat()` (`MyValue.cs:261~282`)
|
|
|
|
|
|
3. 각성: `eAwakening.Stat_ADD`, `eUniqueAwakeningType.PC1_UniqueAwakening1~5` (`MyValue.cs:156~217`)
|
|
|
|
|
|
4. 인장: `eSpecialEffect.CritChance`, `CritDamage` 등 (`MyValue.cs:145~154`)
|
|
|
|
|
|
5. 런 내 버프/디버프: `Set_Buff()` / `Set_Debuff()` (`MyValue.cs:747~792`)
|
|
|
|
|
|
|
|
|
|
|
|
### 3.2 최종 피해 계산 (15단계)
|
|
|
|
|
|
|
|
|
|
|
|
`Actor.cs:521~834` 순서대로 요약.
|
|
|
|
|
|
|
|
|
|
|
|
1. **기본**: `baseDmg = hitterstat.Get_Damage()`
|
|
|
|
|
|
2. **1회성 절대 증가**: `AddDmg_1Time` + 인장 절대값
|
|
|
|
|
|
3. **1회성 배수 증가**: `AddDmgMul_1Time` + 인장 배수
|
|
|
|
|
|
4. **스턴/라인 보정**: `DmgMul_byStun`, `FrontLine_Dmg_Mul_1Time`, `MiddleLine_Dmg_Mul_1Time`, `BackLine_Dmg_Mul_1Time`
|
|
|
|
|
|
5. **G3_PotionNextAttackBoost**: 물약 스택 소모 시 배수 추가
|
|
|
|
|
|
6. **G5_FirstAttackTripleDamage**: 첫 공격이면 배수를 해당 값으로 **대체**(`Actor.cs:719~724`)
|
|
|
|
|
|
7. **곱연산 합산**: `hitter_dmg = base + 절대 + (hitter_dmg * 배수)` (`Actor.cs:726`)
|
|
|
|
|
|
8. **크리티컬**: `hitter_dmg *= CriDmg` (크리 시) (`Actor.cs:758`)
|
|
|
|
|
|
9. **절대 감소**: `ReduceMeeleDmg` / `ReduceRangeDmg` / `ReduceDmg` + 방어 중이면 `PCDefence` (`Actor.cs:776`)
|
|
|
|
|
|
10. **비율 감소**: `ReduceMeeleDmg_Mul` / `ReduceRangeDmg_Mul` + 방어 중이면 `PCDefence_Mul`, `G2_ReduceRangedDamageWithShield` (`Actor.cs:808`)
|
|
|
|
|
|
11. **최소 피해 1**: `hitter_dmg = max(hitter_dmg, 1)` (`Actor.cs:811`)
|
|
|
|
|
|
12. **G4_ShieldedDamageReduction**: 쉴드 보유 시 비율 추가 감소
|
|
|
|
|
|
13. **FixedDmg**: 고정 피해 스탯이 있으면 피해를 해당 값으로 **대체** (`Actor.cs:817`)
|
|
|
|
|
|
14. **G2_StackDamageOnSameTarget**: 동일 대상 연타 스택 추가 피해 (`Actor.cs:826`)
|
|
|
|
|
|
15. **쉴드 우선 감산** → **HP 감산** (`Actor.cs:435`)
|
|
|
|
|
|
|
|
|
|
|
|
**요약식**
|
|
|
|
|
|
```
|
|
|
|
|
|
기본 = Random[Attack_Min, Attack_Max]
|
|
|
|
|
|
중간 = 기본 + 절대증가 + (기본 × 배수증가)
|
|
|
|
|
|
(크리 시) 중간 × CriDmg
|
|
|
|
|
|
→ 중간 - 절대감소
|
|
|
|
|
|
→ 중간 - (중간 × 감소비율)
|
|
|
|
|
|
→ max(중간, 1)
|
|
|
|
|
|
→ (쉴드 존재) 쉴드 먼저 흡수 → HP 감산
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 3.3 크리티컬
|
|
|
|
|
|
|
|
|
|
|
|
`MyClass.cs:354~393`
|
|
|
|
|
|
```csharp
|
|
|
|
|
|
isCri = DSUtil.RandomTrue(crirate); // 1차: 확률 판정
|
|
|
|
|
|
if (Hitter.IsObtainCardSkill(G2_NextSevenHitsCritical)) // 2차: N연타 강제
|
|
|
|
|
|
{
|
|
|
|
|
|
var card = Hitter.Get_CardSkillData_orNull(cardtype);
|
|
|
|
|
|
if (card.UseCount_Acc < card.m_Data.Get_IntValue1())
|
|
|
|
|
|
{
|
|
|
|
|
|
++card.UseCount_Acc;
|
|
|
|
|
|
isCri = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**크리 확률 상한**: `MaxCri = 0.9f` (`MyValue.cs:23`).
|
|
|
|
|
|
**크리 배수 적용**: `hitter_dmg *= Get_TotalStat(eStat.CriDmg)` (`Actor.cs:758`).
|
|
|
|
|
|
|
|
|
|
|
|
### 3.4 회피 판정 (3단계)
|
|
|
|
|
|
|
|
|
|
|
|
**1단계 — 명중률 체크 (PC 한정)** (`Actor.cs:623`)
|
|
|
|
|
|
```csharp
|
|
|
|
|
|
isHit = DSUtil.RandomTrue(hitterstat.Get_TotalStat(eStat.HitRate) / (avoid * 3.69));
|
|
|
|
|
|
```
|
|
|
|
|
|
> **(확인 필요)** 3.69 상수의 근거.
|
|
|
|
|
|
|
|
|
|
|
|
**2단계 — PC 회피율** (`Actor.cs:633~647`)
|
|
|
|
|
|
```csharp
|
|
|
|
|
|
if (DSUtil.RandomTrue(Attack가_Melee ? avoid_melee : avoid_range))
|
|
|
|
|
|
Run_AvoidStatus(...); return;
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**3단계 — 최초 공격 무조건 회피** (`Actor.cs:649~669`)
|
|
|
|
|
|
- 근접 첫 공격: `G2_FirstMeleeAlwaysEvade`
|
|
|
|
|
|
- 원거리 첫 공격: `G3_DodgeFirstRangedAttack`
|
|
|
|
|
|
|
|
|
|
|
|
**회피율 상한**: `MaxAvoid = 0.9f` (`MyValue.cs:23`) — **PC 한정**. 몬스터 회피는 정수형(비일관성 리스크).
|
|
|
|
|
|
|
|
|
|
|
|
### 3.5 상태이상
|
|
|
|
|
|
|
|
|
|
|
|
`Actor.cs:512~513`
|
|
|
|
|
|
```csharp
|
|
|
|
|
|
OnEvent_GetDmg(pdData);
|
|
|
|
|
|
Set_StatusEffect(pdData.Get_SoSData(pdData.Hitter), this);
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
상태이상 데이터는 `table_StatusOptionSet`에서 조회 (`MyClass.cs:401~438`). 업데이트 불가 CC(Stun/Freezing 등) 은 `Actor.cs:52~53` 상수 참조.
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2026-04-17 16:54:32 +00:00
|
|
|
|
## 4. 터치 방어 메커닉 (Q-P1 → Q-P2)
|
Initial sync: 너드나비스 조직 전체 자산 (v2 §3 인벤토리 기준)
- 루트: CLAUDE.md + pm-general 에이전트
- 공유/: PD 지시 트래킹, 일일보고, 공통_업무_규칙(C1~C15 + P1~P20 + 부록 A SOT), 조직공지, 부서간 REQ
- 개발실/: CLAUDE.md(C14-4 SOT 참조 전환), 에이전트·커맨드, 코어_설계(_skeleton 제외), 프로젝트 숙지 10종, 조직공지
- 기획실/: CLAUDE.md(C14-4 SOT 참조 전환), 에이전트·스킬모듈, 밸런싱 .md, Phase 3 HOLD 공지
- memory/org/: 사용자 메모리 6종 (외부 ~/.claude/projects/*/memory/ 사본)
- setup/: Windows·macOS 셋업 스크립트
- 제외: Unity·*.xlsm·*.sqlite·settings.local.json·data/·.cache/·_skeleton/
C14-4 참조 무결성 정리: '작업 시점별 자동 환기 메모'를 공통_업무_규칙.md 부록 A(SOT)로 단일화, 개발실/기획실 CLAUDE.md는 참조 링크로 전환.
PD 지시 #7 Phase 1 착수. push는 PAT 수신 후 실행 예정.
2026-04-14 16:40:28 +00:00
|
|
|
|
|
|
|
|
|
|
### 4.1 결론
|
|
|
|
|
|
|
2026-04-17 16:54:32 +00:00
|
|
|
|
**플레이어 터치 입력으로 방어가 발동된다 — 그러나 현재 확인된 경로는 "타겟팅"이다.** 명시적 방어 입력 윈도우는 ~~(확인 필요)~~ → **✅ 실측 확정 (2026-04-17 #37 Q-P2 정밀 2차)**: `UITouchHandler.cs` `IPointerDownHandler`·`IPointerUpHandler`·`IPointerExitHandler` 인터페이스로 구현. `IngameUIManager.cs:39` `m_PCDefence.Set(m_PCActor.Play_Defence, m_PCActor.Release_Defence, null)` 바인딩. **터치 Down↔Up 구간 동안 지속되는 상태 효과**. 근거: [`공유/소통/완료/2026-04-17_Phase0-C_QP2_정밀2차_응답서.md`](../../../공유/소통/완료/2026-04-17_Phase0-C_QP2_정밀2차_응답서.md).
|
Initial sync: 너드나비스 조직 전체 자산 (v2 §3 인벤토리 기준)
- 루트: CLAUDE.md + pm-general 에이전트
- 공유/: PD 지시 트래킹, 일일보고, 공통_업무_규칙(C1~C15 + P1~P20 + 부록 A SOT), 조직공지, 부서간 REQ
- 개발실/: CLAUDE.md(C14-4 SOT 참조 전환), 에이전트·커맨드, 코어_설계(_skeleton 제외), 프로젝트 숙지 10종, 조직공지
- 기획실/: CLAUDE.md(C14-4 SOT 참조 전환), 에이전트·스킬모듈, 밸런싱 .md, Phase 3 HOLD 공지
- memory/org/: 사용자 메모리 6종 (외부 ~/.claude/projects/*/memory/ 사본)
- setup/: Windows·macOS 셋업 스크립트
- 제외: Unity·*.xlsm·*.sqlite·settings.local.json·data/·.cache/·_skeleton/
C14-4 참조 무결성 정리: '작업 시점별 자동 환기 메모'를 공통_업무_규칙.md 부록 A(SOT)로 단일화, 개발실/기획실 CLAUDE.md는 참조 링크로 전환.
PD 지시 #7 Phase 1 착수. push는 PAT 수신 후 실행 예정.
2026-04-14 16:40:28 +00:00
|
|
|
|
|
|
|
|
|
|
### 4.2 구현
|
|
|
|
|
|
|
|
|
|
|
|
`MonsterNodeControler.cs:263~290` — 마우스/터치 다운 이벤트
|
|
|
|
|
|
```csharp
|
|
|
|
|
|
void Update()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (Input.GetMouseButtonDown(0))
|
|
|
|
|
|
{
|
|
|
|
|
|
// ... RaycastHit2D로 Actor 탐색
|
|
|
|
|
|
if (actor != null && !pc.IsDead() && targetlines && !actor.IsDead())
|
|
|
|
|
|
InGameInfo.Ins.m_PCActor.Set_Target(actor); // 타겟 변경
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 4.3 방어 상태 관련 흔적
|
|
|
|
|
|
|
|
|
|
|
|
- `PCActor.Play_Defence()` `PCActor.cs:148~154`: 방어 애니메이션 실행
|
|
|
|
|
|
- `PCActor.Release_Defence()` `PCActor.cs:155~161`: 방어 해제
|
2026-04-17 16:54:32 +00:00
|
|
|
|
- 실제 호출부 ~~(확인 필요)~~ → **✅ 실측 확정 (#37)**: `IngameUIManager.cs:39` — `m_PCDefence.Set(...)` 으로 `UITouchHandler` 이벤트가 `Play_Defence`/`Release_Defence` 에 바인딩. `Update()`에서 `m_onHold?.Invoke()` 지속 호출 (현재 no-op).
|
Initial sync: 너드나비스 조직 전체 자산 (v2 §3 인벤토리 기준)
- 루트: CLAUDE.md + pm-general 에이전트
- 공유/: PD 지시 트래킹, 일일보고, 공통_업무_규칙(C1~C15 + P1~P20 + 부록 A SOT), 조직공지, 부서간 REQ
- 개발실/: CLAUDE.md(C14-4 SOT 참조 전환), 에이전트·커맨드, 코어_설계(_skeleton 제외), 프로젝트 숙지 10종, 조직공지
- 기획실/: CLAUDE.md(C14-4 SOT 참조 전환), 에이전트·스킬모듈, 밸런싱 .md, Phase 3 HOLD 공지
- memory/org/: 사용자 메모리 6종 (외부 ~/.claude/projects/*/memory/ 사본)
- setup/: Windows·macOS 셋업 스크립트
- 제외: Unity·*.xlsm·*.sqlite·settings.local.json·data/·.cache/·_skeleton/
C14-4 참조 무결성 정리: '작업 시점별 자동 환기 메모'를 공통_업무_규칙.md 부록 A(SOT)로 단일화, 개발실/기획실 CLAUDE.md는 참조 링크로 전환.
PD 지시 #7 Phase 1 착수. push는 PAT 수신 후 실행 예정.
2026-04-14 16:40:28 +00:00
|
|
|
|
|
|
|
|
|
|
### 4.4 방어 성공 효과 (`Actor.cs:515~519`)
|
|
|
|
|
|
|
|
|
|
|
|
```csharp
|
|
|
|
|
|
if (ActorStatus == eActorStatus.Defecne)
|
|
|
|
|
|
{
|
|
|
|
|
|
huddmg.Set_Block(dmg, Get_World_Position());
|
|
|
|
|
|
EffectMgr.Ins.Show_Effect("PCBlock", Get_World_Position(), this);
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
방어 중이면 피해 감소:
|
|
|
|
|
|
- 절대: `PCDefence` (`Actor.cs:775`, `table_GlobalValue`)
|
|
|
|
|
|
- 비율: `PCDefence_Mul` (`Actor.cs:783`)
|
|
|
|
|
|
|
2026-04-17 16:54:32 +00:00
|
|
|
|
#### ✅ 실측 확정 수치 (2026-04-17 #37 Q-P2 정밀 2차)
|
|
|
|
|
|
|
|
|
|
|
|
| 항목 | 기획 초기 가정 | **실측 확정값** | 근거 |
|
|
|
|
|
|
|------|---------------|---------------|------|
|
|
|
|
|
|
| 피해 감소 비율 | 50% | **30%** (`PCDefence_Mul = 0.3`) | `GlobalValue.json` — `{"s_ID": "PCDefence_Mul", "n_Value": "0.3"}` |
|
|
|
|
|
|
| 고정 절대 감소 | 미정 | **1** (`PCDefence = 1`) | `GlobalValue.json` + `Actor.cs:775` |
|
|
|
|
|
|
| 지속 형태 | 단일 공격 바인딩 가정 | **지속형 상태 효과** (터치 Down↔Up 유지 동안 반복 적용) | `UITouchHandler.cs` + `IngameUIManager.cs:39` |
|
|
|
|
|
|
| 쿨다운 | 미정 | **없음** (즉시 재사용) | `UITouchHandler.cs`·`PCActor.cs:148-162` 전수 확인 |
|
|
|
|
|
|
| 방어 중 공격 | 미정 | **불가** (DPS 0) | `Actor.cs:4500` — 공격 프레임 return |
|
|
|
|
|
|
| 방어 중 피격 애니 | 미정 | **차단** (Play_Hit 조기 return) | `PCActor.cs:133` |
|
|
|
|
|
|
| 적용 공격 종류 | 미정 | **Melee / Ranged 공통** | `Actor.cs:782-783` 단일 분기 |
|
|
|
|
|
|
| Mob 방어 메커닉 | 미정 | **부재** | `MobActor.cs` override 전수 확인 결과 부재 |
|
|
|
|
|
|
|
|
|
|
|
|
**근거 응답서**: [`2026-04-17_Phase0-C_QP2_정밀2차_응답서.md`](../../../공유/소통/완료/2026-04-17_Phase0-C_QP2_정밀2차_응답서.md) (#37 PD 지시). **기획 초기 가정("50%")은 추적성 보존을 위해 유지**(원칙 1), 실측 수치로 전환하여 밸런스 작업은 0.3 기준으로 진행.
|
|
|
|
|
|
|
Initial sync: 너드나비스 조직 전체 자산 (v2 §3 인벤토리 기준)
- 루트: CLAUDE.md + pm-general 에이전트
- 공유/: PD 지시 트래킹, 일일보고, 공통_업무_규칙(C1~C15 + P1~P20 + 부록 A SOT), 조직공지, 부서간 REQ
- 개발실/: CLAUDE.md(C14-4 SOT 참조 전환), 에이전트·커맨드, 코어_설계(_skeleton 제외), 프로젝트 숙지 10종, 조직공지
- 기획실/: CLAUDE.md(C14-4 SOT 참조 전환), 에이전트·스킬모듈, 밸런싱 .md, Phase 3 HOLD 공지
- memory/org/: 사용자 메모리 6종 (외부 ~/.claude/projects/*/memory/ 사본)
- setup/: Windows·macOS 셋업 스크립트
- 제외: Unity·*.xlsm·*.sqlite·settings.local.json·data/·.cache/·_skeleton/
C14-4 참조 무결성 정리: '작업 시점별 자동 환기 메모'를 공통_업무_규칙.md 부록 A(SOT)로 단일화, 개발실/기획실 CLAUDE.md는 참조 링크로 전환.
PD 지시 #7 Phase 1 착수. push는 PAT 수신 후 실행 예정.
2026-04-14 16:40:28 +00:00
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 5. 몬스터 배치 · 스폰 패턴 (Q-P2)
|
|
|
|
|
|
|
|
|
|
|
|
### 5.1 배치 흐름
|
|
|
|
|
|
|
|
|
|
|
|
`MonsterNodeControler.Set()` (`cs:42~171`)
|
|
|
|
|
|
1. `StageNodeData_Mob.PatternID` → `table_MonsterPatternList` 조회
|
|
|
|
|
|
2. `PatternID < 1001`이면 `+900` 구데이터 호환 (`cs:70`)
|
|
|
|
|
|
3. `Get_MakeMob_Dynamic()`가 라인 × 슬롯 9개에 대해 근접/원거리/고유 확률 누적 추첨
|
|
|
|
|
|
4. **고유 몬스터는 1개 제한** (`uniqueMakeCount`) — **(확인 필요)** 의도된 캡인지
|
|
|
|
|
|
|
|
|
|
|
|
### 5.2 데이터 테이블 키 매핑
|
|
|
|
|
|
|
|
|
|
|
|
| 테이블 | 필드 | 역할 | 위치 |
|
|
|
|
|
|
|---|---|---|---|
|
|
|
|
|
|
| `table_MonsterPatternList` | `n_PatternId` | 패턴 ID | `cs:11` |
|
|
|
|
|
|
| 동 | `list_MeleeRate_Front/Middle/Back` | 라인별 근접 확률 | `cs:33` |
|
|
|
|
|
|
| 동 | `list_RangeRate_Front/Middle/Back` | 라인별 원거리 확률 | `cs:34` |
|
|
|
|
|
|
| 동 | `list_FixedRate_Front/Middle/Back` | 라인별 고유 확률 | `cs:35` |
|
|
|
|
|
|
| 동 | `n_FixedMonsterId` | 고유 몬스터 ID | `cs:17` |
|
|
|
|
|
|
| `StageNodeData_Mob` | `MobCount` | 배치할 몬스터 수 | `IngameStageData.cs:86` |
|
|
|
|
|
|
| 동 | `list_MobID` | 선택 가능한 몬스터 풀 | `IngameStageData.cs:86` |
|
|
|
|
|
|
|
|
|
|
|
|
확률 문자열 포맷: `^`로 구분된 정수(10000 스케일) → 파싱 시 10000으로 나눠 0~1 정규화 (`table_MonsterPatternList.Init()` `cs:43~115`).
|
|
|
|
|
|
|
|
|
|
|
|
### 5.3 몬스터 ID 결정
|
|
|
|
|
|
|
|
|
|
|
|
`MonsterNodeControler.cs:183~196`
|
|
|
|
|
|
```csharp
|
|
|
|
|
|
int Get_MobID(MakeMobData mob, StageNodeData_Mob mobnode, int makecount, int bossid)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (mob.MobID > 0) return mob.MobID; // 고유 몬스터 즉시 반환
|
|
|
|
|
|
var lst = mobnode.list_MobID;
|
|
|
|
|
|
if (bossid > 0) lst = lst.FindAll(f => f != bossid); // 보스 ID 중복 방지
|
|
|
|
|
|
if (mobnode.MakeRandom) return lst[Random.Range(0, lst.Count)];
|
|
|
|
|
|
return MyValue.m_MyStageData.Get_MobID_onStage(mob.e_ToolMobType, mobnode.list_MobID);
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 6. 보스 처리 (Q-P3)
|
|
|
|
|
|
|
|
|
|
|
|
### 6.1 판정
|
|
|
|
|
|
|
|
|
|
|
|
`table_monsterlist.cs:36~39`
|
|
|
|
|
|
```csharp
|
|
|
|
|
|
public override bool IsBoss()
|
|
|
|
|
|
=> e_MonsterType == eMonsterType.Boss_Melee
|
|
|
|
|
|
|| e_MonsterType == eMonsterType.Boss_Range;
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 6.2 배치 규칙
|
|
|
|
|
|
|
|
|
|
|
|
`MonsterNodeControler.cs:76~90`
|
|
|
|
|
|
```csharp
|
|
|
|
|
|
if (stagedata.m_Type == eStageNodeType.Boss)
|
|
|
|
|
|
{
|
|
|
|
|
|
++makeMobCount;
|
|
|
|
|
|
var bossdata = stagedata.Get_Data<StageNodeData_Boss>();
|
|
|
|
|
|
bossid = bossdata.BossID;
|
|
|
|
|
|
dic_mob[eMobBattlePos.Backline][2] = bossid; // 대기열 중앙 고정
|
|
|
|
|
|
...
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**보스는 항상 Backline 슬롯 2에 배치된다.**
|
|
|
|
|
|
|
|
|
|
|
|
### 6.3 특수 패턴
|
|
|
|
|
|
|
|
|
|
|
|
- **Death 특수효과 피해**: 보스는 50% HP 피해, 일반 몬스터는 9999 (즉사) — `Actor.cs:570`
|
|
|
|
|
|
- **미션 등급 가중치**: `MobActor.cs:123~220` — 보스=2, 악마=3, 일반=1
|
|
|
|
|
|
|
|
|
|
|
|
> **(확인 필요)** 보스10002 클리어 가능성(Q-P3)은 전용 AI 패턴이 아닌 **스탯·카드 풀 기반 시뮬레이션**으로 검증해야 한다. 현재 코드상 보스 전용 공격 로직은 발견되지 않음.
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 7. 발견된 리스크 · 이슈
|
|
|
|
|
|
|
|
|
|
|
|
### 7.1 기획 문서 vs 코드 불일치 후보
|
|
|
|
|
|
|
|
|
|
|
|
| 항목 | 코드 실태 | 위치 |
|
|
|
|
|
|
|---|---|---|
|
|
|
|
|
|
| 회피 공식 | `HitRate / (Avoid × 3.69)` — 3.69 근거 불명 | `Actor.cs:623` |
|
|
|
|
|
|
| PC 방어 | 터치는 타겟팅만 확인, 명시적 방어 윈도우 미확인 | `PCActor.cs`, `MonsterNodeControler.cs` |
|
|
|
|
|
|
| 크리 상한 | 0.9f 고정 (90%) | `MyValue.cs:23` |
|
|
|
|
|
|
| 회피 상한 | PC만 0.9f, 몬스터는 정수형 | `MyValue.cs:625~639` |
|
|
|
|
|
|
|
|
|
|
|
|
### 7.2 하드코딩 값 (밸런싱 숨김)
|
|
|
|
|
|
|
|
|
|
|
|
| 값 | 용도 | 위치 | 개선 |
|
|
|
|
|
|
|---|---|---|---|
|
|
|
|
|
|
| `3.69` | 회피 상수 | `Actor.cs:623` | 테이블화 |
|
|
|
|
|
|
| `0.01f` | 회피율 % 변환 | `MyValue.cs:629` | eStat에서 처리 |
|
|
|
|
|
|
| `"PCDefence"` | 방어 절대 감소 | `Actor.cs:775` | GlobalValue 참조 OK |
|
|
|
|
|
|
| `"PCDefence_Mul"` | 방어 비율 감소 | `Actor.cs:783` | GlobalValue 참조 OK |
|
|
|
|
|
|
| `list_scale[]` | 9슬롯 스케일 | `MonsterNodeControler.cs:26` | 테이블화 |
|
|
|
|
|
|
| `list_pos[]` | 9슬롯 좌표 | `MonsterNodeControler.cs:27~32` | 테이블화 |
|
|
|
|
|
|
|
|
|
|
|
|
### 7.3 시뮬레이터 이원화
|
|
|
|
|
|
|
|
|
|
|
|
- 단일 경로 확인됨 — `Actor.Get_Dmg()` 외 병행 계산 경로 없음.
|
|
|
|
|
|
- 이원화 리스크는 **낮음**. (기획실 시뮬레이터는 외부 엑셀/도구이므로, SOT를 이 문서로 일원화하면 검증 기준 확정 가능.)
|
|
|
|
|
|
|
|
|
|
|
|
### 7.4 코드 품질
|
|
|
|
|
|
|
|
|
|
|
|
- `Actor.cs` ≈ 3,700줄 · `Get_Dmg` ≈ 300줄 — 분할 권고
|
|
|
|
|
|
- 카드 효과 조건분기 난립 (`eCardType.Max = 200+`) — 효과 테이블화·전략 패턴 리팩토링 후보
|
|
|
|
|
|
- `ObscuredInt/Float` 빈번 사용 — 보안 목적 유지하되 핫패스 프로파일링 필요
|
|
|
|
|
|
|
|
|
|
|
|
### 7.5 버그 냄새
|
|
|
|
|
|
|
|
|
|
|
|
1. **HP 0 허용 가능성** — `Math.Max(1, ...)` 가드가 Attack_Min/Max에만 적용 (`MyValue.cs:709`)
|
|
|
|
|
|
2. **몬스터 회피 비일관성** — PC 상한 0.9 vs 몬스터 정수
|
|
|
|
|
|
3. **라인 변경 중 공격 수신** — `Co_LineChange` 도중 상태 불일치 가능성
|
|
|
|
|
|
4. **보스 ID 풀 중복 처리 의존** — `list_MobID`에 boss가 들어가 있을 때 `FindAll` 예외 안전성 **(확인 필요)**
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 8. B-1 완료 조건 체크리스트
|
|
|
|
|
|
|
|
|
|
|
|
SOT를 완전 확정하려면 다음 항목이 추가로 필요.
|
|
|
|
|
|
|
|
|
|
|
|
- [ ] 기획 엑셀 SOT와 회피·크리 상한·3.69 상수 대조
|
|
|
|
|
|
- [ ] `table_GlobalValue` 실제 값 덤프 (PCDefence, PCDefence_Mul, PC_ProjectileSpeed 등)
|
|
|
|
|
|
- [ ] `eCardType.G1_* ~ G5_*` 200+개 효과 전수 맵 (효과 종류별 분류표)
|
|
|
|
|
|
- [ ] 상태이상 중첩 규칙 명문화 (Stun/Freezing 등 CC 상호작용)
|
2026-04-17 16:54:32 +00:00
|
|
|
|
- [x] PC 방어 입력 경로 특정 (UI 버튼 vs 터치 윈도우) — **완료 (2026-04-17 #37)**: `UITouchHandler` 기반 터치 윈도우, `IngameUIManager.cs:39` 바인딩
|
|
|
|
|
|
- [x] Q-P1 응답서 확정 — 터치 방어 구조 최종 확인 — **완료 (2026-04-17 #37 Q-P2 정밀 2차)**: [응답서](../../../공유/소통/완료/2026-04-17_Phase0-C_QP2_정밀2차_응답서.md) 참조
|
|
|
|
|
|
- [ ] Q-P2 응답서 확정 — 패턴별 배치 예시 생성 (본 항목은 몬스터 배치 패턴 예시 별개 작업)
|
Initial sync: 너드나비스 조직 전체 자산 (v2 §3 인벤토리 기준)
- 루트: CLAUDE.md + pm-general 에이전트
- 공유/: PD 지시 트래킹, 일일보고, 공통_업무_규칙(C1~C15 + P1~P20 + 부록 A SOT), 조직공지, 부서간 REQ
- 개발실/: CLAUDE.md(C14-4 SOT 참조 전환), 에이전트·커맨드, 코어_설계(_skeleton 제외), 프로젝트 숙지 10종, 조직공지
- 기획실/: CLAUDE.md(C14-4 SOT 참조 전환), 에이전트·스킬모듈, 밸런싱 .md, Phase 3 HOLD 공지
- memory/org/: 사용자 메모리 6종 (외부 ~/.claude/projects/*/memory/ 사본)
- setup/: Windows·macOS 셋업 스크립트
- 제외: Unity·*.xlsm·*.sqlite·settings.local.json·data/·.cache/·_skeleton/
C14-4 참조 무결성 정리: '작업 시점별 자동 환기 메모'를 공통_업무_규칙.md 부록 A(SOT)로 단일화, 개발실/기획실 CLAUDE.md는 참조 링크로 전환.
PD 지시 #7 Phase 1 착수. push는 PAT 수신 후 실행 예정.
2026-04-14 16:40:28 +00:00
|
|
|
|
- [ ] Q-P3 응답서 확정 — 보스10002 시뮬 결과 포함
|
|
|
|
|
|
- [ ] 핫패스 성능 프로파일 (Get_Dmg 호출/프레임, ObscuredInt 오버헤드)
|
|
|
|
|
|
- [ ] 위 7.5 버그 냄새 재현 테스트
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 9. 변경 이력
|
|
|
|
|
|
|
|
|
|
|
|
| 버전 | 일자 | 작성자 | 내용 |
|
|
|
|
|
|
|---|---|---|---|
|
|
|
|
|
|
| v1 | 2026-04-14 | 개발실장 (Explore 위임) | 초안 — Phase 0-B-1 |
|