Skip to content

Commit

Permalink
#213 Implemented bot spawn initialization
Browse files Browse the repository at this point in the history
  • Loading branch information
xthebat committed May 1, 2024
1 parent 45c0991 commit 1c171a5
Show file tree
Hide file tree
Showing 11 changed files with 59 additions and 53 deletions.
Binary file modified Content/Characters/Effects/BP_ShieldEffectBot.uasset
Binary file not shown.
Binary file modified Content/Modes/BP_Cloud9Default.uasset
Binary file not shown.
23 changes: 12 additions & 11 deletions Source/Cloud9/Character/Cloud9Character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include "Cloud9/Character/Effects/Cloud9CharacterEffectTrait.h"
#include "Cloud9/Modes/Cloud9GameMode.h"
#include "Cloud9/Game/Cloud9GameInstance.h"
#include "Cloud9/Tools/Extensions/ACharacter.h"
#include "Components/Cloud9InventoryComponent.h"
#include "Components/Cloud9CharacterMovement.h"
#include "Components/Cloud9SpringArmComponent.h"
Expand Down Expand Up @@ -489,8 +490,9 @@ void ACloud9Character::BeginPlay()
CameraBoom->Deactivate();
}

log(Error, "[Character='%s'] BeginPlay IsPlayer=%d", *GetName(), IsPlayerControlled());
log(Display, "[Character='%s'] IsPlayer=%d", *GetName(), IsPlayerControlled());

// Load all characters (even it's a bot) because LoadCharacter also handle GameMode initialization
if (let GameMode = GetWorld() | EUWorld::GetGameMode<ACloud9GameMode>{})
{
GameMode->LoadCharacter(this);
Expand All @@ -499,16 +501,6 @@ void ACloud9Character::BeginPlay()

void ACloud9Character::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
log(Error, "[Character='%s'] EndPlay IsPlayer=%d", *GetName(), IsPlayerControlled());

if (EndPlayReason == EEndPlayReason::LevelTransition)
{
if (let GameMode = GetWorld() | EUWorld::GetGameMode<ACloud9GameMode>{})
{
GameMode->SaveCharacter(this);
}
}

Super::EndPlay(EndPlayReason);
}

Expand All @@ -522,3 +514,12 @@ void ACloud9Character::Tick(float DeltaSeconds)
InventoryComponent->SelectOtherAvailableWeapon(false);
}
}

void ACloud9Character::OnLevelChanged() const
{
if (let GameMode = GetWorld() | EUWorld::GetGameMode<ACloud9GameMode>{};
IsValid(GameMode) and IsPlayerControlled())
{
GameMode->SaveCharacter(this);
}
}
7 changes: 7 additions & 0 deletions Source/Cloud9/Character/Cloud9Character.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,17 @@ class ACloud9Character : public ACharacter
ACloud9Character(const FObjectInitializer& ObjectInitializer);

virtual void OnConstruction(const FTransform& Transform) override;

virtual void BeginPlay() override;

// Don't touch f...k EndPlay cus we got half-dead object in this callback
// Override left just for the comment above
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;

virtual void Tick(float DeltaSeconds) override;

virtual void OnLevelChanged() const;

/** Returns TopDownCameraComponent subobject **/
FORCEINLINE class UCameraComponent* GetTopDownCameraComponent() const { return TopDownCameraComponent; }

Expand Down
52 changes: 22 additions & 30 deletions Source/Cloud9/Game/Cloud9GameInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,50 +27,42 @@
#include "Cloud9/Character/Components/Cloud9InventoryComponent.h"
#include "Cloud9/Tools/Extensions/ACharacter.h"

