403 lines
15 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using static BulletHellTemplate.PlayerSave;
namespace BulletHellTemplate
{
public class UIMainMenu : MonoBehaviour
{
[Header("UI Account")]
public TextMeshProUGUI playerName;
public Image playerIcon;
public Image playerFrame;
public TextMeshProUGUI accountLevel;
public TextMeshProUGUI accountcurrentExp;
public Image accountLevelProgressBar;
public Transform characterContainer;
public static UIMainMenu Singleton;
private int selectedCharacter;
private CharacterData characterData;
[Header("Battle Pass")]
public TextMeshProUGUI battlePassLevel;
public TextMeshProUGUI battlePassCurrentExp;
public Image battlePassProgressBar;
public GameObject hasRewardToClaim;
[Header("Character")]
public TextMeshProUGUI characterLevel;
public TextMeshProUGUI characterCurrentExp;
public Image characterProgressLevel;
public TextMeshProUGUI masteryLevelName;
public Image masteryIcon;
[Header("Daily Rewards")]
public TextMeshProUGUI nextDailyReward;
public GameObject canClaimDailyRewardObj;
public GameObject canClaimNewPlayerRewardObj;
private string currentLang;
private DailyRewardsData localDailyData;
private NewPlayerRewardsData localNewPlayerData;
private bool canClaimDaily; // cached flags
private bool canClaimNewPlayer;
private int currentDayIndex;
private bool allRewardsCollected;
private DateTime nextResetTime;
/// <summary>
/// Awake is called when the script Singleton is being loaded.
/// It initializes the Singleton.
/// </summary>
private void Awake()
{
Singleton = this;
currentLang = LanguageManager.LanguageManager.Instance.GetCurrentLanguage();
LanguageManager.LanguageManager.onLanguageChanged += UpdateCharacter;
}
/// <summary>
/// Refreshes reward flags every time.
/// </summary>
private void OnEnable()
{
localDailyData = PlayerSave.GetDailyRewardsLocal();
localNewPlayerData = PlayerSave.GetNewPlayerRewardsLocal();
if (localDailyData.firstClaimDate != DateTime.MinValue)
currentDayIndex = (int)(DateTime.Now.Date - localDailyData.firstClaimDate.Date).TotalDays;
else
currentDayIndex = 0;
nextResetTime = PlayerSave.GetNextDailyReset();
if (nextResetTime == DateTime.MinValue || nextResetTime <= DateTime.Now)
{
nextResetTime = DateTime.Now.Date.AddDays(1);
PlayerSave.SetNextDailyReset(nextResetTime);
}
EvaluateRewardFlags();
UpdateDailyRewardUI();
}
public void OnDestroy()
{
Singleton = null;
LanguageManager.LanguageManager.onLanguageChanged -= UpdateCharacter;
}
/// <summary>
/// Start is called before the first frame update.
/// </summary>
private void Start()
{
BackendManager.SetBackendInitialized();
LoadPlayerInfo();
canClaimDailyRewardObj.SetActive(false);
canClaimNewPlayerRewardObj.SetActive(false);
// Load local daily data once
localDailyData = PlayerSave.GetDailyRewardsLocal();
// Calculate current day index based on firstClaimDate
DateTime firstDate = localDailyData.firstClaimDate.Date;
currentDayIndex = (int)(DateTime.Now.Date - firstDate).TotalDays;
// Get the next daily reset time
nextResetTime = PlayerSave.GetNextDailyReset();
}
private void Update()
{
if (Time.frameCount % 30 == 0) EvaluateRewardFlags();
UpdateDailyRewardUI();
}
/// <summary>
/// Loads player information from PlayerSave and updates the UI elements.
/// Shows "MAX" if the account level is at maximum.
/// </summary>
public void LoadPlayerInfo()
{
// Get player name
string name = PlayerSave.GetPlayerName();
playerName.text = !string.IsNullOrEmpty(name) ? name : "Unknown Player";
// Account level and EXP
int _accountLevel = PlayerSave.GetAccountLevel();
int _currentAccountExp = PlayerSave.GetAccountCurrentExp();
int _expToNextLevel = GameInstance.Singleton.GetAccountExpForLevel(_accountLevel);
accountLevel.text = _accountLevel.ToString();
// Check if the account is at max level
int maxAccountLevel = GameInstance.Singleton.accountLevels.accountMaxLevel;
if (_accountLevel >= maxAccountLevel)
{
accountcurrentExp.text = "MAX";
accountLevelProgressBar.fillAmount = 1f;
}
else
{
accountcurrentExp.text = $"{_currentAccountExp}/{_expToNextLevel}";
accountLevelProgressBar.fillAmount = _expToNextLevel > 0
? (float)_currentAccountExp / _expToNextLevel
: 0f;
}
// Assign player icon
string iconId = PlayerSave.GetPlayerIcon();
foreach (IconItem item in GameInstance.Singleton.iconItems)
{
if (item.iconId == iconId)
{
playerIcon.sprite = item.icon;
break;
}
}
// Assign player frame
string frameId = PlayerSave.GetPlayerFrame();
foreach (FrameItem item in GameInstance.Singleton.frameItems)
{
if (item.frameId == frameId)
{
playerFrame.sprite = item.icon;
break;
}
}
// Battle Pass info
int currentPassLevel = BattlePassManager.Singleton.currentLevel;
int currentPassXP = BattlePassManager.Singleton.currentXP;
int xpForNextPassLevel = BattlePassManager.Singleton.xpForNextLevel;
battlePassLevel.text = currentPassLevel.ToString();
battlePassCurrentExp.text = currentPassXP + "/" + xpForNextPassLevel;
battlePassProgressBar.fillAmount = (float)currentPassXP / xpForNextPassLevel;
// Finally, load the selected character info
LoadCharacterInfo();
}
/// <summary>
/// Updates only the battle pass elements.
/// </summary>
public void UpdateBattlePassInfo()
{
int currentPassLevel = BattlePassManager.Singleton.currentLevel;
int currentPassXP = BattlePassManager.Singleton.currentXP;
int xpForNextPassLevel = BattlePassManager.Singleton.xpForNextLevel;
battlePassLevel.text = currentPassLevel.ToString();
battlePassCurrentExp.text = currentPassXP + "/" + xpForNextPassLevel;
battlePassProgressBar.fillAmount = (float)currentPassXP / xpForNextPassLevel;
}
/// <summary>
/// Loads character information and updates the character model.
/// </summary>
public void LoadCharacterInfo()
{
selectedCharacter = PlayerSave.GetSelectedCharacter();
UpdateCharacter();
}
/// <summary>
/// Updates the displayed character model based on the selected character and applied skin.
/// Shows "MAX" if the character is at max level.
/// </summary>
public void UpdateCharacter()
{
currentLang = LanguageManager.LanguageManager.Instance.GetCurrentLanguage();
// Clear previous character model
if (characterContainer != null)
{
for (int i = characterContainer.childCount - 1; i >= 0; i--)
{
Transform child = characterContainer.GetChild(i);
if (child != null)
Destroy(child.gameObject);
}
}
// Find the character data for the selected character
characterData = null;
foreach (CharacterData character in GameInstance.Singleton.characterData)
{
if (character.characterId == selectedCharacter)
{
characterData = character;
break;
}
}
if (characterContainer == null || characterData == null)
{
return;
}
// Retrieve the skin index from PlayerSave
int skinIndex = PlayerSave.GetCharacterSkin(selectedCharacter);
// Check if a valid skin is applied
if (characterData.characterSkins != null &&
characterData.characterSkins.Length > 0 &&
skinIndex >= 0 &&
skinIndex < characterData.characterSkins.Length)
{
CharacterSkin skin = characterData.characterSkins[skinIndex];
if (skin.skinCharacterModel != null)
{
Instantiate(skin.skinCharacterModel, characterContainer);
}
else if (characterData.characterModel != null)
{
Instantiate(characterData.characterModel, characterContainer);
}
}
else if (characterData.characterModel != null)
{
Instantiate(characterData.characterModel, characterContainer);
}
// Optional: update rotation or other logic
if (DragRotateAndHit.Singleton != null)
{
DragRotateAndHit.Singleton.UpdateCharacter();
}
// Get character level and current exp
int _chracterLevel = PlayerSave.GetCharacterLevel(selectedCharacter);
int _characterCurrentExp = PlayerSave.GetCharacterCurrentExp(selectedCharacter);
// Calculate required exp safely
int requiredExp = 0;
if (characterData.expPerLevel != null && _chracterLevel < characterData.expPerLevel.Length)
{
requiredExp = characterData.expPerLevel[_chracterLevel];
}
// Check if character is at max level
if (_chracterLevel >= characterData.maxLevel)
{
// Display MAX
characterLevel.text = _chracterLevel.ToString();
characterCurrentExp.text = "MAX";
characterProgressLevel.fillAmount = 1f;
}
else
{
characterLevel.text = _chracterLevel.ToString();
characterCurrentExp.text = $"{_characterCurrentExp}/{requiredExp}";
characterProgressLevel.fillAmount = requiredExp > 0
? (float)_characterCurrentExp / requiredExp
: 0f;
}
// Mastery level name and icon
int currentMasteryLevel = PlayerSave.GetCharacterMasteryLevel(selectedCharacter);
CharacterMasteryLevel masteryInfo = GameInstance.Singleton.GetMasteryLevel(currentMasteryLevel);
string masteryTranslatedName = GetTranslatedString(
masteryInfo.masteryNameTranslated,
masteryInfo.masteryName,
currentLang);
masteryLevelName.text = masteryTranslatedName;
if (masteryIcon != null)
masteryIcon.sprite = masteryInfo.masteryIcon;
}
/// <summary>
/// Changes the selected character and updates the UI accordingly.
/// </summary>
/// <param name="characterId">The ID of the new selected character.</param>
public void ChangeSelectedCharacter(int characterId)
{
LoadCharacterInfo();
}
private void EvaluateRewardFlags()
{
/* DAILY */
bool claimedToday = localDailyData.lastClaimDate != DateTime.MinValue &&
localDailyData.lastClaimDate.Date == DateTime.Now.Date;
bool notClaimedCurrentDay = !localDailyData.claimedRewards.Contains(currentDayIndex);
bool resetReached = (nextResetTime - DateTime.Now).TotalSeconds <= 0;
canClaimDaily = (!claimedToday && notClaimedCurrentDay) || resetReached;
/* NEWPLAYER */
int expectedIdx = localNewPlayerData.claimedRewards.Count;
int daysSinceJoin = localNewPlayerData.accountCreationDate != DateTime.MinValue
? (int)(DateTime.Now.Date - localNewPlayerData.accountCreationDate.Date).TotalDays
: int.MaxValue;
bool claimedNPtoday = localNewPlayerData.lastClaimDate != DateTime.MinValue &&
localNewPlayerData.lastClaimDate.Date == DateTime.Now.Date;
canClaimNewPlayer =
!claimedNPtoday &&
expectedIdx <= daysSinceJoin;
}
public void UpdateDailyRewardUI()
{
// Toggle buttons
canClaimDailyRewardObj.SetActive(canClaimDaily);
canClaimNewPlayerRewardObj.SetActive(canClaimNewPlayer);
if (canClaimDaily)
{
nextDailyReward.text = "Daily reward ready!";
return;
}
TimeSpan remaining = nextResetTime - DateTime.Now;
if (remaining.TotalSeconds < 0) remaining = TimeSpan.Zero;
nextDailyReward.text = string.Format(
"{0:D2}:{1:D2}:{2:D2}",
remaining.Hours,
remaining.Minutes,
remaining.Seconds
);
}
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;
}
public async void TestAddAccountExp()
{
var result = await BackendManager.Service.TestAddAccountExpAsync(200);
if (result.Success)
{
LoadPlayerInfo();
return;
}
Debug.LogError("Failed to add account exp");
}
}
}