HAxis sos

This commit is contained in:
guus
2018-08-11 16:46:35 +02:00
commit 510654f8a1
480 changed files with 54126 additions and 0 deletions

View File

@@ -0,0 +1,61 @@
// Project Lab - NHTV Igad
#include "UnrealProject.h"
#include "AbilityButton.h"
#include "NetworkCharacter.h"
#include "AbilityInfo.h"
#include "AbilityState.h"
void UAbilityButton::NativeConstruct()
{
m_globalEnable = true;
Super::NativeConstruct();
SetCooldown(1.0f);
SetToggled(false);
SetupButton(nullptr, false);
}
UAbilityInfo* UAbilityButton::GetAbility()
{
return m_abilityInfo;
}
void UAbilityButton::InitButton(class UAbilityInfo* info, int32 index, bool alt)
{
if (info)
{
SetCooldown(1.0f);
SetToggled(false);
SetupButton(info, false);
SetIndex(index, alt);
SetAbilityAvailable(true);
m_index = index;
m_abilityInfo = info;
}
}
bool UAbilityButton::IsAssigned() const
{
return m_abilityInfo != nullptr;
}
void UAbilityButton::UpdateState(class AAbilityState* state, ANetworkCharacter* character)
{
SetToggled(state->toggleState);
SetCooldown(state->cooldownRate);
SetAbilityAvailable(character->GetMana() >= state->info->mana);
}
void UAbilityButton::SetButtonEnabled(bool enabled)
{
m_enabled = enabled;
if (m_abilityInfo)
{
SetupButton(m_abilityInfo, m_enabled && m_globalEnable);
}
}
void UAbilityButton::SetGlobalEnable(bool enabled)
{
m_globalEnable = enabled;
SetupButton(m_abilityInfo, m_enabled && m_globalEnable);
}

View File

@@ -0,0 +1,42 @@
// Project Lab - NHTV Igad
#pragma once
#include "Blueprint/UserWidget.h"
#include "AbilityButton.generated.h"
/**
*
*/
UCLASS()
class UNREALPROJECT_API UAbilityButton : public UUserWidget
{
GENERATED_BODY()
public:
void NativeConstruct() override;
UFUNCTION(BlueprintImplementableEvent, Category = "Button")
void SetupButton(class UAbilityInfo* info, bool enabled);
UFUNCTION(BlueprintImplementableEvent, Category = "Button")
void SetCooldown(float cooldown);
UFUNCTION(BlueprintImplementableEvent, Category = "Button")
void SetToggled(bool toggled);
UFUNCTION(BlueprintImplementableEvent, Category = "Button")
void SetIndex(int32 index, bool alt);
UFUNCTION(BlueprintImplementableEvent, Category = "Button")
void SetAbilityAvailable(bool available);
class UAbilityInfo* GetAbility();
void InitButton(class UAbilityInfo* info, int32 index, bool alt);
bool IsAssigned() const;
void UpdateState(class AAbilityState* state, class ANetworkCharacter* character);
void SetButtonEnabled(bool enabled);
void SetGlobalEnable(bool enabled);
private:
int32 m_index;
bool m_enabled;
bool m_globalEnable;
class UAbilityInfo* m_abilityInfo;
};

View File

