void AShooterWeapon::UseAmmo() { if (!HasInfiniteAmmo()) { CurrentAmmoInClip--; } if (!HasInfiniteAmmo() && !HasInfiniteClip()) { CurrentAmmo--; } AShooterAIController* BotAI = MyPawn ? Cast<AShooterAIController>(MyPawn->GetController()) : NULL; AShooterPlayerController* PlayerController = MyPawn ? Cast<AShooterPlayerController>(MyPawn->GetController()) : NULL; if (BotAI) { BotAI->CheckAmmo(this); } else if(PlayerController) { AShooterPlayerState* PlayerState = Cast<AShooterPlayerState>(PlayerController->PlayerState); switch (GetAmmoType()) { case EAmmoType::ERocket: PlayerState->AddRocketsFired(1); break; case EAmmoType::EBullet: default: PlayerState->AddBulletsFired(1); break; } } }
void AWeapon::HandleFiring() { if ((CurrentAmmoInClip > 0 || HasInfiniteClip() || HasInfiniteAmmo()) && CanFire()) { if (GetNetMode() != NM_DedicatedServer) { SimulateWeaponFire(); } if (MyPawn && MyPawn->IsLocallyControlled()) { FireWeapon(); UseAmmo(); // update firing FX on remote clients if function was called on server BurstCounter++; } } else if (CanReload()) { StartReload(); } else if (MyPawn && MyPawn->IsLocallyControlled()) { // stop weapon fire FX, but stay in Firing state if (BurstCounter > 0) { OnBurstFinished(); } } if (MyPawn && MyPawn->IsLocallyControlled()) { // local client will notify server if (Role < ROLE_Authority) { ServerHandleFiring(); } // reload after firing last round if (CurrentAmmoInClip <= 0 && CanReload()) { StartReload(); } // setup refire timer bRefiring = (CurrentState == EWeaponState::Firing && WeaponConfig.TimeBetweenShots > 0.0f); if (bRefiring) { GetWorldTimerManager().SetTimer(TimerHandle_HandleFiring, this, &AWeapon::HandleFiring, WeaponConfig.TimeBetweenShots, false); } } LastFireTime = GetWorld()->GetTimeSeconds(); }
void AShooterWeapon::ReloadWeapon() { int32 ClipDelta = FMath::Min(WeaponConfig.AmmoPerClip - CurrentAmmoInClip, CurrentAmmo - CurrentAmmoInClip); if (HasInfiniteClip()) { ClipDelta = WeaponConfig.AmmoPerClip - CurrentAmmoInClip; } if (ClipDelta > 0) { CurrentAmmoInClip += ClipDelta; } if (HasInfiniteClip()) { CurrentAmmo = FMath::Max(CurrentAmmoInClip, CurrentAmmo); } }
void AWeapon::UseAmmo() { if (!HasInfiniteAmmo()) { CurrentAmmoInClip--; } if (!HasInfiniteAmmo() && !HasInfiniteClip()) { CurrentAmmo--; } }
bool AShooterWeapon::CanReload() const { bool bCanReload = (!MyPawn || MyPawn->CanReload()); bool bGotAmmo = ( CurrentAmmoInClip < WeaponConfig.AmmoPerClip) && (CurrentAmmo - CurrentAmmoInClip > 0 || HasInfiniteClip()); bool bStateOKToReload = ( ( CurrentState == EWeaponState::Idle ) || ( CurrentState == EWeaponState::Firing) ); return ( ( bCanReload == true ) && ( bGotAmmo == true ) && ( bStateOKToReload == true) ); }