// Project Lab - NHTV Igad #include "UnrealProject.h" #include "MiniBossCreature.h" #include "NetworkPlayer.h" #include "CreatureSpawn.h" #include "AbilityInfo.h" #include "Effect.h" AMiniBossCreature::AMiniBossCreature() { PrimaryActorTick.bCanEverTick = true; m_usesMana = false; target = nullptr; m_spawn = nullptr; m_castTimer = 0; keyDropped = PlayerKeyType::None; } void AMiniBossCreature::BeginPlay() { Super::BeginPlay(); if (Role != ROLE_Authority) return; // Select two random abilities to cast if (IsValid(inheritAbilities) && IsValid(inheritAbilities.GetDefaultObject())) { TArray& bossAbilities = inheritAbilities.GetDefaultObject()->abilities; if (bossAbilities.Num() > 1) { TArray abilityIndices; for (int32 i = 0; i < bossAbilities.Num(); i++) abilityIndices.Add(i); while (m_bossAbilityPattern.Num() < 2) { const int32 index = FMath::Rand() % abilityIndices.Num(); const int32 ability = abilityIndices[index]; abilityIndices.RemoveAt(index); m_bossAbilityPattern.Add(ability); } } else if (bossAbilities.Num() == 1) m_bossAbilityPattern.Add(0); } } void AMiniBossCreature::EndPlay(const EEndPlayReason::Type EndPlayReason) { Super::EndPlay(EndPlayReason); if (Role != ROLE_Authority) return; // Drop a key if (m_health <= 0) { ANetworkPlayer* const killedBy = Cast(GetLastPlayerDamage()); if (IsValid(killedBy) && keyDropped != PlayerKeyType::None && IsValid(m_spawn) && !m_spawn->hasDroppedKey) { killedBy->AssignKey(keyDropped, m_spawn); } } } void AMiniBossCreature::Tick(float deltaTime) { Super::Tick(deltaTime); if (Role != ROLE_Authority) return; // If the distance of the target to the spawn is greater than the aggro range of the spawner, // then lose the target. if (IsValid(target)) { float targetDistSqr = FVector::DistSquared(target->GetActorLocation(), m_spawn->SpawnResetPosition()); float aggroSqr = m_spawn->deaggroRadius * m_spawn->deaggroRadius; if (aggroSqr < targetDistSqr) { // Reset target = nullptr; m_castTimer = 0; } } if (!IsValid(target)) return; // Boss casting logic MoveToPoint(target->GetActorLocation()); m_castTimer += deltaTime; if (m_castTimer > 2.5f && IsValid(inheritAbilities) && IsValid(inheritAbilities.GetDefaultObject())) { TArray& bossAbilities = inheritAbilities.GetDefaultObject()->abilities; if (bossAbilities.Num() > 0 && m_bossAbilityPattern.Num() > 0) { // Cast a random ability UAbilityInfo* ability = bossAbilities[m_bossAbilityPattern[FMath::Rand() % m_bossAbilityPattern.Num()]]; if (IsValid(ability)&& ability->AICastRange*ability->AICastRange>FVector::DistSquared(GetActorLocation(),target->GetActorLocation())) CastAbility(ability); } m_castTimer = 0; } }