@@ -0,0 +1,160 @@
// Project Lab - NHTV Igad
#include "UnrealProject.h"
#include "AbilityButton.h"
#include "ButtonBarSwitcher.h"
#include "BaseSkillObject.h"
#include "AbilityState.h"
#include "NetworkPlayer.h"
#include "IngameSkillTree.h"
#include "AbilityInfo.h"
void UButtonBarSwitcher::NativeConstruct()
{
Super::NativeConstruct();
m_globalEnable = true;
m_alternateSkillSet = false;
m_FindAndAddButtonBar("ButtonBarMain");
m_FindAndAddButtonBar("ButtonBarAlt");
}
bool UButtonBarSwitcher::AssignSkillButton(const FIngameSkillTreeSkill& skill, bool isAlt)
{
if (m_mappedButtons.Find(skill.selectedEffect))
return true;
int32 bar = isAlt ? 1 : 0;
if (bar >= m_buttonBars.Num())
return false;
UAbilityButton* targetButton;
if(!m_buttonBars[bar]->AssignSkillButton(skill, targetButton, isAlt))
{
GERROR("Too many skills, can't assign " + skill.selectedEffect->GetName() + " to bar " + bar);
return false;
}
m_mappedButtons.Add(skill.selectedEffect, targetButton);
return true;
}
void UButtonBarSwitcher::UpdateCooldowns(TArray<class AAbilityState*> abilityStates, ANetworkPlayer* player)
{
for (int32 i = 0; i < abilityStates.Num(); i++)
{
UAbilityButton** button = m_mappedButtons.Find(abilityStates[i]->info);
if (button)
{
(*button)->UpdateState(abilityStates[i], player);
}
}
}
UButtonBar* UButtonBarSwitcher::m_FindAndAddButtonBar(const FName& name)
{
UButtonBar* bar = Cast<UButtonBar>(WidgetTree->FindWidget(name));
if (bar)
{
m_buttonBars.Add(bar);
}
return bar;
}
void UButtonBarSwitcher::SetSkillButtonEnabled(const FIngameSkillTreeSkill& skill, bool enabled)
{
UAbilityButton** button = m_mappedButtons.Find(skill.selectedEffect);
if (button)
{
(*button)->SetButtonEnabled(enabled);
}
}
void UButtonBarSwitcher::SetGlobalEnable(bool enabled)
{
for(UButtonBar* bb : m_buttonBars)
{
bb->SetGlobalEnable(enabled);
}
}
class UAbilityInfo* UButtonBarSwitcher::GetAbilityMapping(int32 index)
{
if(m_buttonBars.Num() != 2)
{
GERROR("m_buttonBars.Num() != 2");
return nullptr;
}
UButtonBar* currentBar = m_buttonBars[m_alternateSkillSet ? 1 : 0];
if(index < 0 || index >= currentBar->buttons.Num())
return nullptr;
return currentBar->buttons[index]->GetAbility();
}
class UAbilityInfo* UButtonBarSwitcher::GetAbilityMapping(int32 index, bool isAlt)
{
if(m_buttonBars.Num() != 2)
{
GERROR("m_buttonBars.Num() != 2");
return nullptr;
}
UButtonBar* currentBar = m_buttonBars[isAlt ? 1 : 0];
if(index < 0 || index >= currentBar->buttons.Num())
return nullptr;
return currentBar->buttons[index]->GetAbility();
}
void UButtonBarSwitcher::TransitionToAlternateSkillSet_Implementation()
{
}
void UButtonBarSwitcher::TransitionToMainSkillSet_Implementation()
{
}
void UButtonBarSwitcher::ToggleSkillSet(bool useAlternateSkillSet)
{
if (m_alternateSkillSet != useAlternateSkillSet)
{
if(useAlternateSkillSet)
TransitionToAlternateSkillSet();
else
TransitionToMainSkillSet();
m_alternateSkillSet = useAlternateSkillSet;
}
}
void UButtonBar::NativeConstruct()
{
TArray<UWidget*> widgets;
WidgetTree->GetAllWidgets(widgets);
for (int32 i = 0; i < widgets.Num(); i++)
{
UAbilityButton* button = Cast<UAbilityButton>(widgets[i]);
if (button)
{
buttons.Add(button);
}
}
}
bool UButtonBar::AssignSkillButton(const FIngameSkillTreeSkill& skill, class UAbilityButton*& buttonOut, bool alt)
{
for (int32 i = 0; i < buttons.Num(); i++)
{
if (buttons[i]->IsAssigned())
continue;
buttonOut = buttons[i];
buttonOut->InitButton(skill.selectedEffect, i, alt);
return true;
}
return false;
}
void UButtonBar::SetGlobalEnable(bool enabled)
{
for(UAbilityButton* button : buttons)
{
if(button)
{
button->SetGlobalEnable(enabled);
}
}
}

View File

@@ -0,0 +1,58 @@
// Project Lab - NHTV Igad
#pragma once
#include "Blueprint/UserWidget.h"
#include "ButtonBarSwitcher.generated.h"
UCLASS()
class UNREALPROJECT_API UButtonBar : public UUserWidget
{
GENERATED_BODY()
public:
virtual void NativeConstruct() override;
bool AssignSkillButton(const struct FIngameSkillTreeSkill& skill, class UAbilityButton*& buttonOut, bool alt);
void SetGlobalEnable(bool enabled);
UPROPERTY()
TArray<class UAbilityButton*> buttons;
};
UCLASS()
class UNREALPROJECT_API UButtonBarSwitcher : public UUserWidget
{
GENERATED_BODY()
public:
virtual void NativeConstruct() override;
bool AssignSkillButton(const struct FIngameSkillTreeSkill& skill, bool isAlt);
void UpdateCooldowns(TArray<class AAbilityState*> abilityStates, class ANetworkPlayer* player);
void SetSkillButtonEnabled(const struct FIngameSkillTreeSkill& skill, bool enabled);
// Set the global enabled button state
void SetGlobalEnable(bool enabled);
class UAbilityInfo* GetAbilityMapping(int32 index);
class UAbilityInfo* GetAbilityMapping(int32 index, bool isAlt);
UFUNCTION(BlueprintNativeEvent, Category="Animation")
void TransitionToAlternateSkillSet();
UFUNCTION(BlueprintNativeEvent, Category="Animation")
void TransitionToMainSkillSet();
void ToggleSkillSet(bool useAlternateSkillSet);
private:
UButtonBar* m_FindAndAddButtonBar(const FName& name);
bool m_globalEnable;
bool m_alternateSkillSet;
UPROPERTY()
TArray<UButtonBar*> m_buttonBars;
UPROPERTY()
TMap<class UAbilityInfo*, UAbilityButton*> m_mappedButtons;
};

View File

