Full replication of movement and attacks implemented

pull/5/head
eyakm1 2 years ago
parent 77951cd5ee
commit cdd8c11f8b

@ -29,3 +29,5 @@ AppliedDefaultGraphicsPerformance=Maximum
[CoreRedirects] [CoreRedirects]
+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.MoveTropper",NewName="/Script/TurnBasedTutorial.MyPlayerController.MoveTrooper")

@ -16,35 +16,37 @@ AMyGameMode::AMyGameMode() : Super()
void AMyGameMode::BeginPlay() void AMyGameMode::BeginPlay()
{ {
Super::BeginPlay(); Super::BeginPlay();
// ATrooper::InitNumberOfTroopersForId();
// UE_LOG(LogTemp, Warning, TEXT("GameMode BeginPlay"));
// if (GetWorld()->GetMapName().Contains("BattleFieldMap"))
// {
// UE_LOG(LogTemp, Warning, TEXT("Player Logined"));
// InitializeBattleField();
// GetMyPlayerController()->StartTurn();
// }
} }
void AMyGameMode::InitializeBattleField() const void AMyGameMode::InitializeBattleField() const
{ {
// FVector Location(2000.0f, -1000.0f, 0.0f); UE_LOG(LogTemp, Warning, TEXT("InitializeBattleField"));
// FRotator Rotation(0.0f, 180.0f, 0.0f); FVector Location(2000.0f, -1000.0f, 0.0f);
// FActorSpawnParameters const SpawnInfo; FRotator Rotation(0.0f, 180.0f, 0.0f);
// for (int i = 0; i < 5; ++i) FActorSpawnParameters const SpawnInfo;
// {
// AActor* Spawned = GetWorld()->SpawnActor<ATrooper>(Location, Rotation, SpawnInfo); uint8 TrooperCount = 0;
// dynamic_cast<ATrooper*>(Spawned)->InitTrooper(Location, true);
// Location += {0.f, 500.f, 0.0f}; for (int i = 0; i < 5; ++i)
// } {
// Location = {-2000.0f, -1000.0f, 0.0f}; FTransform SpawnLocationAndRotation(Rotation);
// Rotation = {0.0f, 0.0f, 0.0f}; SpawnLocationAndRotation.SetLocation(Location);
// for (int i = 0; i < 5; ++i) AActor* Spawned = GetWorld()->SpawnActorDeferred<ATrooper>(ATrooper::StaticClass(), SpawnLocationAndRotation);
// { dynamic_cast<ATrooper*>(Spawned)->Initialize(0, Location, TrooperCount++);
// AActor* Spawned = GetWorld()->SpawnActor<ATrooper>(Location, Rotation, SpawnInfo); Spawned->FinishSpawning(SpawnLocationAndRotation);
// dynamic_cast<ATrooper*>(Spawned)->InitTrooper(Location, false); Location += {0.f, 500.f, 0.0f};
// Location += {0.f, 500.f, 0.0f}; }
// } Location = {-2000.0f, -1000.0f, 0.0f};
Rotation = {0.0f, 0.0f, 0.0f};
for (int i = 0; i < 5; ++i)
{
FTransform SpawnLocationAndRotation(Rotation);
SpawnLocationAndRotation.SetLocation(Location);
AActor* Spawned = GetWorld()->SpawnActorDeferred<ATrooper>(ATrooper::StaticClass(), SpawnLocationAndRotation);
dynamic_cast<ATrooper*>(Spawned)->Initialize(1, Location, TrooperCount++);
Spawned->FinishSpawning(SpawnLocationAndRotation);
Location += {0.f, 500.f, 0.0f};
}
} }
@ -90,6 +92,9 @@ void AMyGameMode::PostLogin(APlayerController* NewPlayer)
UE_LOG(LogTemp, Warning, TEXT("PostLogin")); UE_LOG(LogTemp, Warning, TEXT("PostLogin"));
const auto World = GetWorld(); const auto World = GetWorld();
const auto CurrentNumberOfPlayers = GetNumPlayers(); const auto CurrentNumberOfPlayers = GetNumPlayers();
// 0-indexation
dynamic_cast<AMyPlayerController*>(NewPlayer)->SetPlayerIndex(CurrentNumberOfPlayers - 1);
UE_LOG(LogTemp, Warning, TEXT("%d"), CurrentNumberOfPlayers); UE_LOG(LogTemp, Warning, TEXT("%d"), CurrentNumberOfPlayers);
if (CurrentNumberOfPlayers == 2) if (CurrentNumberOfPlayers == 2)
{ {
@ -107,6 +112,7 @@ void AMyGameMode::PostLogin(APlayerController* NewPlayer)
void AMyGameMode::StartGame() void AMyGameMode::StartGame()
{ {
InitializeBattleField();
PlayerInTurn()->StartTurn(); PlayerInTurn()->StartTurn();
} }

@ -32,6 +32,7 @@ private:
void InitializeBattleField() const; void InitializeBattleField() const;
UPROPERTY()
TMap<uint8, AMyPlayerStart*> SpawnPoints{}; TMap<uint8, AMyPlayerStart*> SpawnPoints{};
AMyPlayerController* GetMyPlayerController(uint8 const PlayerIndex) const; AMyPlayerController* GetMyPlayerController(uint8 const PlayerIndex) const;

@ -3,6 +3,8 @@
#include "MyPlayerController.h" #include "MyPlayerController.h"
#include "Kismet/GameplayStatics.h" #include "Kismet/GameplayStatics.h"
#include "MyGameMode.h" #include "MyGameMode.h"
#include "AIController.h"
#include "Net/UnrealNetwork.h"
AMyPlayerController::AMyPlayerController() : Super(), bIsMyTurn(false), SelectedTrooper(nullptr) AMyPlayerController::AMyPlayerController() : Super(), bIsMyTurn(false), SelectedTrooper(nullptr)
{ {
@ -40,68 +42,93 @@ void AMyPlayerController::EndTurn_Implementation()
UE_LOG(LogTemp, Warning, TEXT("Not your turn")); UE_LOG(LogTemp, Warning, TEXT("Not your turn"));
} }
void AMyPlayerController::SetTrooperIsMoving(bool isMoving) auto AMyPlayerController::GetMyGameMode() const
{ {
bIsThereTrooperMoving = isMoving; return dynamic_cast<AMyGameMode*>(UGameplayStatics::GetGameMode(GetWorld()));
} }
auto AMyPlayerController::GetMyGameMode() const void AMyPlayerController::MoveTrooper_Implementation(ATrooper* Trooper, FVector Location)
{ {
return dynamic_cast<AMyGameMode*>(UGameplayStatics::GetGameMode(GetWorld())); Trooper->MoveTrooper(Location);
GetMyGameMode()->CycleTurns();
} }
void AMyPlayerController::MoveHero_Implementation()
void AMyPlayerController::AttackTrooper_Implementation(ATrooper* Attacker, ATrooper* Victim)
{ {
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red,
FString::Printf(
TEXT("ATTACK!! %d attacked %d"), Attacker->GetId(), Victim->GetId()));
GetMyGameMode()->CycleTurns(); GetMyGameMode()->CycleTurns();
} }
void AMyPlayerController::SetPlayerIndex(uint8 NewPlayerIndex)
{
PlayerIndex = NewPlayerIndex;
}
void AMyPlayerController::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
DOREPLIFETIME(AMyPlayerController, PlayerIndex);
}
void AMyPlayerController::OnLeftMouseClick() void AMyPlayerController::OnLeftMouseClick()
{ {
// if (bIsThereTrooperMoving)
// {
// return;
// }
// UE_LOG(LogTemp, Warning, TEXT("Mouse clicked"));
// FHitResult HitResult;
// bool const IsHitResult = GetHitResultUnderCursorByChannel(TraceTypeQuery1, false, HitResult);
// if (IsHitResult)
// {
// AActor* Actor = HitResult.Actor.Get();
// if (Actor->ActorHasTag(FName("Trooper")))
// {
// ATrooper* Trooper = dynamic_cast<ATrooper*>(Actor);
// if (Trooper != nullptr && Trooper != SelectedTrooper)
// {
// if (Trooper->IsOnPlayersSide())
// {
// UE_LOG(LogTemp, Warning, TEXT("Hitted trooper id: %d, on our side"),
// Trooper->GetId());
// SelectedTrooper = Trooper;
// }
// else
// {
// UE_LOG(LogTemp, Warning, TEXT("Hitted trooper id: %d, enemy"),
// Trooper->GetId());
// UE_LOG(LogTemp, Warning, TEXT("Trooper #%d hit enemy trooper #%d"),
// SelectedTrooper->GetId(), Trooper->GetId());
// }
// }
// }
// else if (Actor->ActorHasTag(FName("Floor")))
// {
// UE_LOG(LogTemp, Warning, TEXT("Hitted floor: %f, %f, %f"), HitResult.Location.X,
// HitResult.Location.Y, HitResult.Location.Z);
// if (SelectedTrooper != nullptr)
// {
// SelectedTrooper->MoveTrooper(HitResult.Location);
// bIsThereTrooperMoving = true;
// }
// }
// }
if (!bIsMyTurn) if (!bIsMyTurn)
{ {
return; return;
} }
MoveHero(); UE_LOG(LogTemp, Warning, TEXT("Mouse clicked"));
FHitResult HitResult;
bool const IsHitResult = GetHitResultUnderCursorByChannel(TraceTypeQuery1, false, HitResult);
if (!IsHitResult)
return;
UE_LOG(LogTemp, Warning, TEXT("Got hit result"));
auto const NewlySelectedLocation = HitResult.Location;
ATrooper* NewlySelectedTrooper = dynamic_cast<ATrooper*>(HitResult.GetActor());
if (NewlySelectedTrooper == nullptr || !NewlySelectedTrooper->IsValidLowLevel())
{
// we selected something that is not a trooper (or trooper in shitty state...)
// probably we should move to it if we can...
UE_LOG(LogTemp, Warning, TEXT("Not a trooper"));
// if initial trooper is valid...
if (SelectedTrooper != nullptr && SelectedTrooper->IsValidLowLevel())
{
UE_LOG(LogTemp, Warning, TEXT("Do move"));
// move this mf
MoveTrooper(SelectedTrooper, NewlySelectedLocation);
// and reset the selection....
SelectedTrooper = nullptr;
}
return;
}
UE_LOG(LogTemp, Warning, TEXT("New Selected Player Index %d"), NewlySelectedTrooper->GetPlayerIndex());
// skip re-selection
if (SelectedTrooper == NewlySelectedTrooper)
{
UE_LOG(LogTemp, Warning, TEXT("Skip reselection"));
return;
}
// we selected valid trooper...
if (NewlySelectedTrooper->GetPlayerIndex() == PlayerIndex)
{
UE_LOG(LogTemp, Warning, TEXT("Do reselect"));
// our move, selection
SelectedTrooper = NewlySelectedTrooper;
}
else
{
UE_LOG(LogTemp, Warning, TEXT("Attack or skip..."));
// maybe selected trooper had gone crazy...
if (SelectedTrooper == nullptr || !SelectedTrooper->IsValidLowLevel())
return;
UE_LOG(LogTemp, Warning, TEXT("Do attack"));
// ATTACK!!! ATTACK!!!!!!
AttackTrooper(SelectedTrooper, NewlySelectedTrooper);
SelectedTrooper = nullptr;
}
} }

