Neg_Utils/Achivments/AchivmentManager.cs
LubieKakao1212 9dfb118f88 fix
2023-01-02 11:54:46 +01:00

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}");
}
}
}
}