Fix merge conflicts with feature-ui-and-logics

pull/6/head
eyakm1 2 years ago
commit f798fd22b1

@ -0,0 +1,13 @@
# Default ignored files
/shelf/
/workspace.xml
# Rider ignored files
/modules.xml
/contentModel.xml
/projectSettingsUpdater.xml
/.idea.TurnBased.iml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
</project>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="UserContentModel">
<attachedFolders />
<explicitIncludes />
<explicitExcludes />
</component>
</project>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

@ -31,6 +31,14 @@ AppliedDefaultGraphicsPerformance=Maximum
+PropertyRedirects=(OldName="/Script/TurnBasedTutorial.Trooper.OnPlayersSide",NewName="/Script/TurnBasedTutorial.Trooper.bOnPlayersSide") +PropertyRedirects=(OldName="/Script/TurnBasedTutorial.Trooper.OnPlayersSide",NewName="/Script/TurnBasedTutorial.Trooper.bOnPlayersSide")
+FunctionRedirects=(OldName="/Script/TurnBasedTutorial.MyPlayerController.MoveHero",NewName="/Script/TurnBasedTutorial.MyPlayerController.MoveTropper") +FunctionRedirects=(OldName="/Script/TurnBasedTutorial.MyPlayerController.MoveHero",NewName="/Script/TurnBasedTutorial.MyPlayerController.MoveTropper")
+FunctionRedirects=(OldName="/Script/TurnBasedTutorial.MyPlayerController.MoveTropper",NewName="/Script/TurnBasedTutorial.MyPlayerController.MoveTrooper") +FunctionRedirects=(OldName="/Script/TurnBasedTutorial.MyPlayerController.MoveTropper",NewName="/Script/TurnBasedTutorial.MyPlayerController.MoveTrooper")
+PropertyRedirects=(OldName="/Script/TurnBasedTutorial.ManageSquadTrooper.IndexInSquad",NewName="/Script/TurnBasedTutorial.ManageSquadTrooper.Index")
+PropertyRedirects=(OldName="/Script/TurnBasedTutorial.ManageSquadTrooper.IndexInSquadOrSample",NewName="/Script/TurnBasedTutorial.ManageSquadTrooper.Index")
+FunctionRedirects=(OldName="/Script/TurnBasedTutorial.Trooper.GetActionCost",NewName="/Script/TurnBasedTutorial.Trooper.GetActionRadius")
+FunctionRedirects=(OldName="/Script/TurnBasedTutorial.Trooper.GetActionCost",NewName="/Script/TurnBasedTutorial.Trooper.GetActionRadius")
+PropertyRedirects=(OldName="/Script/TurnBasedTutorial.Trooper.RedMaterialInterface",NewName="/Script/TurnBasedTutorial.Trooper.RedMaterial")
+FunctionRedirects=(OldName="/Script/TurnBasedTutorial.Trooper.HighlightEnemy",NewName="/Script/TurnBasedTutorial.Trooper.HighlightAsEnemy")
+PropertyRedirects=(OldName="/Script/TurnBasedTutorial.Trooper.bIsDying",NewName="/Script/TurnBasedTutorial.Trooper.bIsDead")
+PropertyRedirects=(OldName="/Script/TurnBasedTutorial.Trooper.bIsDying",NewName="/Script/TurnBasedTutorial.Trooper.bIsDead")
[OnlineSubsystem] [OnlineSubsystem]
DefaultPlatformService=Null DefaultPlatformService=Null

@ -78,6 +78,8 @@ DefaultViewportMouseLockMode=LockOnCapture
FOVScale=0.011110 FOVScale=0.011110
DoubleClickTime=0.200000 DoubleClickTime=0.200000
+ActionMappings=(ActionName="MyAction",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=LeftMouseButton) +ActionMappings=(ActionName="MyAction",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=LeftMouseButton)
+AxisMappings=(AxisName="MoveForward",Scale=1.000000,Key=W)
+AxisMappings=(AxisName="MoveForward",Scale=-1.000000,Key=S)
DefaultPlayerInputClass=/Script/Engine.PlayerInput DefaultPlayerInputClass=/Script/Engine.PlayerInput
DefaultInputComponentClass=/Script/Engine.InputComponent DefaultInputComponentClass=/Script/Engine.InputComponent
DefaultTouchInterface=/Engine/MobileResources/HUD/DefaultVirtualJoysticks.DefaultVirtualJoysticks DefaultTouchInterface=/Engine/MobileResources/HUD/DefaultVirtualJoysticks.DefaultVirtualJoysticks

Binary file not shown.

@ -0,0 +1,13 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "MainMenuPlayerController.h"
#include "Blueprint/UserWidget.h"
void AMainMenuPlayerController::BeginPlay() {
Super::BeginPlay();
SetShowMouseCursor(true);
UUserWidget *CreatedWidget = CreateWidget<UUserWidget>(
GetWorld(), WidgetClass);
CreatedWidget->AddToViewport();
}

@ -0,0 +1,22 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "MainMenuPlayerController.generated.h"
/**
*
*/
UCLASS()
class TURNBASEDTUTORIAL_API
AMainMenuPlayerController : public APlayerController {
GENERATED_BODY()
virtual void BeginPlay() override;
protected:
UPROPERTY(EditAnywhere)
TSubclassOf<UUserWidget> WidgetClass;
};

