using System.Collections.Generic; using System; using cfg; using GameCore; using UnityEngine.Assertions; using asap.core; using UnityEngine; using System.Linq; public class GenericChainPackData : IChainPackData where T : IHasChainPack { protected const int SlotCount = 6; protected List ChainList { get; set; } protected DateTime ExpireTime { get; set; } protected Pack[] Packs { get; set; } public bool IsEndGame => ChainProgress > ChainListCount - SlotCount; public int ChainListCount => ChainList.Count; private readonly T _rawData; public int ChainProgress { get { return _rawData.GetChainProgress(); } set { _rawData.SetChainProgress(value); } } public int EventId { get; set; } public TimeSpan RemainingTime => ExpireTime - ZZTimeHelper.UtcNow(); public bool IsChainPackDepleted => ChainProgress >= ChainListCount; public bool DoNeedPackRedPoint { get { if (!IsChainPackDepleted && ChainProgress < ChainListCount) return Packs[ChainProgress].IAPID == 0; return false; } } private string _redPointKey = "eventcan.pack"; public string RedPointKey => _redPointKey; public static GenericChainPackData Create(T data, EventChainPackInfo info) { return new GenericChainPackData(data, info); } private GenericChainPackData(T data, EventChainPackInfo info) { EventId = data.EventId; _rawData = data; ChainList = info.ChainList; ExpireTime = info.ExpireTime; Packs = info.Packs; _redPointKey = info.RedPointKey; } public Pack GetChainPackByChainProgress(int chainProgress) { return Packs[chainProgress]; } public int GetChainProgressBySlotIdx(int slotIdx) { int res; if (ChainProgress > ChainList.Count - SlotCount) res = ChainList.Count - SlotCount + slotIdx; else res = ChainProgress + slotIdx; Assert.IsTrue(res < ChainList.Count, $"Progress {res} out of range: {ChainListCount}"); return res; } public List GetItemsByPackDropId(int dropId) { throw new NotImplementedException(); } public List GetTokenProgressRewardAfterAddingToken(int tokenAdded) { throw new NotImplementedException(); } public void OnBuySuccess() { // Debug.Log($"[EventLuckMagic] 2nd: {this.GetHashCode()}"); ChainProgress++; UploadData(); } public void UploadData() { _rawData.Save(); } } [Obsolete] public abstract class AChainPackData : IChainPackData { public AChainPackData() { } protected const int SlotCount = 6; protected List ChainList { get; set; } protected DateTime ExpireTime { get; set; } protected Pack[] Packs { get; set; } public bool IsEndGame => ChainProgress > ChainListCount - SlotCount; public int ChainListCount => ChainList.Count; public int ChainProgress { get; set; } public int EventId { get; set; } public TimeSpan RemainingTime => ExpireTime - ZZTimeHelper.UtcNow(); public bool IsChainPackDepleted => ChainProgress >= ChainListCount; public bool DoNeedPackRedPoint { get { if (!IsChainPackDepleted && ChainProgress < ChainListCount) return Packs[ChainProgress].IAPID == 0; return false; } } public string RedPointKey => "eventcan.pack"; public AChainPackData(int eventId, int chainProgress) { EventId = eventId; ChainProgress = chainProgress; } public Pack GetChainPackByChainProgress(int chainProgress) { return Packs[chainProgress]; } public int GetChainProgressBySlotIdx(int slotIdx) { int res; if (ChainProgress > ChainList.Count - SlotCount) res = ChainList.Count - SlotCount + slotIdx; else res = ChainProgress + slotIdx; Assert.IsTrue(res < ChainList.Count, $"Progress {res} out of range: {ChainListCount}"); return res; } public List GetItemsByPackDropId(int dropId) { throw new NotImplementedException(); } public List GetTokenProgressRewardAfterAddingToken(int tokenAdded) { throw new NotImplementedException(); } public void OnBuySuccess() { ChainProgress++; UploadData(); } abstract public void UploadData(); } public interface IChainPackData { public bool IsEndGame { get; } public Pack GetChainPackByChainProgress(int chainProgress); public int GetChainProgressBySlotIdx(int slotIdx); public int ChainListCount { get; } public int ChainProgress { get; set; } public int EventId { get; } public List GetTokenProgressRewardAfterAddingToken(int tokenAdded); public void UploadData(); public TimeSpan RemainingTime { get; } public bool IsChainPackDepleted { get; } public void OnBuySuccess(); public bool DoNeedPackRedPoint { get; } public string RedPointKey { get; } public List GetItemsByPackDropId(int dropId); } public interface IHasChainPack { public int EventId { get; } public void SetChainProgress(int p); public int GetChainProgress(); public void Save(); } public class EventChainPackInfo { public List ChainList { get; set; } public DateTime ExpireTime { get; set; } public Pack[] Packs { get; set; } public string RedPointKey { get; set; } } public interface IProgressChainPackData : IChainPackData { public int TokenProgress { get; } public int GetTokenProgressTargetByIdx(int idx); public void GetTokenProgressTargetByProgress(int progress, out int targetDisplay, out int scoreDisplay); public int GetRewardDropByChainProgress(int chainProgress); public string TokenIconUrl { get; } public void AddToken(int count); } public interface IHasProgressChainPack : IHasChainPack { public int PackId { get; } public void SetTaskProgress(int p); public int GetTaskProgress(); } public class GenericChainPackWithProgressData : IProgressChainPackData where T : IHasProgressChainPack { private T _rawData; public int TokenProgress { get { return _rawData.GetTaskProgress(); } set { _rawData.SetTaskProgress(value); } } public const int SlotCount = 6; private readonly Tables _tables = GContext.container.Resolve(); private readonly TbFishingEvent _fishingEvent = GContext.container.Resolve().TbFishingEvent; private readonly TbEventPackManager _eventPackManager = GContext.container.Resolve().TbEventPackManager; private readonly TbPack _tablePack = GContext.container.Resolve().TbPack; private readonly PlayerItemData _playerItemData = GContext.container.Resolve(); private List MileStoneList => GContext.container.Resolve().TbEventPackManager[_rawData.PackId].MilestoneList; private Pack[] _packs; protected List ChainList; private DateTime _expireTime; private string _redPointKey = "This should be overridden."; private GenericChainPackWithProgressData(T data, EventChainPackInfo info) { EventId = data.EventId; _rawData = data; ChainList = info.ChainList; _expireTime = info.ExpireTime; _packs = info.Packs; _redPointKey = info.RedPointKey; } public bool DoNeedPackRedPoint { get { if (!IsChainPackDepleted && ChainProgress < ChainListCount) return _packs[ChainProgress].IAPID == 0; return false; } } public string TokenIconUrl { get { int tokenId = _tables.TbDrop[_tablePack[ChainList[0]].DropID].DropList.DropIDList[0]; var emp = _eventPackManager[_rawData.PackId]; if (emp?.MilestoneItem?.Count >= 2 && tokenId == _eventPackManager[_rawData.PackId].MilestoneItem[0]) tokenId = _eventPackManager[_rawData.PackId].MilestoneItem[1]; return _tables.TbItem[tokenId].Icon; } } public bool IsEndGame => ChainProgress > ChainListCount - SlotCount; public int ChainListCount => _eventPackManager[_rawData.PackId].VIPPackList[0].Count; public int ChainProgress { get { return _rawData.GetChainProgress(); } set { _rawData.SetChainProgress(value); } } public int EventId { get; set; } public TimeSpan RemainingTime => _expireTime - ZZTimeHelper.UtcNow(); public bool IsChainPackDepleted => ChainProgress >= ChainListCount; public string RedPointKey => _redPointKey; public void AddToken(int count) { // TODO: Add negative detection? var c = _rawData.GetChainProgress() + count; _rawData.SetChainProgress(c); } public static GenericChainPackWithProgressData Create(T data, EventChainPackInfo info) { return new GenericChainPackWithProgressData(data, info); } public Pack GetChainPackByChainProgress(int chainProgress) { return _packs[chainProgress]; } public int GetChainProgressBySlotIdx(int slotIdx) { int res; if (ChainProgress > ChainList.Count - SlotCount) res = ChainList.Count - SlotCount + slotIdx; else res = ChainProgress + slotIdx; Assert.IsTrue(res < ChainList.Count, $"Progress {res} out of range: {ChainListCount}"); return res; } public List GetItemsByPackDropId(int dropId) { var res = new List(); if (!_tables.TbDrop.DataMap.TryGetValue(dropId, out var drop)) { Debug.Log($"Drop id {dropId} not found."); return res; } if (drop.Type != DropType.Probability) { Debug.Log($"Unsupported drop type {drop.Type} from drop Id {dropId}."); return res; } try { int n = drop.DropList.DropIDList.Count; for (int i = 0; i < n; i++) { var itemId = drop.DropList.DropIDList[i]; var mileStoneItem = _eventPackManager[_rawData.PackId].MilestoneItem; // if (!mileStoneItem.IsNullOrEmpty() && mileStoneItem.Count >= 2 && itemId == mileStoneItem[0]) if (mileStoneItem != null && mileStoneItem.Count >= 2 && itemId == mileStoneItem[0]) { itemId = mileStoneItem[1]; } res.Add(new ItemData(itemId, drop.DropList.DropCountList[i])); _playerItemData.ItemTransition(res[i]); } } catch (Exception e) { Debug.LogError($"[ChainPackW]Invalid drop id {drop}: {e.Message}\n{e.StackTrace}"); return res; } return res; } public int GetRewardDropByChainProgress(int chainProgress) { int i, sum = 0; // var mileStoneList = _eventPackManager[_data.RedirectId].MilestoneList; for (i = 0; i < MileStoneList.Count - 1; i++) { sum += MileStoneList[i]; if (chainProgress < sum) break; } var mileStoneRewards = _eventPackManager[_rawData.PackId].MilestoneReward; return mileStoneRewards[i]; } public List GetTokenProgressRewardAfterAddingToken(int tokenAdded) { // Debug.Log($"Add {tokenAdded}"); int previousTokenProgress = TokenProgress - tokenAdded, i, sum = 0, previousIdx = -1, currentIdx = -1; for (i = 0; i < MileStoneList.Count; i++) { sum += MileStoneList[i]; if (previousIdx == -1 && previousTokenProgress < sum) previousIdx = i; if (currentIdx == -1 && TokenProgress < sum) currentIdx = i; } if (currentIdx == -1 && TokenProgress >= sum) currentIdx = MileStoneList.Count; if (previousIdx == -1 && previousTokenProgress >= sum) previousIdx = MileStoneList.Count; // Debug.Log($"current:{currentIdx}, previous {previousIdx}"); int count = Math.Max(0, currentIdx - previousIdx); if (count > 0) { var res = _eventPackManager[_rawData.PackId].MilestoneReward.GetRange(previousIdx, count); return res; } return new List(); // Debug.Log($"Progress Reward Length: {res.Count}, or {count}"); } public int GetTokenProgressTargetByIdx(int idx) { if (idx < MileStoneList.Count) return MileStoneList.GetRange(0, idx + 1).Sum(); Debug.LogError($"Index {idx} is not within the scale of list length {MileStoneList.Count}"); return -1; } public void GetTokenProgressTargetByProgress(int progress, out int targetDisplay, out int scoreDisplay) { // var mileStoneList = _eventPackManager[_data.RedirectId].MilestoneList; // Debug.Log($"VS: {progress}"); int i = 0, accTarget = 0; while (i < MileStoneList.Count) { accTarget += MileStoneList[i]; if (accTarget > progress) { targetDisplay = MileStoneList[i]; scoreDisplay = progress - MileStoneList.GetRange(0, i).Sum(); // Debug.Log($"Within: {scoreDisplay} / {targetDisplay}"); return; } i++; } targetDisplay = MileStoneList[^1]; scoreDisplay = targetDisplay; // Debug.Log($"Out: {scoreDisplay} / {targetDisplay}"); } public void OnBuySuccess() { if (ChainProgress >= ChainListCount) { Debug.LogError($"Trying to buy pack no.{ChainProgress} while there are/is only {ChainListCount} packs."); return; } int tokenAdded = _tables.TbDrop[GetChainPackByChainProgress(ChainProgress).DropID].DropList.DropCountList[0]; ChainProgress++; var dropList = GetTokenProgressRewardAfterAddingToken(tokenAdded); _playerItemData.AddItemByDropList(dropList, false); } public void UploadData() { _rawData.Save(); } }