다중 Row 드랍 & 인벤토리 직접 지급
개요
적 사망 시 여러 드랍 Row를 각각 확률 굴림하여, 마지막으로 공격한 플레이어의 인벤토리로 직접 지급한다. (아이템 액터 스폰 없음)
주요 변경
1. 데이터 구조 — RetrieveDataTableTypes.h
FEnemyDropRow:ItemTag(FGameplayTag)→ItemId(FName)+ItemCategoryTag(FGameplayTag)(인벤토리 키와 일치)FMonsterDataRow:DropRow(FName)→DropRows(TArray<FName>)
2. 드랍 처리 — DropComponent.h/.cpp
Initialize(UDataTable*, const TArray<FName>&)— 배열 수신ProcessDrop(): 서버 권한 확인 → 마지막 공격자 폰의InventoryComponent확보 →DropRows각 행을DropChance로 독립 굴림 →AddItem(ItemId, ItemCategoryTag, Quantity)
3. 적용 지점 — RetrieveEnemyCharacter.cpp
InitializeComponents()에서DropRows.Num() > 0일 때 배열 전달ProcessDrop()호출은 BP_EnemyBase(사망 시)에서 단일 호출
4. 버그 수정 — CombatAttributeSet.cpp (마지막 공격자 null 문제)
- 증상: 플레이어가 죽여도
LastDamageInstigator가 null → 드랍 대상(인벤토리) 못 찾음.MonsterDied.Killer도 계속 null이던 잠재 버그. - 원인: 데미지가
IncomingDamage메타 어트리뷰트 →SetHealth()로 적용됨. 이로 인한 Health 변경은 GE 직접 수정이 아니라서HandleHealthChanged의ChangeData.GEModData가 null → instigator 세팅 누락. (NotifyDamageContext는 정의만 있고 호출처 없음) - 수정:
PostGameplayEffectExecute에서SetHealth()직전에EffectContext의 instigator/causer를HealthComponent->NotifyDamageContext()로 전달. - 효과: 근접·원거리·버스트·화상(DoT) 등 모든 데미지 경로에서 마지막 공격자 확정.
Killer잠재 버그도 함께 해결.
미적용 / 참고
- 보스:
RetrieveBossCharacter::HandleDeathStarted는 상위RetrieveEnemyCharacter를 건너뛰므로 이 드랍 경로를 타지 않음. 보스도 동일 드랍이 필요하면 별도 배선 필요. - PlayerState fallback(DropComponent의 폰 해석 보강)은 instigator가 폰으로 확정되어 불필요 → 미적용.