193 lines
6.1 KiB
C#
193 lines
6.1 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
using UnityEngine.AddressableAssets;
|
|
using System.Runtime.CompilerServices;
|
|
using UnityEditor;
|
|
|
|
namespace NEG.Utils.Achivments
|
|
{
|
|
public class AchivmentManager
|
|
{
|
|
public class Builder
|
|
{
|
|
public const string DefaultAchivmentsConfigLabel = "Achivments";
|
|
|
|
private AchivmentManager manager = new AchivmentManager();
|
|
private IAchivmentStorage storage;
|
|
|
|
public static Builder FromDefaultConfig()
|
|
{
|
|
return FromLabeledConfig(DefaultAchivmentsConfigLabel);
|
|
}
|
|
|
|
public static Builder FromLabeledConfig(string label)
|
|
{
|
|
var builder = new Builder();
|
|
|
|
var handle = Addressables.LoadAssetsAsync<IAchivmentManagerConfig>((IEnumerable)new string[] { label }, delegate { }, Addressables.MergeMode.Union, false);
|
|
|
|
var configs = handle.WaitForCompletion();
|
|
|
|
foreach (var config in configs)
|
|
{
|
|
config.Apply(builder);
|
|
}
|
|
|
|
foreach (var config in configs)
|
|
{
|
|
config.ApplyLast(builder);
|
|
}
|
|
|
|
Addressables.Release(handle);
|
|
|
|
return builder;
|
|
}
|
|
|
|
public Builder WithLabeledDefinitions(string label)
|
|
{
|
|
var handle = Addressables.LoadAssetsAsync<AchivmentDefinitionCollection>((IEnumerable)new string[] { label }, delegate { }, Addressables.MergeMode.Union, false);
|
|
|
|
var achivmentCollections = handle.WaitForCompletion();
|
|
|
|
foreach (var achivmentCollection in achivmentCollections)
|
|
WithDefinitionsFrom(achivmentCollection);
|
|
|
|
return this;
|
|
}
|
|
|
|
public Builder WithDefinitionsFrom(AchivmentDefinitionCollection collection)
|
|
{
|
|
foreach (var def in collection.Achivments)
|
|
{
|
|
manager.RegisterAchivment(def);
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
public Builder LoadedFrom(IAchivmentStorage storageIn)
|
|
{
|
|
if (storage != null)
|
|
{
|
|
throw new ApplicationException("Cannot Load achivment data from multiple storage instances");
|
|
}
|
|
|
|
this.storage = storageIn;
|
|
|
|
return this;
|
|
}
|
|
|
|
public Builder WithCallbackReciever(IAchivmentCallbackReciever callbackReciever)
|
|
{
|
|
manager.AddCallbackReciever(callbackReciever);
|
|
return this;
|
|
}
|
|
|
|
public AchivmentManager Build()
|
|
{
|
|
if (storage != null)
|
|
{
|
|
manager.LoadFrom(storage);
|
|
}
|
|
return manager;
|
|
}
|
|
}
|
|
|
|
public delegate void AchivmentSetCallback(AchivmentData achivment);
|
|
public delegate void AchivmentProgressSetCallback(AchivmentData achivment, int progressLeft);
|
|
|
|
public event AchivmentSetCallback AchivmentSet;
|
|
public event AchivmentProgressSetCallback AchivmentProgressSet;
|
|
|
|
private Dictionary<string, AchivmentDefinition> definitionCache;
|
|
private Dictionary<AchivmentDefinition, AchivmentData> dataCache;
|
|
|
|
private AchivmentManager()
|
|
{
|
|
definitionCache = new Dictionary<string, AchivmentDefinition>();
|
|
dataCache = new Dictionary<AchivmentDefinition, AchivmentData>();
|
|
}
|
|
|
|
private void RegisterAchivment(AchivmentDefinition definition)
|
|
{
|
|
if (!definitionCache.ContainsKey(definition.Id))
|
|
{
|
|
definitionCache.Add(definition.Id, definition);
|
|
dataCache.Add(definition, new AchivmentData(definition, definition.ProgressRequired));
|
|
}
|
|
else
|
|
{
|
|
Debug.LogWarning($"Duplicate Achivment with ID: {definition.Id}");
|
|
}
|
|
}
|
|
|
|
private void LoadFrom(IAchivmentStorage achivmentStorage)
|
|
{
|
|
foreach (var entry in definitionCache)
|
|
{
|
|
var storedProgress = achivmentStorage.GetStoredAchivmentProgress(entry.Key);
|
|
|
|
dataCache[entry.Value].ProgressLeft = storedProgress;
|
|
}
|
|
}
|
|
|
|
public void AddCallbackRecievers(IEnumerable<IAchivmentCallbackReciever> initialCallbacks)
|
|
{
|
|
foreach (var callback in initialCallbacks)
|
|
{
|
|
AddCallbackReciever(callback);
|
|
}
|
|
}
|
|
|
|
public void AddCallbackReciever(IAchivmentCallbackReciever callback)
|
|
{
|
|
AchivmentSet += callback.SetAchivment;
|
|
AchivmentProgressSet += callback.SetAchivmentProgress;
|
|
}
|
|
|
|
public void RemoveCallbackReciever(IAchivmentCallbackReciever callback)
|
|
{
|
|
AchivmentSet -= callback.SetAchivment;
|
|
AchivmentProgressSet -= callback.SetAchivmentProgress;
|
|
}
|
|
|
|
public void SetAchivment(string id)
|
|
{
|
|
var data = GetAchivmentForId(id);
|
|
data.ProgressLeft = 0;
|
|
AchivmentSet?.Invoke(data);
|
|
}
|
|
|
|
public void AddProgress(string id, int amount)
|
|
{
|
|
var data = GetAchivmentForId(id);
|
|
if (data.IsCompleted)
|
|
{
|
|
return;
|
|
}
|
|
data.ProgressLeft = Mathf.Max(data.ProgressLeft - amount, 0);
|
|
AchivmentProgressSet?.Invoke(data, data.Achivment.ProgressRequired - data.ProgressLeft);
|
|
|
|
if (data.IsCompleted)
|
|
{
|
|
AchivmentSet?.Invoke(data);
|
|
}
|
|
}
|
|
|
|
private AchivmentData GetAchivmentForId(string id)
|
|
{
|
|
var def = definitionCache.GetValueOrDefault(id);
|
|
if (def != null)
|
|
{
|
|
return dataCache[def];
|
|
}
|
|
else
|
|
{
|
|
throw new ApplicationException($"Invalid achivment id {id}");
|
|
}
|
|
}
|
|
}
|
|
} |