@@ -0,0 +1,126 @@
// Project Lab - NHTV Igad
#include "UnrealProject.h"
#include "HealthBar.h"
#include "StatBar.h"
// 1 = Crown
// 2 = Mini-Boss
// 3 = Dot
// 4 = Camp
// 5 = PlayerIcon
static UTexture2D* barIcons[6];
UHealthBar::UHealthBar(const FObjectInitializer& init) : Super(init)
{
barIcons[0] = ConstructorHelpers::FObjectFinder<UTexture2D>(L"/Game/Assets/Art/UI/Minimap/T_IconCrown").Object;
barIcons[1] = ConstructorHelpers::FObjectFinder<UTexture2D>(L"/Game/Assets/Art/UI/Minimap/T_IconMini").Object;
barIcons[2] = ConstructorHelpers::FObjectFinder<UTexture2D>(L"/Game/Assets/Art/UI/Minimap/T_IconDot").Object;
barIcons[3] = ConstructorHelpers::FObjectFinder<UTexture2D>(L"/Game/Assets/Art/UI/Minimap/T_IconCamp").Object;
barIcons[4] = ConstructorHelpers::FObjectFinder<UTexture2D>(L"/Game/Assets/Art/UI/Minimap/T_IconPlayer").Object;
}
void UHealthBar::NativeConstruct()
{
Super::NativeConstruct();
m_currentIcon = (EMinimapIcon)-1;
m_HP = Cast<UStatBar>(WidgetTree->FindWidget("HP"));
m_mana = Cast<UStatBar>(WidgetTree->FindWidget("Mana"));
m_styleSwitcher = Cast<UWidgetSwitcher>(WidgetTree->FindWidget("StyleSwitcher"));
m_HP1 = Cast<UStatBar>(WidgetTree->FindWidget("HP1"));
m_icon = Cast<UImage>(WidgetTree->FindWidget("Icon"));
m_name = Cast<UTextBlock>(WidgetTree->FindWidget("Name"));
SetName("");
SetIcon(EMinimapIcon::None);
if(m_mana)
{
m_mana->SetBarColor(EBarColor::Blue);
}
m_style = 0;
m_friendly = false;
}
void UHealthBar::NativeDestruct()
{
Super::NativeDestruct();
}
void UHealthBar::SetIcon(EMinimapIcon _iconID)
{
if(!m_icon)
return;
if(_iconID == m_currentIcon)
return;
int32 iconID = FMath::Clamp((int32)_iconID, 0, 5);
if(iconID == 0)
m_icon->SetVisibility(ESlateVisibility::Collapsed);
else
{
m_icon->SetBrushFromTexture(barIcons[iconID - 1]);
m_icon->SetVisibility(ESlateVisibility::SelfHitTestInvisible);
}
}
void UHealthBar::SetStyle(int32 style)
{
if(style == m_style)
return;
m_style = FMath::Clamp(style, 0, 1);
m_styleSwitcher->SetActiveWidgetIndex(m_style);
}
void UHealthBar::UpdateHealth(int32 curr, int32 max)
{
m_updateCount++;
bool showAnimation = m_updateCount > 8;
if(m_style == 0)
{
m_HP->SetStat(curr, max, showAnimation);
}
else
{
m_HP1->SetStat(curr, max, showAnimation);
}
}
void UHealthBar::UpdateMana(int32 curr, int32 max, float blocked)
{
if(m_style == 0)
{
m_mana->SetStat(curr, max, true);
}
}
void UHealthBar::UpdateAlignment(bool friendly)
{
m_friendly = friendly;
const FLinearColor colorFriendly = FLinearColor(0.18f, 0.8f, 0.23f);
const FLinearColor colorEnemy = FLinearColor(0.73f, 0.1f, 0.13f);
if(m_style == 0)
{
m_HP->SetBarColor(friendly ? EBarColor::Green : EBarColor::Red);
}
else
{
m_HP1->SetBarColor(friendly ? EBarColor::Green : EBarColor::Red);
}
}
void UHealthBar::SetName(FString name)
{
if(!m_name)
return;
if(name.IsEmpty())
{
m_name->SetVisibility(ESlateVisibility::Collapsed);
}
else
{
if(name.Len() > 16)
{
name = name.Left(13) + "...";
}
m_name->SetText(FText::FromString(name));
m_name->SetVisibility(ESlateVisibility::SelfHitTestInvisible);
}
}

View File

@@ -0,0 +1,53 @@
// Project Lab - NHTV Igad
#pragma once
#include "Blueprint/UserWidget.h"
#include "HealthBar.generated.h"
UENUM()
enum class EMinimapIcon : uint8
{
None = 0,
Crown,
MiniBoss,
Dot,
Camp,
Player
};
UCLASS()
class UNREALPROJECT_API UHealthBar : public UUserWidget
{
GENERATED_BODY()
public:
UHealthBar(const FObjectInitializer& init);
virtual void NativeConstruct() override;
virtual void NativeDestruct() override;
// Icon ID's
// 0 = nothing
// 1 = Crown
// 2 = Mini-Boss
// 3 = Dot
// 4 = Camp
// 5 = PlayerIcon
void SetIcon(EMinimapIcon iconID);
void SetStyle(int32 style);
void UpdateHealth(int32 curr, int32 max);
void UpdateMana(int32 curr, int32 max, float blocked = 0.0f);
void UpdateAlignment(bool friendly);
void SetName(FString name);
private:
int32 m_style;
bool m_friendly;
class UWidgetSwitcher* m_styleSwitcher;
class UStatBar* m_HP;
class UStatBar* m_mana;
class UStatBar* m_HP1;
UTextBlock* m_name;
UImage* m_icon;
EMinimapIcon m_currentIcon;
int32 m_updateCount = 0;
};

View File