@ -0,0 +1,68 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "MyExplosion.h"
#include "Trooper.h"
#include "Components/SphereComponent.h"
#include "Net/UnrealNetwork.h"
#include "Particles/ParticleSystemComponent.h"
AMyExplosion::AMyExplosion() {
// if (!CollisionComponent) {
// CollisionComponent = CreateDefaultSubobject<USphereComponent>(
// TEXT("SphereComponent"));
// RootComponent = CollisionComponent;
// }
if (!ParticleSystemComponent) {
ParticleSystemComponent = CreateDefaultSubobject<
UParticleSystemComponent>(
TEXT("ParticleSystemComponent"));
RootComponent = ParticleSystemComponent;
}
InitialLifeSpan = 1.0f;
}
void AMyExplosion::Initialize(float damage,
float splashRadius,
uint8 playerIndex) {
Damage = damage;
PlayerIndex = playerIndex;
float Scale = splashRadius / 50;
// CollisionComponent->SetWorldScale3D({Scale, Scale, Scale});
if (ParticleSystemComponent && ParticleSystemComponent->IsValidLowLevel()) {
ParticleSystemComponent->SetWorldScale3D({Scale, Scale, Scale});
}
}
void AMyExplosion::BeginPlay() {
Super::BeginPlay();
}
void AMyExplosion::NotifyActorBeginOverlap(AActor *OtherActor) {
Super::NotifyActorBeginOverlap(OtherActor);
ATrooper *OtherTrooper = Cast<ATrooper>(OtherActor);
if (OtherTrooper) {
UE_LOG(LogTemp, Warning,
TEXT(
"Begin explosion overlap: id: %d, index: %d, damage: %f, my index: %d"
),
OtherTrooper->GetId(), OtherTrooper->GetPlayerIndex(), Damage,
PlayerIndex);
if (PlayerIndex != -1 && PlayerIndex != OtherTrooper->
GetPlayerIndex()) {
OtherTrooper->TakeDamage(Damage);
}
} else {
UE_LOG(LogTemp, Warning, TEXT("Overlapped not a trooper"));
}
}
void AMyExplosion::GetLifetimeReplicatedProps(
TArray<FLifetimeProperty> &OutLifetimeProps) const {
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(AMyExplosion, Damage);
DOREPLIFETIME(AMyExplosion, PlayerIndex);
// DOREPLIFETIME(AMyExplosion, CollisionComponent);
DOREPLIFETIME(AMyExplosion, ParticleSystemComponent);
}

@ -0,0 +1,37 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "Components/SphereComponent.h"
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyExplosion.generated.h"
UCLASS()
class TURNBASEDTUTORIAL_API AMyExplosion : public AActor {
GENERATED_BODY()
public:
AMyExplosion();
void Initialize(float damage,
float splashRadius,
uint8 playerIndex);
protected:
virtual void BeginPlay() override;
virtual void NotifyActorBeginOverlap(AActor *OtherActor) override;
UPROPERTY(Replicated)
float Damage;
UPROPERTY(Replicated)
int8 PlayerIndex = -1;
// UPROPERTY(EditAnywhere, Replicated)
// USphereComponent *CollisionComponent;
UPROPERTY(EditAnywhere, Replicated)
UParticleSystemComponent *ParticleSystemComponent;
};

