void FFriendsMessageManager::SendGameInviteRequest()
{
	TSharedPtr<FUniqueNetId> UserId = OnlineSubMcp->GetIdentityInterface()->GetUniquePlayerId(0);
	if ( GameInvitesToSend[ 0 ]->IsValid()  )
	{
		FOnlineMessagePayload InvitePayload;
		TArray<TSharedRef<FUniqueNetId> > Recipients;
		Recipients.Add( GameInvitesToSend[0] );
 		InvitePayload.SetAttribute( TEXT("SenderID"), FVariantData( DisplayName ) );
		InvitePayload.SetAttribute( TEXT("GameInvite"), FVariantData( UserId.Get()->ToString() ) );
		OnlineSubMcp->GetMessageInterface()->SendMessage( 0, Recipients, TEXT("GameInvite"), InvitePayload );
	}

	GameInvitesToSend.RemoveAt( 0 );
}
void FShooterMainMenu::HostTeamDeathMatch()
{	
	EMap SelectedMap = GetSelectedMap();
	AShooterPlayerController_Menu * ShooterPC = Cast<AShooterPlayerController_Menu>(PCOwner);
	FString StartStr = FString::Printf(TEXT("/Game/Maps/%s?game=TDM?listen%s?%s=%d"), *MapNames[(int)SelectedMap], bIsLanMatch ? TEXT("?bIsLanMatch") : TEXT(""), *AShooterGameMode::GetBotsCountOptionName(), BotsCountOpt);
	
	CreateSplitScreenPlayers();

	if (ShooterPC != NULL && ShooterPC->CreateGame(LOCTEXT("TDM","TDM").ToString(), StartStr))
	{		
		// Set presence for playing in a map
		if(ShooterPC->PlayerState && ShooterPC->PlayerState->UniqueId.IsValid())
		{
			const auto Presence = Online::GetPresenceInterface();
			if(Presence.IsValid())
			{
				FPresenceProperties Props;
				Props.Add(DefaultPresenceKey, FVariantData(FString("InGame")));
				Presence->SetPresence(*ShooterPC->PlayerState->UniqueId, Props);
			}
		}

		FSlateApplication::Get().SetFocusToGameViewport();
		LockAndHideMenu();
		DisplayLoadingScreen();
	}
}
void AShooterPlayerController::OnDeathMessage(class AShooterPlayerState* KillerPlayerState, class AShooterPlayerState* KilledPlayerState, const UDamageType* KillerDamageType) 
{
	AShooterHUD* ShooterHUD = GetShooterHUD();
	if (ShooterHUD)
	{
		ShooterHUD->ShowDeathMessage(KillerPlayerState, KilledPlayerState, KillerDamageType);		
	}

	ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(Player);
	if (LocalPlayer && LocalPlayer->GetUniqueNetId().IsValid() && KilledPlayerState->UniqueId.IsValid())
	{
		// if this controller is the player who died, update the hero stat.
		if (*LocalPlayer->GetUniqueNetId() == *KilledPlayerState->UniqueId)
		{
			const auto Events = Online::GetEventsInterface();
			const auto Identity = Online::GetIdentityInterface();

			if (Events.IsValid() && Identity.IsValid())
			{							
				int32 UserIndex = LocalPlayer->ControllerId;
				TSharedPtr<FUniqueNetId> UniqueID = Identity->GetUniquePlayerId(UserIndex);
				if (UniqueID.IsValid())
				{				
					ACharacter* Pawn = GetCharacter();
					check(Pawn);
					FVector Location = Pawn->GetActorLocation();

					FOnlineEventParms Params;
					Params.Add( TEXT( "SectionId" ), FVariantData( (int32)1 ) );
					Params.Add( TEXT( "GameplayModeId" ), FVariantData( (int32)1 ) );
					Params.Add( TEXT( "DifficultyLevelId" ), FVariantData( (int32)0 ) );

					Params.Add( TEXT( "PlayerRoleId" ), FVariantData( (int32)0 ) );
					Params.Add( TEXT( "PlayerWeaponId" ), FVariantData( (int32)0 ) );
					Params.Add( TEXT( "EnemyRoleId" ), FVariantData( (int32)0 ) );
					Params.Add( TEXT( "EnemyWeaponId" ), FVariantData( (int32)0 ) );	
				
					Params.Add( TEXT( "LocationX" ), FVariantData( Location.X ) );
					Params.Add( TEXT( "LocationY" ), FVariantData( Location.Y ) );
					Params.Add( TEXT( "LocationZ" ), FVariantData( Location.Z ) );
										
					Events->TriggerEvent(*UniqueID, TEXT("PlayerDeath"), Params);
				}
			}
		}
	}	
}
void FFriendsMessageManager::SendChatMessageRequest()
{
	TSharedPtr<FUniqueNetId> UserId = OnlineSubMcp->GetIdentityInterface()->GetUniquePlayerId(0);

	if ( ChatMessagesToSend.Num() > 0 )
	{
		FString DisplayMessage = DisplayName;
		DisplayMessage += TEXT ( " says:\n" );
		DisplayMessage += ChatMessagesToSend[0].Message.ToString();

		ChatMessages.Add( MakeShareable ( new FFriendsAndChatMessage( DisplayMessage ) ) );

		FOnlineMessagePayload TestPayload;
		TArray<TSharedRef<FUniqueNetId> > Recipients;
		Recipients.Add( ChatMessagesToSend[0].FriendID );
 		TestPayload.SetAttribute(TEXT("STRINGValue"), FVariantData( ChatMessagesToSend[0].Message.ToString() ) ); 
 		TestPayload.SetAttribute(TEXT("SenderID"), FVariantData( DisplayName ) ); 
		OnlineSubMcp->GetMessageInterface()->SendMessage(0, Recipients, TEXT("TestType"), TestPayload);
	}
	ChatMessagesToSend.RemoveAt( 0 );
}
bool AShooterPlayerController::SetPause(bool bPause, FCanUnpause CanUnpauseDelegate /*= FCanUnpause()*/)
{
	const bool Result = APlayerController::SetPause(bPause, CanUnpauseDelegate);

	// Update rich presence.
	const auto PresenceInterface = Online::GetPresenceInterface();
	const auto Events = Online::GetEventsInterface();
	if(PresenceInterface.IsValid() && PlayerState->UniqueId.IsValid())
	{
		FPresenceProperties Props;
		if(Result && bPause)
		{
			Props.Add(DefaultPresenceKey, FString("Paused"));
		}
		else
		{
			Props.Add(DefaultPresenceKey, FString("InGame"));
		}
		PresenceInterface->SetPresence(*PlayerState->UniqueId, Props);

	}

	if(Events.IsValid() && PlayerState->UniqueId.IsValid())
	{
		FOnlineEventParms Params;
		Params.Add( TEXT( "GameplayModeId" ), FVariantData( (int32)1 ) );
		Params.Add( TEXT( "DifficultyLevelId" ), FVariantData( (int32)0 ) );
		if(Result && bPause)
		{
			Events->TriggerEvent(*PlayerState->UniqueId, TEXT("PlayerSessionPause"), Params);
		}
		else
		{
			Events->TriggerEvent(*PlayerState->UniqueId, TEXT("PlayerSessionResume"), Params);
		}
	}

	return Result;
}
void AMessageSubsystemTestActor::LoginCallback(int32 LocalUserNum, bool bWasSuccessful, const FUniqueNetId& UserId, const FString& Error)
{
	UE_LOG(LogTemp, Log, TEXT("%s"), (_identity->GetLoginStatus(0) == ELoginStatus::LoggedIn) ? TEXT("true") : TEXT("false"));

	TArray<TSharedRef<const FUniqueNetId>> ids;
	ids.Add(UserId.AsShared());

	FOnlineMessagePayload payload = FOnlineMessagePayload();
	FVariantData data = FVariantData();
	data.SetValue(true);
	payload.SetAttribute("test", data);

	_message->SendMessage(0, ids, TEXT("testMessage"), payload);
}
/** Simple test cases for key value pair code */
void TestKeyValuePairs()
{
	bool bSuccess = true;

	TArray<uint8> TestData;
	TestData.Add((uint8)200);

 	typedef FOnlineKeyValuePairs<FName, FVariantData> TestDataType;
	TestDataType TestKeyValuePairs;
 
 	// Test Templates
 	TestKeyValuePairs.Add(TEXT("INTValue"), FVariantData(512)); 
 	TestKeyValuePairs.Add(TEXT("FLOATValue"), FVariantData(512.0f)); 
 	TestKeyValuePairs.Add(TEXT("QWORDValue"), FVariantData((uint64)512)); 
 	TestKeyValuePairs.Add(TEXT("DOUBLEValue"), FVariantData(512000.0)); 
 	TestKeyValuePairs.Add(TEXT("STRINGValue"), FVariantData(TEXT("This Is A Test!"))); 
 	TestKeyValuePairs.Add(TEXT("BLOBValue"), FVariantData(TestData)); 

	UE_LOG(LogOnline, Display, TEXT("ConstIterator"));
	for (TestDataType::TConstIterator It(TestKeyValuePairs); It; ++It)
	{
		UE_LOG(LogOnline, Display, TEXT("%s = %s"), *It.Key().ToString(), *It.Value().ToString());
	}

	UE_LOG(LogOnline, Display, TEXT("Iterator"));
	for (TestDataType::TIterator It(TestKeyValuePairs); It; ++It)
	{
		UE_LOG(LogOnline, Display, TEXT("Iterator %s = %s"), *It.Key().ToString(), *It.Value().ToString());
	}

	UE_LOG(LogOnline, Display, TEXT("Finding all elements"));
	if (TestKeyValuePairs.Find(TEXT("INTValue")) == NULL)
	{
		bSuccess = false;
	}
	if (TestKeyValuePairs.Find(TEXT("FLOATValue")) == NULL)
	{
		bSuccess = false;
	}
	if (TestKeyValuePairs.Find(TEXT("QWORDValue")) == NULL)
	{
		bSuccess = false;
	}
	if (TestKeyValuePairs.Find(TEXT("DOUBLEValue")) == NULL)
	{
		bSuccess = false;
	}
	if (TestKeyValuePairs.Find(TEXT("STRINGValue")) == NULL)
	{
		bSuccess = false;
	}
	if (TestKeyValuePairs.Find(TEXT("BLOBValue")) == NULL)
	{
		bSuccess = false;
	}

	if (!bSuccess)
	{
		UE_LOG(LogOnline, Display, TEXT("Not all elements found!"));
	}

	TestKeyValuePairs.Remove(TEXT("INTValue"));
	TestKeyValuePairs.Remove(TEXT("BLOBValue"));

	UE_LOG(LogOnline, Display, TEXT("Iterator AFTER removing int32 and Blob elements"));
	for (TestDataType::TIterator It(TestKeyValuePairs); It; ++It)
	{
		UE_LOG(LogOnline, Display, TEXT("Iterator %s = %s"), *It.Key().ToString(), *It.Value().ToString());
	}

	TestKeyValuePairs.Empty();
	UE_LOG(LogOnline, Display, TEXT("Iterator AFTER emptying structure"));
	for (TestDataType::TIterator It(TestKeyValuePairs); It; ++It)
	{
		UE_LOG(LogOnline, Display, TEXT("Iterator %s = %s"), *It.Key().ToString(), *It.Value().ToString());
	}

	bSuccess = TestKeyValuePairs.Num() == 0 ? true : false;

	// Test basic variant data type functionality
	FVariantData OrigKeyValuePair;
	FVariantData CopyValue;

	{
		// Test int32
		int32 OutValue = 0;
		int32 TestValue = 5;
		OrigKeyValuePair.SetValue(TestValue);
		OrigKeyValuePair.GetValue(OutValue);
		bSuccess = bSuccess && (OutValue == TestValue);   
		
		CopyValue = OrigKeyValuePair; 
		UE_LOG(LogOnline, Display, TEXT("int32 Test %s == %s"), *OrigKeyValuePair.ToString(), *CopyValue.ToString());

		OrigKeyValuePair.Increment<int32,EOnlineKeyValuePairDataType::Int32>((int32)1);
		UE_LOG(LogOnline, Display, TEXT("+1 Now is %s"), *OrigKeyValuePair.ToString());

		OrigKeyValuePair.Decrement<int32,EOnlineKeyValuePairDataType::Int32>((int32)1);
		UE_LOG(LogOnline, Display, TEXT("-1 Now is %s"), *OrigKeyValuePair.ToString());

		bSuccess = bSuccess && (OrigKeyValuePair == CopyValue); 
		bSuccess = bSuccess && OrigKeyValuePair.FromString(TEXT("5"));
		UE_LOG(LogOnline, Display, TEXT("int32 Test %s == %s"), *OrigKeyValuePair.ToString(), *CopyValue.ToString());
	}

	{
		// Test float
		float OutValue = 0.0f;
		float TestValue = 5.0f;
		OrigKeyValuePair.SetValue(TestValue);
		OrigKeyValuePair.GetValue(OutValue);
		bSuccess = bSuccess && (OutValue == TestValue);

		CopyValue = OrigKeyValuePair; 
		UE_LOG(LogOnline, Display, TEXT("float Test %s == %s"), *OrigKeyValuePair.ToString(), *CopyValue.ToString());

		OrigKeyValuePair.Increment<float,EOnlineKeyValuePairDataType::Float>(1.0f);
		UE_LOG(LogOnline, Display, TEXT("+1 Now is %s"), *OrigKeyValuePair.ToString());

		OrigKeyValuePair.Decrement<float,EOnlineKeyValuePairDataType::Float>(1.0f);
		UE_LOG(LogOnline, Display, TEXT("-1 Now is %s"), *OrigKeyValuePair.ToString());

		bSuccess = bSuccess && (OrigKeyValuePair == CopyValue); 
		bSuccess = bSuccess && OrigKeyValuePair.FromString(TEXT("5.0"));
		UE_LOG(LogOnline, Display, TEXT("float Test %s == %s"), *OrigKeyValuePair.ToString(), *CopyValue.ToString());
	}

	{
		// Test double
		double OutValue = 0.0;
		double TestValue = 5.0;
		OrigKeyValuePair.SetValue(TestValue);
		OrigKeyValuePair.GetValue(OutValue);
		bSuccess = bSuccess && (OutValue == TestValue);

		CopyValue = OrigKeyValuePair; 
		UE_LOG(LogOnline, Display, TEXT("double Test %s == %s"), *OrigKeyValuePair.ToString(), *CopyValue.ToString());

		OrigKeyValuePair.Increment<double,EOnlineKeyValuePairDataType::Double>(1.0);
		UE_LOG(LogOnline, Display, TEXT("+1 Now is %s"), *OrigKeyValuePair.ToString());

		OrigKeyValuePair.Decrement<double,EOnlineKeyValuePairDataType::Double>(1.0);
		UE_LOG(LogOnline, Display, TEXT("-1 Now is %s"), *OrigKeyValuePair.ToString());

		bSuccess = bSuccess && (OrigKeyValuePair == CopyValue); 
		bSuccess = bSuccess && OrigKeyValuePair.FromString(TEXT("5.0"));
		UE_LOG(LogOnline, Display, TEXT("double Test %s == %s"), *OrigKeyValuePair.ToString(), *CopyValue.ToString());
	}

	{
		// Test uint64
		uint64 OutValue = 0;
		uint64 TestValue = 524288;
		OrigKeyValuePair.SetValue(TestValue);
		OrigKeyValuePair.GetValue(OutValue);
		bSuccess = bSuccess && (OutValue == TestValue);

		CopyValue = OrigKeyValuePair; 
		UE_LOG(LogOnline, Display, TEXT("uint64 Test %s == %s"), *OrigKeyValuePair.ToString(), *CopyValue.ToString()); 

		OrigKeyValuePair.Increment<uint64,EOnlineKeyValuePairDataType::Int64>(1.0);
		UE_LOG(LogOnline, Display, TEXT("+1 Now is %s"), *OrigKeyValuePair.ToString());

		OrigKeyValuePair.Decrement<uint64,EOnlineKeyValuePairDataType::Int64>(1.0);
		UE_LOG(LogOnline, Display, TEXT("-1 Now is %s"), *OrigKeyValuePair.ToString());

		bSuccess = bSuccess && (OrigKeyValuePair == CopyValue);
		bSuccess = bSuccess && OrigKeyValuePair.FromString(TEXT("524288"));
		UE_LOG(LogOnline, Display, TEXT("uint64 Test %s == %s"), *OrigKeyValuePair.ToString(), *CopyValue.ToString());
	}

	{
		// Test String
		FString OutValue;
		FString TestValue(TEXT("This is a test!"));
		OrigKeyValuePair.SetValue(TestValue);
		OrigKeyValuePair.GetValue(OutValue);
		bSuccess = bSuccess && (OutValue == TestValue);

		CopyValue = OrigKeyValuePair; 
		bSuccess = bSuccess && (OrigKeyValuePair == CopyValue);
		UE_LOG(LogOnline, Display, TEXT("STRING Test %s == %s"), *OrigKeyValuePair.ToString(), *CopyValue.ToString()); 
	}

	{
		// Test Blob
		TArray<uint8> OutValue;
		TArray<uint8> TestValue;
		for (int32 i=0; i<512; i++)
		{
			TestValue.Add(FMath::Rand() % 255);
		}

		OrigKeyValuePair.SetValue(TestValue);
		OrigKeyValuePair.GetValue(OutValue);
		bSuccess = bSuccess && (OutValue == TestValue);

		CopyValue = OrigKeyValuePair; 
		bSuccess = bSuccess && (OrigKeyValuePair == CopyValue); 
		UE_LOG(LogOnline, Display, TEXT("BLOB Test %s == %s"), *OrigKeyValuePair.ToString(), *CopyValue.ToString());
	}

	UE_LOG(LogOnline, Warning, TEXT("KeyValuePairTest: %s!"), bSuccess ? TEXT("PASSED") : TEXT("FAILED"));
}
void AShooterPlayerController::UpdateAchievementsOnGameEnd()
{
	ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(Player);
	if (LocalPlayer)
	{
		AShooterPlayerState* ShooterPlayerState = Cast<AShooterPlayerState>(PlayerState);
		if (ShooterPlayerState)
		{			
			const UShooterPersistentUser*  PersistentUser = GetPersistentUser();

			if (PersistentUser)
			{						
				const int32 Wins = PersistentUser->GetWins();
				const int32 Losses = PersistentUser->GetLosses();
				const int32 Matches = Wins + Losses;

				const int32 TotalKills = PersistentUser->GetKills();
				const int32 MatchScore = (int32)ShooterPlayerState->GetScore();

				const int32 TotalBulletsFired = PersistentUser->GetBulletsFired();
				const int32 TotalRocketsFired = PersistentUser->GetRocketsFired();
			
				float TotalGameAchievement = 0;
				float CurrentGameAchievement = 0;
			
				///////////////////////////////////////
				// Kill achievements
				{
					float fSomeKillPct = ((float)TotalKills / (float)SomeKillsCount) * 100.0f;
					fSomeKillPct = FMath::RoundToFloat(fSomeKillPct);
					UpdateAchievementProgress(ACH_SOME_KILLS, fSomeKillPct);

					CurrentGameAchievement += FMath::Min(fSomeKillPct, 100.0f);
					TotalGameAchievement += 100;
				}

				{
					float fLotsKillPct = ((float)TotalKills / (float)LotsKillsCount) * 100.0f;
					fLotsKillPct = FMath::RoundToFloat(fLotsKillPct);
					UpdateAchievementProgress(ACH_LOTS_KILLS, fLotsKillPct);

					CurrentGameAchievement += FMath::Min(fLotsKillPct, 100.0f);
					TotalGameAchievement += 100;
				}
				///////////////////////////////////////

				///////////////////////////////////////
				// Match Achievements
				{
					UpdateAchievementProgress(ACH_FINISH_MATCH, 100.0f);

					CurrentGameAchievement += 100;
					TotalGameAchievement += 100;
				}
			
				{
					float fLotsRoundsPct = ((float)Matches / (float)LotsMatchesCount) * 100.0f;
					fLotsRoundsPct = FMath::RoundToFloat(fLotsRoundsPct);
					UpdateAchievementProgress(ACH_LOTS_MATCHES, fLotsRoundsPct);

					CurrentGameAchievement += FMath::Min(fLotsRoundsPct, 100.0f);
					TotalGameAchievement += 100;
				}
				///////////////////////////////////////

				///////////////////////////////////////
				// Win Achievements
				if (Wins >= 1)
				{
					UpdateAchievementProgress(ACH_FIRST_WIN, 100.0f);

					CurrentGameAchievement += 100.0f;
				}
				TotalGameAchievement += 100;

				{			
					float fLotsWinPct = ((float)Wins / (float)LotsWinsCount) * 100.0f;
					fLotsWinPct = FMath::RoundToInt(fLotsWinPct);
					UpdateAchievementProgress(ACH_LOTS_WIN, fLotsWinPct);

					CurrentGameAchievement += FMath::Min(fLotsWinPct, 100.0f);
					TotalGameAchievement += 100;
				}

				{			
					float fManyWinPct = ((float)Wins / (float)ManyWinsCount) * 100.0f;
					fManyWinPct = FMath::RoundToInt(fManyWinPct);
					UpdateAchievementProgress(ACH_MANY_WIN, fManyWinPct);

					CurrentGameAchievement += FMath::Min(fManyWinPct, 100.0f);
					TotalGameAchievement += 100;
				}
				///////////////////////////////////////

				///////////////////////////////////////
				// Ammo Achievements
				{
					float fLotsBulletsPct = ((float)TotalBulletsFired / (float)LotsBulletsCount) * 100.0f;
					fLotsBulletsPct = FMath::RoundToFloat(fLotsBulletsPct);
					UpdateAchievementProgress(ACH_SHOOT_BULLETS, fLotsBulletsPct);

					CurrentGameAchievement += FMath::Min(fLotsBulletsPct, 100.0f);
					TotalGameAchievement += 100;
				}

				{
					float fLotsRocketsPct = ((float)TotalRocketsFired / (float)LotsRocketsCount) * 100.0f;
					fLotsRocketsPct = FMath::RoundToFloat(fLotsRocketsPct);
					UpdateAchievementProgress(ACH_SHOOT_ROCKETS, fLotsRocketsPct);

					CurrentGameAchievement += FMath::Min(fLotsRocketsPct, 100.0f);
					TotalGameAchievement += 100;
				}
				///////////////////////////////////////

				///////////////////////////////////////
				// Score Achievements
				{
					float fGoodScorePct = ((float)MatchScore / (float)GoodScoreCount) * 100.0f;
					fGoodScorePct = FMath::RoundToFloat(fGoodScorePct);
					UpdateAchievementProgress(ACH_GOOD_SCORE, fGoodScorePct);
				}

				{
					float fGreatScorePct = ((float)MatchScore / (float)GreatScoreCount) * 100.0f;
					fGreatScorePct = FMath::RoundToFloat(fGreatScorePct);
					UpdateAchievementProgress(ACH_GREAT_SCORE, fGreatScorePct);
				}
				///////////////////////////////////////

				///////////////////////////////////////
				// Map Play Achievements
				UWorld* World = GetWorld();
				if (World)
				{			
					FString MapName = *FPackageName::GetShortName(World->PersistentLevel->GetOutermost()->GetName());
					if (MapName.Find(TEXT("Highrise")) != -1)
					{
						UpdateAchievementProgress(ACH_PLAY_HIGHRISE, 100.0f);
					}
					else if (MapName.Find(TEXT("Sanctuary")) != -1)
					{
						UpdateAchievementProgress(ACH_PLAY_SANCTUARY, 100.0f);
					}
				}
				///////////////////////////////////////			

				const auto Events = Online::GetEventsInterface();
				const auto Identity = Online::GetIdentityInterface();

				if (Events.IsValid() && Identity.IsValid())
				{							
					int32 UserIndex = LocalPlayer->ControllerId;
					TSharedPtr<FUniqueNetId> UniqueID = Identity->GetUniquePlayerId(UserIndex);
					if (UniqueID.IsValid())
					{				
						FOnlineEventParms Params;

						float fGamePct = (CurrentGameAchievement / TotalGameAchievement) * 100.0f;
						fGamePct = FMath::RoundToFloat(fGamePct);
						Params.Add( TEXT( "CompletionPercent" ), FVariantData( (float)fGamePct ) );
						if (UniqueID.IsValid())
						{				
							Events->TriggerEvent(*UniqueID, TEXT("GameProgress"), Params);
						}
					}
				}
			}
		}
	}
}
void AShooterPlayerController::OnKill()
{
	UpdateAchievementProgress(ACH_FRAG_SOMEONE, 100.0f);

	const auto Events = Online::GetEventsInterface();
	const auto Identity = Online::GetIdentityInterface();

	if (Events.IsValid() && Identity.IsValid())
	{
		ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(Player);
		if (LocalPlayer)
		{
			int32 UserIndex = LocalPlayer->ControllerId;
			TSharedPtr<FUniqueNetId> UniqueID = Identity->GetUniquePlayerId(UserIndex);			
			if (UniqueID.IsValid())
			{			
				ACharacter* Pawn = GetCharacter();
				// If player is dead, use location stored during pawn cleanup.
				FVector Location = LastDeathLocation;
				if (Pawn)
				{
					Pawn->GetActorLocation();
				}

				FOnlineEventParms Params;		

				Params.Add( TEXT( "SectionId" ), FVariantData( (int32)1 ) );
				Params.Add( TEXT( "GameplayModeId" ), FVariantData( (int32)1 ) );
				Params.Add( TEXT( "DifficultyLevelId" ), FVariantData( (int32)0 ) );

				Params.Add( TEXT( "PlayerRoleId" ), FVariantData( (int32)0 ) );
				Params.Add( TEXT( "PlayerWeaponId" ), FVariantData( (int32)0 ) );
				Params.Add( TEXT( "EnemyRoleId" ), FVariantData( (int32)0 ) );
				Params.Add( TEXT( "KillTypeId" ), FVariantData( (int32)0 ) );			
				Params.Add( TEXT( "LocationX" ), FVariantData( Location.X ) );
				Params.Add( TEXT( "LocationY" ), FVariantData( Location.Y ) );
				Params.Add( TEXT( "LocationZ" ), FVariantData( Location.Z ) );
				Params.Add( TEXT( "EnemyWeaponId" ), FVariantData( (int32)0 ) );			
			
				Events->TriggerEvent(*UniqueID, TEXT("KillOponent"), Params);				
			}
		}
	}
}