@@ -0,0 +1,347 @@
// Project Lab - NHTV Igad
#include "UnrealProject.h"
#include "DefaultPlayerController.h"
#include "IngameHUD.h"
#include "AbilityInfo.h"
#include "AbilityState.h"
#include "NetworkPlayer.h"
#include "HealthBar.h"
#include "CreatureSpawn.h"
#include "PlayerSlot.h"
#include "DefaultGameState.h"
#include "DefaultPlayerState.h"
#include "MiniMapWidget.h"
#include "ToolTipWidget.h"
#include "CombatText/CombatTextWidget.h"
#include "SpellInfoDisplay.h"
#include "ButtonBarSwitcher.h"
#include "BaseSkillObject.h"
#include "WidgetLayoutLibrary.h"
#include "NetworkGhost.h"
#include "TouhouBoss.h"
#include "MiniBossCreature.h"
#include "StatBar.h"
#include <algorithm>
static UClass* healthBarWidgetClass;
static UClass* playerSlotWidgetClass;
UIngameHUD::UIngameHUD(const FObjectInitializer& init)
:Super(init)
{
ConstructorHelpers::FClassFinder<UHealthBar> HealthBarWidgetCF(TEXT("/Game/Assets/GUI/WEEGEE_HealthBar"));
healthBarWidgetClass = HealthBarWidgetCF.Class;
miniMap = nullptr;
}
void UIngameHUD::NativeConstruct()
{
m_myTeam = 0;
m_character = nullptr;
Super::NativeConstruct();
m_spellInfoDisplay = Cast<USpellInfoDisplay>(WidgetTree->FindWidget("SpellInfoDisplay"));
miniMap = Cast<UMiniMapWidget>(WidgetTree->FindWidget("Minimap"));
toolTips = Cast<UToolTipWidget>(WidgetTree->FindWidget("ToolTipLayer"));
combatText = Cast<UCombatTextWidget>(WidgetTree->FindWidget("CombatTextLayer"));
buttonBarSwitcher = Cast<UButtonBarSwitcher>(WidgetTree->FindWidget("ButtonBarSwitcher"));
healthBarLayer = Cast<UCanvasPanel>(WidgetTree->FindWidget("HealthBarLayer"));
// Find stat display items
m_playerStatDisplay.hpBar = Cast<UStatBar>(WidgetTree->FindWidget("HP"));
m_playerStatDisplay.manaBar = Cast<UStatBar>(WidgetTree->FindWidget("Mana"));
m_playerStatDisplay.expBar = Cast<UExperienceBar>(WidgetTree->FindWidget("Exp"));
m_allyStatDisplay.hpBar = Cast<UStatBar>(WidgetTree->FindWidget("HP1"));
m_allyStatDisplay.manaBar = Cast<UStatBar>(WidgetTree->FindWidget("Mana1"));
m_allyStatDisplay.name = Cast<UTextBlock>(WidgetTree->FindWidget("Name1"));
m_InitStatDisplay(m_playerStatDisplay);
m_InitStatDisplay(m_allyStatDisplay);
check(healthBarLayer);
}
void UIngameHUD::NativeDestruct()
{
Super::NativeDestruct();
}
void UIngameHUD::NativeTick(const FGeometry& MyGeometry, float InDeltaTime)
{
Super::NativeTick(MyGeometry, InDeltaTime);
auto p = m_healthBars.CreateIterator();
while (p)
{
m_UpdateHealthBar(p.Key(), p.Value());
++p;
}
ADefaultPlayerState* ps = Cast<ADefaultPlayerState>(GetOwningPlayer()->PlayerState);
if (IsValid(ps))
{
m_UpdateStatDisplay(ps, m_playerStatDisplay);
m_UpdateStatDisplay(ps->teamMate, m_allyStatDisplay);
}
//UWorld* world = GetWorld();
//check(world);
//ADefaultGameState* state = Cast<ADefaultGameState>(world->GetGameState());
}
void UIngameHUD::NativeOnAssignCharacter(class ANetworkPossessable* pawn /*= nullptr*/, TArray<FIngameSkillTreeSkill> skillsetPrototype /*= TArray<FIngameSkillTreeSkill>()*/)
{
m_character = pawn;
// Cast to ghost or player
ANetworkPlayer* player = Cast<ANetworkPlayer>(pawn);
ANetworkGhost* ghost = Cast<ANetworkGhost>(pawn);
if(ghost)
{
// Grey out buttons in ghost mode
buttonBarSwitcher->SetGlobalEnable(false);
}
else if(player)
{
// Enable buttons back in player mode
buttonBarSwitcher->SetGlobalEnable(true);
// Set skill prototypes
if(buttonBarSwitcher)
{
for(int32 i = 0; i < skillsetPrototype.Num(); i++)
{
// Don't assign buttons for passive skills
if(skillsetPrototype[i].selectedEffect->passive)
continue;
switch(skillsetPrototype[i].abilityType)
{
case 0:
buttonBarSwitcher->AssignSkillButton(skillsetPrototype[i], false);
break;
case 1:
buttonBarSwitcher->AssignSkillButton(skillsetPrototype[i], true);
break;
case 2:
if(skillsetPrototype[i].selectedEffect && !skillsetPrototype[i].selectedEffect->passive)
{
GERROR("Non-passive skill added to skill with shape type == passive, " +
skillsetPrototype[i].skillObject->GetName() + " <= " +
skillsetPrototype[i].selectedEffect->GetName());
}
}
}
}
m_myTeam = player->GetTeam();
}
OnAssignCharacter(pawn);
}
void UIngameHUD::OnLevelUp(TArray<FIngameSkillTreeSkill> updatedSkills)
{
if (m_spellInfoDisplay && GetPlayer())
m_spellInfoDisplay->OnLevelUp(GetPlayer(), updatedSkills);
if (buttonBarSwitcher)
{
for (int32 i = 0; i < updatedSkills.Num(); i++)
{
buttonBarSwitcher->SetSkillButtonEnabled(updatedSkills[i], true);
}
}
}
void UIngameHUD::UpdateCooldowns(TArray<class AAbilityState*> abilityStates, ANetworkPlayer* player)
{
if (buttonBarSwitcher)
buttonBarSwitcher->UpdateCooldowns(abilityStates, player);
}
void UIngameHUD::OnCharacterCreated(ANetworkCharacter* character)
{
if (m_healthBars.Find(character))
{
// When OnCharacterCreated is called twice
GWWARNING(L"OnCharacterCreated called more thatn once");
return;
}
UHealthBar* widget = CreateWidget<UHealthBar>(GetOwningPlayer(), healthBarWidgetClass);
check(widget);
healthBarLayer->AddChild(widget);
m_healthBars.Add(character, widget);
m_UpdateHealthBar(character, widget);
}
void UIngameHUD::OnCharacterDestroyed(ANetworkCharacter* character)
{
auto it = m_healthBars.Find(character);
if (it)
{
(*it)->RemoveFromViewport();
m_healthBars.Remove(character);
}
else
{
// When OnCharacterDestroyed is called twice
GWWARNING(L"OnCharacterDestroyed called more than once");
}
}
ANetworkPlayer* UIngameHUD::GetTeamMate() const
{
if (Cast<ANetworkPlayer>(m_character))
{
ANetworkPlayer* teamMate = Cast<ANetworkPlayer>(m_character)->GetTeamMate();
return teamMate;
}
return nullptr;
}
ANetworkPlayer* UIngameHUD::GetPlayer() const
{
return Cast<ANetworkPlayer>(m_character);
}
ANetworkGhost* UIngameHUD::GetGhost() const
{
return Cast<ANetworkGhost>(m_character);
}
class ADefaultPlayerState* UIngameHUD::GetPlayerState() const
{
if (!m_character)
return nullptr;
return Cast<ADefaultPlayerState>(m_character->PlayerState);
}
void UIngameHUD::m_UpdateHealthBar(class ANetworkCharacter* character, class UHealthBar* bar)
{
APlayerController* pc = GetOwningPlayer();
if (!IsValid(pc)) return;
FVector screenPos;
const float height = character->GetCapsuleComponent()->GetScaledCapsuleHalfHeight();
const FVector position = character->GetActorLocation();
const FVector worldLocation = FVector(position.X, position.Y, position.Z + height);
// Check if is approximately in camera view
const FVector forward = pc->PlayerCameraManager->GetCameraRotation().RotateVector(FVector(1.0f, 0.0f, 0.0f));
const FVector dir = (worldLocation - pc->PlayerCameraManager->GetCameraLocation()).GetSafeNormal();
float dot = FVector::DotProduct(forward, dir);
if (dot < 0.01f)
{
bar->SetVisibility(ESlateVisibility::Hidden);
return;
}
bar->SetVisibility(ESlateVisibility::Visible);
pc->ProjectWorldLocationToScreenWithDistance(FVector(position.X, position.Y, position.Z + height), screenPos);
const float viewportScale = UWidgetLayoutLibrary::GetViewportScale(healthBarLayer);
uint32 otherTeam = character->GetTeam();
// Check witch bar style to use
bool useExtendedBarStyle = character->playerName.Len() > 0;
if(useExtendedBarStyle)
{
bar->SetStyle(0);
bar->UpdateMana(character->GetMana(), character->GetMaxMana(), character->GetBlockedMana());
bar->SetName(character->playerName);
}
else
{
bar->SetStyle(1);
bar->SetName("");
}
bar->UpdateAlignment(otherTeam == m_myTeam);
bar->UpdateHealth(character->GetHealth(), character->GetMaxHealth());
// Set the icon next to the bar
EMinimapIcon icon = EMinimapIcon::None;
if(character->IsA<ATouhouBoss>())
{
icon = EMinimapIcon::Crown;
}
else if(character->IsA<AMiniBossCreature>())
{
icon = EMinimapIcon::MiniBoss;
}
bar->SetIcon(icon);
// Set the on-screen position
UCanvasPanelSlot* asSlot = Cast<UCanvasPanelSlot>(bar->Slot);
if (IsValid(asSlot))
{
asSlot->SetAutoSize(true);
asSlot->SetAlignment(FVector2D(0.5f, 1));
const FVector2D setPos = FVector2D(screenPos.X, screenPos.Y) / viewportScale;
asSlot->SetPosition(FVector2D(FPlatformMath::RoundToFloat(setPos.X), FPlatformMath::RoundToFloat(setPos.Y)));
}
}
void UIngameHUD::m_UpdateStatDisplay(class ADefaultPlayerState* state, const FStatDisplay& sd)
{
ANetworkPlayer* player = state ? state->character : nullptr;
if(sd.hpBar)
{
if(!player)
sd.hpBar->SetStat(0.0f, true);
else
{
sd.hpBar->SetStat(player->GetHealth(), player->GetMaxHealth(), true);
}
}
if(sd.manaBar)
{
if(!player)
{
sd.manaBar->SetBlocked(0.0f);
sd.manaBar->SetStat(0, 1, true);
}
else
{
sd.manaBar->SetStat(player->GetMana(), player->GetMaxMana(), true);
sd.manaBar->SetBlocked((float)player->GetBlockedMana() / (float)player->GetMaxMana());
}
}
if(sd.expBar)
{
if(state)
{
if(state->GetLevel() == state->GetMaxLevel())
sd.expBar->Update(1.0f, state->GetMaxLevel(), true);
else
sd.expBar->Update((float)state->GetExperience() / (float)state->GetExperienceToLevel(), state->GetLevel(), false);
}
else
{
sd.expBar->Update(0.0f, 0, false);
}
}
if(sd.name)
{
if(state)
{
state->UpdatePersona();
sd.name->SetText(FText::FromString(state->nickname));
}
else
{
sd.name->SetText(FText());
}
}
if(sd.avatar && state)
{
sd.avatar->SetBrushFromTexture(state->avatar);
}
}
void UIngameHUD::m_InitStatDisplay(const FStatDisplay& sd)
{
if(sd.hpBar)
{
sd.hpBar->SetBarColor(EBarColor::GreenGradient);
}
if(sd.manaBar)
{
sd.manaBar->SetBarColor(EBarColor::BlueGradient);
}
}

