Full replication of movement and attacks implemented

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

@ -28,4 +28,6 @@ AppliedDefaultGraphicsPerformance=Maximum
[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()
{
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
{
// FVector Location(2000.0f, -1000.0f, 0.0f);
// FRotator Rotation(0.0f, 180.0f, 0.0f);
// FActorSpawnParameters const SpawnInfo;
// for (int i = 0; i < 5; ++i)
// {
// AActor* Spawned = GetWorld()->SpawnActor<ATrooper>(Location, Rotation, SpawnInfo);
// dynamic_cast<ATrooper*>(Spawned)->InitTrooper(Location, true);
// 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)
// {
// AActor* Spawned = GetWorld()->SpawnActor<ATrooper>(Location, Rotation, SpawnInfo);
// dynamic_cast<ATrooper*>(Spawned)->InitTrooper(Location, false);
// Location += {0.f, 500.f, 0.0f};
// }
UE_LOG(LogTemp, Warning, TEXT("InitializeBattleField"));
FVector Location(2000.0f, -1000.0f, 0.0f);
FRotator Rotation(0.0f, 180.0f, 0.0f);
FActorSpawnParameters const SpawnInfo;
uint8 TrooperCount = 0;
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(0, Location, TrooperCount++);
Spawned->FinishSpawning(SpawnLocationAndRotation);
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"));
const auto World = GetWorld();
const auto CurrentNumberOfPlayers = GetNumPlayers();
// 0-indexation
dynamic_cast<AMyPlayerController*>(NewPlayer)->SetPlayerIndex(CurrentNumberOfPlayers - 1);
UE_LOG(LogTemp, Warning, TEXT("%d"), CurrentNumberOfPlayers);
if (CurrentNumberOfPlayers == 2)
{
@ -107,6 +112,7 @@ void AMyGameMode::PostLogin(APlayerController* NewPlayer)
void AMyGameMode::StartGame()
{
InitializeBattleField();
PlayerInTurn()->StartTurn();
}

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

@ -3,6 +3,8 @@
#include "MyPlayerController.h"
#include "Kismet/GameplayStatics.h"
#include "MyGameMode.h"
#include "AIController.h"
#include "Net/UnrealNetwork.h"
AMyPlayerController::AMyPlayerController() : Super(), bIsMyTurn(false), SelectedTrooper(nullptr)
{
@ -40,68 +42,93 @@ void AMyPlayerController::EndTurn_Implementation()
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();
}
void AMyPlayerController::SetPlayerIndex(uint8 NewPlayerIndex)
{
PlayerIndex = NewPlayerIndex;
}
void AMyPlayerController::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
DOREPLIFETIME(AMyPlayerController, PlayerIndex);
}
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)
{
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();
UFUNCTION(Server, Reliable)
void MoveHero();
void MoveTrooper(ATrooper *Trooper, FVector Location);
UFUNCTION(Server, Reliable)
void AttackTrooper(ATrooper *Attacker, ATrooper *Victim);
virtual void SetupInputComponent() override;
void SetTrooperIsMoving(bool isMoving);
UFUNCTION()
void SetPlayerIndex(uint8 NewPlayerIndex);
private:
bool bIsMyTurn;
bool bIsThereTrooperMoving = false;
UPROPERTY(Replicated)
uint8 PlayerIndex;
ATrooper* SelectedTrooper;

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

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

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

Loading…
Cancel
Save