presidents-brigade/Source/PresidentsBrigade/EnemyAIController.cpp
2024-01-02 19:40:23 -08:00

125 lines
2.7 KiB
C++
Executable File

// Fill out your copyright notice in the Description page of Project Settings.
#include "EnemyAIController.h"
#include "EngineUtils.h"
#include "DrawDebugHelpers.h"
#include "Kismet/KismetSystemLibrary.h"
#include "Util.h"
#define LogInfo(Msg) Util::log_info(TEXT("AEnemyIController"), Msg)
#define LogError(Msg) Util::log_error(TEXT("AEnemyIController"), Msg)
void AEnemyAIController::Tick(float delta_time)
{
Super::Tick(delta_time);
switch(current_state)
{
case state_t::init:
president = get_president();
if (UKismetSystemLibrary::IsValid(president))
{
current_state = state_t::wait;
}
break;
case state_t::wait:
waiting_time += delta_time;
if (waiting_time > wait_threshold)
{
waiting_time = 0;
current_state = state_t::target;
}
break;
case state_t::target:
if (!UKismetSystemLibrary::IsValid(president))
{
current_state = state_t::init;
}
else
{
FVector target_location = president->get_location();
const ABasePawn* local_pawn = Cast<ABasePawn>(GetPawn());
if (UKismetSystemLibrary::IsValid(local_pawn))
{
FVector current_location = local_pawn->get_location();
starting_location = current_location;
FVector between = target_location - current_location;
between = FVector(between.X, between.Y, 0);
between.Normalize();
FVector extended = (between * overshoot_multiplier) + target_location;
MoveToLocation(extended);
current_state = state_t::moving_attack;
}
else
{
// This will be cleaned up shortly.
current_state = state_t::dead;
}
}
break;
case state_t::moving_attack:
case state_t::moving_retreat:
if (move_completed)
{
move_completed = false;
current_state = state_t::wait;
}
break;
default:
/*
* Do nothing.
*/
break;
}
}
void AEnemyAIController::redirect_target()
{
if (current_state == moving_attack)
{
MoveToLocation(starting_location);
current_state = moving_retreat;
}
}
void AEnemyAIController::OnMoveCompleted(FAIRequestID request_id, const FPathFollowingResult& result)
{
move_completed = true;
}
/**
* Helper function to find president in level.
*/
ABasePawn* AEnemyAIController::get_president() const
{
ABasePawn* found = nullptr;
for (TActorIterator<AActor> iterator(GetWorld()); iterator; ++iterator)
{
AActor* actor = *iterator;
if (actor && actor != this)
{
UClass* actor_class = actor->GetClass();
if (actor_class == (*president_class))
{
if (found)
{
LogError("Multiple presidents found!");
break;
}
found = Cast<ABasePawn>(actor);
}
}
}
if (!found)
{
// LogError("No president found!");
}
return found;
}