View File

@@ -0,0 +1,93 @@
// Project Lab - NHTV Igad
#pragma once
#include "Blueprint/UserWidget.h"
#include "IngameSkillTree.h"
#include <vector>
#include <map>
#include "IngameHUD.generated.h"
UCLASS()
class UExperienceBar : public UUserWidget
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintImplementableEvent)
void Update(float rate, int32 level, bool max);
};
struct FStatDisplay
{
class UStatBar* hpBar;
class UStatBar* manaBar;
class UExperienceBar* expBar;
class UImage* avatar;
class UTextBlock* name;
};
UCLASS()
class UNREALPROJECT_API UIngameHUD : public UUserWidget
{
GENERATED_BODY()
public:
UIngameHUD(const FObjectInitializer& init);
virtual void NativeConstruct() override;
virtual void NativeDestruct() override;
virtual void NativeTick(const FGeometry& MyGeometry, float InDeltaTime) override;
// Sets the player owned character
void NativeOnAssignCharacter(class ANetworkPossessable* pawn = nullptr, TArray<FIngameSkillTreeSkill> skillsetPrototype = TArray<FIngameSkillTreeSkill>());
UFUNCTION(BlueprintImplementableEvent, Category = "HUD")
void OnAssignCharacter(ANetworkPossessable* pawn);
// Called when the character levels up
void OnLevelUp(TArray<FIngameSkillTreeSkill> updatedSkills);
// Updates the displayed cooldowns in the UI with the provided ability states
void UpdateCooldowns(TArray<class AAbilityState*> abilityStates, class ANetworkPlayer* player);
// Called when a character spawns
// this makes it display a health-bar in the HUD
void OnCharacterCreated(class ANetworkCharacter* character);
// Called when a character despawns(destroyed, killed)
// this removes all the health-bars, etc. for this character
void OnCharacterDestroyed(class ANetworkCharacter* character);
UFUNCTION(BlueprintCallable, Category = "UI")
class ANetworkPlayer* GetTeamMate() const;
UFUNCTION(BlueprintCallable, Category = "UI")
class ANetworkPlayer* GetPlayer() const;
UFUNCTION(BlueprintCallable, Category = "UI")
class ANetworkGhost* GetGhost() const;
UFUNCTION(BlueprintCallable, Category = "UI")
class ADefaultPlayerState* GetPlayerState() const;
class UMiniMapWidget* miniMap;
class UToolTipWidget* toolTips;
class UCombatTextWidget* combatText;
class UButtonBarSwitcher* buttonBarSwitcher;
class UCanvasPanel* healthBarLayer;
private:
// This updates an on screen health bar for a given network character
void m_UpdateHealthBar(class ANetworkCharacter* character, class UHealthBar* bar);
void m_UpdateStatDisplay(class ADefaultPlayerState* player, const FStatDisplay& statDisplay);
void m_InitStatDisplay(const FStatDisplay& statDisplay);
FStatDisplay m_playerStatDisplay;
FStatDisplay m_allyStatDisplay;
// Maps every character in the game to a health bar widget on-screen
UPROPERTY()
TMap<class ANetworkCharacter*, class UHealthBar*> m_healthBars;
UPROPERTY()
class ANetworkPossessable* m_character;
UPROPERTY()
class USpellInfoDisplay* m_spellInfoDisplay;
uint32 m_myTeam;
};

