Skip to content

Commit

Permalink
#248 Work for actor iterator
Browse files Browse the repository at this point in the history
  • Loading branch information
xthebat committed Apr 27, 2024
1 parent 67f9b8c commit 91efbe3
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 91 deletions.
9 changes: 7 additions & 2 deletions Source/Cloud9/Character/Components/Cloud9HealthComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ UCloud9HealthComponent::UCloud9HealthComponent()
Armor = 0.0f;
bHasHelmet = false;
bIsAlive = true;
bIsInvulnerable = false;
}

void UCloud9HealthComponent::Initialize(FHealthConfig Config)
Expand Down Expand Up @@ -65,6 +66,10 @@ bool UCloud9HealthComponent::IncreaseArmor(float Change)
return false;
}

bool UCloud9HealthComponent::GetIsInvulnerable() const { return bIsInvulnerable; }

void UCloud9HealthComponent::SetIsInvulnerable(bool NewValue) { bIsInvulnerable = NewValue; }

bool UCloud9HealthComponent::ChangeHealth(float NewHealth)
{
if (let Value = FMath::Max(NewHealth, 0.0f); Value != Health)
Expand Down Expand Up @@ -166,7 +171,7 @@ void UCloud9HealthComponent::OnTakePointDamage(
const UDamageType* DamageType,
AActor* DamageCauser)
{
TakeHealthDamage(Damage);
TakeHealthDamage(not bIsInvulnerable ? Damage : 0.0f);
AddAttackerScore(InstigatedBy);
}

Expand All @@ -179,6 +184,6 @@ void UCloud9HealthComponent::OnTakeRadialDamage(
AController* InstigatedBy,
AActor* DamageCauser)
{
TakeHealthDamage(Damage);
TakeHealthDamage(not bIsInvulnerable ? Damage : 0.0f);
AddAttackerScore(InstigatedBy);
}
11 changes: 8 additions & 3 deletions Source/Cloud9/Character/Components/Cloud9HealthComponent.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ class CLOUD9_API UCloud9HealthComponent : public UActorComponent
bool IncreaseHealth(float Change);
bool IncreaseArmor(float Change);

// Helmet is permanent(?)
bool ChangeHasHelmet(bool NewState);

UFUNCTION()
Expand Down Expand Up @@ -87,7 +86,10 @@ class CLOUD9_API UCloud9HealthComponent : public UActorComponent
bool HasHelmet() const { return bHasHelmet; }
bool IsAlive() const { return bIsAlive; }

public:
bool GetIsInvulnerable() const;

void SetIsInvulnerable(bool NewValue);

UPROPERTY(BlueprintAssignable, Category=Events)
FOnHealthChange OnHealthChange;

Expand All @@ -108,7 +110,6 @@ class CLOUD9_API UCloud9HealthComponent : public UActorComponent

void AddAttackerScore(const AController* InstigatedBy) const;

protected:
/** Current percentage health of character */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=State, meta=(AllowPrivateAccess))
float Health;
Expand All @@ -124,4 +125,8 @@ class CLOUD9_API UCloud9HealthComponent : public UActorComponent
/** Whether current character dead or alive */
UPROPERTY(BlueprintReadOnly, Category=State, meta=(AllowPrivateAccess))
bool bIsAlive;

/** Whether current character can't take damage */
UPROPERTY(BlueprintReadOnly, Category=State, meta=(AllowPrivateAccess))
bool bIsInvulnerable;
};
13 changes: 12 additions & 1 deletion Source/Cloud9/Character/Effects/Cloud9CharacterShieldEffect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
#include "Cloud9CharacterShieldEffect.h"

#include "Cloud9/Character/Cloud9Character.h"
#include "Cloud9/Character/Components/Cloud9EffectsComponent.h"
#include "Cloud9/Tools/Extensions/TContainer.h"
#include "Cloud9/Character/Components/Cloud9EffectsComponent.h"
#include "Cloud9/Character/Components/Cloud9HealthComponent.h"

const FName UCloud9CharacterShieldEffect::ShieldEnableName = TEXT("Shield Enabled");
const FName UCloud9CharacterShieldEffect::ShieldReflectName = TEXT("Shield Reflect");
Expand All @@ -19,8 +20,18 @@ void UCloud9CharacterShieldEffect::ToggleEffect(bool IsEnabled) const
if (not IsValid(Character))
{
log(Error, "[Effect='%s'] Owner is invalid", *GetName());
return;
}

let HealthComponent = Character->GetHealthComponent();
if (not IsValid(HealthComponent))
{
log(Error, "[Effect='%s'] Character HealthComponent is invalid", *GetName());
return;
}

HealthComponent->SetIsInvulnerable(IsEnabled);