@ -238,7 +238,7 @@ void UMyGameInstanceSubsystem::FindSessions(int32 MaxSearchResults, bool bIsLANQ
LastSessionSearch->QuerySettings.Set(SEARCH_PRESENCE, true, EOnlineComparisonOp::Equals); LastSessionSearch->QuerySettings.Set(SEARCH_PRESENCE, true, EOnlineComparisonOp::Equals);
const ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController(); const ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController();
if (!SessionInterface->FindSessions(*LocalPlayer->GetPreferredUniqueNetId(), LastSessionSearch.ToSharedRef()) if (!SessionInterface->FindSessions(*LocalPlayer->GetPreferredUniqueNetId(), LastSessionSearch.ToSharedRef()))
{ {
SessionInterface->ClearOnFindSessionsCompleteDelegate_Handle(FindSessionsCompleteDelegateHandle); SessionInterface->ClearOnFindSessionsCompleteDelegate_Handle(FindSessionsCompleteDelegateHandle);

@ -12,24 +12,23 @@ auto AMyGameState::GetMyPlayerState(uint8 PlayerIndex) const {
void AMyGameState::BeginPlay() { void AMyGameState::BeginPlay() {
Super::BeginPlay(); Super::BeginPlay();
LivingTroopers.SetNum(2);
} }
void AMyGameState::AddTrooper_Implementation(ATrooper *Trooper) { void AMyGameState::AddTrooper_Implementation(ATrooper *Trooper) {
if (Trooper->GetPlayerIndex() >= 0 && Trooper->GetPlayerIndex() <= LivingTroopers.Num()) {
LivingTroopers[Trooper->GetPlayerIndex()]++;
}
Troopers.Add(Trooper); Troopers.Add(Trooper);
} }
void AMyGameState::StartGame_Implementation() const { void AMyGameState::StartGame_Implementation() {
PlayerNotInTurn()->SetEnemySelection(Troopers); PlayerNotInTurn()->SetEnemySelection();
PlayerInTurn()->SetEnemySelection(Troopers); PlayerInTurn()->SetEnemySelection();
bGameStarted = true;
PlayerInTurn()->StartTurn(); PlayerInTurn()->StartTurn();
} }
// void AMyGameState::StartGame() const {
// PlayerNotInTurn()->SetEnemySelection(Troopers);
// PlayerInTurn()->SetEnemySelection(Troopers);
// PlayerInTurn()->StartTurn();
// }
void AMyGameState::CycleTurns_Implementation() { void AMyGameState::CycleTurns_Implementation() {
PlayerInTurn()->EndTurn(); PlayerInTurn()->EndTurn();
for (const auto Trooper : Troopers) { for (const auto Trooper : Troopers) {
@ -70,9 +69,25 @@ bool AMyGameState::IsInTurn(uint8 PlayerIndex) const {
return PlayerIndex == CurrentPlayerTurn; return PlayerIndex == CurrentPlayerTurn;
} }
bool AMyGameState::IsGameStarted() const {
return bGameStarted;
}
void AMyGameState::DecreaseLivingTroopers(int PlayerIndex) {
if (bGameIsOver)
return;
LivingTroopers[PlayerIndex]--;
if (LivingTroopers[PlayerIndex] <= 0) {
UE_LOG(LogTemp, Warning, TEXT("Player %d lose!"), PlayerIndex);
bGameIsOver = true;
}
}
void AMyGameState::GetLifetimeReplicatedProps( void AMyGameState::GetLifetimeReplicatedProps(
TArray<FLifetimeProperty> &OutLifetimeProps) const { TArray<FLifetimeProperty> &OutLifetimeProps) const {
Super::GetLifetimeReplicatedProps(OutLifetimeProps); Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(AMyGameState, Troopers); DOREPLIFETIME(AMyGameState, Troopers);
DOREPLIFETIME(AMyGameState, CurrentPlayerTurn); DOREPLIFETIME(AMyGameState, CurrentPlayerTurn);
DOREPLIFETIME(AMyGameState, bGameStarted);
} }

@ -21,7 +21,7 @@ public:
void AddTrooper(ATrooper *Trooper); void AddTrooper(ATrooper *Trooper);
UFUNCTION(Server, Reliable) UFUNCTION(Server, Reliable)
void StartGame() const; void StartGame();
UFUNCTION(BlueprintCallable, Server, Reliable) UFUNCTION(BlueprintCallable, Server, Reliable)
void CycleTurns(); void CycleTurns();
@ -38,10 +38,25 @@ public:
UFUNCTION() UFUNCTION()
bool IsInTurn(uint8 PlayerIndex) const; bool IsInTurn(uint8 PlayerIndex) const;
UFUNCTION()
bool IsGameStarted() const;
UFUNCTION()
void DecreaseLivingTroopers(int PlayerIndex);
private: private:
UPROPERTY(Replicated)
bool bGameIsOver = false;
UPROPERTY(Replicated) UPROPERTY(Replicated)
TArray<ATrooper *> Troopers; TArray<ATrooper *> Troopers;
UPROPERTY(Replicated)
TArray<int> LivingTroopers;
UPROPERTY(Replicated)
bool bGameStarted = false;
UPROPERTY(Replicated) UPROPERTY(Replicated)
uint8 CurrentPlayerTurn{0}; uint8 CurrentPlayerTurn{0};

@ -15,6 +15,20 @@ void AMyPawn::BeginPlay() {
Super::BeginPlay(); Super::BeginPlay();
} }
void AMyPawn::MoveForward(float Val) {
if (Val != 0.f)
{
if (Controller)
{
FRotator ControlSpaceRot = Controller->GetControlRotation();
ControlSpaceRot.Pitch = 0;
// transform to world space and add it
AddMovementInput( FRotationMatrix(ControlSpaceRot).GetScaledAxis( EAxis::X ), Val );
}
}
}
// Called every frame // Called every frame
void AMyPawn::Tick(float DeltaTime) { void AMyPawn::Tick(float DeltaTime) {
Super::Tick(DeltaTime); Super::Tick(DeltaTime);

@ -19,6 +19,8 @@ protected:
// Called when the game starts or when spawned // Called when the game starts or when spawned
virtual void BeginPlay() override; virtual void BeginPlay() override;
virtual void MoveForward(float Val) override;
public: public:
// Called every frame // Called every frame
virtual void Tick(float DeltaTime) override; virtual void Tick(float DeltaTime) override;

@ -5,6 +5,7 @@
#include "MyGameMode.h" #include "MyGameMode.h"
#include "MyGameState.h" #include "MyGameState.h"
#include "MyPlayerState.h" #include "MyPlayerState.h"
#include "Blueprint/UserWidget.h"
#include "Net/UnrealNetwork.h" #include "Net/UnrealNetwork.h"
AMyPlayerController::AMyPlayerController() AMyPlayerController::AMyPlayerController()
@ -13,6 +14,13 @@ AMyPlayerController::AMyPlayerController()
SetShowMouseCursor(true); SetShowMouseCursor(true);
} }
void AMyPlayerController::BeginPlay() {
Super::BeginPlay();
UUserWidget *CreatedWidget = CreateWidget<UUserWidget>(
GetWorld(), WidgetClass);
CreatedWidget->AddToViewport();
}
void AMyPlayerController::SetupInputComponent() { void AMyPlayerController::SetupInputComponent() {
Super::SetupInputComponent(); Super::SetupInputComponent();
InputComponent->BindAction("MyAction", IE_Pressed, this, InputComponent->BindAction("MyAction", IE_Pressed, this,
@ -129,7 +137,7 @@ void AMyPlayerController::EndTurn_Implementation() {
void AMyPlayerController::SetPlayerIndex(uint8 NewPlayerIndex) { void AMyPlayerController::SetPlayerIndex(uint8 NewPlayerIndex) {
PlayerIndex = NewPlayerIndex; PlayerIndex = NewPlayerIndex;
GetMyPlayerState()->SetPlayerIndex(NewPlayerIndex); GetMyPlayerState()->SetPlayerIndex(NewPlayerIndex);
// GetMyPlayerState()->PlayerIndex = NewPlayerIndex; // GetMyPlayerState()->PlayerIndex = NewPlayerIndex;
} }

@ -12,6 +12,8 @@ class TURNBASEDTUTORIAL_API AMyPlayerController : public APlayerController {
GENERATED_BODY() GENERATED_BODY()
public: public:
virtual void BeginPlay() override;
// FOnMyTurnChangedDelegate OnMyTurnChanged; // FOnMyTurnChangedDelegate OnMyTurnChanged;
virtual void SetupInputComponent() override; virtual void SetupInputComponent() override;
@ -49,6 +51,9 @@ public:
// void SetEnemySelection(const TArray<ATrooper *> &Troopers) const; // void SetEnemySelection(const TArray<ATrooper *> &Troopers) const;
private: private:
UPROPERTY(EditAnywhere)
TSubclassOf<UUserWidget> WidgetClass;
// UPROPERTY(Replicated) // UPROPERTY(Replicated)
// bool bIsMyTurn; // bool bIsMyTurn;
// //

@ -4,10 +4,12 @@
#include "MyPlayerState.h" #include "MyPlayerState.h"
#include "MyGameState.h" #include "MyGameState.h"
#include "Kismet/GameplayStatics.h"
#include "Net/UnrealNetwork.h" #include "Net/UnrealNetwork.h"
AMyPlayerState::AMyPlayerState() AMyPlayerState::AMyPlayerState()
: Super(), bIsMyTurn(false), SelectedTrooper(nullptr) { : Super(), bIsMyTurn(false), SelectedTrooper(nullptr) {
// PrimaryActorTick.bCanEverTick = true;
} }
void AMyPlayerState::BeginPlay() { void AMyPlayerState::BeginPlay() {
@ -18,15 +20,35 @@ auto AMyPlayerState::GetMyGameState() const {
return Cast<AMyGameState>(GetWorld()->GetGameState()); return Cast<AMyGameState>(GetWorld()->GetGameState());
} }
// void AMyPlayerState::Tick(float DeltaSeconds) {
// Super::Tick(DeltaSeconds);
// if (GetMyGameState() && GetMyGameState()->IsGameStarted()) {
// // for (const auto Actor : Troopers) {
// // const auto Trooper = Cast<ATrooper>(Actor);
// // if (Trooper != nullptr && Trooper->GetPlayerIndex() !=
// // PlayerIndex) {
// // Trooper->HighlightAsEnemy(PlayerIndex);
// // }
// // }
// bIsSelectionInitialized = true;
// SetActorTickEnabled(false);
// }
// }
void AMyPlayerState::SetPlayerIndex(uint8 NewPlayerIndex) { void AMyPlayerState::SetPlayerIndex(uint8 NewPlayerIndex) {
PlayerIndex = NewPlayerIndex; PlayerIndex = NewPlayerIndex;
} }
void AMyPlayerState::SetEnemySelection_Implementation( void AMyPlayerState::SetEnemySelection_Implementation(
const TArray<ATrooper *> &Troopers) const { /*const TArray<AActor *> &Troopers*/) const {
for (const auto Trooper : Troopers) { TArray<AActor *> Troopers;
if (Trooper != nullptr && Trooper->GetPlayerIndex() != PlayerIndex) { UGameplayStatics::GetAllActorsOfClass(GetWorld(),
Trooper->HighlightAsEnemy(); ATrooper::StaticClass(),
Troopers);
for (const auto Actor : Troopers) {
const auto Trooper = Cast<ATrooper>(Actor);
if (Trooper != nullptr) {
Trooper->HighlightAsEnemy(PlayerIndex);
} }
} }
} }
@ -60,7 +82,8 @@ void AMyPlayerState::MoveTrooper_Implementation(ATrooper *Trooper,
void AMyPlayerState::Attack_Implementation(ATrooper *Attacker, void AMyPlayerState::Attack_Implementation(ATrooper *Attacker,
FVector Location, FVector Location,
int ActionIndex, int ActionIndex,
const TArray<ATrooper *> &Troopers) { const TArray<ATrooper *> &
Troopers) {
if (Attacker->CheckAttackCorrectness(Location, ActionIndex)) { if (Attacker->CheckAttackCorrectness(Location, ActionIndex)) {
Attacker->Attack(ActionIndex, Location); Attacker->Attack(ActionIndex, Location);
// for (const auto Trooper : Troopers) { // for (const auto Trooper : Troopers) {
@ -96,7 +119,6 @@ void AMyPlayerState::SetMyTurn(bool bMyTurn) {
} }
} }
void AMyPlayerState::StartTurn_Implementation() { void AMyPlayerState::StartTurn_Implementation() {
SetMyTurn(true); SetMyTurn(true);
UE_LOG(LogTemp, Warning, TEXT("Your turn, %d"), PlayerIndex); UE_LOG(LogTemp, Warning, TEXT("Your turn, %d"), PlayerIndex);
@ -104,7 +126,8 @@ void AMyPlayerState::StartTurn_Implementation() {
void AMyPlayerState::EndTurn_Implementation() { void AMyPlayerState::EndTurn_Implementation() {
if (bIsMyTurn) { if (bIsMyTurn) {
UE_LOG(LogTemp, Warning, TEXT("End Turn from player %d"), PlayerIndex); UE_LOG(LogTemp, Warning, TEXT("End Turn from player %d"),
PlayerIndex);
SetMyTurn(false); SetMyTurn(false);
if (SelectedTrooper) { if (SelectedTrooper) {
SelectedTrooper->SetSelection(false, CurrentAction); SelectedTrooper->SetSelection(false, CurrentAction);
@ -117,7 +140,6 @@ void AMyPlayerState::EndTurn_Implementation() {
} }
} }
void AMyPlayerState::OnPlayerAction(const FHitResult &HitResult) { void AMyPlayerState::OnPlayerAction(const FHitResult &HitResult) {
auto const NewlySelectedLocation = HitResult.Location; auto const NewlySelectedLocation = HitResult.Location;
ATrooper *NewlySelectedTrooper = Cast<ATrooper>( ATrooper *NewlySelectedTrooper = Cast<ATrooper>(
@ -132,7 +154,8 @@ void AMyPlayerState::OnPlayerAction(const FHitResult &HitResult) {
if (NewlySelectedTrooper == nullptr || !NewlySelectedTrooper-> if (NewlySelectedTrooper == nullptr || !NewlySelectedTrooper->
IsValidLowLevel() || NewlySelectedTrooper->GetPlayerIndex() != IsValidLowLevel() || NewlySelectedTrooper->GetPlayerIndex() !=
PlayerIndex) { PlayerIndex) {
if (SelectedTrooper != nullptr && SelectedTrooper->IsValidLowLevel()) { if (SelectedTrooper != nullptr && SelectedTrooper->
IsValidLowLevel()) {
switch (CurrentAction) { switch (CurrentAction) {
case 0: case 0:
UE_LOG(LogTemp, Warning, TEXT("Do move")); UE_LOG(LogTemp, Warning, TEXT("Do move"));
@ -153,7 +176,8 @@ void AMyPlayerState::OnPlayerAction(const FHitResult &HitResult) {
} }
} }
} else if (NewlySelectedTrooper != nullptr && NewlySelectedTrooper-> } else if (NewlySelectedTrooper != nullptr && NewlySelectedTrooper->
IsValidLowLevel() && NewlySelectedTrooper->GetPlayerIndex() == IsValidLowLevel() && NewlySelectedTrooper->GetPlayerIndex()
==
PlayerIndex) { PlayerIndex) {
UE_LOG(LogTemp, Warning, TEXT("Do reselect")); UE_LOG(LogTemp, Warning, TEXT("Do reselect"));
// our move, selection // our move, selection
@ -170,11 +194,11 @@ void AMyPlayerState::SetCurrentAction_Implementation(int Action) {
if (SelectedTrooper) { if (SelectedTrooper) {
SelectedTrooper->UpdateSelectionRadius(Action); SelectedTrooper->UpdateSelectionRadius(Action);
} }
UE_LOG(LogTemp, Warning, TEXT("SetCurrentAction: %d on Player Controller " UE_LOG(LogTemp, Warning,
TEXT("SetCurrentAction: %d on Player Controller "
"with index %d"), CurrentAction, PlayerIndex); "with index %d"), CurrentAction, PlayerIndex);
} }
uint8 AMyPlayerState::GetPlayerIndex() const { uint8 AMyPlayerState::GetPlayerIndex() const {
return PlayerIndex; return PlayerIndex;
} }
@ -186,4 +210,5 @@ void AMyPlayerState::GetLifetimeReplicatedProps(
DOREPLIFETIME(AMyPlayerState, CurrentAction); DOREPLIFETIME(AMyPlayerState, CurrentAction);
DOREPLIFETIME(AMyPlayerState, bIsMyTurn); DOREPLIFETIME(AMyPlayerState, bIsMyTurn);
DOREPLIFETIME(AMyPlayerState, SelectedTrooper); DOREPLIFETIME(AMyPlayerState, SelectedTrooper);
DOREPLIFETIME(AMyPlayerState, bIsSelectionInitialized);
} }

@ -19,6 +19,8 @@ public:
virtual void BeginPlay() override; virtual void BeginPlay() override;
// virtual void Tick(float DeltaSeconds) override;
UFUNCTION(Client, Reliable) UFUNCTION(Client, Reliable)
void StartTurn(); void StartTurn();
@ -53,10 +55,11 @@ public:
void SetPlayerIndex(uint8 NewPlayerIndex); void SetPlayerIndex(uint8 NewPlayerIndex);
UFUNCTION(Client, Reliable) UFUNCTION(Client, Reliable)
void SetEnemySelection(const TArray<ATrooper *> &Troopers) const; void SetEnemySelection(/*const TArray<AActor *> &Troopers*/) const;
private: private:
UPROPERTY(Replicated)
bool bIsSelectionInitialized = false;
UPROPERTY(Replicated) UPROPERTY(Replicated)
uint8 PlayerIndex; uint8 PlayerIndex;

@ -47,6 +47,7 @@ void AMyProjectile::Initialize(const UAbility *Ability,
ProjectileMovementComponent->InitialSpeed = ProjectileMovementComponent->InitialSpeed =
ProjectileMovementComponent->MaxSpeed = Ability->Speed; ProjectileMovementComponent->MaxSpeed = Ability->Speed;
Damage = Ability->Damage; Damage = Ability->Damage;
SplashRadius = Ability->SplashRadius;
float Scale = Ability->LinearWidth / 100; float Scale = Ability->LinearWidth / 100;
// CollisionComponent->SetSphereRadius(Ability->LinearWidth / 2); // CollisionComponent->SetSphereRadius(Ability->LinearWidth / 2);
ProjectileMeshComponent->SetWorldScale3D({Scale, Scale, Scale}); ProjectileMeshComponent->SetWorldScale3D({Scale, Scale, Scale});
@ -77,38 +78,55 @@ void AMyProjectile::NotifyActorBeginOverlap(AActor *OtherActor) {
} }
} }
void AMyProjectile::NotifyHit(UPrimitiveComponent *MyComp, // void AMyProjectile::NotifyHit(UPrimitiveComponent *MyComp,
AActor *Other, // AActor *Other,
UPrimitiveComponent *OtherComp, // UPrimitiveComponent *OtherComp,
bool bSelfMoved, // bool bSelfMoved,
FVector HitLocation, // FVector HitLocation,
FVector HitNormal, // FVector HitNormal,
FVector NormalImpulse, // FVector NormalImpulse,
const FHitResult &Hit) { // const FHitResult &Hit) {
Super::NotifyHit(MyComp, Other, OtherComp, bSelfMoved, HitLocation, // Super::NotifyHit(MyComp, Other, OtherComp, bSelfMoved, HitLocation,
HitNormal, // HitNormal,
NormalImpulse, Hit); // NormalImpulse, Hit);
ATrooper *OtherTrooper = Cast<ATrooper>(Other); // ATrooper *OtherTrooper = Cast<ATrooper>(Other);
if (OtherTrooper) { // if (OtherTrooper) {
UE_LOG(LogTemp, Warning, // UE_LOG(LogTemp, Warning,
TEXT("On Hit: id: %d, index: %d, damage: %f, my index: %d" // TEXT("On Hit: id: %d, index: %d, damage: %f, my index: %d"
), // ),
OtherTrooper->GetId(), OtherTrooper->GetPlayerIndex(), Damage, // OtherTrooper->GetId(), OtherTrooper->GetPlayerIndex(), Damage,
PlayerIndex); // PlayerIndex);
if (PlayerIndex != -1 && PlayerIndex != OtherTrooper-> // if (PlayerIndex != -1 && PlayerIndex != OtherTrooper->
GetPlayerIndex()) { // GetPlayerIndex()) {
OtherTrooper->TakeDamage(Damage); // OtherTrooper->TakeDamage(Damage);
} // }
} else { // } else {
UE_LOG(LogTemp, Warning, TEXT("Overlapped not a trooper")); // UE_LOG(LogTemp, Warning, TEXT("Overlapped not a trooper"));
} // }
} // }
void AMyProjectile::BeginPlay() { void AMyProjectile::BeginPlay() {
Super::BeginPlay(); Super::BeginPlay();
} }
void AMyProjectile::EndPlay(const EEndPlayReason::Type EndPlayReason) {
Super::EndPlay(EndPlayReason);
Explode();
}
void AMyProjectile::Explode_Implementation() const {
const FTransform SpawnTransform = GetTransform();
FActorSpawnParameters SpawnParameters;
SpawnParameters.Instigator = GetInstigator();
SpawnParameters.SpawnCollisionHandlingOverride =
ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
AMyExplosion *Explosion = GetWorld()->SpawnActor<AMyExplosion>(
ExplosionSubclass, SpawnTransform, SpawnParameters);
Explosion->Initialize(Damage, SplashRadius, PlayerIndex);
Explosion->SetActorLocation(GetActorLocation());
}
void AMyProjectile::GetLifetimeReplicatedProps( void AMyProjectile::GetLifetimeReplicatedProps(
TArray<FLifetimeProperty> &OutLifetimeProps) const { TArray<FLifetimeProperty> &OutLifetimeProps) const {
Super::GetLifetimeReplicatedProps(OutLifetimeProps); Super::GetLifetimeReplicatedProps(OutLifetimeProps);
@ -117,4 +135,5 @@ void AMyProjectile::GetLifetimeReplicatedProps(
// DOREPLIFETIME(AMyProjectile, CollisionComponent); // DOREPLIFETIME(AMyProjectile, CollisionComponent);
DOREPLIFETIME(AMyProjectile, ProjectileMeshComponent); DOREPLIFETIME(AMyProjectile, ProjectileMeshComponent);
DOREPLIFETIME(AMyProjectile, ProjectileMovementComponent); DOREPLIFETIME(AMyProjectile, ProjectileMovementComponent);
DOREPLIFETIME(AMyProjectile, SplashRadius);
} }

@ -4,6 +4,7 @@
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "Ability.h" #include "Ability.h"
#include "MyExplosion.h"
#include "Components/SphereComponent.h" #include "Components/SphereComponent.h"
#include "GameFramework/Actor.h" #include "GameFramework/Actor.h"
#include "GameFramework/ProjectileMovementComponent.h" #include "GameFramework/ProjectileMovementComponent.h"
@ -24,15 +25,18 @@ public:
protected: protected:
virtual void NotifyActorBeginOverlap(AActor *OtherActor) override; virtual void NotifyActorBeginOverlap(AActor *OtherActor) override;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TSubclassOf<AMyExplosion> ExplosionSubclass;
virtual void NotifyHit(UPrimitiveComponent *MyComp, // virtual void NotifyHit(UPrimitiveComponent *MyComp,
AActor *Other, // AActor *Other,
UPrimitiveComponent *OtherComp, // UPrimitiveComponent *OtherComp,
bool bSelfMoved, // bool bSelfMoved,
FVector HitLocation, // FVector HitLocation,
FVector HitNormal, // FVector HitNormal,
FVector NormalImpulse, // FVector NormalImpulse,
const FHitResult &Hit) override; // const FHitResult &Hit) override;
UPROPERTY(Replicated) UPROPERTY(Replicated)
float Damage; float Damage;
@ -40,6 +44,9 @@ protected:
UPROPERTY(Replicated) UPROPERTY(Replicated)
int8 PlayerIndex = -1; int8 PlayerIndex = -1;
UPROPERTY(Replicated)
float SplashRadius;
// UPROPERTY(EditAnywhere, Replicated) // UPROPERTY(EditAnywhere, Replicated)
// USphereComponent *CollisionComponent; // USphereComponent *CollisionComponent;
@ -50,4 +57,9 @@ protected:
UProjectileMovementComponent *ProjectileMovementComponent; UProjectileMovementComponent *ProjectileMovementComponent;
virtual void BeginPlay() override; virtual void BeginPlay() override;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
UFUNCTION(Server, Reliable)
void Explode() const;
}; };

@ -2,6 +2,7 @@
#include <Kismet/GameplayStatics.h> #include <Kismet/GameplayStatics.h>
#include "HealthBar.h" #include "HealthBar.h"
#include "MyGameState.h"
#include "MyPlayerController.h" #include "MyPlayerController.h"
#include "MyPlayerState.h" #include "MyPlayerState.h"
#include "MyProjectile.h" #include "MyProjectile.h"
@ -113,22 +114,22 @@ void ATrooper::Tick(float const DeltaTime) {
} }
} }
void ATrooper::OnRepNotify_PlayerIndex() const { // void ATrooper::OnRepNotify_PlayerIndex() const {
const AMyPlayerState *player = Cast<AMyPlayerState>( // const AMyPlayerState *player = Cast<AMyPlayerState>(
GetPlayerState()); // GetPlayerState());
if (!player) // if (!player)
return; // return;
const uint8 ClientIndex = player->GetPlayerIndex(); // const uint8 ClientIndex = player->GetPlayerIndex();
UE_LOG(LogTemp, Warning, // UE_LOG(LogTemp, Warning,
TEXT("On rep notify, index: %d, client index: %d, id: %d"), // TEXT("On rep notify, index: %d, client index: %d, id: %d"),
PlayerIndex, // PlayerIndex,
ClientIndex, Id); // ClientIndex, Id);
if (ClientIndex == PlayerIndex) { // if (ClientIndex == PlayerIndex) {
HighlightAsEnemy(); // HighlightAsEnemy();
} // }
} // }
void ATrooper::MoveTrooper(FVector const NewPos) { void ATrooper::MoveTrooper_Implementation(FVector const NewPos) {
TargetLocation = NewPos; TargetLocation = NewPos;
bIsMoving = true; bIsMoving = true;
ActionPoints -= (NewPos - CurrentLocation).Size() * MoveCost; ActionPoints -= (NewPos - CurrentLocation).Size() * MoveCost;
@ -158,7 +159,7 @@ void ATrooper::GetLifetimeReplicatedProps(
DOREPLIFETIME(ATrooper, CurrentAbilityDestination); DOREPLIFETIME(ATrooper, CurrentAbilityDestination);
} }
uint8 ATrooper::GetPlayerIndex() const { int8 ATrooper::GetPlayerIndex() const {
return PlayerIndex; return PlayerIndex;
} }
@ -225,8 +226,10 @@ void ATrooper::UpdateSelectionRadius(uint8 ActionType) const {
{radiusScale, radiusScale, 0.01f}); {radiusScale, radiusScale, 0.01f});
} }
void ATrooper::HighlightAsEnemy_Implementation() const { void ATrooper::HighlightAsEnemy_Implementation(int8 Index) const {
SelectionStaticMesh->SetVisibility(true); if (PlayerIndex != Index) {
SelectionStaticMesh->SetVisibility(true);
}
} }
void ATrooper::ResetActionPoints() { void ATrooper::ResetActionPoints() {
@ -244,17 +247,18 @@ UAbility *ATrooper::GetAbility(int AbilityIndex) const {
} }
} }
bool ATrooper::TakeDamage(float Damage) { void ATrooper::TakeDamage_Implementation(float Damage) {
if (bIsTakingDamage) { if (bIsTakingDamage || bIsDead) {
return false; return;
} }
HitPoints = FMath::Max<float>(0, HitPoints - Damage); HitPoints = FMath::Max<float>(0, HitPoints - Damage);
if (HitPoints == 0) { if (HitPoints == 0) {
bIsDead = true; bIsDead = true;
return true; SetLifeSpan(DyingAnimationDuration);
GetWorld()->GetGameState<AMyGameState>()->DecreaseLivingTroopers(PlayerIndex);
} else {
bIsTakingDamage = true;
} }
bIsTakingDamage = true;
return false;
} }
TSubclassOf<AMyProjectile> ATrooper::GetProjectileClass( TSubclassOf<AMyProjectile> ATrooper::GetProjectileClass(
@ -310,7 +314,7 @@ int ATrooper::GetAnimationValue() {
return 0; return 0;
} }
void ATrooper::Attack(int AbilityIndex, FVector ToLocation) { void ATrooper::Attack_Implementation(int AbilityIndex, FVector ToLocation) {
bIsAttacking = true; bIsAttacking = true;
bIsWaitingForFire = true; bIsWaitingForFire = true;
ActionPoints -= GetAbility(AbilityIndex)->ActionCost; ActionPoints -= GetAbility(AbilityIndex)->ActionCost;

@ -18,9 +18,9 @@ public:
uint8 const NewId); uint8 const NewId);
UFUNCTION() UFUNCTION()
uint8 GetPlayerIndex() const; int8 GetPlayerIndex() const;
UFUNCTION() UFUNCTION(Server, Reliable)
void MoveTrooper(FVector const NewPos); void MoveTrooper(FVector const NewPos);
UFUNCTION() UFUNCTION()
@ -38,7 +38,7 @@ public:
UFUNCTION(BlueprintCallable) UFUNCTION(BlueprintCallable)
int GetAnimationValue(); int GetAnimationValue();
UFUNCTION() UFUNCTION(Server, Reliable)
void Attack(int AbilityIndex, FVector ToLocation); void Attack(int AbilityIndex, FVector ToLocation);
UFUNCTION() UFUNCTION()
@ -57,16 +57,16 @@ public:
void UpdateSelectionRadius(uint8 ActionType) const; void UpdateSelectionRadius(uint8 ActionType) const;
UFUNCTION(Client, Reliable) UFUNCTION(Client, Reliable)
void HighlightAsEnemy() const; void HighlightAsEnemy(int8 Index) const;
UFUNCTION() UFUNCTION()
void ResetActionPoints(); void ResetActionPoints();
UFUNCTION() UFUNCTION()
UAbility *GetAbility(int AbilityIndex) const; UAbility *GetAbility(int AbilityIndex) const;
UFUNCTION() UFUNCTION(Server, Reliable)
bool TakeDamage(float Damage); void TakeDamage(float Damage);
protected: protected:
constexpr static float PIXELS_IN_RADIUS = 50; constexpr static float PIXELS_IN_RADIUS = 50;
@ -139,6 +139,8 @@ protected:
float TakingDamagePlayedTime; float TakingDamagePlayedTime;
const float TakingDamageDuration = 1.46667f; const float TakingDamageDuration = 1.46667f;
const float DyingAnimationDuration = 2.83333f;
UPROPERTY(Replicated) UPROPERTY(Replicated)
bool bIsDead = false; bool bIsDead = false;
@ -160,11 +162,11 @@ protected:
// const TCHAR *MeshPath = nullptr; // const TCHAR *MeshPath = nullptr;
UFUNCTION() // UFUNCTION()
void OnRepNotify_PlayerIndex() const; // void OnRepNotify_PlayerIndex() const;
UPROPERTY(ReplicatedUsing = OnRepNotify_PlayerIndex) UPROPERTY(Replicated/*Using = OnRepNotify_PlayerIndex*/)
uint8 PlayerIndex = -1; int8 PlayerIndex = -1;
UPROPERTY(Replicated) UPROPERTY(Replicated)
uint8 Id; uint8 Id;

@ -0,0 +1,2 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/PencilsConfiguration/ActualSeverity/@EntryValue">INFO</s:String></wpf:ResourceDictionary>

@ -0,0 +1,25 @@
TurnBased/Binaries/Win64/TurnBasedTutorial.exe 2023-03-16T03:05:02.259Z
TurnBased/Binaries/Win64/OpenImageDenoise.dll 2023-03-16T01:52:15.842Z
TurnBased/Binaries/Win64/tbb12.dll 2023-03-16T01:52:15.844Z
Engine/Extras/Redist/en-us/UE4PrereqSetup_x64.exe 2023-03-16T01:46:38.646Z
Engine/Binaries/ThirdParty/Oculus/OVRPlugin/OVRPlugin/Win64/OVRPlugin.dll 2023-03-16T01:41:33.496Z
Engine/Binaries/ThirdParty/DbgHelp/dbghelp.dll 2023-03-16T01:41:25.090Z
Engine/Binaries/ThirdParty/PhysX3/Win64/VS2015/PxFoundationPROFILE_x64.dll 2023-03-16T01:41:46.155Z
Engine/Binaries/ThirdParty/PhysX3/Win64/VS2015/PxPvdSDKPROFILE_x64.dll 2023-03-16T01:41:46.339Z
Engine/Binaries/ThirdParty/PhysX3/Win64/VS2015/PhysX3PROFILE_x64.dll 2023-03-16T01:41:45.025Z
Engine/Binaries/ThirdParty/PhysX3/Win64/VS2015/PhysX3CookingPROFILE_x64.dll 2023-03-16T01:41:45.005Z
Engine/Binaries/ThirdParty/PhysX3/Win64/VS2015/PhysX3CommonPROFILE_x64.dll 2023-03-16T01:41:44.869Z
Engine/Binaries/ThirdParty/PhysX3/Win64/VS2015/APEX_ClothingPROFILE_x64.dll 2023-03-16T01:41:41.229Z
Engine/Binaries/ThirdParty/PhysX3/Win64/VS2015/APEX_LegacyPROFILE_x64.dll 2023-03-16T01:41:42.482Z
Engine/Binaries/ThirdParty/PhysX3/Win64/VS2015/ApexFrameworkPROFILE_x64.dll 2023-03-16T01:41:43.065Z
Engine/Binaries/ThirdParty/PhysX3/Win64/VS2015/NvClothPROFILE_x64.dll 2023-03-16T01:41:43.666Z
Engine/Binaries/ThirdParty/Ogg/Win64/VS2015/libogg_64.dll 2023-03-16T01:41:33.497Z
Engine/Binaries/ThirdParty/Vorbis/Win64/VS2015/libvorbis_64.dll 2023-03-16T01:41:53.464Z
Engine/Binaries/ThirdParty/Vorbis/Win64/VS2015/libvorbisfile_64.dll 2023-03-16T01:41:53.464Z
Engine/Binaries/ThirdParty/NVIDIA/NVaftermath/Win64/GFSDK_Aftermath_Lib.x64.dll 2023-03-16T01:41:32.651Z
Engine/Binaries/ThirdParty/OpenXR/win64/openxr_loader.dll 2023-03-16T01:41:33.921Z
Engine/Binaries/ThirdParty/OpenVR/OpenVRv1_5_17/Win64/openvr_api.dll 2023-03-16T01:41:33.917Z
Engine/Binaries/ThirdParty/NVIDIA/GeForceNOW/Win64/GfnRuntimeSdk.dll 2023-03-16T01:41:32.648Z
Engine/Binaries/ThirdParty/Windows/WinPixEventRuntime/x64/WinPixEventRuntime.dll 2023-03-16T01:41:53.487Z
Engine/Binaries/ThirdParty/Windows/XAudio2_9/x64/xaudio2_9redist.dll 2023-03-16T01:41:54.149Z
TurnBasedTutorial.exe 2023-03-16T03:07:14.267Z
Loading…
Cancel
Save