View File

@@ -0,0 +1,13 @@
// Project Lab - NHTV Igad
#include "UnrealProject.h"
#include "KOTHHUD.h"
void UKOTHHUD::NativeConstruct()
{
Super::NativeConstruct();
}
void UKOTHHUD::Update(TArray<FKOTHTeamState> teamStates)
{
}

View File

@@ -0,0 +1,16 @@
// Project Lab - NHTV Igad
#pragma once
#include "Blueprint/UserWidget.h"
#include "KOTHTeamState.h"
#include "KOTHHUD.generated.h"
UCLASS()
class UNREALPROJECT_API UKOTHHUD : public UUserWidget
{
GENERATED_BODY()
public:
void NativeConstruct() override;
void Update(TArray<FKOTHTeamState> teamStates);
};

View File

@@ -0,0 +1,14 @@
// Project Lab - NHTV Igad
#include "UnrealProject.h"
#include "KeyDisplay.h"
void UKeyDisplay::NativeConstruct()
{
Super::NativeConstruct();
}
void UKeyDisplay::NativeDestruct()
{
Super::NativeDestruct();
}

View File

@@ -0,0 +1,16 @@
// Project Lab - NHTV Igad
#pragma once
#include "Blueprint/UserWidget.h"
#include "KeyDisplay.generated.h"
UCLASS()
class UNREALPROJECT_API UKeyDisplay : public UUserWidget
{
GENERATED_BODY()
public:
virtual void NativeConstruct() override;
virtual void NativeDestruct() override;
};

View File