if (let Mesh = Character->GetMesh(); IsValid(Mesh))
{
Mesh->GetMaterials()
Expand Down
46 changes: 30 additions & 16 deletions Source/Cloud9/Modes/Cloud9DefaultGameMode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@
#include "Cloud9/Tools/Macro/Logging.h"
#include "Cloud9/Game/Cloud9GameInstance.h"
#include "Cloud9/Character/Cloud9Character.h"

// ReSharper disable once CppUnusedIncludeDirective
#include "Cloud9/Character/Components/Cloud9InventoryComponent.h"
// ReSharper disable once CppUnusedIncludeDirective
#include "EngineUtils.h"
#include "Cloud9/Character/Components/Cloud9HealthComponent.h"

FName ACloud9DefaultGameMode::CtSidePlayer = TEXT("CT");
FName ACloud9DefaultGameMode::TSidePlayer = TEXT("T");
FName ACloud9DefaultGameMode::GodSidePlayer = TEXT("God");
FName ACloud9DefaultGameMode::PlayerConfigName = TEXT("God");
FName ACloud9DefaultGameMode::BotConfigName = TEXT("Bot");

ACloud9DefaultGameMode::ACloud9DefaultGameMode() {}

Expand Down Expand Up @@ -64,27 +67,38 @@ bool ACloud9DefaultGameMode::OnWorldStart(FSavedInfo& SavedInfo)
}
else
{
if (not InitialPlayerConfig.Contains(GodSidePlayer))
// TODO: Rework initialization process

let PlayerConfig = InitialPlayerConfig.Find(PlayerConfigName);
let BotConfig = InitialPlayerConfig.Find(BotConfigName);

let MyWorld = GameInstance->GetWorld();
if (not IsValid(MyWorld))
{
log(Error, "Can't initialize player for now...")
log(Error, "World isn't exist now -> can't initialize players and bots")
return false;
}

let& PlayerConfig = InitialPlayerConfig[GodSidePlayer];

GameInstance->GetLocalPlayers()
TActorIterator<ACloud9Character>(MyWorld)
| ETContainer::FromIterator{}
| ETContainer::ForEach{
[&PlayerConfig](let LocalPlayer)
[PlayerConfig, BotConfig](var& Character)
{
let Character = GetPlayerCharacter(LocalPlayer);
let Inventory = Character->GetInventoryComponent();
let Health = Character->GetHealthComponent();
if (let Config = Character.IsBotControlled() ? BotConfig : PlayerConfig; Config == nullptr)
{
log(Warning, "[Character='%s'] Initialization skipped cus config wasn't specified",
*Character.GetName());
return;
}

let Inventory = Character.GetInventoryComponent();
let Health = Character.GetHealthComponent();

Inventory->Initialize(PlayerConfig.WeaponConfigs, PlayerConfig.WeaponSlot);
Health->Initialize(PlayerConfig.HealthConfig);
Inventory->Initialize(PlayerConfig->WeaponConfigs, PlayerConfig->WeaponSlot);
Health->Initialize(PlayerConfig->HealthConfig);

PlayerConfig.Effects | ETContainer::ForEach{
[Character](let EffectClass) { Character->AddCharacterEffect(EffectClass); }
PlayerConfig->Effects | ETContainer::ForEach{
[&Character](let EffectClass) { Character.AddCharacterEffect(EffectClass); }
};
}
};
Expand Down
6 changes: 2 additions & 4 deletions Source/Cloud9/Modes/Cloud9DefaultGameMode.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,9 @@ class CLOUD9_API ACloud9DefaultGameMode : public ACloud9GameMode
GENERATED_BODY()

public:
static FName GodSidePlayer;
static FName TSidePlayer;
static FName CtSidePlayer;
static FName PlayerConfigName;
static FName BotConfigName;

public:
ACloud9DefaultGameMode();

protected:
Expand Down
24 changes: 13 additions & 11 deletions Source/Cloud9/Tools/Containers/Sequence.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class TSequence
* Function returns next element of sequence.
*
* NOTE: Sequence is itself iterator so function increments
* internal iterator and then return next self value.
* internal iterator and then returns the next self-value.
*/
TSequence& operator++()
{
Expand All @@ -54,7 +54,7 @@ class TSequence
/**
* Function returns current underlying Iterator value.
*/
const ElementType& operator*() { return *Iterator; }
ElementType& operator*() { return *Iterator; }

/**
* Function returns false if sequence is empty.
Expand All @@ -72,6 +72,12 @@ class TSequence
using TIterator = TSequence;
using TConstIterator = TSequence<const ElementType, IteratorType>;

constexpr TIterator& CreateIterator()
{
Initialize();
return *reinterpret_cast<TIterator*>(this);
}

constexpr TConstIterator& CreateConstIterator()
{
Initialize();
Expand All @@ -81,24 +87,20 @@ class TSequence
// Compatability with stl-like for-based loop

/**
* Tag class required to check if sequence has been finished.
* Tag class required to check if the sequence has been finished.
*/
struct FEndTag {};

/**
* Functions returns begin iterator value to support for-based loop.
* @see note for `TSequence& operator++()`.
*/
constexpr TSequence& begin()
{
Initialize();
return *this;
}
constexpr TSequence& begin() { return CreateIterator(); }

/**
* Functions return end iterator value to support for-based loop.
* NOTE: In fact special tag-object returned only to check if
* underlying Iterator finished or not.
* Function returns end iterator value to support for-based loop.
* NOTE: In fact, special tag-object returned only to check if
* the underlying Iterator finished or not.
*/
constexpr FEndTag end() const { return TSequence::FEndTag(); }

Expand Down
Loading

0 comments on commit 91efbe3

Please sign in to comment.