normal convenient movement, borders at hp widgets, explosions, beautiful fireballs

pull/6/head
m4xxx1m 2 years ago
parent a51acf9d02
commit e68312eaec

@ -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;
};

@ -18,18 +18,13 @@ void AMyGameState::AddTrooper_Implementation(ATrooper *Trooper) {
Troopers.Add(Trooper);
}
void AMyGameState::StartGame_Implementation() const {
PlayerNotInTurn()->SetEnemySelection(Troopers);
PlayerInTurn()->SetEnemySelection(Troopers);
void AMyGameState::StartGame_Implementation() {
PlayerNotInTurn()->SetEnemySelection();
PlayerInTurn()->SetEnemySelection();
bGameStarted = true;
PlayerInTurn()->StartTurn();
}
// void AMyGameState::StartGame() const {
// PlayerNotInTurn()->SetEnemySelection(Troopers);
// PlayerInTurn()->SetEnemySelection(Troopers);
// PlayerInTurn()->StartTurn();
// }
void AMyGameState::CycleTurns_Implementation() {
PlayerInTurn()->EndTurn();
for (const auto Trooper : Troopers) {
@ -70,9 +65,14 @@ bool AMyGameState::IsInTurn(uint8 PlayerIndex) const {
return PlayerIndex == CurrentPlayerTurn;
}
bool AMyGameState::IsGameStarted() const {
return bGameStarted;
}
void AMyGameState::GetLifetimeReplicatedProps(
TArray<FLifetimeProperty> &OutLifetimeProps) const {
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(AMyGameState, Troopers);
DOREPLIFETIME(AMyGameState, CurrentPlayerTurn);
DOREPLIFETIME(AMyGameState, bGameStarted);
}

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

@ -15,6 +15,20 @@ void AMyPawn::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
void AMyPawn::Tick(float DeltaTime) {
Super::Tick(DeltaTime);

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

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

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

@ -47,6 +47,7 @@ void AMyProjectile::Initialize(const UAbility *Ability,
ProjectileMovementComponent->InitialSpeed =
ProjectileMovementComponent->MaxSpeed = Ability->Speed;
Damage = Ability->Damage;
SplashRadius = Ability->SplashRadius;
float Scale = Ability->LinearWidth / 100;
// CollisionComponent->SetSphereRadius(Ability->LinearWidth / 2);
ProjectileMeshComponent->SetWorldScale3D({Scale, Scale, Scale});
@ -77,38 +78,55 @@ void AMyProjectile::NotifyActorBeginOverlap(AActor *OtherActor) {
}
}
void AMyProjectile::NotifyHit(UPrimitiveComponent *MyComp,
AActor *Other,
UPrimitiveComponent *OtherComp,
bool bSelfMoved,
FVector HitLocation,
FVector HitNormal,
FVector NormalImpulse,
const FHitResult &Hit) {
Super::NotifyHit(MyComp, Other, OtherComp, bSelfMoved, HitLocation,
HitNormal,
NormalImpulse, Hit);
ATrooper *OtherTrooper = Cast<ATrooper>(Other);
if (OtherTrooper) {
UE_LOG(LogTemp, Warning,
TEXT("On Hit: 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 AMyProjectile::NotifyHit(UPrimitiveComponent *MyComp,
// AActor *Other,
// UPrimitiveComponent *OtherComp,
// bool bSelfMoved,
// FVector HitLocation,
// FVector HitNormal,
// FVector NormalImpulse,
// const FHitResult &Hit) {
// Super::NotifyHit(MyComp, Other, OtherComp, bSelfMoved, HitLocation,
// HitNormal,
// NormalImpulse, Hit);
// ATrooper *OtherTrooper = Cast<ATrooper>(Other);
// if (OtherTrooper) {
// UE_LOG(LogTemp, Warning,
// TEXT("On Hit: 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 AMyProjectile::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(
TArray<FLifetimeProperty> &OutLifetimeProps) const {
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
@ -117,4 +135,5 @@ void AMyProjectile::GetLifetimeReplicatedProps(
// DOREPLIFETIME(AMyProjectile, CollisionComponent);
DOREPLIFETIME(AMyProjectile, ProjectileMeshComponent);
DOREPLIFETIME(AMyProjectile, ProjectileMovementComponent);
DOREPLIFETIME(AMyProjectile, SplashRadius);
}

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

@ -113,20 +113,20 @@ void ATrooper::Tick(float const DeltaTime) {
}
}
void ATrooper::OnRepNotify_PlayerIndex() const {
const AMyPlayerState *player = Cast<AMyPlayerState>(
GetPlayerState());
if (!player)
return;
const uint8 ClientIndex = player->GetPlayerIndex();
UE_LOG(LogTemp, Warning,
TEXT("On rep notify, index: %d, client index: %d, id: %d"),
PlayerIndex,
ClientIndex, Id);
if (ClientIndex == PlayerIndex) {
HighlightAsEnemy();
}
}
// void ATrooper::OnRepNotify_PlayerIndex() const {
// const AMyPlayerState *player = Cast<AMyPlayerState>(
// GetPlayerState());
// if (!player)
// return;
// const uint8 ClientIndex = player->GetPlayerIndex();
// UE_LOG(LogTemp, Warning,
// TEXT("On rep notify, index: %d, client index: %d, id: %d"),
// PlayerIndex,
// ClientIndex, Id);
// if (ClientIndex == PlayerIndex) {
// HighlightAsEnemy();
// }
// }
void ATrooper::MoveTrooper(FVector const NewPos) {
TargetLocation = NewPos;
@ -225,8 +225,10 @@ void ATrooper::UpdateSelectionRadius(uint8 ActionType) const {
{radiusScale, radiusScale, 0.01f});
}
void ATrooper::HighlightAsEnemy_Implementation() const {
SelectionStaticMesh->SetVisibility(true);
void ATrooper::HighlightAsEnemy_Implementation(int8 Index) const {
if (PlayerIndex != Index) {
SelectionStaticMesh->SetVisibility(true);
}
}
void ATrooper::ResetActionPoints() {

@ -57,8 +57,8 @@ public:
void UpdateSelectionRadius(uint8 ActionType) const;
UFUNCTION(Client, Reliable)
void HighlightAsEnemy() const;
void HighlightAsEnemy(int8 Index) const;
UFUNCTION()
void ResetActionPoints();
@ -160,11 +160,11 @@ protected:
// const TCHAR *MeshPath = nullptr;
UFUNCTION()
void OnRepNotify_PlayerIndex() const;
// UFUNCTION()
// void OnRepNotify_PlayerIndex() const;
UPROPERTY(ReplicatedUsing = OnRepNotify_PlayerIndex)
uint8 PlayerIndex = -1;
UPROPERTY(Replicated/*Using = OnRepNotify_PlayerIndex*/)
int8 PlayerIndex = -1;
UPROPERTY(Replicated)
uint8 Id;

Loading…
Cancel
Save