@@ -0,0 +1,192 @@
// Project Lab - NHTV Igad
#include "UnrealProject.h"
#include "StatBar.h"
static UTexture2D* barTextures[6];
static FLinearColor barColors[4];
static UMaterial* textureBarMaterialClass;
UStatBar::UStatBar(const FObjectInitializer& init) : Super(init)
{
textureBarMaterialClass = ConstructorHelpers::FObjectFinder<UMaterial>(L"/Game/Assets/Art/UI/M_HealthBar2.M_HealthBar2").Object;
barColors[0] = FLinearColor::Green * 0.5f;
barColors[1] = FLinearColor::Red * 0.6f;
barColors[2] = FLinearColor::Blue * 0.8f;
barColors[3] = FLinearColor(1.0f, 0.0f, 1.0f, 1.0f);
barTextures[0] = ConstructorHelpers::FObjectFinder<UTexture2D>(L"/Game/Assets/Art/UI/HealthBar/UI_MainStatusBarHealth").Object;
barTextures[1] = ConstructorHelpers::FObjectFinder<UTexture2D>(L"/Game/Assets/Art/UI/HealthBar/UI_MainStatusBarMana").Object;
m_lastValue = 1.0f;
m_currentValue = 1.0f;
damageAnimationDuration = 0.3f;
m_damageAnimation = 0.0f;
showText = false;
}
void UStatBar::NativeConstruct()
{
Super::NativeConstruct();
m_base = Cast<UImage>(WidgetTree->FindWidget("Base"));
m_blocked = Cast<UImage>(WidgetTree->FindWidget("Blocked"));
m_damage = Cast<UImage>(WidgetTree->FindWidget("Damage"));
m_text = Cast<UTextBlock>(WidgetTree->FindWidget("BarText"));
if(m_damage)
{
m_damage->SetVisibility(ESlateVisibility::Hidden);
UMaterialInstanceDynamic* damageMat = m_damage->GetDynamicMaterial();
damageMat->SetScalarParameterValue("Brightness", 4.0f);
}
if(m_blocked)
m_blocked->SetVisibility(ESlateVisibility::Hidden);
}
#pragma optimize("", off)
void UStatBar::NativeTick(const FGeometry& MyGeometry, float InDeltaTime)
{
Super::NativeTick(MyGeometry, InDeltaTime);
if(m_damageAnimation > 0.0f && m_damage)
{
float r = m_damageAnimation / damageAnimationDuration;
float damageSize = (m_currentValue - m_lastValue);
UMaterialInstanceDynamic* matDamage = m_damage->GetDynamicMaterial();
if(damageSize < 0.0f)
{
damageSize *= (1.0f - r);
matDamage->SetScalarParameterValue("Start", m_currentValue);
matDamage->SetScalarParameterValue("End", m_lastValue + damageSize);
}
else
{
damageSize *= (1.0f-r);
matDamage->SetScalarParameterValue("Start", m_lastValue + damageSize);
matDamage->SetScalarParameterValue("End", m_currentValue);
}
m_damageAnimation -= InDeltaTime;
if(m_damageAnimation <= 0.0f)
{
m_damageAnimation = 0.0f;
m_damage->SetVisibility(ESlateVisibility::Hidden);
}
}
}
#pragma optimize("", off)
void UStatBar::SetStat(float newStat, bool applyAnimation)
{
if(!m_base)
return;
if(newStat == m_currentValue)
return;
float delta = newStat - m_currentValue;
if(delta != 0 && m_damageAnimation > 0.0f)
{
// Append animation
float r = m_damageAnimation / damageAnimationDuration;
float damageSize = (m_currentValue - m_lastValue);
if(damageSize < 0.0f)
damageSize *= (1.0f - r);
else
damageSize *= (1.0f - r);
delta += damageSize;
m_lastValue = m_lastValue + damageSize;
}
else
{
m_lastValue = m_currentValue;
}
m_currentValue = newStat;
// Apply animation
if(delta != 0.0f && applyAnimation && m_damage)
{
const FLinearColor deltaColor = FLinearColor(1.0f, 0.0f, 0.0f, 1.0f);
m_damageAnimation = damageAnimationDuration;
UMaterialInstanceDynamic* matDamage = m_base->GetDynamicMaterial();
if(delta < 0.0f)
{
matDamage->SetScalarParameterValue("Start", newStat);
matDamage->SetScalarParameterValue("End", m_lastValue);
}
else
{
matDamage->SetScalarParameterValue("Start", m_lastValue);
matDamage->SetScalarParameterValue("End", newStat);
}
m_damage->SetVisibility(ESlateVisibility::SelfHitTestInvisible);
}
UMaterialInstanceDynamic* matBase = m_base->GetDynamicMaterial();
matBase->SetScalarParameterValue("Start", 0.0f);
matBase->SetScalarParameterValue("End", newStat);
}
void UStatBar::SetStat(int32 newStat, int32 max, bool applyAnimation)
{
if(showText && m_text)
{
FText t = FText::FromString(FString::Printf(L"%d / %d", newStat, max));
m_text->SetText(t);
m_text->SetVisibility(ESlateVisibility::SelfHitTestInvisible);
}
else
{
m_text->SetVisibility(ESlateVisibility::Hidden);
}
float r = (float)newStat / (float)max;
SetStat(r, applyAnimation);
}
void UStatBar::SetBlocked(float newBlocked)
{
if(!m_blocked)
return;
UMaterialInstanceDynamic* mat = m_blocked->GetDynamicMaterial();
if(newBlocked > 0.0f)
{
mat->SetScalarParameterValue("Start", 1.0f - newBlocked);
mat->SetScalarParameterValue("End", 1.0f);
m_blocked->SetVisibility(ESlateVisibility::SelfHitTestInvisible);
}
else
{
m_blocked->SetVisibility(ESlateVisibility::Hidden);
}
}
void UStatBar::SetBarColor(EBarColor _colorID)
{
int32 colorID = (int32)_colorID;
if(!m_base)
return;
if((colorID & 0x80) != 0)
{
colorID = colorID & 0x7F;
colorID = FMath::Clamp(colorID, 0, (int32)(sizeof(barTextures) / sizeof(UTexture2D*)));
m_base->SetBrushFromMaterial(textureBarMaterialClass);
m_blocked->SetBrushFromMaterial(textureBarMaterialClass);
m_damage->SetBrushFromMaterial(textureBarMaterialClass);
UMaterialInstanceDynamic* baseMat = m_base->GetDynamicMaterial();
baseMat->SetTextureParameterValue("Texture", barTextures[colorID]);
baseMat = m_damage->GetDynamicMaterial();
baseMat->SetTextureParameterValue("Texture", barTextures[colorID]);
baseMat = m_blocked->GetDynamicMaterial();
baseMat->SetTextureParameterValue("Texture", barTextures[colorID]);
}
else
{
colorID = FMath::Clamp(colorID, 0, (int32)(sizeof(barColors) / sizeof(FLinearColor)));
UMaterialInstanceDynamic* baseMat = m_base->GetDynamicMaterial();
baseMat->SetVectorParameterValue("Color", barColors[colorID]);
}
}

