// Project Lab - NHTV Igad #include "UnrealProject.h" #include "OffensiveEnemy.h" #include "AbilityInfo.h" #include "SpawnerBase.h" #include "NetworkPlayer.h" #include "MinionAnimInstance.h" #include "BehaviorTree/EnemyAIController.h" AOffensiveEnemy::AOffensiveEnemy() { PrimaryActorTick.bCanEverTick = true; } void AOffensiveEnemy::BeginPlay() { Super::BeginPlay(); if (Role != ROLE_Authority) return; } void AOffensiveEnemy::EndPlay(const EEndPlayReason::Type EndPlayReason) { Super::EndPlay(EndPlayReason); if (Role != ROLE_Authority) return; } void AOffensiveEnemy::Tick(float deltaTime) { Super::Tick(deltaTime); if (Role != ROLE_Authority) return; if (IsValid(target)) { if (hasGeneral) { GeneralBehavior(); } else { if (m_confusionTimer > 0.0f) { ConfusionBehavior(); return; } BasicBehavior(); } // Move to target } } void AOffensiveEnemy::GeneralBehavior() { if (!meleeAbility || !specialAbility) { //RERROR("there is no abilities"); return; } const FVector2D actorLocation = FVector2D(GetActorLocation().X, GetActorLocation().Y); const FVector2D targetLocation = FVector2D(target->GetActorLocation().X, target->GetActorLocation().Y); const float targetDistSqr = FVector2D::DistSquared(targetLocation, actorLocation); m_tempAbility = meleeAbility; if (((m_tempAbility->AICastRange + 150)*(m_tempAbility->AICastRange + 150)) < targetDistSqr) return; if (GetAbilityState(m_tempAbility)->onCooldownTimer <= 0) { CastAbility(m_tempAbility); UMinionAnimInstance* animInstance = Cast(GetMesh()->GetAnimInstance()); if (IsValid(animInstance)) { animInstance->ChangeAnimationStateTo(EMinionAnimState::MAS_Attacking); } //m_rotateToPlayer = m_tempAbility->rotateTowardsPlayer; } } void AOffensiveEnemy::BasicBehavior() { if (!IsValid(target)) return; if (FVector::DistSquared(target->GetActorLocation(), GetActorLocation()) > 200 * 200) { MoveToPoint(target->GetActorLocation()); } else { FVector addvec = GetActorLocation() - target->GetActorLocation(); addvec.Normalize(); MoveToPoint(target->GetActorLocation()+addvec*200.0f); GetCharacterMovement()->Velocity = FVector::ZeroVector; } SetActorRotation(FVector(target->GetActorLocation() - GetActorLocation()).Rotation()); if (!meleeAbility || !specialAbility) { //RERROR("there is no abilities"); return; } const FVector2D actorLocation = FVector2D(GetActorLocation().X, GetActorLocation().Y); const FVector2D targetLocation = FVector2D(target->GetActorLocation().X, target->GetActorLocation().Y); const float targetDistSqr = FVector2D::DistSquared(targetLocation, actorLocation); m_tempAbility = meleeAbility; if ((rand() % 1000) > specialAbilityChance&&!m_isPulled) { m_tempAbility = specialAbility; } m_isPulled = true; if (((m_tempAbility->AICastRange + 150)*(m_tempAbility->AICastRange + 150)) < targetDistSqr) return; if (GetAbilityState(m_tempAbility)->onCooldownTimer <= 0) { CastAbility(m_tempAbility); UMinionAnimInstance* animInstance = Cast(GetMesh()->GetAnimInstance()); if (IsValid(animInstance)) { animInstance->ChangeAnimationStateTo(EMinionAnimState::MAS_Attacking); } } } int32 AOffensiveEnemy::NativeDealDamage(class ANetworkCharacter* dealer, int32 damage, float armorPercentageIgnore, class UAbilityInfo* ability) { if (hasGeneral) { float damageMultiplier = FVector::DotProduct(dealer->GetActorForwardVector(), GetActorForwardVector()); damageMultiplier += 1.0f; damageMultiplier *= 0.5f; damageMultiplier += 0.5f; return Super::NativeDealDamage(dealer, damage*damageMultiplier, armorPercentageIgnore, ability); } else return Super::NativeDealDamage(dealer, damage, armorPercentageIgnore, ability); }