259 lines
9.7 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
using static BulletHellTemplate.PlayerSave;
namespace BulletHellTemplate
{
/// <summary>
/// Manages the new-account rewards UI and claiming logic.
/// All Firebase calls have been moved to BackendManager for server saving,
/// and PlayerSave for local data storage.
/// </summary>
public class NewAccountRewardManager : MonoBehaviour
{
[Header("Rewards Configuration")]
[Tooltip("Rewards for new players, typically one per day.")]
public RewardItem[] rewardItems;
[Header("UI Elements")]
[Tooltip("Prefab for displaying each reward in the list.")]
public RewardEntry rewardEntryPrefab;
[Tooltip("Container to hold the reward entries.")]
public Transform rewardsContainer;
[Tooltip("Popup shown when a reward is claimed.")]
public RewardPopup rewardPopup;
[Header("Settings")]
[Tooltip("Total days the new player rewards are available.")]
public int totalRewardDays = 7;
private NewPlayerRewardsData localNewPlayerData;
private int currentDayIndex;
private string currentLang;
/// <summary>
/// Called when the GameObject becomes enabled and active.
/// Loads local new-player reward data and displays them.
/// </summary>
private void OnEnable()
{
// Retrieve the new-player reward data from local storage
localNewPlayerData = PlayerSave.GetNewPlayerRewardsLocal();
currentLang = LanguageManager.LanguageManager.Instance.GetCurrentLanguage();
// Calculate how many days since account creation
TimeSpan timeSinceCreation = DateTime.Now.Date - localNewPlayerData.accountCreationDate.Date;
currentDayIndex = (int)timeSinceCreation.TotalDays;
DisplayNewPlayerRewards();
}
/// <summary>
/// Displays the new player rewards in the UI, enabling claim where applicable.
/// </summary>
private void DisplayNewPlayerRewards()
{
// Clear existing entries
if (rewardsContainer != null)
{
foreach (Transform child in rewardsContainer)
{
Destroy(child.gameObject);
}
}
if (rewardItems == null || rewardItems.Length == 0)
{
Debug.LogWarning("No new player rewards are configured.");
return;
}
// Create entries for each reward day
for (int i = 0; i < rewardItems.Length; i++)
{
RewardEntry entry = Instantiate(rewardEntryPrefab, rewardsContainer);
// Translate reward title/description
string titleTranslated = GetTranslatedString(
rewardItems[i].titleTranslated,
rewardItems[i].title,
currentLang
);
string descriptionTranslated = GetTranslatedString(
rewardItems[i].descriptionTranslated,
rewardItems[i].description,
currentLang
);
// Setup the UI element
entry.Setup(
rewardItems[i].icon,
titleTranslated,
descriptionTranslated,
rewardItems[i].rewardId,
i + 1
);
// If already claimed
if (localNewPlayerData.claimedRewards.Contains(i))
{
entry.SetClaimed();
}
// If day index <= currentDayIndex and within totalRewardDays
else if (i <= currentDayIndex && i < totalRewardDays)
{
int dayIndex = i;
entry.EnableClaimButton(() => ClaimNewPlayerReward(dayIndex));
}
else
{
// Lock
entry.SetLocked();
}
}
}
/// <summary>
/// Claims a new player reward for the specified day and updates local + server data.
/// </summary>
private async void ClaimNewPlayerReward(int dayIndex)
{
// If already claimed
if (localNewPlayerData.claimedRewards.Contains(dayIndex))
{
Debug.LogWarning($"Reward for day {dayIndex + 1} has already been claimed.");
return;
}
// Ensure it's not a future day
if (dayIndex > currentDayIndex)
{
Debug.LogWarning($"Cannot claim reward for day {dayIndex + 1} yet.");
return;
}
// Mark as claimed
localNewPlayerData.claimedRewards.Add(dayIndex);
// Award the in-game reward
RewardItem reward = rewardItems[dayIndex];
AwardReward(reward);
// Optionally show a popup
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);
}
// Save locally
PlayerSave.SetNewPlayerRewardsLocal(localNewPlayerData);
// Refresh UI
DisplayNewPlayerRewards();
// Also save to server
await BackendManager.Singleton.SaveNewPlayerRewardsDataAsync(localNewPlayerData);
}
/// <summary>
/// Grants the reward to the player via MonetizationManager or other systems.
/// </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 New Player 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;
}
}
}