diff --git a/Source/Nakatomi/PlayerCharacter.cpp b/Source/Nakatomi/PlayerCharacter.cpp index eb8b9e9..fa7c5a5 100644 --- a/Source/Nakatomi/PlayerCharacter.cpp +++ b/Source/Nakatomi/PlayerCharacter.cpp @@ -95,7 +95,8 @@ void APlayerCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputCom if (FireAction) { - Input->BindAction(FireAction, ETriggerEvent::Started, this, &APlayerCharacter::FireCallback); + Input->BindAction(FireAction, ETriggerEvent::Started, this, &APlayerCharacter::BeginFireCallback); + Input->BindAction(FireAction, ETriggerEvent::Completed, this, &APlayerCharacter::EndFireCallback); } if (QuitAction) @@ -143,13 +144,32 @@ void APlayerCharacter::JumpCallback(const FInputActionInstance& Instance) Jump(); } -void APlayerCharacter::FireCallback(const FInputActionInstance& Instance) +void APlayerCharacter::BeginFireCallback(const FInputActionInstance& Instance) { - // TODO: Add extra gun fire logic + if (CurrentWeapon == nullptr || CurrentWeapon->GetCurrentWeaponStatus()->GetValue() != WeaponState::Idle) + { + return; + } - // Calculate hits from hitscan - TArray Hits = TArray(); - CalculateHits(&Hits); + IsFiring = true; + + OnFire(); + + + if (CurrentWeapon->GetWeaponProperties()->IsAutomatic) + { + GetWorldTimerManager().SetTimer(CooldownTimerHandle, this, &APlayerCharacter::WeaponCooldownHandler, CurrentWeapon->GetWeaponProperties()->WeaponCooldown, true); + GetWorldTimerManager().SetTimer(FireTimerHandle, this, &APlayerCharacter::OnFire, CurrentWeapon->GetWeaponProperties()->WeaponCooldown, true); + } + else + { + GetWorldTimerManager().SetTimer(CooldownTimerHandle, this, &APlayerCharacter::WeaponCooldownHandler, CurrentWeapon->GetWeaponProperties()->WeaponCooldown, true); + } +} + +void APlayerCharacter::EndFireCallback(const FInputActionInstance& Instance) +{ + IsFiring = false; } void APlayerCharacter::QuitCallback(const FInputActionInstance& Instance) @@ -342,3 +362,42 @@ void APlayerCharacter::RemoveCurrentWeaponFromInventory() // TODO: Add more checking here } + +void APlayerCharacter::OnFire() +{ + if (!IsFiring) + { + return; + } + + CurrentWeapon->SetCurrentWeaponStatus(WeaponState::Firing); + + TArray Hits = TArray(); + CalculateHits(&Hits); + + // TODO: Decrement ammo count + + // TODO: Play sound effect + + CurrentWeapon->SetCurrentWeaponStatus(WeaponState::Cooldown); +} + +void APlayerCharacter::WeaponCooldownHandler() +{ + if (CurrentWeapon->GetCurrentWeaponStatus()->GetValue() != WeaponState::Idle) + { + CurrentWeapon->SetCurrentWeaponStatus(WeaponState::Idle); + } + + if (!IsFiring) + { + GetWorldTimerManager().ClearTimer(FireTimerHandle); + GetWorldTimerManager().ClearTimer(CooldownTimerHandle); + } +} + +void APlayerCharacter::ClearAllTimers() +{ + GetWorldTimerManager().ClearTimer(FireTimerHandle); + GetWorldTimerManager().ClearTimer(CooldownTimerHandle); +} diff --git a/Source/Nakatomi/PlayerCharacter.h b/Source/Nakatomi/PlayerCharacter.h index ebcaf8a..1ccd018 100644 --- a/Source/Nakatomi/PlayerCharacter.h +++ b/Source/Nakatomi/PlayerCharacter.h @@ -78,6 +78,12 @@ private: UPROPERTY() AWeapon* CurrentWeapon = nullptr; + FTimerHandle FireTimerHandle; + + FTimerHandle CooldownTimerHandle; + + bool IsFiring = false; + public: // Sets default values for this character's properties APlayerCharacter(); @@ -99,7 +105,9 @@ public: void JumpCallback(const FInputActionInstance& Instance); - void FireCallback(const FInputActionInstance& Instance); + void BeginFireCallback(const FInputActionInstance& Instance); + + void EndFireCallback(const FInputActionInstance& Instance); void QuitCallback(const FInputActionInstance& Instance); @@ -130,4 +138,10 @@ public: void RemoveWeaponFromInventory(int i); void RemoveCurrentWeaponFromInventory(); + + void OnFire(); + + void WeaponCooldownHandler(); + + void ClearAllTimers(); };