251 lines
9.4 KiB
C#
251 lines
9.4 KiB
C#
using System;
|
|
using UnityEngine;
|
|
using static BulletHellTemplate.PlayerSave;
|
|
|
|
namespace BulletHellTemplate
|
|
{
|
|
/// <summary>
|
|
/// Manages daily rewards UI and claiming logic.
|
|
/// Firebase calls are delegated to BackendManager for server saving,
|
|
/// while local data is stored in PlayerSave.
|
|
/// </summary>
|
|
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;
|
|
|
|
/// <summary>
|
|
/// Called when the object becomes enabled.
|
|
/// Ensures data is loaded from Firebase if needed,
|
|
/// then displays the local daily rewards data.
|
|
/// </summary>
|
|
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();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Builds the UI for daily rewards, enabling claim when appropriate.
|
|
/// </summary>
|
|
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();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Claims the specified daily reward day,
|
|
/// then saves locally and on Firebase.
|
|
/// </summary>
|
|
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);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gives the actual reward to the player, e.g. currency or items.
|
|
/// </summary>
|
|
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<BattlePassItem>();
|
|
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;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieves a translated string or returns the fallback if not found.
|
|
/// </summary>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieves a translated description string or returns the fallback if not found.
|
|
/// </summary>
|
|
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;
|
|
}
|
|
}
|
|
}
|