Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include "CoreMinimal.h"
- #include "Components/ActorComponent.h"
- #include "Engine/DataTable.h"
- #include "AbilityComponent.generated.h"
- class UInputAction;
- class UDecalComponent;
- class USoundWave;
- class UTurnQueue;
- UENUM(BlueprintType)
- enum class EAbilityIndicatorType : uint8 {
- Melee = 0 UMETA(DisplayName = "Melee"),
- Range = 1 UMETA(DisplayName = "Range"),
- // Không biết tên, CC, AOE, Burst?
- };
- UCLASS(Abstract, Blueprintable)
- class UAbilityComponent : public UActorComponent
- {
- GENERATED_BODY()
- public:
- UAbilityComponent();
- UFUNCTION(BlueprintCallable)
- void SetIndicatorDecalComponent(UDecalComponent* NewIndicatorDecalComponent);
- UFUNCTION(BlueprintCallable, Category = "Ability")
- void SetTimerOnDecision();
- // https://forums.unrealengine.com/t/how-to-override-c-function-in-blueprint/327399/4?u=xeryvelgarde
- // Keep this in mind, change them back to virtual functions late
- UFUNCTION(BlueprintCallable, Category = "Ability")
- void OnDecision();
- UFUNCTION(BlueprintCallable)
- void SetAbilityIcon(UTexture2D* NewAbilityIcon);
- UFUNCTION(BlueprintCallable)
- void SetAbilityPhase(EPhase NewAbilityPhase);
- UFUNCTION(BlueprintCallable)
- void SendSignalToTriggerOnPhase();
- UFUNCTION(BlueprintCallable)
- void SetAbilitySoundHovered(USoundWave* NewAbilitySoundHovered);
- UFUNCTION(BlueprintCallable)
- void SetAbilitySoundPressed(USoundWave* NewAbilitySoundPressed);
- UFUNCTION(BlueprintCallable)
- void SetAbilityRange(float NewAbilityRange);
- UFUNCTION(BlueprintCallable)
- void SetSetDestinationInputAction(UInputAction* NewSetDestinationInputAction);
- protected:
- UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Ability Indicator Type")
- TEnumAsByte<EAbilityIndicatorType> AbilityIndicatorType;
- UPROPERTY(BlueprintReadOnly, Category = "Ability")
- UTurnQueue* TurnQueue;
- UFUNCTION(BlueprintCallable)
- void SetTargetPosition(FVector NewTargetPosition);
- // https://forums.unrealengine.com/t/how-to-override-c-function-in-blueprint/327399/4?u=xeryvelgarde
- // Keep this in mind, change them back to virtual functions late
- UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Ability")
- void PreDecision(UDecalComponent* NewIndicatorDecalComponent, const float& MaxIndicatorDistance, UInputAction* NewSetDestinationInputAction);
- virtual void PreDecision_Implementation(UDecalComponent* NewIndicatorDecalComponent, const float& MaxIndicatorDistance, UInputAction* NewSetDestinationInputAction);
- UFUNCTION(BlueprintImplementableEvent, Category = "Ability")
- void Resolution();
- /*
- virtual void Decision();
- virtual void Resolution();
- */
- UFUNCTION(BlueprintCallable, Category = "Ability")
- void SetIndicatorDecalAtLocation();
- private:
- virtual void BeginPlay() override;
- FTimerHandle DecisionTimerHandle;
- FTimerDelegate DecisionTimerDelegate;
- UPROPERTY(BlueprintGetter = GetIndicatorDecalComponent, BlueprintSetter = SetIndicatorDecalComponent)
- UDecalComponent* IndicatorDecalComponent;
- UFUNCTION(BlueprintPure)
- UDecalComponent* GetIndicatorDecalComponent() const;
- void PostDecision();
- UPROPERTY(BlueprintGetter = GetAbilityIcon, BlueprintSetter = SetAbilityIcon)
- UTexture2D* AbilityIcon;
- UFUNCTION(BlueprintPure)
- UTexture2D* GetAbilityIcon() const;
- UPROPERTY(BlueprintGetter = GetAbilityPhase, BlueprintSetter = SetAbilityPhase)
- EPhase AbilityPhase;
- UFUNCTION(BlueprintPure)
- EPhase GetAbilityPhase() const;
- UPROPERTY(BlueprintGetter = GetAbilitySoundHovered, BlueprintSetter = SetAbilitySoundHovered)
- USoundWave* AbilitySoundHovered;
- UFUNCTION(BlueprintPure)
- USoundWave* GetAbilitySoundHovered() const;
- UPROPERTY(BlueprintGetter = GetAbilitySoundPressed, BlueprintSetter = SetAbilitySoundPressed)
- USoundWave* AbilitySoundPressed;
- UFUNCTION(BlueprintPure)
- USoundWave* GetAbilitySoundPressed() const;
- UPROPERTY(BlueprintGetter = GetAbilityRange, BlueprintSetter = SetAbilityRange)
- float AbilityRange;
- UFUNCTION(BlueprintPure)
- float GetAbilityRange() const;
- class UEnhancedInputLocalPlayerSubsystem* EnhancedInputLocalPlayerSubsystem;
- class UEnhancedPlayerInput* EnhancedPlayerInput;
- UPROPERTY(BlueprintGetter = GetSetDestinationInputAction, BlueprintSetter = SetSetDestinationInputAction)
- UInputAction* SetDestinationInputAction;
- UFUNCTION(BlueprintPure)
- UInputAction* GetSetDestinationInputAction() const;
- UPROPERTY(BlueprintGetter = GetTargetPosition, BlueprintSetter = SetTargetPosition)
- FVector TargetPosition;
- UFUNCTION(BlueprintPure)
- FVector GetTargetPosition() const;
- UFUNCTION(BlueprintPure)
- FVector GetPlayerCursorLocation() const;
- };
- #include "Battle/AbilityComponent.h"
- #include "Battle/TurnQueue.h"
- #include "Components/DecalComponent.h"
- #include "EnhancedInputSubsystems.h"
- #include "Kismet/GameplayStatics.h"
- #include "Kismet/KismetMathLibrary.h"
- // Sets default values for this component's properties
- UAbilityComponent::UAbilityComponent()
- {
- // Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features
- // off to improve performance if you don't need them.
- PrimaryComponentTick.bCanEverTick = false;
- // ...
- IndicatorDecalComponent = CreateDefaultSubobject<UDecalComponent>(FName(TEXT("IndicatorDecalComponent")));
- TurnQueue = CreateDefaultSubobject<UTurnQueue>(FName(TEXT("TurnQueue")));
- }
- void UAbilityComponent::BeginPlay()
- {
- Super::BeginPlay();
- }
- UTexture2D* UAbilityComponent::GetAbilityIcon() const
- {
- return AbilityIcon;
- }
- void UAbilityComponent::SetAbilityIcon(UTexture2D* NewAbilityIcon)
- {
- AbilityIcon = NewAbilityIcon;
- }
- EPhase UAbilityComponent::GetAbilityPhase() const
- {
- return AbilityPhase;
- }
- void UAbilityComponent::SetAbilityPhase(EPhase NewAbilityPhase)
- {
- AbilityPhase = NewAbilityPhase;
- }
- USoundWave* UAbilityComponent::GetAbilitySoundHovered() const
- {
- return AbilitySoundHovered;
- }
- void UAbilityComponent::SetAbilitySoundHovered(USoundWave* NewAbilitySoundHovered)
- {
- AbilitySoundHovered = NewAbilitySoundHovered;
- }
- USoundWave* UAbilityComponent::GetAbilitySoundPressed() const
- {
- return AbilitySoundPressed;
- }
- void UAbilityComponent::SetAbilitySoundPressed(USoundWave* NewAbilitySoundPressed)
- {
- AbilitySoundPressed = NewAbilitySoundPressed;
- }
- float UAbilityComponent::GetAbilityRange() const
- {
- return AbilityRange;
- }
- void UAbilityComponent::SetAbilityRange(float NewAbilityRange)
- {
- AbilityRange = NewAbilityRange;
- }
- UInputAction* UAbilityComponent::GetSetDestinationInputAction() const
- {
- return SetDestinationInputAction;
- }
- void UAbilityComponent::SetSetDestinationInputAction(UInputAction* NewSetDestinationInputAction)
- {
- SetDestinationInputAction = NewSetDestinationInputAction;
- }
- UDecalComponent* UAbilityComponent::GetIndicatorDecalComponent() const
- {
- return IndicatorDecalComponent;
- }
- void UAbilityComponent::SetIndicatorDecalComponent(UDecalComponent* NewIndicatorDecalComponent)
- {
- IndicatorDecalComponent = NewIndicatorDecalComponent;
- }
- void UAbilityComponent::PreDecision_Implementation(UDecalComponent* NewIndicatorDecalComponent, const float& MaxIndicatorDistance, UInputAction* NewSetDestinationInputAction)
- {
- SetIndicatorDecalComponent(NewIndicatorDecalComponent);
- SetAbilityRange(MaxIndicatorDistance);
- SetSetDestinationInputAction(NewSetDestinationInputAction);
- if (EnhancedInputLocalPlayerSubsystem == nullptr)
- {
- EnhancedInputLocalPlayerSubsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(GetWorld()->GetFirstPlayerController()->GetLocalPlayer());
- EnhancedPlayerInput = EnhancedInputLocalPlayerSubsystem->GetPlayerInput();
- }
- }
- void UAbilityComponent::SetTimerOnDecision()
- {
- if (GetWorld())
- GetWorld()->GetTimerManager().SetTimer(DecisionTimerHandle, this, &UAbilityComponent::OnDecision, 0.35f, true, 0);
- }
- void UAbilityComponent::OnDecision()
- {
- if (EnhancedPlayerInput == nullptr|| SetDestinationInputAction == nullptr) {
- if (GetWorld())
- GetWorld()->GetTimerManager().ClearTimer(DecisionTimerHandle);
- return;
- }
- if (EnhancedPlayerInput->GetActionValue(SetDestinationInputAction).Get<bool>())
- {
- if (GetWorld())
- GetWorld()->GetTimerManager().ClearTimer(DecisionTimerHandle);
- SetTargetPosition(GetPlayerCursorLocation());
- }
- else
- {
- SetIndicatorDecalAtLocation();
- }
- }
- FVector UAbilityComponent::GetPlayerCursorLocation() const
- {
- FHitResult HitResult;
- GetWorld()->GetFirstPlayerController()->GetHitResultUnderCursor(ECollisionChannel::ECC_Visibility, true, HitResult);
- return HitResult.Location;
- }
- void UAbilityComponent::SetIndicatorDecalAtLocation()
- {
- if (GetOwner() == nullptr || IndicatorDecalComponent == nullptr)
- return;
- FVector PlayerCursorLocation = GetPlayerCursorLocation();
- // Cự ly của indicator nên tương đối, 0 là địa điểm của nhân vật
- FVector PlayerCharacterLocation = GetOwner()->GetActorLocation();
- if (FVector::Dist(PlayerCursorLocation, PlayerCharacterLocation) > GetAbilityRange())
- {
- FHitResult Hit;
- FVector End = PlayerCharacterLocation + UKismetMathLibrary::FindLookAtRotation(PlayerCharacterLocation, PlayerCursorLocation).Vector() * GetAbilityRange();
- const FCollisionQueryParams CollisionQueryParams;
- const FCollisionResponseParams CollisionResponseParams;
- GetWorld()->LineTraceSingleByChannel(Hit, PlayerCharacterLocation, End, ECollisionChannel::ECC_Visibility, CollisionQueryParams, CollisionResponseParams);
- PlayerCursorLocation = Hit.Location;
- }
- GetIndicatorDecalComponent()->SetWorldLocation(PlayerCursorLocation);
- }
- FVector UAbilityComponent::GetTargetPosition() const
- {
- return TargetPosition;
- }
- void UAbilityComponent::SetTargetPosition(FVector NewTargetPosition)
- {
- TargetPosition = NewTargetPosition;
- }
- void UAbilityComponent::PostDecision()
- {
- GetIndicatorDecalComponent()->SetWorldLocation(GetTargetPosition());
- }
- void UAbilityComponent::SendSignalToTriggerOnPhase()
- {
- // .AddDynamic: expression must be an lvalue or function designator
- switch (AbilityPhase)
- {
- /*
- case EPhase::Decision:
- TurnQueue->OnPlayerInputSignature.AddDynamic(this, &UAbilityComponent::OnDecision);
- break;
- */
- case EPhase::Prep:
- TurnQueue->OnPrepSignature.AddDynamic(this, &UAbilityComponent::Resolution);
- break;
- case EPhase::Dash:
- TurnQueue->OnDashSignature.AddDynamic(this, &UAbilityComponent::Resolution);
- break;
- case EPhase::Blast:
- TurnQueue->OnBlastSignature.AddDynamic(this, &UAbilityComponent::Resolution);
- break;
- case EPhase::Move:
- TurnQueue->OnBlastSignature.AddDynamic(this, &UAbilityComponent::Resolution);
- break;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement