1193 lines
42 KiB
C#
1193 lines
42 KiB
C#
using asap.core;
|
||
using cfg;
|
||
using game;
|
||
using GameCore;
|
||
using Newtonsoft.Json;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Threading.Tasks;
|
||
using UniRx;
|
||
using UnityEngine;
|
||
|
||
public enum MiniBattlePassType
|
||
{
|
||
None = 0,
|
||
LuckMagic = 1,
|
||
Dive = 2,
|
||
Fishcard = 3,
|
||
Bingo = 4,
|
||
Smash = 5
|
||
}
|
||
|
||
public enum MiniBattleVIPItemType
|
||
{
|
||
None = 0,
|
||
LuckMagic = 4,
|
||
Dive = 5,
|
||
Fishcard = 6,
|
||
Bingo = 7,
|
||
Smash = 8
|
||
}
|
||
|
||
/// <summary>
|
||
/// 小战令已将 <see cref="HomeBtnMiniBP.redKey"/> + type 写入 <see cref="RedPointManager"/> 后发布。
|
||
/// 依赖该 Key 的合并红点、入口等可订阅并按 <see cref="Type"/> 自行刷新,无需在 MiniBP 内引用具体活动。
|
||
/// </summary>
|
||
public readonly struct MiniBattlePassRedPointChangedEvent
|
||
{
|
||
public MiniBattlePassType Type { get; }
|
||
|
||
public MiniBattlePassRedPointChangedEvent(MiniBattlePassType type)
|
||
{
|
||
Type = type;
|
||
}
|
||
}
|
||
|
||
public interface IMiniBattlePassDataProvider
|
||
{
|
||
MiniBattlePassRecord GetMiniBattlePassRecord(string key);
|
||
void SetMiniBattlePassRecord(string key, MiniBattlePassRecord record);
|
||
}
|
||
|
||
|
||
|
||
public class MiniBattlePassDataProvider : IMiniBattlePassDataProvider
|
||
{
|
||
private Tables _tables;
|
||
PlayerItemData _playerItemData;
|
||
string newDataKey => "MiniBPKeyNew";
|
||
Dictionary<MiniBattlePassType, MiniBattlePassDataModel> models = new Dictionary<MiniBattlePassType, MiniBattlePassDataModel>();
|
||
Dictionary<string, MiniBattlePassRecord> datas;
|
||
Dictionary<MiniBattleVIPItemType, MiniBattlePassType> itemSubEventToEventSubEvent = new Dictionary<MiniBattleVIPItemType, MiniBattlePassType>() {
|
||
{ MiniBattleVIPItemType.LuckMagic, MiniBattlePassType.LuckMagic },
|
||
{ MiniBattleVIPItemType.Dive, MiniBattlePassType.Dive },
|
||
{ MiniBattleVIPItemType.Fishcard, MiniBattlePassType.Fishcard },
|
||
{ MiniBattleVIPItemType.Bingo, MiniBattlePassType.Bingo },
|
||
{ MiniBattleVIPItemType.Smash, MiniBattlePassType.Smash }
|
||
};
|
||
public MiniBattlePassDataProvider(Tables tables, PlayerItemData playerItemData)
|
||
{
|
||
_tables = tables;
|
||
_playerItemData = playerItemData;
|
||
}
|
||
|
||
MiniBattlePassDataModel NewModel(MiniBattlePassType subType)
|
||
{
|
||
MiniBattlePassDataModel model;
|
||
|
||
model = new MiniBattlePassDataModel(_tables, _playerItemData, subType, this);
|
||
models[subType] = model;
|
||
return model;
|
||
}
|
||
public MiniBattlePassDataModel GetModel(MiniBattlePassType subType)
|
||
{
|
||
if (models.TryGetValue(subType, out MiniBattlePassDataModel model))
|
||
{
|
||
return model;
|
||
}
|
||
return NewModel(subType);
|
||
}
|
||
// 根据活动开启 redirectID 在活动主表里面配置的 redirectID 字段获取
|
||
|
||
public void EventRefresh(FishingEvent t, int redirectID)
|
||
{
|
||
//根据活动新增
|
||
MiniBattlePassType miniBattlePassType = MiniBattlePassType.None;
|
||
//Debug.Log($"[MiniBattlePass]MiniBattlePassDataProvider.EventRefresh: t.ID = {t.ID}, t.Type = {t.Type}, t.SubType = {t.SubType}, redirectID = {redirectID}");
|
||
if (t.Type == 9)
|
||
{
|
||
miniBattlePassType = (MiniBattlePassType)t.SubType;
|
||
}
|
||
else if (t.Type == 4)
|
||
{
|
||
miniBattlePassType = MiniBattlePassType.Bingo;
|
||
}
|
||
else if (t.Type == 7 && t.SubType == 7)
|
||
{
|
||
miniBattlePassType = MiniBattlePassType.Smash;
|
||
}
|
||
if (!models.TryGetValue(miniBattlePassType, out MiniBattlePassDataModel model))
|
||
{
|
||
model = NewModel(miniBattlePassType);
|
||
}
|
||
model.Refresh(t, redirectID);
|
||
}
|
||
public void UpdateTaskData(MiniBattlePassType subType, int count)
|
||
{
|
||
if (models.TryGetValue(subType, out MiniBattlePassDataModel model))
|
||
{
|
||
model.UpdateTaskData(count);
|
||
}
|
||
}
|
||
|
||
public void SetVipUnlock(int itemSubType)
|
||
{
|
||
MiniBattlePassType subType;
|
||
itemSubEventToEventSubEvent.TryGetValue((MiniBattleVIPItemType)itemSubType, out subType);
|
||
if (subType == 0)
|
||
{
|
||
Debug.LogError($"MiniBattlePassDataProvider.SetVipUnlock: itemSubType {itemSubType} not found in itemSubEventToEventSubEvent mapping.");
|
||
return;
|
||
}
|
||
//Debug.Log($"MiniBattlePassDataProvider.SetVipUnlock: itemSubType = {itemSubType}, bpSubType = {subType}");
|
||
if (models.TryGetValue(subType, out MiniBattlePassDataModel model))
|
||
{
|
||
model.SetVipUnlock();
|
||
}
|
||
}
|
||
|
||
public MiniBattlePassRecord GetMiniBattlePassRecord(string key)
|
||
{
|
||
MiniBattlePassRecord Data;
|
||
if (datas == null)
|
||
{
|
||
string dataStr = PlayFabMgr.Instance.GetLocalData(newDataKey);
|
||
//Debug.Log($"GetMiniBattlePassRecord: dataStr = {dataStr}");
|
||
if (string.IsNullOrEmpty(dataStr))
|
||
{
|
||
datas = new Dictionary<string, MiniBattlePassRecord>();
|
||
}
|
||
else
|
||
{
|
||
datas = JsonConvert.DeserializeObject<Dictionary<string, MiniBattlePassRecord>>(dataStr);
|
||
}
|
||
}
|
||
if (datas.TryGetValue(key, out Data))
|
||
{
|
||
return Data;
|
||
}
|
||
else
|
||
{
|
||
Data = new MiniBattlePassRecord();
|
||
datas[key] = Data;
|
||
return Data;
|
||
}
|
||
}
|
||
|
||
|
||
public void SetMiniBattlePassRecord(string key, MiniBattlePassRecord record)
|
||
{
|
||
datas[key] = record;
|
||
PlayFabMgr.Instance.UpdateUserDataValue(newDataKey, JsonConvert.SerializeObject(datas));
|
||
}
|
||
}
|
||
public class MiniBattlePassProgressInfo
|
||
{
|
||
public float FillAmount { get; set; }
|
||
public int CurrentLevel { get; set; }
|
||
public int NextLevel { get; set; }
|
||
public int CurrentExp { get; set; }
|
||
public int MaxExpForNextLevel { get; set; }
|
||
public bool IsAtMaxLevel { get; set; }
|
||
public bool HasProgress { get; set; }
|
||
public int MaxLevelCount { get; set; }
|
||
}
|
||
|
||
public class MiniBattlePassDataModel
|
||
{
|
||
string _dataKey = "BP_";
|
||
MiniBattlePassType _type = MiniBattlePassType.LuckMagic;
|
||
private Tables _tables;
|
||
PlayerItemData _playerItemData;
|
||
MiniBattlePass miniBattlePassTable;
|
||
MiniBattlePassLevel miniBattlePassLevel;
|
||
public string PanelName => miniBattlePassTable.Prefab;
|
||
public List<int> ItemCountShow => miniBattlePassLevel.ItemCount;
|
||
public List<int> ItemShow => miniBattlePassLevel.ItemShow;
|
||
public string Icon => miniBattlePassTable.Icon;
|
||
public int Param => miniBattlePassTable.Param;
|
||
public string TaskDesc => miniBattlePassTable.TaskDesc_l10n_key;
|
||
public List<int> ProgressList
|
||
{
|
||
get
|
||
{
|
||
var taskParamList = new List<int>(miniBattlePassLevel.TaskParamList);
|
||
if (Data.InflationRate > 0)
|
||
{
|
||
for (int i = 0; i < taskParamList.Count; i++)
|
||
{
|
||
taskParamList[i] = _playerItemData.IntInflation(taskParamList[i], Data.InflationRate);
|
||
}
|
||
}
|
||
return taskParamList;
|
||
}
|
||
}
|
||
public List<int> OverFlow => miniBattlePassTable.OverFlow;
|
||
public List<int> FreeRewards => miniBattlePassLevel.FreeRewardList;
|
||
//public int Type => miniBattlePassTable.Type;
|
||
FishingEvent fishingEvent;
|
||
public DateTime endTime { get; private set; } = DateTime.MinValue; //活动结束时间
|
||
public DateTime startTime = DateTime.MaxValue; //活动开始时间
|
||
public MiniBattlePassRecord Data { get; private set; }
|
||
public bool IsVip => Data.IsVIP;
|
||
public bool RedPoint;
|
||
public int rewardIndex { get; private set; } = -1;//0~
|
||
CompositeDisposable disposables;
|
||
IMiniBattlePassDataProvider _provider;
|
||
public MiniBattlePassDataModel(Tables tables, PlayerItemData playerItemData, MiniBattlePassType type, IMiniBattlePassDataProvider provider)
|
||
{
|
||
_type = type;
|
||
_tables = tables;
|
||
_playerItemData = playerItemData;
|
||
_dataKey = "BP_" + type;
|
||
_provider = provider;
|
||
Data = new MiniBattlePassRecord();
|
||
}
|
||
|
||
void UpdateTaskData(ConditionTypeEvent e)
|
||
{
|
||
if (!IsShow() || Data == null)
|
||
{
|
||
disposables?.Dispose();
|
||
disposables = null;
|
||
return;
|
||
}
|
||
int param = miniBattlePassTable.Param;
|
||
if (param > 0)
|
||
{
|
||
e.count *= param;
|
||
}
|
||
Data.Exp += e.count;
|
||
SetLevel();
|
||
SaveBattlePassRecord();
|
||
}
|
||
/// <summary>
|
||
/// TaskType == ConditionType.None 手动调用进度增加接口
|
||
/// </summary>
|
||
/// <param name="count"></param>
|
||
public void UpdateTaskData(int count)
|
||
{
|
||
if (!IsShow() || Data == null)
|
||
{
|
||
return;
|
||
}
|
||
int param = miniBattlePassTable.Param;
|
||
if (param > 0)
|
||
{
|
||
count *= param;
|
||
}
|
||
Data.Exp += count;
|
||
SetLevel();
|
||
SaveBattlePassRecord();
|
||
}
|
||
|
||
void SetLevel()
|
||
{
|
||
var tasks = ProgressList;
|
||
for (int i = rewardIndex + 1; i < tasks?.Count; i++)
|
||
{
|
||
if (Data.Exp < tasks[i])
|
||
{
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
rewardIndex = i;
|
||
}
|
||
}
|
||
|
||
SetRedPoint();
|
||
}
|
||
|
||
void SetRedPoint()
|
||
{
|
||
if (RedPoint)
|
||
{
|
||
RedPointManager.Instance.SetRedPointState(HomeBtnMiniBP.redKey + _type, true);
|
||
GContext.Publish(new MiniBattlePassRedPointChangedEvent(_type));
|
||
return;
|
||
}
|
||
bool isRed = false;
|
||
var freeRewards = miniBattlePassLevel?.FreeRewardList;
|
||
int count = 0;
|
||
if (freeRewards?.Count > rewardIndex)
|
||
{
|
||
if (Data.NRIndexs.Count <= rewardIndex)
|
||
{
|
||
isRed = true;
|
||
count = rewardIndex - Data.NRIndexs.Count + 1;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
isRed = rewardIndex > Data.showIndex;
|
||
}
|
||
|
||
if (Data.IsVIP)
|
||
{
|
||
if (Data.VRIndexs.Count <= rewardIndex)
|
||
{
|
||
isRed = true;
|
||
count += rewardIndex - Data.VRIndexs.Count + 1;
|
||
}
|
||
var overFlow = OverFlow;
|
||
if (overFlow.Count >= 3)
|
||
{
|
||
var taskParam = ProgressList[^1];
|
||
int exp = Data.Exp - taskParam;
|
||
if (exp >= overFlow[0])
|
||
{
|
||
isRed = true;
|
||
count += exp / overFlow[0] * overFlow[1];
|
||
}
|
||
}
|
||
}
|
||
|
||
RedPointManager.Instance.SetRedPointState(HomeBtnMiniBP.redKey + _type, isRed, count);
|
||
GContext.Publish(new MiniBattlePassRedPointChangedEvent(_type));
|
||
}
|
||
|
||
public void Refresh(FishingEvent t, int redirectID)
|
||
{
|
||
//没有数据或者活动ID不一致时,拿数据再判断
|
||
if (t.ID != Data.Id)
|
||
{
|
||
fishingEvent = t;
|
||
endTime = DateTime.Parse((t.TimeDefinition as LimitedTime).EndTime);
|
||
startTime = DateTime.Parse((t.TimeDefinition as LimitedTime).StartTime);
|
||
InitData(redirectID);
|
||
}
|
||
if (!string.IsNullOrEmpty(PanelName) && IsShow() && miniBattlePassTable.TaskType != ConditionType.None)
|
||
{
|
||
GContext.container.Resolve<IFaceUIService>().AddGiftFaceUI(Data.Id, new UIType(PanelName), 0);
|
||
}
|
||
}
|
||
|
||
public bool IsShow()
|
||
{
|
||
return /*false &&*/ fishingEvent != null
|
||
&& miniBattlePassTable != null
|
||
&& endTime > ZZTimeHelper.UtcNow()
|
||
&& startTime < ZZTimeHelper.UtcNow();
|
||
}
|
||
|
||
|
||
public bool IsDone()
|
||
{
|
||
return Data.VRIndexs.Count >= miniBattlePassLevel.PrimeRewardList.Count;
|
||
}
|
||
|
||
void InitData(int redirectID)
|
||
{
|
||
Data = _provider.GetMiniBattlePassRecord(_dataKey);
|
||
//拿到数据判断刷新活动
|
||
miniBattlePassTable = _tables.TbMiniBattlePass.GetOrDefault(redirectID);
|
||
if (Data.Id != fishingEvent.ID)
|
||
{
|
||
RedPoint = true;
|
||
int oldRedirectID = Data.RedirectID;
|
||
int oldID = Data.Id;
|
||
int oldExp = 0;
|
||
bool oldIsVIP = Data.IsVIP;
|
||
List<int> lastDropIDs = new List<int>();
|
||
if (oldRedirectID > 0)
|
||
{
|
||
var miniTabel = _tables.TbMiniBattlePass.GetOrDefault(oldRedirectID);
|
||
if (miniTabel != null)
|
||
{
|
||
int Level = Data.PriceLv;
|
||
int levelId = miniTabel.VipList.Count > Level ? miniTabel.VipList[Level] : miniTabel.VipList[^1];
|
||
MiniBattlePassLevel passLevel = _tables.TbMiniBattlePassLevel.GetOrDefault(levelId);
|
||
List<int> taskParamList = new List<int>(passLevel.TaskParamList);
|
||
if (Data.InflationRate > 0)
|
||
{
|
||
for (int i = 0; i < taskParamList.Count; i++)
|
||
{
|
||
taskParamList[i] = _playerItemData.IntInflation(taskParamList[i], Data.InflationRate);
|
||
}
|
||
}
|
||
int lv = GetLevel(Data.Exp, taskParamList);
|
||
if (lv >= 0)
|
||
{
|
||
lastDropIDs = SetLastDropIDs(passLevel, lv, Data.NRIndexs, Data.VRIndexs, Data.IsVIP);
|
||
oldExp = Data.Exp;
|
||
}
|
||
}
|
||
}
|
||
Data = new MiniBattlePassRecord();
|
||
Data.Id = fishingEvent.ID;
|
||
if (miniBattlePassTable.TaskType == ConditionType.ConsumeEnergy)
|
||
{
|
||
Data.InflationRate = GContext.container.Resolve<PlayerData>().InflationRate;
|
||
}
|
||
Data.PriceLv = GContext.container.Resolve<PlayerData>().PriceLv;
|
||
Data.LastDropIDs = lastDropIDs;
|
||
Data.oldExp = oldExp;
|
||
Data.oldRedirectID = oldRedirectID;
|
||
Data.oldID = oldID;
|
||
Data.oldIsVIP = oldIsVIP;
|
||
rewardIndex = -1;
|
||
SaveBattlePassRecord();
|
||
}
|
||
int id = miniBattlePassTable.VipList.Count > Data.PriceLv ? miniBattlePassTable.VipList[Data.PriceLv] : miniBattlePassTable.VipList[^1];
|
||
miniBattlePassLevel = _tables.TbMiniBattlePassLevel.GetOrDefault(id);
|
||
Data.RedirectID = redirectID;
|
||
SetLevel();
|
||
disposables?.Dispose();
|
||
disposables = new CompositeDisposable();
|
||
if (miniBattlePassTable.TaskType != ConditionType.None)
|
||
{
|
||
GContext.OnEvent<ConditionTypeEvent>().Where(x => x.type == miniBattlePassTable?.TaskType).Subscribe(UpdateTaskData).AddTo(disposables);
|
||
}
|
||
}
|
||
|
||
public bool CheckIfGetLastBpRewards()
|
||
{
|
||
MiniBattlePass miniBattlePass = _tables.TbMiniBattlePass.GetOrDefault(Data.oldRedirectID);
|
||
if (miniBattlePass == null)
|
||
{
|
||
return false;
|
||
}
|
||
int Level = Data.PriceLv;
|
||
int id = miniBattlePass.VipList.Count > Level ? miniBattlePass.VipList[Level] : miniBattlePass.VipList[^1];
|
||
var passLevel = _tables.TbMiniBattlePassLevel.GetOrDefault(id);
|
||
var TaskParamList = passLevel.TaskParamList;
|
||
//passLevel 鱼卡战令任务需求最后转换 所以此处 TaskParamList 不需要膨胀处理
|
||
if (Data.LastDropIDs.Count != 0 || (miniBattlePass.OverFlow.Count >= 3 && Data.oldExp > TaskParamList[^1]))
|
||
{
|
||
//旧的需求
|
||
var playerData = GContext.container.Resolve<PlayerItemData>();
|
||
var newList = new List<int>(Data.LastDropIDs);
|
||
var itemDatas = playerData.GetMergedItemDataByDropList(newList);
|
||
playerData.LureInflation(itemDatas, null);
|
||
//int lv = GetLevel(Data.oldExp, TaskParamList);
|
||
ItemData itemDataOverFlow = null;
|
||
if (miniBattlePass.OverFlow.Count >= 3)
|
||
{
|
||
int exp = Data.oldExp - TaskParamList[^1];
|
||
if (exp >= miniBattlePass.OverFlow[0])
|
||
{
|
||
itemDataOverFlow = new ItemData
|
||
{
|
||
id = miniBattlePass.OverFlow[2], // 钩子
|
||
count = exp * miniBattlePass.OverFlow[1] / miniBattlePass.OverFlow[0]
|
||
};
|
||
|
||
#if AGG
|
||
using (var e = GEvent.GameEvent("minibp_reward_extra"))
|
||
{
|
||
e.AddContent("event_id", Data.oldID)
|
||
.AddContent("bp_id", passLevel.Id)
|
||
.AddContent("is_activate", Data.oldID)
|
||
.AddContent("extra_points", exp)
|
||
.AddContent("reward", $"{itemDataOverFlow.id},{itemDataOverFlow.count}");
|
||
}
|
||
#endif
|
||
}
|
||
}
|
||
Data.oldExp = 0;
|
||
if (itemDatas.Count == 0 && itemDataOverFlow == null)
|
||
{
|
||
return false;
|
||
}
|
||
if (itemDatas.Count > 0)
|
||
{
|
||
ChangeSource changeSource = new ChangeSource(Data.oldID, "MiniBattlePass", "MiniBattlePass", "ExpiredReward");
|
||
if (_type == MiniBattlePassType.Bingo)
|
||
{
|
||
changeSource.Source_Group = "Event_Minigame1";
|
||
changeSource.Source_Type = "Event_Minigame1_Bingo";
|
||
}
|
||
else if (_type == MiniBattlePassType.Fishcard)
|
||
{
|
||
changeSource.Source_Type = "MiniBattlePass_FishCard";
|
||
}
|
||
else if (_type == MiniBattlePassType.Dive)
|
||
{
|
||
changeSource.Source_Type = "MiniBattlePass_Lure";
|
||
}
|
||
else if (_type == MiniBattlePassType.Smash)
|
||
{
|
||
changeSource.Source_Group = "Event_Minigame2";
|
||
changeSource.Source_Type = "Event_Minigame2_Smash";
|
||
}
|
||
|
||
GContext.Publish(new ShowData(itemDatas));
|
||
playerData.AddItem(itemDatas, changeSource);
|
||
}
|
||
if (itemDataOverFlow != null)
|
||
{
|
||
ChangeSource changeSource = new ChangeSource(Data.oldID, "MiniBattlePass", "MiniBattlePass", "OverflowReward");
|
||
if (_type == MiniBattlePassType.Fishcard)
|
||
{
|
||
changeSource.Source_Type = "MiniBattlePass_FishCard";
|
||
}
|
||
|
||
GContext.Publish(new ShowData(itemDataOverFlow) { rewardType = RewardType.FishCardBoxOpen });
|
||
playerData.AddItem(itemDataOverFlow, changeSource);
|
||
}
|
||
#if AGG
|
||
using (var e = GEvent.GameEvent("minibp_level_reward"))
|
||
{
|
||
e.AddContent("bp_id", passLevel.Id)
|
||
.AddContent("drop_id_list", JsonConvert.SerializeObject(newList));
|
||
if (itemDatas != null && itemDatas.Count > 0)
|
||
{
|
||
for (int i = 0; i < itemDatas.Count; i++)
|
||
{
|
||
if (itemDatas[i].id == 1001)
|
||
{
|
||
e.AddContent("reward_hook", itemDatas[i].count)
|
||
.AddContent("hook_origin", itemDatas[i].origin);
|
||
}
|
||
else if (itemDatas[i].id == 1002)
|
||
{
|
||
e.AddContent("reward_cash", itemDatas[i].count);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
#endif
|
||
string eventName = "";
|
||
if (miniBattlePass != null)
|
||
{
|
||
eventName = LocalizationMgr.GetText(miniBattlePass.TitleDesc_l10n_key);
|
||
}
|
||
|
||
string textValue = LocalizationMgr.GetFormatTextValue("UI_MiniBattlePass_DivePopupPanel_7", eventName);
|
||
GContext.Publish(new ShowData(textValue: textValue));
|
||
Data.LastDropIDs.Clear();
|
||
SaveBattlePassRecord();
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
//async void ShowBox(ItemData itemData)
|
||
//{
|
||
// GameObject go = await UIManager.Instance.ShowUI(new UIType("RewardPopupPanel_Fishcard"));
|
||
// RewardPopupPanel_Fishcard panel_Fishcard = go.GetComponent<RewardPopupPanel_Fishcard>();
|
||
// panel_Fishcard.Open(itemData);
|
||
//}
|
||
|
||
/// <summary>
|
||
/// 能领奖的等级 从0开始
|
||
/// </summary>
|
||
/// <param name="exp"></param>
|
||
/// <param name="tasks"></param>
|
||
/// <returns></returns>
|
||
int GetLevel(int exp, List<int> tasks)
|
||
{
|
||
int index = -1;
|
||
for (int i = 0; i < tasks.Count; i++)
|
||
{
|
||
if (exp < tasks[i])
|
||
{
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
index = i;
|
||
}
|
||
}
|
||
return index;
|
||
}
|
||
/// <summary>
|
||
/// 获得未获得奖励
|
||
/// </summary>
|
||
/// <param name="miniTabel"></param>
|
||
/// <param name="reward"></param>
|
||
/// <param name="nrIndexs"></param>
|
||
/// <param name="vrIndexs"></param>
|
||
/// <param name="vip"></param>
|
||
/// <returns></returns>
|
||
List<int> SetLastDropIDs(MiniBattlePassLevel passLevel, int reward, List<int> nrIndexs, List<int> vrIndexs, bool vip)
|
||
{
|
||
var freeRewards = passLevel.FreeRewardList;
|
||
var primeRewards = passLevel.PrimeRewardList;
|
||
List<int> rewardList = new List<int>();
|
||
if (freeRewards.Count > reward)
|
||
{
|
||
for (int i = 0; i <= reward; i++)
|
||
{
|
||
if (!nrIndexs.Contains(i))
|
||
{
|
||
rewardList.Add(freeRewards[i]);
|
||
}
|
||
}
|
||
}
|
||
if (vip)
|
||
{
|
||
for (int i = 0; i <= reward; i++)
|
||
{
|
||
if (!vrIndexs.Contains(i))
|
||
{
|
||
rewardList.Add(primeRewards[i]);
|
||
}
|
||
}
|
||
}
|
||
return rewardList;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 展示后
|
||
/// </summary>
|
||
public void SetOldLevel()
|
||
{
|
||
if (Data != null)
|
||
{
|
||
Data.showIndex = rewardIndex;
|
||
SaveBattlePassRecord();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 将面板已浏览档位记为指定下标(用于 Second 面板追进度动画与 spine 锚点同步)。
|
||
/// </summary>
|
||
public void SetShowIndexForPanelView(int tierIndex)
|
||
{
|
||
if (Data != null)
|
||
{
|
||
Data.showIndex = tierIndex;
|
||
SaveBattlePassRecord();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 在已达成的最高档 <see cref="rewardIndex"/> 内,从高档向低档找仍有未领奖励(免费或 VIP 付费)的最高档下标;若均已领完则返回 <see cref="rewardIndex"/>(<0 时返回 0)。
|
||
/// </summary>
|
||
public int GetHighestClaimableTierIndex()
|
||
{
|
||
int r = rewardIndex;
|
||
if (r < 0 || Data == null || miniBattlePassLevel == null)
|
||
{
|
||
return Mathf.Max(0, r);
|
||
}
|
||
|
||
var freeRewards = miniBattlePassLevel.FreeRewardList;
|
||
var primeRewards = miniBattlePassLevel.PrimeRewardList;
|
||
for (int i = r; i >= 0; i--)
|
||
{
|
||
bool freeLeft = freeRewards != null && i < freeRewards.Count && !Data.NRIndexs.Contains(i);
|
||
bool primeLeft = Data.IsVIP && primeRewards != null && i < primeRewards.Count && !Data.VRIndexs.Contains(i);
|
||
if (freeLeft || primeLeft)
|
||
{
|
||
return i;
|
||
}
|
||
}
|
||
|
||
return r;
|
||
}
|
||
|
||
void CheckDone()
|
||
{
|
||
if (IsDone())
|
||
{
|
||
GContext.Publish(new TargetEvent(fishingEvent.ID, fishingEvent.Type, fishingEvent.SubType));
|
||
}
|
||
}
|
||
public ItemData ReceiveOverFlow()
|
||
{
|
||
var overFlow = miniBattlePassTable.OverFlow;
|
||
if (overFlow.Count >= 3)
|
||
{
|
||
var taskParam = ProgressList[^1];
|
||
int exp = Data.Exp - taskParam;
|
||
if (exp >= overFlow[0])
|
||
{
|
||
int count = exp / overFlow[0];
|
||
int cost_points = count * overFlow[0];
|
||
Data.Exp -= cost_points;
|
||
count *= overFlow[1];
|
||
int id = overFlow[2];
|
||
//发奖励刷界面,保存数据
|
||
ItemData itemData = new ItemData
|
||
{
|
||
id = id,
|
||
count = count,
|
||
inflate = GContext.container.Resolve<PlayerData>().InflationRate
|
||
};
|
||
GContext.Publish(new game.ShowData(itemData) { rewardType = RewardType.FishCardBoxOpen });
|
||
ChangeSource changeSource = new ChangeSource(Data.Id, "MiniBattlePass", "MiniBattlePass", "OverflowReward");
|
||
if (_type == MiniBattlePassType.Fishcard)
|
||
{
|
||
changeSource.Source_Type = "MiniBattlePass_FishCard";
|
||
}
|
||
_playerItemData.AddItem(itemData, changeSource);
|
||
SetRedPoint();
|
||
#if AGG
|
||
using (var e = GEvent.GameEvent("minibp_fishcard_overflow_reward"))
|
||
{
|
||
e.AddContent("event_id", Data.Id)
|
||
.AddContent("bp_id", miniBattlePassLevel.Id)
|
||
.AddContent("cost_points", cost_points)
|
||
.AddContent("reward", $"{itemData.id},{itemData.count}");
|
||
}
|
||
#endif
|
||
GContext.Publish(new ShowData());
|
||
SaveBattlePassRecord();
|
||
return itemData;
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
|
||
public void ReceiveReward(int index, bool isFree)
|
||
{
|
||
if (Data != null)
|
||
{
|
||
var freeRewards = miniBattlePassLevel.FreeRewardList;
|
||
var primeRewards = miniBattlePassLevel.PrimeRewardList;
|
||
int dropid = 0;
|
||
ChangeSource changeSource = new ChangeSource(Data.Id, "MiniBattlePass", "MiniBattlePass", "FreeLevelReward");
|
||
if (isFree)
|
||
{
|
||
if (!Data.NRIndexs.Contains(index))
|
||
{
|
||
if (_type == MiniBattlePassType.Bingo)
|
||
{
|
||
changeSource.Source_Group = "Event_Minigame1";
|
||
changeSource.Source_Type = "Event_Minigame1_Bingo";
|
||
changeSource.Source_Module = "PassFreeReward";
|
||
}
|
||
else if (_type == MiniBattlePassType.Fishcard)
|
||
{
|
||
changeSource.Source_Group = "MiniBattlePass";
|
||
changeSource.Source_Type = "MiniBattlePass_FishCard";
|
||
changeSource.Source_Module = "FreeLevelReward";
|
||
}
|
||
else if (_type == MiniBattlePassType.Dive)
|
||
{
|
||
changeSource.Source_Group = "MiniBattlePass";
|
||
changeSource.Source_Type = "MiniBattlePass_Lure";
|
||
changeSource.Source_Module = "FreeLevelReward";
|
||
}
|
||
else if (_type == MiniBattlePassType.Smash)
|
||
{
|
||
changeSource.Source_Group = "Event_Minigame2";
|
||
changeSource.Source_Type = "Event_Minigame2_Smash";
|
||
changeSource.Source_Module = "PassFreeReward";
|
||
}
|
||
Data.NRIndexs.Add(index);
|
||
dropid = freeRewards[index];
|
||
miniBPItemDatas[index].isFreeClaimed = true;
|
||
}
|
||
}
|
||
else if (Data.IsVIP)
|
||
{
|
||
|
||
if (!Data.VRIndexs.Contains(index))
|
||
{
|
||
if (_type == MiniBattlePassType.Bingo)
|
||
{
|
||
changeSource.Source_Group = "Event_Minigame1";
|
||
changeSource.Source_Type = "Event_Minigame1_Bingo";
|
||
changeSource.Source_Module = "PassPrimeReward";
|
||
}
|
||
else if (_type == MiniBattlePassType.Fishcard)
|
||
{
|
||
changeSource.Source_Group = "MiniBattlePass";
|
||
changeSource.Source_Type = "MiniBattlePass_FishCard";
|
||
changeSource.Source_Module = "PrimeLevelReward";
|
||
}
|
||
else if (_type == MiniBattlePassType.Dive)
|
||
{
|
||
changeSource.Source_Group = "MiniBattlePass";
|
||
changeSource.Source_Type = "MiniBattlePass_Lure";
|
||
changeSource.Source_Module = "PrimeLevelReward";
|
||
}
|
||
else if (_type == MiniBattlePassType.Smash)
|
||
{
|
||
changeSource.Source_Group = "Event_Minigame2";
|
||
changeSource.Source_Type = "Event_Minigame2_Smash";
|
||
changeSource.Source_Module = "PassPrimeReward";
|
||
}
|
||
Data.VRIndexs.Add(index);
|
||
dropid = primeRewards[index];
|
||
miniBPItemDatas[index].isGrandClaimed = true;
|
||
}
|
||
}
|
||
if (dropid == 0)
|
||
{
|
||
return;
|
||
}
|
||
List<ItemData> itemDatas = _playerItemData.AddItemByDropLureInflation(null, dropid, changeSource);
|
||
GContext.Publish(new ShowData());
|
||
CheckDone();
|
||
SaveBattlePassRecord();
|
||
#if AGG
|
||
using (var e = GEvent.GameEvent("minibp_reward"))
|
||
{
|
||
e.AddContent("bp_level", index + 1)
|
||
.AddContent("bp_id", miniBattlePassLevel.Id)
|
||
.AddContent("event_id", Data.Id)
|
||
.AddContent("is_activate", Data.IsVIP)
|
||
.AddContent("drop_id_list", dropid);
|
||
if (itemDatas != null && itemDatas.Count > 0)
|
||
{
|
||
for (int i = 0; i < itemDatas.Count; i++)
|
||
{
|
||
if (itemDatas[i].id == 1001)
|
||
{
|
||
e.AddContent("reward_hook", itemDatas[i].count)
|
||
.AddContent("hook_origin", itemDatas[i].origin);
|
||
}
|
||
else if (itemDatas[i].id == 1002)
|
||
{
|
||
e.AddContent("reward_cash", itemDatas[i].count);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
#endif
|
||
}
|
||
}
|
||
|
||
public bool ReceiveAllReward()
|
||
{
|
||
if (Data == null)
|
||
{
|
||
return false;
|
||
}
|
||
var freeRewards = miniBattlePassLevel.FreeRewardList;
|
||
var primeRewards = miniBattlePassLevel.PrimeRewardList;
|
||
List<int> rewardList = new List<int>();
|
||
List<int> rewardList1 = new List<int>();
|
||
List<int> rewardList2 = new List<int>();
|
||
List<ItemData> itemDatas = new List<ItemData>();
|
||
List<ItemData> itemDatas1 = new List<ItemData>();
|
||
List<ItemData> itemDatas2 = new List<ItemData>();
|
||
if (freeRewards.Count > rewardIndex)
|
||
{
|
||
for (int i = 0; i <= rewardIndex; i++)
|
||
{
|
||
if (!Data.NRIndexs.Contains(i))
|
||
{
|
||
Data.NRIndexs.Add(i);
|
||
rewardList1.Add(freeRewards[i]);
|
||
}
|
||
}
|
||
if (rewardList1.Count > 0)
|
||
{
|
||
rewardList.AddRange(rewardList1);
|
||
ChangeSource changeSource = new ChangeSource(Data.Id, "MiniBattlePass", "MiniBattlePass", "FreeLevelReward");
|
||
if (_type == MiniBattlePassType.Bingo)
|
||
{
|
||
changeSource.Source_Group = "Event_Minigame1";
|
||
changeSource.Source_Type = "Event_Minigame1_Bingo";
|
||
changeSource.Source_Module = "PassFreeReward";
|
||
}
|
||
else if (_type == MiniBattlePassType.Fishcard)
|
||
{
|
||
changeSource.Source_Group = "MiniBattlePass";
|
||
changeSource.Source_Type = "MiniBattlePass_FishCard";
|
||
changeSource.Source_Module = "FreeLevelReward";
|
||
}
|
||
else if (_type == MiniBattlePassType.Dive)
|
||
{
|
||
changeSource.Source_Group = "MiniBattlePass";
|
||
changeSource.Source_Type = "MiniBattlePass_Lure";
|
||
changeSource.Source_Module = "FreeLevelReward";
|
||
}
|
||
else if (_type == MiniBattlePassType.Smash)
|
||
{
|
||
changeSource.Source_Group = "Event_Minigame2";
|
||
changeSource.Source_Type = "Event_Minigame2_Smash";
|
||
changeSource.Source_Module = "PassFreeReward";
|
||
}
|
||
|
||
itemDatas1 = _playerItemData.GetItemByDropListLureInflation(null, rewardList1);
|
||
for (int i = 0; i < itemDatas1.Count; i++)
|
||
{
|
||
itemDatas1[i].changeSource = changeSource;
|
||
}
|
||
itemDatas.AddRange(itemDatas1);
|
||
}
|
||
}
|
||
if (Data.IsVIP)
|
||
{
|
||
for (int i = 0; i <= rewardIndex; i++)
|
||
{
|
||
if (!Data.VRIndexs.Contains(i))
|
||
{
|
||
Data.VRIndexs.Add(i);
|
||
rewardList2.Add(primeRewards[i]);
|
||
}
|
||
}
|
||
if (rewardList2.Count > 0)
|
||
{
|
||
rewardList.AddRange(rewardList2);
|
||
ChangeSource changeSource = new ChangeSource(Data.Id, "MiniBattlePass", "MiniBattlePass", "PrimeLevelReward");
|
||
if (_type == MiniBattlePassType.Bingo)
|
||
{
|
||
changeSource.Source_Group = "Event_Minigame1";
|
||
changeSource.Source_Type = "Event_Minigame1_Bingo";
|
||
changeSource.Source_Module = "PassPrimeReward";
|
||
}
|
||
else if (_type == MiniBattlePassType.Fishcard)
|
||
{
|
||
changeSource.Source_Group = "MiniBattlePass";
|
||
changeSource.Source_Type = "MiniBattlePass_FishCard";
|
||
changeSource.Source_Module = "PrimeLevelReward";
|
||
}
|
||
else if (_type == MiniBattlePassType.Dive)
|
||
{
|
||
changeSource.Source_Group = "MiniBattlePass";
|
||
changeSource.Source_Type = "MiniBattlePass_Lure";
|
||
changeSource.Source_Module = "PrimeLevelReward";
|
||
}
|
||
else if (_type == MiniBattlePassType.Smash)
|
||
{
|
||
changeSource.Source_Group = "Event_Minigame2";
|
||
changeSource.Source_Type = "Event_Minigame2_Smash";
|
||
changeSource.Source_Module = "PassPrimeReward";
|
||
}
|
||
itemDatas2 = _playerItemData.GetItemByDropListLureInflation(null, rewardList2);
|
||
for (int i = 0; i < itemDatas2.Count; i++)
|
||
{
|
||
itemDatas2[i].changeSource = changeSource;
|
||
}
|
||
itemDatas.AddRange(itemDatas2);
|
||
}
|
||
}
|
||
if (rewardList.Count == 0)
|
||
{
|
||
return false;
|
||
}
|
||
GContext.Publish(new ShowData(itemDatas));
|
||
_playerItemData.AddItem(itemDatas, null);
|
||
GContext.Publish(new ShowData());
|
||
RefreshDataReward();
|
||
CheckDone();
|
||
|
||
SaveBattlePassRecord();
|
||
#if AGG
|
||
using (var e = GEvent.GameEvent("minibp_reward"))
|
||
{
|
||
e.AddContent("bp_level", rewardIndex + 1)
|
||
.AddContent("bp_id", miniBattlePassLevel.Id)
|
||
.AddContent("event_id", Data.Id)
|
||
.AddContent("is_activate", Data.IsVIP)
|
||
.AddContent("drop_id_list", JsonConvert.SerializeObject(rewardList));
|
||
if (itemDatas != null && itemDatas.Count > 0)
|
||
{
|
||
int reward_hook = 0;
|
||
int hook_origin = 0;
|
||
int reward_cash = 0;
|
||
for (int i = 0; i < itemDatas.Count; i++)
|
||
{
|
||
if (itemDatas[i].id == 1001)
|
||
{
|
||
reward_hook += itemDatas[i].count;
|
||
hook_origin += itemDatas[i].origin;
|
||
}
|
||
else if (itemDatas[i].id == 1002)
|
||
{
|
||
reward_cash += itemDatas[i].count;
|
||
}
|
||
}
|
||
e.AddContent("reward_hook", reward_hook)
|
||
.AddContent("hook_origin", hook_origin)
|
||
.AddContent("reward_cash", reward_cash);
|
||
}
|
||
}
|
||
#endif
|
||
return true;
|
||
}
|
||
|
||
public void SaveBattlePassRecord()
|
||
{
|
||
SetRedPoint();
|
||
_provider.SetMiniBattlePassRecord(_dataKey, Data);
|
||
}
|
||
|
||
public IAPItemList GetIAPItem()
|
||
{
|
||
return _tables.TbIAPItemList.GetOrDefault(miniBattlePassLevel.IapId);
|
||
}
|
||
|
||
public async Task<bool> BuyBattlePass()
|
||
{
|
||
var iAPItemList = _tables.TbIAPItemList.GetOrDefault(miniBattlePassLevel.IapId);
|
||
int dropID = miniBattlePassLevel.ActivateId;
|
||
var itemDatas = GContext.container.Resolve<PlayerItemData>().GetItemDataByDropId(dropID);
|
||
|
||
ShopBuyTypeData shopBuyTypeData = new ShopBuyTypeData();
|
||
shopBuyTypeData.type = ShopBuyType.None;
|
||
shopBuyTypeData.IsHide = true;
|
||
bool Result = await GContext.container.Resolve<PlayerShopData>().OnBuy(dropID, shopBuyTypeData, iAPItemList, itemDatas);
|
||
if (Result)
|
||
{
|
||
RefreshDataVIP();
|
||
}
|
||
return Result;
|
||
|
||
}
|
||
|
||
void RefreshDataVIP()
|
||
{
|
||
if (miniBPItemDatas != null && miniBPItemDatas.Count > 0)
|
||
{
|
||
for (int i = 0; i < miniBPItemDatas.Count; i++)
|
||
{
|
||
miniBPItemDatas[i].isGrandReward = true;
|
||
}
|
||
}
|
||
}
|
||
|
||
void RefreshDataReward()
|
||
{
|
||
if (miniBPItemDatas != null && miniBPItemDatas.Count > 0)
|
||
{
|
||
for (int i = 0; i < miniBPItemDatas.Count; i++)
|
||
{
|
||
var item = miniBPItemDatas[i];
|
||
item.isGrandClaimed = Data.VRIndexs.Contains(i);
|
||
item.isFreeClaimed = Data.NRIndexs.Contains(i);
|
||
}
|
||
}
|
||
}
|
||
|
||
public void SetVipUnlock()
|
||
{
|
||
if (Data != null && miniBattlePassTable != null && IsShow())
|
||
{
|
||
Data.IsVIP = true;
|
||
SaveBattlePassRecord();
|
||
}
|
||
}
|
||
|
||
public void SetPanelData()
|
||
{
|
||
if (miniBattlePassTable == null)
|
||
{
|
||
miniBattlePassTable = _tables.TbMiniBattlePass.GetOrDefault(Data.RedirectID);
|
||
}
|
||
if (miniBattlePassTable == null)
|
||
{
|
||
return;
|
||
}
|
||
int Level = Data.PriceLv;
|
||
int id = miniBattlePassTable.VipList.Count > Level ? miniBattlePassTable.VipList[Level] : miniBattlePassTable.VipList[^1];
|
||
miniBattlePassLevel = _tables.TbMiniBattlePassLevel.GetOrDefault(id);
|
||
SetData();
|
||
RedPoint = false;
|
||
SetRedPoint();
|
||
}
|
||
|
||
public List<MiniBPItemData> miniBPItemDatas;
|
||
|
||
void SetData()
|
||
{
|
||
miniBPItemDatas = new List<MiniBPItemData>();
|
||
var tasks = ProgressList;
|
||
var FreeRewardList = miniBattlePassLevel.FreeRewardList;
|
||
var PrimeRewardList = miniBattlePassLevel.PrimeRewardList;
|
||
string format = LocalizationMgr.GetText(miniBattlePassTable.TaskDesc_l10n_key);
|
||
|
||
for (int i = 0; i < tasks.Count; i++)
|
||
{
|
||
MiniBPItemData item = new MiniBPItemData();
|
||
item.index = i;
|
||
item.progress = Data.Exp;
|
||
item.maxProgress = tasks[i];
|
||
if (miniBattlePassTable.TaskType != ConditionType.None)
|
||
{
|
||
item.taskName = format.SafeFormat(tasks[i]);
|
||
}
|
||
|
||
if (FreeRewardList.Count > i)
|
||
{
|
||
item.freeReward = _playerItemData.GetItemDataOneLureInflation(null, FreeRewardList[i]);
|
||
}
|
||
item.grandReward = _playerItemData.GetItemDataOneLureInflation(null, PrimeRewardList[i]);
|
||
item.isGrandReward = Data.IsVIP;
|
||
item.isGrandClaimed = Data.VRIndexs.Contains(i);
|
||
item.isFreeClaimed = Data.NRIndexs.Contains(i);
|
||
miniBPItemDatas.Add(item);
|
||
}
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// Gets the progress information for UI display
|
||
/// </summary>
|
||
public MiniBattlePassProgressInfo GetUiProgressInfo()
|
||
{
|
||
var progressList = ProgressList;
|
||
int nextlv = rewardIndex + 1;
|
||
|
||
var info = new MiniBattlePassProgressInfo();
|
||
|
||
if (nextlv < progressList.Count)
|
||
{
|
||
int startExp = 0;
|
||
if (nextlv > 0)
|
||
{
|
||
startExp = progressList[nextlv - 1];
|
||
}
|
||
int curExp = Data.Exp - startExp;
|
||
int curMax = progressList[nextlv] - startExp;
|
||
|
||
info.CurrentExp = curExp;
|
||
info.MaxExpForNextLevel = curMax;
|
||
info.FillAmount = curMax <= 0 ? 0f : curExp / (float)curMax;
|
||
info.CurrentLevel = rewardIndex;
|
||
info.NextLevel = nextlv;
|
||
info.IsAtMaxLevel = false;
|
||
info.HasProgress = true;
|
||
}
|
||
else
|
||
{
|
||
// At max level
|
||
info.CurrentExp = progressList[^1];
|
||
info.MaxExpForNextLevel = progressList[^1];
|
||
info.FillAmount = 1f;
|
||
info.CurrentLevel = rewardIndex;
|
||
info.NextLevel = rewardIndex; // Same as current when at max
|
||
info.IsAtMaxLevel = true;
|
||
info.HasProgress = false;
|
||
}
|
||
info.MaxLevelCount = progressList.Count;
|
||
return info;
|
||
}
|
||
|
||
~MiniBattlePassDataModel()
|
||
{
|
||
Dispose();
|
||
}
|
||
|
||
void Dispose()
|
||
{
|
||
disposables?.Dispose();
|
||
disposables = null;
|
||
}
|
||
}
|
||
|
||
|
||
public class MiniBattlePassRecord
|
||
{
|
||
/// <summary>
|
||
/// 活动ID
|
||
/// </summary>
|
||
public int Id;
|
||
public int RedirectID;
|
||
public int PriceLv;
|
||
public float InflationRate;
|
||
/// <summary>
|
||
/// 普通领奖进度
|
||
/// </summary>
|
||
public List<int> NRIndexs = new List<int>();
|
||
/// <summary>
|
||
/// 是否付费
|
||
/// </summary>
|
||
public bool IsVIP;
|
||
/// <summary>
|
||
/// 付费领奖进度
|
||
/// </summary>
|
||
public List<int> VRIndexs = new List<int>();
|
||
public int oldID;
|
||
public int oldRedirectID;
|
||
public int oldExp;
|
||
public bool oldIsVIP;
|
||
|
||
public List<int> LastDropIDs = new List<int>();
|
||
/// <summary>
|
||
/// 展示过的等级,和新等级之间表现用
|
||
/// </summary>
|
||
public int showIndex;
|
||
/// <summary>
|
||
/// 累计经验
|
||
/// </summary>
|
||
public int Exp;
|
||
}
|