460 lines
13 KiB
C#
460 lines
13 KiB
C#
using System.Collections.Generic;
|
|
using Bansonic;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
public class dailyTaskManager : MonoBehaviour
|
|
{
|
|
[Header("任务池so")]
|
|
public userTasksPool taskPool;
|
|
|
|
[Header("player data")]
|
|
public Player_SO playerData;
|
|
|
|
[Header("今日进度")]
|
|
public Slider todayProgressSlider;
|
|
public Text todayProgressPercent;
|
|
public Text todayProgressText;
|
|
public Text notasksanymore;
|
|
|
|
[Header("一键领取")]
|
|
public Button oneKeyRewardBtn;
|
|
|
|
[Header("刷新任务")]
|
|
public Button refreshTaskBtn;
|
|
|
|
[Header("任务配置")]
|
|
[Tooltip("任务列表最大容量")]
|
|
public int taskMaxSize = 5;
|
|
[Tooltip("最大刷新次数")]
|
|
public int refreshMaxTimes = 3;
|
|
|
|
[Header("prefabs")]
|
|
public GameObject dailyTaskItemPrefab;
|
|
public Transform dailyTaskItemParent;
|
|
|
|
[Header("reward sprites")]
|
|
public Sprite coinRewardSprite;
|
|
|
|
private readonly List<GameObject> spawnedTaskItems = new List<GameObject>();
|
|
private readonly Dictionary<int, Sprite> rewardSpriteByItemId = new Dictionary<int, Sprite>();
|
|
private readonly Dictionary<int, storeItemSO> rewardStoreItemByItemId = new Dictionary<int, storeItemSO>();
|
|
|
|
private void Start()
|
|
{
|
|
CacheRewardSpritesFromStoreItems();
|
|
|
|
var taskService = DailyTaskService.EnsureInstance();
|
|
taskService.Configure(taskPool, taskMaxSize, refreshMaxTimes);
|
|
taskService.OnTasksChanged += RefreshTaskUi;
|
|
|
|
if (oneKeyRewardBtn != null)
|
|
{
|
|
oneKeyRewardBtn.onClick.RemoveAllListeners();
|
|
oneKeyRewardBtn.onClick.AddListener(OnOneKeyRewardClicked);
|
|
}
|
|
|
|
if (refreshTaskBtn != null)
|
|
{
|
|
refreshTaskBtn.onClick.RemoveAllListeners();
|
|
refreshTaskBtn.onClick.AddListener(OnRefreshTaskClicked);
|
|
}
|
|
|
|
RefreshTaskUi();
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
if (DailyTaskService.Instance != null)
|
|
{
|
|
DailyTaskService.Instance.OnTasksChanged -= RefreshTaskUi;
|
|
}
|
|
}
|
|
|
|
private void RefreshTaskUi()
|
|
{
|
|
ClearSpawnedItems();
|
|
|
|
var tasks = DailyTaskService.EnsureInstance().GetActiveTaskViews();
|
|
if (notasksanymore != null)
|
|
{
|
|
notasksanymore.gameObject.SetActive(tasks.Count == 0);
|
|
notasksanymore.text = tasks.Count == 0 ? "今日暂无任务" : string.Empty;
|
|
}
|
|
|
|
int completedCount = 0;
|
|
for (int i = 0; i < tasks.Count; i++)
|
|
{
|
|
var taskView = tasks[i];
|
|
if (taskView == null || taskView.definition == null || taskView.runtimeEntry == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (taskView.runtimeEntry.isCompleted)
|
|
{
|
|
completedCount += 1;
|
|
}
|
|
|
|
SpawnTaskItem(i, taskView);
|
|
}
|
|
|
|
UpdateTodayProgress(tasks.Count, completedCount);
|
|
RefreshOneKeyRewardButtonState(tasks);
|
|
RefreshTaskButtonState();
|
|
}
|
|
|
|
private void SpawnTaskItem(int index, DailyTaskViewData taskView)
|
|
{
|
|
if (dailyTaskItemPrefab == null || dailyTaskItemParent == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var instance = Instantiate(dailyTaskItemPrefab, dailyTaskItemParent);
|
|
spawnedTaskItems.Add(instance);
|
|
|
|
var controller = instance.GetComponent<taskPrefabController>();
|
|
if (controller == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
controller.Setup(taskView, index + 1, ResolveRewardSprite(taskView.definition), () => OnSingleRewardClicked(taskView.runtimeEntry.taskID));
|
|
}
|
|
|
|
private void UpdateTodayProgress(int totalTaskCount, int completedCount)
|
|
{
|
|
float progress = totalTaskCount <= 0 ? 0f : (float)completedCount / totalTaskCount;
|
|
|
|
if (todayProgressSlider != null)
|
|
{
|
|
todayProgressSlider.value = progress;
|
|
}
|
|
|
|
if (todayProgressPercent != null)
|
|
{
|
|
todayProgressPercent.text = (progress * 100f).ToString("F0") + "%";
|
|
}
|
|
|
|
if (todayProgressText != null)
|
|
{
|
|
todayProgressText.text = completedCount + "/" + totalTaskCount;
|
|
}
|
|
}
|
|
|
|
private void ClearSpawnedItems()
|
|
{
|
|
for (int i = spawnedTaskItems.Count - 1; i >= 0; i--)
|
|
{
|
|
if (spawnedTaskItems[i] != null)
|
|
{
|
|
Destroy(spawnedTaskItems[i]);
|
|
}
|
|
}
|
|
|
|
spawnedTaskItems.Clear();
|
|
}
|
|
|
|
private void OnSingleRewardClicked(string taskID)
|
|
{
|
|
var rewardEntry = BuildRewardEntryForTask(taskID);
|
|
string failureMessage;
|
|
if (!DailyTaskService.EnsureInstance().TryClaimReward(taskID, playerData, out failureMessage))
|
|
{
|
|
if (!string.IsNullOrEmpty(failureMessage))
|
|
{
|
|
gNotice.warning.display(failureMessage);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if (rewardEntry.HasValue)
|
|
{
|
|
gItemGet.display(rewardEntry.Value);
|
|
}
|
|
|
|
RefreshTaskUi();
|
|
}
|
|
|
|
private void OnOneKeyRewardClicked()
|
|
{
|
|
var taskService = DailyTaskService.EnsureInstance();
|
|
var tasks = taskService.GetActiveTaskViews();
|
|
var grantedEntries = new List<gItemGet.ItemEntry>();
|
|
string failureMessage = string.Empty;
|
|
int claimedCount = 0;
|
|
|
|
for (int i = 0; i < tasks.Count; i++)
|
|
{
|
|
var taskView = tasks[i];
|
|
if (taskView == null || taskView.runtimeEntry == null || taskView.definition == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (!taskView.runtimeEntry.isCompleted || taskView.runtimeEntry.isClaimed)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
string claimError;
|
|
if (!taskService.TryClaimReward(taskView.runtimeEntry.taskID, playerData, out claimError))
|
|
{
|
|
if (claimedCount <= 0 && string.IsNullOrEmpty(failureMessage))
|
|
{
|
|
failureMessage = claimError;
|
|
}
|
|
|
|
continue;
|
|
}
|
|
|
|
claimedCount += 1;
|
|
grantedEntries.Add(BuildRewardEntry(taskView.definition));
|
|
}
|
|
|
|
if (claimedCount <= 0)
|
|
{
|
|
if (string.IsNullOrEmpty(failureMessage))
|
|
{
|
|
failureMessage = "暂无可领取奖励";
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(failureMessage))
|
|
{
|
|
gNotice.warning.display(failureMessage);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if (grantedEntries.Count > 0)
|
|
{
|
|
gItemGet.display(grantedEntries);
|
|
}
|
|
|
|
RefreshTaskUi();
|
|
}
|
|
|
|
private void RefreshOneKeyRewardButtonState(IReadOnlyList<DailyTaskViewData> tasks)
|
|
{
|
|
if (oneKeyRewardBtn == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
bool hasClaimableReward = false;
|
|
for (int i = 0; i < tasks.Count; i++)
|
|
{
|
|
var taskView = tasks[i];
|
|
if (taskView == null || taskView.runtimeEntry == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (taskView.runtimeEntry.isCompleted && !taskView.runtimeEntry.isClaimed)
|
|
{
|
|
hasClaimableReward = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
oneKeyRewardBtn.interactable = hasClaimableReward;
|
|
}
|
|
|
|
private void OnRefreshTaskClicked()
|
|
{
|
|
if (taskPool == null)
|
|
{
|
|
gNotice.warning.display("未配置任务池");
|
|
return;
|
|
}
|
|
|
|
var taskService = DailyTaskService.EnsureInstance();
|
|
if (!taskService.TryRefreshTasks())
|
|
{
|
|
if (taskService.GetRemainingRefreshCount() <= 0)
|
|
{
|
|
gNotice.warning.display("已达到今日刷新上限");
|
|
}
|
|
else
|
|
{
|
|
gNotice.warning.display("刷新失败");
|
|
}
|
|
|
|
RefreshTaskButtonState();
|
|
return;
|
|
}
|
|
|
|
RefreshTaskUi();
|
|
}
|
|
|
|
private void RefreshTaskButtonState()
|
|
{
|
|
if (refreshTaskBtn == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
refreshTaskBtn.interactable = taskPool != null && DailyTaskService.EnsureInstance().GetRemainingRefreshCount() > 0;
|
|
}
|
|
|
|
private Sprite ResolveRewardSprite(userTasksPool.TaskDefinition definition)
|
|
{
|
|
if (definition == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
switch (definition.rewardType)
|
|
{
|
|
case userTasksPool.RewardType.coins:
|
|
return coinRewardSprite;
|
|
case userTasksPool.RewardType.expBottle:
|
|
return GetRewardSpriteByItemId(GetExpBottleRewardItemId(definition.rewardExpBottleKind));
|
|
case userTasksPool.RewardType.dushMaterial:
|
|
return GetRewardSpriteByItemId(GetDushMaterialRewardItemId(definition.rewardDushMaterialKind));
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private void CacheRewardSpritesFromStoreItems()
|
|
{
|
|
rewardSpriteByItemId.Clear();
|
|
rewardStoreItemByItemId.Clear();
|
|
|
|
var rewardStoreItems = RuntimeResourcesCache.LoadAllStoreItems();
|
|
for (int i = 0; i < rewardStoreItems.Length; i++)
|
|
{
|
|
var itemSO = rewardStoreItems[i];
|
|
if (itemSO == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (itemSO.itemIcon != null)
|
|
{
|
|
rewardSpriteByItemId[itemSO.itemID] = itemSO.itemIcon;
|
|
}
|
|
|
|
rewardStoreItemByItemId[itemSO.itemID] = itemSO;
|
|
}
|
|
}
|
|
|
|
private Sprite GetRewardSpriteByItemId(int itemId)
|
|
{
|
|
if (itemId <= 0)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
Sprite sprite;
|
|
return rewardSpriteByItemId.TryGetValue(itemId, out sprite) ? sprite : null;
|
|
}
|
|
|
|
private gItemGet.ItemEntry? BuildRewardEntryForTask(string taskID)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(taskID))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
var tasks = DailyTaskService.EnsureInstance().GetActiveTaskViews();
|
|
for (int i = 0; i < tasks.Count; i++)
|
|
{
|
|
var taskView = tasks[i];
|
|
if (taskView == null || taskView.runtimeEntry == null || taskView.definition == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (string.Equals(taskView.runtimeEntry.taskID, taskID, System.StringComparison.Ordinal))
|
|
{
|
|
return BuildRewardEntry(taskView.definition);
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private gItemGet.ItemEntry BuildRewardEntry(userTasksPool.TaskDefinition definition)
|
|
{
|
|
if (definition == null)
|
|
{
|
|
return gItemGet.Create("未知奖励", null, 1, ItemRarity.None);
|
|
}
|
|
|
|
switch (definition.rewardType)
|
|
{
|
|
case userTasksPool.RewardType.coins:
|
|
return gItemGet.Create("Coins", coinRewardSprite, Mathf.Max(1, definition.rewardAmount), ItemRarity.Common);
|
|
|
|
case userTasksPool.RewardType.expBottle:
|
|
{
|
|
int itemId = GetExpBottleRewardItemId(definition.rewardExpBottleKind);
|
|
storeItemSO itemSO;
|
|
if (rewardStoreItemByItemId.TryGetValue(itemId, out itemSO) && itemSO != null)
|
|
{
|
|
return gItemGet.FromStoreItem(itemSO, Mathf.Max(1, definition.rewardAmount));
|
|
}
|
|
|
|
return gItemGet.Create(
|
|
ExpBottleCatalog.GetDisplayName(definition.rewardExpBottleKind),
|
|
GetRewardSpriteByItemId(itemId),
|
|
Mathf.Max(1, definition.rewardAmount),
|
|
ItemRarity.None);
|
|
}
|
|
|
|
case userTasksPool.RewardType.dushMaterial:
|
|
{
|
|
int itemId = GetDushMaterialRewardItemId(definition.rewardDushMaterialKind);
|
|
storeItemSO itemSO;
|
|
if (rewardStoreItemByItemId.TryGetValue(itemId, out itemSO) && itemSO != null)
|
|
{
|
|
return gItemGet.FromStoreItem(itemSO, Mathf.Max(1, definition.rewardAmount));
|
|
}
|
|
|
|
return gItemGet.Create(
|
|
DushMaterialCatalog.GetDisplayName(definition.rewardDushMaterialKind),
|
|
GetRewardSpriteByItemId(itemId),
|
|
Mathf.Max(1, definition.rewardAmount),
|
|
ItemRarity.None);
|
|
}
|
|
|
|
default:
|
|
return gItemGet.Create("未知奖励", null, Mathf.Max(1, definition.rewardAmount), ItemRarity.None);
|
|
}
|
|
}
|
|
|
|
private static int GetExpBottleRewardItemId(ExpBottleKind kind)
|
|
{
|
|
switch (kind)
|
|
{
|
|
case ExpBottleKind.Common: return 78001;
|
|
case ExpBottleKind.Medium: return 78002;
|
|
case ExpBottleKind.Superior: return 78003;
|
|
case ExpBottleKind.Supreme: return 78004;
|
|
case ExpBottleKind.Extraordinary: return 78005;
|
|
case ExpBottleKind.Celestial: return 78006;
|
|
case ExpBottleKind.RainAll: return 78011;
|
|
case ExpBottleKind.AdvancedRainAll: return 78012;
|
|
case ExpBottleKind.SuperRainAll: return 78013;
|
|
default: return 0;
|
|
}
|
|
}
|
|
|
|
private static int GetDushMaterialRewardItemId(DushMaterialKind kind)
|
|
{
|
|
switch (kind)
|
|
{
|
|
case DushMaterialKind.Material78021: return 78021;
|
|
case DushMaterialKind.Material78022: return 78022;
|
|
case DushMaterialKind.Material78023: return 78023;
|
|
case DushMaterialKind.Material78024: return 78024;
|
|
default: return 0;
|
|
}
|
|
}
|
|
}
|