// Fill out your copyright notice in the Description page of Project Settings. #include "PresidentAIController.h" #include "EngineUtils.h" #include "Util.h" #define LogInfo(Msg) Util::log_info(TEXT("APresidentAIController"), Msg) #define LogError(Msg) Util::log_error(TEXT("APresidentAIController"), Msg) APresidentAIController::APresidentAIController() { level_location = TUniquePtr(new LevelLocation()); } void APresidentAIController::BeginPlay() { Super::BeginPlay(); /* * Initialize random stream. */ random.Initialize(FMath::Rand()); } void APresidentAIController::Tick(float delta) { Super::Tick(delta); switch (current_state) { case state_t::init: { // Without this offset, the path finding to return to starting location will fail with // invalid. I'm too sleepy to dig further. const FVector offset(1.0, 1.0, 0); starting_location = GetPawn()->GetActorLocation() + offset; target_location = starting_location; level_location->initialize(GetWorld(), marker_class); // Update state. current_state = state_t::idle; } break; case state_t::idle: { const bool should_wait = random.GetFraction() > .5; const bool is_home = target_location == starting_location; if (should_wait && is_home) { current_state = state_t::waiting; } else { target_location = is_home ? level_location->get_random_mark() : starting_location; MoveToLocation(target_location); current_state = state_t::moving; } } break; case state_t::moving: if (move_completed) { move_completed = false; current_state = state_t::waiting; } break; case state_t::waiting: waiting_time += delta; if (waiting_time > wait_threshold) { waiting_time = 0; current_state = state_t::idle; } break; default: /* * Do nothing. */ break; } } void APresidentAIController::OnMoveCompleted(FAIRequestID request_id, const FPathFollowingResult& result) { move_completed = true; }