diff --git a/Content/BattleField/BattleFieldMap.umap b/Content/BattleField/BattleFieldMap.umap index 80cd99c..97450eb 100644 Binary files a/Content/BattleField/BattleFieldMap.umap and b/Content/BattleField/BattleFieldMap.umap differ diff --git a/Content/Troopers/TrooperSkeletonMelee.uasset b/Content/Troopers/TrooperSkeletonMelee.uasset index 91c9c3c..0eed9e2 100644 Binary files a/Content/Troopers/TrooperSkeletonMelee.uasset and b/Content/Troopers/TrooperSkeletonMelee.uasset differ diff --git a/Content/Troopers/TrooperWizard.uasset b/Content/Troopers/TrooperWizard.uasset index 09c2e99..7fb6aec 100644 Binary files a/Content/Troopers/TrooperWizard.uasset and b/Content/Troopers/TrooperWizard.uasset differ diff --git a/Source/TurnBasedTutorial/MyGameState.cpp b/Source/TurnBasedTutorial/MyGameState.cpp index 98f7675..e219a74 100644 --- a/Source/TurnBasedTutorial/MyGameState.cpp +++ b/Source/TurnBasedTutorial/MyGameState.cpp @@ -12,9 +12,13 @@ auto AMyGameState::GetMyPlayerState(uint8 PlayerIndex) const { void AMyGameState::BeginPlay() { Super::BeginPlay(); + LivingTroopers.SetNum(2); } void AMyGameState::AddTrooper_Implementation(ATrooper *Trooper) { + if (Trooper->GetPlayerIndex() >= 0 && Trooper->GetPlayerIndex() <= LivingTroopers.Num()) { + LivingTroopers[Trooper->GetPlayerIndex()]++; + } Troopers.Add(Trooper); } @@ -69,6 +73,17 @@ 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( TArray &OutLifetimeProps) const { Super::GetLifetimeReplicatedProps(OutLifetimeProps); diff --git a/Source/TurnBasedTutorial/MyGameState.h b/Source/TurnBasedTutorial/MyGameState.h index 858afae..1b4bf8a 100644 --- a/Source/TurnBasedTutorial/MyGameState.h +++ b/Source/TurnBasedTutorial/MyGameState.h @@ -41,10 +41,19 @@ public: UFUNCTION() bool IsGameStarted() const; + UFUNCTION() + void DecreaseLivingTroopers(int PlayerIndex); + private: + UPROPERTY(Replicated) + bool bGameIsOver = false; + UPROPERTY(Replicated) TArray Troopers; + UPROPERTY(Replicated) + TArray LivingTroopers; + UPROPERTY(Replicated) bool bGameStarted = false; diff --git a/Source/TurnBasedTutorial/Trooper.cpp b/Source/TurnBasedTutorial/Trooper.cpp index edc00fe..b560e27 100644 --- a/Source/TurnBasedTutorial/Trooper.cpp +++ b/Source/TurnBasedTutorial/Trooper.cpp @@ -2,6 +2,7 @@ #include #include "HealthBar.h" +#include "MyGameState.h" #include "MyPlayerController.h" #include "MyPlayerState.h" #include "MyProjectile.h" @@ -128,7 +129,7 @@ void ATrooper::Tick(float const DeltaTime) { // } // } -void ATrooper::MoveTrooper(FVector const NewPos) { +void ATrooper::MoveTrooper_Implementation(FVector const NewPos) { TargetLocation = NewPos; bIsMoving = true; ActionPoints -= (NewPos - CurrentLocation).Size() * MoveCost; @@ -158,7 +159,7 @@ void ATrooper::GetLifetimeReplicatedProps( DOREPLIFETIME(ATrooper, CurrentAbilityDestination); } -uint8 ATrooper::GetPlayerIndex() const { +int8 ATrooper::GetPlayerIndex() const { return PlayerIndex; } @@ -246,17 +247,18 @@ UAbility *ATrooper::GetAbility(int AbilityIndex) const { } } -bool ATrooper::TakeDamage(float Damage) { - if (bIsTakingDamage) { - return false; +void ATrooper::TakeDamage_Implementation(float Damage) { + if (bIsTakingDamage || bIsDead) { + return; } HitPoints = FMath::Max(0, HitPoints - Damage); if (HitPoints == 0) { bIsDead = true; - return true; + SetLifeSpan(DyingAnimationDuration); + GetWorld()->GetGameState()->DecreaseLivingTroopers(PlayerIndex); + } else { + bIsTakingDamage = true; } - bIsTakingDamage = true; - return false; } TSubclassOf ATrooper::GetProjectileClass( @@ -312,7 +314,7 @@ int ATrooper::GetAnimationValue() { return 0; } -void ATrooper::Attack(int AbilityIndex, FVector ToLocation) { +void ATrooper::Attack_Implementation(int AbilityIndex, FVector ToLocation) { bIsAttacking = true; bIsWaitingForFire = true; ActionPoints -= GetAbility(AbilityIndex)->ActionCost; diff --git a/Source/TurnBasedTutorial/Trooper.h b/Source/TurnBasedTutorial/Trooper.h index c48dabf..0ca380f 100644 --- a/Source/TurnBasedTutorial/Trooper.h +++ b/Source/TurnBasedTutorial/Trooper.h @@ -18,9 +18,9 @@ public: uint8 const NewId); UFUNCTION() - uint8 GetPlayerIndex() const; + int8 GetPlayerIndex() const; - UFUNCTION() + UFUNCTION(Server, Reliable) void MoveTrooper(FVector const NewPos); UFUNCTION() @@ -38,7 +38,7 @@ public: UFUNCTION(BlueprintCallable) int GetAnimationValue(); - UFUNCTION() + UFUNCTION(Server, Reliable) void Attack(int AbilityIndex, FVector ToLocation); UFUNCTION() @@ -65,8 +65,8 @@ public: UFUNCTION() UAbility *GetAbility(int AbilityIndex) const; - UFUNCTION() - bool TakeDamage(float Damage); + UFUNCTION(Server, Reliable) + void TakeDamage(float Damage); protected: constexpr static float PIXELS_IN_RADIUS = 50; @@ -139,6 +139,8 @@ protected: float TakingDamagePlayedTime; const float TakingDamageDuration = 1.46667f; + + const float DyingAnimationDuration = 2.83333f; UPROPERTY(Replicated) bool bIsDead = false;