int n = elements.size();
vector<int> arr2(2*n);
for (int i = 0; i < n; i++)
{
arr2[i] = elements[i];
arr2[i+n] = elements[i];
}
vector<int> ps(2*n + 1, 0);
for (int i = 0; i < 2*n; i++)
{
ps[i+1] = ps[i] + arr2[i];
}
unordered_set<int> sums;
for (int len = 1; len <= n; len++)
{
for (int start = 0; start < n; start++)
{
int end = start + len;
int sum = ps[end] - ps[start];
sums.insert(sum);
}
}
TMap<EMonsterType, TSubclassOf<APotatoMonster>> MonsterClassByType;
신규 타입 Enum 추가 후 TMap에 연결.
Monster->InitFromStats(FinalStats);
신규 몬스터는 코드 수정 없이 Data 중심으로 확장 가능해야 한다.
UPROPERTY(VisibleAnywhere)
UWidgetComponent* HealthBarWidget;
if (HealthBarWidget)
{
HealthBarWidget->SetWidgetSpace(EWidgetSpace::World);
}
void APotatoMonster::OnDamaged(float NewHP)
{
if (UHealthBar* HB = Cast<UHealthBar>(HealthBarWidget->GetUserWidgetObject()))
{
HB->UpdateHealth(CurrentHP / MaxHP);
}
}
DamageTextPool->SpawnDamageText(
Damage,
WorldLocation,
StackIndex
);
FVector Origin, Extent;
Target->GetActorBounds(true, Origin, Extent);
FVector SpawnLoc = Origin + FVector(0,0,Extent.Z);
TextBlock->SetText(FText::FromString(FString::FromInt(Damage)));
UGameplayStatics::PlaySoundAtLocation(
this,
HitSFX,
GetActorLocation()
);
if (Now - LastHitSFXTime < 0.1f)
return;
if (Now - LastHitReactTime < HitReactCooldown)
return;
if (bIsHitReacting)
return;
GetWorldTimerManager().SetTimer(
HitReactResumeTH,
this,
&APotatoMonster::ResumeFromHit,
0.3f,
false
);
void APotatoMonster::Die()
{
if (bIsDead) return;
bIsDead = true;
StopAIForDead();
GetCharacterMovement()->StopMovementImmediately();
GetCharacterMovement()->DisableMovement();
SetActorEnableCollision(false);
if (AnimInst && AS->DeathMontage)
{
float Len = AnimInst->Montage_Play(AS->DeathMontage);
SetLifeSpan(Len);
}
}