@ -29,16 +29,21 @@ public:
void EndTurn(); void EndTurn();
UFUNCTION(Server, Reliable) UFUNCTION(Server, Reliable)
void MoveHero(); void MoveTrooper(ATrooper *Trooper, FVector Location);
UFUNCTION(Server, Reliable)
void AttackTrooper(ATrooper *Attacker, ATrooper *Victim);
virtual void SetupInputComponent() override; virtual void SetupInputComponent() override;
void SetTrooperIsMoving(bool isMoving); UFUNCTION()
void SetPlayerIndex(uint8 NewPlayerIndex);
private: private:
bool bIsMyTurn; bool bIsMyTurn;
bool bIsThereTrooperMoving = false; UPROPERTY(Replicated)
uint8 PlayerIndex;
ATrooper* SelectedTrooper; ATrooper* SelectedTrooper;

@ -1,22 +1,23 @@
#include "Trooper.h" #include "Trooper.h"
#include <Kismet/GameplayStatics.h> #include <Kismet/GameplayStatics.h>
#include "MyPlayerController.h" #include "MyPlayerController.h"
#include "Net/UnrealNetwork.h"
// Sets default values // Sets default values
ATrooper::ATrooper() ATrooper::ATrooper()
{ {
bReplicates = true;
PrimaryActorTick.bCanEverTick = true; PrimaryActorTick.bCanEverTick = true;
Tags.Add(FName("Trooper")); Tags.Add(FName("Trooper"));
Id = NumberOfTroopersForId++; MyStaticMesh = CreateDefaultSubobject<UStaticMeshComponent>("Mesh");
Position.Set(0, 0, 0); RootComponent = MyStaticMesh;
Mesh = CreateDefaultSubobject<UStaticMeshComponent>("Mesh");
RootComponent = Mesh;
static ConstructorHelpers::FObjectFinder<UStaticMesh> MeshToUse(TEXT( static ConstructorHelpers::FObjectFinder<UStaticMesh> MeshToUse(TEXT(
"StaticMesh'/Game/StarterContent/Props/SM_Chair.SM_Chair'" "StaticMesh'/Game/StarterContent/Props/SM_Chair.SM_Chair'"
)); ));
if (MeshToUse.Object) if (MeshToUse.Object)
{ {
Mesh->SetStaticMesh(MeshToUse.Object); MyStaticMesh->SetStaticMesh(MeshToUse.Object);
} }
} }
@ -26,59 +27,55 @@ void ATrooper::BeginPlay()
Super::BeginPlay(); Super::BeginPlay();
} }
void ATrooper::Initialize(uint8 const NewPlayerIndex, FVector const SpawnLocation, uint8 const NewId)
{
PlayerIndex = NewPlayerIndex;
bIsMoving = false;
CurrentLocation = SpawnLocation;
Id = NewId;
}
void ATrooper::Tick(float const DeltaTime) void ATrooper::Tick(float const DeltaTime)
{ {
if (bIsMoving) if (!bIsMoving)
return;
FVector PositionVector = (TargetLocation - CurrentLocation);
PositionVector.Normalize();
PositionVector *= (Speed * DeltaTime);
if (PositionVector.Size() >= (TargetLocation - CurrentLocation).Size())
{ {
FVector vector = (MoveToVector - Position); CurrentLocation = TargetLocation;
vector.Normalize();
vector *= (Speed * DeltaTime);
if (vector.Size() >= (MoveToVector - Position).Size())
{
Position = MoveToVector;
bIsMoving = false; bIsMoving = false;
dynamic_cast<AMyPlayerController*>(
UGameplayStatics::GetPlayerController(GetWorld(), 0)
)->SetTrooperIsMoving(false);
} }
else else
{ {
Position += vector; CurrentLocation += PositionVector;
}
SetActorLocation(Position);
} }
SetActorLocation(CurrentLocation);
} }
void ATrooper::MoveTrooper(FVector const NewPos) void ATrooper::MoveTrooper(FVector const NewPos)
{ {
MoveToVector = NewPos; TargetLocation = NewPos;
bIsMoving = true; bIsMoving = true;
} }
uint8 ATrooper::NumberOfTroopersForId = 0; uint8 ATrooper::GetId() const
void ATrooper::InitNumberOfTroopersForId()
{
NumberOfTroopersForId = 0;
}
FVector ATrooper::GetPosition() const
{ {
return Position; return Id;
} }
bool ATrooper::IsOnPlayersSide() const
{
return bOnPlayersSide;
}
uint8 ATrooper::GetId() const void ATrooper::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{ {
return Id; DOREPLIFETIME(ATrooper, PlayerIndex);
DOREPLIFETIME(ATrooper, CurrentLocation);
DOREPLIFETIME(ATrooper, TargetLocation);
DOREPLIFETIME(ATrooper, bIsMoving);
DOREPLIFETIME(ATrooper, Id);
} }
void ATrooper::InitTrooper(FVector const NewPosition, bool const bIsOnPlayersSide) uint8 ATrooper::GetPlayerIndex() const
{ {
Position = NewPosition; return PlayerIndex;
bOnPlayersSide = bIsOnPlayersSide;
} }

