using System; using UnityEngine; using static BulletHellTemplate.PlayerSave; namespace BulletHellTemplate { /// /// Manages daily rewards UI and claiming logic. /// Firebase calls are delegated to BackendManager for server saving, /// while local data is stored in PlayerSave. /// public class DayleRewardManager : MonoBehaviour { [Header("UI Prefabs and Containers")] [Tooltip("All daily reward items for each day.")] public RewardItem[] rewardItems; [Tooltip("Prefab used to display each reward entry.")] public RewardEntry rewardEntryPrefab; [Tooltip("Parent transform to hold all spawned reward entries.")] public Transform rewardsContainer; [Tooltip("Popup shown when a reward is claimed.")] public RewardPopup rewardPopup; private DailyRewardsData localDailyData; private int currentDayIndex; private string currentLang; /// /// Called when the object becomes enabled. /// Ensures data is loaded from Firebase if needed, /// then displays the local daily rewards data. /// private async void OnEnable() { currentLang = LanguageManager.LanguageManager.Instance.GetCurrentLanguage(); // Load daily rewards data from local storage localDailyData = PlayerSave.GetDailyRewardsLocal(); Debug.Log($"[DayleRewardManager] Now (local) = {DateTime.Now} / " + $"firstClaimDate (localDailyData) = {localDailyData.firstClaimDate} / " + $"(Now.Date - firstClaimDate.Date) = {(DateTime.Now.Date - localDailyData.firstClaimDate.Date).TotalDays}"); // Calculate how many days have passed since firstClaimDate TimeSpan timeSinceFirstClaim = DateTime.Now.Date - localDailyData.firstClaimDate.Date; currentDayIndex = (int)timeSinceFirstClaim.TotalDays; Debug.Log($"[DayleRewardManager] currentDayIndex = {currentDayIndex}"); // Check if user surpassed total daily rewards if (currentDayIndex >= rewardItems.Length) { currentDayIndex = rewardItems.Length - 1; } // Build UI DisplayRewards(); } /// /// Builds the UI for daily rewards, enabling claim when appropriate. /// private void DisplayRewards() { // Clear old entries if (rewardsContainer != null) { foreach (Transform child in rewardsContainer) { Destroy(child.gameObject); } } if (rewardItems == null || rewardItems.Length == 0) { Debug.LogWarning("No daily rewards configured."); return; } for (int i = 0; i < rewardItems.Length; i++) { RewardEntry entry = Instantiate(rewardEntryPrefab, rewardsContainer); entry.Setup( rewardItems[i].icon, rewardItems[i].title, rewardItems[i].description, $"Day {i + 1}", i + 1 ); // If already claimed if (localDailyData.claimedRewards.Contains(i)) { entry.SetClaimed(); } // If day index is within or equal to currentDayIndex, enable claim (if not claimed) else if (i <= currentDayIndex) { int dayIndex = i; entry.EnableClaimButton(() => ClaimReward(dayIndex)); } else { // Future days entry.SetLocked(); } } } /// /// Claims the specified daily reward day, /// then saves locally and on Firebase. /// private async void ClaimReward(int dayIndex) { // Already claimed? if (localDailyData.claimedRewards.Contains(dayIndex)) { Debug.LogWarning($"Reward for day {dayIndex + 1} is already claimed."); return; } // If it's a future day, do not allow if (dayIndex > currentDayIndex) { Debug.LogWarning($"Cannot claim day {dayIndex + 1} yet."); return; } // Add to claimed localDailyData.claimedRewards.Add(dayIndex); // Show popup RewardItem reward = rewardItems[dayIndex]; if (rewardPopup != null) { string titleTranslated = GetTranslatedString( reward.titleTranslated, reward.title, currentLang ); string descriptionTranslated = GetTranslatedString( reward.descriptionTranslated, reward.description, currentLang ); rewardPopup.Setup(reward.icon, titleTranslated, descriptionTranslated); } // Award in-game AwardReward(reward); // Save locally PlayerSave.SetDailyRewardsLocal(localDailyData); // Refresh UI DisplayRewards(); // Also save to Firebase await BackendManager.Singleton.SaveDailyRewardsDataAsync(localDailyData); } /// /// Gives the actual reward to the player, e.g. currency or items. /// private void AwardReward(RewardItem reward) { switch (reward.rewardType) { case RewardType.Currency: int currentAmount = MonetizationManager.GetCurrency(reward.currencyRewards[0].coinID); int newAmount = currentAmount + reward.amount; MonetizationManager.SetCurrency(reward.currencyRewards[0].coinID, newAmount); break; default: BattlePassItem tempPassItem = ScriptableObject.CreateInstance(); tempPassItem.passId = "Reward_" + reward.rewardId; tempPassItem.itemTitle = reward.title; tempPassItem.itemDescription = reward.description ?? "Reward from Daily Rewards."; tempPassItem.itemIcon = reward.icon; tempPassItem.rewardTier = BattlePassItem.RewardTier.Free; switch (reward.rewardType) { case RewardType.Icon: tempPassItem.rewardType = BattlePassItem.RewardType.IconReward; tempPassItem.iconReward = reward.iconRewards[0]; break; case RewardType.Frame: tempPassItem.rewardType = BattlePassItem.RewardType.FrameReward; tempPassItem.frameReward = reward.frameRewards[0]; break; case RewardType.Character: tempPassItem.rewardType = BattlePassItem.RewardType.CharacterReward; tempPassItem.characterData = new CharacterData[] { reward.characterRewards[0] }; break; case RewardType.InventoryItem: tempPassItem.rewardType = BattlePassItem.RewardType.InventoryItemReward; tempPassItem.inventoryItems = new InventoryItem[] { reward.inventoryItems[0] }; break; } MonetizationManager.Singleton.BattlePassUnlockItem(tempPassItem); break; } } /// /// Retrieves a translated string or returns the fallback if not found. /// public 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; } /// /// Retrieves a translated description string or returns the fallback if not found. /// public 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; } } }