void UCloud9GameInstance::SaveCharacterInfo(ACloud9Character* Character)
void UCloud9GameInstance::SaveCharacterInfo(const ACloud9Character* Character)
{
using namespace EACharacter;

if (let PlayerId = Character | GetPlayerId{}; IsPlayerIdValid(PlayerId))
{
var PlayerSavedInfo = FPlayerSavedInfo();
log(Error,
"[Character='%s'] IsPlayer=%d PlayerState=%p PlayerId=%d",
*Character->GetName(),
Character->IsPlayerControlled(),
Character->GetPlayerState(),
Character | EACharacter::GetPlayerId{});

let Inventory = Character->GetInventoryComponent();
var PlayerSavedInfo = FPlayerSavedInfo();

PlayerSavedInfo.WeaponConfigs = Inventory->GetWeapons()
| ETContainer::Filter{[](let Weapon) { return IsValid(Weapon); }}
| ETContainer::Transform{[](let Weapon) { return FWeaponConfig::FromWeapon(Weapon); }}
| ETContainer::ToArray{};
let Inventory = Character->GetInventoryComponent();

if (let SelectedWeapon = Inventory->GetSelectedWeapon(); IsValid(SelectedWeapon))
{
PlayerSavedInfo.WeaponSlot = SelectedWeapon->GetWeaponSlot();
}
PlayerSavedInfo.WeaponConfigs = Inventory->GetWeapons()
| ETContainer::Filter{[](let Weapon) { return IsValid(Weapon); }}
| ETContainer::Transform{[](let Weapon) { return FWeaponConfig::FromWeapon(Weapon); }}
| ETContainer::ToArray{};

SavedInfo.Players[PlayerId] = PlayerSavedInfo;
if (let SelectedWeapon = Inventory->GetSelectedWeapon(); IsValid(SelectedWeapon))
{
PlayerSavedInfo.WeaponSlot = SelectedWeapon->GetWeaponSlot();
}

SavedInfo.Players.Add(Character->GetFName(), PlayerSavedInfo);
}

void UCloud9GameInstance::LoadCharacterInfo(ACloud9Character* Character)
{
using namespace EACharacter;

if (let PlayerId = Character | GetPlayerId{}; IsPlayerIdValid(PlayerId))
{
let Inventory = Character->GetInventoryComponent();
let& PlayerSavedInfo = SavedInfo.Players[PlayerId];
Inventory->Initialize(PlayerSavedInfo.WeaponConfigs, PlayerSavedInfo.WeaponSlot);
}
let Inventory = Character->GetInventoryComponent();
let& PlayerSavedInfo = SavedInfo.Players[Character->GetFName()];
Inventory->Initialize(PlayerSavedInfo.WeaponConfigs, PlayerSavedInfo.WeaponSlot);
}

bool UCloud9GameInstance::HasCharacterInfo(const ACloud9Character* Character) const
{
using namespace EACharacter;

if (let PlayerId = Character | GetPlayerId{}; IsPlayerIdValid(PlayerId))
{
return SavedInfo.Players.Contains(PlayerId);
}

return false;
return SavedInfo.Players.Contains(Character->GetFName());
}
2 changes: 1 addition & 1 deletion Source/Cloud9/Game/Cloud9GameInstance.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class CLOUD9_API UCloud9GameInstance : public UGameInstance
GENERATED_BODY()

public:
void SaveCharacterInfo(ACloud9Character* Character);
void SaveCharacterInfo(const ACloud9Character* Character);

void LoadCharacterInfo(ACloud9Character* Character);

Expand Down
8 changes: 3 additions & 5 deletions Source/Cloud9/Modes/Cloud9DefaultGameMode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@
#include "Cloud9/Character/Components/Cloud9InventoryComponent.h"
// ReSharper disable once CppUnusedIncludeDirective
#include "Cloud9/Character/Components/Cloud9HealthComponent.h"
#include "Cloud9/Tools/Extensions/ACharacter.h"

FName ACloud9DefaultGameMode::PlayerConfigName = TEXT("God");
FName ACloud9DefaultGameMode::BotConfigName = TEXT("Bot");

ACloud9DefaultGameMode::ACloud9DefaultGameMode() {}

void ACloud9DefaultGameMode::SaveCharacter(ACloud9Character* Character)
void ACloud9DefaultGameMode::SaveCharacter(const ACloud9Character* Character)
{
GetCloud9GameInstance()->SaveCharacterInfo(Character);
}
Expand Down Expand Up @@ -46,12 +47,9 @@ void ACloud9DefaultGameMode::InitializeCharacter(ACloud9Character* Character)

let Config = Character->IsPlayerControlled() ? PlayerConfig : BotConfig;

log(Error, "[Character='%s'] InitializeCharacter AsPlayer=%d", *GetName(), Character->IsPlayerControlled());

if (Config == nullptr)
{
log(Warning, "[Character='%s'] Initialization skipped cus config wasn't specified",
*Character->GetName());
log(Warning, "[Character='%s'] Initialization skipped cus config wasn't specified", *Character->GetName());
return;
}

Expand Down
4 changes: 2 additions & 2 deletions Source/Cloud9/Modes/Cloud9DefaultGameMode.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ class CLOUD9_API ACloud9DefaultGameMode : public ACloud9GameMode
ACloud9DefaultGameMode();

protected:
virtual void LoadCharacter(ACloud9Character* Character) override;
virtual void SaveCharacter(const ACloud9Character* Character) override;

virtual void SaveCharacter(ACloud9Character* Character) override;
virtual void LoadCharacter(ACloud9Character* Character) override;

UPROPERTY(Category=Config, EditDefaultsOnly)
TMap<FName, FPlayerSavedInfo> InitialPlayerConfig;
Expand Down
12 changes: 10 additions & 2 deletions Source/Cloud9/Modes/Cloud9GameMode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#include "Cloud9GameMode.h"

#include "EngineUtils.h"
#include "Cloud9/Game/Cloud9GameState.h"
#include "Cloud9/Contollers//Cloud9PlayerController.h"
#include "Cloud9/Character/Cloud9Character.h"
Expand All @@ -35,7 +36,7 @@ ACloud9GameMode::ACloud9GameMode()
GameStateClass = ACloud9GameState::StaticClass();
}

