711 lines
23 KiB
C#
711 lines
23 KiB
C#
using System.Linq;
|
|
using GameCore;
|
|
using UnityEngine;
|
|
using System.Collections.Generic;
|
|
using UnityEngine.Assertions;
|
|
using asap.core;
|
|
using game;
|
|
using System.Text;
|
|
using cfg;
|
|
using System;
|
|
|
|
public class EventLuckMagicModel : IHasChainPack, ILuckyTaskGetData, ILuckyTaskUIGetData
|
|
{
|
|
private int _eventId, _ticketCount, _chainProgress, _roundCount;
|
|
|
|
/// <summary>
|
|
/// Position of selection GameObject, or null if hidden.
|
|
/// </summary>
|
|
public Vector2? SelectionState;
|
|
private readonly List<EventLuckMagicRing> _rings = new List<EventLuckMagicRing>();
|
|
public EventLuckMagicRing CurrentRing { get; set; }
|
|
public EventLuckMagicRing OuterRing => _rings[0];
|
|
public EventLuckMagicRing MiddleRing => _rings[1];
|
|
public EventLuckMagicRing InnerRing => _rings[2];
|
|
public EventLuckMagicHigherRingData HigherRingData;
|
|
public Dictionary<EEventLuckMagicRingType, EventLuckMagicRing> RingMap;
|
|
public int TicketCount => _ticketCount;
|
|
public Dictionary<int, int> TaskProgress;
|
|
public const int TaskProgressCount = 3;
|
|
public bool IsGameDepleted => _rings.All(x => x.IsDepleted);
|
|
public bool DoesSkipAnimation = false;
|
|
private DateTime _expiryTime, _startTime;
|
|
public TimeSpan RemainingTime => _expiryTime - ZZTimeHelper.UtcNow();
|
|
public bool IsActive => RemainingTime.TotalSeconds > 0;
|
|
public int EventId => _eventId;
|
|
public int RoundCount => _roundCount;
|
|
public DateTime ExpiryTime => _expiryTime;
|
|
|
|
public EventLuckMagicParamsCtrl ParamsCtrl;
|
|
|
|
public void InitNew(int eventId)
|
|
{
|
|
_eventId = eventId;
|
|
_rings.Clear();
|
|
EventLuckMagicAct.TableContext.GetRingsInfo(out int[] costs, out int[] roadSignIds);
|
|
for (int i = 0; i < costs.Length; i++)
|
|
_rings.Add(EventLuckMagicRing.CreateEmpty(costs[i], roadSignIds[i], (EEventLuckMagicRingType)(i + 1)));
|
|
EventLuckMagicAct.TableContext.GetBlocksInfo(out var infoList);
|
|
RingMap = new Dictionary<EEventLuckMagicRingType, EventLuckMagicRing>()
|
|
{
|
|
{EEventLuckMagicRingType.OuterRing, OuterRing},
|
|
{EEventLuckMagicRingType.MiddleRing, MiddleRing},
|
|
{EEventLuckMagicRingType.InnerRing, InnerRing}
|
|
};
|
|
foreach (var info in infoList)
|
|
{
|
|
RingMap[info.RingType].AddBlock(new EventLuckMagicBlock(info, RingMap[info.RingType]));
|
|
}
|
|
RingMap[EEventLuckMagicRingType.OuterRing].ImportBitWiseBlockState(0);
|
|
RingMap[EEventLuckMagicRingType.MiddleRing].ImportBitWiseBlockState(0);
|
|
RingMap[EEventLuckMagicRingType.InnerRing].ImportBitWiseBlockState(0);
|
|
|
|
HigherRingData = EventLuckMagicHigherRingData.CreateEmpty();
|
|
LinkRings();
|
|
|
|
_ticketCount = EventLuckMagicAct.TableContext.GetWelcomeGift();
|
|
_chainProgress = 0;
|
|
|
|
TaskProgress = GetTaskProgress();
|
|
CurrentRing = _rings.FirstOrDefault(r => !r.IsDepleted) ?? _rings.Last();
|
|
SelectionState = null;
|
|
DoesSkipAnimation = false;
|
|
(_startTime, _expiryTime) = EventLuckMagicAct.TableContext.GetEventStartTimeAndEndTime();
|
|
_roundCount = 0;
|
|
|
|
_taskData?.Dispose();
|
|
_dicTasks = new Dictionary<int, int>();
|
|
_taskData = new LuckyTaskData(this);
|
|
_taskData.InitDicTasks(EventLuckMagicAct.TableContext.GetFirstLuckyTaskIdList());
|
|
}
|
|
|
|
public void Load(EventLuckMagicPlayfabData pfData, EventLuckMagicPlayerPreferenceData ppData)
|
|
{
|
|
_eventId = pfData.EventId;
|
|
EventLuckMagicAct.TableContext.GetRingsInfo(out int[] costs, out int[] roadSignIds);
|
|
for (int i = 0; i < costs.Length; i++)
|
|
_rings.Add(EventLuckMagicRing.CreateEmpty(costs[i], roadSignIds[i], (EEventLuckMagicRingType)(i + 1)));
|
|
EventLuckMagicAct.TableContext.GetBlocksInfo(out var infoList);
|
|
RingMap = new Dictionary<EEventLuckMagicRingType, EventLuckMagicRing>()
|
|
{
|
|
{EEventLuckMagicRingType.OuterRing, OuterRing},
|
|
{EEventLuckMagicRingType.MiddleRing, MiddleRing},
|
|
{EEventLuckMagicRingType.InnerRing, InnerRing}
|
|
};
|
|
foreach (var info in infoList)
|
|
{
|
|
RingMap[info.RingType].AddBlock(new EventLuckMagicBlock(info, RingMap[info.RingType]));
|
|
}
|
|
RingMap[EEventLuckMagicRingType.OuterRing].ImportBitWiseBlockState(pfData.OuterState);
|
|
RingMap[EEventLuckMagicRingType.MiddleRing].ImportBitWiseBlockState(pfData.MiddleState);
|
|
RingMap[EEventLuckMagicRingType.InnerRing].ImportBitWiseBlockState(pfData.InnerState);
|
|
|
|
HigherRingData = EventLuckMagicHigherRingData.Create(RingMap[pfData.HigherRingType], pfData.HigherRingExpireTime.Value);
|
|
LinkRings();
|
|
|
|
_ticketCount = pfData.TicketCount;
|
|
_chainProgress = pfData.ChainProgress;
|
|
_roundCount = pfData.RoundCount;
|
|
|
|
TaskProgress = GetTaskProgress();
|
|
CurrentRing = _rings.FirstOrDefault(r => !r.IsDepleted) ?? _rings.Last();
|
|
ppData ??= EventLuckMagicPlayerPreferenceData.CreateEmpty();
|
|
SelectionState = ppData.SelectionPosition;
|
|
DoesSkipAnimation = ppData.DoesSkipAnimation;
|
|
(_startTime, _expiryTime) = EventLuckMagicAct.TableContext.GetEventStartTimeAndEndTime();
|
|
|
|
_dicTasks = pfData.DicTasks;
|
|
_taskData = new LuckyTaskData(this);
|
|
}
|
|
|
|
public void AddTicket(int num)
|
|
{
|
|
if (_ticketCount + num < 0)
|
|
{
|
|
Debug.Log($"[EventLuckMagic] Try to add {num} ticket(s) failed. Having {_ticketCount} ticket(s) now.");
|
|
return;
|
|
}
|
|
_ticketCount += num;
|
|
GContext.container.Resolve<FishingEventData>().SaveTransitionData(_eventId, _ticketCount);
|
|
ToPfData().Save();
|
|
EventLuckMagicAct.EventAggregator.Publish(new EventLuckMagicTicketChange());
|
|
}
|
|
|
|
public void LinkRings()
|
|
{
|
|
for (int i = 0; i < _rings.Count - 1; i++)
|
|
_rings[i].HigherRing = _rings[i + 1];
|
|
CurrentRing = _rings.FirstOrDefault(r => !r.IsDepleted);
|
|
if (CurrentRing == null)
|
|
{
|
|
Debug.Log($"[EventLuckMagic] Cannot find any available ring. Seems that all rings are depleted.");
|
|
return;
|
|
}
|
|
var r = CurrentRing;
|
|
// The Higher ring of r is the next ring that is not depleted.
|
|
while (r != null && r.HigherRing != null)
|
|
{
|
|
while (r.HigherRing != null && r.HigherRing.IsDepleted)
|
|
{
|
|
r.HigherRing = r.HigherRing.HigherRing;
|
|
}
|
|
r = r.HigherRing;
|
|
}
|
|
}
|
|
|
|
public void UpdateTaskProgress(int targetId)
|
|
{
|
|
TaskProgress[targetId]++;
|
|
// Debug.Log($"[EventLuckMagic] Task progress of {targetId} is {TaskProgress[targetId]}.");
|
|
ToPfData().Save();
|
|
}
|
|
|
|
public bool IsTaskCompleted(int targetId)
|
|
{
|
|
return TaskProgress[targetId] >= TaskProgressCount;
|
|
}
|
|
|
|
public void Reset()
|
|
{
|
|
for (int i = 0; i < _rings.Count; i++)
|
|
_rings[i].Reset();
|
|
HigherRingData.SetEmpty();
|
|
LinkRings();
|
|
HigherRingData.PointTo(CurrentRing.HigherRing);
|
|
HigherRingData.ExpireTime = System.DateTime.MinValue;
|
|
TaskProgress = EventLuckMagicAct.TableContext.GetTaskInfo(GContext.container.Resolve<EventLuckMagicModel>().RoundCount)
|
|
.Keys.ToDictionary(x => x, x => 0);
|
|
CurrentRing = _rings.FirstOrDefault(r => !r.IsDepleted) ?? _rings.Last();
|
|
_taskData.InitDicTasks(EventLuckMagicAct.TableContext.GetLastLuckyTaskIdList());
|
|
|
|
ToPfData().Save();
|
|
}
|
|
|
|
public void SetChainProgress(int p)
|
|
{
|
|
Debug.Log($"[EventLuckMagic]SetProgress {p}");
|
|
_chainProgress = p;
|
|
}
|
|
|
|
public int GetChainProgress()
|
|
{
|
|
return _chainProgress;
|
|
}
|
|
|
|
public void Save()
|
|
{
|
|
ToPfData().Save();
|
|
}
|
|
|
|
public EventLuckMagicPlayerPreferenceData ToPpData()
|
|
{
|
|
return new EventLuckMagicPlayerPreferenceData
|
|
{
|
|
SelectionPosition = SelectionState,
|
|
DoesSkipAnimation = DoesSkipAnimation
|
|
};
|
|
}
|
|
|
|
public EventLuckMagicPlayfabData ToPfData()
|
|
{
|
|
var expireTime = HigherRingData.DoesExist ? HigherRingData.ExpireTime : DateTime.MinValue;
|
|
// var expireTime = HigherRingData.DoesExist ? HigherRingData.ExpireTime : ZZTimeHelper.UtcNow().AddSeconds(-1);
|
|
var ringType = HigherRingData.DoesExist ? HigherRingData.Ring.RingType : EEventLuckMagicRingType.OuterRing;
|
|
return new EventLuckMagicPlayfabData
|
|
{
|
|
EventId = _eventId,
|
|
TicketCount = TicketCount,
|
|
ChainProgress = _chainProgress,
|
|
InnerState = InnerRing.GetBitWiseBlockState(),
|
|
MiddleState = MiddleRing.GetBitWiseBlockState(),
|
|
OuterState = OuterRing.GetBitWiseBlockState(),
|
|
HigherRingExpireTime = expireTime,
|
|
HigherRingType = ringType,
|
|
RoundCount = _roundCount,
|
|
DicTasks = _dicTasks
|
|
};
|
|
}
|
|
|
|
private Dictionary<int, int> GetTaskProgress()
|
|
{
|
|
var taskInfo = EventLuckMagicAct.TableContext.GetTaskInfo(RoundCount);
|
|
var res = taskInfo.ToDictionary(
|
|
kv => kv.Key,
|
|
kv => _rings.Sum(ring => ring.Blocks.Count(x => x.Reward.id == kv.Key && x.IsTaken))
|
|
);
|
|
return res;
|
|
}
|
|
|
|
public EventLuckMagicEntranceData ToEntranceData()
|
|
{
|
|
return new EventLuckMagicEntranceData
|
|
{
|
|
TicketCount = _ticketCount,
|
|
ExpiryTime = _expiryTime,
|
|
Icon = EventLuckMagicAct.TableContext.GetIcon(),
|
|
StartTime = _startTime,
|
|
};
|
|
}
|
|
|
|
public GenericChainPackData<EventLuckMagicModel> ToChainPackData()
|
|
{
|
|
return GenericChainPackData<EventLuckMagicModel>.Create(
|
|
this, EventLuckMagicAct.TableContext.GetChainPackInfo());
|
|
}
|
|
|
|
public void AddRoundCount()
|
|
{
|
|
_roundCount++;
|
|
Save();
|
|
}
|
|
|
|
public void SaveTaskData()
|
|
{
|
|
ToPfData().Save();
|
|
}
|
|
|
|
|
|
#region Lucky Task
|
|
private Dictionary<int, int> _dicTasks;
|
|
private LuckyTaskData _taskData;
|
|
public string LuckyTaskRedPointKey => "eventluckmagic.entrance.luckytask";
|
|
public Dictionary<int, int> DicTasks { get => _dicTasks; set => _dicTasks = value; }
|
|
public string TaskPanelName => "EventLuckyMagicTaskPopupPanel";
|
|
|
|
public bool OnGetTaskReward(int id)
|
|
{
|
|
return _taskData.OnGetTaskReward(id, EventLuckMagicAct.TableContext.GetLastLuckyTaskIdList());
|
|
}
|
|
|
|
public int GetLuckyPackID()
|
|
{
|
|
return EventLuckMagicAct.TableContext.GetPackId();
|
|
}
|
|
|
|
public void DisposeLuckyTaskSubscription()
|
|
{
|
|
_taskData.Dispose();
|
|
}
|
|
#endregion
|
|
|
|
|
|
}
|
|
|
|
public class EventLuckMagicRing
|
|
{
|
|
public readonly int Cost, RoadSignId;
|
|
public List<EventLuckMagicBlock> Blocks;
|
|
public bool IsDepleted => Blocks.All(x => x.IsTaken || EventLuckMagicAct.TableContext.IsRewardRoadSign(x.Reward.id, out _, out _, out _));
|
|
public readonly EEventLuckMagicRingType RingType;
|
|
public EventLuckMagicRing HigherRing { get; set; }
|
|
public int[] CornerIndices = new int[4];
|
|
|
|
private int BlockCount => Blocks.Count;
|
|
|
|
public int AvailableBlockCount => Blocks.Count(x => !x.IsTaken);
|
|
|
|
private EventLuckMagicRing(int cost, int roadSignId, EEventLuckMagicRingType ringType)
|
|
{
|
|
Blocks = new List<EventLuckMagicBlock>();
|
|
Cost = cost;
|
|
RoadSignId = roadSignId;
|
|
RingType = ringType;
|
|
HigherRing = null;
|
|
}
|
|
|
|
public static EventLuckMagicRing CreateEmpty(int cost, int roadSignId, EEventLuckMagicRingType ringType)
|
|
{
|
|
return new EventLuckMagicRing(cost, roadSignId, ringType);
|
|
}
|
|
|
|
public void AddBlock(EventLuckMagicBlock block)
|
|
{
|
|
Blocks.Add(block);
|
|
}
|
|
|
|
public void Reset()
|
|
{
|
|
Blocks.ForEach(x => x.Reset());
|
|
}
|
|
|
|
public void GetLoopAnimationInfo(int targetIdx, int extraLoopCount, out int startIdx, out int totalMovementCount)
|
|
{
|
|
int idx = 0, gap = BlockCount / 4;
|
|
startIdx = 0;
|
|
while (idx < BlockCount)
|
|
{
|
|
idx += gap;
|
|
if (GetShortestDistance(idx, targetIdx) > GetShortestDistance(startIdx, targetIdx))
|
|
startIdx = idx;
|
|
}
|
|
totalMovementCount = GetClockWiseDistance(startIdx, targetIdx) + extraLoopCount * BlockCount;
|
|
}
|
|
|
|
private int GetClockWiseDistance(int startIdx, int endIdx)
|
|
{
|
|
Assert.IsTrue(startIdx >= 0 && startIdx < BlockCount && endIdx >= 0 && endIdx < BlockCount);
|
|
return (endIdx - startIdx + BlockCount) % BlockCount;
|
|
}
|
|
|
|
private int GetShortestDistance(int startIdx, int endIdx)
|
|
{
|
|
int d = Mathf.Abs(startIdx - endIdx);
|
|
d = d > BlockCount / 2 ? BlockCount - d : d;
|
|
return d;
|
|
}
|
|
|
|
public int GetBitWiseBlockState()
|
|
{
|
|
var res = 0;
|
|
for (int i = 0; i < BlockCount; i++)
|
|
{
|
|
if (Blocks[i].IsTaken)
|
|
res |= 1 << i;
|
|
}
|
|
return res;
|
|
}
|
|
|
|
public void ImportBitWiseBlockState(int state)
|
|
{
|
|
for (int i = 0; i < BlockCount; i++)
|
|
{
|
|
if ((state & (1 << i)) != 0)
|
|
Blocks[i].Take();
|
|
else
|
|
Blocks[i].Reset();
|
|
}
|
|
}
|
|
}
|
|
|
|
public class EventLuckMagicBlock
|
|
{
|
|
public int TableId;
|
|
public readonly ItemData Reward;
|
|
private bool _isTaken;
|
|
public bool IsTaken
|
|
{
|
|
get
|
|
{
|
|
if (EventLuckMagicAct.TableContext.IsRewardRoadSign(Reward.id, out _, out _, out _))
|
|
return ParentRing == null || ParentRing.HigherRing == null || ParentRing.HigherRing.IsDepleted;
|
|
return _isTaken;
|
|
}
|
|
}
|
|
|
|
private int _weight;
|
|
public int Weight
|
|
{
|
|
get
|
|
{
|
|
if (EventLuckMagicAct.TableContext.IsRewardRoadSign(Reward.id, out _, out _, out var weightConfig))
|
|
{
|
|
if (weightConfig.Length != 2)
|
|
return _weight;
|
|
return ParentRing.AvailableBlockCount <= weightConfig[0] ? weightConfig[1] : _weight;
|
|
}
|
|
return _weight;
|
|
}
|
|
set
|
|
{
|
|
_weight = value;
|
|
}
|
|
}
|
|
public EEventLuckMagicBlockType BlockType;
|
|
/// <summary>
|
|
/// The ring this block belongs to.
|
|
/// </summary>
|
|
public EventLuckMagicRing ParentRing { get; }
|
|
|
|
public EventLuckMagicBlock(EventLuckMagicBlockInfo info, EventLuckMagicRing parentRing)
|
|
{
|
|
Reward = info.Reward;
|
|
Weight = info.Weight;
|
|
BlockType = GetBlockType(info.RingType, info.Reward.id);
|
|
ParentRing = parentRing;
|
|
TableId = info.TableId;
|
|
// _isTaken = isTaken;
|
|
}
|
|
|
|
public void Take()
|
|
{
|
|
_isTaken = true;
|
|
}
|
|
|
|
private static EEventLuckMagicBlockType GetBlockType(EEventLuckMagicRingType ringType, int rewardId)
|
|
{
|
|
if (EventLuckMagicAct.TableContext.IsRewardRoadSign(ringType, rewardId))
|
|
return EEventLuckMagicBlockType.RoadSign;
|
|
else
|
|
return (EEventLuckMagicBlockType)(ringType - 1);
|
|
}
|
|
|
|
public void Reset()
|
|
{
|
|
_isTaken = false;
|
|
}
|
|
}
|
|
|
|
public class EventLuckMagicHigherRingData
|
|
{
|
|
public EventLuckMagicRing Ring { get; set; }
|
|
public System.DateTime ExpireTime;
|
|
public System.TimeSpan RemainingTime => ExpireTime - ZZTimeHelper.UtcNow();
|
|
public bool DoesExist => Ring != null && !Ring.IsDepleted && RemainingTime.TotalSeconds > 0;
|
|
|
|
private EventLuckMagicHigherRingData() { }
|
|
|
|
public void PointTo(EventLuckMagicRing ring)
|
|
{
|
|
Ring = ring;
|
|
}
|
|
|
|
public void Activate(int expireDuration)
|
|
{
|
|
ExpireTime = ZZTimeHelper.UtcNow().AddSeconds(expireDuration);
|
|
}
|
|
|
|
public void SetEmpty()
|
|
{
|
|
Ring = null;
|
|
ExpireTime = ZZTimeHelper.UtcNow().AddSeconds(-5);
|
|
}
|
|
|
|
public static EventLuckMagicHigherRingData CreateEmpty()
|
|
{
|
|
var res = new EventLuckMagicHigherRingData();
|
|
res.SetEmpty();
|
|
return res;
|
|
}
|
|
|
|
public static EventLuckMagicHigherRingData Create(EventLuckMagicRing ring, System.DateTime? expireTime)
|
|
{
|
|
var res = new EventLuckMagicHigherRingData();
|
|
res.PointTo(ring);
|
|
if (expireTime != null)
|
|
res.ExpireTime = expireTime.Value;
|
|
else
|
|
res.ExpireTime = ZZTimeHelper.UtcNow().AddSeconds(-4);
|
|
return res;
|
|
}
|
|
}
|
|
|
|
public class EventLuckMagicPanelData
|
|
{
|
|
public EventLuckMagicTableContext TableContext;
|
|
public EventLuckMagicModel Model;
|
|
public EventLuckMagicSystem System;
|
|
public EventLuckMagicParamsCtrl ParamsCtrl;
|
|
public IEventAggregator EventAggregator;
|
|
public Vector2? SelectionPosition;
|
|
}
|
|
|
|
public class EventLuckMagicSpinParams
|
|
{
|
|
public float MaxInterval;
|
|
public float MinInterval;
|
|
public int ExtraLoopCount;
|
|
public AnimationCurve IntervalLerpCurve;
|
|
}
|
|
|
|
public class EventLuckMagicSpinCtx
|
|
{
|
|
public EventLuckMagicRing Ring;
|
|
public int Index;
|
|
public ItemData Reward;
|
|
public bool doesHideButton;
|
|
public int RoundCount;
|
|
}
|
|
|
|
public class EventRewardFlyStashRequest
|
|
{
|
|
public ItemData Reward;
|
|
public bool DoesPlayOpen;
|
|
// public Vector2 Position;
|
|
// public float SourceIconSize;
|
|
public RectTransform SourceIconRt;
|
|
public RectTransform SourceTextRt;
|
|
public EventRewardFlyStashRequest(ItemData reward, RectTransform sourceIconRt, bool doesPlayOpen = true, RectTransform sourceTextRt = null)
|
|
{
|
|
Reward = reward;
|
|
DoesPlayOpen = doesPlayOpen;
|
|
SourceIconRt = sourceIconRt;
|
|
SourceTextRt = sourceTextRt;
|
|
}
|
|
}
|
|
|
|
public class EventLuckMagicPlayfabData
|
|
{
|
|
public int EventId;
|
|
public int TicketCount;
|
|
public int ChainProgress;
|
|
public int InnerState, MiddleState, OuterState;
|
|
public int RoundCount;
|
|
public System.DateTime? HigherRingExpireTime;
|
|
public EEventLuckMagicRingType HigherRingType;
|
|
public Dictionary<int, int> DicTasks;
|
|
|
|
public const string Key = "EventLuckMagicPlayfabData";
|
|
private const string Splitter = "|", Comma = ",";
|
|
private const int Count = 11;
|
|
|
|
public string Serialize()
|
|
{
|
|
var sb = new StringBuilder();
|
|
sb.Append(EventId).Append(Splitter);
|
|
sb.Append(TicketCount).Append(Splitter);
|
|
sb.Append(ChainProgress).Append(Splitter);
|
|
sb.Append(InnerState).Append(Splitter);
|
|
sb.Append(MiddleState).Append(Splitter);
|
|
sb.Append(OuterState).Append(Splitter);
|
|
sb.Append(HigherRingExpireTime).Append(Splitter);
|
|
sb.Append((int)HigherRingType).Append(Splitter);
|
|
sb.Append(RoundCount).Append(Splitter);
|
|
if (DicTasks != null)
|
|
{
|
|
foreach (var kv in DicTasks)
|
|
sb.Append(kv.Key).Append(Comma);
|
|
sb.Append(Splitter);
|
|
foreach (var kv in DicTasks)
|
|
sb.Append(kv.Value).Append(Comma);
|
|
}
|
|
return sb.ToString();
|
|
}
|
|
|
|
public static EventLuckMagicPlayfabData Deserialize(string s)
|
|
{
|
|
try
|
|
{
|
|
if (s == null || s == "")
|
|
return null;
|
|
var tokens = s.Trim(Splitter.ToCharArray()).Split(Splitter);
|
|
if (tokens.Length != Count)
|
|
{
|
|
var e = new Exception($"[EventLuckMagic]Wrong amount of parameters. Expect {Count}, but got {tokens.Length} in \"{s}\".");
|
|
Debug.LogError(e);
|
|
return null;
|
|
}
|
|
// Debug.Log($"[EventLuckMagic] time string:{tokens[6]}");
|
|
var keyList = tokens[9].Trim(Comma[0]).Split(Comma).Select(int.Parse).ToList();
|
|
var valueList = tokens[10].Trim(Comma[0]).Split(Comma).Select(int.Parse).ToList();
|
|
if (keyList == null || valueList == null || keyList.Count != valueList.Count)
|
|
{
|
|
var e = new Exception($"[EventLuckMagic]Dictionary Error.");
|
|
Debug.LogError(e);
|
|
return null;
|
|
}
|
|
var dicTasks = new Dictionary<int, int>();
|
|
for (int i = 0; i < keyList.Count; i++)
|
|
dicTasks.Add(keyList[i], valueList[i]);
|
|
return new EventLuckMagicPlayfabData
|
|
{
|
|
EventId = int.Parse(tokens[0]),
|
|
TicketCount = int.Parse(tokens[1]),
|
|
ChainProgress = int.Parse(tokens[2]),
|
|
InnerState = int.Parse(tokens[3]),
|
|
MiddleState = int.Parse(tokens[4]),
|
|
OuterState = int.Parse(tokens[5]),
|
|
HigherRingExpireTime = ParseTime(tokens[6]),
|
|
HigherRingType = (EEventLuckMagicRingType)int.Parse(tokens[7]),
|
|
RoundCount = int.Parse(tokens[8]),
|
|
DicTasks = dicTasks
|
|
};
|
|
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Debug.Log($"[EventLuckMagic] Deserialize error: ");
|
|
Debug.LogError(e);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private static System.DateTime ParseTime(string timeString)
|
|
{
|
|
if (timeString == "")
|
|
return System.DateTime.MinValue;
|
|
else
|
|
try
|
|
{
|
|
return System.DateTime.Parse(timeString);
|
|
}
|
|
catch
|
|
{
|
|
Debug.LogError($"[EventLuckMagic] Failed to parse time string \"{timeString}\"");
|
|
return System.DateTime.MinValue;
|
|
}
|
|
}
|
|
|
|
public void Save()
|
|
{
|
|
var s = Serialize();
|
|
// Debug.Log($"[EventLuckMagic] Save playfab data : \n" + s);
|
|
PlayFabMgr.Instance.UpdateUserDataValue(Key, s);
|
|
}
|
|
}
|
|
|
|
public class EventLuckMagicPlayerPreferenceData
|
|
{
|
|
public Vector2? SelectionPosition;
|
|
public bool DoesSkipAnimation;
|
|
public static string Key => "EventLuckMagic" + GContext.container.Resolve<IUserService>().UserId;
|
|
private const char Splitter = '|', Comma = ',';
|
|
|
|
public static EventLuckMagicPlayerPreferenceData CreateEmpty()
|
|
{
|
|
var res = new EventLuckMagicPlayerPreferenceData();
|
|
res.SelectionPosition = null;
|
|
res.DoesSkipAnimation = false;
|
|
return res;
|
|
}
|
|
|
|
public string Serialize()
|
|
{
|
|
var sb = new StringBuilder();
|
|
sb.Append(DoesSkipAnimation).Append(Splitter);
|
|
if (SelectionPosition != null)
|
|
sb.Append(SelectionPosition.Value.x).Append(Comma).Append(SelectionPosition.Value.y).Append(Splitter);
|
|
return sb.ToString();
|
|
}
|
|
|
|
public static EventLuckMagicPlayerPreferenceData Deserialize(string s)
|
|
{
|
|
var res = new EventLuckMagicPlayerPreferenceData();
|
|
if (s == null || s == "")
|
|
return res;
|
|
try
|
|
{
|
|
var tokens = s.Trim(Splitter).Split(Splitter);
|
|
res.DoesSkipAnimation = bool.Parse(tokens[0]);
|
|
if (tokens.Length > 1)
|
|
{
|
|
var posTokens = tokens[1].Split(Comma);
|
|
res.SelectionPosition = new Vector2(float.Parse(posTokens[0]), float.Parse(posTokens[1]));
|
|
}
|
|
else
|
|
res.SelectionPosition = null;
|
|
}
|
|
catch (System.Exception e)
|
|
{
|
|
Debug.LogError($"[EventLuckMagic] Failed to deserialize:");
|
|
Debug.LogError(e);
|
|
}
|
|
return res;
|
|
}
|
|
|
|
public void Save()
|
|
{
|
|
var s = Serialize();
|
|
PlayerPrefs.SetString(Key, s);
|
|
}
|
|
}
|
|
|
|
public class EventLuckMagicEntranceData
|
|
{
|
|
public int TicketCount;
|
|
public DateTime ExpiryTime;
|
|
public DateTime StartTime;
|
|
public TimeSpan RemainingTime => ExpiryTime - ZZTimeHelper.UtcNow();
|
|
public bool IsActive => ZZTimeHelper.UtcNow() >= StartTime && ZZTimeHelper.UtcNow() < ExpiryTime;
|
|
public string Icon;
|
|
}
|