Commit b3235cbb authored by Carl Findahl's avatar Carl Findahl 💬
Browse files

Add end match to arena. Fix equipping and looting abilities on client

parent e522d90b
No preview for this file type
......@@ -106,7 +106,7 @@ bool UInventoryComponent::EquipItem(UVikingItem* Item)
/* Only if we have authority to give the ability */
UE_LOG(LogTemp, Warning, TEXT("Giving Ability from equipped weapon to player."));
auto* OwningCharacter = Cast<AVikingCharacter>(Cast<APlayerController>(Owner)->GetCharacter());
OwningCharacter->GiveAbilityFromItem(Item);
OwningCharacter->ServerGiveAbilityFromItem(Item);
}
OnItemEquipped.Broadcast(Owner, this, Item, Item->Slot);
......@@ -124,7 +124,7 @@ bool UInventoryComponent::UnequipItem(UVikingItem* Item)
{
/* Only if we have authority to give the ability */
auto* OwningCharacter = Cast<AVikingCharacter>(Cast<APlayerController>(Owner)->GetCharacter());
OwningCharacter->ClearAbilityFromItem(Item);
OwningCharacter->ServerClearAbilityFromItem(Item);
}
OnItemUnEquipped.Broadcast(Owner, this, Item, Item->Slot);
......
......@@ -6,6 +6,9 @@
#include "Components/StaticMeshComponent.h"
#include "LootMovementComponent.h"
#include "VikingAssetManager.h"
#include "VikingPlayerController.h"
#include "InventoryComponent.h"
#include "GameFramework/Character.h"
// Sets default values
APickup::APickup()
......@@ -36,6 +39,19 @@ APickup::APickup()
GlowLight->SetRelativeLocation(FVector(0.f, 0.f, SphereRadius));
GlowLight->SetLightColor(FLinearColor(FVector4(1.f, 0.7f, 0.1f, 1.f)));
GlowLight->SetAttenuationRadius(400.f);
SetReplicates(true);
}
void APickup::InteractWith_Implementation(ACharacter* Interactee)
{
AVikingPlayerController* Controller = Cast<AVikingPlayerController>(Interactee->GetController());
if (!ensure(Controller != nullptr)) return;
UInventoryComponent* Inventory = Controller->GetInventory();
Inventory->AddItem(Asset, 1);
Destroy(true);
}
// Called when the game starts or when spawned
......
// Carl, Tomas, Jon Gunnar, Leon - 2019
#include "VikingArenaOverlay.h"
#include "Kismet/GameplayStatics.h"
#include "VikingArenaGameState.h"
#include "TextBlock.h"
bool UVikingArenaOverlay::Initialize()
{
const bool bSuccess = Super::Initialize();
if (!bSuccess) { return bSuccess; }
NotificationText->SetText(FText::FromString(FString()));
AVikingArenaGameState * GameState = Cast<AVikingArenaGameState>(UGameplayStatics::GetGameState(GetWorld()));
TimeLeftText->SetText(FText::AsTimespan(FTimespan(0, 0, 120)));
return true;
}
......@@ -39,7 +39,7 @@ bool UVikingPauseMenu::Initialize()
void UVikingPauseMenu::RemoveFromParent()
{
APlayerController* Controller = GetOwningPlayer<APlayerController>();
if (!ensure(Controller != nullptr)) return;
if (Controller == nullptr) return;
// Game Input Only
FInputModeGameOnly InputModeData{};
......
......@@ -7,13 +7,32 @@
#include "Engine/World.h"
#include "Kismet/GameplayStatics.h"
#include "GameFramework/PlayerStart.h"
#include "VikingPlayerState.h"
#include "VikingArenaGameState.h"
#include "UserWidget.h"
void AVikingArenaGameMode::StartMatch() {
Super::StartMatch();
bool AVikingArenaGameMode::ReadyToStartMatch_Implementation()
{
Super::ReadyToStartMatch_Implementation();
return GetNumPlayers() == MaxPlayers;
}
void AVikingArenaGameMode::BeginPlay()
{
Super::BeginPlay();
FindAndStoreAllSpawnPoints();
}
void AVikingArenaGameMode::HandleMatchHasStarted()
{
Super::HandleMatchHasStarted();
UWorld* World = GetWorld();
if (!ensure(World != nullptr)) return;
// Reset game state timer etc
Cast<AVikingArenaGameState>(GameState)->ResetGameState();
/** Spawn Player Weapons on Match Start */
for (FConstPlayerControllerIterator PCIterator = World->GetPlayerControllerIterator(); PCIterator; ++PCIterator)
{
......@@ -23,9 +42,12 @@ void AVikingArenaGameMode::StartMatch() {
AVikingCharacter* PlayerPawn = Cast<AVikingCharacter>(Controller->GetPawn());
if (!ensure(PlayerPawn != nullptr)) return;
/** Add character to our stored character array */
Characters.Add(PlayerPawn);
/** Spawn the weapon */
AActor* Weapon = World->SpawnActor(WeaponItem->WeaponActor);
PlayerPawn->GiveAbilityFromItem(WeaponItem);
PlayerPawn->ServerGiveAbilityFromItem(WeaponItem);
PlayerPawn->SetCurrentWeapon(Weapon);
Weapon->Instigator = PlayerPawn;
......@@ -33,16 +55,49 @@ void AVikingArenaGameMode::StartMatch() {
}
}
bool AVikingArenaGameMode::ReadyToStartMatch_Implementation()
bool AVikingArenaGameMode::ReadyToEndMatch_Implementation()
{
Super::ReadyToStartMatch_Implementation();
return GetNumPlayers() == MaxPlayers;
Super::ReadyToEndMatch_Implementation();
// If the health of any player is 0, then they are dead and the match has ended
AVikingCharacter* Loser = nullptr;
for (AVikingCharacter* Char : Characters)
{
if (FMath::IsNearlyZero(Char->GetHealth()))
{
Loser = Char;
break;
}
}
// Check if anyone died. If they did remove them and if there is only 1 combatant left they won
if (Loser)
{
Characters.Remove(Loser);
if (Characters.Num() == 1)
{
Winner = Characters[0];
return true;
}
}
return false;
}
void AVikingArenaGameMode::BeginPlay()
void AVikingArenaGameMode::HandleMatchHasEnded()
{
Super::BeginPlay();
FindAndStoreAllSpawnPoints();
Super::HandleMatchHasEnded();
AVikingArenaGameState* GameState = GetGameState<AVikingArenaGameState>();
if (!ensure(GameState != nullptr)) return;
if (Winner)
{
AVikingPlayerState* WinnerState = Winner->GetPlayerState<AVikingPlayerState>();
if (!ensure(WinnerState != nullptr)) return;
WinnerState->AddKill();
}
}
AActor* AVikingArenaGameMode::ChoosePlayerStart_Implementation(AController* Player)
......@@ -59,6 +114,15 @@ AActor* AVikingArenaGameMode::ChoosePlayerStart_Implementation(AController* Play
return SpawnPoint;
}
void AVikingArenaGameMode::PreLogin(const FString& Options, const FString& Address, const FUniqueNetIdRepl& UniqueId, FString& ErrorMessage)
{
Super::PreLogin(Options, Address, UniqueId, ErrorMessage);
if (GetNumPlayers() >= MaxPlayers)
{
ErrorMessage = TEXT("Game is full.");
}
}
void AVikingArenaGameMode::FindAndStoreAllSpawnPoints()
{
UWorld* World = GetWorld();
......
......@@ -2,15 +2,23 @@
#include "VikingArenaGameState.h"
#include "UserWidget.h"
void AVikingArenaGameState::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
TimeLeft -= DeltaSeconds;
TimeLeft = GetTimeLeft() - DeltaSeconds;
}
void AVikingArenaGameState::Reset(float RoundDuration /*= 120.f*/, int32 InPurchasePoints /*= 150*/)
void AVikingArenaGameState::ResetGameState(float RoundDuration /*= 120.f*/, int32 InPurchasePoints /*= 150*/)
{
TimeLeft = RoundDuration;
PurchasePoints = InPurchasePoints;
}
void AVikingArenaGameState::SetUpArenaUI_Implementation()
{
APlayerController* Controller = GetWorld()->GetFirstPlayerController();
UUserWidget* Widget = CreateWidget(Controller, ArenaWidget);
Widget->AddToViewport();
}
......@@ -64,12 +64,12 @@ bool AVikingCharacter::ActivateAbilitiesWithTags(FGameplayTagContainer AbilityTa
return false;
}
void AVikingCharacter::GiveAbilityFromItem(UVikingItem* Item)
void AVikingCharacter::ServerGiveAbilityFromItem_Implementation(UVikingItem* Item)
{
if (AbilitySystem && HasAuthority())
{
/* Try to clear first */
ClearAbilityFromItem(Item);
ServerClearAbilityFromItem(Item);
/* Give the new ability */
EquipmentAbilities.Add(
......@@ -77,7 +77,7 @@ void AVikingCharacter::GiveAbilityFromItem(UVikingItem* Item)
}
}
void AVikingCharacter::ClearAbilityFromItem(UVikingItem* Item)
void AVikingCharacter::ServerClearAbilityFromItem_Implementation(UVikingItem* Item)
{
if (AbilitySystem && HasAuthority())
{
......
......@@ -7,3 +7,18 @@ AVikingPlayerState::AVikingPlayerState()
SetPlayerName(TEXT("Viking"));
UE_LOG(LogTemp, Warning, TEXT("Player is known as: %s"), *GetPlayerName());
}
int32 AVikingPlayerState::GetKills() const
{
return Kills;
}
void AVikingPlayerState::SetKills(int32 val)
{
Kills = val;
}
void AVikingPlayerState::AddKill()
{
++Kills;
}
......@@ -5,13 +5,14 @@
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "GameplayAbilitySpec.h"
#include "InteractableInterface.h"
#include "Pickup.generated.h"
/**
* Native base class for pickups
*/
UCLASS(HideCategories = ("StaticMesh|Materials|Light|Physics|Collision|Shape"))
class VIKING_API APickup : public AActor
class VIKING_API APickup : public AActor, public IInteractableInterface
{
GENERATED_BODY()
......@@ -34,6 +35,8 @@ public:
// Sets default values for this actor's properties
APickup();
virtual void InteractWith_Implementation(ACharacter* Interactee) override;
protected:
/**
* Asset we are referencing (to pick up / loot)
......@@ -47,4 +50,5 @@ protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
};
// Carl, Tomas, Jon Gunnar, Leon - 2019
#pragma once
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "VikingArenaOverlay.generated.h"
/**
*
*/
UCLASS()
class VIKING_API UVikingArenaOverlay : public UUserWidget
{
GENERATED_BODY()
private:
/** Quit Button Binding */
UPROPERTY(meta = (BindWidget))
class UTextBlock* TimeLeftText;
/** Quit Button Binding */
UPROPERTY(meta = (BindWidget))
class UTextBlock* NotificationText;
public:
virtual bool Initialize() override;
};
......@@ -15,14 +15,18 @@ class VIKING_API AVikingArenaGameMode : public AGameMode
GENERATED_BODY()
private:
virtual void StartMatch() override;
/** Possible spawn points for player */
TArray<AActor*> SpawnPoints{};
/** Next spawn point to use */
int32 NextSpawnPoint = 0;
/** Characters that are dueling in the arena */
TArray<class AVikingCharacter*> Characters{};
/** Stores the winner of a match */
AVikingCharacter* Winner = nullptr;
protected:
/** Max players in Arena */
UPROPERTY(BlueprintReadOnly, Category = ArenaMode)
......@@ -38,9 +42,23 @@ protected:
/** Fetches all spawn points and stores them */
virtual void BeginPlay() override;
/** Spawn weapons for each player */
virtual void HandleMatchHasStarted() override;
/** When a player dies the match ends */
virtual bool ReadyToEndMatch_Implementation() override;
/** Awards points to winning player and resets match timer */
virtual void HandleMatchHasEnded() override;
public:
/** Used to ensure players are scattered throughout the arena and do not get the same spawn location */
virtual AActor* ChoosePlayerStart_Implementation(AController* Player) override;
/** Overridden to disallow more than 2 players from joining */
virtual void PreLogin(const FString& Options, const FString& Address, const FUniqueNetIdRepl& UniqueId, FString& ErrorMessage) override;
private:
/** Helper function to find and store spawn poitns */
void FindAndStoreAllSpawnPoints();
};
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment