fix: selection
This commit is contained in:
@@ -5,7 +5,7 @@ USkillTreeComponent::USkillTreeComponent()
|
||||
{
|
||||
PrimaryComponentTick.bCanEverTick = false;
|
||||
|
||||
AvailableSkillPoints = 5; // Start with 5 skill points for testing
|
||||
AvailableSkillPoints = 5;
|
||||
TotalSkillPointsEarned = 5;
|
||||
CurrentSelectionCost = 0;
|
||||
}
|
||||
@@ -22,22 +22,22 @@ void USkillTreeComponent::InitializeSkillTree()
|
||||
|
||||
if (!SkillDataTable)
|
||||
{
|
||||
UE_LOG(LogTemp, Warning, TEXT("SkillTreeComponent: No skill data table assigned!"));
|
||||
UE_LOG(LogTemp, Warning,
|
||||
TEXT("SkillTreeComponent: No skill data table assigned!"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Load all skills from the data table using RowNames as IDs
|
||||
TArray<FName> RowNames = SkillDataTable->GetRowNames();
|
||||
|
||||
for (const FName& RowName : RowNames)
|
||||
{
|
||||
FSkillNodeData* Row = SkillDataTable->FindRow<FSkillNodeData>(RowName, TEXT("SkillTreeComponent"));
|
||||
FSkillNodeData* Row = SkillDataTable->FindRow<FSkillNodeData>(
|
||||
RowName, TEXT("SkillTreeComponent"));
|
||||
if (Row)
|
||||
{
|
||||
FSkillNodeRuntime RuntimeNode;
|
||||
RuntimeNode.NodeData = *Row;
|
||||
RuntimeNode.CurrentState = ESkillNodeState::Locked;
|
||||
RuntimeNode.bIsSelected = false;
|
||||
|
||||
// Use RowName as the skill ID
|
||||
AllSkills.Add(RowName, RuntimeNode);
|
||||
@@ -46,7 +46,8 @@ void USkillTreeComponent::InitializeSkillTree()
|
||||
|
||||
UpdateSkillStates();
|
||||
|
||||
UE_LOG(LogTemp, Log, TEXT("SkillTreeComponent: Initialized with %d skills"), AllSkills.Num());
|
||||
UE_LOG(LogTemp, Log, TEXT("SkillTreeComponent: Initialized with %d skills"),
|
||||
AllSkills.Num());
|
||||
}
|
||||
|
||||
void USkillTreeComponent::AddSkillPoints(int32 Amount)
|
||||
@@ -84,27 +85,24 @@ bool USkillTreeComponent::SelectSkill(FName SkillID)
|
||||
|
||||
FSkillNodeRuntime* SkillNode = AllSkills.Find(SkillID);
|
||||
|
||||
// Check if already purchased
|
||||
if (SkillNode->CurrentState == ESkillNodeState::Purchased)
|
||||
// Validate skill state
|
||||
switch (SkillNode->CurrentState)
|
||||
{
|
||||
case ESkillNodeState::Purchased:
|
||||
// Already purchased, cannot select
|
||||
ErrorMessage = FText::FromString(TEXT("Skill already purchased"));
|
||||
OnSelectionError.Broadcast(SkillID, ErrorMessage);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if already selected
|
||||
if (SkillNode->bIsSelected)
|
||||
{
|
||||
case ESkillNodeState::Selected:
|
||||
// Already selected, cannot select again
|
||||
ErrorMessage = FText::FromString(TEXT("Skill already selected"));
|
||||
OnSelectionError.Broadcast(SkillID, ErrorMessage);
|
||||
return false;
|
||||
}
|
||||
|
||||
// For locked skills, we allow selection but will validate on purchase
|
||||
case ESkillNodeState::Locked:
|
||||
// For locked skills, we allow selection but validate prerequisites
|
||||
// This allows players to "plan" their build
|
||||
if (SkillNode->CurrentState == ESkillNodeState::Locked)
|
||||
{
|
||||
// Check if prerequisites would be met with current selection
|
||||
bool bWouldBeAvailable = true;
|
||||
for (const FName& PrereqID : SkillNode->NodeData.Prerequisites)
|
||||
{
|
||||
@@ -114,17 +112,22 @@ bool USkillTreeComponent::SelectSkill(FName SkillID)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bWouldBeAvailable)
|
||||
{
|
||||
ErrorMessage = FText::FromString(TEXT("Prerequisites not selected. Select prerequisite skills first."));
|
||||
ErrorMessage = FText::FromString(TEXT(
|
||||
"Prerequisites not selected. Select prerequisite skills first"));
|
||||
OnSelectionError.Broadcast(SkillID, ErrorMessage);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case ESkillNodeState::Available:
|
||||
// Available skills can be selected without additional checks
|
||||
break;
|
||||
}
|
||||
|
||||
// Add to selection
|
||||
SkillNode->bIsSelected = true;
|
||||
SkillNode->CurrentState = ESkillNodeState::Selected;
|
||||
SelectedSkills.Add(SkillID);
|
||||
UpdateSelectionCost();
|
||||
|
||||
@@ -137,16 +140,12 @@ bool USkillTreeComponent::SelectSkill(FName SkillID)
|
||||
bool USkillTreeComponent::DeselectSkill(FName SkillID)
|
||||
{
|
||||
if (!AllSkills.Contains(SkillID))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
FSkillNodeRuntime* SkillNode = AllSkills.Find(SkillID);
|
||||
|
||||
if (!SkillNode->bIsSelected)
|
||||
{
|
||||
if (SkillNode->CurrentState != ESkillNodeState::Selected)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if any selected skills depend on this one
|
||||
for (const FName& SelectedID : SelectedSkills)
|
||||
@@ -154,21 +153,28 @@ bool USkillTreeComponent::DeselectSkill(FName SkillID)
|
||||
if (SelectedID != SkillID)
|
||||
{
|
||||
FSkillNodeRuntime* SelectedNode = AllSkills.Find(SelectedID);
|
||||
if (SelectedNode && SelectedNode->NodeData.Prerequisites.Contains(SkillID))
|
||||
if (SelectedNode
|
||||
&& SelectedNode->NodeData.Prerequisites.Contains(SkillID))
|
||||
{
|
||||
// Can't deselect if other selected skills depend on it
|
||||
FText ErrorMessage = FText::FromString(TEXT("Other selected skills depend on this one"));
|
||||
FText ErrorMessage = FText::FromString(
|
||||
TEXT("Other selected skills depend on this one"));
|
||||
OnSelectionError.Broadcast(SkillID, ErrorMessage);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove from selection
|
||||
SkillNode->bIsSelected = false;
|
||||
// Remove from selection and update state
|
||||
SelectedSkills.Remove(SkillID);
|
||||
UpdateSelectionCost();
|
||||
|
||||
// Update state to either Available or Locked based on prerequisites
|
||||
if (ArePrerequisitesMet(SkillNode->NodeData))
|
||||
SkillNode->CurrentState = ESkillNodeState::Available;
|
||||
else
|
||||
SkillNode->CurrentState = ESkillNodeState::Locked;
|
||||
|
||||
OnSkillSelectionChanged.Broadcast(CurrentSelectionCost);
|
||||
OnSkillStateChanged.Broadcast(SkillID);
|
||||
|
||||
@@ -181,7 +187,11 @@ void USkillTreeComponent::ClearSelection()
|
||||
{
|
||||
if (FSkillNodeRuntime* SkillNode = AllSkills.Find(SkillID))
|
||||
{
|
||||
SkillNode->bIsSelected = false;
|
||||
// Update state based on prerequisites
|
||||
if (ArePrerequisitesMet(SkillNode->NodeData))
|
||||
SkillNode->CurrentState = ESkillNodeState::Available;
|
||||
else
|
||||
SkillNode->CurrentState = ESkillNodeState::Locked;
|
||||
OnSkillStateChanged.Broadcast(SkillID);
|
||||
}
|
||||
}
|
||||
@@ -201,14 +211,18 @@ bool USkillTreeComponent::ConfirmPurchase()
|
||||
return false;
|
||||
}
|
||||
|
||||
// Sort selected skills by purchase order to ensure prerequisites are purchased first
|
||||
// Sort selected skills by purchase order to ensure prerequisites are
|
||||
// purchased first
|
||||
TArray<FName> SortedSelection = SelectedSkills;
|
||||
SortedSelection.Sort([this](const FName& A, const FName& B) {
|
||||
SortedSelection.Sort(
|
||||
[this](const FName& A, const FName& B)
|
||||
{
|
||||
FSkillNodeRuntime* NodeA = AllSkills.Find(A);
|
||||
FSkillNodeRuntime* NodeB = AllSkills.Find(B);
|
||||
if (NodeA && NodeB)
|
||||
{
|
||||
return NodeA->NodeData.PurchaseOrder < NodeB->NodeData.PurchaseOrder;
|
||||
return NodeA->NodeData.PurchaseOrder
|
||||
< NodeB->NodeData.PurchaseOrder;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
@@ -218,17 +232,17 @@ bool USkillTreeComponent::ConfirmPurchase()
|
||||
{
|
||||
FSkillNodeRuntime* SkillNode = AllSkills.Find(SkillID);
|
||||
if (!SkillNode)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check prerequisites (considering already processed skills in this batch)
|
||||
// Check prerequisites (considering already processed skills in this
|
||||
// batch)
|
||||
bool bPrereqsMet = true;
|
||||
for (const FName& PrereqID : SkillNode->NodeData.Prerequisites)
|
||||
{
|
||||
if (!IsSkillPurchased(PrereqID))
|
||||
{
|
||||
// Check if it's in our current batch and would be purchased before this
|
||||
// Check if it's in our current batch and would be purchased
|
||||
// before this
|
||||
int32 PrereqIndex = SortedSelection.IndexOfByKey(PrereqID);
|
||||
int32 CurrentIndex = SortedSelection.IndexOfByKey(SkillID);
|
||||
|
||||
@@ -243,9 +257,9 @@ bool USkillTreeComponent::ConfirmPurchase()
|
||||
if (!bPrereqsMet)
|
||||
{
|
||||
FText ErrorMessage = FText::Format(
|
||||
FText::FromString(TEXT("Cannot purchase {0}: prerequisites not met")),
|
||||
SkillNode->NodeData.DisplayName
|
||||
);
|
||||
FText::FromString(
|
||||
TEXT("Cannot purchase {0}: prerequisites not met")),
|
||||
SkillNode->NodeData.DisplayName);
|
||||
OnSelectionError.Broadcast(SkillID, ErrorMessage);
|
||||
return false;
|
||||
}
|
||||
@@ -259,7 +273,6 @@ bool USkillTreeComponent::ConfirmPurchase()
|
||||
{
|
||||
// Mark as purchased
|
||||
SkillNode->CurrentState = ESkillNodeState::Purchased;
|
||||
SkillNode->bIsSelected = false;
|
||||
PurchasedSkills.Add(SkillID);
|
||||
|
||||
// Apply effects
|
||||
@@ -298,14 +311,13 @@ bool USkillTreeComponent::IsSkillAvailable(FName SkillID) const
|
||||
{
|
||||
const FSkillNodeRuntime* SkillNode = AllSkills.Find(SkillID);
|
||||
if (!SkillNode)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return SkillNode->CurrentState == ESkillNodeState::Available;
|
||||
}
|
||||
|
||||
bool USkillTreeComponent::CanSelectSkill(FName SkillID, FText& OutErrorMessage) const
|
||||
bool USkillTreeComponent::CanSelectSkill(FName SkillID,
|
||||
FText& OutErrorMessage) const
|
||||
{
|
||||
const FSkillNodeRuntime* SkillNode = AllSkills.Find(SkillID);
|
||||
if (!SkillNode)
|
||||
@@ -314,34 +326,38 @@ bool USkillTreeComponent::CanSelectSkill(FName SkillID, FText& OutErrorMessage)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (SkillNode->CurrentState == ESkillNodeState::Purchased)
|
||||
switch (SkillNode->CurrentState)
|
||||
{
|
||||
case ESkillNodeState::Purchased:
|
||||
OutErrorMessage = FText::FromString(TEXT("Skill already purchased"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (SkillNode->bIsSelected)
|
||||
{
|
||||
case ESkillNodeState::Selected:
|
||||
OutErrorMessage = FText::FromString(TEXT("Skill already selected"));
|
||||
return false;
|
||||
}
|
||||
|
||||
case ESkillNodeState::Locked:
|
||||
case ESkillNodeState::Available:
|
||||
OutErrorMessage = FText::GetEmpty();
|
||||
return true;
|
||||
|
||||
default:
|
||||
OutErrorMessage = FText::FromString(TEXT("Unknown skill state"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ESkillNodeState USkillTreeComponent::GetSkillState(FName SkillID) const
|
||||
{
|
||||
const FSkillNodeRuntime* SkillNode = AllSkills.Find(SkillID);
|
||||
if (SkillNode)
|
||||
{
|
||||
return SkillNode->CurrentState;
|
||||
}
|
||||
|
||||
return ESkillNodeState::Locked;
|
||||
}
|
||||
|
||||
bool USkillTreeComponent::GetSkillNodeData(FName SkillID, FSkillNodeRuntime& OutNodeData) const
|
||||
bool USkillTreeComponent::GetSkillNodeData(FName SkillID,
|
||||
FSkillNodeRuntime& OutNodeData) const
|
||||
{
|
||||
const FSkillNodeRuntime* SkillNode = AllSkills.Find(SkillID);
|
||||
if (SkillNode)
|
||||
@@ -357,9 +373,8 @@ TArray<FSkillNodeRuntime> USkillTreeComponent::GetAllSkillNodes() const
|
||||
{
|
||||
TArray<FSkillNodeRuntime> Result;
|
||||
for (const auto& Pair : AllSkills)
|
||||
{
|
||||
Result.Add(Pair.Value);
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
@@ -369,10 +384,9 @@ float USkillTreeComponent::GetTotalHealthBonus() const
|
||||
for (const FName& SkillID : PurchasedSkills)
|
||||
{
|
||||
if (const FSkillNodeRuntime* SkillNode = AllSkills.Find(SkillID))
|
||||
{
|
||||
Total += SkillNode->NodeData.HealthBonus;
|
||||
}
|
||||
}
|
||||
|
||||
return Total;
|
||||
}
|
||||
|
||||
@@ -382,10 +396,9 @@ float USkillTreeComponent::GetTotalDamageBonus() const
|
||||
for (const FName& SkillID : PurchasedSkills)
|
||||
{
|
||||
if (const FSkillNodeRuntime* SkillNode = AllSkills.Find(SkillID))
|
||||
{
|
||||
Total += SkillNode->NodeData.DamageBonus;
|
||||
}
|
||||
}
|
||||
|
||||
return Total;
|
||||
}
|
||||
|
||||
@@ -395,10 +408,9 @@ float USkillTreeComponent::GetTotalSpeedBonus() const
|
||||
for (const FName& SkillID : PurchasedSkills)
|
||||
{
|
||||
if (const FSkillNodeRuntime* SkillNode = AllSkills.Find(SkillID))
|
||||
{
|
||||
Total += SkillNode->NodeData.SpeedBonus;
|
||||
}
|
||||
}
|
||||
|
||||
return Total;
|
||||
}
|
||||
|
||||
@@ -408,10 +420,9 @@ float USkillTreeComponent::GetTotalHealthBonusPercent() const
|
||||
for (const FName& SkillID : PurchasedSkills)
|
||||
{
|
||||
if (const FSkillNodeRuntime* SkillNode = AllSkills.Find(SkillID))
|
||||
{
|
||||
Total += SkillNode->NodeData.HealthBonusPercent;
|
||||
}
|
||||
}
|
||||
|
||||
return Total;
|
||||
}
|
||||
|
||||
@@ -421,10 +432,9 @@ float USkillTreeComponent::GetTotalDamageBonusPercent() const
|
||||
for (const FName& SkillID : PurchasedSkills)
|
||||
{
|
||||
if (const FSkillNodeRuntime* SkillNode = AllSkills.Find(SkillID))
|
||||
{
|
||||
Total += SkillNode->NodeData.DamageBonusPercent;
|
||||
}
|
||||
}
|
||||
|
||||
return Total;
|
||||
}
|
||||
|
||||
@@ -434,10 +444,9 @@ float USkillTreeComponent::GetTotalSpeedBonusPercent() const
|
||||
for (const FName& SkillID : PurchasedSkills)
|
||||
{
|
||||
if (const FSkillNodeRuntime* SkillNode = AllSkills.Find(SkillID))
|
||||
{
|
||||
Total += SkillNode->NodeData.SpeedBonusPercent;
|
||||
}
|
||||
}
|
||||
|
||||
return Total;
|
||||
}
|
||||
|
||||
@@ -459,10 +468,7 @@ void USkillTreeComponent::ResetAllSkills()
|
||||
|
||||
// Reset all skill states
|
||||
for (auto& Pair : AllSkills)
|
||||
{
|
||||
Pair.Value.CurrentState = ESkillNodeState::Locked;
|
||||
Pair.Value.bIsSelected = false;
|
||||
}
|
||||
|
||||
// Clear selection
|
||||
SelectedSkills.Empty();
|
||||
@@ -484,22 +490,27 @@ void USkillTreeComponent::UpdateSkillStates()
|
||||
{
|
||||
FSkillNodeRuntime& SkillNode = Pair.Value;
|
||||
|
||||
// Skip if already purchased
|
||||
if (SkillNode.CurrentState == ESkillNodeState::Purchased)
|
||||
// Only update Locked and Available states based on prerequisites
|
||||
// Purchased and Selected states should not be changed
|
||||
switch (SkillNode.CurrentState)
|
||||
{
|
||||
case ESkillNodeState::Purchased:
|
||||
case ESkillNodeState::Selected:
|
||||
// Don't change these states
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if prerequisites are met
|
||||
case ESkillNodeState::Locked:
|
||||
case ESkillNodeState::Available:
|
||||
// Update state based on prerequisites
|
||||
if (ArePrerequisitesMet(SkillNode.NodeData))
|
||||
{
|
||||
SkillNode.CurrentState = SkillNode.bIsSelected ?
|
||||
ESkillNodeState::Selected : ESkillNodeState::Available;
|
||||
SkillNode.CurrentState = ESkillNodeState::Available;
|
||||
}
|
||||
else
|
||||
{
|
||||
SkillNode.CurrentState = SkillNode.bIsSelected ?
|
||||
ESkillNodeState::Selected : ESkillNodeState::Locked;
|
||||
SkillNode.CurrentState = ESkillNodeState::Locked;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -516,7 +527,8 @@ void USkillTreeComponent::UpdateSelectionCost()
|
||||
}
|
||||
}
|
||||
|
||||
bool USkillTreeComponent::ArePrerequisitesMet(const FSkillNodeData& SkillData) const
|
||||
bool USkillTreeComponent::ArePrerequisitesMet(
|
||||
const FSkillNodeData& SkillData) const
|
||||
{
|
||||
for (const FName& PrereqID : SkillData.Prerequisites)
|
||||
{
|
||||
@@ -533,8 +545,8 @@ bool USkillTreeComponent::HasChildrenPurchased(FName SkillID) const
|
||||
for (const auto& Pair : AllSkills)
|
||||
{
|
||||
// Pair.Key is the RowName (SkillID)
|
||||
if (Pair.Value.NodeData.Prerequisites.Contains(SkillID) &&
|
||||
IsSkillPurchased(Pair.Key))
|
||||
if (Pair.Value.NodeData.Prerequisites.Contains(SkillID)
|
||||
&& IsSkillPurchased(Pair.Key))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -546,12 +558,14 @@ void USkillTreeComponent::ApplySkillEffects(const FSkillNodeData& SkillData)
|
||||
{
|
||||
// This is where you would apply the actual skill effects to the character
|
||||
// For now, we just log it
|
||||
UE_LOG(LogTemp, Log, TEXT("Applied skill effects for: %s"), *SkillData.DisplayName.ToString());
|
||||
UE_LOG(LogTemp, Log, TEXT("Applied skill effects for: %s"),
|
||||
*SkillData.DisplayName.ToString());
|
||||
}
|
||||
|
||||
void USkillTreeComponent::RemoveSkillEffects(const FSkillNodeData& SkillData)
|
||||
{
|
||||
// This is where you would remove skill effects from the character
|
||||
// For now, we just log it
|
||||
UE_LOG(LogTemp, Log, TEXT("Removed skill effects for: %s"), *SkillData.DisplayName.ToString());
|
||||
UE_LOG(LogTemp, Log, TEXT("Removed skill effects for: %s"),
|
||||
*SkillData.DisplayName.ToString());
|
||||
}
|
||||
@@ -8,19 +8,27 @@
|
||||
UENUM(BlueprintType)
|
||||
enum class ESkillNodeState : uint8
|
||||
{
|
||||
Locked UMETA(DisplayName = "Locked"), // Can't be purchased yet (missing prerequisites)
|
||||
Available UMETA(DisplayName = "Available"), // Can be purchased
|
||||
Selected UMETA(DisplayName = "Selected"), // Currently selected for purchase
|
||||
Purchased UMETA(DisplayName = "Purchased") // Already owned
|
||||
// Can't be purchased yet (missing prerequisites)
|
||||
Locked UMETA(DisplayName = "Locked"),
|
||||
|
||||
// Can be purchased
|
||||
Available UMETA(DisplayName = "Available"),
|
||||
|
||||
// Currently selected for purchase
|
||||
Selected UMETA(DisplayName = "Selected"),
|
||||
|
||||
// Already owned
|
||||
Purchased UMETA(DisplayName = "Purchased")
|
||||
};
|
||||
|
||||
// Struct for individual skill node data
|
||||
// Note: RowName in the DataTable serves as the unique SkillID
|
||||
USTRUCT(BlueprintType)
|
||||
struct FSkillNodeData : public FTableRowBase
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
// RowName will be used as SkillID
|
||||
|
||||
// Display name for UI
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Skill")
|
||||
FText DisplayName;
|
||||
@@ -37,31 +45,27 @@ struct FSkillNodeData : public FTableRowBase
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Skill")
|
||||
int32 Cost;
|
||||
|
||||
// Purchase order priority (lower = buy first, used when confirming multiple skills)
|
||||
// Purchase order priority
|
||||
// (lower = buy first, used when confirming multiple skills)
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Skill")
|
||||
int32 PurchaseOrder;
|
||||
|
||||
// Prerequisites - must have these skills first (RowNames of required skills)
|
||||
// Prerequisites - must have these skills first
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Skill")
|
||||
TArray<FName> Prerequisites;
|
||||
|
||||
// Effects this skill provides (actual stat bonuses)
|
||||
// Effects this skill provides
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Effects")
|
||||
float HealthBonus;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Effects")
|
||||
float DamageBonus;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Effects")
|
||||
float SpeedBonus;
|
||||
|
||||
// Percentage bonuses (multiplicative)
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Effects")
|
||||
float HealthBonusPercent;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Effects")
|
||||
float DamageBonusPercent;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Effects")
|
||||
float SpeedBonusPercent;
|
||||
|
||||
@@ -93,12 +97,5 @@ struct FSkillNodeRuntime
|
||||
UPROPERTY(BlueprintReadOnly, Category = "Skill")
|
||||
ESkillNodeState CurrentState;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = "Skill")
|
||||
bool bIsSelected;
|
||||
|
||||
FSkillNodeRuntime()
|
||||
{
|
||||
CurrentState = ESkillNodeState::Locked;
|
||||
bIsSelected = false;
|
||||
}
|
||||
FSkillNodeRuntime() { CurrentState = ESkillNodeState::Locked; }
|
||||
};
|
||||
Reference in New Issue
Block a user