using System.Collections; using System.Collections.Generic; using UnityEngine; using Sirenix.OdinInspector; using KairoEngine.Statistics; using KairoEngine.Core; using UniRx; using StatisticsSystem = KairoEngine.Statistics.Statistics; namespace KairoEngine.Achievements { [HideMonoScript] public class AchievementsController : SerializedMonoBehaviour { public string achievementUnlockedEvent = "AchievementUnlockedEvent"; public string achievementLockedEvent = "AchievementLockedEvent"; public string achievementOverrideEvent = "AchievementOverrideEvent"; public bool CheckOnStart = true; public bool checkOnInterval = true; [ShowIf("@checkOnInterval"), SuffixLabel("ms")] public int checkInterval = 1000; [SuffixLabel("ms")] public int startDelay = 0; public bool debug = false; [ShowIf("@!initialized")] public AchievementsLibrary library; [ShowIf("@initialized"), System.NonSerialized, ShowInInspector, HideReferenceObjectPicker] [ListDrawerSettings(IsReadOnly = true, DraggableItems = false, Expanded = true, ShowIndexLabels = false, ShowPaging = false, ShowItemCount = true, HideRemoveButton = true)] public List achievementsStatus; private bool initialized = false; private CompositeDisposable timerComposite; private void Start() { if(debug) Debug.Log("Initializing AchievementsController"); if(StatisticsSystem.instance == null) Debug.LogError("Missing Statistics component"); if(library == null) { Debug.LogError("Missing Achievements Library on AchievementsController.\nPlease configure the Achievements module in the GameConfig file."); return; } achievementsStatus = new List(); for (int i = 0; i < library.achievements.Count; i++) { int value = PlayerPrefs.GetInt($"ACHIEVEMENT_{library.achievements[i].identifier}", 0); achievementsStatus.Add(new AchievementStatus(library.achievements[i], value == 0 ? false : true)); PlayerPrefs.SetInt($"ACHIEVEMENT_{library.achievements[i].identifier}", value); } if(initialized == false) initialized = true; Timer.ExecuteRealTime(startDelay, () => { if(CheckOnStart) CheckAchievements(); if(checkOnInterval) StartCheckTimer(); }); GenericEvents.StartListening("UnlockAchievement", UnlockAchievement); GenericEvents.StartListening("LockAchievement", LockAchievement); GenericEvents.StartListening(achievementOverrideEvent, ChangeAchievement); } private void OnDestroy() { if (timerComposite != null) timerComposite.Dispose(); } public void ChangeAchievement(string identifier, bool unlock) { if(unlock) UnlockAchievement(identifier); else LockAchievement(identifier); } public void CheckAchievements() { //if(debug) Debug.Log($"Checking achievements ({achievementsStatus.Count})"); if(library == null) return; for (int i = 0; i < achievementsStatus.Count; i++) { if(achievementsStatus[i].unlocked == true) continue; if(achievementsStatus[i].achievement.HasAchieved()) { Debug.Log($"Achievement Unlocked: {achievementsStatus[i].achievement.title}"); achievementsStatus[i].unlocked = true; GenericEvents.Trigger(achievementUnlockedEvent, achievementsStatus[i].achievement.identifier); PlayerPrefs.SetInt($"ACHIEVEMENT_{achievementsStatus[i].achievement.identifier}", 1); } } } public void StartCheckTimer() { timerComposite = Timer.ExecuteRealTime(checkInterval, () => { if(checkOnInterval) { CheckAchievements(); StartCheckTimer(); } }); } public void UnlockAchievement(string identifier) { if(library == null) return; for (int i = 0; i < achievementsStatus.Count; i++) { if(achievementsStatus[i].achievement.identifier == identifier) { if(achievementsStatus[i].unlocked == true) return; if(debug) Debug.Log($"Unlocking achievement {identifier}"); achievementsStatus[i].unlocked = true; GenericEvents.Trigger(achievementUnlockedEvent, achievementsStatus[i].achievement.identifier); PlayerPrefs.SetInt($"ACHIEVEMENT_{achievementsStatus[i].achievement.identifier}", 1); } } } public void LockAchievement(string identifier) { if(library == null) return; for (int i = 0; i < achievementsStatus.Count; i++) { if(achievementsStatus[i].achievement.identifier == identifier) { if(achievementsStatus[i].unlocked == false) return; if(debug) Debug.Log($"Locking achievement {identifier}"); achievementsStatus[i].unlocked = false; GenericEvents.Trigger(achievementLockedEvent, achievementsStatus[i].achievement.identifier); PlayerPrefs.SetInt($"ACHIEVEMENT_{achievementsStatus[i].achievement.identifier}", 0); } } } } }