View File

@@ -0,0 +1,49 @@
// Project Lab - NHTV Igad
#pragma once
#include "Blueprint/UserWidget.h"
#include "StatBar.generated.h"
enum class EBarColor
{
Green = 0,
Red,
Blue,
Purple,
GreenGradient = 0x80,
BlueGradient
};
/**
*
*/
UCLASS()
class UNREALPROJECT_API UStatBar : public UUserWidget
{
GENERATED_BODY()
public:
UStatBar(const FObjectInitializer& init);
void NativeConstruct() override;
void NativeTick(const FGeometry& MyGeometry, float InDeltaTime) override;
void SetStat(int32 newStat, int32 max, bool applyAnimation);
void SetStat(float newStat, bool applyAnimation);
void SetBlocked(float newBlocked);
void SetBarColor(EBarColor colorID);
UPROPERTY(EditDefaultsOnly, Category = "Stat Bar")
float damageAnimationDuration;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Stat Bar")
bool showText;
private:
float m_damageAnimation;
float m_lastValue;
float m_currentValue;
UImage* m_base;
UImage* m_blocked;
UImage* m_damage;
UTextBlock* m_text;
};

View File

@@ -0,0 +1,49 @@
// Project Lab - NHTV Igad
#include "UnrealProject.h"
#include "Timer.h"
#include "Kismet/KismetStringLibrary.h"
void UTimer::NativeConstruct()
{
m_duration = 0.0f;
m_text = Cast<UTextBlock>(WidgetTree->FindWidget("Text"));
m_timerText = Cast<UTextBlock>(WidgetTree->FindWidget("Time"));
m_clock = Cast<UImage>(WidgetTree->FindWidget("Klokje"));
if(!m_text)
GWARNING("No \"Text\" text widget found in " + GetName());
if(!m_text)
GWARNING("No \"Time\" text widget found in " + GetName());
if(!m_clock)
GWARNING("No \"Klokje\" image widget found in " + GetName());
Super::NativeConstruct();
}
void UTimer::NativeTick(const FGeometry& MyGeometry, float InDeltaTime)
{
m_time = FMath::Clamp(m_time - InDeltaTime, 0.0f, m_duration);
if(m_duration == 0.0f)
OnSetTimer(0.0f);
else
OnSetTimer(m_time / m_duration);
if(m_timerText)
{
FString msg = UKismetStringLibrary::TimeSecondsToString(m_time);
m_timerText->SetText(FText::FromString(msg));
}
Super::NativeTick(MyGeometry, InDeltaTime);
}
void UTimer::SetTimer(float duration, bool reset)
{
m_duration = duration;
if(reset)
m_time = duration;
}
void UTimer::SetText(const FString& text)
{
if(m_text)
m_text->SetText(FText::FromString(text));
}

View File

@@ -0,0 +1,44 @@
// Project Lab - NHTV Igad
#pragma once
#include "Blueprint/UserWidget.h"
#include "Timer.generated.h"
/**
*
*/
UCLASS()
class UNREALPROJECT_API UTimer : public UUserWidget
{
GENERATED_BODY()
public:
// Calbacks handling timer changes
UFUNCTION(BlueprintImplementableEvent, Category = "HUDTimer")
void OnSetTimer(float rate);
UFUNCTION(BlueprintImplementableEvent, Category = "HUDTimer")
void OnHide(); // Play animation
UFUNCTION(BlueprintImplementableEvent, Category = "HUDTimer")
void OnShow(); // Play animation
void NativeConstruct();
void NativeTick(const FGeometry& MyGeometry, float InDeltaTime) override;
UFUNCTION(BlueprintCallable, Category = "HUDTimer")
void SetTimer(float duration, bool reset = true);
UFUNCTION(BlueprintCallable, Category = "HUDTimer")
void SetText(const FString& text);
UFUNCTION(BlueprintCallable, Category = "HUDTimer")
float GetTime() const
{
return m_time;
}
private:
float m_time;
float m_duration;
UImage* m_clock;
UTextBlock* m_text;
UTextBlock* m_timerText;
};