@ -3,10 +3,11 @@
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "GameFramework/Actor.h" #include "GameFramework/Actor.h"
#include "Components/StaticMeshComponent.h" #include "Components/StaticMeshComponent.h"
#include "GameFramework/Character.h"
#include "Trooper.generated.h" #include "Trooper.generated.h"
UCLASS() UCLASS()
class TURNBASEDTUTORIAL_API ATrooper : public AActor class TURNBASEDTUTORIAL_API ATrooper : public ACharacter
{ {
GENERATED_BODY() GENERATED_BODY()
@ -14,42 +15,41 @@ public:
// Sets default values for this actor's properties // Sets default values for this actor's properties
ATrooper(); ATrooper();
protected: void Initialize(uint8 const NewPlayerIndex, FVector const SpawnLocation, uint8 const NewId);
static uint8 NumberOfTroopersForId;
UFUNCTION()
uint8 GetPlayerIndex() const;
UFUNCTION()
void MoveTrooper(FVector const NewPos);
UFUNCTION()
uint8 GetId() const;
protected:
virtual void BeginPlay() override; virtual void BeginPlay() override;
virtual void Tick(float const DeltaTime) override; virtual void Tick(float const DeltaTime) override;
UPROPERTY() UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
FVector Position; UStaticMeshComponent* MyStaticMesh;
UPROPERTY() private:
bool bOnPlayersSide; UPROPERTY(Replicated)
uint8 PlayerIndex;
UPROPERTY() UPROPERTY(Replicated)
uint8 Id; uint8 Id;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
UStaticMeshComponent* Mesh;
UPROPERTY() UPROPERTY()
float Speed = 300.0f; float Speed = 300.0f;
bool bIsMoving = false; UPROPERTY(Replicated)
FVector CurrentLocation;
FVector MoveToVector;
public:
void MoveTrooper(FVector const NewPos);
static void InitNumberOfTroopersForId(); UPROPERTY(Replicated)
FVector TargetLocation;
FVector GetPosition() const; UPROPERTY(Replicated)
bool bIsMoving = false;
bool IsOnPlayersSide() const;
uint8 GetId() const;
void InitTrooper(FVector const NewPosition, bool const bIsOnPlayersSide);
}; };

@ -2,5 +2,5 @@
#pragma once #pragma once
#include "CoreMinimal.h" #include "Core.h"

Loading…
Cancel
Save