#include "SkillTreeBlueprintLibrary.h" #include "SkillTreeComponent.h" FLinearColor USkillTreeBlueprintLibrary::GetSkillStateColor(ESkillNodeState State) { switch (State) { case ESkillNodeState::Locked: return FLinearColor(0.3f, 0.3f, 0.3f, 1.0f); // Gray case ESkillNodeState::Available: return FLinearColor(1.0f, 1.0f, 1.0f, 1.0f); // White case ESkillNodeState::Selected: return FLinearColor(1.0f, 0.8f, 0.0f, 1.0f); // Gold case ESkillNodeState::Purchased: return FLinearColor(0.0f, 1.0f, 0.0f, 1.0f); // Green default: return FLinearColor::White; } } FText USkillTreeBlueprintLibrary::GetSkillStateText(ESkillNodeState State) { switch (State) { case ESkillNodeState::Locked: return FText::FromString(TEXT("Locked")); case ESkillNodeState::Available: return FText::FromString(TEXT("Available")); case ESkillNodeState::Selected: return FText::FromString(TEXT("Selected")); case ESkillNodeState::Purchased: return FText::FromString(TEXT("Purchased")); default: return FText::FromString(TEXT("Unknown")); } } FText USkillTreeBlueprintLibrary::GetSkillAvailabilityText(USkillTreeComponent* SkillTreeComponent, FName SkillID) { if (!SkillTreeComponent) { return FText::FromString(TEXT("No Skill Tree Component")); } FSkillNodeRuntime NodeData; if (!SkillTreeComponent->GetSkillNodeData(SkillID, NodeData)) { return FText::FromString(TEXT("Invalid Skill")); } ESkillNodeState State = SkillTreeComponent->GetSkillState(SkillID); switch (State) { case ESkillNodeState::Purchased: return FText::FromString(TEXT("Already Purchased")); case ESkillNodeState::Selected: return FText::FromString(TEXT("Selected for Purchase")); case ESkillNodeState::Available: return FText::Format(FText::FromString(TEXT("Available - Cost: {0} Points")), NodeData.NodeData.Cost); case ESkillNodeState::Locked: { // Check why it's locked if (NodeData.NodeData.Prerequisites.Num() > 0) { FString MissingPrereqs; for (const FName& PrereqID : NodeData.NodeData.Prerequisites) { if (!SkillTreeComponent->IsSkillPurchased(PrereqID)) { FSkillNodeRuntime PrereqData; if (SkillTreeComponent->GetSkillNodeData(PrereqID, PrereqData)) { if (!MissingPrereqs.IsEmpty()) { MissingPrereqs += TEXT(", "); } MissingPrereqs += PrereqData.NodeData.DisplayName.ToString(); } } } return FText::Format(FText::FromString(TEXT("Requires: {0}")), FText::FromString(MissingPrereqs)); } return FText::FromString(TEXT("Locked")); } default: return FText::FromString(TEXT("Unknown State")); } } FText USkillTreeBlueprintLibrary::FormatSkillDescription(const FSkillNodeData& NodeData) { FString Description = NodeData.Description.ToString(); // Add effect descriptions FString Effects; if (NodeData.HealthBonus > 0) { Effects += FString::Printf(TEXT("\n+%.0f Health"), NodeData.HealthBonus); } if (NodeData.HealthBonusPercent > 0) { Effects += FString::Printf(TEXT("\n+%.0f%% Health"), NodeData.HealthBonusPercent); } if (NodeData.DamageBonus > 0) { Effects += FString::Printf(TEXT("\n+%.0f Damage"), NodeData.DamageBonus); } if (NodeData.DamageBonusPercent > 0) { Effects += FString::Printf(TEXT("\n+%.0f%% Damage"), NodeData.DamageBonusPercent); } if (NodeData.SpeedBonus > 0) { Effects += FString::Printf(TEXT("\n+%.0f Speed"), NodeData.SpeedBonus); } if (NodeData.SpeedBonusPercent > 0) { Effects += FString::Printf(TEXT("\n+%.0f%% Speed"), NodeData.SpeedBonusPercent); } if (!Effects.IsEmpty()) { Description += TEXT("\n\nEffects:") + Effects; } return FText::FromString(Description); } float USkillTreeBlueprintLibrary::GetPreviewTotalDamageBonus(USkillTreeComponent* SkillTreeComponent) { if (!SkillTreeComponent) { return 0.0f; } float Total = SkillTreeComponent->GetTotalDamageBonus(); // Add selected (but not purchased) skills TArray SelectedSkills = SkillTreeComponent->GetSelectedSkills(); for (const FName& SkillID : SelectedSkills) { FSkillNodeRuntime NodeData; if (SkillTreeComponent->GetSkillNodeData(SkillID, NodeData)) { Total += NodeData.NodeData.DamageBonus; } } return Total; } float USkillTreeBlueprintLibrary::GetPreviewTotalSpeedBonus(USkillTreeComponent* SkillTreeComponent) { if (!SkillTreeComponent) { return 0.0f; } float Total = SkillTreeComponent->GetTotalSpeedBonus(); // Add selected (but not purchased) skills TArray SelectedSkills = SkillTreeComponent->GetSelectedSkills(); for (const FName& SkillID : SelectedSkills) { FSkillNodeRuntime NodeData; if (SkillTreeComponent->GetSkillNodeData(SkillID, NodeData)) { Total += NodeData.NodeData.SpeedBonus; } } return Total; } float USkillTreeBlueprintLibrary::GetPreviewTotalHealthBonus(USkillTreeComponent* SkillTreeComponent) { if (!SkillTreeComponent) { return 0.0f; } float Total = SkillTreeComponent->GetTotalHealthBonus(); // Add selected (but not purchased) skills TArray SelectedSkills = SkillTreeComponent->GetSelectedSkills(); for (const FName& SkillID : SelectedSkills) { FSkillNodeRuntime NodeData; if (SkillTreeComponent->GetSkillNodeData(SkillID, NodeData)) { Total += NodeData.NodeData.HealthBonus; } } return Total; } bool USkillTreeBlueprintLibrary::HasSelectedSkills(USkillTreeComponent* SkillTreeComponent) { if (!SkillTreeComponent) { return false; } return SkillTreeComponent->GetSelectedSkills().Num() > 0; } bool USkillTreeBlueprintLibrary::CanPlayerRespec(USkillTreeComponent* SkillTreeComponent) { if (!SkillTreeComponent) { return false; } // Check if player has any purchased skills to reset TArray AllNodes = SkillTreeComponent->GetAllSkillNodes(); for (const FSkillNodeRuntime& Node : AllNodes) { if (Node.CurrentState == ESkillNodeState::Purchased) { return true; } } return false; } TArray USkillTreeBlueprintLibrary::GetSkillConnections(USkillTreeComponent* SkillTreeComponent, FName SkillID) { TArray Connections; if (!SkillTreeComponent) { return Connections; } FSkillNodeRuntime NodeData; if (SkillTreeComponent->GetSkillNodeData(SkillID, NodeData)) { // Return the prerequisites as connections Connections = NodeData.NodeData.Prerequisites; } return Connections; }