mirror of
https://github.com/Milxnor/Project-Reboot-3.0.git
synced 2026-01-13 10:52:22 +01:00
Give bot skins
This commit is contained in:
8
Project Reboot 3.0/AIController.h
Normal file
8
Project Reboot 3.0/AIController.h
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Controller.h"
|
||||||
|
|
||||||
|
class AAIController : public AController
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
};
|
||||||
@@ -42,7 +42,7 @@ class UCurveTable : public UObject
|
|||||||
public:
|
public:
|
||||||
static int GetCurveTableSize()
|
static int GetCurveTableSize()
|
||||||
{
|
{
|
||||||
static auto CurveTableClass = FindObject<UClass>("/Script/Engine.CurveTable");
|
static auto CurveTableClass = FindObject<UClass>(L"/Script/Engine.CurveTable");
|
||||||
return CurveTableClass->GetPropertiesSize();
|
return CurveTableClass->GetPropertiesSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
14
Project Reboot 3.0/FortAthenaAIBotController.h
Normal file
14
Project Reboot 3.0/FortAthenaAIBotController.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "reboot.h"
|
||||||
|
#include "AIController.h"
|
||||||
|
|
||||||
|
class AFortAthenaAIBotController : public AAIController
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static UClass* StaticClass()
|
||||||
|
{
|
||||||
|
static auto Class = FindObject<UClass>(L"/Script/FortniteGame.FortAthenaAIBotController");
|
||||||
|
return Class;
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -15,7 +15,7 @@ class AFortAthenaMutator : public AActor // AFortGameplayMutator
|
|||||||
public:
|
public:
|
||||||
static UClass* StaticClass()
|
static UClass* StaticClass()
|
||||||
{
|
{
|
||||||
static auto Class = FindObject<UClass>("/Script/FortniteGame.FortAthenaMutator");
|
static auto Class = FindObject<UClass>(L"/Script/FortniteGame.FortAthenaMutator");
|
||||||
return Class;
|
return Class;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -241,11 +241,22 @@ void AFortGameModeAthena::OverrideSupplyDrop(AFortGameStateAthena* GameState, UC
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static auto SupplyDropInfoListOffset = MapInfo->GetOffset("SupplyDropInfoList");
|
static auto SupplyDropInfoListOffset = MapInfo->GetOffset("SupplyDropInfoList", false);
|
||||||
auto& SupplyDropInfoList = MapInfo->Get<TArray<UFortSupplyDropInfo*>>(SupplyDropInfoListOffset);
|
|
||||||
|
|
||||||
static auto SupplyDropClassOffset = SupplyDropInfoList.at(0)->GetOffset("SupplyDropClass");
|
if (SupplyDropInfoListOffset == -1)
|
||||||
SupplyDropInfoList.at(0)->Get<TSubclassOf<AFortAthenaSupplyDrop*>>(SupplyDropClassOffset) = OverrideSupplyDropBusClass;
|
return;
|
||||||
|
|
||||||
|
auto& SupplyDropInfoList = MapInfo->Get<TArray<UFortSupplyDropInfo*>>(SupplyDropInfoListOffset);
|
||||||
|
auto FirstSupplyDropInfo = SupplyDropInfoList.at(0);
|
||||||
|
|
||||||
|
if (!FirstSupplyDropInfo)
|
||||||
|
{
|
||||||
|
LOG_WARN(LogGame, "No FirstSupplyDropInfo!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static auto SupplyDropClassOffset = FirstSupplyDropInfo->GetOffset("SupplyDropClass");
|
||||||
|
FirstSupplyDropInfo->Get<TSubclassOf<AFortAthenaSupplyDrop*>>(SupplyDropClassOffset) = OverrideSupplyDropBusClass;
|
||||||
|
|
||||||
LOG_INFO(LogGame, "Overridden SupplyDropClass: {}", OverrideSupplyDropBusClass->GetFullName());
|
LOG_INFO(LogGame, "Overridden SupplyDropClass: {}", OverrideSupplyDropBusClass->GetFullName());
|
||||||
}
|
}
|
||||||
@@ -283,6 +294,15 @@ void AFortGameModeAthena::OnAircraftEnteredDropZoneHook(AFortGameModeAthena* Gam
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetupEverythingAI() // find better name lol
|
||||||
|
{
|
||||||
|
PlayerBot::InitializeBotClasses();
|
||||||
|
// SetupAIGoalManager();
|
||||||
|
// SetupAIDirector();
|
||||||
|
SetupServerBotManager();
|
||||||
|
// SetupNavConfig(UKismetStringLibrary::Conv_StringToName(L"MANG"));
|
||||||
|
}
|
||||||
|
|
||||||
bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* GameMode)
|
bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* GameMode)
|
||||||
{
|
{
|
||||||
Globals::bHitReadyToStartMatch = true;
|
Globals::bHitReadyToStartMatch = true;
|
||||||
@@ -348,14 +368,6 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
|
|||||||
|
|
||||||
LOG_INFO(LogDev, "Presetup!");
|
LOG_INFO(LogDev, "Presetup!");
|
||||||
|
|
||||||
if (false)
|
|
||||||
{
|
|
||||||
SetupAIGoalManager();
|
|
||||||
SetupAIDirector();
|
|
||||||
SetupServerBotManager();
|
|
||||||
}
|
|
||||||
// SetupNavConfig(UKismetStringLibrary::Conv_StringToName(L"MANG"));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
static auto WorldManagerOffset = GameState->GetOffset("WorldManager", false);
|
static auto WorldManagerOffset = GameState->GetOffset("WorldManager", false);
|
||||||
@@ -402,12 +414,14 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (Fortnite_Version >= 4.1) // ????
|
if (Fortnite_Version > 4.0) // bruh
|
||||||
{
|
{
|
||||||
SetPlaylist(PlaylistToUse, true);
|
SetPlaylist(PlaylistToUse, true);
|
||||||
|
|
||||||
auto CurrentPlaylist = GameState->GetCurrentPlaylist();
|
auto CurrentPlaylist = GameState->GetCurrentPlaylist();
|
||||||
LOG_INFO(LogDev, "Set playlist to {}!", CurrentPlaylist->IsValidLowLevel() ? CurrentPlaylist->GetFullName() : "Invalid");
|
LOG_INFO(LogDev, "Set playlist to {}!", CurrentPlaylist->IsValidLowLevel() ? CurrentPlaylist->GetFullName() : "Invalid");
|
||||||
|
|
||||||
|
SetupEverythingAI();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -674,7 +688,7 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
|
|||||||
|
|
||||||
static int LastNum5 = 1;
|
static int LastNum5 = 1;
|
||||||
|
|
||||||
if (AmountOfRestarts != LastNum5 && LastNum6 == AmountOfRestarts) // Make sure we loaded the event.
|
if (AmountOfRestarts != LastNum5 && LastNum6 == AmountOfRestarts) // Make sure we loaded the event successfully.
|
||||||
{
|
{
|
||||||
LastNum5 = AmountOfRestarts;
|
LastNum5 = AmountOfRestarts;
|
||||||
|
|
||||||
@@ -706,7 +720,9 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
|
|||||||
|
|
||||||
auto MapInfo = GameState->GetMapInfo();
|
auto MapInfo = GameState->GetMapInfo();
|
||||||
|
|
||||||
if (Engine_Version >= 421 && !MapInfo)
|
if (Engine_Version >= 421 && // todo recheck this version
|
||||||
|
!MapInfo
|
||||||
|
)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
static int LastNum = 1;
|
static int LastNum = 1;
|
||||||
@@ -717,8 +733,11 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
|
|||||||
|
|
||||||
LOG_INFO(LogDev, "Initializing!");
|
LOG_INFO(LogDev, "Initializing!");
|
||||||
|
|
||||||
if (Fortnite_Version == 3)
|
if (Fortnite_Version >= 3.5 && Fortnite_Version <= 4) // todo check 3.4
|
||||||
|
{
|
||||||
SetPlaylist(GetPlaylistToUse(), true);
|
SetPlaylist(GetPlaylistToUse(), true);
|
||||||
|
SetupEverythingAI();
|
||||||
|
}
|
||||||
|
|
||||||
LOG_INFO(LogDev, "GameMode 0x{:x}", __int64(GameMode));
|
LOG_INFO(LogDev, "GameMode 0x{:x}", __int64(GameMode));
|
||||||
|
|
||||||
@@ -1531,6 +1550,18 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
|
|||||||
if (PlayerAbilitySet && Fortnite_Version != 12.00)
|
if (PlayerAbilitySet && Fortnite_Version != 12.00)
|
||||||
{
|
{
|
||||||
PlayerAbilitySet->GiveToAbilitySystem(AbilitySystemComponent);
|
PlayerAbilitySet->GiveToAbilitySystem(AbilitySystemComponent);
|
||||||
|
|
||||||
|
if (Fortnite_Version >= 21)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
static auto BGAClass = FindObject<UClass>(L"/Script/Engine.BlueprintGeneratedClass");
|
||||||
|
auto TacticalSprintClass = LoadObject<UClass>("/TacticalSprint/Gameplay/GA_Athena_GrantTacticalSprint.GA_Athena_GrantTacticalSprint_C", BGAClass);
|
||||||
|
AbilitySystemComponent->GiveAbilityEasy(TacticalSprintClass);
|
||||||
|
#else
|
||||||
|
auto TacticalSprintAbilitySet = LoadObject<UFortAbilitySet>("/TacticalSprint/Gameplay/AS_TacticalSprint.AS_TacticalSprint");
|
||||||
|
// TacticalSprintAbilitySet->GiveToAbilitySystem(AbilitySystemComponent);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static auto PlayerCameraManagerOffset = NewPlayer->GetOffset("PlayerCameraManager");
|
static auto PlayerCameraManagerOffset = NewPlayer->GetOffset("PlayerCameraManager");
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include "FortAbilitySet.h"
|
#include "FortAbilitySet.h"
|
||||||
#include "FortPlayerControllerAthena.h"
|
#include "FortPlayerControllerAthena.h"
|
||||||
#include "FortItemDefinition.h"
|
#include "FortItemDefinition.h"
|
||||||
|
#include "FortServerBotManagerAthena.h"
|
||||||
|
|
||||||
struct FAircraftFlightInfo
|
struct FAircraftFlightInfo
|
||||||
{
|
{
|
||||||
@@ -82,9 +83,8 @@ static inline UFortAbilitySet* GetPlayerAbilitySet()
|
|||||||
{
|
{
|
||||||
// There are some variables that contain this but it changes through versions soo..
|
// There are some variables that contain this but it changes through versions soo..
|
||||||
|
|
||||||
static auto GameplayAbilitySet = (UFortAbilitySet*)(Fortnite_Version >= 8.30
|
static auto GameplayAbilitySet = (Fortnite_Version >= 8.30 ? LoadObject<UFortAbilitySet>(L"/Game/Abilities/Player/Generic/Traits/DefaultPlayer/GAS_AthenaPlayer.GAS_AthenaPlayer")
|
||||||
? LoadObject(L"/Game/Abilities/Player/Generic/Traits/DefaultPlayer/GAS_AthenaPlayer.GAS_AthenaPlayer", UFortAbilitySet::StaticClass())
|
: LoadObject<UFortAbilitySet>(L"/Game/Abilities/Player/Generic/Traits/DefaultPlayer/GAS_DefaultPlayer.GAS_DefaultPlayer"));
|
||||||
: LoadObject(L"/Game/Abilities/Player/Generic/Traits/DefaultPlayer/GAS_DefaultPlayer.GAS_DefaultPlayer", UFortAbilitySet::StaticClass()));
|
|
||||||
|
|
||||||
return GameplayAbilitySet;
|
return GameplayAbilitySet;
|
||||||
}
|
}
|
||||||
@@ -251,6 +251,12 @@ public:
|
|||||||
return Get<AFortSafeZoneIndicator*>(SafeZoneIndicatorOffset);
|
return Get<AFortSafeZoneIndicator*>(SafeZoneIndicatorOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UFortServerBotManagerAthena*& GetServerBotManager()
|
||||||
|
{
|
||||||
|
static auto ServerBotManagerOffset = GetOffset("ServerBotManager");
|
||||||
|
return Get<UFortServerBotManagerAthena*>(ServerBotManagerOffset);
|
||||||
|
}
|
||||||
|
|
||||||
AFortGameStateAthena* GetGameStateAthena()
|
AFortGameStateAthena* GetGameStateAthena()
|
||||||
{
|
{
|
||||||
return (AFortGameStateAthena*)GetGameState();
|
return (AFortGameStateAthena*)GetGameState();
|
||||||
|
|||||||
@@ -1817,7 +1817,8 @@ void AFortPlayerController::ServerEndEditingBuildingActorHook(AFortPlayerControl
|
|||||||
if (auto EditTool = Cast<AFortWeap_EditingTool>(Pawn->GetCurrentWeapon()))
|
if (auto EditTool = Cast<AFortWeap_EditingTool>(Pawn->GetCurrentWeapon()))
|
||||||
{
|
{
|
||||||
EditTool->SetEditActor(nullptr);
|
EditTool->SetEditActor(nullptr);
|
||||||
|
// PlayerController->ClientForceCancelBuildingTool();
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayerController->ClientForceCancelBuildingTool();
|
// PlayerController->ClientForceCancelBuildingTool();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "Object.h"
|
#include "Object.h"
|
||||||
#include "FortPlayerPawnAthena.h"
|
#include "FortPlayerPawnAthena.h"
|
||||||
#include "FortAthenaAIBotCustomizationData.h"
|
#include "FortAthenaAIBotCustomizationData.h"
|
||||||
|
#include "FortAthenaMutator_Bots.h"
|
||||||
|
|
||||||
struct FFortAthenaAIBotRunTimeCustomizationData
|
struct FFortAthenaAIBotRunTimeCustomizationData
|
||||||
{
|
{
|
||||||
@@ -16,5 +17,11 @@ class UFortServerBotManagerAthena : public UObject
|
|||||||
public:
|
public:
|
||||||
static inline AFortPlayerPawnAthena* (*SpawnBotOriginal)(UFortServerBotManagerAthena* BotManager, FVector InSpawnLocation, FRotator InSpawnRotation, UFortAthenaAIBotCustomizationData* InBotData, FFortAthenaAIBotRunTimeCustomizationData InRuntimeBotData);
|
static inline AFortPlayerPawnAthena* (*SpawnBotOriginal)(UFortServerBotManagerAthena* BotManager, FVector InSpawnLocation, FRotator InSpawnRotation, UFortAthenaAIBotCustomizationData* InBotData, FFortAthenaAIBotRunTimeCustomizationData InRuntimeBotData);
|
||||||
|
|
||||||
|
AFortAthenaMutator_Bots*& GetCachedBotMutator()
|
||||||
|
{
|
||||||
|
static auto CachedBotMutatorOffset = GetOffset("CachedBotMutator");
|
||||||
|
return Get<AFortAthenaMutator_Bots*>(CachedBotMutatorOffset);
|
||||||
|
}
|
||||||
|
|
||||||
static AFortPlayerPawnAthena* SpawnBotHook(UFortServerBotManagerAthena* BotManager, FVector& InSpawnLocation, FRotator& InSpawnRotation, UFortAthenaAIBotCustomizationData* InBotData, FFortAthenaAIBotRunTimeCustomizationData* InRuntimeBotData);
|
static AFortPlayerPawnAthena* SpawnBotHook(UFortServerBotManagerAthena* BotManager, FVector& InSpawnLocation, FRotator& InSpawnRotation, UFortAthenaAIBotCustomizationData* InBotData, FFortAthenaAIBotRunTimeCustomizationData* InRuntimeBotData);
|
||||||
};
|
};
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Actor.h"
|
#include "Actor.h"
|
||||||
|
#include "TSubClassOf.h"
|
||||||
|
|
||||||
class APawn : public AActor
|
class APawn : public AActor
|
||||||
{
|
{
|
||||||
@@ -16,4 +17,10 @@ public:
|
|||||||
static auto ControllerOffset = GetOffset("Controller");
|
static auto ControllerOffset = GetOffset("Controller");
|
||||||
return Get<class APlayerController*>(ControllerOffset);
|
return Get<class APlayerController*>(ControllerOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TSubclassOf<class AController> GetAIControllerClass()
|
||||||
|
{
|
||||||
|
static auto AIControllerClassOffset = GetOffset("AIControllerClass");
|
||||||
|
return Get<TSubclassOf<class AController>>(AIControllerClassOffset);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
@@ -70,6 +70,9 @@
|
|||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<PropertyGroup Label="UserMacros" />
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<TargetName>$(ProjectName)</TargetName>
|
||||||
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
@@ -274,6 +277,7 @@
|
|||||||
<ClInclude Include="ActorComponent.h" />
|
<ClInclude Include="ActorComponent.h" />
|
||||||
<ClInclude Include="addresses.h" />
|
<ClInclude Include="addresses.h" />
|
||||||
<ClInclude Include="ai.h" />
|
<ClInclude Include="ai.h" />
|
||||||
|
<ClInclude Include="AIController.h" />
|
||||||
<ClInclude Include="AndOrNot.h" />
|
<ClInclude Include="AndOrNot.h" />
|
||||||
<ClInclude Include="anticheat.h" />
|
<ClInclude Include="anticheat.h" />
|
||||||
<ClInclude Include="Array.h" />
|
<ClInclude Include="Array.h" />
|
||||||
@@ -328,6 +332,7 @@
|
|||||||
<ClInclude Include="FortAbilitySet.h" />
|
<ClInclude Include="FortAbilitySet.h" />
|
||||||
<ClInclude Include="FortAIEncounterInfo.h" />
|
<ClInclude Include="FortAIEncounterInfo.h" />
|
||||||
<ClInclude Include="FortAthenaAIBotCharacterCustomization.h" />
|
<ClInclude Include="FortAthenaAIBotCharacterCustomization.h" />
|
||||||
|
<ClInclude Include="FortAthenaAIBotController.h" />
|
||||||
<ClInclude Include="FortAthenaAIBotCustomizationData.h" />
|
<ClInclude Include="FortAthenaAIBotCustomizationData.h" />
|
||||||
<ClInclude Include="FortAthenaAIBotSpawnerData.h" />
|
<ClInclude Include="FortAthenaAIBotSpawnerData.h" />
|
||||||
<ClInclude Include="FortAthenaAISpawnerDataComponent_CosmeticLoadout.h" />
|
<ClInclude Include="FortAthenaAISpawnerDataComponent_CosmeticLoadout.h" />
|
||||||
|
|||||||
@@ -978,6 +978,12 @@
|
|||||||
<ClInclude Include="FortServerBotManagerAthena.h">
|
<ClInclude Include="FortServerBotManagerAthena.h">
|
||||||
<Filter>FortniteGame\Source\FortniteGame\Public\AI</Filter>
|
<Filter>FortniteGame\Source\FortniteGame\Public\AI</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="FortAthenaAIBotController.h">
|
||||||
|
<Filter>FortniteGame\Source\FortniteGame\Public\AI</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="AIController.h">
|
||||||
|
<Filter>Engine\Source\Runtime\AIModule\Classes</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Filter Include="Engine">
|
<Filter Include="Engine">
|
||||||
|
|||||||
@@ -105,6 +105,27 @@ static bool SetNavigationSystem(AAthenaNavSystemConfigOverride* NavSystemOverrid
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline AFortAthenaMutator_Bots* SpawnBotMutator() //sets up all the classes for phoebe
|
||||||
|
{
|
||||||
|
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
|
||||||
|
auto GameMode = Cast<AFortGameModeAthena>(GetWorld()->GetGameMode());
|
||||||
|
|
||||||
|
static auto BGAClass = FindObject<UClass>(L"/Script/Engine.BlueprintGeneratedClass");
|
||||||
|
static auto PhoebeMutatorClass = LoadObject<UClass>(L"/Game/Athena/AI/Phoebe/BP_Phoebe_Mutator.BP_Phoebe_Mutator_C", BGAClass);
|
||||||
|
|
||||||
|
auto BotMutator = GetWorld()->SpawnActor<AFortAthenaMutator_Bots>(PhoebeMutatorClass);
|
||||||
|
|
||||||
|
static auto CachedGameModeOffset = BotMutator->GetOffset("CachedGameMode");
|
||||||
|
BotMutator->Get(CachedGameModeOffset) = GameMode;
|
||||||
|
|
||||||
|
static auto CachedGameStateOffset = BotMutator->GetOffset("CachedGameState", false);
|
||||||
|
|
||||||
|
if (CachedGameStateOffset != -1)
|
||||||
|
BotMutator->Get(CachedGameStateOffset) = GameState;
|
||||||
|
|
||||||
|
return BotMutator;
|
||||||
|
}
|
||||||
|
|
||||||
static void SetupServerBotManager()
|
static void SetupServerBotManager()
|
||||||
{
|
{
|
||||||
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
|
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
|
||||||
@@ -115,11 +136,10 @@ static void SetupServerBotManager()
|
|||||||
if (!FortServerBotManagerClass)
|
if (!FortServerBotManagerClass)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
static auto ServerBotManagerOffset = GameMode->GetOffset("ServerBotManager");
|
UFortServerBotManagerAthena*& ServerBotManager = GameMode->GetServerBotManager();
|
||||||
UObject*& ServerBotManager = GameMode->Get(ServerBotManagerOffset);
|
|
||||||
|
|
||||||
if (!ServerBotManager)
|
if (!ServerBotManager)
|
||||||
ServerBotManager = UGameplayStatics::SpawnObject(FortServerBotManagerClass, GetTransientPackage());
|
ServerBotManager = (UFortServerBotManagerAthena*)UGameplayStatics::SpawnObject(FortServerBotManagerClass, GetTransientPackage());
|
||||||
|
|
||||||
if (ServerBotManager)
|
if (ServerBotManager)
|
||||||
{
|
{
|
||||||
@@ -132,7 +152,20 @@ static void SetupServerBotManager()
|
|||||||
ServerBotManager->Get(CachedGameStateOffset) = GameState;
|
ServerBotManager->Get(CachedGameStateOffset) = GameState;
|
||||||
|
|
||||||
static auto CachedBotMutatorOffset = ServerBotManager->GetOffset("CachedBotMutator");
|
static auto CachedBotMutatorOffset = ServerBotManager->GetOffset("CachedBotMutator");
|
||||||
ServerBotManager->Get(CachedBotMutatorOffset) = FindFirstMutator(FindObject<UClass>(L"/Script/FortniteGame.FortAthenaMutator_Bots"));
|
auto BotMutator = FindFirstMutator(FindObject<UClass>(L"/Script/FortniteGame.FortAthenaMutator_Bots"));
|
||||||
|
|
||||||
|
if (!BotMutator)
|
||||||
|
{
|
||||||
|
LOG_WARN(LogAI, "Failed to find Bot Mutator! Spawning it..");
|
||||||
|
BotMutator = SpawnBotMutator();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!BotMutator)
|
||||||
|
{
|
||||||
|
LOG_ERROR(LogAI, "Failed to spawn or find Bot Mutator!");
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerBotManager->Get(CachedBotMutatorOffset) = BotMutator;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "FortGameModeAthena.h"
|
#include "FortGameModeAthena.h"
|
||||||
#include "OnlineReplStructs.h"
|
#include "OnlineReplStructs.h"
|
||||||
|
#include "FortAthenaAIBotController.h"
|
||||||
#include "BuildingContainer.h"
|
#include "BuildingContainer.h"
|
||||||
|
|
||||||
class BotPOI
|
class BotPOI
|
||||||
@@ -21,7 +22,13 @@ public:
|
|||||||
class PlayerBot
|
class PlayerBot
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AController* Controller = nullptr;
|
static inline UClass* PawnClass = nullptr;
|
||||||
|
static inline UClass* ControllerClass = nullptr;
|
||||||
|
|
||||||
|
AController* Controller = nullptr; // This can be 1. AFortAthenaAIBotController OR AFortPlayerControllerAthena
|
||||||
|
bool bIsAthenaController = false;
|
||||||
|
AFortPlayerPawnAthena* Pawn = nullptr;
|
||||||
|
AFortPlayerStateAthena* PlayerState = nullptr;
|
||||||
BotPOIEncounter currentBotEncounter;
|
BotPOIEncounter currentBotEncounter;
|
||||||
int TotalPlayersEncountered;
|
int TotalPlayersEncountered;
|
||||||
std::vector<BotPOI> POIsTraveled;
|
std::vector<BotPOI> POIsTraveled;
|
||||||
@@ -38,108 +45,48 @@ public:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Initialize(const FTransform& SpawnTransform)
|
static bool ShouldUseAIBotController()
|
||||||
{
|
{
|
||||||
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
|
return Fortnite_Version >= 11 && Engine_Version < 500;
|
||||||
auto GameMode = Cast<AFortGameModeAthena>(GetWorld()->GetGameMode());
|
}
|
||||||
|
|
||||||
static UClass* PawnClass = nullptr;
|
static void InitializeBotClasses()
|
||||||
static UClass* ControllerClass = nullptr;
|
{
|
||||||
|
static auto BlueprintGeneratedClassClass = FindObject<UClass>(L"/Script/Engine.BlueprintGeneratedClass");
|
||||||
bool bUsePhoebeClasses = false;
|
|
||||||
|
if (!ShouldUseAIBotController())
|
||||||
if (!PawnClass)
|
|
||||||
{
|
{
|
||||||
if (!bUsePhoebeClasses)
|
|
||||||
PawnClass = FindObject<UClass>(L"/Game/Athena/PlayerPawn_Athena.PlayerPawn_Athena_C");
|
PawnClass = FindObject<UClass>(L"/Game/Athena/PlayerPawn_Athena.PlayerPawn_Athena_C");
|
||||||
else
|
|
||||||
PawnClass = FindObject<UClass>(L"/Game/Athena/AI/Phoebe/BP_PlayerPawn_Athena_Phoebe.BP_PlayerPawn_Athena_Phoebe_C");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ControllerClass)
|
|
||||||
{
|
|
||||||
if (!bUsePhoebeClasses)
|
|
||||||
ControllerClass = AFortPlayerControllerAthena::StaticClass();
|
ControllerClass = AFortPlayerControllerAthena::StaticClass();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
ControllerClass = FindObject<UClass>(L"/Game/Athena/AI/Phoebe/BP_PhoebePlayerController.BP_PhoebePlayerController_C");
|
{
|
||||||
|
PawnClass = LoadObject<UClass>(L"/Game/Athena/AI/Phoebe/BP_PlayerPawn_Athena_Phoebe.BP_PlayerPawn_Athena_Phoebe_C", BlueprintGeneratedClassClass);
|
||||||
|
|
||||||
|
// ControllerClass = PawnClass->CreateDefaultObject()->GetAIControllerClass();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ControllerClass || !PawnClass)
|
if (/* !ControllerClass
|
||||||
|
|| */ !PawnClass
|
||||||
|
)
|
||||||
{
|
{
|
||||||
LOG_ERROR(LogBots, "Failed to find a class for the bots!");
|
LOG_ERROR(LogBots, "Failed to find a class for the bots!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static auto FortAthenaAIBotControllerClass = FindObject<UClass>(L"/Script/FortniteGame.FortAthenaAIBotController");
|
|
||||||
|
|
||||||
Controller = GetWorld()->SpawnActor<AController>(ControllerClass);
|
|
||||||
AFortPlayerPawnAthena* Pawn = GetWorld()->SpawnActor<AFortPlayerPawnAthena>(PawnClass, SpawnTransform, CreateSpawnParameters(ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn));
|
|
||||||
AFortPlayerStateAthena* PlayerState = Cast<AFortPlayerStateAthena>(Controller->GetPlayerState());
|
|
||||||
|
|
||||||
if (!Pawn || !PlayerState)
|
|
||||||
return;
|
|
||||||
|
|
||||||
bool bUseOverrideName = false;
|
|
||||||
|
|
||||||
FString NewName;
|
|
||||||
|
|
||||||
if (bUseOverrideName)
|
|
||||||
{
|
|
||||||
NewName = L"Override";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
static int CurrentBotNum = 1;
|
|
||||||
auto BotNumWStr = std::to_wstring(CurrentBotNum++);
|
|
||||||
NewName = (L"RebootBot" + BotNumWStr).c_str();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto PlayerController = Cast<APlayerController>(Controller))
|
static bool IsReadyToSpawnBot()
|
||||||
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() - NumToSubtractFromSquadId;
|
|
||||||
|
|
||||||
GameState->AddPlayerStateToGameMemberInfo(PlayerState);
|
|
||||||
|
|
||||||
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!");
|
return PawnClass;
|
||||||
|
|
||||||
Pawn->K2_DestroyActor();
|
|
||||||
PlayerController->K2_DestroyActor();
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& PlayerInfo = PlayerController->Get(MyPlayerInfoOffset);
|
void SetupInventory()
|
||||||
|
{
|
||||||
static auto UniqueIdOffset = PlayerState->GetOffset("UniqueId");
|
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
|
||||||
static auto PlayerInfo_PlayerNameOffset = PlayerInfo->GetOffset("PlayerName");
|
auto GameMode = Cast<AFortGameModeAthena>(GetWorld()->GetGameMode());
|
||||||
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);
|
|
||||||
|
|
||||||
|
if (!ShouldUseAIBotController()) // TODO REWRITE
|
||||||
|
{
|
||||||
AFortInventory** Inventory = nullptr;
|
AFortInventory** Inventory = nullptr;
|
||||||
|
|
||||||
if (auto FortPlayerController = Cast<AFortPlayerController>(Controller))
|
if (auto FortPlayerController = Cast<AFortPlayerController>(Controller))
|
||||||
@@ -148,7 +95,7 @@ public:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (Controller->IsA(FortAthenaAIBotControllerClass))
|
if (auto FortAthenaAIBotController = Cast<AFortAthenaAIBotController>(Controller))
|
||||||
{
|
{
|
||||||
static auto InventoryOffset = Controller->GetOffset("Inventory");
|
static auto InventoryOffset = Controller->GetOffset("Inventory");
|
||||||
Inventory = Controller->GetPtr<AFortInventory*>(InventoryOffset);
|
Inventory = Controller->GetPtr<AFortInventory*>(InventoryOffset);
|
||||||
@@ -164,10 +111,8 @@ public:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FTransform InventorySpawnTransform{};
|
|
||||||
|
|
||||||
static auto FortInventoryClass = FindObject<UClass>(L"/Script/FortniteGame.FortInventory"); // AFortInventory::StaticClass()
|
static auto FortInventoryClass = FindObject<UClass>(L"/Script/FortniteGame.FortInventory"); // AFortInventory::StaticClass()
|
||||||
*Inventory = GetWorld()->SpawnActor<AFortInventory>(FortInventoryClass, InventorySpawnTransform, CreateSpawnParameters(ESpawnActorCollisionHandlingMethod::AlwaysSpawn, false, Controller));
|
*Inventory = GetWorld()->SpawnActor<AFortInventory>(FortInventoryClass, FTransform{}, CreateSpawnParameters(ESpawnActorCollisionHandlingMethod::AlwaysSpawn, false, Controller));
|
||||||
|
|
||||||
if (!*Inventory)
|
if (!*Inventory)
|
||||||
{
|
{
|
||||||
@@ -212,6 +157,84 @@ public:
|
|||||||
(*Inventory)->Update();
|
(*Inventory)->Update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Initialize(const FTransform& SpawnTransform, AActor* InSpawnLocator)
|
||||||
|
{
|
||||||
|
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
|
||||||
|
auto GameMode = Cast<AFortGameModeAthena>(GetWorld()->GetGameMode());
|
||||||
|
|
||||||
|
if (!IsReadyToSpawnBot())
|
||||||
|
{
|
||||||
|
LOG_ERROR(LogBots, "We are not prepared to spawn a bot!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ShouldUseAIBotController())
|
||||||
|
{
|
||||||
|
Controller = GetWorld()->SpawnActor<AController>(ControllerClass);
|
||||||
|
Pawn = GetWorld()->SpawnActor<AFortPlayerPawnAthena>(PawnClass, SpawnTransform, CreateSpawnParameters(ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn));
|
||||||
|
PlayerState = Cast<AFortPlayerStateAthena>(Controller->GetPlayerState());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Pawn = GameMode->GetServerBotManager()->GetCachedBotMutator()->SpawnBot(PawnClass, InSpawnLocator, SpawnTransform.Translation, SpawnTransform.Rotation.Rotator(), false);
|
||||||
|
|
||||||
|
if (Fortnite_Version < 17)
|
||||||
|
Controller = Cast<AFortAthenaAIBotController>(Pawn->GetController());
|
||||||
|
else
|
||||||
|
Controller = GetWorld()->SpawnActor<AFortAthenaAIBotController>(Pawn->GetAIControllerClass());
|
||||||
|
|
||||||
|
PlayerState = Cast<AFortPlayerStateAthena>(Controller->GetPlayerState());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Controller || !Pawn || !PlayerState)
|
||||||
|
{
|
||||||
|
LOG_ERROR(LogBots, "Failed to spawn controller, pawn or playerstate ({} {})!", bool(__int64(Controller)), bool(__int64(Pawn)), bool(__int64(Controller->GetPlayerState())));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PlayerState->SetIsBot(true);
|
||||||
|
|
||||||
|
if (Controller->GetPawn() != Pawn)
|
||||||
|
{
|
||||||
|
Controller->Possess(Pawn);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CurrentBotNum = 1;
|
||||||
|
auto BotNumWStr = std::to_wstring(CurrentBotNum++);
|
||||||
|
FString NewName = (L"Jimmy" + BotNumWStr).c_str();
|
||||||
|
|
||||||
|
if (true ||
|
||||||
|
Fortnite_Version < 9
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (auto PlayerController = Cast<APlayerController>(Controller))
|
||||||
|
{
|
||||||
|
PlayerController->ServerChangeName(NewName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GameMode->ChangeName(Controller, NewName, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
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() - NumToSubtractFromSquadId;
|
||||||
|
|
||||||
|
GameState->AddPlayerStateToGameMemberInfo(PlayerState);
|
||||||
|
|
||||||
|
Controller->Possess(Pawn);
|
||||||
|
|
||||||
|
Pawn->SetHealth(100);
|
||||||
|
Pawn->SetMaxHealth(100);
|
||||||
|
|
||||||
auto PlayerAbilitySet = GetPlayerAbilitySet();
|
auto PlayerAbilitySet = GetPlayerAbilitySet();
|
||||||
auto AbilitySystemComponent = PlayerState->GetAbilitySystemComponent();
|
auto AbilitySystemComponent = PlayerState->GetAbilitySystemComponent();
|
||||||
@@ -221,13 +244,13 @@ public:
|
|||||||
PlayerAbilitySet->GiveToAbilitySystem(AbilitySystemComponent);
|
PlayerAbilitySet->GiveToAbilitySystem(AbilitySystemComponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SetupInventory();
|
||||||
|
|
||||||
// PlayerController->GetCosmeticLoadout()->GetCharacter() = FindObject("/Game/Athena/Items/Cosmetics/Characters/CID_263_Athena_Commando_F_MadCommander.CID_263_Athena_Commando_F_MadCommander");
|
// 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();
|
// Pawn->GetCosmeticLoadout()->GetCharacter() = PlayerController->GetCosmeticLoadout()->GetCharacter();
|
||||||
|
|
||||||
// PlayerController->ApplyCosmeticLoadout();
|
// PlayerController->ApplyCosmeticLoadout();
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
auto AllHeroTypes = GetAllObjectsOfClass(FindObject<UClass>(L"/Script/FortniteGame.FortHeroType"));
|
auto AllHeroTypes = GetAllObjectsOfClass(FindObject<UClass>(L"/Script/FortniteGame.FortHeroType"));
|
||||||
std::vector<UFortItemDefinition*> AthenaHeroTypes;
|
std::vector<UFortItemDefinition*> AthenaHeroTypes;
|
||||||
|
|
||||||
@@ -249,38 +272,19 @@ public:
|
|||||||
static auto HeroTypeOffset = PlayerState->GetOffset("HeroType");
|
static auto HeroTypeOffset = PlayerState->GetOffset("HeroType");
|
||||||
|
|
||||||
if (HeroTypeOffset != -1)
|
if (HeroTypeOffset != -1)
|
||||||
|
{
|
||||||
PlayerState->Get(HeroTypeOffset) = HeroType;
|
PlayerState->Get(HeroTypeOffset) = HeroType;
|
||||||
|
}
|
||||||
static auto OwningGameInstanceOffset = GetWorld()->GetOffset("OwningGameInstance");
|
|
||||||
auto OwningGameInstance = GetWorld()->Get(OwningGameInstanceOffset);
|
|
||||||
|
|
||||||
static auto RegisteredPlayersOffset = OwningGameInstance->GetOffset("RegisteredPlayers");
|
|
||||||
auto& RegisteredPlayers = OwningGameInstance->Get<TArray<UObject*>>(RegisteredPlayersOffset);
|
|
||||||
|
|
||||||
static auto FortRegisteredPlayerInfoClass = FindObject<UClass>("/Script/FortniteGame.FortRegisteredPlayerInfo");
|
|
||||||
|
|
||||||
auto NewPlayerInfo = UGameplayStatics::SpawnObject(FortRegisteredPlayerInfoClass, Controller);
|
|
||||||
static auto PlayerIDOffset = NewPlayerInfo->GetOffset("PlayerID");
|
|
||||||
|
|
||||||
static auto UniqueIdOffset = PlayerState->GetOffset("UniqueId");
|
|
||||||
auto PlayerStateUniqueId = PlayerState->GetPtr<FUniqueNetIdRepl>(UniqueIdOffset);
|
|
||||||
|
|
||||||
NewPlayerInfo->GetPtr<FUniqueNetIdRepl>(PlayerIDOffset)->CopyFromAnotherUniqueId(PlayerStateUniqueId);
|
|
||||||
|
|
||||||
static auto MyPlayerInfoOffset = Controller->GetOffset("MyPlayerInfo");
|
|
||||||
Controller->Get(MyPlayerInfoOffset) = NewPlayerInfo;
|
|
||||||
|
|
||||||
RegisteredPlayers.Add(NewPlayerInfo);
|
|
||||||
|
|
||||||
ApplyHID(Pawn, HeroType, true);
|
ApplyHID(Pawn, HeroType, true);
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
GameState->GetPlayersLeft()++;
|
GameState->GetPlayersLeft()++;
|
||||||
GameState->OnRep_PlayersLeft();
|
GameState->OnRep_PlayersLeft();
|
||||||
|
|
||||||
if (auto FortPlayerControllerAthena = Cast<AFortPlayerControllerAthena>(Controller))
|
if (auto FortPlayerControllerAthena = Cast<AFortPlayerControllerAthena>(Controller))
|
||||||
GameMode->GetAlivePlayers().Add(FortPlayerControllerAthena);
|
GameMode->GetAlivePlayers().Add(FortPlayerControllerAthena);
|
||||||
|
|
||||||
|
LOG_INFO(LogDev, "Finished spawning bot!")
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -288,10 +292,10 @@ static inline std::vector<PlayerBot> AllPlayerBotsToTick;
|
|||||||
|
|
||||||
namespace Bots
|
namespace Bots
|
||||||
{
|
{
|
||||||
static AController* SpawnBot(FTransform SpawnTransform)
|
static AController* SpawnBot(FTransform SpawnTransform, AActor* InSpawnLocator)
|
||||||
{
|
{
|
||||||
auto playerBot = PlayerBot();
|
auto playerBot = PlayerBot();
|
||||||
playerBot.Initialize(SpawnTransform);
|
playerBot.Initialize(SpawnTransform, InSpawnLocator);
|
||||||
AllPlayerBotsToTick.push_back(playerBot);
|
AllPlayerBotsToTick.push_back(playerBot);
|
||||||
return playerBot.Controller;
|
return playerBot.Controller;
|
||||||
}
|
}
|
||||||
@@ -303,27 +307,36 @@ namespace Bots
|
|||||||
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
|
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
|
||||||
auto GameMode = Cast<AFortGameModeAthena>(GetWorld()->GetGameMode());
|
auto GameMode = Cast<AFortGameModeAthena>(GetWorld()->GetGameMode());
|
||||||
|
|
||||||
|
static auto FortPlayerStartCreativeClass = FindObject<UClass>(L"/Script/FortniteGame.FortPlayerStartCreative");
|
||||||
|
static auto FortPlayerStartWarmupClass = FindObject<UClass>(L"/Script/FortniteGame.FortPlayerStartWarmup");
|
||||||
|
TArray<AActor*> PlayerStarts = UGameplayStatics::GetAllActorsOfClass(GetWorld(), Globals::bCreative ? FortPlayerStartCreativeClass : FortPlayerStartWarmupClass);
|
||||||
|
|
||||||
|
int ActorsNum = PlayerStarts.Num();
|
||||||
|
|
||||||
|
// Actors.Free();
|
||||||
|
|
||||||
|
if (ActorsNum == 0)
|
||||||
|
{
|
||||||
|
// LOG_INFO(LogDev, "No Actors!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find playerstart (scuffed)
|
||||||
|
|
||||||
for (int i = 0; i < AmountOfBots; ++i)
|
for (int i = 0; i < AmountOfBots; ++i)
|
||||||
{
|
{
|
||||||
FTransform SpawnTransform{};
|
AActor* PlayerStart = PlayerStarts.at(std::rand() % (PlayerStarts.size() - 1));
|
||||||
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)
|
if (!PlayerStart)
|
||||||
{
|
{
|
||||||
LOG_ERROR(LogBots, "Failed to find PlayerStart for bot!");
|
return;
|
||||||
NewBot->GetPawn()->K2_DestroyActor();
|
|
||||||
NewBot->K2_DestroyActor();
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NewBot->TeleportTo(PlayerStart->GetActorLocation(), FRotator());
|
auto NewBot = SpawnBot(PlayerStart->GetTransform(), PlayerStart);
|
||||||
NewBot->SetCanBeDamaged(Fortnite_Version < 7); // idk lol for spawn island
|
NewBot->SetCanBeDamaged(Fortnite_Version < 7); // idk lol for spawn island
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Tick()
|
static void Tick()
|
||||||
@@ -346,9 +359,14 @@ namespace Bots
|
|||||||
|
|
||||||
auto CurrentPawn = CurrentPlayer->GetPawn();
|
auto CurrentPawn = CurrentPlayer->GetPawn();
|
||||||
|
|
||||||
|
if (CurrentPawn->IsActorBeingDestroyed())
|
||||||
|
continue;
|
||||||
|
|
||||||
auto CurrentPlayerState = Cast<AFortPlayerStateAthena>(CurrentPlayer->GetPlayerState());
|
auto CurrentPlayerState = Cast<AFortPlayerStateAthena>(CurrentPlayer->GetPlayerState());
|
||||||
|
|
||||||
if (!CurrentPlayerState || !CurrentPlayerState->IsBot())
|
if (!CurrentPlayerState
|
||||||
|
// || !CurrentPlayerState->IsBot()
|
||||||
|
)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (GameState->GetGamePhase() == EAthenaGamePhase::Warmup)
|
if (GameState->GetGamePhase() == EAthenaGamePhase::Warmup)
|
||||||
@@ -362,7 +380,7 @@ namespace Bots
|
|||||||
} */
|
} */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CurrentPlayerState->IsInAircraft() && !CurrentPlayerState->HasThankedBusDriver())
|
if (PlayerBot.bIsAthenaController && CurrentPlayerState->IsInAircraft() && !CurrentPlayerState->HasThankedBusDriver())
|
||||||
{
|
{
|
||||||
static auto ServerThankBusDriverFn = FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerControllerAthena.ServerThankBusDriver");
|
static auto ServerThankBusDriverFn = FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerControllerAthena.ServerThankBusDriver");
|
||||||
CurrentPlayer->ProcessEvent(ServerThankBusDriverFn);
|
CurrentPlayer->ProcessEvent(ServerThankBusDriverFn);
|
||||||
|
|||||||
@@ -789,7 +789,7 @@ void ServerCheatHook(AFortPlayerControllerAthena* PlayerController, FString Msg)
|
|||||||
Transform.Translation = Loc;
|
Transform.Translation = Loc;
|
||||||
Transform.Scale3D = FVector(1, 1, 1);
|
Transform.Scale3D = FVector(1, 1, 1);
|
||||||
|
|
||||||
auto NewActor = Bots::SpawnBot(Transform);
|
auto NewActor = Bots::SpawnBot(Transform, Pawn);
|
||||||
|
|
||||||
if (!NewActor)
|
if (!NewActor)
|
||||||
{
|
{
|
||||||
@@ -801,6 +801,7 @@ void ServerCheatHook(AFortPlayerControllerAthena* PlayerController, FString Msg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (AmountSpawned > 0)
|
||||||
SendMessageToConsole(PlayerController, L"Summoned!");
|
SendMessageToConsole(PlayerController, L"Summoned!");
|
||||||
}
|
}
|
||||||
else if (Command == "sethealth")
|
else if (Command == "sethealth")
|
||||||
|
|||||||
@@ -1005,10 +1005,15 @@ DWORD WINAPI Main(LPVOID)
|
|||||||
|
|
||||||
if (std::floor(Fortnite_Version) == 4)
|
if (std::floor(Fortnite_Version) == 4)
|
||||||
{
|
{
|
||||||
auto RetrieveCharacterPartsAddr = Memcury::Scanner::FindPattern("48 89 5C 24 ? 57 48 83 EC 20 48 8B 01 0F B6 FA 48 8B D9 FF 90 ? ? ? ? 48 8B C8 E8 ? ? ? ? 84 C0 74 0D 33 C0 48 8B 5C 24 ? 48 83 C4 20 5F").Get();
|
auto RetrieveCharacterPartsAddr = Memcury::Scanner::FindPattern("48 89 5C 24 ? 57 48 83 EC 20 48 8B 01 0F B6 FA 48 8B D9 FF 90 ? ? ? ? 48 8B C8 E8 ? ? ? ? 84 C0 74 0D 33 C0 48 8B 5C 24 ? 48 83 C4 20 5F", false).Get();
|
||||||
|
|
||||||
|
if (!RetrieveCharacterPartsAddr)
|
||||||
|
RetrieveCharacterPartsAddr = Memcury::Scanner::FindPattern("40 53 48 83 EC 20 48 8B 01 48 8B D9 FF 90 ? ? ? ? 48 8B C8 E8 ? ? ? ? 84 C0 74 08 33 C0 48 83 C4 20 5B C3 48 8B CB").Get(); // 4.0
|
||||||
|
|
||||||
LOG_INFO(LogDev, "RetrieveCharacterPartsAddr: {}", RetrieveCharacterPartsAddr);
|
LOG_INFO(LogDev, "RetrieveCharacterPartsAddr: {}", RetrieveCharacterPartsAddr);
|
||||||
|
|
||||||
|
if (RetrieveCharacterPartsAddr)
|
||||||
|
{
|
||||||
for (int i = 0; i < 400; i++)
|
for (int i = 0; i < 400; i++)
|
||||||
{
|
{
|
||||||
if (*(uint8_t*)(RetrieveCharacterPartsAddr + i) == 0x74) // jz
|
if (*(uint8_t*)(RetrieveCharacterPartsAddr + i) == 0x74) // jz
|
||||||
@@ -1026,6 +1031,7 @@ DWORD WINAPI Main(LPVOID)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (Globals::bGoingToPlayEvent)
|
if (Globals::bGoingToPlayEvent)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -95,14 +95,18 @@ void SetZoneToIndexHook(AFortGameModeAthena* GameModeAthena, int OverridePhaseMa
|
|||||||
bFilledDurations = true;
|
bFilledDurations = true;
|
||||||
|
|
||||||
auto CurrentPlaylist = GameState->GetCurrentPlaylist();
|
auto CurrentPlaylist = GameState->GetCurrentPlaylist();
|
||||||
UCurveTable* FortGameData = nullptr;
|
|
||||||
|
|
||||||
static auto GameDataOffset = CurrentPlaylist->GetOffset("GameData");
|
static auto GameDataOffset = CurrentPlaylist->GetOffset("GameData");
|
||||||
FortGameData = CurrentPlaylist ? CurrentPlaylist->Get<TSoftObjectPtr<UCurveTable>>(GameDataOffset).Get() : nullptr;
|
UCurveTable* FortGameData = CurrentPlaylist ? CurrentPlaylist->Get<TSoftObjectPtr<UCurveTable>>(GameDataOffset).Get() : nullptr;
|
||||||
|
|
||||||
if (!FortGameData)
|
if (!FortGameData)
|
||||||
FortGameData = FindObject<UCurveTable>(L"/Game/Balance/AthenaGameData.AthenaGameData");
|
FortGameData = FindObject<UCurveTable>(L"/Game/Balance/AthenaGameData.AthenaGameData");
|
||||||
|
|
||||||
|
if (!FortGameData)
|
||||||
|
{
|
||||||
|
LOG_ERROR(LogZone, "Unable to get FortGameData.");
|
||||||
|
return SetZoneToIndexOriginal(GameModeAthena, OverridePhaseMaybeIDFK);
|
||||||
|
}
|
||||||
|
|
||||||
auto ShrinkTimeFName = UKismetStringLibrary::Conv_StringToName(L"Default.SafeZone.ShrinkTime");
|
auto ShrinkTimeFName = UKismetStringLibrary::Conv_StringToName(L"Default.SafeZone.ShrinkTime");
|
||||||
auto HoldTimeFName = UKismetStringLibrary::Conv_StringToName(L"Default.SafeZone.WaitTime");
|
auto HoldTimeFName = UKismetStringLibrary::Conv_StringToName(L"Default.SafeZone.WaitTime");
|
||||||
|
|
||||||
|
|||||||
@@ -585,8 +585,10 @@ static inline uint64 FindSetWorld()
|
|||||||
SetWorldIndex = 0x73;
|
SetWorldIndex = 0x73;
|
||||||
else if (Fortnite_Season >= 19 && Fortnite_Season < 21)
|
else if (Fortnite_Season >= 19 && Fortnite_Season < 21)
|
||||||
SetWorldIndex = 0x7A;
|
SetWorldIndex = 0x7A;
|
||||||
if (Fortnite_Version == 20.40)
|
if (Fortnite_Season == 20) // 20.40
|
||||||
SetWorldIndex = 0x7B;
|
SetWorldIndex = 0x7B;
|
||||||
|
if (Fortnite_Season == 21)
|
||||||
|
SetWorldIndex = 0x7C; // 21.00
|
||||||
|
|
||||||
// static auto DefaultNetDriver = FindObject("/Script/Engine.Default__NetDriver");
|
// static auto DefaultNetDriver = FindObject("/Script/Engine.Default__NetDriver");
|
||||||
return SetWorldIndex;
|
return SetWorldIndex;
|
||||||
@@ -606,6 +608,9 @@ static inline uint64 FindInitListen()
|
|||||||
|
|
||||||
static inline uint64 FindOnDamageServer()
|
static inline uint64 FindOnDamageServer()
|
||||||
{
|
{
|
||||||
|
if (Fortnite_Version >= 20) // 8B 15 on name ref???
|
||||||
|
return Memcury::Scanner::FindPattern("E8 ? ? ? ? 41 39 B4 24").RelativeOffset(1).Get(); // 20.40 (not 21.00)
|
||||||
|
|
||||||
auto Addr = FindFunctionCall(L"OnDamageServer",
|
auto Addr = FindFunctionCall(L"OnDamageServer",
|
||||||
Engine_Version == 416 ? std::vector<uint8_t>{ 0x4C, 0x89, 0x4C } :
|
Engine_Version == 416 ? std::vector<uint8_t>{ 0x4C, 0x89, 0x4C } :
|
||||||
Engine_Version == 419 || Engine_Version >= 427 ? std::vector<uint8_t>{ 0x48, 0x8B, 0xC4 } : std::vector<uint8_t>{ 0x40, 0x55 }
|
Engine_Version == 419 || Engine_Version >= 427 ? std::vector<uint8_t>{ 0x48, 0x8B, 0xC4 } : std::vector<uint8_t>{ 0x40, 0x55 }
|
||||||
|
|||||||
@@ -21,9 +21,7 @@ extern inline double Fortnite_Version = 0; // For example, 4.1, 6.21, etc. // Pr
|
|||||||
extern inline int Fortnite_CL = 0;
|
extern inline int Fortnite_CL = 0;
|
||||||
|
|
||||||
// #define PROD // this doesnt do anything besides remove processeventhook and some assert stuff
|
// #define PROD // this doesnt do anything besides remove processeventhook and some assert stuff
|
||||||
// DEPRACTERD ^^^
|
// DEPRACTERD ^^^ (see Globals::bDeveloperMode)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// #define ABOVE_S20
|
// #define ABOVE_S20
|
||||||
|
|
||||||
|
|||||||
13
vendor/memcury.h
vendored
13
vendor/memcury.h
vendored
@@ -960,6 +960,8 @@
|
|||||||
{
|
{
|
||||||
const auto scanBytes = _address.GetAs<std::uint8_t*>();
|
const auto scanBytes = _address.GetAs<std::uint8_t*>();
|
||||||
|
|
||||||
|
bool bFound = false;
|
||||||
|
|
||||||
for (auto i = (forward ? 1 : -1); forward ? (i < 2048) : (i > -2048); forward ? i++ : i--)
|
for (auto i = (forward ? 1 : -1); forward ? (i < 2048) : (i > -2048); forward ? i++ : i--)
|
||||||
{
|
{
|
||||||
bool found = true;
|
bool found = true;
|
||||||
@@ -971,7 +973,7 @@
|
|||||||
if (currentOpcode == -1)
|
if (currentOpcode == -1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// std::cout << std::format("[{} {}] 0x{:x}\n", i, k, currentOpcode);
|
// LOG_INFO(LogDev, "[{} 0x{:x}] 0x{:x}", i, __int64(&scanBytes[i]) - __int64(GetModuleHandleW(0)), currentOpcode);
|
||||||
|
|
||||||
found = currentOpcode == scanBytes[i + k];
|
found = currentOpcode == scanBytes[i + k];
|
||||||
}
|
}
|
||||||
@@ -984,10 +986,17 @@
|
|||||||
return ScanFor(opcodesToFind, forward, toSkip - 1);
|
return ScanFor(opcodesToFind, forward, toSkip - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bFound = true;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!bFound)
|
||||||
|
{
|
||||||
|
LOG_ERROR(LogDev, "ScanFor failed!");
|
||||||
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1439,6 +1448,8 @@
|
|||||||
if (!NameRef)
|
if (!NameRef)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
LOG_INFO(LogDev, "FindFunctionCall NameRef: 0x{:x}", __int64(NameRef) - __int64(GetModuleHandleW(0)));
|
||||||
|
|
||||||
return Memcury::Scanner(NameRef).ScanFor(Bytes, false).Get();
|
return Memcury::Scanner(NameRef).ScanFor(Bytes, false).Get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user