2025-09-19 14:56:58 +05:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using TMPro;
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
using static UnityEngine.EventSystems.EventTrigger;
|
|
|
|
|
|
|
|
|
|
namespace BulletHellTemplate
|
|
|
|
|
{
|
2025-09-19 19:43:49 +05:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Manages the maps UI menu, including loading standard and event maps.
|
|
|
|
|
/// Adapted for offline mode by completely removing Firebase dependencies.
|
|
|
|
|
/// </summary>
|
2025-09-19 14:56:58 +05:00
|
|
|
|
public class UIMapsMenu : MonoBehaviour
|
|
|
|
|
{
|
2025-09-19 19:43:49 +05:00
|
|
|
|
#region Map Entry Settings
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Prefab for standard map entries in the UI.
|
|
|
|
|
/// </summary>
|
2025-09-19 14:56:58 +05:00
|
|
|
|
[Tooltip("Prefab for standard map entries in the UI.")]
|
|
|
|
|
public MapEntry mapEntryPrefab;
|
2025-09-19 19:43:49 +05:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Container for standard map entries.
|
|
|
|
|
/// </summary>
|
2025-09-19 14:56:58 +05:00
|
|
|
|
[Tooltip("Container for standard map entries.")]
|
|
|
|
|
public Transform mapContainer;
|
|
|
|
|
|
2025-09-19 19:43:49 +05:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Prefab for event map entries in the UI.
|
|
|
|
|
/// </summary>
|
2025-09-19 14:56:58 +05:00
|
|
|
|
[Tooltip("Prefab for event map entries in the UI.")]
|
|
|
|
|
public MapEntry eventMapEntryPrefab;
|
2025-09-19 19:43:49 +05:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Container for event map entries.
|
|
|
|
|
/// </summary>
|
2025-09-19 14:56:58 +05:00
|
|
|
|
[Tooltip("Container for event map entries.")]
|
|
|
|
|
public Transform eventMapContainer;
|
|
|
|
|
|
2025-09-19 19:43:49 +05:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Event Map Settings
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Bypass Firebase check and display all event maps.
|
|
|
|
|
/// </summary>
|
2025-09-19 14:56:58 +05:00
|
|
|
|
[Tooltip("Bypass Firebase check and display all event maps")]
|
|
|
|
|
public bool alwaysShowEventMap;
|
|
|
|
|
|
2025-09-19 19:43:49 +05:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region UI Elements
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Text component for error messages.
|
|
|
|
|
/// </summary>
|
2025-09-19 14:56:58 +05:00
|
|
|
|
[Tooltip("Text component for error messages")]
|
|
|
|
|
public TextMeshProUGUI errorMessage;
|
|
|
|
|
|
2025-09-19 19:43:49 +05:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Difficulty label.
|
|
|
|
|
/// </summary>
|
2025-09-19 14:56:58 +05:00
|
|
|
|
public string difficulty = "Difficulty:";
|
2025-09-19 19:43:49 +05:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Translated difficulty labels.
|
|
|
|
|
/// </summary>
|
2025-09-19 14:56:58 +05:00
|
|
|
|
public NameTranslatedByLanguage[] difficultyTranslated;
|
2025-09-19 19:43:49 +05:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Fallback string for insufficient currency.
|
|
|
|
|
/// </summary>
|
2025-09-19 14:56:58 +05:00
|
|
|
|
public string insufficientCurrency = "Insufficient Tickets!";
|
2025-09-19 19:43:49 +05:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Translated messages for insufficient currency.
|
|
|
|
|
/// </summary>
|
2025-09-19 14:56:58 +05:00
|
|
|
|
public NameTranslatedByLanguage[] insufficientCurrencyTranslated;
|
|
|
|
|
|
2025-09-19 19:43:49 +05:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Private Variables
|
2025-09-19 14:56:58 +05:00
|
|
|
|
|
|
|
|
|
private List<MapEntry> mapEntries = new List<MapEntry>();
|
|
|
|
|
public static UIMapsMenu Singleton;
|
|
|
|
|
private string currentLang;
|
2025-09-19 19:43:49 +05:00
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Unity Callbacks
|
|
|
|
|
|
2025-09-19 14:56:58 +05:00
|
|
|
|
private void Awake()
|
|
|
|
|
{
|
|
|
|
|
if (Singleton == null)
|
|
|
|
|
{
|
|
|
|
|
Singleton = this;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2025-09-19 19:43:49 +05:00
|
|
|
|
Destroy(gameObject);
|
2025-09-19 14:56:58 +05:00
|
|
|
|
}
|
|
|
|
|
}
|
2025-09-19 19:43:49 +05:00
|
|
|
|
|
2025-09-19 14:56:58 +05:00
|
|
|
|
private void OnEnable()
|
|
|
|
|
{
|
|
|
|
|
currentLang = LanguageManager.LanguageManager.Instance.GetCurrentLanguage();
|
|
|
|
|
StartCoroutine(LoadMapsCoroutine());
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-19 19:43:49 +05:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Map Loading
|
2025-09-19 14:56:58 +05:00
|
|
|
|
|
2025-09-19 19:43:49 +05:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Coroutine that loads and processes map entries.
|
|
|
|
|
/// </summary>
|
2025-09-19 14:56:58 +05:00
|
|
|
|
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++)
|
|
|
|
|
{
|
2025-09-19 19:43:49 +05:00
|
|
|
|
MapInfoData current = allMaps[i];
|
2025-09-19 14:56:58 +05:00
|
|
|
|
|
2025-09-19 19:43:49 +05:00
|
|
|
|
if (!current.isEventMap)
|
2025-09-19 14:56:58 +05:00
|
|
|
|
{
|
2025-09-19 19:43:49 +05:00
|
|
|
|
CreateStandardMapEntry(current);
|
2025-09-19 14:56:58 +05:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2025-09-19 19:43:49 +05:00
|
|
|
|
yield return StartCoroutine(ProcessEventMap(current));
|
2025-09-19 14:56:58 +05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-19 19:43:49 +05:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Creates a standard map entry UI element.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="mapData">Map information data.</param>
|
|
|
|
|
/// <returns>The created map entry.</returns>
|
2025-09-19 14:56:58 +05:00
|
|
|
|
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);
|
2025-09-19 19:43:49 +05:00
|
|
|
|
string difficultyTranslatedStr = GetTranslatedString(difficultyTranslated, difficulty, currentLang);
|
|
|
|
|
entry.Setup(mapData, mapNameTranslated, mapDescriptionTranslated, difficultyTranslatedStr, IsMapUnlocked(mapData));
|
2025-09-19 14:56:58 +05:00
|
|
|
|
mapEntries.Add(entry);
|
|
|
|
|
return entry;
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-19 19:43:49 +05:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Processes event map entries.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="mapData">Map information data for event map.</param>
|
2025-09-19 14:56:58 +05:00
|
|
|
|
private IEnumerator ProcessEventMap(MapInfoData mapData)
|
|
|
|
|
{
|
|
|
|
|
bool shouldDisplay = alwaysShowEventMap;
|
|
|
|
|
|
|
|
|
|
if (shouldDisplay)
|
|
|
|
|
{
|
|
|
|
|
MapEntry eventEntry = Instantiate(eventMapEntryPrefab, eventMapContainer);
|
|
|
|
|
string mapNameTranslated = GetTranslatedString(mapData.mapNameTranslated, mapData.mapName, currentLang);
|
|
|
|
|
string mapDescriptionTranslated = GetTranslatedString(mapData.mapDescriptionTranslated, mapData.mapDescription, currentLang);
|
2025-09-19 19:43:49 +05:00
|
|
|
|
string difficultyTranslatedStr = GetTranslatedString(difficultyTranslated, difficulty, currentLang);
|
|
|
|
|
eventEntry.Setup(mapData, mapNameTranslated, mapDescriptionTranslated, difficultyTranslatedStr, IsMapUnlocked(mapData));
|
2025-09-19 14:56:58 +05:00
|
|
|
|
mapEntries.Add(eventEntry);
|
|
|
|
|
}
|
2025-09-19 19:43:49 +05:00
|
|
|
|
yield return null;
|
2025-09-19 14:56:58 +05:00
|
|
|
|
}
|
|
|
|
|
|
2025-09-19 19:43:49 +05:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Clears all map entries from the UI containers.
|
|
|
|
|
/// </summary>
|
|
|
|
|
private void ClearMapEntries()
|
2025-09-19 14:56:58 +05:00
|
|
|
|
{
|
2025-09-19 19:43:49 +05:00
|
|
|
|
foreach (Transform child in mapContainer)
|
|
|
|
|
Destroy(child.gameObject);
|
|
|
|
|
foreach (Transform child in eventMapContainer)
|
|
|
|
|
Destroy(child.gameObject);
|
|
|
|
|
mapEntries.Clear();
|
2025-09-19 14:56:58 +05:00
|
|
|
|
}
|
|
|
|
|
|
2025-09-19 19:43:49 +05:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Reloads the map entries.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public void ReloadMaps()
|
2025-09-19 14:56:58 +05:00
|
|
|
|
{
|
2025-09-19 19:43:49 +05:00
|
|
|
|
StartCoroutine(LoadMapsCoroutine());
|
2025-09-19 14:56:58 +05:00
|
|
|
|
}
|
|
|
|
|
|
2025-09-19 19:43:49 +05:00
|
|
|
|
#endregion
|
2025-09-19 14:56:58 +05:00
|
|
|
|
|
2025-09-19 19:43:49 +05:00
|
|
|
|
#region Map Unlocking and Translation
|
2025-09-19 14:56:58 +05:00
|
|
|
|
|
2025-09-19 19:43:49 +05:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Determines if a map is unlocked.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="mapData">Map information data.</param>
|
|
|
|
|
/// <returns>True if unlocked; otherwise, false.</returns>
|
|
|
|
|
/// <summary>Retorna true se o mapa estiver jog<6F>vel.</summary>
|
|
|
|
|
private bool IsMapUnlocked(MapInfoData mapData)
|
2025-09-19 14:56:58 +05:00
|
|
|
|
{
|
2025-09-19 19:43:49 +05:00
|
|
|
|
if (mapData.isUnlocked) return true;
|
|
|
|
|
if (PlayerSave.GetUnlockedMaps().Contains(mapData.mapId)) return true;
|
|
|
|
|
|
|
|
|
|
foreach (var m in GameInstance.Singleton.mapInfoData)
|
|
|
|
|
{
|
|
|
|
|
if (m.isEventMap) continue;
|
|
|
|
|
return m.mapId == mapData.mapId;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
2025-09-19 14:56:58 +05:00
|
|
|
|
}
|
|
|
|
|
|
2025-09-19 19:43:49 +05:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Retrieves a translated string based on the current language.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="translations">Array of translations.</param>
|
|
|
|
|
/// <param name="fallback">Fallback string if no translation is found.</param>
|
|
|
|
|
/// <param name="currentLang">Current language ID.</param>
|
|
|
|
|
/// <returns>Translated string.</returns>
|
2025-09-19 14:56:58 +05:00
|
|
|
|
private string GetTranslatedString(NameTranslatedByLanguage[] translations, string fallback, string currentLang)
|
|
|
|
|
{
|
|
|
|
|
if (translations != null)
|
|
|
|
|
{
|
|
|
|
|
foreach (var trans in translations)
|
|
|
|
|
{
|
2025-09-19 19:43:49 +05:00
|
|
|
|
if (!string.IsNullOrEmpty(trans.LanguageId) &&
|
|
|
|
|
trans.LanguageId.Equals(currentLang) &&
|
|
|
|
|
!string.IsNullOrEmpty(trans.Translate))
|
2025-09-19 14:56:58 +05:00
|
|
|
|
{
|
|
|
|
|
return trans.Translate;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return fallback;
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-19 19:43:49 +05:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Retrieves a translated string for map descriptions based on the current language.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="translations">Array of description translations.</param>
|
|
|
|
|
/// <param name="fallback">Fallback description if no translation is found.</param>
|
|
|
|
|
/// <param name="currentLang">Current language ID.</param>
|
|
|
|
|
/// <returns>Translated description.</returns>
|
2025-09-19 14:56:58 +05:00
|
|
|
|
private string GetTranslatedString(DescriptionTranslatedByLanguage[] translations, string fallback, string currentLang)
|
|
|
|
|
{
|
|
|
|
|
if (translations != null)
|
|
|
|
|
{
|
|
|
|
|
foreach (var trans in translations)
|
|
|
|
|
{
|
2025-09-19 19:43:49 +05:00
|
|
|
|
if (!string.IsNullOrEmpty(trans.LanguageId) &&
|
|
|
|
|
trans.LanguageId.Equals(currentLang) &&
|
|
|
|
|
!string.IsNullOrEmpty(trans.Translate))
|
2025-09-19 14:56:58 +05:00
|
|
|
|
{
|
|
|
|
|
return trans.Translate;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return fallback;
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-19 19:43:49 +05:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Error Display
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Displays an error message for a specified duration.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="duration">Duration in seconds to display the error message.</param>
|
|
|
|
|
/// <returns>IEnumerator for coroutine.</returns>
|
2025-09-19 14:56:58 +05:00
|
|
|
|
public IEnumerator ShowErrorMessage(float duration)
|
|
|
|
|
{
|
|
|
|
|
string errorTranslated = GetTranslatedString(insufficientCurrencyTranslated, insufficientCurrency, currentLang);
|
|
|
|
|
errorMessage.text = errorTranslated;
|
|
|
|
|
yield return new WaitForSeconds(duration);
|
|
|
|
|
errorMessage.text = "";
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-19 19:43:49 +05:00
|
|
|
|
#endregion
|
2025-09-19 14:56:58 +05:00
|
|
|
|
}
|
2025-09-19 19:43:49 +05:00
|
|
|
|
}
|