331 lines
9.1 KiB
C#
331 lines
9.1 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 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)
|
|
{
|
|
string failureMessage;
|
|
if (!DailyTaskService.EnsureInstance().TryClaimReward(taskID, playerData, out failureMessage))
|
|
{
|
|
if (!string.IsNullOrEmpty(failureMessage))
|
|
{
|
|
gNotice.warning.display(failureMessage);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
RefreshTaskUi();
|
|
}
|
|
|
|
private void OnOneKeyRewardClicked()
|
|
{
|
|
string failureMessage;
|
|
int claimedCount = DailyTaskService.EnsureInstance().ClaimAllAvailableRewards(playerData, out failureMessage);
|
|
if (claimedCount <= 0)
|
|
{
|
|
if (!string.IsNullOrEmpty(failureMessage))
|
|
{
|
|
gNotice.warning.display(failureMessage);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
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();
|
|
|
|
var rewardStoreItems = Resources.LoadAll<storeItemSO>("so/storeSO");
|
|
for (int i = 0; i < rewardStoreItems.Length; i++)
|
|
{
|
|
var itemSO = rewardStoreItems[i];
|
|
if (itemSO == null || itemSO.itemIcon == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
rewardSpriteByItemId[itemSO.itemID] = itemSO.itemIcon;
|
|
}
|
|
}
|
|
|
|
private Sprite GetRewardSpriteByItemId(int itemId)
|
|
{
|
|
if (itemId <= 0)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
Sprite sprite;
|
|
return rewardSpriteByItemId.TryGetValue(itemId, out sprite) ? sprite : null;
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|