achivments #1
341
Achievments/AchievmentManager.cs
Normal file
341
Achievments/AchievmentManager.cs
Normal file
@ -0,0 +1,341 @@
|
|||||||
|
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.Achievments
|
||||||
|
{
|
||||||
|
using AchievmentTypes;
|
||||||
|
|
||||||
|
public class AchievmentManager
|
||||||
|
{
|
||||||
|
public class Builder
|
||||||
|
{
|
||||||
|
public const string DefaultAchivmentsConfigLabel = "Achivments";
|
||||||
|
|
||||||
|
private AchievmentManager manager = new AchievmentManager();
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
BitterSmile
commented
no check for empty label no check for empty label
Ghost
commented
empty meaning null or empty meaning label with nothing assigned? empty meaning null or empty meaning label with nothing assigned?
BitterSmile
commented
you check for nothing, why even bother questioning you check for nothing, why even bother questioning
|
|||||||
|
|
||||||
|
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(IAchievmentCallbackReciever callbackReciever)
|
||||||
|
{
|
||||||
|
manager.AddCallbackReciever(callbackReciever);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AchievmentManager Build()
|
||||||
|
{
|
||||||
|
//TODO
|
||||||
|
/*if (storage != null)
|
||||||
|
{
|
||||||
|
manager.LoadFrom(storage);
|
||||||
|
}*/
|
||||||
|
return manager;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public delegate void AchievmentCompletedCallback(AchievmentData achivment);
|
||||||
|
public delegate void AchievmentStateChangedCallback(AchievmentData achivment);
|
||||||
|
|
||||||
|
public event AchievmentCompletedCallback AchievmentCompleted;
|
||||||
|
public event AchievmentStateChangedCallback AchievmentStateChanged;
|
||||||
|
|
||||||
|
private Dictionary<string, AchievmentDefinition> definitionCache;
|
||||||
|
private Dictionary<AchievmentDefinition, AchievmentData> dataCache;
|
||||||
|
|
||||||
|
private AchievmentManager()
|
||||||
|
{
|
||||||
|
definitionCache = new Dictionary<string, AchievmentDefinition>();
|
||||||
|
dataCache = new Dictionary<AchievmentDefinition, AchievmentData>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RegisterAchivment(AchievmentDefinition definition)
|
||||||
|
{
|
||||||
|
if (!definitionCache.ContainsKey(definition.Id))
|
||||||
|
{
|
||||||
|
definitionCache.Add(definition.Id, definition);
|
||||||
|
dataCache.Add(definition, definition.Construct());
|
||||||
|
}
|
||||||
|
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<IAchievmentCallbackReciever> initialCallbacks)
|
||||||
|
{
|
||||||
|
foreach (var callback in initialCallbacks)
|
||||||
|
{
|
||||||
|
AddCallbackReciever(callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddCallbackReciever(IAchievmentCallbackReciever callback)
|
||||||
|
{
|
||||||
|
AchievmentCompleted += callback.AchievmentCompleted;
|
||||||
|
AchievmentStateChanged += callback.AchievmentStateChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveCallbackReciever(IAchievmentCallbackReciever callback)
|
||||||
|
{
|
||||||
|
AchievmentCompleted -= callback.AchievmentCompleted;
|
||||||
|
AchievmentStateChanged -= callback.AchievmentStateChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Achievment Manipulation (Sets, Gets)
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns if an achivment at a given id is completed
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool IsCompleted(string id)
|
||||||
|
{
|
||||||
|
return GetAchievmentForId(id).IsCompleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Toggle
|
||||||
|
/// <summary>
|
||||||
|
/// Sets a <see cref="ToggleAchievmentData"/> as completed, after which sends <see cref="AchievmentStateChanged"/>, also if the achievment is completed sends a <see cref="AchievmentCompleted"/>. <br/>
|
||||||
|
/// If there is no achievment at a given id throws an <see cref="ApplicationException"/>. If achievment at a given id is of a wrong tupe throws an <see cref="ApplicationException"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="ToggleAchievmentDefinition"/>
|
||||||
|
public void SetToggleAchivment(string id)
|
||||||
|
{
|
||||||
|
ManipulateAchievment<ToggleAchievmentData>(id, (achievment) => achievment.CompletionState = true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a completion state from a <see cref="ToggleAchievmentData"/>.<br/>
|
||||||
|
/// If there is no achievment at a given id throws an <see cref="ApplicationException"/>. If achievment at a given id is of a wrong tupe throws an <see cref="ApplicationException"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="ToggleAchievmentDefinition"/>
|
||||||
|
public bool GetToggleState(string id)
|
||||||
|
{
|
||||||
|
return GetAchievmentForId<ToggleAchievmentData>(id).CompletionState;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Int
|
||||||
|
/// <summary>
|
||||||
|
/// Sets progress of a given <see cref="IntAchievmentData"/> to <paramref name="progress"/>, after which sends <see cref="AchievmentStateChanged"/>, also if the achievment is completed sends a <see cref="AchievmentCompleted"/>. <br/>
|
||||||
|
/// If there is no achievment at a given id throws an <see cref="ApplicationException"/>. If achievment at a given id is of a wrong tupe throws an <see cref="ApplicationException"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="IntAchievmentDefinition"/>
|
||||||
|
public void SetIntProgress(string id, int progress)
|
||||||
|
{
|
||||||
|
ManipulateAchievment<IntAchievmentData>(id, (achievment) => achievment.CurrentProgress = progress);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Changes progress of a given <see cref="IntAchievmentData"/> by <paramref name="delta"/>, after which sends <see cref="AchievmentStateChanged"/>, also if the achievment is completed sends a <see cref="AchievmentCompleted"/>. <br/>
|
||||||
|
/// If there is no achievment at a given id throws an <see cref="ApplicationException"/>. If achievment at a given id is of a wrong tupe throws an <see cref="ApplicationException"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="IntAchievmentDefinition"/>
|
||||||
|
public void CangeIntProgress(string id, int delta)
|
||||||
|
{
|
||||||
|
ManipulateAchievment<IntAchievmentData>(id, (achievment) => achievment.CurrentProgress += delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets current progress from a <see cref="IntAchievmentData"/>.<br/>
|
||||||
|
/// If there is no achievment at a given id throws an <see cref="ApplicationException"/>. If achievment at a given id is of a wrong tupe throws an <see cref="ApplicationException"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="ToggleAchievmentDefinition"/>
|
||||||
|
public int GetIntProgress(string id)
|
||||||
|
{
|
||||||
|
return GetAchievmentForId<IntAchievmentData>(id).CurrentProgress;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Float
|
||||||
|
/// <summary>
|
||||||
|
/// Sets progress of a given <see cref="FloatAchievmentData"/> to <paramref name="progress"/>, after which sends <see cref="AchievmentStateChanged"/>, also if the achievment is completed sends a <see cref="AchievmentCompleted"/>. <br/>
|
||||||
|
/// If there is no achievment at a given id throws an <see cref="ApplicationException"/>. If achievment at a given id is of a wrong tupe throws an <see cref="ApplicationException"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="FloatAchievmentDefinition"/>
|
||||||
|
public void SetFloatProgress(string id, float progress)
|
||||||
|
{
|
||||||
|
ManipulateAchievment<FloatAchievmentData>(id, (achievment) => achievment.CurrentProgress = progress);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Changes progress of a given <see cref="FloatAchievmentData"/> by <paramref name="delta"/>, after which sends <see cref="AchievmentStateChanged"/>, also if the achievment is completed sends a <see cref="AchievmentCompleted"/>. <br/>
|
||||||
|
/// If there is no achievment at a given id throws an <see cref="ApplicationException"/>. If achievment at a given id is of a wrong tupe throws an <see cref="ApplicationException"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="FloatAchievmentDefinition"/>
|
||||||
|
public void CangeFloatProgress(string id, float delta)
|
||||||
|
{
|
||||||
|
ManipulateAchievment<FloatAchievmentData>(id, (achievment) => achievment.CurrentProgress += delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets current progress from a <see cref="FloatAchievmentData"/>.<br/>
|
||||||
|
/// If there is no achievment at a given id throws an <see cref="ApplicationException"/>. If achievment at a given id is of a wrong tupe throws an <see cref="ApplicationException"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="FloatAchievmentDefinition"/>
|
||||||
|
public float GetFloatProgress(string id)
|
||||||
|
{
|
||||||
|
return GetAchievmentForId<FloatAchievmentData>(id).CurrentProgress;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns an achievment of type <typeparamref name="T"/> under <paramref name="id"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">Type of the achievment</typeparam>
|
||||||
|
/// <param name="id">Id of requested achievment</param>
|
||||||
|
/// <remarks>throws an <see cref="ApplicationException"/> if either there is no achievment under id or achievment under id is of a different type</remarks>
|
||||||
|
public T GetAchievmentForId<T>(string id) where T : AchievmentData
|
||||||
|
{
|
||||||
|
return CheckAchievmentType<T>(GetAchievmentForId(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns an achievment under <paramref name="id"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">Id of requested achievment</param>
|
||||||
|
/// <remarks>throws an <see cref="ApplicationException"/> if there is no achievment under id</remarks>
|
||||||
|
public AchievmentData GetAchievmentForId(string id)
|
||||||
|
{
|
||||||
|
var def = definitionCache.GetValueOrDefault(id);
|
||||||
|
if (def != null)
|
||||||
|
{
|
||||||
|
return dataCache[def];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new ApplicationException($"Invalid achivment id {id}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private T CheckAchievmentType<T>(AchievmentData data) where T : AchievmentData
|
||||||
|
{
|
||||||
|
if (data is not T convetred)
|
||||||
|
{
|
||||||
|
throw new ApplicationException($"Attempting to perform an operation on an invalid achievment type. Expected {typeof(T)} got {data.GetType()}");
|
||||||
|
}
|
||||||
|
return convetred;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <param name="id"></param>
|
||||||
|
/// <param name="manipulation">Action to perform on the achievment</param>
|
||||||
|
private void ManipulateAchievment<T>(string id, Action<T> manipulation) where T : AchievmentData
|
||||||
|
{
|
||||||
|
var data = GetAchievmentForId<T>(id);
|
||||||
|
|
||||||
|
if (CheckNotCompleted(data))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
manipulation(data);
|
||||||
|
|
||||||
|
SendUpdateCallbacks(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Helper method to print a warning if an achievment is already completed
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="data"></param>
|
||||||
|
/// <returns>Completion state</returns>
|
||||||
|
private bool CheckNotCompleted(AchievmentData data)
|
||||||
|
{
|
||||||
|
if (data.IsCompleted)
|
||||||
|
{
|
||||||
|
Debug.LogWarning($"Achievment already completed: {data.Achivment.Id}");
|
||||||
|
}
|
||||||
|
return data.IsCompleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SendUpdateCallbacks(AchievmentData data)
|
||||||
|
{
|
||||||
|
AchievmentStateChanged?.Invoke(data);
|
||||||
|
|
||||||
|
if (data.IsCompleted)
|
||||||
|
{
|
||||||
|
AchievmentCompleted?.Invoke(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 841f326ebfd59e646835bf81432d3ae4
|
guid: 7339f725e382e4b4bab7db6d7cc14b30
|
||||||
MonoImporter:
|
MonoImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 48ec3460d89c2f144827761002d7f4d9
|
guid: 79e626bf8b94e5f4d813912f9b1d304e
|
||||||
folderAsset: yes
|
folderAsset: yes
|
||||||
DefaultImporter:
|
DefaultImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
21
Achievments/AchievmentTypes/AchievmentData.cs
Normal file
21
Achievments/AchievmentTypes/AchievmentData.cs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace NEG.Utils.Achievments.AchievmentTypes
|
||||||
|
{
|
||||||
|
public abstract class AchievmentData
|
||||||
|
{
|
||||||
|
public AchievmentDefinition Achivment { get; private set; }
|
||||||
|
|
||||||
|
public abstract bool IsCompleted { get; }
|
||||||
|
|
||||||
|
public AchievmentData(AchievmentDefinition achivment)
|
||||||
|
{
|
||||||
|
Achivment = achivment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: fad96d35cce2d3e469d300e6e48a048a
|
guid: 1f39500a9deabad43b87bc76122646fc
|
||||||
MonoImporter:
|
MonoImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
15
Achievments/AchievmentTypes/AchievmentDefinition.cs
Normal file
15
Achievments/AchievmentTypes/AchievmentDefinition.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace NEG.Utils.Achievments.AchievmentTypes
|
||||||
|
{
|
||||||
|
public abstract class AchievmentDefinition : ScriptableObject
|
||||||
|
{
|
||||||
|
[field: SerializeField]
|
||||||
|
public string Id { get; private set; }
|
||||||
|
|
||||||
|
public abstract AchievmentData Construct();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: f9bd42dd58472044b8ecc0d69caa7da8
|
guid: 4aef60a6b4e41e243845a476862049e1
|
||||||
MonoImporter:
|
MonoImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
35
Achievments/AchievmentTypes/FloatAchievmentData.cs
Normal file
35
Achievments/AchievmentTypes/FloatAchievmentData.cs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace NEG.Utils.Achievments.AchievmentTypes
|
||||||
|
{
|
||||||
|
public class FloatAchievmentData : AchievmentData
|
||||||
|
{
|
||||||
|
public override bool IsCompleted => CurrentProgress >= Def.ProgressRequired;
|
||||||
|
|
||||||
|
public float CurrentProgress
|
||||||
|
{
|
||||||
|
get => currentProgress;
|
||||||
|
internal set
|
||||||
|
{
|
||||||
|
if (Def.Clamped)
|
||||||
|
{
|
||||||
|
value = Mathf.Max(value, Def.LowerBound);
|
||||||
|
}
|
||||||
|
currentProgress = Mathf.Min(value, Def.ProgressRequired);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public float ProgressLeft => Def.ProgressRequired - CurrentProgress;
|
||||||
|
|
||||||
|
private FloatAchievmentDefinition Def => (FloatAchievmentDefinition)Achivment;
|
||||||
|
|
||||||
|
private float currentProgress;
|
||||||
|
|
||||||
|
public FloatAchievmentData(FloatAchievmentDefinition def) : base(def)
|
||||||
|
{
|
||||||
|
currentProgress = def.InitialProgress;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Achievments/AchievmentTypes/FloatAchievmentData.cs.meta
Normal file
11
Achievments/AchievmentTypes/FloatAchievmentData.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 32572809c0644434d8e64878a3c22f0e
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
29
Achievments/AchievmentTypes/FloatAchievmentDefinition.cs
Normal file
29
Achievments/AchievmentTypes/FloatAchievmentDefinition.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace NEG.Utils.Achievments.AchievmentTypes
|
||||||
|
{
|
||||||
|
[CreateAssetMenu(menuName = "Achievments/Float Achievment")]
|
||||||
|
public class FloatAchievmentDefinition : AchievmentDefinition
|
||||||
|
{
|
||||||
|
[field: Tooltip("Amount of progress required for completion, required to be at leas 1, otherwise would be considered completed from the beginning")]
|
||||||
|
[field: Min(0)]
|
||||||
|
[field: SerializeField]
|
||||||
|
public float ProgressRequired { get; private set; } = 1;
|
||||||
|
|
||||||
|
[field: SerializeField]
|
||||||
|
public float InitialProgress { get; private set; } = 0;
|
||||||
|
|
||||||
|
[field: SerializeField]
|
||||||
|
public bool Clamped { get; private set; } = false;
|
||||||
|
|
||||||
|
public float LowerBound { get; private set; } = 0;
|
||||||
|
|
||||||
|
|
||||||
|
public override AchievmentData Construct()
|
||||||
|
{
|
||||||
|
return new FloatAchievmentData(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2d7270d5452c9b04ca07ef43a491a18d
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
36
Achievments/AchievmentTypes/IntAchievmentData.cs
Normal file
36
Achievments/AchievmentTypes/IntAchievmentData.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.Serialization.Formatters;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace NEG.Utils.Achievments.AchievmentTypes
|
||||||
|
{
|
||||||
|
public class IntAchievmentData : AchievmentData
|
||||||
|
{
|
||||||
|
public override bool IsCompleted => CurrentProgress >= Def.ProgressRequired;
|
||||||
|
|
||||||
|
public int CurrentProgress
|
||||||
|
{
|
||||||
|
get => currentProgress;
|
||||||
|
internal set
|
||||||
|
{
|
||||||
|
if (Def.Clamped)
|
||||||
|
{
|
||||||
|
value = Mathf.Max(value, Def.LowerBound);
|
||||||
|
}
|
||||||
|
currentProgress = Mathf.Min(value, Def.ProgressRequired);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int ProgressLeft => Def.ProgressRequired - CurrentProgress;
|
||||||
|
|
||||||
|
private IntAchievmentDefinition Def => (IntAchievmentDefinition)Achivment;
|
||||||
|
|
||||||
|
private int currentProgress;
|
||||||
|
|
||||||
|
public IntAchievmentData(IntAchievmentDefinition def) : base(def)
|
||||||
|
{
|
||||||
|
currentProgress = def.InitialProgress;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Achievments/AchievmentTypes/IntAchievmentData.cs.meta
Normal file
11
Achievments/AchievmentTypes/IntAchievmentData.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 0a121b6e6fa8ecc45ab4506c15e5f46e
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
27
Achievments/AchievmentTypes/IntAchievmentDefinition.cs
Normal file
27
Achievments/AchievmentTypes/IntAchievmentDefinition.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace NEG.Utils.Achievments.AchievmentTypes
|
||||||
|
{
|
||||||
|
[CreateAssetMenu(menuName = "Achievments/Int Achievment")]
|
||||||
|
public class IntAchievmentDefinition : AchievmentDefinition
|
||||||
|
{
|
||||||
|
[field: Tooltip("Amount of progress required for completion, required to be at leas 1, otherwise would be considered completed from the beginning")]
|
||||||
|
[field: SerializeField]
|
||||||
|
public int ProgressRequired { get; private set; } = 1;
|
||||||
|
|
||||||
|
[field: SerializeField]
|
||||||
|
public int InitialProgress { get; private set; } = 0;
|
||||||
|
|
||||||
|
[field: SerializeField]
|
||||||
|
public bool Clamped { get; private set; } = false;
|
||||||
|
|
||||||
|
public int LowerBound { get; private set; } = 0;
|
||||||
|
|
||||||
|
public override AchievmentData Construct()
|
||||||
|
{
|
||||||
|
return new IntAchievmentData(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Achievments/AchievmentTypes/IntAchievmentDefinition.cs.meta
Normal file
11
Achievments/AchievmentTypes/IntAchievmentDefinition.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 5318fea685aa56646a3310c38a9a9bac
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
18
Achievments/AchievmentTypes/ToggleAchievmentData.cs
Normal file
18
Achievments/AchievmentTypes/ToggleAchievmentData.cs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace NEG.Utils.Achievments.AchievmentTypes
|
||||||
|
{
|
||||||
|
public class ToggleAchievmentData : AchievmentData
|
||||||
|
{
|
||||||
|
public override bool IsCompleted => CompletionState;
|
||||||
|
|
||||||
|
public bool CompletionState { get; internal set; } = false;
|
||||||
|
|
||||||
|
public ToggleAchievmentData(ToggleAchievmentDefinition def) : base(def)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Achievments/AchievmentTypes/ToggleAchievmentData.cs.meta
Normal file
11
Achievments/AchievmentTypes/ToggleAchievmentData.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 1e0806da00902994f9aeb26d295956f0
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
15
Achievments/AchievmentTypes/ToggleAchievmentDefinition.cs
Normal file
15
Achievments/AchievmentTypes/ToggleAchievmentDefinition.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace NEG.Utils.Achievments.AchievmentTypes
|
||||||
|
{
|
||||||
|
[CreateAssetMenu(menuName = "Achievments/Toggle Achievment")]
|
||||||
|
public class ToggleAchievmentDefinition : AchievmentDefinition
|
||||||
|
{
|
||||||
|
public override AchievmentData Construct()
|
||||||
|
{
|
||||||
|
return new ToggleAchievmentData(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 608c7e921b8b16b42919fc6f55b67fcb
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -2,12 +2,14 @@ using System.Collections;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace NEG.Utils.Achivments
|
namespace NEG.Utils.Achievments
|
||||||
{
|
{
|
||||||
|
using AchievmentTypes;
|
||||||
|
|
||||||
[CreateAssetMenu(menuName = "Achivments/Collection")]
|
[CreateAssetMenu(menuName = "Achivments/Collection")]
|
||||||
public class AchivmentDefinitionCollection : ScriptableObject
|
public class AchivmentDefinitionCollection : ScriptableObject
|
||||||
{
|
{
|
||||||
[field: SerializeField]
|
[field: SerializeField]
|
||||||
public List<AchivmentDefinition> Achivments { get; private set; } = new List<AchivmentDefinition>();
|
public List<AchievmentDefinition> Achivments { get; private set; } = new List<AchievmentDefinition>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2,7 +2,7 @@ using System.Collections;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace NEG.Utils.Achivments
|
namespace NEG.Utils.Achievments
|
||||||
{
|
{
|
||||||
[CreateAssetMenu(menuName = "Achivments/BaseConfig")]
|
[CreateAssetMenu(menuName = "Achivments/BaseConfig")]
|
||||||
public class AchivmentManagerConfig : ScriptableObject, IAchivmentManagerConfig
|
public class AchivmentManagerConfig : ScriptableObject, IAchivmentManagerConfig
|
||||||
@ -12,12 +12,12 @@ namespace NEG.Utils.Achivments
|
|||||||
[field: SerializeField]
|
[field: SerializeField]
|
||||||
public string AchivmentCollectionAssetLabel { get; private set; } = DefaultAchivmentsCollectionLabel;
|
public string AchivmentCollectionAssetLabel { get; private set; } = DefaultAchivmentsCollectionLabel;
|
||||||
|
|
||||||
public void Apply(AchivmentManager.Builder builder)
|
public void Apply(AchievmentManager.Builder builder)
|
||||||
{
|
{
|
||||||
builder.WithLabeledDefinitions(AchivmentCollectionAssetLabel);
|
builder.WithLabeledDefinitions(AchivmentCollectionAssetLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ApplyLast(AchivmentManager.Builder builder)
|
public void ApplyLast(AchievmentManager.Builder builder)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
23
Achievments/IAchievmentCallbackReciever.cs
Normal file
23
Achievments/IAchievmentCallbackReciever.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace NEG.Utils.Achievments
|
||||||
|
{
|
||||||
|
using AchievmentTypes;
|
||||||
|
|
||||||
|
public interface IAchievmentCallbackReciever
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Called when an achivment is completed
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="achivment"></param>
|
||||||
|
void AchievmentCompleted(AchievmentData achivment);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when achivment progress changes
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="achivment"></param>
|
||||||
|
void AchievmentStateChanged(AchievmentData achivment);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,7 +2,7 @@ using System.Collections;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace NEG.Utils.Achivments
|
namespace NEG.Utils.Achievments
|
||||||
{
|
{
|
||||||
public interface IAchivmentManagerConfig
|
public interface IAchivmentManagerConfig
|
||||||
{
|
{
|
||||||
@ -10,12 +10,12 @@ namespace NEG.Utils.Achivments
|
|||||||
/// Used to Apply config data
|
/// Used to Apply config data
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="builder"></param>
|
/// <param name="builder"></param>
|
||||||
void Apply(AchivmentManager.Builder builder);
|
void Apply(AchievmentManager.Builder builder);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called after <see cref="Apply(AchivmentManager.Builder)"/> was called on every other config
|
/// Called after <see cref="Apply(AchievmentManager.Builder)"/> was called on every other config
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="builder"></param>
|
/// <param name="builder"></param>
|
||||||
void ApplyLast(AchivmentManager.Builder builder);
|
void ApplyLast(AchievmentManager.Builder builder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2,7 +2,7 @@ using System.Collections;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace NEG.Utils.Achivments
|
namespace NEG.Utils.Achievments
|
||||||
{
|
{
|
||||||
public interface IAchivmentStorage
|
public interface IAchivmentStorage
|
||||||
{
|
{
|
||||||
@ -1,22 +0,0 @@
|
|||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace NEG.Utils.Achivments
|
|
||||||
{
|
|
||||||
public class AchivmentData
|
|
||||||
{
|
|
||||||
public AchivmentDefinition Achivment { get; private set; }
|
|
||||||
|
|
||||||
public int ProgressLeft { get; internal set; }
|
|
||||||
|
|
||||||
public bool IsCompleted => ProgressLeft <= 0;
|
|
||||||
|
|
||||||
public AchivmentData(AchivmentDefinition achivment, int progressLeft)
|
|
||||||
{
|
|
||||||
Achivment = achivment;
|
|
||||||
ProgressLeft = progressLeft;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace NEG.Utils.Achivments
|
|
||||||
{
|
|
||||||
[CreateAssetMenu(menuName = "Achivments/AchivmentDefinition")]
|
|
||||||
public class AchivmentDefinition : ScriptableObject
|
|
||||||
{
|
|
||||||
public JToken AdditionalData
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
additionalData ??= JObject.Parse(additionalDataInitializer);
|
|
||||||
return additionalData;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[field: SerializeField]
|
|
||||||
public string Id { get; private set; }
|
|
||||||
|
|
||||||
[field: Tooltip("Amount of progress required for completion, required to be at leas 1, otherwise would be considered completed from the beginning")]
|
|
||||||
[field: Min(1)]
|
|
||||||
[field: SerializeField]
|
|
||||||
public int ProgressRequired { get; private set; } = 1;
|
|
||||||
|
|
||||||
[SerializeField]
|
|
||||||
[Tooltip("Temporary until json editor is a thing")]
|
|
||||||
private string additionalDataInitializer;
|
|
||||||
|
|
||||||
private JToken additionalData;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,193 +0,0 @@
|
|||||||
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}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace NEG.Utils.Achivments
|
|
||||||
{
|
|
||||||
public interface IAchivmentCallbackReciever
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Called when an achivment is completed
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="achivment"></param>
|
|
||||||
/// <param name="getState"></param>
|
|
||||||
void SetAchivment(AchivmentData achivment);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Called when achivment progress changes
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="achivment"></param>
|
|
||||||
/// <param name="progress">Current achivment progress, equal to <paramref name="achivment"/> <see cref="AchivmentDefinition.ProgressRequired"/> - <see cref="AchivmentData.ProgressLeft"/></param>
|
|
||||||
void SetAchivmentProgress(AchivmentData achivment, int progress);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user
Why need this, when all are empty
was needed in earlier version, i will remove it