备份CatanBuilding瘦身独立工程
This commit is contained in:
57
Assets/Scripts/EventBingo/BingoRng.cs
Normal file
57
Assets/Scripts/EventBingo/BingoRng.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
public class TrackedRng
|
||||
{
|
||||
private readonly System.Random _rng;
|
||||
private readonly int _seed;
|
||||
private int _stepCount;
|
||||
public int Seed => _seed;
|
||||
public int StepCount => _stepCount;
|
||||
public TrackedRngState State => new TrackedRngState() { Seed = _seed, StepCount = _stepCount };
|
||||
|
||||
public TrackedRng(int seed, int stepCount = 0)
|
||||
{
|
||||
_rng = new System.Random(seed);
|
||||
_seed = seed;
|
||||
_stepCount = stepCount;
|
||||
while (stepCount-- > 0)
|
||||
_rng.Next();
|
||||
}
|
||||
|
||||
public TrackedRng(TrackedRngState state)
|
||||
{
|
||||
_rng = new System.Random(state.Seed);
|
||||
_seed = state.Seed;
|
||||
_stepCount = state.StepCount;
|
||||
while (state.StepCount-- > 0)
|
||||
_rng.Next();
|
||||
}
|
||||
|
||||
public int Next()
|
||||
{
|
||||
_stepCount++;
|
||||
return _rng.Next();
|
||||
}
|
||||
|
||||
public int Next(int maxValue)
|
||||
{
|
||||
_stepCount++;
|
||||
return _rng.Next(maxValue);
|
||||
}
|
||||
|
||||
public int Next(int minValue, int maxValue)
|
||||
{
|
||||
_stepCount++;
|
||||
return _rng.Next(minValue, maxValue);
|
||||
}
|
||||
|
||||
/* private void AdvanceBySteps(int stepCount)
|
||||
{
|
||||
while (stepCount-- > 0)
|
||||
_rng.Next();
|
||||
} */
|
||||
}
|
||||
|
||||
public class TrackedRngState
|
||||
{
|
||||
public int StepCount = 0;
|
||||
public int Seed;
|
||||
}
|
||||
11
Assets/Scripts/EventBingo/BingoRng.cs.meta
Normal file
11
Assets/Scripts/EventBingo/BingoRng.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 98d806ad5f3ae3b409d2ffc761f0a93e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
60
Assets/Scripts/EventBingo/BingoTimer.cs
Normal file
60
Assets/Scripts/EventBingo/BingoTimer.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using UniRx;
|
||||
|
||||
public class BingoTimer : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private TMP_Text textTimer;
|
||||
private DateTime _expireTime;
|
||||
private DateTime _startTime;
|
||||
private TimeSpan RemainingTime => _expireTime - ZZTimeHelper.UtcNow();
|
||||
private Action _onExpire;
|
||||
private bool IsActive
|
||||
{
|
||||
get
|
||||
{
|
||||
var res = _expireTime > ZZTimeHelper.UtcNow();
|
||||
if (_startTime != null)
|
||||
res &= _startTime < ZZTimeHelper.UtcNow();
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
public void Init(ITimerContext ctx)
|
||||
{
|
||||
_expireTime = ctx.ExpiryTime;
|
||||
_startTime = ctx.StartTime;
|
||||
_onExpire = ctx.OnExpire;
|
||||
UpdateTimer();
|
||||
Observable.Interval(TimeSpan.FromSeconds(1)).Subscribe(UpdateTimer).AddTo(this);
|
||||
}
|
||||
|
||||
private void UpdateTimer(long _ = 0L)
|
||||
{
|
||||
textTimer.text = ConvertTools.ConvertTime2(RemainingTime);
|
||||
if (!IsActive)
|
||||
{
|
||||
_onExpire?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
private void Reset()
|
||||
{
|
||||
textTimer = GetComponent<TMP_Text>();
|
||||
}
|
||||
}
|
||||
|
||||
public class TimerContext : ITimerContext
|
||||
{
|
||||
public DateTime ExpiryTime { get; set; }
|
||||
public DateTime StartTime { get; set; }
|
||||
public Action OnExpire { get; set; }
|
||||
}
|
||||
|
||||
public interface ITimerContext
|
||||
{
|
||||
public DateTime ExpiryTime { get; }
|
||||
public DateTime StartTime { get; }
|
||||
public Action OnExpire { get; }
|
||||
}
|
||||
11
Assets/Scripts/EventBingo/BingoTimer.cs.meta
Normal file
11
Assets/Scripts/EventBingo/BingoTimer.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2c3fd4c81bcb87c4ca3b5b9bef70bce5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
41
Assets/Scripts/EventBingo/EventBingoAct.cs
Normal file
41
Assets/Scripts/EventBingo/EventBingoAct.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using asap.core;
|
||||
using GameCore;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine.UI;
|
||||
using DG.Tweening;
|
||||
using UnityEngine;
|
||||
|
||||
public class EventBingoAct : AGameAct
|
||||
{
|
||||
public static IEventAggregator EventAggregator = new EventAggregator();
|
||||
public readonly static string ActAddressable = "EventBingoAct";
|
||||
private CanvasScaler _canvasScaler;
|
||||
private readonly float normalScale = 0.75f, actScale = 1.0f, duration = 0.75f;
|
||||
private readonly Vector2 targetResolution = new Vector2(1080, 2340);
|
||||
private Vector2 originalResolution;
|
||||
public override async Task<bool> StartAsync()
|
||||
{
|
||||
GContext.container.Resolve<IDeferredRewardStashService>().Reset();
|
||||
_canvasScaler = UIManager.Instance.GetComponent<CanvasScaler>();
|
||||
// DOTween.To(() => _canvasScaler.matchWidthOrHeight, v => _canvasScaler.matchWidthOrHeight = v, actScale, duration).SetEase(Ease.OutQuad);
|
||||
originalResolution = _canvasScaler.referenceResolution;
|
||||
DOTween.To(() => _canvasScaler.referenceResolution, v => _canvasScaler.referenceResolution = v, targetResolution, duration).SetEase(Ease.OutQuad);
|
||||
var panelGo = await UIManager.Instance.ShowUILoad(UITypes.EventBingoPanel);
|
||||
var panel = panelGo.GetComponent<EventBingoPanel>();
|
||||
panel.Init();
|
||||
var bingoModel = GContext.container.Resolve<EventBingoModel>();
|
||||
if (bingoModel is { IsFirstTime: true })
|
||||
{
|
||||
await UIManager.Instance.ShowUINotLoading(UITypes.EventBingoInfoPanel);
|
||||
bingoModel.SetFirstTimeFlag();
|
||||
}
|
||||
return await base.StartAsync();
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
// DOTween.To(() => _canvasScaler.matchWidthOrHeight, v => _canvasScaler.matchWidthOrHeight = v, normalScale, duration).SetEase(Ease.OutQuad);
|
||||
DOTween.To(() => _canvasScaler.referenceResolution, v => _canvasScaler.referenceResolution = v, originalResolution, duration).SetEase(Ease.OutQuad);
|
||||
UIManager.Instance.DestroyUI(UITypes.EventBingoPanel);
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/EventBingo/EventBingoAct.cs.meta
Normal file
11
Assets/Scripts/EventBingo/EventBingoAct.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 94dcbd2776e372a4aad6e8dceb7a99dd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
13
Assets/Scripts/EventBingo/EventBingoBaseballFly.cs
Normal file
13
Assets/Scripts/EventBingo/EventBingoBaseballFly.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
public class EventBingoBaseballFly : RewardFly
|
||||
{
|
||||
public override async Task ShowAsync(CollectionItemFly itemFly)
|
||||
{
|
||||
Vector2 direction = itemFly.destPos - itemFly.sourcePos;
|
||||
direction.Normalize();
|
||||
transform.rotation = Quaternion.FromToRotation(Vector2.right, direction);
|
||||
await base.ShowAsync(itemFly);
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/EventBingo/EventBingoBaseballFly.cs.meta
Normal file
11
Assets/Scripts/EventBingo/EventBingoBaseballFly.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dc430e3374283824ca9abb6606efc01a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
149
Assets/Scripts/EventBingo/EventBingoBlockView.cs
Normal file
149
Assets/Scripts/EventBingo/EventBingoBlockView.cs
Normal file
@@ -0,0 +1,149 @@
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using GameCore;
|
||||
using asap.core;
|
||||
using cfg;
|
||||
using UniRx;
|
||||
|
||||
public class EventBingoBlockView : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private TMP_Text numberWhite, numberYellow;
|
||||
[SerializeField] private GameObject bingoGo;
|
||||
[SerializeField] private Image rewardIcon, imgNumberItem;
|
||||
[SerializeField] private CardLogoNum rewardIconCard;
|
||||
[SerializeField] private Animation ani;
|
||||
public Image RewardIcon => rewardIcon;
|
||||
private int _number;
|
||||
private EventBingoNumberItemFlyData _flyData;
|
||||
private const string StandBy = "baseball_normal",
|
||||
NearBingo = "baseball_flash",
|
||||
Hit = "baseball_change",
|
||||
Bingo = "baseball_completed",
|
||||
Into = "baseball_in",
|
||||
Out = "baseball_out";
|
||||
|
||||
public void Init(EventBingoBlockViewData viewData, EventBingoNumberItemFlyData flyData)
|
||||
{
|
||||
_flyData = flyData;
|
||||
_number = viewData.number;
|
||||
numberWhite.text = viewData.number.ToString();
|
||||
numberYellow.text = viewData.number.ToString();
|
||||
imgNumberItem.gameObject.SetActive(viewData.haveItem);
|
||||
rewardIcon.gameObject.SetActive(false);
|
||||
rewardIconCard.gameObject.SetActive(false);
|
||||
EventBingoAct.EventAggregator.GetEvent<EventBingoNumberShown>().Subscribe(OnNumberShown).AddTo(this);
|
||||
if (viewData.reward == null)
|
||||
return;
|
||||
var itemTableData = GContext.container.Resolve<Tables>().TbItem.GetOrDefault(viewData.reward.id);
|
||||
if (itemTableData == null)
|
||||
{
|
||||
Debug.LogWarning($"[EventBingo] SetReward: Invalid id({viewData.reward.id}) in Table.");
|
||||
return;
|
||||
}
|
||||
if (viewData.haveItem)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (itemTableData.Type == 5)
|
||||
{
|
||||
rewardIconCard.Init(itemTableData);
|
||||
rewardIconCard.gameObject.SetActive(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
rewardIcon.gameObject.SetActive(true);
|
||||
GContext.container.Resolve<IUIService>().SetImageSprite(rewardIcon, itemTableData.Icon);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnHit(bool doHit)
|
||||
{
|
||||
imgNumberItem.gameObject.SetActive(doHit);
|
||||
numberWhite.gameObject.SetActive(!doHit);
|
||||
numberYellow.gameObject.SetActive(doHit);
|
||||
}
|
||||
|
||||
private async void OnNumberShown(EventBingoNumberShown e)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (e.Number != _number)
|
||||
return;
|
||||
var itemFlyData = new CollectionItemFly
|
||||
{
|
||||
iconName = GContext.container.Resolve<EventBingoModel>().Ctx.GetItemIconByIdx(0),
|
||||
numStr = "",
|
||||
targetIconSize = imgNumberItem.rectTransform.rect.width,
|
||||
sourcePos = _flyData.StartPos,
|
||||
destPos = imgNumberItem.transform.position,
|
||||
isPlayOpen = false,
|
||||
isPlayClose = false,
|
||||
isDestinationRewardStash = false
|
||||
};
|
||||
var flyingItem = Instantiate(_flyData.FlyingNumberItem, transform.parent.parent);
|
||||
flyingItem.gameObject.SetActive(true);
|
||||
await flyingItem.ShowAsync(itemFlyData);
|
||||
Destroy(flyingItem.gameObject);
|
||||
OnReceiveNumberItem();
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Debug.LogError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnReceiveNumberItem()
|
||||
{
|
||||
imgNumberItem.gameObject.SetActive(true);
|
||||
ani.Play(Hit);
|
||||
}
|
||||
|
||||
public void SetNearBingo()
|
||||
{
|
||||
ani.Rewind();
|
||||
ani.Play(NearBingo);
|
||||
}
|
||||
|
||||
public float SetBingo()
|
||||
{
|
||||
ani.Play(Bingo);
|
||||
return ani.GetClip(Bingo).length;
|
||||
}
|
||||
|
||||
public void SetStandBy()
|
||||
{
|
||||
ani.Play(StandBy);
|
||||
}
|
||||
|
||||
public float SetInto()
|
||||
{
|
||||
// Debug.Log("[EventBingo] Play into.");
|
||||
ani.Play(Into);
|
||||
return ani.GetClip(Into).length;
|
||||
}
|
||||
|
||||
public float SetOut()
|
||||
{
|
||||
ani.Play(Out);
|
||||
return ani.GetClip(Out).length;
|
||||
}
|
||||
}
|
||||
|
||||
public class EventBingoBlockViewData
|
||||
{
|
||||
public int number;
|
||||
public ItemData reward;
|
||||
public bool haveItem;
|
||||
}
|
||||
|
||||
public class EventBingoNumberShown
|
||||
{
|
||||
public int Number;
|
||||
}
|
||||
|
||||
public class EventBingoNumberItemFlyData
|
||||
{
|
||||
public Vector2 StartPos;
|
||||
public RewardFly FlyingNumberItem;
|
||||
}
|
||||
11
Assets/Scripts/EventBingo/EventBingoBlockView.cs.meta
Normal file
11
Assets/Scripts/EventBingo/EventBingoBlockView.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7763d172b3de70c468cab2b3eb12e9b5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
582
Assets/Scripts/EventBingo/EventBingoData.cs
Normal file
582
Assets/Scripts/EventBingo/EventBingoData.cs
Normal file
@@ -0,0 +1,582 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using GameCore;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using asap.core;
|
||||
using game;
|
||||
using cfg;
|
||||
|
||||
public class EventBingoModel
|
||||
{
|
||||
public readonly static int BoardSize = 5;
|
||||
public readonly static int NumberCount = BoardSize * BoardSize;
|
||||
public readonly static string SfxItemIn = "audio_ui_eventbingobaseball_in", SfxItemOut = "audio_ui_eventbingobaseball_out";
|
||||
public const int RecordLength = 4;
|
||||
public const char Splitter = '|', Comma = ',';
|
||||
private int _stepInRound, _ticketCount, _roundCount, _eventId, _chainProgress, _chainTaskTokenProgress;
|
||||
private EventBingoRoundData _roundData;
|
||||
private EventBingoProgressTaskData _taskData;
|
||||
private EventBingoTableContext _ctx;
|
||||
private bool _isFirstTime;
|
||||
// This is actually used as a dequeue.
|
||||
public LinkedList<EventBingoNumberRollerItemData> NumberRollerDataList;
|
||||
public int[] BoardNumbers => _roundData.BoardNumbers;
|
||||
public EventBingoStepState StepState => _roundData[_stepInRound];
|
||||
public int BoardState => StepState.BoardState;
|
||||
public int TicketCount => _ticketCount;
|
||||
public int RoundCount => _roundCount;
|
||||
public EventBingoProgressTaskData TaskData => _taskData;
|
||||
public int EventId => _eventId;
|
||||
public int StepInRound => _stepInRound;
|
||||
public bool IsActivated
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_ctx == null)
|
||||
return false;
|
||||
var timeLimit = _ctx.GetTimeLimit();
|
||||
return timeLimit.Item1 <= ZZTimeHelper.UtcNow() && ZZTimeHelper.UtcNow() < timeLimit.Item2;
|
||||
}
|
||||
}
|
||||
public bool IsFirstTime => _isFirstTime;
|
||||
public EventBingoTableContext Ctx => _ctx;
|
||||
public int PackId => _ctx.GetPackId();
|
||||
|
||||
public void Init(FishingEvent e)
|
||||
{
|
||||
_eventId = e.ID;
|
||||
RefreshTableContext();
|
||||
_roundCount = 0;
|
||||
var seed = _ctx.PickSeed(_roundCount);
|
||||
_roundData = new EventBingoRoundData(seed);
|
||||
_stepInRound = 0;
|
||||
NumberRollerDataList = new LinkedList<EventBingoNumberRollerItemData>();
|
||||
_taskData = _ctx.GetTaskData();
|
||||
_ticketCount = 0;
|
||||
AddTicket(_ctx.GetWelcomeGift());
|
||||
SetUiPanel(_ctx.GetUiData());
|
||||
_isFirstTime = true;
|
||||
ToPlayfabData().Save();
|
||||
}
|
||||
|
||||
public void Load(EventBingoPlayfabData pfData, EventBingoPlayerPreferenceData ppData, FishingEvent e)
|
||||
{
|
||||
_eventId = pfData.EventId;
|
||||
RefreshTableContext();
|
||||
_ticketCount = pfData.TicketCount;
|
||||
_roundCount = pfData.RoundCount;
|
||||
_stepInRound = pfData.StepInRound;
|
||||
_roundData = new EventBingoRoundData(pfData.Seed);
|
||||
if (!_roundData.ValidateStepIndex(_stepInRound))
|
||||
{
|
||||
Debug.LogWarning($"[EventBingo] Wrong data detected. Step count out of range. Reset round data.");
|
||||
_stepInRound = 0;
|
||||
var seed = _ctx.PickSeed(_roundCount);
|
||||
_roundData = new EventBingoRoundData(seed);
|
||||
}
|
||||
_taskData = _ctx.GetTaskData(pfData.TaskId, pfData.TaskProgress);
|
||||
if (ppData == null || ppData.RollerDataList == null)
|
||||
NumberRollerDataList = new LinkedList<EventBingoNumberRollerItemData>();
|
||||
else
|
||||
NumberRollerDataList = new LinkedList<EventBingoNumberRollerItemData>(ppData.RollerDataList);
|
||||
SetUiPanel(_ctx.GetUiData());
|
||||
_isFirstTime = ppData == null ? true : ppData.IsFirstTime;
|
||||
}
|
||||
|
||||
public void InitTest()
|
||||
{
|
||||
Debug.Log("[EventBingo] Abandon.");
|
||||
}
|
||||
|
||||
public void NextStep()
|
||||
{
|
||||
_stepInRound++;
|
||||
var taskUpdate = _taskData.AddProgress(1);
|
||||
ToPlayfabData().Save();
|
||||
// Debug.Log($"[EventBingo] Step{_stepInRound}: {StepState.Number}.");
|
||||
}
|
||||
|
||||
public void NextRound()
|
||||
{
|
||||
_roundCount++;
|
||||
var seed = _ctx.PickSeed(_roundCount);
|
||||
_roundData = new EventBingoRoundData(seed);
|
||||
_stepInRound = 0;
|
||||
NumberRollerDataList.Clear();
|
||||
ToPlayfabData().Save();
|
||||
ToPlayerPreferenceData().Save();
|
||||
}
|
||||
|
||||
public bool CheckIfTaken(int index)
|
||||
{
|
||||
var flag = 1 << index;
|
||||
return (BoardState & flag) != 0;
|
||||
}
|
||||
|
||||
public List<EventBingoBlockViewData> GetBoardInitiationData()
|
||||
{
|
||||
var res = new List<EventBingoBlockViewData>();
|
||||
for (int i = 0; i < NumberCount; i++)
|
||||
{
|
||||
_roundData.MinorRewards.TryGetValue(i, out var minorReward);
|
||||
res.Add(new EventBingoBlockViewData
|
||||
{
|
||||
number = _roundData.BoardNumbers[i],
|
||||
reward = minorReward,
|
||||
haveItem = CheckIfTaken(i)
|
||||
});
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public void AddNumberRecord(int number)
|
||||
{
|
||||
_ctx.GetRandomItemIcon(out int iconIdx, out string iconUrl);
|
||||
NumberRollerDataList.AddLast(new EventBingoNumberRollerItemData
|
||||
{
|
||||
number = number,
|
||||
iconIdx = iconIdx,
|
||||
});
|
||||
while (NumberRollerDataList.Count > RecordLength)
|
||||
NumberRollerDataList.RemoveFirst();
|
||||
ToPlayerPreferenceData().Save();
|
||||
}
|
||||
|
||||
public bool AddTicket(int count)
|
||||
{
|
||||
_ticketCount += count;
|
||||
if (_ticketCount < 0)
|
||||
{
|
||||
_ticketCount -= count;
|
||||
return false;
|
||||
}
|
||||
EventBingoAct.EventAggregator.Publish(new EventBingoTicketUpdateEvent());
|
||||
ToPlayfabData().Save();
|
||||
GContext.container.Resolve<FishingEventData>().SaveTransitionData(_eventId, _ticketCount);
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool DeliverMinorReward(int index, out ItemData reward)
|
||||
{
|
||||
bool haveReward = _roundData.MinorRewards.TryGetValue(index, out reward);
|
||||
if (haveReward)
|
||||
{
|
||||
EventBingoSystem.GrantReward(reward);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Debug.Log($"[EventBingo] No reward for idx {index}");
|
||||
}
|
||||
return haveReward;
|
||||
}
|
||||
|
||||
public void RefreshTableContext()
|
||||
{
|
||||
_ctx = new EventBingoTableContext(_eventId);
|
||||
}
|
||||
|
||||
public EventBingoPlayfabData ToPlayfabData()
|
||||
{
|
||||
return new EventBingoPlayfabData(
|
||||
_eventId, _ticketCount, _roundCount, _stepInRound, _roundData.Seed,
|
||||
TaskData.TaskId, TaskData.Progress, _chainProgress,
|
||||
_chainTaskTokenProgress);
|
||||
}
|
||||
|
||||
public EventBingoEntranceData ToEntranceData()
|
||||
{
|
||||
(var startTime, var expiryTime) = _ctx.GetTimeLimit();
|
||||
bool needRedPoint = _ticketCount >= _ctx.GetRedPointThreshold();
|
||||
return new EventBingoEntranceData
|
||||
{
|
||||
NeedRedPoint = needRedPoint,
|
||||
ExpiryTime = expiryTime,
|
||||
StartTime = startTime,
|
||||
Icon = _ctx.GetEntranceIcon(),
|
||||
};
|
||||
}
|
||||
|
||||
public EventBingoPlayerPreferenceData ToPlayerPreferenceData()
|
||||
{
|
||||
return new EventBingoPlayerPreferenceData
|
||||
{
|
||||
RollerDataList = NumberRollerDataList.ToList(),
|
||||
IsFirstTime = _isFirstTime
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#region ChainPack
|
||||
public int GetChainProgress()
|
||||
{
|
||||
return _chainProgress;
|
||||
}
|
||||
|
||||
public void SetChainProgress(int p)
|
||||
{
|
||||
_chainProgress = p;
|
||||
}
|
||||
|
||||
public int GetTaskProgress()
|
||||
{
|
||||
return _chainTaskTokenProgress;
|
||||
}
|
||||
|
||||
public void SetTaskProgress(int p)
|
||||
{
|
||||
_chainTaskTokenProgress = p;
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
ToPlayfabData().Save();
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void SetUiPanel(EventBingoUiData panelData)
|
||||
{
|
||||
UITypes.EventBingoInfoPanel.SetType(panelData.InfoPanel);
|
||||
UITypes.EventBingoChainPackPanel.SetType(panelData.ChainPackPanel);
|
||||
}
|
||||
|
||||
public bool IsHit(int number)
|
||||
{
|
||||
foreach (var n in BoardNumbers)
|
||||
{
|
||||
if (n == number)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void SetFirstTimeFlag()
|
||||
{
|
||||
_isFirstTime = false;
|
||||
ToPlayerPreferenceData().Save();
|
||||
}
|
||||
|
||||
public void ActivateInstantBingo()
|
||||
{
|
||||
_stepInRound = _roundData.StepCount - 2;
|
||||
}
|
||||
}
|
||||
|
||||
public class EventBingoRoundData
|
||||
{
|
||||
private int _seed;
|
||||
public int[] BoardNumbers;
|
||||
private List<int> _playerNumberSequence;
|
||||
private List<int> _stateSequence;
|
||||
private List<int> _playerIdxSequence;
|
||||
public Dictionary<int, ItemData> MinorRewards;
|
||||
public int Seed => _seed;
|
||||
public int StepCount => _stateSequence.Count;
|
||||
|
||||
public EventBingoStepState this[int idx]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (idx >= _stateSequence.Count || idx >= _playerNumberSequence.Count)
|
||||
{
|
||||
var actualIdx = Mathf.Min(_stateSequence.Count - 2, _playerNumberSequence.Count - 2);
|
||||
return new EventBingoStepState
|
||||
{
|
||||
Number = _playerNumberSequence[actualIdx],
|
||||
BoardState = _stateSequence[actualIdx],
|
||||
Index = _playerIdxSequence[actualIdx],
|
||||
};
|
||||
throw new IndexOutOfRangeException(
|
||||
$"[EventBingo] Index {idx} out of range. Expected range: [0, {Math.Min(_stateSequence.Count, _playerNumberSequence.Count)}]");
|
||||
}
|
||||
return new EventBingoStepState
|
||||
{
|
||||
Number = _playerNumberSequence[idx],
|
||||
BoardState = _stateSequence[idx],
|
||||
Index = _playerIdxSequence[idx]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public EventBingoRoundData(int seed)
|
||||
{
|
||||
_playerNumberSequence = new List<int>();
|
||||
_playerIdxSequence = new List<int>();
|
||||
_stateSequence = new List<int>();
|
||||
UpdateWithSeed(seed);
|
||||
}
|
||||
|
||||
public void UpdateWithSeed(int seed)
|
||||
{
|
||||
var model = GContext.container.Resolve<EventBingoModel>();
|
||||
_seed = seed;
|
||||
var rng = new System.Random(_seed);
|
||||
BoardNumbers = EventBingoSystem.GenerateBoardNumbers(rng).ToArray();
|
||||
_playerNumberSequence.Clear();
|
||||
_playerIdxSequence.Clear();
|
||||
_stateSequence.Clear();
|
||||
_playerNumberSequence.Add(-1);
|
||||
_playerIdxSequence.Add(-1);
|
||||
_stateSequence.Add(0b0);
|
||||
var numberPool = Enumerable.Range(1, 99).ToList();
|
||||
int state = 0b0;
|
||||
var pickedIndexSet = new HashSet<int>();
|
||||
while (numberPool.Count > 0 && EventBingoSystem.CheckBingo(state, out _) <= 0)
|
||||
{
|
||||
var pickedNumber = EventBingoSystem.PickRandomNumberFromList(numberPool, rng);
|
||||
var pickedIdx = Array.IndexOf(BoardNumbers, pickedNumber);
|
||||
if (pickedIdx > -1)
|
||||
{
|
||||
pickedIndexSet.Add(pickedIdx);
|
||||
state |= 1 << pickedIdx;
|
||||
}
|
||||
_playerIdxSequence.Add(pickedIdx);
|
||||
_playerNumberSequence.Add(pickedNumber);
|
||||
_stateSequence.Add(state);
|
||||
}
|
||||
MinorRewards = new Dictionary<int, ItemData>();
|
||||
model.Ctx.GetMinorDropData(rng, out var availableRewards, out var displayRewards);
|
||||
|
||||
var allIndices = Enumerable.Range(0, EventBingoModel.NumberCount).ToList();
|
||||
FtMathUtils.ShuffleList(allIndices, rng);
|
||||
var pickedIndices = pickedIndexSet.ToList();
|
||||
FtMathUtils.ShuffleList(pickedIndices, rng);
|
||||
var unpickedIndices = allIndices.Except(pickedIndexSet).ToList();
|
||||
FtMathUtils.ShuffleList(unpickedIndices, rng);
|
||||
// Assign rewards to picked positions
|
||||
for (int i = 0; i < availableRewards.Count && i < pickedIndices.Count; i++)
|
||||
{
|
||||
MinorRewards[pickedIndices[i]] = availableRewards[i];
|
||||
Debug.Log($"[EventBingo] Available MiniDrop: item {availableRewards[i].id} @ idx{pickedIndices[i]}");
|
||||
}
|
||||
// Assign display rewards to unpicked positions
|
||||
for (int i = 0; i < displayRewards.Count && i < unpickedIndices.Count; i++)
|
||||
{
|
||||
MinorRewards[unpickedIndices[i]] = displayRewards[i];
|
||||
Debug.Log($"[EventBingo] Unavailable MiniDrop: item {displayRewards[i].id} @ idx {unpickedIndices[i]}");
|
||||
}
|
||||
// var leftOverIndices = Enumerable.Range(0, EventBingoModel.NumberCount)
|
||||
// .Where(x => !pickedIndexSet.Contains(x))
|
||||
// .ToHashSet()
|
||||
// .ToList()
|
||||
// .OrderBy(x => rng.Next())
|
||||
// .ToList();
|
||||
// var pickedIndexList = pickedIndexSet.ToList().OrderBy(x => rng.Next()).ToList();
|
||||
// for (int i = 0; i < availableRewards.Count && i < pickedIndexList.Count; i++)
|
||||
// {
|
||||
// var idx = pickedIndexList.First();
|
||||
// MinorRewards[idx] = availableRewards[i];
|
||||
// pickedIndexList.Remove(idx);
|
||||
// }
|
||||
// for (int i = 0; i < displayRewards.Count && i < leftOverIndices.Count; i++)
|
||||
// {
|
||||
// var idx = leftOverIndices.First();
|
||||
// MinorRewards[idx] = displayRewards[i];
|
||||
// leftOverIndices.Remove(idx);
|
||||
// }
|
||||
}
|
||||
|
||||
public int[] GetNumberRollerDataList(int step)
|
||||
{
|
||||
var startIdx = Mathf.Max(1, step - EventBingoModel.RecordLength + 1);
|
||||
var count = Mathf.Min(EventBingoModel.RecordLength, step);
|
||||
return _playerNumberSequence.GetRange(startIdx, count).ToArray();
|
||||
}
|
||||
|
||||
public bool ValidateStepIndex(int idx)
|
||||
{
|
||||
return idx < _playerNumberSequence.Count && idx < _playerIdxSequence.Count && idx < _stateSequence.Count;
|
||||
}
|
||||
}
|
||||
|
||||
public class EventBingoStepState
|
||||
{
|
||||
public int BoardState;
|
||||
public int Number;
|
||||
public int Index;
|
||||
}
|
||||
|
||||
public class EventBingoProgressTaskData
|
||||
{
|
||||
public int TaskId;
|
||||
public int Progress;
|
||||
public ItemData Reward;
|
||||
public int TargetProgress;
|
||||
public int NextTaskId;
|
||||
|
||||
/// <summary>
|
||||
/// Increase progress and check if task is completed.
|
||||
/// </summary>
|
||||
/// <param name="count">Usually 1 in this event.</param>
|
||||
/// <returns>True is the old task is completed.</returns>
|
||||
public bool AddProgress(int count)
|
||||
{
|
||||
Progress += count;
|
||||
if (Progress >= TargetProgress)
|
||||
{
|
||||
EventBingoSystem.GrantReward(Reward);
|
||||
MoveToNextTask();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void MoveToNextTask()
|
||||
{
|
||||
var nextTask = GContext.container.Resolve<EventBingoModel>().Ctx.GetTaskData(NextTaskId);
|
||||
TaskId = NextTaskId;
|
||||
Progress = 0;
|
||||
Reward = nextTask.Reward;
|
||||
TargetProgress = nextTask.TargetProgress;
|
||||
NextTaskId = nextTask.NextTaskId;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class EventBingoPlayfabData
|
||||
{
|
||||
public int EventId, TicketCount, RoundCount, StepInRound, Seed, TaskId, TaskProgress, ChainProgress, ChainTaskTokenProgress;
|
||||
private const int TokenCount = 9;
|
||||
private const string Key = "EventBingo";
|
||||
private string Serialize()
|
||||
{
|
||||
var sb = new System.Text.StringBuilder();
|
||||
sb.Append(EventId).Append(EventBingoModel.Splitter);
|
||||
sb.Append(TicketCount).Append(EventBingoModel.Splitter);
|
||||
sb.Append(RoundCount).Append(EventBingoModel.Splitter);
|
||||
sb.Append(StepInRound).Append(EventBingoModel.Splitter);
|
||||
sb.Append(Seed).Append(EventBingoModel.Splitter);
|
||||
sb.Append(TaskId).Append(EventBingoModel.Splitter);
|
||||
sb.Append(TaskProgress).Append(EventBingoModel.Splitter);
|
||||
sb.Append(ChainProgress).Append(EventBingoModel.Splitter);
|
||||
sb.Append(ChainTaskTokenProgress).Append(EventBingoModel.Splitter);
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static EventBingoPlayfabData Deserialize(string s)
|
||||
{
|
||||
if (s == null || s == "")
|
||||
return null;
|
||||
var tokens = s.Trim(EventBingoModel.Splitter).Split(EventBingoModel.Splitter);
|
||||
if (tokens.Length != TokenCount)
|
||||
{
|
||||
Debug.LogError($"[EventBingo]Wrong amount of parameters. Expect {TokenCount}, but got {tokens.Length} in \"{s}\".");
|
||||
return null;
|
||||
}
|
||||
var eventId = int.Parse(tokens[0]);
|
||||
var ticketCount = int.Parse(tokens[1]);
|
||||
var roundCount = int.Parse(tokens[2]);
|
||||
var stepInRound = int.Parse(tokens[3]);
|
||||
var seed = int.Parse(tokens[4]);
|
||||
var taskId = int.Parse(tokens[5]);
|
||||
var taskProgress = int.Parse(tokens[6]);
|
||||
var chainProgress = int.Parse(tokens[7]);
|
||||
var chainTaskTokenProgress = int.Parse(tokens[8]);
|
||||
return new EventBingoPlayfabData(eventId, ticketCount, roundCount,
|
||||
stepInRound, seed, taskId, taskProgress, chainProgress, chainTaskTokenProgress);
|
||||
}
|
||||
|
||||
public EventBingoPlayfabData(int eventId, int ticketCount, int roundCount, int stepInRound,
|
||||
int seed, int taskId, int taskProgress, int chainProgress, int chainTaskTokenProgress)
|
||||
{
|
||||
EventId = eventId;
|
||||
TicketCount = ticketCount;
|
||||
RoundCount = roundCount;
|
||||
StepInRound = stepInRound;
|
||||
Seed = seed;
|
||||
TaskId = taskId;
|
||||
TaskProgress = taskProgress;
|
||||
ChainProgress = chainProgress;
|
||||
ChainTaskTokenProgress = chainTaskTokenProgress;
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
PlayFabMgr.Instance.UpdateUserDataValue(Key, Serialize());
|
||||
}
|
||||
|
||||
public static EventBingoPlayfabData Load()
|
||||
{
|
||||
var s = PlayFabMgr.Instance.GetLocalData(Key);
|
||||
return Deserialize(s);
|
||||
}
|
||||
}
|
||||
|
||||
public class EventBingoEntranceData
|
||||
{
|
||||
public bool NeedRedPoint;
|
||||
public DateTime ExpiryTime;
|
||||
public DateTime StartTime;
|
||||
public string Icon;
|
||||
}
|
||||
|
||||
public class EventBingoPlayerPreferenceData
|
||||
{
|
||||
public List<EventBingoNumberRollerItemData> RollerDataList;
|
||||
public bool IsFirstTime = true;
|
||||
private readonly static string Key = "EventBingo" + GContext.container.Resolve<IUserService>().UserId;
|
||||
|
||||
private string Serialize()
|
||||
{
|
||||
var sb = new System.Text.StringBuilder();
|
||||
sb.Append(IsFirstTime ? "1" : "0").Append(EventBingoModel.Splitter);
|
||||
foreach (var data in RollerDataList)
|
||||
sb.Append(data.number).Append(EventBingoModel.Comma).Append(data.iconIdx).Append(EventBingoModel.Splitter);
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static EventBingoPlayerPreferenceData Deserialize(string s)
|
||||
{
|
||||
var tokens = s.Trim(EventBingoModel.Splitter).Split(EventBingoModel.Splitter);
|
||||
var rollerData = new List<EventBingoNumberRollerItemData>();
|
||||
bool isFirstTime;
|
||||
if (tokens.Length < 1)
|
||||
{
|
||||
throw new Exception("[EventBingo] Invalid serialized data, length < 1");
|
||||
}
|
||||
isFirstTime = tokens[0] == "1";
|
||||
for (int i = 1; i < tokens.Length; i++)
|
||||
{
|
||||
var token = tokens[i];
|
||||
var tokenTokens = token.Split(EventBingoModel.Comma);
|
||||
if (tokenTokens.Length != 2)
|
||||
throw new Exception("[EventBingo] Wrong amount of parameters in " + token);
|
||||
rollerData.Add(new EventBingoNumberRollerItemData
|
||||
{
|
||||
number = int.Parse(tokenTokens[0]),
|
||||
iconIdx = int.Parse(tokenTokens[1])
|
||||
});
|
||||
}
|
||||
return new EventBingoPlayerPreferenceData { RollerDataList = rollerData, IsFirstTime = isFirstTime };
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
PlayerPrefs.SetString(Key, Serialize());
|
||||
}
|
||||
|
||||
public static EventBingoPlayerPreferenceData Load()
|
||||
{
|
||||
var s = PlayerPrefs.GetString(Key);
|
||||
if (s == null || s == "")
|
||||
return null;
|
||||
try
|
||||
{
|
||||
var res = Deserialize(s);
|
||||
return res;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class EventBingoTicketUpdateEvent { }
|
||||
|
||||
public class EventBingoUiData
|
||||
{
|
||||
public string InfoPanel { get; set; }
|
||||
public string ChainPackPanel { get; set; }
|
||||
}
|
||||
11
Assets/Scripts/EventBingo/EventBingoData.cs.meta
Normal file
11
Assets/Scripts/EventBingo/EventBingoData.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7e36873243b281e489e4d7f3bcc83f94
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,12 @@
|
||||
using EnhancedUI.EnhancedScroller;
|
||||
using UnityEngine;
|
||||
public static class EventBingoEnhancedScrollViewExtension
|
||||
{
|
||||
public static int GetSnapDataIndexFromScrollPosition(this EnhancedScroller enhancedScroller)
|
||||
{
|
||||
var snapPosition = enhancedScroller.ScrollPosition + (enhancedScroller.ScrollRectSize * Mathf.Clamp01(0.5f));
|
||||
var snapCellViewIndex = enhancedScroller.GetCellViewIndexAtPosition(snapPosition);
|
||||
var dataIndex = snapCellViewIndex % enhancedScroller.NumberOfCells;
|
||||
return dataIndex;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9979b385a52ef8947b95b4ba3243b729
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
78
Assets/Scripts/EventBingo/EventBingoEntranceBtn.cs
Normal file
78
Assets/Scripts/EventBingo/EventBingoEntranceBtn.cs
Normal file
@@ -0,0 +1,78 @@
|
||||
using System.Collections.Generic;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using UnityEngine.UI;
|
||||
using UniRx;
|
||||
using asap.core;
|
||||
using game;
|
||||
using GameCore;
|
||||
|
||||
public class EventBingoEntranceBtn : EventButtonResource
|
||||
{
|
||||
[SerializeField] private TMP_Text textTimer;
|
||||
[SerializeField] private Button button;
|
||||
[SerializeField] private Image icon;
|
||||
private ILoadResourceService _loadResourceService;
|
||||
private EventBingoEntranceData _data;
|
||||
private TimeSpan RemainingTime => _data.ExpiryTime - ZZTimeHelper.UtcNow();
|
||||
private bool IsActive => _data.ExpiryTime > ZZTimeHelper.UtcNow() && ZZTimeHelper.UtcNow() > _data.StartTime;
|
||||
private const string RedPointKey = "eventbingo.entrance";
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
var model = GContext.container.Resolve<EventBingoModel>();
|
||||
if (model == null)
|
||||
{
|
||||
gameObject.SetActive(false);
|
||||
return;
|
||||
}
|
||||
_data = model.ToEntranceData();
|
||||
UpdateTimer();
|
||||
Observable.Interval(TimeSpan.FromSeconds(1f)).Subscribe(UpdateTimer).AddTo(this);
|
||||
_loadResourceService = GContext.container.Resolve<ILoadResourceService>();
|
||||
button.onClick.AddListener(EnterActAsync);
|
||||
RedPointManager.Instance.SetRedPointState(RedPointKey, _data.NeedRedPoint);
|
||||
CheckResource(new List<string>() { UITypes.EventBingoPanel.Path, EventBingoAct.ActAddressable, _data.Icon });
|
||||
}
|
||||
|
||||
private void UpdateTimer(long _ = 0L)
|
||||
{
|
||||
textTimer.text = ConvertTools.ConvertTime2(RemainingTime);
|
||||
if (!IsActive)
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
private async void EnterActAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
bool isReady = await _loadResourceService.Loads(
|
||||
new List<string>() { UITypes.EventBingoPanel.Path, EventBingoAct.ActAddressable });
|
||||
if (isReady)
|
||||
{
|
||||
GContext.Publish(new UnloadActToNextAct { actId = EventBingoAct.ActAddressable, TransitionPanel = UITypes.CloudTransitionPanel });
|
||||
}
|
||||
else
|
||||
{
|
||||
var panel = await UIManager.Instance.ShowUI(UITypes.CloudTransitionPanel);
|
||||
panel.GetComponent<CloudTransitionPanel>()
|
||||
.SetBtn(true, () => GContext.Publish(new UnloadActToNextAct(EventBingoAct.ActAddressable)));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Log($"<color=#22a6f2>[EventBingo] EnterActError: {e.Message}\n{e.StackTrace}</color>");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnLoadEventResource()
|
||||
{
|
||||
if (IsActive)
|
||||
{
|
||||
GContext.container.Resolve<IUIService>().SetImageSprite(icon, _data.Icon);
|
||||
gameObject.SetActive(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/EventBingo/EventBingoEntranceBtn.cs.meta
Normal file
11
Assets/Scripts/EventBingo/EventBingoEntranceBtn.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: af9011f11cfd6434aa503263f8be1cb9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/Scripts/EventBingo/EventBingoInfoPanel.cs
Normal file
9
Assets/Scripts/EventBingo/EventBingoInfoPanel.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class EventBingoInfoPanel : MonoBehaviour
|
||||
{
|
||||
|
||||
}
|
||||
11
Assets/Scripts/EventBingo/EventBingoInfoPanel.cs.meta
Normal file
11
Assets/Scripts/EventBingo/EventBingoInfoPanel.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 110f25fda9663704a9dc16d729a3ac9f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
52
Assets/Scripts/EventBingo/EventBingoNumberItemView.cs
Normal file
52
Assets/Scripts/EventBingo/EventBingoNumberItemView.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using asap.core;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using DG.Tweening;
|
||||
|
||||
public class EventBingoNumberItemView : MonoBehaviour
|
||||
{
|
||||
[SerializeField] TMP_Text text_number;
|
||||
[SerializeField] Image icon;
|
||||
[SerializeField] Animation ani;
|
||||
System.Action<EventBingoNumberItemView> _onPassThreshold;
|
||||
private const string ItemRollAnimation = "baseball_rotate";
|
||||
|
||||
public void Init(EventBingoNumberRollerItemData data, GameObject parent, Vector2 anchoredPos, System.Action<EventBingoNumberItemView> onPassThreshold = null)
|
||||
{
|
||||
text_number.text = data.number.ToString();
|
||||
var url = GContext.container.Resolve<EventBingoModel>().Ctx.GetItemIconByIdx(data.iconIdx);
|
||||
GContext.container.Resolve<IUIService>().SetImageSprite(icon, url);
|
||||
gameObject.transform.SetParent(parent.transform);
|
||||
transform.localScale = Vector3.one;
|
||||
gameObject.GetComponent<RectTransform>().anchoredPosition = anchoredPos;
|
||||
gameObject.name = "NumberItem_" + data.number;
|
||||
gameObject.SetActive(true);
|
||||
_onPassThreshold = onPassThreshold;
|
||||
}
|
||||
|
||||
public async void Move(float gap, float threshold)
|
||||
{
|
||||
try
|
||||
{
|
||||
var rect = transform as RectTransform;
|
||||
var endValue = rect.anchoredPosition.x - gap;
|
||||
var clip = ani.GetClip(ItemRollAnimation);
|
||||
ani.Play(ItemRollAnimation);
|
||||
await rect.DOAnchorPosX(endValue, clip.length).AsyncWaitForCompletion();
|
||||
if (rect.anchoredPosition.x < threshold)
|
||||
_onPassThreshold?.Invoke(this);
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Debug.LogError("[EventBingo] RollItemError: ");
|
||||
Debug.LogError(e);
|
||||
}
|
||||
}
|
||||
|
||||
public float GetItemRollDuration()
|
||||
{
|
||||
var clip = ani.GetClip(ItemRollAnimation);
|
||||
return clip.length;
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/EventBingo/EventBingoNumberItemView.cs.meta
Normal file
11
Assets/Scripts/EventBingo/EventBingoNumberItemView.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e46c8cce78c4c2049894ab539bcebc83
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
80
Assets/Scripts/EventBingo/EventBingoNumberRollerView.cs
Normal file
80
Assets/Scripts/EventBingo/EventBingoNumberRollerView.cs
Normal file
@@ -0,0 +1,80 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using asap.core;
|
||||
using Game;
|
||||
using UnityEngine;
|
||||
|
||||
public class EventBingoNumberRollerView : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private RectTransform[] numberReferenceList;
|
||||
private float _numberGap, _numberThreshold;
|
||||
private Vector2 pivot;
|
||||
private List<EventBingoNumberItemView> _numberList;
|
||||
private EventBingoNumberItemView _numberPrefab => numberReferenceList[0].GetComponent<EventBingoNumberItemView>();
|
||||
public Vector2 StartPos => numberReferenceList[0].transform.position;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
foreach (var numRef in numberReferenceList)
|
||||
numRef.gameObject.SetActive(false);
|
||||
pivot = numberReferenceList[0].anchoredPosition;
|
||||
_numberGap = Mathf.Abs((numberReferenceList.First().anchoredPosition.x - numberReferenceList.Last().anchoredPosition.x) / (numberReferenceList.Length - 1));
|
||||
_numberThreshold = numberReferenceList.Last().anchoredPosition.x - _numberGap * 0.1f;
|
||||
}
|
||||
|
||||
public void Init(List<EventBingoNumberRollerItemData> dataList)
|
||||
{
|
||||
var pos = pivot;
|
||||
_numberList = new List<EventBingoNumberItemView>();
|
||||
for (int i = dataList.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var number = Instantiate(_numberPrefab);
|
||||
number.Init(dataList[i], gameObject, pos, DestroyNumber);
|
||||
_numberList.Add(number);
|
||||
pos -= new Vector2(_numberGap, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public async System.Threading.Tasks.Task RollIn(EventBingoNumberRollerItemData data)
|
||||
{
|
||||
var number = Instantiate(_numberPrefab);
|
||||
var model = GContext.container.Resolve<EventBingoModel>();
|
||||
GContext.Publish(new EventUISound(model.Ctx.GetNumberSfxUrl(data.number)));
|
||||
number.Init(data, gameObject, pivot + new Vector2(_numberGap, 0), DestroyNumber);
|
||||
_numberList.Add(number);
|
||||
foreach (var item in _numberList)
|
||||
item.Move(_numberGap, _numberThreshold);
|
||||
await System.Threading.Tasks.Task.Delay(
|
||||
System.TimeSpan.FromSeconds(_numberList[0].GetItemRollDuration()));
|
||||
}
|
||||
|
||||
public void SetEmpty()
|
||||
{
|
||||
for (int i = 0; i < _numberList.Count; i++)
|
||||
{
|
||||
Destroy(_numberList[i].gameObject);
|
||||
}
|
||||
_numberList.Clear();
|
||||
}
|
||||
|
||||
private void DestroyNumber(EventBingoNumberItemView number)
|
||||
{
|
||||
EventBingoNumberItemView item = null;
|
||||
for (int i = 0; i < _numberList.Count; i++)
|
||||
{
|
||||
if (_numberList[i] == number)
|
||||
{
|
||||
item = _numberList[i];
|
||||
_numberList.RemoveAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Destroy(item.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
public class EventBingoNumberRollerItemData
|
||||
{
|
||||
public int number;
|
||||
public int iconIdx;
|
||||
}
|
||||
11
Assets/Scripts/EventBingo/EventBingoNumberRollerView.cs.meta
Normal file
11
Assets/Scripts/EventBingo/EventBingoNumberRollerView.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6d63cf494cadb334bb7946da8ca2931d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
344
Assets/Scripts/EventBingo/EventBingoPanel.cs
Normal file
344
Assets/Scripts/EventBingo/EventBingoPanel.cs
Normal file
@@ -0,0 +1,344 @@
|
||||
using asap.core;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using game;
|
||||
using System.Linq;
|
||||
using TMPro;
|
||||
using UniRx;
|
||||
using GameCore;
|
||||
using System;
|
||||
using asap.core.common;
|
||||
using System.Threading.Tasks;
|
||||
using Game;
|
||||
|
||||
public class EventBingoPanel : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private EventBingoBlockView[] blockViews;
|
||||
[SerializeField] private Button btnPlay, btnClose, btnInfo;
|
||||
[SerializeField] private EventBingoScrollView rewardScrollView;
|
||||
[SerializeField] private EventBingoNumberRollerView numberRollerView;
|
||||
[SerializeField] private RewardFly flyingNumberItem;
|
||||
[SerializeField] private EventBingoTaskView taskView;
|
||||
[SerializeField] private TMP_Text textTicketCount;
|
||||
[SerializeField] private BingoTimer timer;
|
||||
[SerializeField] private RewardFly rewardFlyPrefab;
|
||||
[SerializeField] private Animator btnAni;
|
||||
[SerializeField] private GameObject goClickMask;
|
||||
// [SerializeField] private ChainPackBtn btnPack;
|
||||
private IObjectPoolService _objectPoolService;
|
||||
private const float RewardFlyDuration = 1.2f, BaseBallChangeDuration = 1f;
|
||||
private const string ButtonPlayAnimation = "Pressed", ButtonNormalAnimation = "Normal";
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
btnClose.onClick.AddListener(OnClickClose);
|
||||
btnPlay.onClick.AddListener(OnClickPlay);
|
||||
btnInfo.onClick.AddListener(OnClickInfo);
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
var model = GContext.container.Resolve<EventBingoModel>();
|
||||
var blockViewDataList = model.GetBoardInitiationData();
|
||||
for (int i = 0; i < blockViews.Length; i++)
|
||||
blockViews[i].Init(blockViewDataList[i],
|
||||
new EventBingoNumberItemFlyData
|
||||
{
|
||||
StartPos = numberRollerView.StartPos,
|
||||
FlyingNumberItem = flyingNumberItem
|
||||
});
|
||||
numberRollerView.Init(model.NumberRollerDataList.ToList());
|
||||
taskView.Init(model.TaskData);
|
||||
UpdateTicketCount();
|
||||
EventBingoAct.EventAggregator.GetEvent<EventBingoTicketUpdateEvent>()
|
||||
.Subscribe(_ => UpdateTicketCount())
|
||||
.AddTo(this);
|
||||
var timeLimit = model.Ctx.GetTimeLimit();
|
||||
var timerContext = new TimerContext
|
||||
{
|
||||
StartTime = timeLimit.Item1,
|
||||
ExpiryTime = timeLimit.Item2,
|
||||
OnExpire = OnClickClose
|
||||
};
|
||||
timer.Init(timerContext);
|
||||
CreateRewardFlyObjectPool();
|
||||
rewardScrollView.ToggleBingoGlitterFx(false);
|
||||
}
|
||||
|
||||
public async void Start()
|
||||
{
|
||||
float duration = 0;
|
||||
try
|
||||
{
|
||||
Debug.Log($"[EventBingo] Start.");
|
||||
for (int i = 0; i < blockViews.Length; i++)
|
||||
duration = blockViews[i].SetInto();
|
||||
await Task.Delay(TimeSpan.FromSeconds(duration / 2));
|
||||
GContext.Publish(new EventUISound(EventBingoModel.SfxItemIn));
|
||||
await Task.Delay(TimeSpan.FromSeconds(duration / 2));
|
||||
PlayNearBingoLoopFx();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogError("[EventBingo] Panel start error.");
|
||||
Debug.LogError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnClickClose()
|
||||
{
|
||||
var _model = GContext.container.Resolve<EventBingoModel>();
|
||||
_model.ToPlayfabData().Save();
|
||||
_model.ToPlayerPreferenceData().Save();
|
||||
ReleaseRewardFlyObjectPool();
|
||||
GContext.Publish(new UnloadActToNextAct());
|
||||
}
|
||||
|
||||
private async void OnClickPlay()
|
||||
{
|
||||
// Debug.Log($"[EventBingo] Play.");
|
||||
try
|
||||
{
|
||||
BlockInput();
|
||||
PlayButtonAnimation();
|
||||
var model = GContext.container.Resolve<EventBingoModel>();
|
||||
var ticketStatus = model.AddTicket(-1);
|
||||
if (!ticketStatus)
|
||||
{
|
||||
Debug.Log($"[EventBingo] Insufficient tickets.");
|
||||
var res = await OnClickPack();
|
||||
if (!res)
|
||||
{
|
||||
ToastPanel.Show(LocalizationMgr.GetFormatTextValue("UI_ToastPanel_75", LocalizationMgr.GetText(model.Ctx.GetTicketNameKey())));
|
||||
UnblockInput();
|
||||
return;
|
||||
}
|
||||
UnblockInput();
|
||||
return;
|
||||
}
|
||||
model.NextStep();
|
||||
var stepState = model.StepState;
|
||||
model.AddNumberRecord(stepState.Number);
|
||||
var haveMinorReward = model.DeliverMinorReward(stepState.Index, out var minorReward);
|
||||
var bingo = EventBingoSystem.CheckBingo(stepState.BoardState, out var pickedIndices);
|
||||
var hit = model.IsHit(stepState.Number);
|
||||
|
||||
int evSuccessMultiple = bingo;
|
||||
int evItemConsume = model.StepInRound;
|
||||
int evIsCorrect = hit ? 1 : 0;
|
||||
string evBoxReward = haveMinorReward ? $"{minorReward.id},{minorReward.count}" : "";
|
||||
int evMilestoneReward = model.TaskData.TaskId != taskView.TaskId ? model.Ctx.GetTaskRewardDropId(taskView.TaskId) : 0;
|
||||
|
||||
// Debug.Log($"<color=red>[EventBingo] -------------------Event Tracking---------------------</color>");
|
||||
// Debug.Log($"[EventBingo] success_multiple: {evSuccessMultiple}");
|
||||
// Debug.Log($"[EventBingo] item_consume: {evItemConsume}");
|
||||
// Debug.Log($"[EventBingo] is_correct: {evIsCorrect}");
|
||||
// Debug.Log($"[EventBingo] box_reward: {evBoxReward}");
|
||||
// Debug.Log($"[EventBingo] milestone_reward: {evMilestoneReward}");
|
||||
// Debug.Log($"[EventBingo] -------------------End of Event Tracking---------------------");
|
||||
#if AGG
|
||||
using (var e = GEvent.GameEvent("event_bingo_start"))
|
||||
{
|
||||
e.AddContent("success_multiple", evSuccessMultiple)
|
||||
.AddContent("item_consume", evItemConsume)
|
||||
.AddContent("is_correct", evIsCorrect)
|
||||
.AddContent("box_reward", evBoxReward)
|
||||
.AddContent("milestone_reward", evMilestoneReward);
|
||||
}
|
||||
#endif
|
||||
await numberRollerView.RollIn(model.NumberRollerDataList.Last.Value);
|
||||
if (!hit)
|
||||
{
|
||||
await taskView.UpdateProgress();
|
||||
// PlayNearBingoLoopFx();
|
||||
UnblockInput();
|
||||
return;
|
||||
}
|
||||
CancelNearBingoLoopFx();
|
||||
EventBingoAct.EventAggregator.Publish(new EventBingoNumberShown { Number = stepState.Number });
|
||||
await Task.Delay(TimeSpan.FromSeconds(RewardFlyDuration));
|
||||
// all animation in nml
|
||||
// foreach (var v in blockViews)
|
||||
// {
|
||||
// v.SetStandBy();
|
||||
// }
|
||||
// Debug.Log($"[EventBingo] Clear animation.");
|
||||
await Awaiters.NextFrame;
|
||||
if (haveMinorReward)
|
||||
{
|
||||
GContext.Publish(new EventRewardFlyStashRequest(reward: minorReward,
|
||||
sourceIconRt: blockViews[stepState.Index].GetComponent<RectTransform>(),
|
||||
doesPlayOpen: true));
|
||||
await Task.Delay(TimeSpan.FromSeconds(RewardFlyDuration));
|
||||
}
|
||||
if (bingo > 0)
|
||||
{
|
||||
Debug.Log($"[EventBingo] Bingo * {bingo}!");
|
||||
var rewards = model.Ctx.GetBingoRewards(bingo, model.RoundCount);
|
||||
rewards.ForEach(EventBingoSystem.GrantReward);
|
||||
model.NextRound();
|
||||
rewardScrollView.ToggleBingoGlitterFx(true);
|
||||
var bingoDuration = PlayBingoAnimation(pickedIndices);
|
||||
await Task.Delay(TimeSpan.FromSeconds(bingoDuration));
|
||||
var rewardPanel = (await UIManager.Instance.ShowUINotLoading(UITypes.EventBingoRewardPanel))
|
||||
.GetComponent<EventBingoRewardPanel>();
|
||||
var tcs = new TaskCompletionSource<bool>();
|
||||
rewardPanel.Init(new EventBingoRewardPanelData { BingoCount = bingo, Rewards = rewards }, EventBingoAct.EventAggregator, tcs);
|
||||
await tcs.Task;
|
||||
rewardScrollView.ToggleBingoGlitterFx(false);
|
||||
await taskView.UpdateProgress();
|
||||
rewardScrollView.ReloadData(model.RoundCount);
|
||||
await RefreshPanel();
|
||||
UnblockInput();
|
||||
}
|
||||
else
|
||||
{
|
||||
await taskView.UpdateProgress();
|
||||
PlayNearBingoLoopFx();
|
||||
UnblockInput();
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError("[EventBingo] Bingo play error.");
|
||||
Debug.LogError(e);
|
||||
}
|
||||
}
|
||||
|
||||
private async void PlayButtonAnimation()
|
||||
{
|
||||
try
|
||||
{
|
||||
btnAni.Play(ButtonPlayAnimation);
|
||||
await Task.Delay(TimeSpan.FromSeconds(0.3f));
|
||||
btnAni.Play(ButtonNormalAnimation);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError(e);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RefreshPanel()
|
||||
{
|
||||
var model = GContext.container.Resolve<EventBingoModel>();
|
||||
var blockViewDataList = model.GetBoardInitiationData();
|
||||
float duration = 0;
|
||||
numberRollerView.SetEmpty();
|
||||
GContext.Publish(new EventUISound(EventBingoModel.SfxItemOut));
|
||||
for (int i = 0; i < blockViews.Length; i++)
|
||||
duration = blockViews[i].SetOut();
|
||||
await Task.Delay(TimeSpan.FromSeconds(duration));
|
||||
for (int i = 0; i < blockViews.Length; i++)
|
||||
{
|
||||
blockViews[i].Init(blockViewDataList[i],
|
||||
new EventBingoNumberItemFlyData
|
||||
{
|
||||
StartPos = numberRollerView.StartPos,
|
||||
FlyingNumberItem = flyingNumberItem
|
||||
});
|
||||
}
|
||||
await Awaiters.NextFrame;
|
||||
for (int i = 0; i < blockViews.Length; i++)
|
||||
duration = blockViews[i].SetInto();
|
||||
await Task.Delay(TimeSpan.FromSeconds(duration / 2));
|
||||
GContext.Publish(new EventUISound(EventBingoModel.SfxItemIn));
|
||||
await Task.Delay(TimeSpan.FromSeconds(duration / 2));
|
||||
}
|
||||
|
||||
private void PlayNearBingoLoopFx()
|
||||
{
|
||||
var model = GContext.container.Resolve<EventBingoModel>();
|
||||
var nearBingoIndices = EventBingoSystem.CheckNearBingoIndices(model.StepState.BoardState);
|
||||
for (int i = 0; i < nearBingoIndices.Length; i++)
|
||||
{
|
||||
var index = nearBingoIndices[i];
|
||||
blockViews[index].SetNearBingo();
|
||||
}
|
||||
}
|
||||
|
||||
private float PlayBingoAnimation(int[] pickedIndices)
|
||||
{
|
||||
// Debug.Log("[EventBingo] Play Bingo.");
|
||||
float res = 0;
|
||||
foreach (var index in pickedIndices)
|
||||
{
|
||||
res = blockViews[index].SetBingo();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private void CancelNearBingoLoopFx()
|
||||
{
|
||||
Debug.Log("[EventBingo] Play cancel Bingo.");
|
||||
foreach (var v in blockViews)
|
||||
{
|
||||
v.SetStandBy();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateTicketCount()
|
||||
{
|
||||
var n = GContext.container.Resolve<EventBingoModel>().TicketCount;
|
||||
textTicketCount.text = $"{n}";
|
||||
textTicketCount.color = n > 0 ? Color.white : Color.red;
|
||||
}
|
||||
|
||||
private async Task<bool> OnClickPack()
|
||||
{
|
||||
try
|
||||
{
|
||||
var chainPackData = GContext.container.Resolve<FishingEventData>().ChainPackWithProgressMigrationData;
|
||||
if (chainPackData == null || chainPackData.IsChainPackDepleted)
|
||||
{
|
||||
Debug.Log("[EventBingo] No chain pack.");
|
||||
return false;
|
||||
}
|
||||
var panel = (await UIManager.Instance.ShowUINotLoading(UITypes.EventBingoChainPackPanel)).GetComponent<ThanksGivingPopupPanel>();
|
||||
panel.Init(chainPackData);
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Log($"[EventBingo]Open Chain Pack Error:");
|
||||
Debug.LogError(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private async void OnClickInfo()
|
||||
{
|
||||
try
|
||||
{
|
||||
await UIManager.Instance.ShowUINotLoading(UITypes.EventBingoInfoPanel);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateRewardFlyObjectPool()
|
||||
{
|
||||
_objectPoolService = GContext.container.Resolve<IObjectPoolService>();
|
||||
_objectPoolService.CreatePool(rewardFlyPrefab, 0, 10);
|
||||
}
|
||||
|
||||
private void ReleaseRewardFlyObjectPool()
|
||||
{
|
||||
_objectPoolService?.DestroyPool(typeof(RewardFly));
|
||||
}
|
||||
|
||||
private void BlockInput()
|
||||
{
|
||||
// Debug.Log("[EventBingo] Block.");
|
||||
goClickMask.SetActive(true);
|
||||
}
|
||||
|
||||
private void UnblockInput()
|
||||
{
|
||||
// Debug.Log("[EventBingo] Unblock.");
|
||||
goClickMask.SetActive(false);
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/EventBingo/EventBingoPanel.cs.meta
Normal file
11
Assets/Scripts/EventBingo/EventBingoPanel.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8bbb5826b3bb7324eb9b143df9e1badf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
10
Assets/Scripts/EventBingo/EventBingoPlayerItemData.cs
Normal file
10
Assets/Scripts/EventBingo/EventBingoPlayerItemData.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using cfg;
|
||||
using asap.core;
|
||||
using System.Linq;
|
||||
|
||||
namespace GameCore
|
||||
{
|
||||
}
|
||||
|
||||
11
Assets/Scripts/EventBingo/EventBingoPlayerItemData.cs.meta
Normal file
11
Assets/Scripts/EventBingo/EventBingoPlayerItemData.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4cdcf6b273084f041a3904a0ecd44494
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
13
Assets/Scripts/EventBingo/EventBingoPosTracker.cs
Normal file
13
Assets/Scripts/EventBingo/EventBingoPosTracker.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
|
||||
public class EventBingoPosTracker : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private TMP_Text text;
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
text.text = transform.position.ToString();
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/EventBingo/EventBingoPosTracker.cs.meta
Normal file
11
Assets/Scripts/EventBingo/EventBingoPosTracker.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d239870565903024dbae406aa65b8258
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
68
Assets/Scripts/EventBingo/EventBingoRewardPanel.cs
Normal file
68
Assets/Scripts/EventBingo/EventBingoRewardPanel.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
using GameCore;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using System.Collections.Generic;
|
||||
using asap.core;
|
||||
using UnityEngine.Assertions;
|
||||
using System.Threading.Tasks;
|
||||
using System;
|
||||
|
||||
public class EventBingoRewardPanel : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private Button btnClose;
|
||||
[SerializeField] private GameObject[] goBingoBanners;
|
||||
[SerializeField] private RewardItemNew[] rewardDisplayList;
|
||||
private IEventAggregator _eventAggregator1;
|
||||
private ItemData[] _rewards;
|
||||
private TaskCompletionSource<bool> _tcs;
|
||||
private const float RewardFlyDuration = 1.2f;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
btnClose.onClick.AddListener(OnClickClose);
|
||||
}
|
||||
|
||||
public void Init(EventBingoRewardPanelData data, IEventAggregator eventAggregator, TaskCompletionSource<bool> tcs)
|
||||
{
|
||||
for (int i = 0; i < goBingoBanners.Length; i++)
|
||||
goBingoBanners[i].SetActive(i == data.BingoCount - 1);
|
||||
_eventAggregator1 = eventAggregator;
|
||||
Assert.IsTrue(rewardDisplayList.Length == data.Rewards.Count, $"Inconsistent reward count: {rewardDisplayList.Length} in UI vs {data.Rewards.Count} in data.");
|
||||
for (int i = 0; i < data.Rewards.Count; i++)
|
||||
rewardDisplayList[i].SetData(data.Rewards[i]);
|
||||
_rewards = data.Rewards.ToArray();
|
||||
_tcs = tcs;
|
||||
}
|
||||
|
||||
private async void OnClickClose()
|
||||
{
|
||||
try
|
||||
{
|
||||
btnClose.gameObject.SetActive(false);
|
||||
GContext.Publish(new EventRewardFlyStashRequest(
|
||||
reward: _rewards[0],
|
||||
sourceIconRt: rewardDisplayList[0].icon.GetComponent<RectTransform>(),
|
||||
doesPlayOpen: true));
|
||||
GContext.Publish(new EventRewardFlyStashRequest(
|
||||
reward: _rewards[1],
|
||||
sourceIconRt: rewardDisplayList[1].icon.GetComponent<RectTransform>(),
|
||||
doesPlayOpen: true));
|
||||
// _ = rewardDisplayList[0].ParticleAttractor();
|
||||
// _ = rewardDisplayList[1].ParticleAttractor();
|
||||
await Task.Delay(TimeSpan.FromSeconds(RewardFlyDuration - 0.2f));
|
||||
_tcs.SetResult(true);
|
||||
UIManager.Instance.DestroyUI(UITypes.EventBingoRewardPanel);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError("[EventBingo] bingo reward panel error.");
|
||||
Debug.LogError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class EventBingoRewardPanelData
|
||||
{
|
||||
public int BingoCount;
|
||||
public List<ItemData> Rewards;
|
||||
}
|
||||
11
Assets/Scripts/EventBingo/EventBingoRewardPanel.cs.meta
Normal file
11
Assets/Scripts/EventBingo/EventBingoRewardPanel.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fd6d7f46160ee7c4db39ab39be352b05
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
10
Assets/Scripts/EventBingo/EventBingoScrollRect.cs
Normal file
10
Assets/Scripts/EventBingo/EventBingoScrollRect.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
public class EventBingoScrollRect : ScrollRect
|
||||
{
|
||||
public override void OnBeginDrag(PointerEventData eventData) { }
|
||||
public override void OnDrag(PointerEventData eventData) { }
|
||||
public override void OnEndDrag(PointerEventData eventData) { }
|
||||
}
|
||||
11
Assets/Scripts/EventBingo/EventBingoScrollRect.cs.meta
Normal file
11
Assets/Scripts/EventBingo/EventBingoScrollRect.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d9411c7312428f945a9e620d729cf122
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
129
Assets/Scripts/EventBingo/EventBingoScrollView.cs
Normal file
129
Assets/Scripts/EventBingo/EventBingoScrollView.cs
Normal file
@@ -0,0 +1,129 @@
|
||||
using UnityEngine;
|
||||
using EnhancedUI.EnhancedScroller;
|
||||
using System.Collections;
|
||||
using asap.core;
|
||||
|
||||
public class EventBingoScrollView : MonoBehaviour, IEnhancedScrollerDelegate
|
||||
{
|
||||
[SerializeField] private EventBingoScrollViewItem scrollViewItem;
|
||||
[SerializeField] private EnhancedScroller scroller;
|
||||
[SerializeField] private EventBingoScrollViewPointerListener pointerListener;
|
||||
[SerializeField] private GameObject fxBingoGlitter;
|
||||
[SerializeField] private GameObject[] goPaginationDots;
|
||||
private const int _bingoCount = 4;
|
||||
private const float _interval = 5f;
|
||||
private int _currentIndex, _roundCount;
|
||||
// private bool _pauseAutoScroll;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
scroller.Delegate = this;
|
||||
_currentIndex = 0;
|
||||
UpdatePaginationDots();
|
||||
StartCoroutine(AutoScroll());
|
||||
pointerListener.Init(PauseAutoScroll, ContinueAutoScroll, UpdatePaginationDots);
|
||||
}
|
||||
|
||||
private async void Start()
|
||||
{
|
||||
try
|
||||
{
|
||||
await Awaiters.NextFrame;
|
||||
scroller.JumpToDataIndex(_currentIndex, tweenType: scroller.snapTweenType, tweenTime: scroller.snapTweenTime);
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Debug.LogError("[EventBingo] Scroll View Start: " + e.Message);
|
||||
Debug.LogError(e);
|
||||
}
|
||||
}
|
||||
|
||||
#region IEnhancedScrollerDelegate
|
||||
public int GetNumberOfCells(EnhancedScroller scroller)
|
||||
{
|
||||
return _bingoCount;
|
||||
}
|
||||
|
||||
public float GetCellViewSize(EnhancedScroller scroller, int dataIndex)
|
||||
{
|
||||
return 532f;
|
||||
}
|
||||
|
||||
public EnhancedScrollerCellView GetCellView(EnhancedScroller scroller, int dataIndex, int cellIndex)
|
||||
{
|
||||
var res = scroller.GetCellView(scrollViewItem) as EventBingoScrollViewItem;
|
||||
res.Init(dataIndex, GContext.container.Resolve<EventBingoModel>().Ctx.GetBingoRewards(dataIndex + 1, _roundCount));
|
||||
return res;
|
||||
}
|
||||
#endregion
|
||||
|
||||
public IEnumerator AutoScroll()
|
||||
{
|
||||
// scroller.JumpToDataIndex(_currentIndex);
|
||||
do
|
||||
{
|
||||
yield return new WaitForSeconds(_interval);
|
||||
IncCurrentIdx();
|
||||
scroller.JumpToDataIndex(_currentIndex, tweenType: scroller.snapTweenType, tweenTime: scroller.snapTweenTime);
|
||||
UpdatePaginationDots();
|
||||
}
|
||||
while (true);
|
||||
}
|
||||
|
||||
private void IncCurrentIdx()
|
||||
{
|
||||
_currentIndex++;
|
||||
if (_currentIndex >= _bingoCount)
|
||||
_currentIndex = 0;
|
||||
}
|
||||
|
||||
private void PauseAutoScroll()
|
||||
{
|
||||
StopAllCoroutines();
|
||||
}
|
||||
|
||||
private void ContinueAutoScroll()
|
||||
{
|
||||
_currentIndex = scroller.GetSnapDataIndexFromScrollPosition();
|
||||
scroller.JumpToDataIndex(_currentIndex, tweenType: scroller.snapTweenType, tweenTime: scroller.snapTweenTime);
|
||||
StopAllCoroutines();
|
||||
StartCoroutine(AutoScroll());
|
||||
}
|
||||
|
||||
public async void ReloadData(int roundCount)
|
||||
{
|
||||
try
|
||||
{
|
||||
_roundCount = roundCount;
|
||||
scroller.ReloadData();
|
||||
await Awaiters.NextFrame;
|
||||
scroller.JumpToDataIndex(_currentIndex, tweenType: scroller.snapTweenType, tweenTime: scroller.snapTweenTime);
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Debug.LogError("[EventBingo] Scroll View Start: " + e.Message);
|
||||
Debug.LogError(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void ToggleBingoGlitterFx(bool open)
|
||||
{
|
||||
fxBingoGlitter.SetActive(open);
|
||||
}
|
||||
|
||||
private void UpdatePaginationDots()
|
||||
{
|
||||
for (int i = 0; i < goPaginationDots.Length; i++)
|
||||
{
|
||||
goPaginationDots[i].SetActive(i == _currentIndex);
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
private void OnGUI()
|
||||
{
|
||||
GUI.Box(new Rect(20, 20, 200, 20), $"Current Index: {_currentIndex}");
|
||||
GUI.Box(new Rect(20, 60, 200, 20), $"Current Pos: {scroller.ScrollPosition}");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
11
Assets/Scripts/EventBingo/EventBingoScrollView.cs.meta
Normal file
11
Assets/Scripts/EventBingo/EventBingoScrollView.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 10a960900fa887d4e986eab2cad4c3bc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
23
Assets/Scripts/EventBingo/EventBingoScrollViewItem.cs
Normal file
23
Assets/Scripts/EventBingo/EventBingoScrollViewItem.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using EnhancedUI.EnhancedScroller;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using GameCore;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class EventBingoScrollViewItem : EnhancedScrollerCellView
|
||||
{
|
||||
[SerializeField] private RewardItemNew[] rewardDisplayList;
|
||||
[SerializeField] private TMP_Text textBingo;
|
||||
private readonly string[] _bingoTexts = new string[] {
|
||||
"<size=76>BINGO</size>",
|
||||
"<size=100>2x</size>\n<size=64>BINGO</size>",
|
||||
"<size=100>3x</size>\n<size=64>BINGO</size>",
|
||||
"<size=100>4x</size>\n<size=64>BINGO</size>" };
|
||||
|
||||
public void Init(int index, List<ItemData> rewards)
|
||||
{
|
||||
textBingo.text = _bingoTexts[index];
|
||||
for (int i = 0; i < rewardDisplayList.Length && i < rewards.Count; i++)
|
||||
rewardDisplayList[i].SetData(rewards[i]);
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/EventBingo/EventBingoScrollViewItem.cs.meta
Normal file
11
Assets/Scripts/EventBingo/EventBingoScrollViewItem.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 231e9f9ec8acceb4e8b46b8e835d9e8c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
public class EventBingoScrollViewPointerListener : MonoBehaviour, IBeginDragHandler, IEndDragHandler/* , IPointerUpHandler */
|
||||
{
|
||||
public Action PauseAutoScroll, ContinueAutoScroll, UpdatePaginationDots;
|
||||
public void Init(Action pauseAutoScroll, Action continueAutoScroll, Action updatePaginationDots)
|
||||
{
|
||||
PauseAutoScroll = pauseAutoScroll;
|
||||
ContinueAutoScroll = continueAutoScroll;
|
||||
UpdatePaginationDots = updatePaginationDots;
|
||||
}
|
||||
public void OnBeginDrag(PointerEventData e)
|
||||
{
|
||||
// Debug.Log("[EventBingo] ScrollView: begin drag.");
|
||||
PauseAutoScroll?.Invoke();
|
||||
UpdatePaginationDots?.Invoke();
|
||||
}
|
||||
|
||||
public void OnEndDrag(PointerEventData e)
|
||||
{
|
||||
// Debug.Log("[EventBingo] ScrollView: end drag.");
|
||||
ContinueAutoScroll?.Invoke();
|
||||
UpdatePaginationDots?.Invoke();
|
||||
}
|
||||
|
||||
// public void OnPointerUp(PointerEventData eventData)
|
||||
// {
|
||||
// // Debug.Log("[EventBingo] ScrollView: pointer up.");
|
||||
// ContinueAutoScroll?.Invoke();
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 03a8f3d5a823bcd4cb8f8db93a6bd935
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
104
Assets/Scripts/EventBingo/EventBingoSystem.cs
Normal file
104
Assets/Scripts/EventBingo/EventBingoSystem.cs
Normal file
@@ -0,0 +1,104 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UniRx;
|
||||
using UnityEngine.Assertions;
|
||||
using GameCore;
|
||||
using asap.core;
|
||||
|
||||
public class EventBingoSystem
|
||||
{
|
||||
private static readonly int[] BingoStates =
|
||||
{
|
||||
0b0000000000000000000011111,
|
||||
0b0000000000000001111100000,
|
||||
0b0000000000111110000000000,
|
||||
0b0000011111000000000000000,
|
||||
0b1111100000000000000000000,
|
||||
0b1000010000100001000010000,
|
||||
0b0100001000010000100001000,
|
||||
0b0010000100001000010000100,
|
||||
0b0001000010000100001000010,
|
||||
0b0000100001000010000100001,
|
||||
0b1000001000001000001000001,
|
||||
0b0000100010001000100010000,
|
||||
0b1000100000000000000010001
|
||||
};
|
||||
|
||||
private static readonly int[] NearBingoStates =
|
||||
{
|
||||
0b0000000000000000000011110, 0b0000000000000000000011101, 0b0000000000000000000011011, 0b0000000000000000000010111, 0b0000000000000000000001111,
|
||||
0b0000000000000001111000000, 0b0000000000000001110100000, 0b0000000000000001101100000, 0b0000000000000001011100000, 0b0000000000000000111100000,
|
||||
0b0000000000111100000000000, 0b0000000000111010000000000, 0b0000000000110110000000000, 0b0000000000101110000000000, 0b0000000000011110000000000,
|
||||
0b0000011110000000000000000, 0b0000011101000000000000000, 0b0000011011000000000000000, 0b0000010111000000000000000, 0b0000001111000000000000000,
|
||||
0b1111000000000000000000000, 0b1110100000000000000000000, 0b1101100000000000000000000, 0b1011100000000000000000000, 0b0111100000000000000000000,
|
||||
0b1000010000100001000000000, 0b1000010000100000000010000, 0b1000010000000001000010000, 0b1000000000100001000010000, 0b0000010000100001000010000,
|
||||
0b0100001000010000100000000, 0b0100001000010000000001000, 0b0100001000000000100001000, 0b0100000000010000100001000, 0b0000001000010000100001000,
|
||||
0b0010000100001000010000000, 0b0010000100001000000000100, 0b0010000100000000010000100, 0b0010000000001000010000100, 0b0000000100001000010000100,
|
||||
0b0001000010000100001000000, 0b0001000010000100000000010, 0b0001000010000000001000010, 0b0001000000000100001000010, 0b0000000010000100001000010,
|
||||
0b0000100001000010000100000, 0b0000100001000010000000001, 0b0000100001000000000100001, 0b0000100000000010000100001, 0b0000000001000010000100001,
|
||||
0b1000001000001000001000000, 0b1000001000001000000000001, 0b1000001000000000001000001, 0b1000000000001000001000001, 0b0000001000001000001000001,
|
||||
0b0000100010001000100000000, 0b0000100010001000000010000, 0b0000100010000000100010000, 0b0000100000001000100010000, 0b0000000010001000100010000,
|
||||
0b1000100000000000000010000, 0b1000100000000000000000001, 0b1000000000000000000010001, 0b0000100000000000000010001,
|
||||
};
|
||||
|
||||
public static List<int> GenerateBoardNumbers(System.Random rng)
|
||||
{
|
||||
var res = new List<int>();
|
||||
var numPool = Enumerable.Range(1, 99).ToList();
|
||||
for (int i = 0; i < EventBingoModel.NumberCount; i++)
|
||||
{
|
||||
var index = rng.Next(numPool.Count);
|
||||
res.Add(numPool[index]);
|
||||
numPool.RemoveAt(index);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public static int PickRandomNumberFromList(List<int> nums, System.Random rng)
|
||||
{
|
||||
Assert.IsTrue(nums is { Count: >= 1 }, "[EventBingo] Number list is empty.");
|
||||
var idx = rng.Next(nums.Count);
|
||||
var n = nums[idx];
|
||||
nums.RemoveAt(idx);
|
||||
return n;
|
||||
}
|
||||
|
||||
public static int CheckBingo(int state, out int[] indices)
|
||||
{
|
||||
int res = 0;
|
||||
var pickedIndices = new HashSet<int>();
|
||||
for (int i = 0; i < BingoStates.Length; i++)
|
||||
{
|
||||
if ((state & BingoStates[i]) != BingoStates[i])
|
||||
continue;
|
||||
var bingoIndices = FtMathUtils.BitWisePositionScan(BingoStates[i]);
|
||||
foreach(var idx in bingoIndices)
|
||||
pickedIndices.Add(idx);
|
||||
res++;
|
||||
}
|
||||
indices = pickedIndices.ToArray();
|
||||
return res;
|
||||
}
|
||||
|
||||
public static int[] CheckNearBingoIndices(int state)
|
||||
{
|
||||
var res = new HashSet<int>();
|
||||
for (int i = 0; i < NearBingoStates.Length; i++)
|
||||
{
|
||||
if ((state & NearBingoStates[i]) != NearBingoStates[i])
|
||||
continue;
|
||||
var stateIndices = FtMathUtils.BitWisePositionScan(NearBingoStates[i]);
|
||||
foreach (var idx in stateIndices)
|
||||
res.Add(idx);
|
||||
}
|
||||
return res.ToArray();
|
||||
}
|
||||
|
||||
public static void GrantReward(ItemData reward)
|
||||
{
|
||||
// Debug.Log($"[EventBingo] Grant Reward {reward.id} * {reward.count}.");
|
||||
// if (reward.id == )
|
||||
var e = new DeferredRewardStashService.EventStashItem { Item = reward };
|
||||
GContext.Publish(e);
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/EventBingo/EventBingoSystem.cs.meta
Normal file
11
Assets/Scripts/EventBingo/EventBingoSystem.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9790dd1586cc6d5438bea29c2bc6e7f7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
249
Assets/Scripts/EventBingo/EventBingoTableContext.cs
Normal file
249
Assets/Scripts/EventBingo/EventBingoTableContext.cs
Normal file
@@ -0,0 +1,249 @@
|
||||
using System.Collections.Generic;
|
||||
using cfg;
|
||||
using asap.core;
|
||||
using GameCore;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using UnityEngine.Assertions;
|
||||
|
||||
public class EventBingoTableContext
|
||||
{
|
||||
private readonly EventBingoInit _tableInit;
|
||||
private readonly TbEventBingoMiniDrop _tableMiniDrop;
|
||||
private readonly PlayerItemData _playerItemData;
|
||||
private readonly TbEventBingoMain _tableMain;
|
||||
private readonly TbEventBingoCollectingTarget _tableTask;
|
||||
private readonly TbEventBingoConfig _tableConfig;
|
||||
private readonly FishingEvent _tableEvent;
|
||||
private readonly FishingEventCycleItem _tableCycleItem;
|
||||
|
||||
public EventBingoTableContext(int eventId)
|
||||
{
|
||||
_playerItemData = GContext.container.Resolve<PlayerItemData>();
|
||||
_tableEvent = GContext.container.Resolve<Tables>().TbFishingEvent[eventId];
|
||||
var redirectId = _tableEvent.RedirectID;
|
||||
_tableCycleItem = GContext.container.Resolve<Tables>().TbFishingEventCycleItem[redirectId];
|
||||
var cycleId = _tableCycleItem.RedirectID;
|
||||
_tableInit = GContext.container.Resolve<Tables>().TbEventBingoInit[cycleId];
|
||||
_tableMiniDrop = GContext.container.Resolve<Tables>().TbEventBingoMiniDrop;
|
||||
_tableMain = GContext.container.Resolve<Tables>().TbEventBingoMain;
|
||||
_tableTask = GContext.container.Resolve<Tables>().TbEventBingoCollectingTarget;
|
||||
_tableConfig = GContext.container.Resolve<Tables>().TbEventBingoConfig;
|
||||
}
|
||||
|
||||
public void GetMinorDropData(System.Random rng, out List<ItemData> reachableRewards, out List<ItemData> unreachableRewards)
|
||||
{
|
||||
reachableRewards = new List<ItemData>();
|
||||
unreachableRewards = new List<ItemData>();
|
||||
var dropStrat = FtMathUtils.PickRandomItemWithWeight(_tableMiniDrop.DataList, rng, x => _tableMiniDrop.DataList[x].Weight);
|
||||
Assert.IsTrue(dropStrat.DropCount == dropStrat.MiniDropCount1 + dropStrat.MiniDropCount2 && dropStrat.DropCount <= dropStrat.Count,
|
||||
$"[EventBingo] dropStrat {dropStrat.Id} invalid.");
|
||||
Debug.Log($"[EventBingo] MiniDropId: {dropStrat.Id}.");
|
||||
int i = 0;
|
||||
while (i < dropStrat.MiniDropCount1)
|
||||
{
|
||||
reachableRewards.Add(new ItemData(dropStrat.MiniItem1, 1));
|
||||
i++;
|
||||
}
|
||||
while (i < dropStrat.DropCount)
|
||||
{
|
||||
reachableRewards.Add(new ItemData(dropStrat.MiniItem2, 1));
|
||||
i++;
|
||||
}
|
||||
while (i < dropStrat.Count)
|
||||
{
|
||||
var reward = _playerItemData.GetRandomItemDataByDropId(rng, dropStrat.DropID);
|
||||
if (reward != null)
|
||||
unreachableRewards.Add(reward);
|
||||
else
|
||||
Debug.LogWarning($"[EventBingo] MiniDrop reward not found for drop Id {dropStrat.DropID}.");
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
public int PickSeed(int roundCount, int? lordOfSeeds = null, int notThisSeed = -1)
|
||||
{
|
||||
System.Random rng;
|
||||
if (lordOfSeeds != null)
|
||||
rng = new System.Random(lordOfSeeds.Value);
|
||||
else
|
||||
rng = new System.Random();
|
||||
var initSeedPools = GContext.container.Resolve<Tables>().TbEventBingoConfig.DataMap;
|
||||
roundCount += 1;
|
||||
if (initSeedPools.Keys.Contains(roundCount))
|
||||
{
|
||||
var pool = initSeedPools[roundCount].SeedID;
|
||||
var seed = pool[rng.Next(pool.Count)];
|
||||
Debug.Log($"[EventBingo] Pick init seed{seed} in round {roundCount}");
|
||||
return seed;
|
||||
}
|
||||
var seedSetup = FtMathUtils.PickRandomItemWithWeight(_tableMain.DataList, rng, idx => _tableMain.DataList[idx].Weight);
|
||||
var seedList = seedSetup.SeedID.OrderBy(x => rng.Next()).ToList();
|
||||
var res = seedList.FirstOrDefault(x => x != notThisSeed);
|
||||
Debug.Log($"[EventBingo] Selected seed: {res}.");
|
||||
return res;
|
||||
}
|
||||
|
||||
public (int seed, int bingo) PickSeedValidation(int roundCount, int? lordOfSeeds = null)
|
||||
{
|
||||
System.Random rng;
|
||||
if (lordOfSeeds != null)
|
||||
rng = new System.Random(lordOfSeeds.Value);
|
||||
else
|
||||
rng = new System.Random();
|
||||
var initSeedPools = GContext.container.Resolve<Tables>().TbEventBingoConfig.DataMap;
|
||||
roundCount += 1;
|
||||
if (initSeedPools.Keys.Contains(roundCount))
|
||||
{
|
||||
var pool = initSeedPools[roundCount].SeedID;
|
||||
var seed = pool[rng.Next(pool.Count)];
|
||||
Debug.Log($"[EventBingo] Pick init seed{seed} in round {roundCount}");
|
||||
return (seed, 0);
|
||||
}
|
||||
var seedSetup = FtMathUtils.PickRandomItemWithWeight(_tableMain.DataList, rng, idx => _tableMain.DataList[idx].Weight);
|
||||
var seedList = seedSetup.SeedID.OrderBy(x => rng.Next()).ToList();
|
||||
var res = seedList.FirstOrDefault();
|
||||
Debug.Log($"[EventBingo] Selected seed: {res}.");
|
||||
return (res, seedSetup.BingoType);
|
||||
}
|
||||
|
||||
public void GetRandomItemIcon(out int iconIdx, out string iconUrl)
|
||||
{
|
||||
var urlList = _tableInit.ItemResource;
|
||||
iconIdx = UnityEngine.Random.Range(0, urlList.Count);
|
||||
iconUrl = urlList[iconIdx];
|
||||
}
|
||||
|
||||
public string GetItemIconByIdx(int iconId)
|
||||
{
|
||||
var urlList = _tableInit.ItemResource;
|
||||
if (iconId < 0 || iconId >= urlList.Count)
|
||||
return urlList[0];
|
||||
return urlList[iconId];
|
||||
}
|
||||
|
||||
public EventBingoProgressTaskData GetTaskData()
|
||||
{
|
||||
return GetTaskData(_tableInit.TargetID);
|
||||
}
|
||||
|
||||
public EventBingoProgressTaskData GetTaskData(int taskId, int progress = 0)
|
||||
{
|
||||
var task = _tableTask.GetOrDefault(taskId);
|
||||
if (task == null)
|
||||
{
|
||||
Debug.LogError($"[EventBingo] Task not found: {taskId}.");
|
||||
return null;
|
||||
}
|
||||
return new EventBingoProgressTaskData
|
||||
{
|
||||
TaskId = taskId,
|
||||
Progress = progress,
|
||||
Reward = _playerItemData.GetItemDataByDropId(task.DropID)[0],
|
||||
TargetProgress = task.TokenRequired,
|
||||
NextTaskId = task.NextTask
|
||||
};
|
||||
}
|
||||
|
||||
public int GetTaskRewardDropId(int taskId)
|
||||
{
|
||||
return _tableTask.Get(taskId).DropID;
|
||||
}
|
||||
|
||||
public List<ItemData> GetBingoRewards(int bingo, int roundCount)
|
||||
{
|
||||
var bingoId = _tableInit.BingoTypeID[bingo - 1];
|
||||
var bingoConfig = _tableMain.GetOrDefault(bingoId);
|
||||
// var initRoundCount = _tableConfig.DataList.Count;
|
||||
var roundConfigCount = bingoConfig.DropID.Count;
|
||||
// var bingoRewardConfigIdx = (roundCount - initRoundCount) % roundConfigCount;
|
||||
var bingoRewardConfigIdx = roundCount % roundConfigCount;
|
||||
bingoRewardConfigIdx = Mathf.Max(0, bingoRewardConfigIdx);
|
||||
var dropId = bingoConfig.DropID[bingoRewardConfigIdx];
|
||||
return _playerItemData.GetItemDataByDropId(dropId);
|
||||
}
|
||||
|
||||
public Tuple<DateTime, DateTime> GetTimeLimit()
|
||||
{
|
||||
try
|
||||
{
|
||||
var et = DateTime.Parse((_tableEvent.TimeDefinition as LimitedTime).EndTime);
|
||||
var st = DateTime.Parse((_tableEvent.TimeDefinition as LimitedTime).StartTime);
|
||||
return new Tuple<DateTime, DateTime>(st, et);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Log($"[EventBingo] Time Parse Error:");
|
||||
Debug.LogError(e);
|
||||
return new Tuple<DateTime, DateTime>(DateTime.MinValue, DateTime.MinValue);
|
||||
}
|
||||
}
|
||||
|
||||
public string GetEntranceIcon()
|
||||
{
|
||||
return _tableInit.Icon;
|
||||
}
|
||||
|
||||
public int GetRedPointThreshold()
|
||||
{
|
||||
return _tableCycleItem.RedDot;
|
||||
}
|
||||
|
||||
public int GetWelcomeGift()
|
||||
{
|
||||
return _tableCycleItem.WelcomeGift;
|
||||
}
|
||||
|
||||
public EventBingoUiData GetUiData()
|
||||
{
|
||||
return new EventBingoUiData()
|
||||
{
|
||||
ChainPackPanel = _tableInit.ChainPackPanel,
|
||||
InfoPanel = _tableInit.InfoPanel
|
||||
};
|
||||
}
|
||||
|
||||
public int GetPackId()
|
||||
{
|
||||
return _tableInit.PackId;
|
||||
}
|
||||
|
||||
public ItemData GetProgressTaskFinalReward()
|
||||
{
|
||||
var firstTask = _tableInit.TargetID;
|
||||
EventBingoCollectingTarget lastTask = null;
|
||||
foreach (var task in _tableTask.DataList)
|
||||
{
|
||||
if (task.NextTask == firstTask)
|
||||
{
|
||||
lastTask = task;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (lastTask == null)
|
||||
{
|
||||
Debug.LogWarning("[EventBingo] No final reward found.");
|
||||
return null;
|
||||
}
|
||||
return _playerItemData.GetItemDataByDropId(lastTask.DropID)[0];
|
||||
}
|
||||
|
||||
public string GetNumberSfxUrl(int number)
|
||||
{
|
||||
var res = GContext.container.Resolve<Tables>().TbEventBingoVoice.DataMap.TryGetValue(number, out var s);
|
||||
if (res)
|
||||
return s.Count;
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"[EventBingo] Number {number} is not included in voice resource table");
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public string GetTicketNameKey()
|
||||
{
|
||||
var ticketId = _tableCycleItem.ItemId;
|
||||
return GContext.container.Resolve<Tables>().TbItem.Get(ticketId).Name_l10n_key;
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/EventBingo/EventBingoTableContext.cs.meta
Normal file
11
Assets/Scripts/EventBingo/EventBingoTableContext.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dacd7eb32706c4b4bb23b7a226df7bf1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
51
Assets/Scripts/EventBingo/EventBingoTaskView.cs
Normal file
51
Assets/Scripts/EventBingo/EventBingoTaskView.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using asap.core;
|
||||
using DG.Tweening;
|
||||
using GameCore;
|
||||
|
||||
public class EventBingoTaskView : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private Image progressBar;
|
||||
[SerializeField] private RewardItemNew reward, finalReward;
|
||||
[SerializeField] private TMP_Text textProgress;
|
||||
private int _taskId;
|
||||
private float _progressGrowthDuration = 0.3f;
|
||||
private ItemData _reward;
|
||||
private const float RewardFlyDuration = 1.2f;
|
||||
public int TaskId => _taskId;
|
||||
|
||||
public void Init(EventBingoProgressTaskData taskData)
|
||||
{
|
||||
progressBar.fillAmount = taskData.Progress / (float)taskData.TargetProgress;
|
||||
reward.SetData(taskData.Reward);
|
||||
textProgress.text = taskData.Progress + "/" + taskData.TargetProgress;
|
||||
_taskId = taskData.TaskId;
|
||||
_reward = taskData.Reward;
|
||||
var bingoModel = GContext.container.Resolve<EventBingoModel>();
|
||||
var fr = bingoModel.Ctx.GetProgressTaskFinalReward();
|
||||
finalReward.SetData(fr);
|
||||
}
|
||||
|
||||
public async System.Threading.Tasks.Task UpdateProgress()
|
||||
{
|
||||
var newData = GContext.container.Resolve<EventBingoModel>().TaskData;
|
||||
if (newData.TaskId == _taskId)
|
||||
{
|
||||
var newProgress = newData.Progress / (float)newData.TargetProgress;
|
||||
progressBar.DOFillAmount(newProgress, _progressGrowthDuration);
|
||||
textProgress.text = newData.Progress + "/" + newData.TargetProgress;
|
||||
}
|
||||
else
|
||||
{
|
||||
var s = textProgress.text;
|
||||
var tokens = s.Split('/');
|
||||
textProgress.text = tokens[1] + "/" + tokens[1];
|
||||
await progressBar.DOFillAmount(1, _progressGrowthDuration).AsyncWaitForCompletion();
|
||||
GContext.Publish(new EventRewardFlyStashRequest(_reward, reward.icon.GetComponent<RectTransform>()));
|
||||
await System.Threading.Tasks.Task.Delay(System.TimeSpan.FromSeconds(RewardFlyDuration));
|
||||
Init(newData);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/EventBingo/EventBingoTaskView.cs.meta
Normal file
11
Assets/Scripts/EventBingo/EventBingoTaskView.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 57e1896db652f8041805f6029aab5bd4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
217
Assets/Scripts/EventBingo/ProgressChainPackPanel.cs
Normal file
217
Assets/Scripts/EventBingo/ProgressChainPackPanel.cs
Normal file
@@ -0,0 +1,217 @@
|
||||
// Modified from ThanksGivingPackPanel. All Rights Reserved...?
|
||||
using System;
|
||||
using System.Collections;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using asap.core;
|
||||
using DG.Tweening;
|
||||
using game;
|
||||
using GameCore;
|
||||
using UniRx;
|
||||
|
||||
public class ProgressChainPackPanel : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private TMP_Text textTimer, textProgress, textComplete;
|
||||
[SerializeField] private Image barProgress;
|
||||
[SerializeField] private RewardItemNew tokenIcon, rewardProgress;
|
||||
[SerializeField] private ThanksGivingChainSlot[] slots;
|
||||
[SerializeField] private ThanksGivingChainSlot slot6;
|
||||
[SerializeField] private Button btnClose;
|
||||
[SerializeField] private Animation targetAnimation, contentAnimation;
|
||||
[SerializeField] private float jiandaProgressBarIncreaseTime;
|
||||
private readonly IEventAggregator _eventAggregator = new EventAggregator();
|
||||
private static readonly int[] IndexFromToSlotIndex = { 0, 1, 3, 2, 4, 5 };
|
||||
private IProgressChainPackData _data;
|
||||
private int _visualProgress;
|
||||
|
||||
private const string ContentAnimationShiftKey = "item_change",
|
||||
ContentAnimationIdleKey = "item_normal";
|
||||
|
||||
private void Start()
|
||||
{
|
||||
btnClose.onClick.AddListener(OnClickClose);
|
||||
}
|
||||
|
||||
public void Init(IProgressChainPackData data)
|
||||
{
|
||||
_data = data;
|
||||
for (int i = 0; i < IndexFromToSlotIndex.Length; i++) // The idx here is a little confusing....
|
||||
slots[i].Init(IndexFromToSlotIndex[i], _data, _eventAggregator);
|
||||
_eventAggregator.GetEvent<EventThanksGivingSlotClaimed>().Subscribe(OnClaim).AddTo(this);
|
||||
textTimer.text = ConvertTools.ConvertTime2(_data.RemainingTime);
|
||||
Observable.Interval(TimeSpan.FromSeconds(1.0f)).Subscribe(_ =>
|
||||
{
|
||||
textTimer.text = ConvertTools.ConvertTime2(_data.RemainingTime);
|
||||
if (_data.RemainingTime.TotalSeconds <= 0) OnClickClose();
|
||||
}).AddTo(this);
|
||||
_visualProgress = _data.TokenProgress;
|
||||
InitTargetProgress();
|
||||
contentAnimation.Play(ContentAnimationIdleKey);
|
||||
}
|
||||
|
||||
private const string BubbleKey = "bubble_task";
|
||||
|
||||
/// <summary>
|
||||
/// Triggered when player click the claim button on the reward panel. Important.
|
||||
/// </summary>
|
||||
/// <param name="e">Contains the index of the slot that is being called.</param>
|
||||
private void OnClaim(EventThanksGivingSlotClaimed e)
|
||||
{
|
||||
StopAllCoroutines();
|
||||
StartCoroutine(PlayButtonChange(e));
|
||||
StartCoroutine(PlayProgressBar(e));
|
||||
StartCoroutine(ShiftSlots());
|
||||
}
|
||||
|
||||
[SerializeField] private float jiandaParticleDelay;
|
||||
|
||||
private IEnumerator PlayParticle(EventThanksGivingSlotClaimed e)
|
||||
{
|
||||
yield return new WaitForSeconds(jiandaParticleDelay);
|
||||
var slot = slots[IndexFromToSlotIndex[e.SlotIdx]];
|
||||
slot.RewardPanelCallbackSubscription?.Dispose();
|
||||
slot.PlayParticle();
|
||||
}
|
||||
|
||||
[SerializeField] private float jiandaButtonChangeDelay;
|
||||
|
||||
private IEnumerator PlayButtonChange(EventThanksGivingSlotClaimed e)
|
||||
{
|
||||
yield return new WaitForSeconds(jiandaButtonChangeDelay);
|
||||
var slot = slots[IndexFromToSlotIndex[e.SlotIdx]];
|
||||
slot.RewardPanelCallbackSubscription?.Dispose();
|
||||
slot.PlayButtonAnimation();
|
||||
slot.PlayCanvasGroupEffect(false);
|
||||
slot.SetToken(false);
|
||||
if (e.SlotIdx + 1 < IndexFromToSlotIndex.Length)
|
||||
{
|
||||
slots[IndexFromToSlotIndex[e.SlotIdx + 1]].SetLock(false);
|
||||
slots[IndexFromToSlotIndex[e.SlotIdx + 1]].PlayCanvasGroupEffect(true);
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField] private float jiandaProgressBarDelay;
|
||||
|
||||
private IEnumerator PlayProgressBar(EventThanksGivingSlotClaimed e)
|
||||
{
|
||||
yield return new WaitForSeconds(jiandaProgressBarDelay);
|
||||
_data.GetTokenProgressTargetByProgress(_visualProgress, out var targetDisplay,
|
||||
out var scoreDisplay);
|
||||
var midtermTarget = targetDisplay - scoreDisplay + _visualProgress;
|
||||
int rewardDropId;
|
||||
if (_data.IsChainPackDepleted)
|
||||
{
|
||||
yield return DOTween.To(() => _visualProgress, p => _visualProgress = p, midtermTarget,
|
||||
jiandaProgressBarIncreaseTime).OnUpdate(() =>
|
||||
{
|
||||
_data.GetTokenProgressTargetByProgress(_visualProgress, out targetDisplay,
|
||||
out scoreDisplay);
|
||||
textProgress.text = $"{scoreDisplay}/{targetDisplay}";
|
||||
barProgress.fillAmount = (float)scoreDisplay / targetDisplay;
|
||||
}).WaitForCompletion();
|
||||
targetAnimation.Play(BubbleKey);
|
||||
barProgress.fillAmount = 1;
|
||||
textProgress.gameObject.SetActive(false);
|
||||
textComplete.gameObject.SetActive(true);
|
||||
rewardProgress.SetReceived(true);
|
||||
GContext.Publish(new ShowData(GContext.container.Resolve<PlayerItemData>()
|
||||
.GetItemDataByDropId(e.ProgressRewardGot[0], afterAdding: true)));
|
||||
GContext.Publish(new ShowData());
|
||||
yield break;
|
||||
}
|
||||
|
||||
if (e.ProgressRewardGot.Count > 0)
|
||||
{
|
||||
yield return DOTween.To(() => _visualProgress, p => _visualProgress = p, midtermTarget,
|
||||
jiandaProgressBarIncreaseTime)
|
||||
.OnUpdate(() =>
|
||||
{
|
||||
_data.GetTokenProgressTargetByProgress(_visualProgress, out targetDisplay,
|
||||
out scoreDisplay);
|
||||
// Debug.Log($"<color=#f18c0a>{_visualProgress}: {scoreDisplay}/{targetDisplay}</color>");
|
||||
textProgress.text = $"{scoreDisplay}/{targetDisplay}";
|
||||
barProgress.fillAmount = (float)scoreDisplay / targetDisplay;
|
||||
}).WaitForCompletion();
|
||||
targetAnimation.Play(BubbleKey);
|
||||
barProgress.fillAmount = 0;
|
||||
textProgress.text = $"0/{targetDisplay}";
|
||||
yield return new WaitForSeconds(35f / 60);
|
||||
}
|
||||
|
||||
rewardDropId = _data.GetRewardDropByChainProgress(_visualProgress);
|
||||
rewardProgress.SetData(GContext.container.Resolve<PlayerItemData>()
|
||||
.GetItemDataByDropId(rewardDropId)[0]);
|
||||
yield return DOTween.To(() => _visualProgress, p => _visualProgress = p,
|
||||
_data.TokenProgress,
|
||||
jiandaProgressBarIncreaseTime)
|
||||
.OnUpdate(() =>
|
||||
{
|
||||
_data.GetTokenProgressTargetByProgress(_visualProgress, out targetDisplay,
|
||||
out scoreDisplay);
|
||||
textProgress.text = $"{scoreDisplay}/{targetDisplay}";
|
||||
barProgress.fillAmount = (float)scoreDisplay / targetDisplay;
|
||||
}).WaitForCompletion();
|
||||
if (e.ProgressRewardGot.Count > 0)
|
||||
{
|
||||
GContext.Publish(
|
||||
new ShowData(GContext.container.Resolve<PlayerItemData>()
|
||||
.GetItemDataByDropId(e.ProgressRewardGot[0], afterAdding: true)));
|
||||
GContext.Publish(new ShowData());
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField] private float jiandaSlotShiftDelay;
|
||||
|
||||
private IEnumerator ShiftSlots()
|
||||
{
|
||||
yield return new WaitForSeconds(jiandaSlotShiftDelay);
|
||||
if (!_data.IsEndGame)
|
||||
{
|
||||
slot6.Init(6, _data, _eventAggregator);
|
||||
contentAnimation.Play(ContentAnimationShiftKey);
|
||||
yield return new WaitForSeconds(35f / 60);
|
||||
contentAnimation.Play(ContentAnimationIdleKey);
|
||||
}
|
||||
|
||||
for (int i = 0;
|
||||
i < IndexFromToSlotIndex.Length;
|
||||
i++) // The idx here is a little confusing....
|
||||
{
|
||||
slots[i].Init(IndexFromToSlotIndex[i], _data, _eventAggregator);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnClickClose()
|
||||
{
|
||||
RedPointManager.Instance.SetRedPointState(_data.RedPointKey, _data.DoNeedPackRedPoint);
|
||||
UIManager.Instance.DestroyUI(gameObject.name);
|
||||
}
|
||||
|
||||
private void InitTargetProgress()
|
||||
{
|
||||
if (_data.IsChainPackDepleted)
|
||||
{
|
||||
barProgress.fillAmount = 1;
|
||||
textProgress.gameObject.SetActive(false);
|
||||
textComplete.gameObject.SetActive(true);
|
||||
var rewardDropId = _data.GetRewardDropByChainProgress(_visualProgress);
|
||||
rewardProgress.SetData(GContext.container.Resolve<PlayerItemData>()
|
||||
.GetItemDataByDropId(rewardDropId)[0]);
|
||||
rewardProgress.SetReceived(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
_data.GetTokenProgressTargetByProgress(_visualProgress, out var targetDisplay,
|
||||
out var scoreDisplay);
|
||||
// Debug.Log($"<color=#f18c0a>Start {_visualProgress}-{targetDisplay} - {scoreDisplay}</color>");
|
||||
barProgress.fillAmount = scoreDisplay / (float)targetDisplay;
|
||||
textProgress.text = $"{scoreDisplay}/{targetDisplay}";
|
||||
textComplete.gameObject.SetActive(false);
|
||||
tokenIcon.SetIcon(_data.TokenIconUrl);
|
||||
var rewardDropId = _data.GetRewardDropByChainProgress(_visualProgress);
|
||||
rewardProgress.SetData(GContext.container.Resolve<PlayerItemData>()
|
||||
.GetItemDataByDropId(rewardDropId)[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/EventBingo/ProgressChainPackPanel.cs.meta
Normal file
11
Assets/Scripts/EventBingo/ProgressChainPackPanel.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e28c70608f35d0c46b1fde2e9bcc7987
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user