void ASWeaponPickup::OnUsed(APawn* InstigatorPawn) { ASCharacter* MyPawn = Cast<ASCharacter>(InstigatorPawn); if (MyPawn) { /* Fetch the default variables of the class we are about to pick up and check if the storage slot is available on the pawn. */ if (MyPawn->WeaponSlotAvailable(WeaponClass->GetDefaultObject<ASWeapon>()->GetStorageSlot())) { FActorSpawnParameters SpawnInfo; SpawnInfo.bNoCollisionFail = true; ASWeapon* NewWeapon = GetWorld()->SpawnActor<ASWeapon>(WeaponClass, SpawnInfo); MyPawn->AddWeapon(NewWeapon); Super::OnUsed(InstigatorPawn); } else { ASPlayerController* PC = Cast<ASPlayerController>(MyPawn->GetController()); if (PC) { PC->ClientMessageReceived("Weapon slot already taken."); } } } }
void ASHUD::DrawCenterDot() { float CenterX = Canvas->ClipX / 2; float CenterY = Canvas->ClipY / 2; float CenterDotScale = 0.07f; ASPlayerController* PCOwner = Cast<ASPlayerController>(PlayerOwner); if (PCOwner) { ASCharacter* Pawn = Cast<ASCharacter>(PCOwner->GetPawn()); if (Pawn && Pawn->IsAlive()) { // Boost size when hovering over a switchable object. ASUsableActor* usable = Pawn->GetUsableInView(); if (usable) CenterDotScale *= 1.5f; Canvas->SetDrawColor(255, 255, 255, 255); Canvas->DrawIcon(CenterDotIcon, CenterX - CenterDotIcon.UL*CenterDotScale / 2.0f, CenterY - CenterDotIcon.VL*CenterDotScale / 2.0f, CenterDotScale); } } }
void ASPlayerCameraManager::UpdateCamera(float DeltaTime) { ASCharacter* MyPawn = PCOwner ? Cast<ASCharacter>(PCOwner->GetPawn()) : nullptr; if (MyPawn) { const float TargetFOV = MyPawn->IsTargeting() ? TargetingFOV : NormalFOV; DefaultFOV = FMath::FInterpTo(DefaultFOV, TargetFOV, DeltaTime, 20.0f); SetFOV(DefaultFOV); } /* Apply smooth camera lerp between crouch toggling */ if (MyPawn) { if (MyPawn->bIsCrouched && !bWasCrouched) { CurrentCrouchOffset = MaxCrouchOffsetZ; } else if (!MyPawn->bIsCrouched && bWasCrouched) { CurrentCrouchOffset = -MaxCrouchOffsetZ; } bWasCrouched = MyPawn->bIsCrouched; CurrentCrouchOffset = FMath::Lerp(CurrentCrouchOffset, 0.0f, CrouchLerpVelocity * DeltaTime); FVector CurrentCameraOffset = MyPawn->GetCameraComponent()->GetRelativeTransform().GetLocation(); FVector NewCameraOffset = FVector(CurrentCameraOffset.X, CurrentCameraOffset.Y, DefaultCameraOffsetZ + CurrentCrouchOffset); MyPawn->GetCameraComponent()->SetRelativeLocation(NewCameraOffset); } Super::UpdateCamera(DeltaTime); }
void ASGameMode::CheckMatchEnd() { bool bHasAlivePlayer = false; for (FConstPawnIterator It = GetWorld()->GetPawnIterator(); It; It++) { ASCharacter* MyPawn = Cast<ASCharacter>(*It); if (MyPawn && MyPawn->IsAlive()) { ASPlayerState* PS = Cast<ASPlayerState>(MyPawn->PlayerState); if (PS) { if (!PS->bIsABot) { /* Found one player that is still alive, game will continue */ bHasAlivePlayer = true; break; } } } } /* End game is all players died */ if (!bHasAlivePlayer) { FinishMatch(); } }
void ASPlayerController::ServerSuicide_Implementation() { ASCharacter* MyPawn = Cast<ASCharacter>(GetPawn()); if (MyPawn && ((GetWorld()->TimeSeconds - MyPawn->CreationTime > 1) || (GetNetMode() == NM_Standalone))) { MyPawn->Suicide(); } }
void ASConsumableActor::OnUsed(APawn* InstigatorPawn) { ASCharacter* Pawn = Cast<ASCharacter>(InstigatorPawn); if (Pawn) { Pawn->ConsumeFood(Nutrition); } Super::OnUsed(InstigatorPawn); }
void ASWeaponInstant::SimulateInstantHit(const FVector& Origin) { const FVector StartTrace = Origin; const FVector AimDir = GetAdjustedAim(); const FVector EndTrace = StartTrace + (AimDir * WeaponRange); const FHitResult Impact = WeaponTrace(StartTrace, EndTrace); if (Impact.bBlockingHit) { SpawnImpactEffects(Impact); SpawnTrailEffects(Impact.ImpactPoint); } else { SpawnTrailEffects(EndTrace); } // Do not spawn near-hit if we actually hit a pawn if (Impact.GetActor() && Impact.GetActor()->IsA(ASCharacter::StaticClass())) { return; } for (FConstPawnIterator It = GetWorld()->GetPawnIterator(); It; It++) { // Find a locally controlled pawn that is not the instigator of the hit. ASCharacter* OtherPawn = Cast<ASCharacter>(*It); if (OtherPawn && OtherPawn != GetPawnOwner() && OtherPawn->IsLocallyControlled()) { // Calculate shortest distance to point. (using the estimated eye height) const float DistanceToPawn = FVector::CrossProduct(AimDir, OtherPawn->GetActorLocation() - Origin).Size(); /* Owner can be lost before client gets to simulate the hit. */ ASCharacter* P = GetPawnOwner(); if (P) { FVector LookAt = (OtherPawn->GetActorLocation() - GetPawnOwner()->GetActorLocation()); LookAt.Normalize(); float LookDot = FVector::DotProduct(AimDir, LookAt); if (DistanceToPawn < NearHitMaxDistance && LookDot > 0) { // TODO: Play at nearest "almost" hit location. const FVector SoundLocation = Origin + (AimDir * DistanceToPawn); // Volume is based on distance to missed shot float Volume = FMath::Clamp(1 - (DistanceToPawn / NearHitMaxDistance), 0.1f, 1.0f); UGameplayStatics::PlaySoundAtLocation(this, NearHitSound, /*SoundLocation*/ OtherPawn->GetActorLocation(), Volume); } } } } }
void ASConsumableActor::OnUsed(APawn* inInstigatorPawn) { Super::OnUsed(inInstigatorPawn); ASCharacter* lPawn = Cast<ASCharacter>(inInstigatorPawn); if (lPawn) { lPawn->ConsumeFood(Nutrition); } Destroy(); }
void ASGameMode::SpawnDefaultInventory(APawn* PlayerPawn) { ASCharacter* MyPawn = Cast<ASCharacter>(PlayerPawn); if (MyPawn) { for (int32 i = 0; i < DefaultInventoryClasses.Num(); i++) { if (DefaultInventoryClasses[i]) { FActorSpawnParameters SpawnInfo; SpawnInfo.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn; ASWeapon* NewWeapon = GetWorld()->SpawnActor<ASWeapon>(DefaultInventoryClasses[i], SpawnInfo); MyPawn->AddWeapon(NewWeapon); } } } }
void ASWeaponInstant::SpawnTrailEffects(const FVector& EndPoint) { // Keep local count for effects BulletsShotCount++; const FVector Origin = GetMuzzleLocation(); FVector ShootDir = EndPoint - Origin; // Only spawn if a minimum distance is satisfied. if (ShootDir.Size() < MinimumProjectileSpawnDistance) { return; } if (BulletsShotCount % TracerRoundInterval == 0) { if (TracerFX) { ShootDir.Normalize(); UGameplayStatics::SpawnEmitterAtLocation(this, TracerFX, Origin, ShootDir.Rotation()); } } else { // Only create trails FX by other players. ASCharacter* OwningPawn = GetPawnOwner(); if (OwningPawn && OwningPawn->IsLocallyControlled()) { return; } if (TrailFX) { UParticleSystemComponent* TrailPSC = UGameplayStatics::SpawnEmitterAtLocation(this, TrailFX, Origin); if (TrailPSC) { TrailPSC->SetVectorParameter(TrailTargetParam, EndPoint); } } } }
void ASHUD::DrawCenterDot() { float lCenterX = Canvas->ClipX * 0.5f; float lCenterY = Canvas->ClipY * 0.5f; float lCenterDotScale = 0.07f; ASPlayerController* lOwner = Cast<ASPlayerController>(PlayerOwner); if (lOwner) { ASCharacter* lPawn = Cast<ASCharacter>(lOwner->GetPawn()); if (lPawn && lPawn->IsAlive()) { ASUsableActor* lUsable = lPawn->GetUsableInView(); if (lUsable) lCenterDotScale *= 1.5f; Canvas->SetDrawColor(255, 255, 255, 255); Canvas->DrawIcon(CenterDotIcon, lCenterX - CenterDotIcon.UL * lCenterDotScale * 0.5f, lCenterY - CenterDotIcon.VL * lCenterDotScale * 0.5f, lCenterDotScale); } } }
void ASGameMode::DefaultTimer() { /* This function is called every 1 second. */ Super::DefaultTimer(); /* Immediately start the match while playing in editor */ //if (GetWorld()->IsPlayInEditor()) { if (GetMatchState() == MatchState::WaitingToStart) { StartMatch(); } } /* Only increment time of day while game is active */ if (IsMatchInProgress()) { ASGameState* MyGameState = Cast<ASGameState>(GameState); if (MyGameState) { /* Increment our time of day */ MyGameState->ElapsedGameMinutes += MyGameState->GetTimeOfDayIncrement(); /* Determine our state */ MyGameState->GetAndUpdateIsNight(); /* Trigger events when night starts or ends */ bool CurrentIsNight = MyGameState->GetIsNight(); if (CurrentIsNight != LastIsNight) { FString MessageText = CurrentIsNight ? "SURVIVE!" : "You Survived! Now prepare for the coming night!"; ASGameState* MyGameState = Cast<ASGameState>(GameState); if (MyGameState) { MyGameState->BroadcastGameMessage(MessageText); } /* The night just ended, respawn all dead players */ if (!CurrentIsNight) { /* Respawn spectating players that died during the night */ for (FConstPlayerControllerIterator It = GetWorld()->GetPlayerControllerIterator(); It; It++) { /* Look for all players that are spectating */ ASPlayerController* MyController = Cast<ASPlayerController>(*It); if (MyController) { if (MyController->PlayerState->bIsSpectator) { RestartPlayer(MyController); MyController->ClientHUDStateChanged(EHUDState::Playing); } else { /* Player still alive, award him some points */ ASCharacter* MyPawn = Cast<ASCharacter>(MyController->GetPawn()); if (MyPawn && MyPawn->IsAlive()) { ASPlayerState* PS = Cast<ASPlayerState>(MyController->PlayerState); if (PS) { PS->ScorePoints(NightSurvivedScore); } } } } } } /* Update bot states */ if (CurrentIsNight) { WakeAllBots(); } else { PassifyAllBots(); } } LastIsNight = MyGameState->bIsNight; } } }
void ASGameMode::RestartPlayer(class AController* NewPlayer) { /* Fallback to PlayerStart picking if team spawning is disabled or we're trying to spawn a bot. */ if (!bSpawnAtTeamPlayer || (NewPlayer->PlayerState && NewPlayer->PlayerState->bIsABot)) { Super::RestartPlayer(NewPlayer); return; } /* Look for a live player to spawn next to */ FVector SpawnOrigin = FVector::ZeroVector; FRotator StartRotation = FRotator::ZeroRotator; for (FConstPawnIterator It = GetWorld()->GetPawnIterator(); It; It++) { ASCharacter* MyCharacter = Cast<ASCharacter>(*It); if (MyCharacter && MyCharacter->IsAlive()) { /* Get the origin of the first player we can find */ SpawnOrigin = MyCharacter->GetActorLocation(); StartRotation = MyCharacter->GetActorRotation(); break; } } /* No player is alive (yet) - spawn using one of the PlayerStarts */ if (SpawnOrigin == FVector::ZeroVector) { Super::RestartPlayer(NewPlayer); return; } /* Get a point on the nav mesh near the other player */ FVector StartLocation = UNavigationSystem::GetRandomPointInRadius(NewPlayer, SpawnOrigin, 250.0f); // Try to create a pawn to use of the default class for this player if (NewPlayer->GetPawn() == nullptr && GetDefaultPawnClassForController(NewPlayer) != nullptr) { FActorSpawnParameters SpawnInfo; SpawnInfo.Instigator = Instigator; APawn* ResultPawn = GetWorld()->SpawnActor<APawn>(GetDefaultPawnClassForController(NewPlayer), StartLocation, StartRotation, SpawnInfo); if (ResultPawn == nullptr) { UE_LOG(LogGameMode, Warning, TEXT("Couldn't spawn Pawn of type %s at %s"), *GetNameSafe(DefaultPawnClass), &StartLocation); } NewPlayer->SetPawn(ResultPawn); } if (NewPlayer->GetPawn() == nullptr) { NewPlayer->FailedToSpawnPawn(); } else { NewPlayer->Possess(NewPlayer->GetPawn()); // If the Pawn is destroyed as part of possession we have to abort if (NewPlayer->GetPawn() == nullptr) { NewPlayer->FailedToSpawnPawn(); } else { // Set initial control rotation to player start's rotation NewPlayer->ClientSetRotation(NewPlayer->GetPawn()->GetActorRotation(), true); FRotator NewControllerRot = StartRotation; NewControllerRot.Roll = 0.f; NewPlayer->SetControlRotation(NewControllerRot); SetPlayerDefaults(NewPlayer->GetPawn()); } } }