void ACloud9GameMode::SaveCharacter(ACloud9Character* Character) {}
void ACloud9GameMode::SaveCharacter(const ACloud9Character* Character) {}

void ACloud9GameMode::LoadCharacter(ACloud9Character* Character) {}

Expand All @@ -46,13 +47,20 @@ void ACloud9GameMode::StartPlay()

void ACloud9GameMode::StartToLeaveMap()
{
Super::StartToLeaveMap();
// TODO: Maybe move to a delegate pattern
TActorIterator<ACloud9Character>(GetWorld())
| ETContainer::FromIterator{}
| ETContainer::ForEach{
[](let& It) { It.OnLevelChanged(); }
};

if (let MyWorld = GetWorld(); MyWorld != nullptr)
{
log(Verbose, "Cleanup world timers = %p", this);
MyWorld | EUWorld::ClearAllTimers{};
}

Super::StartToLeaveMap();
}

UCloud9GameInstance* ACloud9GameMode::GetCloud9GameInstance() const
Expand Down
2 changes: 1 addition & 1 deletion Source/Cloud9/Modes/Cloud9GameMode.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class ACloud9GameMode : public AGameModeBase
public:
ACloud9GameMode();

virtual void SaveCharacter(ACloud9Character* Character);
virtual void SaveCharacter(const ACloud9Character* Character);

virtual void LoadCharacter(ACloud9Character* Character);

Expand Down
2 changes: 1 addition & 1 deletion Source/Cloud9/Structures/SavedInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ struct FSavedInfo
GENERATED_BODY()

UPROPERTY(Category=Weapon, BlueprintReadOnly)
TMap<int32, FPlayerSavedInfo> Players;
TMap<FName, FPlayerSavedInfo> Players;

void Reset();
};

0 comments on commit 1c171a5

Please sign in to comment.