Files
Project-Reboot-3.0/Project Reboot 3.0/bots.h
Milxnor b64f569551 a bit
proper vending machines like fully, performance
2023-05-08 22:28:32 -04:00

313 lines
9.8 KiB
C++

#pragma once
#include "FortGameModeAthena.h"
#include "OnlineReplStructs.h"
#include "BuildingContainer.h"
class PlayerBot
{
public:
AController* Controller = nullptr;
float NextJumpTime = 1.0f;
void Initialize(const FTransform& SpawnTransform)
{
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
auto GameMode = Cast<AFortGameModeAthena>(GetWorld()->GetGameMode());
static UClass* PawnClass = nullptr;
static UClass* ControllerClass = nullptr;
if (!PawnClass)
{
if (true)
PawnClass = FindObject<UClass>("/Game/Athena/PlayerPawn_Athena.PlayerPawn_Athena_C");
else
PawnClass = FindObject<UClass>("/Game/Athena/AI/Phoebe/BP_PlayerPawn_Athena_Phoebe.BP_PlayerPawn_Athena_Phoebe_C");
}
if (!ControllerClass)
{
if (true)
ControllerClass = AFortPlayerControllerAthena::StaticClass();
else
ControllerClass = FindObject<UClass>("/Game/Athena/AI/Phoebe/BP_PhoebePlayerController.BP_PhoebePlayerController_C");
}
if (!ControllerClass || !PawnClass)
{
LOG_ERROR(LogBots, "Failed to find a class for the bots!");
return;
}
static auto FortAthenaAIBotControllerClass = FindObject<UClass>("/Script/FortniteGame.FortAthenaAIBotController");
FActorSpawnParameters PawnSpawnParameters{};
PawnSpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;
Controller = GetWorld()->SpawnActor<AController>(ControllerClass);
AFortPlayerPawnAthena* Pawn = GetWorld()->SpawnActor<AFortPlayerPawnAthena>(PawnClass, SpawnTransform, PawnSpawnParameters);
AFortPlayerStateAthena* PlayerState = Cast<AFortPlayerStateAthena>(Controller->GetPlayerState());
if (!Pawn || !PlayerState)
return;
static int CurrentBotNum = 1;
auto BotNumWStr = std::to_wstring(CurrentBotNum++);
FString NewName = (L"RebootBot" + BotNumWStr).c_str();
if (auto PlayerController = Cast<APlayerController>(Controller))
PlayerController->ServerChangeName(NewName);
PlayerState->OnRep_PlayerName();
PlayerState->GetTeamIndex() = GameMode->Athena_PickTeamHook(GameMode, 0, Controller);
static auto SquadIdOffset = PlayerState->GetOffset("SquadId", false);
if (SquadIdOffset != -1)
PlayerState->GetSquadId() = PlayerState->GetTeamIndex() - 2;
PlayerState->SetIsBot(true);
/*
static auto FortRegisteredPlayerInfoClass = FindObject<UClass>("/Script/FortniteGame.FortRegisteredPlayerInfo");
static auto MyPlayerInfoOffset = PlayerController->GetOffset("MyPlayerInfo");
PlayerController->Get(MyPlayerInfoOffset) = UGameplayStatics::SpawnObject(FortRegisteredPlayerInfoClass, PlayerController);
if (!PlayerController->Get(MyPlayerInfoOffset))
{
LOG_ERROR(LogBots, "Failed to spawn PlayerInfo!");
Pawn->K2_DestroyActor();
PlayerController->K2_DestroyActor();
return nullptr;
}
auto& PlayerInfo = PlayerController->Get(MyPlayerInfoOffset);
static auto UniqueIdOffset = PlayerState->GetOffset("UniqueId");
static auto PlayerInfo_PlayerNameOffset = PlayerInfo->GetOffset("PlayerName");
static auto PlayerIDOffset = PlayerInfo->GetOffset("PlayerID");
PlayerInfo->GetPtr<FUniqueNetIdRepl>(PlayerIDOffset)->CopyFromAnotherUniqueId(PlayerState->GetPtr<FUniqueNetIdRepl>(UniqueIdOffset));
PlayerInfo->Get<FString>(PlayerInfo_PlayerNameOffset) = PlayerState->GetPlayerName();
*/
Controller->Possess(Pawn);
Pawn->SetHealth(100);
Pawn->SetMaxHealth(100);
AFortInventory** Inventory = nullptr;
if (auto FortPlayerController = Cast<AFortPlayerController>(Controller))
{
Inventory = &FortPlayerController->GetWorldInventory();
}
else
{
if (Controller->IsA(FortAthenaAIBotControllerClass))
{
static auto InventoryOffset = Controller->GetOffset("Inventory");
Inventory = Controller->GetPtr<AFortInventory*>(InventoryOffset);
}
}
if (!Inventory)
{
LOG_ERROR(LogBots, "No inventory pointer!");
Pawn->K2_DestroyActor();
Controller->K2_DestroyActor();
return;
}
FActorSpawnParameters InventorySpawnParameters{};
InventorySpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
InventorySpawnParameters.Owner = Controller;
FTransform InventorySpawnTransform{};
static auto FortInventoryClass = FindObject<UClass>("/Script/FortniteGame.FortInventory"); // AFortInventory::StaticClass()
*Inventory = GetWorld()->SpawnActor<AFortInventory>(FortInventoryClass, InventorySpawnTransform, InventorySpawnParameters);
if (!*Inventory)
{
LOG_ERROR(LogBots, "Failed to spawn Inventory!");
Pawn->K2_DestroyActor();
Controller->K2_DestroyActor();
return;
}
(*Inventory)->GetInventoryType() = EFortInventoryType::World;
if (auto FortPlayerController = Cast<AFortPlayerController>(Controller))
{
static auto bHasInitializedWorldInventoryOffset = FortPlayerController->GetOffset("bHasInitializedWorldInventory");
FortPlayerController->Get<bool>(bHasInitializedWorldInventoryOffset) = true;
}
// if (false)
{
if (Inventory)
{
auto& StartingItems = GameMode->GetStartingItems();
for (int i = 0; i < StartingItems.Num(); i++)
{
auto& StartingItem = StartingItems.at(i);
(*Inventory)->AddItem(StartingItem.GetItem(), nullptr, StartingItem.GetCount());
}
if (auto FortPlayerController = Cast<AFortPlayerController>(Controller))
{
UFortItem* PickaxeInstance = FortPlayerController->AddPickaxeToInventory();
if (PickaxeInstance)
{
FortPlayerController->ServerExecuteInventoryItemHook(FortPlayerController, PickaxeInstance->GetItemEntry()->GetItemGuid());
}
}
(*Inventory)->Update();
}
}
/* static auto HeroType = FindObject(L"/Game/Athena/Heroes/HID_115_Athena_Commando_M_CarbideBlue.HID_115_Athena_Commando_M_CarbideBlue");
static auto HeroTypeOffset = PlayerState->GetOffset("HeroType");
if (HeroTypeOffset != -1)
PlayerState->Get(HeroTypeOffset) = HeroType; */
auto PlayerAbilitySet = GetPlayerAbilitySet();
auto AbilitySystemComponent = PlayerState->GetAbilitySystemComponent();
if (PlayerAbilitySet)
{
PlayerAbilitySet->GiveToAbilitySystem(AbilitySystemComponent);
}
// PlayerController->GetCosmeticLoadout()->GetCharacter() = FindObject("/Game/Athena/Items/Cosmetics/Characters/CID_263_Athena_Commando_F_MadCommander.CID_263_Athena_Commando_F_MadCommander");
// Pawn->GetCosmeticLoadout()->GetCharacter() = PlayerController->GetCosmeticLoadout()->GetCharacter();
// PlayerController->ApplyCosmeticLoadout();
GameState->GetPlayersLeft()++;
GameState->OnRep_PlayersLeft();
if (auto FortPlayerControllerAthena = Cast<AFortPlayerControllerAthena>(Controller))
GameMode->GetAlivePlayers().Add(FortPlayerControllerAthena);
}
};
static std::vector<PlayerBot> AllPlayerBotsToTick;
namespace Bots
{
static AController* SpawnBot(FTransform SpawnTransform)
{
auto playerBot = PlayerBot();
playerBot.Initialize(SpawnTransform);
AllPlayerBotsToTick.push_back(playerBot);
return playerBot.Controller;
}
static void SpawnBotsAtPlayerStarts(int AmountOfBots)
{
return;
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
auto GameMode = Cast<AFortGameModeAthena>(GetWorld()->GetGameMode());
for (int i = 0; i < AmountOfBots; i++)
{
FTransform SpawnTransform{};
SpawnTransform.Translation = FVector(1, 1, 10000);
SpawnTransform.Rotation = FQuat();
SpawnTransform.Scale3D = FVector(1, 1, 1);
auto NewBot = SpawnBot(SpawnTransform);
auto PlayerStart = GameMode->K2_FindPlayerStart(NewBot, NewBot->GetPlayerState()->GetPlayerName()); // i dont think this works
if (!PlayerStart)
{
LOG_ERROR(LogBots, "Failed to find PlayerStart for bot!");
NewBot->GetPawn()->K2_DestroyActor();
NewBot->K2_DestroyActor();
continue;
}
NewBot->TeleportTo(PlayerStart->GetActorLocation(), FRotator());
NewBot->SetCanBeDamaged(Fortnite_Version < 7); // idk lol for spawn island
}
}
static void Tick()
{
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
auto GameMode = Cast<AFortGameModeAthena>(GetWorld()->GetGameMode());
// auto AllBuildingContainers = UGameplayStatics::GetAllActorsOfClass(GetWorld(), ABuildingContainer::StaticClass());
// for (int i = 0; i < GameMode->GetAlivePlayers().Num(); i++)
for (auto& PlayerBot : AllPlayerBotsToTick)
{
auto CurrentPlayer = PlayerBot.Controller;
if (CurrentPlayer->IsActorBeingDestroyed())
continue;
auto CurrentPawn = CurrentPlayer->GetPawn();
auto CurrentPlayerState = Cast<AFortPlayerStateAthena>(CurrentPlayer->GetPlayerState());
if (!CurrentPlayerState || !CurrentPlayerState->IsBot())
continue;
if (GameState->GetGamePhase() == EAthenaGamePhase::Warmup)
{
/* if (!CurrentPlayer->IsPlayingEmote())
{
static auto AthenaDanceItemDefinitionClass = FindObject<UClass>("/Script/FortniteGame.AthenaDanceItemDefinition");
auto RandomDanceID = GetRandomObjectOfClass(AthenaDanceItemDefinitionClass);
CurrentPlayer->ServerPlayEmoteItemHook(CurrentPlayer, RandomDanceID);
} */
}
if (CurrentPlayerState->IsInAircraft() && !CurrentPlayerState->HasThankedBusDriver())
{
static auto ServerThankBusDriverFn = FindObject<UFunction>("/Script/FortniteGame.FortPlayerControllerAthena.ServerThankBusDriver");
CurrentPlayer->ProcessEvent(ServerThankBusDriverFn);
}
if (CurrentPawn)
{
if (PlayerBot.NextJumpTime <= UGameplayStatics::GetTimeSeconds(GetWorld()))
{
static auto JumpFn = FindObject<UFunction>("/Script/Engine.Character.Jump");
CurrentPawn->ProcessEvent(JumpFn);
PlayerBot.NextJumpTime = UGameplayStatics::GetTimeSeconds(GetWorld()) + (rand() % 4 + 3);
}
}
/* bool bShouldJumpFromBus = CurrentPlayerState->IsInAircraft(); // TODO (Milxnor) add a random percent thing
if (bShouldJumpFromBus)
{
CurrentPlayer->ServerAttemptAircraftJumpHook(CurrentPlayer, FRotator());
} */
}
// AllBuildingContainers.Free();
}
}