mirror of
https://github.com/ApfelTeeSaft/OT6-Reconstruction.git
synced 2026-08-27 19:20:41 +00:00
188 lines
5.2 KiB
C++
188 lines
5.2 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
// FortGameplayAbility_Reload Implementation
|
|
|
|
#include "FortGameplayAbility_Reload.h"
|
|
#include "FortWeapon.h"
|
|
#include "FortPawn.h"
|
|
#include "Animation/AnimInstance.h"
|
|
#include "Animation/AnimMontage.h"
|
|
#include "TimerManager.h"
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// UFortGameplayAbility_Reload
|
|
|
|
UFortGameplayAbility_Reload::UFortGameplayAbility_Reload()
|
|
: ReloadMontage(nullptr)
|
|
, ReloadTime(2.0f)
|
|
, WeaponToReload(nullptr)
|
|
{
|
|
|
|
InstancingPolicy = EFortAbilityInstancingPolicy::InstancedPerActor;
|
|
}
|
|
|
|
bool UFortGameplayAbility_Reload::CanActivateAbility_Implementation(UFortAbilitySystemComponent* AbilitySystemComponent) const
|
|
{
|
|
if (!Super::CanActivateAbility_Implementation(AbilitySystemComponent))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// Check if pawn has a weapon
|
|
AFortPawn* FortPawn = Cast<AFortPawn>(GetAvatarActor());
|
|
if (!FortPawn)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// would check if currently equipped weapon needs reload
|
|
// For now, allow activation
|
|
return true;
|
|
}
|
|
|
|
void UFortGameplayAbility_Reload::ActivateAbility_Implementation(UFortAbilitySystemComponent* AbilitySystemComponent, const FFortAbilityActivationInfo& ActivationInfo)
|
|
{
|
|
Super::ActivateAbility_Implementation(AbilitySystemComponent, ActivationInfo);
|
|
|
|
AFortPawn* FortPawn = Cast<AFortPawn>(GetAvatarActor());
|
|
if (!FortPawn)
|
|
{
|
|
UE_LOG(LogTemp, Warning, TEXT("UFortGameplayAbility_Reload: Cannot activate - no pawn"));
|
|
EndAbility(AbilitySystemComponent, true);
|
|
return;
|
|
}
|
|
|
|
// would get currently equipped weapon
|
|
// For now, find first weapon actor owned by pawn
|
|
TArray<AActor*> AttachedActors;
|
|
FortPawn->GetAttachedActors(AttachedActors);
|
|
|
|
for (AActor* Actor : AttachedActors)
|
|
{
|
|
AFortWeapon* Weapon = Cast<AFortWeapon>(Actor);
|
|
if (Weapon)
|
|
{
|
|
WeaponToReload = Weapon;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!WeaponToReload)
|
|
{
|
|
UE_LOG(LogTemp, Warning, TEXT("UFortGameplayAbility_Reload: Cannot activate - no weapon found"));
|
|
EndAbility(AbilitySystemComponent, true);
|
|
return;
|
|
}
|
|
|
|
// Check if weapon needs reloading
|
|
if (WeaponToReload->MagazineAmmoCount >= WeaponToReload->WeaponStats.ClipSize)
|
|
{
|
|
UE_LOG(LogTemp, Verbose, TEXT("UFortGameplayAbility_Reload: Weapon already fully loaded"));
|
|
EndAbility(AbilitySystemComponent, true);
|
|
return;
|
|
}
|
|
|
|
// Check if we have reserve ammo
|
|
if (WeaponToReload->AmmoCount <= 0)
|
|
{
|
|
UE_LOG(LogTemp, Verbose, TEXT("UFortGameplayAbility_Reload: No reserve ammo available"));
|
|
EndAbility(AbilitySystemComponent, true);
|
|
return;
|
|
}
|
|
|
|
UE_LOG(LogTemp, Log, TEXT("UFortGameplayAbility_Reload: Starting reload - Current: %d/%d, Reserve: %d"),
|
|
WeaponToReload->MagazineAmmoCount,
|
|
WeaponToReload->WeaponStats.ClipSize,
|
|
WeaponToReload->AmmoCount);
|
|
|
|
// Play reload montage if available
|
|
if (ReloadMontage && FortPawn->GetMesh())
|
|
{
|
|
UAnimInstance* AnimInstance = FortPawn->GetMesh()->GetAnimInstance();
|
|
if (AnimInstance)
|
|
{
|
|
float MontageLength = AnimInstance->Montage_Play(ReloadMontage);
|
|
if (MontageLength > 0.0f)
|
|
{
|
|
// Use montage duration as reload time
|
|
ReloadTime = MontageLength;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Set timer for reload completion
|
|
UWorld* World = GetWorld();
|
|
if (World)
|
|
{
|
|
float ActualReloadTime = WeaponToReload->WeaponStats.ReloadSeconds > 0.0f ?
|
|
WeaponToReload->WeaponStats.ReloadSeconds : ReloadTime;
|
|
|
|
World->GetTimerManager().SetTimer(
|
|
ReloadTimerHandle,
|
|
this,
|
|
&UFortGameplayAbility_Reload::CompleteReload,
|
|
ActualReloadTime,
|
|
false
|
|
);
|
|
|
|
UE_LOG(LogTemp, Verbose, TEXT("UFortGameplayAbility_Reload: Reload will complete in %.2f seconds"), ActualReloadTime);
|
|
}
|
|
}
|
|
|
|
void UFortGameplayAbility_Reload::EndAbility_Implementation(UFortAbilitySystemComponent* AbilitySystemComponent, bool bWasCancelled)
|
|
{
|
|
// Clear timer if ability is ended early
|
|
UWorld* World = GetWorld();
|
|
if (World)
|
|
{
|
|
World->GetTimerManager().ClearTimer(ReloadTimerHandle);
|
|
}
|
|
|
|
if (bWasCancelled)
|
|
{
|
|
UE_LOG(LogTemp, Verbose, TEXT("UFortGameplayAbility_Reload: Reload cancelled"));
|
|
}
|
|
|
|
Super::EndAbility_Implementation(AbilitySystemComponent, bWasCancelled);
|
|
}
|
|
|
|
void UFortGameplayAbility_Reload::CompleteReload()
|
|
{
|
|
if (!WeaponToReload)
|
|
{
|
|
UE_LOG(LogTemp, Warning, TEXT("UFortGameplayAbility_Reload: CompleteReload called but weapon is null"));
|
|
EndAbility(OwningAbilitySystemComponent, true);
|
|
return;
|
|
}
|
|
|
|
// Calculate ammo to reload
|
|
int32 AmmoNeeded = WeaponToReload->WeaponStats.ClipSize - WeaponToReload->MagazineAmmoCount;
|
|
int32 AmmoToLoad = FMath::Min(AmmoNeeded, WeaponToReload->AmmoCount);
|
|
|
|
if (AmmoToLoad > 0)
|
|
{
|
|
// Transfer ammo from reserve to magazine
|
|
WeaponToReload->MagazineAmmoCount += AmmoToLoad;
|
|
WeaponToReload->AmmoCount -= AmmoToLoad;
|
|
|
|
// Update replicated weapon data
|
|
WeaponToReload->ReplicatedWeaponData.AmmoInClip = WeaponToReload->MagazineAmmoCount;
|
|
|
|
UE_LOG(LogTemp, Log, TEXT("UFortGameplayAbility_Reload: Reload complete - Loaded %d rounds, Magazine: %d/%d, Reserve: %d"),
|
|
AmmoToLoad,
|
|
WeaponToReload->MagazineAmmoCount,
|
|
WeaponToReload->WeaponStats.ClipSize,
|
|
WeaponToReload->AmmoCount);
|
|
}
|
|
|
|
// End the ability
|
|
EndAbility(OwningAbilitySystemComponent, false);
|
|
}
|
|
|
|
void UFortGameplayAbility_Reload::CancelReload()
|
|
{
|
|
UE_LOG(LogTemp, Verbose, TEXT("UFortGameplayAbility_Reload: CancelReload called"));
|
|
|
|
// Cancel the ability
|
|
EndAbility(OwningAbilitySystemComponent, true);
|
|
}
|