Initial Commit - Lesson 31 (Commit #1)

This commit is contained in:
Norman Lansing
2026-02-24 22:39:26 -05:00
commit 9591e7f503
4631 changed files with 1019212 additions and 0 deletions

View File

@@ -0,0 +1,224 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "Player/MatchPlayerState.h"
#include "ShooterTypes/ShooterTypes.h"
#include "UI/Elims/SpecialElimWidget.h"
AMatchPlayerState::AMatchPlayerState()
{
SetNetUpdateFrequency(100.f); // let's not be sluggish, alright?
ScoredElims = 0;
Defeats = 0;
Hits = 0;
Misses = 0;
bOnStreak = false;
HeadShotElims = 0;
SequentialElims = TMap<int32, int32>();
HighestStreak = 0;
RevengeElims = 0;
DethroneElims = 0;
ShowStopperElims = 0;
bFirstBlood = false;
bWinner = false;
}
void AMatchPlayerState::AddScoredElim()
{
++ScoredElims;
}
void AMatchPlayerState::AddDefeat()
{
++Defeats;
}
void AMatchPlayerState::AddHit()
{
++Hits;
}
void AMatchPlayerState::AddMiss()
{
++Misses;
}
void AMatchPlayerState::AddHeadShotElim()
{
++HeadShotElims;
}
void AMatchPlayerState::AddSequentialElim(int32 SequenceCount)
{
if (SequentialElims.Contains(SequenceCount))
{
SequentialElims[SequenceCount]++;
}
else
{
SequentialElims.Add(SequenceCount, 1);
}
// Reduce the count for all lower sequence counts
// This is because a triple elim means a double was scored first,
// But we want to count this as just a triple, i.e:
// elim 1, elim 2, elim 3 = just a triple, not a double and a triple.
for (auto& Elem : SequentialElims)
{
if (Elem.Key < SequenceCount && Elem.Value > 0)
{
Elem.Value--;
}
}
}
void AMatchPlayerState::UpdateHighestStreak(int32 StreakCount)
{
if (StreakCount > HighestStreak)
{
HighestStreak = StreakCount;
}
}
void AMatchPlayerState::AddRevengeElim()
{
++RevengeElims;
}
void AMatchPlayerState::AddDethroneElim()
{
++DethroneElims;
}
void AMatchPlayerState::AddShowStopperElim()
{
++ShowStopperElims;
}
void AMatchPlayerState::GotFirstBlood()
{
bFirstBlood = true;
}
void AMatchPlayerState::IsTheWinner()
{
bWinner = true;
}
TArray<ESpecialElimType> AMatchPlayerState::DecodeElimBitmask(ESpecialElimType ElimTypeBitmask)
{
TArray<ESpecialElimType> ValidElims;
uint8 BitmaskValue = static_cast<uint8>(ElimTypeBitmask);
for(uint8 i = 0; i < 16; i++) // Assuming 8 bits since ESpecialElimType is a uint16
{
if (BitmaskValue & (1 << i))
{
ESpecialElimType EnumValue = static_cast<ESpecialElimType>(1 << i);
ValidElims.Add(EnumValue);
}
}
return ValidElims;
}
void AMatchPlayerState::ProcessNextSpecialElim()
{
FSpecialElimInfo ElimInfo;
if (SpecialElimQueue.Dequeue(ElimInfo))
{
bIsProcessingQueue = true;
ShowSpecialElim(ElimInfo);
// Schedule the next elimination processing after a delay
GetWorldTimerManager().SetTimerForNextTick([this]()
{
constexpr float ElimDisplayTime = 0.5f; // Adjust the time in seconds as needed
FTimerHandle TimerHandle;
GetWorldTimerManager().SetTimer(TimerHandle, this, &AMatchPlayerState::ProcessNextSpecialElim, ElimDisplayTime, false);
});
}
else
{
bIsProcessingQueue = false;
}
}
void AMatchPlayerState::ShowSpecialElim(const FSpecialElimInfo& ElimMessageInfo)
{
FString ElimMessageString = ElimMessageInfo.ElimMessage;
if (ElimMessageInfo.ElimType == ESpecialElimType::Sequential)
{
FString Msg = ElimMessageInfo.ElimMessage;
int32 Seq = ElimMessageInfo.SequentialElimCount;
int32 Streak = ElimMessageInfo.StreakCount;
if (ElimMessageInfo.SequentialElimCount == 2) ElimMessageString = FString("Double Elim!");
else if (ElimMessageInfo.SequentialElimCount == 3) ElimMessageString = FString("Triple Elim!");
else if (ElimMessageInfo.SequentialElimCount == 4) ElimMessageString = FString("Quad Elim!");
else if (ElimMessageInfo.SequentialElimCount > 4) ElimMessageString = FString::Printf(TEXT("Rampage x%d!"), ElimMessageInfo.SequentialElimCount);
}
if (ElimMessageInfo.ElimType == ESpecialElimType::Streak) ElimMessageString = FString::Printf(TEXT("Streak x%d!"), ElimMessageInfo.StreakCount);
if (SpecialElimWidgetClass)
{
USpecialElimWidget* ElimWidget = CreateWidget<USpecialElimWidget>(GetWorld(), SpecialElimWidgetClass);
if (IsValid(ElimWidget))
{
ElimWidget->InitializeWidget(ElimMessageString, ElimMessageInfo.ElimIcon);
ElimWidget->AddToViewport();
}
}
}
void AMatchPlayerState::Client_ScoredElim_Implementation(int32 ElimScore)
{
OnScoreChanged.Broadcast(ElimScore);
}
void AMatchPlayerState::Client_SpecialElim_Implementation(const ESpecialElimType& SpecialElim, int32 SequentialElimCount, int32 StreakCount, int32 ElimScore)
{
OnScoreChanged.Broadcast(ElimScore);
if (!IsValid(SpecialElimData)) return;
TArray<ESpecialElimType> ElimTypes = DecodeElimBitmask(SpecialElim);
for (ESpecialElimType ElimType : ElimTypes)
{
FSpecialElimInfo& ElimInfo = SpecialElimData->SpecialElimInfo.FindChecked(ElimType);
if (ElimType == ESpecialElimType::Sequential)
{
ElimInfo.SequentialElimCount = SequentialElimCount;
}
if (ElimType == ESpecialElimType::Streak)
{
ElimInfo.StreakCount = StreakCount;
}
ElimInfo.ElimType = ElimType;
SpecialElimQueue.Enqueue(ElimInfo);
}
if (!bIsProcessingQueue)
{
ProcessNextSpecialElim();
}
}
void AMatchPlayerState::Client_LostTheLead_Implementation()
{
UE_LOG(LogTemp, Warning, TEXT("%s Lost the Lead"), *GetName());
if (!IsValid(SpecialElimData)) return;
auto& ElimMessageInfo = SpecialElimData->SpecialElimInfo.FindChecked(ESpecialElimType::LostTheLead);
if (SpecialElimWidgetClass)
{
USpecialElimWidget* ElimWidget = CreateWidget<USpecialElimWidget>(GetWorld(), SpecialElimWidgetClass);
if (IsValid(ElimWidget))
{
ElimWidget->InitializeWidget(ElimMessageInfo.ElimMessage, ElimMessageInfo.ElimIcon);
ElimWidget->AddToViewport();
}
}
}