void AShooterGameMode::DefaultTimer() { // don't update timers for Play In Editor mode, it's not real match if (GetWorld()->IsPlayInEditor()) { // start match if necessary. if (GetMatchState() == MatchState::WaitingToStart) { StartMatch(); } return; } AShooterGameState* const MyGameState = Cast<AShooterGameState>(GameState); if (MyGameState && MyGameState->RemainingTime > 0 && !MyGameState->bTimerPaused) { MyGameState->RemainingTime--; if (MyGameState->RemainingTime <= 0) { if (GetMatchState() == MatchState::WaitingPostMatch) { RestartGame(); } else if (GetMatchState() == MatchState::InProgress) { FinishMatch(); // Send end round events for (FConstControllerIterator It = GetWorld()->GetControllerIterator(); It; ++It) { AShooterPlayerController* PlayerController = Cast<AShooterPlayerController>(*It); if (PlayerController && MyGameState) { AShooterPlayerState* PlayerState = Cast<AShooterPlayerState>((*It)->PlayerState); const bool bIsWinner = IsWinner(PlayerState); PlayerController->ClientSendRoundEndEvent(bIsWinner, MyGameState->ElapsedTime); } } } else if (GetMatchState() == MatchState::WaitingToStart) { StartMatch(); } } } }
void FShooterOptions::InfiniteAmmoOptionChanged(TSharedPtr<FShooterMenuItem> MenuItem, int32 MultiOptionIndex) { UWorld* const World = PlayerOwner->GetWorld(); if (World) { for (FConstPlayerControllerIterator It = World->GetPlayerControllerIterator(); It; ++It) { AShooterPlayerController* ShooterPC = Cast<AShooterPlayerController>(*It); if (ShooterPC) { ShooterPC->SetInfiniteAmmo(MultiOptionIndex > 0 ? true : false); } } } }
void AShooterGameMode::RestartGame() { // Hide the scoreboard too ! for (FConstControllerIterator It = GetWorld()->GetControllerIterator(); It; ++It) { AShooterPlayerController* PlayerController = Cast<AShooterPlayerController>(*It); if (PlayerController != nullptr) { AShooterHUD* ShooterHUD = Cast<AShooterHUD>(PlayerController->GetHUD()); if (ShooterHUD != nullptr) { // Passing true to bFocus here ensures that focus is returned to the game viewport. ShooterHUD->ShowScoreboard(false, true); } } } Super::RestartGame(); }
void AShooterGameMode::HandleMatchHasStarted() { bNeedsBotCreation = true; Super::HandleMatchHasStarted(); AShooterGameState* const MyGameState = Cast<AShooterGameState>(GameState); MyGameState->RemainingTime = RoundTime; StartBots(); // notify players for (FConstControllerIterator It = GetWorld()->GetControllerIterator(); It; ++It) { AShooterPlayerController* PC = Cast<AShooterPlayerController>(*It); if (PC) { PC->ClientGameStarted(); } } }
void AShooterPlayerController::OnToggleInGameMenu() { // this is not ideal, but necessary to prevent both players from pausing at the same time on the same frame UWorld* GameWorld = GEngine->GameViewport->GetWorld(); for(auto It = GameWorld->GetControllerIterator(); It; ++It) { AShooterPlayerController* Controller = Cast<AShooterPlayerController>(*It); if(Controller && Controller->IsPaused()) { return; } } // if no one's paused, pause if (ShooterIngameMenu.IsValid()) { ShooterIngameMenu->ToggleGameMenu(); } }
FVector AShooterWeapon::GetCameraDamageStartLocation(const FVector& AimDir) const { AShooterPlayerController* PC = MyPawn ? Cast<AShooterPlayerController>(MyPawn->Controller) : NULL; AShooterAIController* AIPC = MyPawn ? Cast<AShooterAIController>(MyPawn->Controller) : NULL; FVector OutStartTrace = FVector::ZeroVector; if (PC) { // use player's camera FRotator UnusedRot; PC->GetPlayerViewPoint(OutStartTrace, UnusedRot); // Adjust trace so there is nothing blocking the ray between the camera and the pawn, and calculate distance from adjusted start OutStartTrace = OutStartTrace + AimDir * ((Instigator->GetActorLocation() - OutStartTrace) | AimDir); } else if (AIPC) { OutStartTrace = GetMuzzleLocation(); } return OutStartTrace; }
void AShooterGameMode::RequestFinishAndExitToMainMenu() { FinishMatch(); UShooterGameInstance* const GameInstance = Cast<UShooterGameInstance>(GetGameInstance()); if (GameInstance) { GameInstance->RemoveSplitScreenPlayers(); } AShooterPlayerController* LocalPrimaryController = nullptr; for (FConstPlayerControllerIterator Iterator = GetWorld()->GetPlayerControllerIterator(); Iterator; ++Iterator) { AShooterPlayerController* Controller = Cast<AShooterPlayerController>(*Iterator); if (Controller == NULL) { continue; } if (!Controller->IsLocalController()) { const FString RemoteReturnReason = NSLOCTEXT("NetworkErrors", "HostHasLeft", "Host has left the game.").ToString(); Controller->ClientReturnToMainMenu(RemoteReturnReason); } else { LocalPrimaryController = Controller; } } // GameInstance should be calling this from an EndState. So call the PC function that performs cleanup, not the one that sets GI state. if (LocalPrimaryController != NULL) { LocalPrimaryController->HandleReturnToMainMenu(); } }
void AShooterGameMode::PostLogin(APlayerController* NewPlayer) { Super::PostLogin(NewPlayer); // update spectator location for client AShooterPlayerController* NewPC = Cast<AShooterPlayerController>(NewPlayer); if (NewPC && NewPC->GetPawn() == NULL) { NewPC->ClientSetSpectatorCamera(NewPC->GetSpawnLocation(), NewPC->GetControlRotation()); } // notify new player if match is already in progress if (NewPC && IsMatchInProgress()) { NewPC->ClientGameStarted(); NewPC->ClientStartOnlineGame(); } }
void AShooterWeapon::SimulateWeaponFire() { if (Role == ROLE_Authority && CurrentState != EWeaponState::Firing) { return; } if (MuzzleFX) { USkeletalMeshComponent* UseWeaponMesh = GetWeaponMesh(); if (!bLoopedMuzzleFX || MuzzlePSC == NULL) { // Split screen requires we create 2 effects. One that we see and one that the other player sees. if( (MyPawn != NULL ) && ( MyPawn->IsLocallyControlled() == true ) ) { AController* PlayerCon = MyPawn->GetController(); if( PlayerCon != NULL ) { Mesh1P->GetSocketLocation(MuzzleAttachPoint); MuzzlePSC = UGameplayStatics::SpawnEmitterAttached(MuzzleFX, Mesh1P, MuzzleAttachPoint); MuzzlePSC->bOwnerNoSee = false; MuzzlePSC->bOnlyOwnerSee = true; Mesh3P->GetSocketLocation(MuzzleAttachPoint); MuzzlePSCSecondary = UGameplayStatics::SpawnEmitterAttached(MuzzleFX, Mesh3P, MuzzleAttachPoint); MuzzlePSCSecondary->bOwnerNoSee = true; MuzzlePSCSecondary->bOnlyOwnerSee = false; } } else { MuzzlePSC = UGameplayStatics::SpawnEmitterAttached(MuzzleFX, UseWeaponMesh, MuzzleAttachPoint); } } } if (!bLoopedFireAnim || !bPlayingFireAnim) { PlayWeaponAnimation(FireAnim); bPlayingFireAnim = true; } if (bLoopedFireSound) { if (FireAC == NULL) { FireAC = PlayWeaponSound(FireLoopSound); } } else { PlayWeaponSound(FireSound); } AShooterPlayerController* PC = (MyPawn != NULL) ? Cast<AShooterPlayerController>(MyPawn->Controller) : NULL; if (PC != NULL && PC->IsLocalController()) { if (FireCameraShake != NULL) { PC->ClientPlayCameraShake(FireCameraShake, 1); } if (FireForceFeedback != NULL) { PC->ClientPlayForceFeedback(FireForceFeedback, false, "Weapon"); } } }
void AShooterWeapon::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()) { if (GetCurrentAmmo() == 0 && !bRefiring) { PlayWeaponSound(OutOfAmmoSound); AShooterPlayerController* MyPC = Cast<AShooterPlayerController>(MyPawn->Controller); AShooterHUD* MyHUD = MyPC ? Cast<AShooterHUD>(MyPC->GetHUD()) : NULL; if (MyHUD) { MyHUD->NotifyOutOfAmmo(); } } // 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, &AShooterWeapon::HandleFiring, WeaponConfig.TimeBetweenShots, false); } } LastFireTime = GetWorld()->GetTimeSeconds(); }