266 lines
9.2 KiB
C#
266 lines
9.2 KiB
C#
using Firebase.Auth;
|
|
using Firebase.Extensions;
|
|
using Firebase.Firestore;
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using TMPro;
|
|
using UnityEngine;
|
|
using static UnityEngine.EventSystems.EventTrigger;
|
|
|
|
namespace BulletHellTemplate
|
|
{
|
|
public class UIMapsMenu : MonoBehaviour
|
|
{
|
|
[Header("Map Entry Prefabs")]
|
|
[Tooltip("Prefab for standard map entries in the UI.")]
|
|
public MapEntry mapEntryPrefab;
|
|
[Tooltip("Container for standard map entries.")]
|
|
public Transform mapContainer;
|
|
|
|
[Header("Map Entry Events")]
|
|
[Tooltip("Prefab for event map entries in the UI.")]
|
|
public MapEntry eventMapEntryPrefab;
|
|
[Tooltip("Container for event map entries.")]
|
|
public Transform eventMapContainer;
|
|
|
|
[Header("Event Map Settings")]
|
|
[Tooltip("Bypass Firebase check and display all event maps")]
|
|
public bool alwaysShowEventMap;
|
|
|
|
[Header("UI Elements")]
|
|
[Tooltip("Text component for error messages")]
|
|
public TextMeshProUGUI errorMessage;
|
|
|
|
|
|
public string difficulty = "Difficulty:";
|
|
public NameTranslatedByLanguage[] difficultyTranslated;
|
|
public string insufficientCurrency = "Insufficient Tickets!";
|
|
public NameTranslatedByLanguage[] insufficientCurrencyTranslated;
|
|
|
|
[Header("Firebase References")]
|
|
private FirebaseFirestore firestore;
|
|
private FirebaseAuth auth;
|
|
|
|
private List<MapEntry> mapEntries = new List<MapEntry>();
|
|
public static UIMapsMenu Singleton;
|
|
private string currentLang;
|
|
private void Awake()
|
|
{
|
|
if (Singleton == null)
|
|
{
|
|
Singleton = this;
|
|
InitializeFirebase();
|
|
}
|
|
else
|
|
{
|
|
Destroy(gameObject);
|
|
}
|
|
}
|
|
private void OnEnable()
|
|
{
|
|
currentLang = LanguageManager.LanguageManager.Instance.GetCurrentLanguage();
|
|
StartCoroutine(LoadMapsCoroutine());
|
|
}
|
|
|
|
private void InitializeFirebase()
|
|
{
|
|
try
|
|
{
|
|
auth = FirebaseAuth.DefaultInstance;
|
|
firestore = FirebaseFirestore.DefaultInstance;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Debug.LogError($"Firebase initialization failed: {e.Message}");
|
|
}
|
|
}
|
|
|
|
private IEnumerator LoadMapsCoroutine()
|
|
{
|
|
ClearMapEntries();
|
|
|
|
if (GameInstance.Singleton == null || GameInstance.Singleton.mapInfoData == null)
|
|
{
|
|
Debug.LogError("Missing GameInstance or map data");
|
|
yield break;
|
|
}
|
|
|
|
List<MapInfoData> allMaps = new List<MapInfoData>(GameInstance.Singleton.mapInfoData);
|
|
|
|
for (int i = 0; i < allMaps.Count; i++)
|
|
{
|
|
MapInfoData currentMap = allMaps[i];
|
|
|
|
// Handle regular maps
|
|
if (!currentMap.isEventMap)
|
|
{
|
|
MapEntry newEntry = CreateStandardMapEntry(currentMap);
|
|
ProcessMapUnlockRules(currentMap, i, allMaps);
|
|
}
|
|
// Handle event maps
|
|
else
|
|
{
|
|
yield return StartCoroutine(ProcessEventMap(currentMap));
|
|
}
|
|
}
|
|
}
|
|
|
|
private MapEntry CreateStandardMapEntry(MapInfoData mapData)
|
|
{
|
|
MapEntry entry = Instantiate(mapEntryPrefab, mapContainer);
|
|
string mapNameTranslated = GetTranslatedString(mapData.mapNameTranslated, mapData.mapName, currentLang);
|
|
string mapDescriptionTranslated = GetTranslatedString(mapData.mapDescriptionTranslated, mapData.mapDescription, currentLang);
|
|
string _difficultyTranslated = GetTranslatedString(difficultyTranslated,difficulty, currentLang);
|
|
entry.Setup(mapData,mapNameTranslated,mapDescriptionTranslated,_difficultyTranslated, IsMapUnlocked(mapData));
|
|
mapEntries.Add(entry);
|
|
return entry;
|
|
}
|
|
|
|
private IEnumerator ProcessEventMap(MapInfoData mapData)
|
|
{
|
|
bool shouldDisplay = alwaysShowEventMap;
|
|
|
|
if (!alwaysShowEventMap)
|
|
{
|
|
var firebaseTask = GetEventMapStatus(mapData.eventIdName);
|
|
yield return new WaitUntil(() => firebaseTask.IsCompleted);
|
|
|
|
if (firebaseTask.Result != null &&
|
|
firebaseTask.Result.ContainsKey("active") &&
|
|
(bool)firebaseTask.Result["active"])
|
|
{
|
|
shouldDisplay = true;
|
|
}
|
|
}
|
|
|
|
if (shouldDisplay)
|
|
{
|
|
MapEntry eventEntry = Instantiate(eventMapEntryPrefab, eventMapContainer);
|
|
string mapNameTranslated = GetTranslatedString(mapData.mapNameTranslated, mapData.mapName, currentLang);
|
|
string mapDescriptionTranslated = GetTranslatedString(mapData.mapDescriptionTranslated, mapData.mapDescription, currentLang);
|
|
string _difficultyTranslated = GetTranslatedString(difficultyTranslated, difficulty, currentLang);
|
|
eventEntry.Setup(mapData, mapNameTranslated, mapDescriptionTranslated, _difficultyTranslated, IsMapUnlocked(mapData));
|
|
mapEntries.Add(eventEntry);
|
|
}
|
|
}
|
|
|
|
|
|
private void ProcessMapUnlockRules(MapInfoData currentMap, int index, List<MapInfoData> allMaps)
|
|
{
|
|
bool isUnlocked = IsMapUnlocked(currentMap);
|
|
|
|
if (isUnlocked &&
|
|
currentMap.isNeedCurrency &&
|
|
currentMap.canIgnoreMap &&
|
|
index < allMaps.Count - 1)
|
|
{
|
|
MapInfoData nextMap = allMaps[index + 1];
|
|
if (!IsMapUnlocked(nextMap))
|
|
{
|
|
UnlockMap(nextMap.mapId);
|
|
}
|
|
}
|
|
}
|
|
|
|
private bool IsMapUnlocked(MapInfoData mapData)
|
|
{
|
|
return mapData.isUnlocked || PlayerSave.GetUnlockedMaps().Contains(mapData.mapId);
|
|
}
|
|
|
|
private void UnlockMap(int mapId)
|
|
{
|
|
List<int> unlocked = PlayerSave.GetUnlockedMaps();
|
|
if (!unlocked.Contains(mapId))
|
|
{
|
|
unlocked.Add(mapId);
|
|
PlayerSave.SetUnlockedMaps(unlocked);
|
|
}
|
|
}
|
|
|
|
private void ClearMapEntries()
|
|
{
|
|
foreach (Transform child in mapContainer) Destroy(child.gameObject);
|
|
foreach (Transform child in eventMapContainer) Destroy(child.gameObject);
|
|
mapEntries.Clear();
|
|
}
|
|
|
|
public void ReloadMaps()
|
|
{
|
|
StartCoroutine(LoadMapsCoroutine());
|
|
}
|
|
|
|
private string GetTranslatedString(NameTranslatedByLanguage[] translations, string fallback, string currentLang)
|
|
{
|
|
if (translations != null)
|
|
{
|
|
foreach (var trans in translations)
|
|
{
|
|
if (!string.IsNullOrEmpty(trans.LanguageId)
|
|
&& trans.LanguageId.Equals(currentLang)
|
|
&& !string.IsNullOrEmpty(trans.Translate))
|
|
{
|
|
return trans.Translate;
|
|
}
|
|
}
|
|
}
|
|
return fallback;
|
|
}
|
|
|
|
private string GetTranslatedString(DescriptionTranslatedByLanguage[] translations, string fallback, string currentLang)
|
|
{
|
|
if (translations != null)
|
|
{
|
|
foreach (var trans in translations)
|
|
{
|
|
if (!string.IsNullOrEmpty(trans.LanguageId)
|
|
&& trans.LanguageId.Equals(currentLang)
|
|
&& !string.IsNullOrEmpty(trans.Translate))
|
|
{
|
|
return trans.Translate;
|
|
}
|
|
}
|
|
}
|
|
return fallback;
|
|
}
|
|
|
|
public IEnumerator ShowErrorMessage(float duration)
|
|
{
|
|
string errorTranslated = GetTranslatedString(insufficientCurrencyTranslated, insufficientCurrency, currentLang);
|
|
errorMessage.text = errorTranslated;
|
|
yield return new WaitForSeconds(duration);
|
|
errorMessage.text = "";
|
|
}
|
|
|
|
public Task<Dictionary<string, object>> GetEventMapStatus(string eventId)
|
|
{
|
|
var tcs = new TaskCompletionSource<Dictionary<string, object>>();
|
|
|
|
if (firestore == null)
|
|
{
|
|
Debug.LogError("Firestore not initialized!");
|
|
tcs.SetResult(null);
|
|
return tcs.Task;
|
|
}
|
|
|
|
firestore.Collection("EventMaps").Document(eventId).GetSnapshotAsync()
|
|
.ContinueWithOnMainThread(task =>
|
|
{
|
|
if (task.IsFaulted)
|
|
{
|
|
Debug.LogError($"Event map check error: {task.Exception}");
|
|
tcs.SetResult(null);
|
|
return;
|
|
}
|
|
|
|
DocumentSnapshot snapshot = task.Result;
|
|
tcs.SetResult(snapshot.Exists ? snapshot.ToDictionary() : null);
|
|
});
|
|
|
|
return tcs.Task;
|
|
}
|
|
|
|
|
|
}
|
|
} |