/*
* Neural Tanks is a game created by Eddie O'Hagan that leverages Neural Networking
* to use for AI. This was created in Unreal Engine 4 which is developed by Epic Games.
* (Copyright Epic Games, Inc. All Rights Reserved.)
*
* Smart Tanks was originally developed by Mat Buckland in 2002 as an example
* on how Neural Networking can be used to train a set of minesweepers
* to collect mines. I (Eddie O'Hagan) updated this project in 2024 to use more
* Object Oriented Programming and modern practices. To see the original tutorial;
* visit <see href="http://www.ai-junkie.com/ann/evolved/nnt1.html">Neural Networking Tutorial</see>
* and <see href="http://www.ai-junkie.com/ga/intro/gat1.html">Genetic Algorithm Tutorial</see>
*/
#include "AchievementManager.h"
#include <Online.h>
#include <OnlineSubsystem.h>
#include <Interfaces/OnlineAchievementsInterface.h>
#include <Interfaces/OnlineIdentityInterface.h>

/// <summary>
/// Reward the specified achievement to the player using the available online subsystem.
/// </summary>
/// <param name="theAchievement">The specific achievement to reward the player.</param>
void UAchievementManager::RewardAchievement(const ENeuralTanksAchievement& theAchievement)
{
	FString theAchievementName = UEnum::GetValueAsString<ENeuralTanksAchievement>(theAchievement);
    FUniqueNetIdPtr theUserId;
    FOnlineAchievementsWritePtr theAchievementsWriter;
    IOnlineSubsystem* theOnlineSubSystem = IOnlineSubsystem::Get();
    IOnlineAchievementsPtr theAchievementsInterface = NULL;

    //Remove the class name from the achievement name.
    theAchievementName = theAchievementName.RightChop(FString("ENeuralTanksAchievement::").Len());

    //Ensure we have a reference to the Steam back-end.
    if (theOnlineSubSystem != NULL)
    {
        //Get the interface for accessing online achievements.
        theAchievementsInterface = theOnlineSubSystem->GetAchievementsInterface();
        if (theAchievementsInterface.IsValid() == true)
        {
            //Get the unique user ID for the local player (0 for local player).
            theUserId = theOnlineSubSystem->GetIdentityInterface()->GetUniquePlayerId(0);
            if (theUserId.IsValid() == true)
            {
                theAchievementsWriter = MakeShareable(new FOnlineAchievementsWrite());

                //Reward the achievement (100.0f means 100% progress)
                theAchievementsWriter->SetFloatStat(FName(theAchievementName), 100.0f);

                FOnlineAchievementsWriteRef theAchievementsWriterSharedRef = theAchievementsWriter.ToSharedRef();
                theAchievementsInterface->WriteAchievements(*theUserId, theAchievementsWriterSharedRef);
            }
        }
    }
}

/// <summary>
/// The Achievements Interface needs to be queried before writing can begin.
/// </summary>
void UAchievementManager::QueryAchievements()
{
    IOnlineSubsystem* theOnlineSubSystem = IOnlineSubsystem::Get();
    IOnlineIdentityPtr playerIdentity;
    FUniqueNetIdPtr theUserId;
    IOnlineAchievementsPtr theAchievementsInterface = NULL;

    if (theOnlineSubSystem != NULL)
    {
        //Get the Identity (player's profile) and various online services.
        playerIdentity = theOnlineSubSystem->GetIdentityInterface();
        if (playerIdentity.IsValid() == true)
        {
            //Get the unique user ID for the local player (0 for local player).
            theUserId = playerIdentity->GetUniquePlayerId(0);

            //Get the achievements interface for this platform
            theAchievementsInterface = theOnlineSubSystem->GetAchievementsInterface();
            if (theAchievementsInterface.IsValid() == true)
            {
                //Cache all the game's achievements for future use and bind the OnQueryAchievementsComplete function to fire when we're finished caching
                theAchievementsInterface->QueryAchievements(*theUserId.Get());
            }
        }
    }
}