MIF_E31221357/Assets/Scripts/LevelControl.cs

170 lines
4.9 KiB
C#

using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using System;
public class LevelControl : MonoBehaviour
{
[System.Serializable]
public class MateriLevelPair
{
public string materiName;
public List<string> levelNames;
}
public static LevelControl Instance;
public List<string> levelSceneNames;
public string currentMateriName;
public List<MateriLevelPair> materiLevelPairs;
private Dictionary<string, List<string>> materiToLevels = new Dictionary<string, List<string>>();
private Dictionary<string, int> cachedUnlockedLevels = new Dictionary<string, int>();
private void Awake()
{
if (Instance == null)
{
Instance = this;
DontDestroyOnLoad(gameObject);
BuildMateriDictionary();
}
else
{
Destroy(gameObject);
}
}
private void BuildMateriDictionary()
{
materiToLevels.Clear();
foreach (var pair in materiLevelPairs)
{
if (!materiToLevels.ContainsKey(pair.materiName))
{
materiToLevels[pair.materiName] = new List<string>(pair.levelNames);
}
}
}
/// <summary>
/// Dipanggil dari InputUserController setelah login berhasil
/// </summary>
public void LoadLevelsFromFirebase(string kodeLogin)
{
StartCoroutine(LoadAllProgressFromFirebase(kodeLogin));
}
private IEnumerator LoadAllProgressFromFirebase(string kodeLogin)
{
cachedUnlockedLevels.Clear();
foreach (var materi in materiToLevels.Keys)
{
bool done = false;
DBManager.LoadLevelProgress(kodeLogin, materi, (progress) =>
{
if (progress <= 0)
progress = 1;
cachedUnlockedLevels[materi] = progress;
done = true;
});
yield return new WaitUntil(() => done);
}
Debug.Log($"[LevelControl] Semua progress level dari Firebase telah dimuat.");
}
public string NextLevel(string currentScene)
{
string currentMateri = GetMateriByLevel(currentScene);
if (string.IsNullOrEmpty(currentMateri)) return null;
if (materiToLevels.TryGetValue(currentMateri, out List<string> levels))
{
int index = levels.IndexOf(currentScene);
if (index >= 0 && index < levels.Count - 1)
{
return levels[index + 1];
}
}
return null;
}
public void UnlockedNewLevel()
{
string currentScene = SceneManager.GetActiveScene().name;
string currentMateri = GetMateriByLevel(currentScene);
if (string.IsNullOrEmpty(currentMateri)) return;
if (materiToLevels.TryGetValue(currentMateri, out List<string> levels))
{
int index = levels.IndexOf(currentScene);
if (index >= 0 && index < levels.Count - 1)
{
string kodeLogin = TestManager.Instance?.kodeLogin ?? "default";
int currentUnlocked = GetUnlockedLevel(currentMateri);
if (currentUnlocked <= index + 1)
{
DBManager.SaveUnlockedLevel(kodeLogin, currentMateri, index + 2);
cachedUnlockedLevels[currentMateri] = index + 2;
Debug.Log($"[LevelControl] Level {index + 2} unlocked untuk {kodeLogin} pada materi {currentMateri}");
}
}
}
}
public int GetUnlockedLevel(string materiName = null)
{
if (materiName == null) materiName = currentMateriName;
if (cachedUnlockedLevels.TryGetValue(materiName, out int unlocked))
return unlocked;
return 1;
}
public string GetMateriByLevel(string levelName)
{
foreach (var pair in materiToLevels)
{
if (pair.Value.Contains(levelName))
return pair.Key;
}
return null;
}
public bool IsLastLevelOfMateri(string levelName)
{
string materi = GetMateriByLevel(levelName);
if (materi == null) return false;
List<string> levels = materiToLevels[materi];
int index = levels.FindIndex(l => l.Trim().Equals(levelName.Trim(), StringComparison.OrdinalIgnoreCase));
return index == levels.Count - 1;
}
public List<string> GetLevelsInMateri(string materiName)
{
if (materiToLevels.ContainsKey(materiName))
return materiToLevels[materiName];
return new List<string>();
}
public bool AllLevelUnlocked(string materiName)
{
if (!materiToLevels.ContainsKey(materiName)) return false;
int unlocked = GetUnlockedLevel(materiName);
int totalLevel = materiToLevels[materiName].Count;
return unlocked >= totalLevel;
}
}