备份CatanBuilding瘦身独立工程
This commit is contained in:
111
Assets/Scripts/EventBreak/ChainPackPanel.cs
Normal file
111
Assets/Scripts/EventBreak/ChainPackPanel.cs
Normal file
@@ -0,0 +1,111 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using asap.core;
|
||||
using GameCore;
|
||||
using UnityEngine;
|
||||
using TMPro;
|
||||
using UniRx;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class ChainPackPanel : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private TMP_Text textTimer;
|
||||
[SerializeField] private ShootingChainSlot[] slots;
|
||||
[SerializeField] private ShootingChainSlot slot6;
|
||||
[SerializeField] private Button btnClose;
|
||||
[SerializeField] private Animation /*targetAnimation,*/ contentAnimation;
|
||||
private readonly IEventAggregator _eventAggregator = new EventAggregator();
|
||||
private static readonly int[] IndexFromToSlotIndex = { 0, 1, 3, 2, 4, 5 };
|
||||
private IChainPackData _data;
|
||||
|
||||
private const string ContentAnimationShiftKey = "item_change", ContentAnimationIdleKey = "item_normal";
|
||||
|
||||
public void Init(IChainPackData data)
|
||||
{
|
||||
btnClose.onClick.AddListener(OnClickClose);
|
||||
_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<EventChainPackClaimed>().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);
|
||||
contentAnimation.Play(ContentAnimationIdleKey);
|
||||
}
|
||||
|
||||
/// <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(EventChainPackClaimed e)
|
||||
{
|
||||
StopAllCoroutines();
|
||||
StartCoroutine(PlayParticle(e));
|
||||
StartCoroutine(PlayButtonChange(e));
|
||||
StartCoroutine(ShiftSlots());
|
||||
RedPointManager.Instance.SetRedPointState(_data.RedPointKey, _data.DoNeedPackRedPoint);
|
||||
}
|
||||
|
||||
[SerializeField] private float jiandaParticleDelay;
|
||||
private IEnumerator PlayParticle(EventChainPackClaimed e)
|
||||
{
|
||||
yield return new WaitForSeconds(jiandaParticleDelay);
|
||||
var slot = slots[IndexFromToSlotIndex[e.SlotIdx]];
|
||||
slot.RewardPanelCallbackSubscription?.Dispose();
|
||||
}
|
||||
|
||||
[SerializeField] private float jiandaButtonChangeDelay;
|
||||
private IEnumerator PlayButtonChange(EventChainPackClaimed e)
|
||||
{
|
||||
yield return new WaitForSeconds(jiandaButtonChangeDelay);
|
||||
var slot = slots[IndexFromToSlotIndex[e.SlotIdx]];
|
||||
slot.RewardPanelCallbackSubscription?.Dispose();
|
||||
slot.PlayButtonAnimation();
|
||||
slot.PlayCanvasGroupEffect(false);
|
||||
if (e.SlotIdx + 1 < IndexFromToSlotIndex.Length)
|
||||
{
|
||||
slots[IndexFromToSlotIndex[e.SlotIdx + 1]].SetLock(false);
|
||||
slots[IndexFromToSlotIndex[e.SlotIdx + 1]].PlayCanvasGroupEffect(true);
|
||||
}
|
||||
}
|
||||
|
||||
[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....
|
||||
{
|
||||
// Debug.Log($"[EventBreak]Index: {IndexFromToSlotIndex[i]}");
|
||||
slots[i].Init(IndexFromToSlotIndex[i], _data, _eventAggregator);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnClickClose()
|
||||
{
|
||||
// RedPointManager.Instance.SetRedPointState(EventShootingRangeData.PackRedPointId, _data.DoNeedPackRedPoint);
|
||||
UIManager.Instance.DestroyUI(gameObject.name);
|
||||
}
|
||||
}
|
||||
public class EventChainPackClaimed
|
||||
{
|
||||
public readonly int SlotIdx;
|
||||
public List<int> ProgressRewardGot;
|
||||
|
||||
public EventChainPackClaimed(int slotIdx)
|
||||
{
|
||||
SlotIdx = slotIdx;
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/EventBreak/ChainPackPanel.cs.meta
Normal file
11
Assets/Scripts/EventBreak/ChainPackPanel.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cd6d71d5a89f6a94184e15a38c33ead7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
24
Assets/Scripts/EventBreak/CloseSelfPanel.cs
Normal file
24
Assets/Scripts/EventBreak/CloseSelfPanel.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using GameCore;
|
||||
using System;
|
||||
public class CloseSelfPanel : MonoBehaviour
|
||||
{
|
||||
[SerializeField] Button btnClose;
|
||||
private void Start()
|
||||
{
|
||||
btnClose.onClick.AddListener(OnClickClose);
|
||||
}
|
||||
|
||||
private void OnClickClose()
|
||||
{
|
||||
try
|
||||
{
|
||||
UIManager.Instance.DestroyUI(gameObject.name);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Log($"<color=red>{e.Message}\n{e.StackTrace}</color>");
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/EventBreak/CloseSelfPanel.cs.meta
Normal file
11
Assets/Scripts/EventBreak/CloseSelfPanel.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4fd96789afda86140a32c4d74754bec0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
46
Assets/Scripts/EventBreak/EventBreakAct.cs
Normal file
46
Assets/Scripts/EventBreak/EventBreakAct.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using System.Threading.Tasks;
|
||||
using asap.core;
|
||||
using GameCore;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using DG.Tweening;
|
||||
|
||||
public class EventBreakAct : AGameAct
|
||||
{
|
||||
public static EventBreakTableContext Ctx { get; set; }
|
||||
public static DrillSystem DrillSystem { get; private set; }
|
||||
public static string ActAddressable = "EventBreakAct";
|
||||
public static IEventAggregator EventAggregator = new EventAggregator();
|
||||
private IDeferredRewardStashService _rewardStashService;
|
||||
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;
|
||||
private void Awake()
|
||||
{
|
||||
_canvasScaler = UIManager.Instance.GetComponent<CanvasScaler>();
|
||||
originalResolution = _canvasScaler.referenceResolution;
|
||||
// DOTween.To(() => _canvasScaler.referenceResolution, v => _canvasScaler.referenceResolution = v, targetResolution, duration).SetEase(Ease.OutQuad);
|
||||
_canvasScaler.referenceResolution = targetResolution;
|
||||
}
|
||||
|
||||
public override async Task<bool> StartAsync()
|
||||
{
|
||||
_rewardStashService = GContext.container.Resolve<IDeferredRewardStashService>();
|
||||
_rewardStashService.Reset();
|
||||
DrillSystem = new DrillSystem(Ctx);
|
||||
await UIManager.Instance.ShowUILoad(UITypes.EventBreakPanel);
|
||||
return await base.StartAsync();
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
// DOTween.To(() => _canvasScaler.referenceResolution, v => _canvasScaler.referenceResolution = v, originalResolution, duration).SetEase(Ease.OutQuad);
|
||||
_canvasScaler.referenceResolution = originalResolution;
|
||||
UIManager.Instance.DestroyUI(UITypes.EventBreakPanel);
|
||||
Debug.Log("[Break] EventBreakAct destroyed.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
11
Assets/Scripts/EventBreak/EventBreakAct.cs.meta
Normal file
11
Assets/Scripts/EventBreak/EventBreakAct.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 07aada2ca80257b42894937e409ba65c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
87
Assets/Scripts/EventBreak/EventBreakBlock.cs
Normal file
87
Assets/Scripts/EventBreak/EventBreakBlock.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
using DG.Tweening;
|
||||
using UnityEngine;
|
||||
using GameCore;
|
||||
using System;
|
||||
|
||||
public class EventBreakBlock : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private RewardItemNew reward;
|
||||
[SerializeField] private GameObject crack, mask, fxBreak;
|
||||
[SerializeField] private RectTransform rectTransform;
|
||||
public RectTransform RectTransform => rectTransform;
|
||||
private DrillBlockData _blockData;
|
||||
private float _fxLiftTime;
|
||||
|
||||
/// <summary>
|
||||
/// Move Block from startPoint to endPoint within dropTime and set item to it
|
||||
/// </summary>
|
||||
/// <param name="blockData">Item inside. Could be empty.</param>
|
||||
/// <param name="startPoint">Screen Position</param>
|
||||
/// <param name="endPoint">Screen Position</param>
|
||||
/// <param name="dropTime">In Seconds</param>
|
||||
public void Appear(DrillBlockData blockData, float dropHeight, Vector2 endPoint, AnimationCurve easeCurve, float dropTime = 0.5f, float fxLifeTime = 1f)
|
||||
{
|
||||
var startPoint = endPoint + Vector2.up * dropHeight;
|
||||
try
|
||||
{
|
||||
// Debug.Log($"[Break] Block Appear from {startPoint} to {endPoint}.", this);
|
||||
transform.position = startPoint;
|
||||
gameObject.SetActive(true);
|
||||
if (blockData.IsEmpty)
|
||||
SetEmpty();
|
||||
else
|
||||
SetReward(blockData.Item);
|
||||
transform.DOMove(endPoint, dropTime).SetEase(easeCurve);
|
||||
_blockData = blockData;
|
||||
_fxLiftTime = fxLifeTime;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Debug.Log($"Block Spawn Error: {e.Message}, {e.StackTrace}");
|
||||
}
|
||||
}
|
||||
|
||||
public void Break()
|
||||
{
|
||||
// Debug.Log($"[EventBreak] Block broken: {_blockData.IsEmpty}, {_blockData.ItemId}, {_blockData.ItemCount}.", this);
|
||||
PlayBreakFx();
|
||||
gameObject.SetActive(false);
|
||||
if (_blockData == null || _blockData.IsEmpty)
|
||||
return;
|
||||
EventBreakAct.EventAggregator.Publish(new EventBreakBlockBreak{BreakPos = transform.position, Item = _blockData.Item});
|
||||
}
|
||||
|
||||
private async void PlayBreakFx()
|
||||
{
|
||||
try
|
||||
{
|
||||
fxBreak.SetActive(false);
|
||||
// await Awaiters.NextFrame;
|
||||
fxBreak.SetActive(true);
|
||||
// await Awaiters.NextFrame;
|
||||
await System.Threading.Tasks.Task.Delay(TimeSpan.FromSeconds(_fxLiftTime));
|
||||
// await Awaiters.NextFrame;
|
||||
fxBreak.SetActive(false);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Log($"[EventBreak]Block Break Fx Error:{e.Message}\n{e.StackTrace}", this);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetReward(ItemData item)
|
||||
{
|
||||
reward.SetData(item);
|
||||
reward.gameObject.SetActive(true);
|
||||
crack.SetActive(true);
|
||||
mask.SetActive(true);
|
||||
}
|
||||
|
||||
private void SetEmpty()
|
||||
{
|
||||
reward.gameObject.SetActive(false);
|
||||
crack.SetActive(false);
|
||||
mask.SetActive(false);
|
||||
}
|
||||
|
||||
}
|
||||
11
Assets/Scripts/EventBreak/EventBreakBlock.cs.meta
Normal file
11
Assets/Scripts/EventBreak/EventBreakBlock.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1f22a5d20f8817646aedf5cf6673c7f4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
95
Assets/Scripts/EventBreak/EventBreakBoxingGlove.cs
Normal file
95
Assets/Scripts/EventBreak/EventBreakBoxingGlove.cs
Normal file
@@ -0,0 +1,95 @@
|
||||
using DG.Tweening;
|
||||
using Spine.Unity;
|
||||
using UnityEngine;
|
||||
using System.Threading.Tasks;
|
||||
using System;
|
||||
using GameCore;
|
||||
using asap.core;
|
||||
using Game;
|
||||
|
||||
public class EventBreakBoxingGlove : EventBreakDrillDisplay
|
||||
{
|
||||
public override float Y
|
||||
{
|
||||
get
|
||||
{
|
||||
aniSpring.Skeleton.UpdateWorldTransform();
|
||||
var bones = aniSpring.Skeleton.Bones;
|
||||
var bone = bones.Items[59];
|
||||
// var worldPos = bone.GetWorldPosition(aniSpring.transform, 100);
|
||||
var worldPos = bone.GetWorldPosition(aniSpring.transform, UIManager.Instance.CanvasScaler.referencePixelsPerUnit);
|
||||
return worldPos.y;
|
||||
}
|
||||
}
|
||||
private Vector3 _originalPos;
|
||||
[SerializeField] private SkeletonGraphic aniSpring;
|
||||
private const string Idle = "boxing_idle", Push = "boxing_start", Pull = "boxing_return";
|
||||
private readonly string[] _launchAudios =
|
||||
new string[] { "audio_ui_eventbreak_boxing_start_01",
|
||||
"audio_ui_eventbreak_boxing_start_02",
|
||||
"audio_ui_eventbreak_boxing_start_03" };
|
||||
private int _tunnelIdx;
|
||||
|
||||
public override Tween GetDrillTween(Vector3 endPos, float duration = 0.5f)
|
||||
{
|
||||
// transform.position = _originalPos;
|
||||
// var push = transform.DOMove(endPos, duration).SetEase(Ease.InSine);
|
||||
// var pull = transform.DOMove(_originalPos, duration).SetEase(Ease.InSine);
|
||||
// return DOTween.Sequence().Append(push).Append(pull);
|
||||
float t = 0;
|
||||
return DOTween.To(() => t, x => t = x, 1f, duration);
|
||||
}
|
||||
|
||||
public override void Init(int tunnelIndex)
|
||||
{
|
||||
_originalPos = transform.position;
|
||||
PlayAnimation(Idle);
|
||||
_tunnelIdx = tunnelIndex;
|
||||
}
|
||||
|
||||
public override async void PlayDrill(float readyDuration = 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
Debug.Log("[EventBreak] Play Drill.");
|
||||
GContext.Publish(new EventUISound(_launchAudios[_tunnelIdx]));
|
||||
await PlayAnimationAsync(Push);
|
||||
await PlayAnimationAsync(Pull);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Log($"[EventBreak] Play Drill Error");
|
||||
Debug.LogError(e);
|
||||
}
|
||||
}
|
||||
|
||||
public override void PlayEnter(Vector3 startPos)
|
||||
{
|
||||
// Debug.Log("[EventBreak] Play Enter in boxing.");
|
||||
}
|
||||
|
||||
private async Task PlayAnimationAsync(string animationName, double duration = 0)
|
||||
{
|
||||
if (aniSpring == null)
|
||||
return;
|
||||
var animationEntry = aniSpring.AnimationState.SetAnimation(0, animationName, false);
|
||||
if (duration == 0)
|
||||
duration = animationEntry.Animation.Duration;
|
||||
await Task.Delay(TimeSpan.FromSeconds(duration));
|
||||
// var bl = aniSpring.Skeleton.Bones.ToList();
|
||||
// for (int i = 0; i < bl.Count; i++)
|
||||
// {
|
||||
// Debug.Log($"[EventBreak] {i}: {bl[i].Data.Name} at height {bl[i].WorldY}");
|
||||
// }
|
||||
}
|
||||
|
||||
private void PlayAnimation(string animationName)
|
||||
{
|
||||
aniSpring.AnimationState.SetAnimation(0, animationName, false);
|
||||
}
|
||||
|
||||
private void Reset()
|
||||
{
|
||||
aniSpring = transform.Find("spine").GetComponent<SkeletonGraphic>();
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/EventBreak/EventBreakBoxingGlove.cs.meta
Normal file
11
Assets/Scripts/EventBreak/EventBreakBoxingGlove.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ac9dc8d95aa28e4489f0bc3afbc6f4fe
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
379
Assets/Scripts/EventBreak/EventBreakData.cs
Normal file
379
Assets/Scripts/EventBreak/EventBreakData.cs
Normal file
@@ -0,0 +1,379 @@
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using SystemRandom = System.Random;
|
||||
using System.Text;
|
||||
using System;
|
||||
using UnityEngine.Assertions;
|
||||
using GameCore;
|
||||
using cfg;
|
||||
using System.Collections.Generic;
|
||||
using asap.core;
|
||||
|
||||
public class DrillBlockData
|
||||
{
|
||||
public ItemData Item { get; set; }
|
||||
public bool IsEmpty => Item == null || Item.id == -1 || (int)Item.count == 0;
|
||||
public static DrillBlockData CreateEmpty()
|
||||
{
|
||||
return new DrillBlockData();
|
||||
}
|
||||
}
|
||||
|
||||
public class DrillJobModel
|
||||
{
|
||||
public int Cost { get; set; }
|
||||
public DrillBlockData[] Blocks { get; set; }
|
||||
}
|
||||
|
||||
public class EventBreakTaskGenerationInfo
|
||||
{
|
||||
public int TableId { get; set; }
|
||||
public int CurrentGemProgress { get; set; }
|
||||
public int TargetItemId { get; set; }
|
||||
}
|
||||
|
||||
public class EventBreakTaskInfo
|
||||
{
|
||||
public int TaskId { get; set; }
|
||||
public int TargetItemId { get; set; }
|
||||
public ItemData Reward { get; set; }
|
||||
public int TotalGemRequired { get; set; }
|
||||
public int CurrentGemProgress { get; set; }
|
||||
}
|
||||
|
||||
public class DrillModel : IHasChainPack
|
||||
{
|
||||
public int EventId { get; set; }
|
||||
public int TicketCount { get; private set; }
|
||||
public DrillJobModel[] DrillJobList { get; set; }
|
||||
public EventBreakTaskInfo[] TaskInfoList { get; set; }
|
||||
public int[] DrillJobSeeds { get; set; }
|
||||
public int ChainPackProgress;
|
||||
public void Update(int eventId, EventBreakPfData pfData = null) // new event
|
||||
{
|
||||
if (pfData == null || pfData.EventId != eventId)
|
||||
{
|
||||
GenSeeds();
|
||||
EventBreakAct.Ctx.GetFreshNewModelData(DrillJobSeeds, out var welcomeGift, out var drillJobs, out var taskInfoList);
|
||||
EventId = eventId;
|
||||
TicketCount = welcomeGift;
|
||||
TaskInfoList = taskInfoList;
|
||||
DrillJobList = drillJobs;
|
||||
ChainPackProgress = 0;
|
||||
ToPlayfabData().Save();
|
||||
return;
|
||||
}
|
||||
// var playerPreferenceData = EventBreakPlayerPreferenceData.Get(EventBreakAct.Ctx.TunnelCount);
|
||||
EventId = eventId;
|
||||
TicketCount = pfData.TicketCount;
|
||||
DrillJobSeeds = pfData.DrillJobSeeds;
|
||||
TaskInfoList = EventBreakAct.Ctx.GetTaskInfoArray(pfData.TaskData);
|
||||
DrillJobList = EventBreakAct.Ctx.GetDrillJobModels(pfData.DrillJobSeeds);
|
||||
ChainPackProgress = pfData.ChainPackProgress;
|
||||
return;
|
||||
}
|
||||
|
||||
private void GenSeeds()
|
||||
{
|
||||
DrillJobSeeds ??= new int[EventBreakAct.Ctx.TunnelCount];
|
||||
for (int i = 0; i < DrillJobSeeds.Length; i++)
|
||||
DrillJobSeeds[i] = 0;
|
||||
// ToPlayfabData().Save();
|
||||
}
|
||||
|
||||
public void UpdateSeed(int idx)
|
||||
{
|
||||
// DrillJobSeeds ??= new int[EventBreakAct.Ctx.TunnelCount];
|
||||
if (EventBreakAct.Ctx.DoesSeedNeedInc(idx, DrillJobSeeds[idx]))
|
||||
{
|
||||
DrillJobSeeds[idx]++;
|
||||
ToPlayfabData().Save();
|
||||
return;
|
||||
}
|
||||
Assert.IsTrue(idx >= 0 && idx < DrillJobSeeds.Length,
|
||||
$"[EventBreak] Cannot genenrate seed, idx {idx} is out of range [0, {DrillJobSeeds.Length}]");
|
||||
var seed = DateTime.Now.Millisecond;
|
||||
DrillJobSeeds[idx] = new SystemRandom(seed).Next();
|
||||
ToPlayfabData().Save();
|
||||
}
|
||||
|
||||
public bool AddTicket(int add)
|
||||
{
|
||||
if (TicketCount + add < 0)
|
||||
return false;
|
||||
TicketCount += add;
|
||||
ToPlayfabData().Save();
|
||||
GContext.container.Resolve<FishingEventData>().SaveTransitionData(EventId, TicketCount);
|
||||
EventBreakAct.EventAggregator.Publish(new EventTicketUpdate());
|
||||
return true;
|
||||
}
|
||||
|
||||
public EventBreakPfData ToPlayfabData()
|
||||
{
|
||||
return new EventBreakPfData
|
||||
{
|
||||
EventId = EventId,
|
||||
TicketCount = TicketCount,
|
||||
TaskData = TaskInfoList.Select(i => (i.TaskId, i.CurrentGemProgress)).ToArray(),
|
||||
ChainPackProgress = ChainPackProgress,
|
||||
DrillJobSeeds = DrillJobSeeds
|
||||
};
|
||||
}
|
||||
|
||||
public void SetChainProgress(int p)
|
||||
{
|
||||
ChainPackProgress = p;
|
||||
}
|
||||
|
||||
public int GetChainProgress()
|
||||
{
|
||||
return ChainPackProgress;
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
ToPlayfabData().Save();
|
||||
}
|
||||
|
||||
public GenericChainPackData<DrillModel> ToChainPackData()
|
||||
{
|
||||
return GenericChainPackData<DrillModel>.Create(this, EventBreakAct.Ctx.GetPackData());
|
||||
}
|
||||
}
|
||||
|
||||
public class EventBreakPfData
|
||||
{
|
||||
public int EventId { get; set; }
|
||||
public int TicketCount { get; set; }
|
||||
public int ChainPackProgress { get; set; }
|
||||
public (int id, int progress)[] TaskData { get; set; }
|
||||
public int[] DrillJobSeeds { get; set; }
|
||||
private const string Splitter = ",";
|
||||
public const string PfKey = "EventBreak";
|
||||
/// <summary>
|
||||
/// Temporary stash.
|
||||
/// </summary>
|
||||
// public static EventBreakPfData Stash = null;
|
||||
private const int TokenCount = 12;
|
||||
|
||||
public string Serialize()
|
||||
{
|
||||
var s = new StringBuilder();
|
||||
s.Append(EventId + Splitter);
|
||||
s.Append(TicketCount + Splitter);
|
||||
s.Append(ChainPackProgress + Splitter);
|
||||
foreach (var (id, progress) in TaskData)
|
||||
s.Append(id + Splitter + progress + Splitter);
|
||||
foreach (var seed in DrillJobSeeds)
|
||||
s.Append(seed + Splitter);
|
||||
return s.ToString();
|
||||
}
|
||||
|
||||
public static EventBreakPfData Deserialize(string s)
|
||||
{
|
||||
if (s == null)
|
||||
{
|
||||
Debug.Log($"[EventBreak]Null string.");
|
||||
return null;
|
||||
}
|
||||
var res = new EventBreakPfData();
|
||||
var tokens = s.Trim(Splitter[0]).Split(Splitter);
|
||||
if (tokens.Length != TokenCount)
|
||||
{
|
||||
Debug.Log($"[EventBreak]Wrong string format: string \"{s}\" has {tokens.Length} tokens, and the expected number is {TokenCount}");
|
||||
return null;
|
||||
}
|
||||
try
|
||||
{
|
||||
res.EventId = int.Parse(tokens[0]);
|
||||
res.TicketCount = int.Parse(tokens[1]);
|
||||
res.ChainPackProgress = int.Parse(tokens[2]);
|
||||
res.TaskData = new (int id, int progress)[3];
|
||||
int i = 3;
|
||||
while (i < 9)
|
||||
{
|
||||
res.TaskData[i / 2 - 1] = (int.Parse(tokens[i]), int.Parse(tokens[i + 1]));
|
||||
i += 2;
|
||||
}
|
||||
res.DrillJobSeeds = new int[3];
|
||||
while (i < TokenCount)
|
||||
{
|
||||
res.DrillJobSeeds[i - 9] = int.Parse(tokens[i]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Log($"[EventBreak]Possible parse error: {e.Message}\n{e.StackTrace}");
|
||||
return null;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
var s = Serialize();
|
||||
PlayFabMgr.Instance.UpdateUserDataValue(PfKey, s);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
public class EventBreakPlayerPreferenceDataLegacy
|
||||
{
|
||||
public int[] Seeds { get; set; }
|
||||
private const string Splitter = ",", PpKey = "EventBreakCache";
|
||||
|
||||
public static EventBreakPlayerPreferenceDataLegacy Get(int seedCount = 3)
|
||||
{
|
||||
var s = PlayerPrefs.GetString(PpKey);
|
||||
if (s == "")
|
||||
return GenSeeds(seedCount);
|
||||
var res = Deserialize(s);
|
||||
if (res == null)
|
||||
return GenSeeds(seedCount);
|
||||
return res;
|
||||
}
|
||||
|
||||
private static EventBreakPlayerPreferenceDataLegacy GenSeeds(int count)
|
||||
{
|
||||
var seeds = new int[count];
|
||||
var rng = new SystemRandom(DateTime.Now.Millisecond);
|
||||
for (int i = 0; i < count; i++)
|
||||
seeds[i] = rng.Next();
|
||||
return new EventBreakPlayerPreferenceDataLegacy
|
||||
{
|
||||
Seeds = seeds
|
||||
};
|
||||
}
|
||||
|
||||
private static EventBreakPlayerPreferenceDataLegacy Deserialize(string s)
|
||||
{
|
||||
var tokens = s.Trim(Splitter[0]).Split(Splitter);
|
||||
var seeds = new int[tokens.Length];
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < tokens.Length; i++)
|
||||
seeds[i] = int.Parse(tokens[i]);
|
||||
return new EventBreakPlayerPreferenceDataLegacy
|
||||
{
|
||||
Seeds = seeds
|
||||
};
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Log($"[EventBreak]Possible parse error: {e.Message}\n{e.StackTrace}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private string Serialize()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
foreach (var seed in Seeds)
|
||||
{
|
||||
sb.Append(seed + Splitter);
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
var s = Serialize();
|
||||
PlayerPrefs.SetString(PpKey, s);
|
||||
}
|
||||
}
|
||||
|
||||
public class EventBreakUIData
|
||||
{
|
||||
public string MainPanelUrl { get; set; }
|
||||
public string InfoPanelUrl { get; set; }
|
||||
public string ChainPackPanelUrl { get; set; }
|
||||
public string NormalPackPanelUrl { get; set; }
|
||||
public string RewardPanelUrl { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class EventBreakChainPackGenerationInfo
|
||||
{
|
||||
public List<int> ChainList { get; set; }
|
||||
public DateTime ExpireTime { get; set; }
|
||||
public Pack[] Packs { get; set; }
|
||||
}
|
||||
|
||||
// public class EventBreakChainPackData : IChainPackData
|
||||
// {
|
||||
// private const int SlotCount = 6;
|
||||
// private List<int> ChainList { get; set; }
|
||||
// private Pack[] Packs { get; set; }
|
||||
// public bool IsEndGame => ChainProgress > ChainList.Count - SlotCount;
|
||||
// public int ChainListCount => ChainList.Count;
|
||||
// public int ChainProgress { get; set; }
|
||||
// public int EventId { get; set; }
|
||||
// private DateTime ExpireTime { get; set; }
|
||||
// public TimeSpan RemainingTime => ExpireTime - ZZTimeHelper.UtcNow();
|
||||
|
||||
// public bool IsChainPackDepleted => ChainProgress >= ChainListCount;
|
||||
|
||||
// public bool DoNeedPackRedPoint
|
||||
// {
|
||||
// get
|
||||
// {
|
||||
// if (!IsChainPackDepleted && ChainProgress < ChainListCount)
|
||||
// return Packs[ChainProgress].IAPID == 0;
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
|
||||
// public string RedPointKey => "eventbreak.pack";
|
||||
|
||||
// public EventBreakChainPackData(EventBreakChainPackGenerationInfo info, int eventId, ref int chainProgress)
|
||||
// {
|
||||
// ChainList = info.ChainList;
|
||||
// ChainProgress = chainProgress;
|
||||
// EventId = eventId;
|
||||
// ExpireTime = info.ExpireTime;
|
||||
// Packs = info.Packs;
|
||||
// }
|
||||
|
||||
// public Pack GetChainPackByChainProgress(int chainProgress)
|
||||
// {
|
||||
// // Debug.Log($"[EventBreak] chainProgress: {chainProgress}");
|
||||
// return Packs[chainProgress];
|
||||
// }
|
||||
|
||||
// public int GetChainProgressBySlotIdx(int slotIdx)
|
||||
// {
|
||||
// int res;
|
||||
// if (ChainProgress > ChainList.Count - SlotCount)
|
||||
// res = ChainList.Count - SlotCount + slotIdx;
|
||||
// else
|
||||
// res = ChainProgress + slotIdx;
|
||||
// Assert.IsTrue(res < ChainList.Count, $"Progress {res} out of range: {ChainListCount}");
|
||||
// // Debug.Log($"[EventBreak] slotIdx: {slotIdx}, chainProgress: {res}");
|
||||
// return res;
|
||||
// }
|
||||
|
||||
// // Is this needed or what?
|
||||
// public List<int> GetTokenProgressRewardAfterAddingToken(int tokenAdded)
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
|
||||
// public void UploadData()
|
||||
// {
|
||||
// EventBreakAct.DrillModel.ChainPackProgress = ChainProgress;
|
||||
// EventBreakAct.DrillModel.ToPlayfabData().Save();
|
||||
// }
|
||||
|
||||
// public void OnBuySuccess()
|
||||
// {
|
||||
// ChainProgress++;
|
||||
// UploadData();
|
||||
// }
|
||||
|
||||
// public List<ItemData> GetItemsByPackDropId(int dropId)
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
// }
|
||||
11
Assets/Scripts/EventBreak/EventBreakData.cs.meta
Normal file
11
Assets/Scripts/EventBreak/EventBreakData.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 55ff740d191c85b41abf0278bc2e9191
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
96
Assets/Scripts/EventBreak/EventBreakDrill.cs
Normal file
96
Assets/Scripts/EventBreak/EventBreakDrill.cs
Normal file
@@ -0,0 +1,96 @@
|
||||
using UnityEngine;
|
||||
using Spine.Unity;
|
||||
using System.Threading.Tasks;
|
||||
using System;
|
||||
using DG.Tweening;
|
||||
using asap.core;
|
||||
using Game;
|
||||
|
||||
public class EventBreakDrill : EventBreakDrillDisplay
|
||||
{
|
||||
[SerializeField] private SkeletonGraphic aniDrill;
|
||||
private const string _drillAnimationStart = "drill_start", _drillAnimationSpin = "drill_spin", _drillAnimationIdle = "drill_idle";
|
||||
[SerializeField] private float _jiandaDrillResetDuration = 0.3f;
|
||||
[SerializeField] private GameObject fxDrill;
|
||||
private Vector3 _originalPos;
|
||||
|
||||
public override void Init(int tunnelIndex)
|
||||
{
|
||||
_originalPos = transform.position;
|
||||
gameObject.SetActive(false);
|
||||
// Debug.Log($"[EventBreak] Wakeup! Drill {tunnelIndex} init!", this);
|
||||
}
|
||||
|
||||
public override async void PlayDrill(float readyDuration = 0)
|
||||
{
|
||||
// Debug.Log($"[EventBreak] Wakeup! Drill played!", this);
|
||||
fxDrill.SetActive(true);
|
||||
GContext.Publish(new EventUISound("audio_ui_drill_drill_launch", 0));
|
||||
await PlayDrillAnimationReady(_drillAnimationStart, readyDuration);
|
||||
PlayDrillAnimationLoop(_drillAnimationSpin);
|
||||
}
|
||||
|
||||
private void PlayIdle()
|
||||
{
|
||||
fxDrill.SetActive(false);
|
||||
PlayDrillAnimationLoop(_drillAnimationIdle);
|
||||
}
|
||||
|
||||
private async Task PlayDrillAnimationReady(string animationName, double duration = 0)
|
||||
{
|
||||
if (aniDrill == null)
|
||||
return;
|
||||
var animationEntry = aniDrill.AnimationState.SetAnimation(0, animationName, false);
|
||||
if (duration == 0)
|
||||
duration = animationEntry.Animation.Duration;
|
||||
await Task.Delay(TimeSpan.FromSeconds(duration));
|
||||
}
|
||||
|
||||
private void PlayDrillAnimationLoop(string animationName)
|
||||
{
|
||||
try
|
||||
{
|
||||
var animationEntry = aniDrill.AnimationState.SetAnimation(0,animationName, true);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Debug.Log($"[EventBreak] Play Spine Animation Error: {e.Message}\n{e.StackTrace}");
|
||||
}
|
||||
}
|
||||
|
||||
override public async void PlayEnter(Vector3 startPos)
|
||||
{
|
||||
try
|
||||
{
|
||||
var endPos = _originalPos;
|
||||
PlayIdle();
|
||||
transform.position = startPos;
|
||||
await Awaiters.NextFrame;
|
||||
gameObject.SetActive(true);
|
||||
transform.DOMove(endPos, _jiandaDrillResetDuration);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Debug.Log($"[EventBreak]{e.Message}\n{e.StackTrace}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override public Tween GetDrillTween(Vector3 endPos, float duration = 0.5f)
|
||||
{
|
||||
transform.position = _originalPos;
|
||||
return transform.DOMove(endPos, duration).SetEase(Ease.InSine);
|
||||
}
|
||||
|
||||
override public float Y => transform.position.y;
|
||||
|
||||
}
|
||||
|
||||
public abstract class EventBreakDrillDisplay : MonoBehaviour
|
||||
{
|
||||
abstract public void PlayEnter(Vector3 startPos);
|
||||
abstract public void PlayDrill(float readyDuration = 0);
|
||||
abstract public Tween GetDrillTween(Vector3 endPos, float duration);
|
||||
abstract public float Y {get;}
|
||||
abstract public void Init(int tunnelIndex);
|
||||
}
|
||||
11
Assets/Scripts/EventBreak/EventBreakDrill.cs.meta
Normal file
11
Assets/Scripts/EventBreak/EventBreakDrill.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6826cbbb416d751408b86f8a9ae31587
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
98
Assets/Scripts/EventBreak/EventBreakEntranceButton.cs
Normal file
98
Assets/Scripts/EventBreak/EventBreakEntranceButton.cs
Normal file
@@ -0,0 +1,98 @@
|
||||
using asap.core;
|
||||
using game;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using System;
|
||||
using GameCore;
|
||||
using UniRx;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class EventBreakEntranceButton : EventButtonResource
|
||||
{
|
||||
[SerializeField] private Image icon;
|
||||
[SerializeField] private TMP_Text textTimer;
|
||||
[SerializeField] private Button button;
|
||||
private ILoadResourceService _loadResourceService;
|
||||
private EventBreakEntranceData _btnData;
|
||||
private const string EntranceRedPointKey = "eventbreak.enter";
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (EventBreakAct.Ctx == null)
|
||||
{
|
||||
gameObject.SetActive(false);
|
||||
return;
|
||||
}
|
||||
_btnData = EventBreakAct.Ctx.GetEntranceButtonData();
|
||||
var _drillModel = GContext.container.Resolve<DrillModel>();
|
||||
if (_btnData == null || !_btnData.IsActive)
|
||||
{
|
||||
gameObject.SetActive(false);
|
||||
return;
|
||||
}
|
||||
UpdateTimer();
|
||||
Observable.Interval(TimeSpan.FromSeconds(1f)).Subscribe(UpdateTimer).AddTo(this);
|
||||
var chainPackData = GContext.container.Resolve<DrillModel>().ToChainPackData();
|
||||
RedPointManager.Instance.SetRedPointState(EntranceRedPointKey,
|
||||
_drillModel.TicketCount >= _btnData.RedPointTicketThreshold
|
||||
|| chainPackData.DoNeedPackRedPoint);
|
||||
CheckResource(new List<string>() { UITypes.EventBreakPanel.Path, EventBreakAct.ActAddressable, _btnData.BtnIconUrl });
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
button.onClick.AddListener(EnterDrillActAsync);
|
||||
_loadResourceService = GContext.container.Resolve<ILoadResourceService>();
|
||||
}
|
||||
|
||||
private async void EnterDrillActAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
bool isReady = await _loadResourceService.Loads(
|
||||
new List<string>() { UITypes.EventBreakPanel.Path, EventBreakAct.ActAddressable });
|
||||
if (isReady)
|
||||
{
|
||||
// Debug.Log($"<color=#22a6f2>[EventBreak] Download Ready!</color>");
|
||||
GContext.Publish(new UnloadActToNextAct { actId = EventBreakAct.ActAddressable, TransitionPanel = UITypes.CloudTransitionPanel });
|
||||
}
|
||||
else
|
||||
{
|
||||
// Debug.Log($"<color=#22a6f2>[EventBreak] Download Not Ready!</color>");
|
||||
var panel = await UIManager.Instance.ShowUI(UITypes.CloudTransitionPanel);
|
||||
panel.GetComponent<CloudTransitionPanel>().SetBtn(true, () => GContext.Publish(new UnloadActToNextAct(EventBreakAct.ActAddressable)));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Log($"<color=#22a6f2>[EventBreak] EnterActError: {e.Message}\n{e.StackTrace}</color>");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateTimer(long _ = 0L)
|
||||
{
|
||||
textTimer.text = ConvertTools.ConvertTime2(_btnData.RemainingTime);
|
||||
if (!_btnData.IsActive)
|
||||
Destroy(gameObject);
|
||||
}
|
||||
|
||||
protected override void OnLoadEventResource()
|
||||
{
|
||||
if (_btnData.IsActive)
|
||||
{
|
||||
GContext.container.Resolve<IUIService>().SetImageSprite(icon, _btnData.BtnIconUrl);
|
||||
gameObject.SetActive(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
public class EventBreakEntranceData
|
||||
{
|
||||
public string BtnIconUrl { get; set; }
|
||||
public DateTime ExpiryTime { get; set; }
|
||||
public DateTime StartTime { get; set; }
|
||||
public TimeSpan RemainingTime => ExpiryTime - ZZTimeHelper.UtcNow();
|
||||
public bool IsActive => ZZTimeHelper.UtcNow() >= StartTime && ZZTimeHelper.UtcNow() < ExpiryTime;
|
||||
public int RedPointTicketThreshold { get; set; }
|
||||
}
|
||||
11
Assets/Scripts/EventBreak/EventBreakEntranceButton.cs.meta
Normal file
11
Assets/Scripts/EventBreak/EventBreakEntranceButton.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ae2e3ca7ea04b694bbbca268da65e924
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
78
Assets/Scripts/EventBreak/EventBreakNormalPackPanel.cs
Normal file
78
Assets/Scripts/EventBreak/EventBreakNormalPackPanel.cs
Normal file
@@ -0,0 +1,78 @@
|
||||
using System;
|
||||
using asap.core;
|
||||
using cfg;
|
||||
using GameCore;
|
||||
using UnityEngine;
|
||||
using TMPro;
|
||||
using UnityEngine.UI;
|
||||
using UniRx;
|
||||
|
||||
public class EventBreakNormalPackPanel : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
private TMP_Text textTimer, textPriceLeft, textPriceRight, textCountLeft, textCountRight, textDiscount;
|
||||
[SerializeField] private Button btnClose, btnBuyLeft, btnBuyRight;
|
||||
private IAPItemList _iapLeft, _iapRight;
|
||||
private PlayerItemData _playerItemData;
|
||||
private DateTime _expireTime;
|
||||
private TimeSpan RemainingTime => _expireTime - ZZTimeHelper.UtcNow();
|
||||
private int _eventId;
|
||||
private Pack _packLeft, _packRight;
|
||||
|
||||
public void Init(EventBreakNormalPackInfo info)
|
||||
{
|
||||
btnClose.onClick.AddListener(OnClickClose);
|
||||
_eventId = info.EventId;
|
||||
_packLeft = info.PackLeft;
|
||||
_packRight = info.PackRight;
|
||||
_expireTime = info.ExpireTime;
|
||||
_playerItemData = GContext.container.Resolve<PlayerItemData>();
|
||||
textTimer.text = ConvertTools.ConvertTime2(RemainingTime);
|
||||
Observable.Interval(TimeSpan.FromSeconds(1.0f)).Subscribe(_ =>
|
||||
{
|
||||
textTimer.text = ConvertTools.ConvertTime2(RemainingTime);
|
||||
if (RemainingTime.TotalSeconds <= 0) OnClickClose();
|
||||
}).AddTo(this);
|
||||
_playerItemData.ResolveIapId(_packLeft.IAPID, out _iapLeft, textPriceLeft);
|
||||
_playerItemData.ResolveIapId(_packRight.IAPID, out _iapRight, textPriceRight);
|
||||
btnBuyLeft.onClick.AddListener(() => _ = OnClickBuy(_packLeft.DropID, _iapLeft));
|
||||
btnBuyRight.onClick.AddListener(() => _ = OnClickBuy(_packRight.DropID, _iapRight));
|
||||
textCountLeft.text =
|
||||
((int)_playerItemData.GetItemDataByDropId(_packLeft.DropID)[0].count).ToString();
|
||||
textCountRight.text =
|
||||
((int)_playerItemData.GetItemDataByDropId(_packRight.DropID)[0].count).ToString();
|
||||
textDiscount.text = LocalizationMgr.GetFormatTextValue("UI_FishingShopPanel_2", GetDiscountNumber());
|
||||
}
|
||||
|
||||
private int GetDiscountNumber()
|
||||
{
|
||||
float discount = _packRight.Rebate * 100;
|
||||
return (int)discount;
|
||||
}
|
||||
|
||||
private async System.Threading.Tasks.Task OnClickBuy(int dropId, IAPItemList iapItemList)
|
||||
{
|
||||
if (RemainingTime.TotalSeconds <= 0)
|
||||
return;
|
||||
bool res = await GContext.container.Resolve<PlayerShopData>().OnBuy(dropId,
|
||||
new ShopBuyTypeData { type = ShopBuyType.EventPack, ID = _eventId }, iapItemList,
|
||||
_playerItemData.GetItemDataByDropId(dropId));
|
||||
if (res)
|
||||
{
|
||||
EventBreakAct.EventAggregator.Publish(new EventTicketUpdate());
|
||||
OnClickClose();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnClickClose()
|
||||
{
|
||||
// RedPointManager.Instance.SetRedPointState(EventShootingRangeData.PackRedPointId, false);
|
||||
UIManager.Instance.DestroyUI(gameObject.name);
|
||||
}
|
||||
}
|
||||
public class EventBreakNormalPackInfo
|
||||
{
|
||||
public int EventId;
|
||||
public Pack PackLeft, PackRight;
|
||||
public DateTime ExpireTime;
|
||||
}
|
||||
11
Assets/Scripts/EventBreak/EventBreakNormalPackPanel.cs.meta
Normal file
11
Assets/Scripts/EventBreak/EventBreakNormalPackPanel.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 905a69d90d6928341be231da1004f347
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
225
Assets/Scripts/EventBreak/EventBreakPanel.cs
Normal file
225
Assets/Scripts/EventBreak/EventBreakPanel.cs
Normal file
@@ -0,0 +1,225 @@
|
||||
using asap.core;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using game;
|
||||
using UniRx;
|
||||
using System;
|
||||
using GameCore;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections;
|
||||
|
||||
public class EventDrillPanel : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private TMP_Text textTimer, textTicketCount;
|
||||
[SerializeField] private Button btnClose, btnPack, btnInfo;
|
||||
[SerializeField] private EventBreakTunnelView[] tunnels;
|
||||
[SerializeField] private EventBreakTaskView[] tasks;
|
||||
[SerializeField] private float _jiandaBlockSpawnInterval = 0.1f, _jiandaBlockDropTime = 0.5f,_jiandaDrillReadyDuration = 0.5f,
|
||||
_jiandaDrillDuration = 0.8f, _jiandaTaskChangeDuration = 0.5f, _jiandaBarFlashDuration = 1f, _jiandaBlockDropHeight = 1680f,
|
||||
_jiandaRewardFlyDuration = 2f, _jiandaResetTunnelDelay = 3f, _jiandaButtonPressedDuration = 0.3f, _jiandaDrillDetectionRange = 50f,
|
||||
_jiandaBlockDropSfxDelay = 0.3f, _jiandaRewardShowDuration = 2.0f;
|
||||
[SerializeField] private GameObject rewardFly, clickMask;
|
||||
[SerializeField] private AnimationCurve _jiandaBlockEaseCurve;
|
||||
private Coroutine _unblockCoroutine = null;
|
||||
private int _blockCounter;
|
||||
private EventBreakEntranceData _btnData;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
btnClose.onClick.AddListener(OnClose);
|
||||
_btnData = EventBreakAct.Ctx.GetEntranceButtonData();
|
||||
UpdateTimer();
|
||||
Observable.Interval(TimeSpan.FromSeconds(1f)).Subscribe(UpdateTimer).AddTo(this);
|
||||
OnTicketCountChange();
|
||||
btnPack.onClick.AddListener(OnClickPack);
|
||||
btnInfo.onClick.AddListener(OnClickInfo);
|
||||
_blockCounter = 0;
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
var drillModel = GContext.container.Resolve<DrillModel>();
|
||||
GContext.container.Resolve<GuideDataCenter>().InspectTriggerGuide(gameObject.name);
|
||||
if (tunnels.Length != drillModel.DrillJobList.Length || tunnels.Length != tasks.Length)
|
||||
{
|
||||
Debug.LogError("[EventBreak]Tunnel count not match!");
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < tunnels.Length; i++)
|
||||
{
|
||||
var tunnelInfo = new EventBreakTunnelViewInitInfo{
|
||||
Job = drillModel.DrillJobList[i],
|
||||
SpawnInterval = _jiandaBlockSpawnInterval,
|
||||
DropDuration = _jiandaBlockDropTime,
|
||||
DrillDuration = _jiandaDrillDuration,
|
||||
DropHeight = _jiandaBlockDropHeight,
|
||||
Idx = i,
|
||||
EaseCurve = _jiandaBlockEaseCurve,
|
||||
DrillReadyDuration = _jiandaDrillReadyDuration,
|
||||
ResetTunnelDelay = _jiandaResetTunnelDelay,
|
||||
ButtonPressedDuration = _jiandaButtonPressedDuration,
|
||||
DrillDetectionRange = _jiandaDrillDetectionRange,
|
||||
BlockDropSfxDelay = _jiandaBlockDropSfxDelay
|
||||
};
|
||||
tunnels[i].Init(tunnelInfo);
|
||||
var taskInfo = drillModel.TaskInfoList[i];
|
||||
tasks[i].Init(taskInfo, _jiandaTaskChangeDuration, _jiandaBarFlashDuration, _jiandaRewardFlyDuration, rewardFly, _jiandaRewardShowDuration);
|
||||
}
|
||||
EventBreakAct.EventAggregator.GetEvent<EventTicketUpdate>()
|
||||
.Subscribe(OnTicketCountChange).AddTo(this);
|
||||
EventBreakAct.EventAggregator.GetEvent<EventBreakInsufficientTicket>()
|
||||
.Subscribe(_ => OnClickPack()).AddTo(this);
|
||||
EventBreakAct.EventAggregator.GetEvent<EventBreakBlockInput>()
|
||||
.Subscribe(HandleBlockEvent).AddTo(this);
|
||||
EventBreakAct.EventAggregator.GetEvent<EventBreakBlockBreak>()
|
||||
.Subscribe(_ => HandleBlockEvent(new EventBreakBlockInput(EEventBreakBlockInputOperation.Block))).AddTo(this);
|
||||
var chainPackData = drillModel.ToChainPackData();
|
||||
RedPointManager.Instance.SetRedPointState(chainPackData.RedPointKey, chainPackData.DoNeedPackRedPoint);
|
||||
}
|
||||
|
||||
private void OnClose()
|
||||
{
|
||||
GContext.Publish(new UnloadActToNextAct());
|
||||
}
|
||||
|
||||
private void OnTicketCountChange(EventTicketUpdate _ = null)
|
||||
{
|
||||
|
||||
var n = GContext.container.Resolve<DrillModel>().TicketCount;
|
||||
textTicketCount.text = n.ToString();
|
||||
var res = EventBreakAct.Ctx.IsTicketEnough(n);
|
||||
for (int i = 0; i < tunnels.Length; i++)
|
||||
tunnels[i].SetAvailabilityDisplay(res[i]);
|
||||
textTicketCount.color = res.All(r => !r)? Color.red : Color.white;
|
||||
}
|
||||
|
||||
private void UpdateTimer(long _ = 0L)
|
||||
{
|
||||
textTimer.text = ConvertTools.ConvertTime2(_btnData.RemainingTime);
|
||||
}
|
||||
|
||||
private async void OnClickPack()
|
||||
{
|
||||
try
|
||||
{
|
||||
PlayBtnPressedAnimation();
|
||||
GameObject go;
|
||||
var chainPackData = GContext.container.Resolve<DrillModel>().ToChainPackData();
|
||||
if (chainPackData.ChainProgress >= chainPackData.ChainListCount)
|
||||
{
|
||||
go = await UIManager.Instance.ShowUINotLoading(UITypes.EventBreakNormalPackPanel);
|
||||
var normalPanel = go.GetComponent<EventBreakNormalPackPanel>();
|
||||
normalPanel.Init(EventBreakAct.Ctx.GetNormalPackInfo());
|
||||
return;
|
||||
}
|
||||
go = await UIManager.Instance.ShowUINotLoading(UITypes.EventBreakChainPackPanel);
|
||||
var panel = go.GetComponent<ChainPackPanel>();
|
||||
panel.Init(chainPackData);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Log($"[EventBreak]Pack Error: {e.Message}\n{e.StackTrace}");
|
||||
}
|
||||
}
|
||||
|
||||
private async void PlayBtnPressedAnimation()
|
||||
{
|
||||
btnPack.GetComponent<Animator>().Play("Pressed");
|
||||
await Task.Delay(TimeSpan.FromSeconds(_jiandaButtonPressedDuration));
|
||||
btnPack.GetComponent<Animator>().Play("Normal");
|
||||
}
|
||||
|
||||
private async void OnClickInfo()
|
||||
{
|
||||
try
|
||||
{
|
||||
await UIManager.Instance.ShowUINotLoading(UITypes.EventBreakInfoPanel);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Log($"[EventBreak]{e.Message}\n{e.StackTrace}");
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleBlockEvent(EventBreakBlockInput e)
|
||||
{
|
||||
switch (e.BlockOperation)
|
||||
{
|
||||
case EEventBreakBlockInputOperation.Block:
|
||||
BlockInput();
|
||||
break;
|
||||
case EEventBreakBlockInputOperation.Unblock:
|
||||
UnblockInput();
|
||||
break;
|
||||
case EEventBreakBlockInputOperation.StrongUnblock:
|
||||
UnblockInputStrong();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void BlockInput()
|
||||
{
|
||||
_blockCounter++;
|
||||
clickMask.SetActive(true);
|
||||
StartUnblockCountDown();
|
||||
// Debug.Log($"[EventBreak]Block: {_blockCounter}");
|
||||
}
|
||||
|
||||
private void UnblockInput()
|
||||
{
|
||||
_blockCounter--;
|
||||
// Debug.Log($"[EventBreak]Unblock: {_blockCounter}");
|
||||
if (_blockCounter <= 0)
|
||||
{
|
||||
clickMask.SetActive(false);
|
||||
_blockCounter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void UnblockInputStrong()
|
||||
{
|
||||
_blockCounter = 0;
|
||||
clickMask.SetActive(false);
|
||||
// Debug.Log($"[EventBreak]Strong Unblock: {_blockCounter}");
|
||||
}
|
||||
|
||||
private void StartUnblockCountDown()
|
||||
{
|
||||
if (_unblockCoroutine != null)
|
||||
StopAllCoroutines();
|
||||
_unblockCoroutine = StartCoroutine(UnBlockCoroutine());
|
||||
}
|
||||
|
||||
private IEnumerator UnBlockCoroutine()
|
||||
{
|
||||
yield return new WaitForSeconds(5);
|
||||
clickMask.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
public class EventTicketUpdate
|
||||
{
|
||||
}
|
||||
|
||||
public class EventBreakInsufficientTicket
|
||||
{
|
||||
}
|
||||
|
||||
public class EventBreakBlockInput
|
||||
{
|
||||
public EEventBreakBlockInputOperation BlockOperation = EEventBreakBlockInputOperation.Block;
|
||||
public EventBreakBlockInput(EEventBreakBlockInputOperation bo)
|
||||
{
|
||||
BlockOperation = bo;
|
||||
}
|
||||
}
|
||||
public enum EEventBreakBlockInputOperation
|
||||
{
|
||||
Block,
|
||||
Unblock,
|
||||
StrongUnblock
|
||||
}
|
||||
11
Assets/Scripts/EventBreak/EventBreakPanel.cs.meta
Normal file
11
Assets/Scripts/EventBreak/EventBreakPanel.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 96ab51583c04bd845bb986accd7ccd7a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
75
Assets/Scripts/EventBreak/EventBreakStashButtonFxCtrl.cs
Normal file
75
Assets/Scripts/EventBreak/EventBreakStashButtonFxCtrl.cs
Normal file
@@ -0,0 +1,75 @@
|
||||
using UnityEngine;
|
||||
using UniRx;
|
||||
using System;
|
||||
using asap.core;
|
||||
using Game;
|
||||
using DG.Tweening;
|
||||
|
||||
public class EventBreakStashButtonFxCtrl : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private DeferredRewardStashButton rewardStashButton;
|
||||
[SerializeField] private GameObject rewardFly;
|
||||
[SerializeField] private float jiandaRewardShowDuration = 2.0f;
|
||||
private void Start()
|
||||
{
|
||||
EventBreakAct.EventAggregator.GetEvent<EventBreakBlockBreak>().Subscribe(OnBlockBreak).AddTo(this);
|
||||
}
|
||||
|
||||
private void OnBlockBreak(EventBreakBlockBreak e)
|
||||
{
|
||||
if (EventBreakAct.Ctx.IsItemGem(e.Item))
|
||||
return;
|
||||
MakeRewardFly(e);
|
||||
}
|
||||
private async void MakeRewardFly(EventBreakBlockBreak e)
|
||||
{
|
||||
try
|
||||
{
|
||||
var fly = Instantiate(rewardFly, transform).GetComponent<RewardItemNew>();
|
||||
fly.SetRewardPopupData(e.Item);
|
||||
fly.transform.position = e.BreakPos;
|
||||
fly.gameObject.SetActive(true);
|
||||
if (EventBreakAct.Ctx.IsItemFishCard(e.Item))
|
||||
{
|
||||
// Debug.Log($"[EventBreak] FishCard: From {rewardFly.transform.position} to {transform.position}");
|
||||
_ = PlayFishCardBundleAudio();
|
||||
fly.GetComponent<Animation>().Play("reward_common_open");
|
||||
await System.Threading.Tasks.Task.Delay(TimeSpan.FromSeconds(jiandaRewardShowDuration));
|
||||
fly.GetComponent<Animation>().Play("reward_common_close");
|
||||
await System.Threading.Tasks.Task.Delay(24 * 1000 / 60);
|
||||
fly.GetComponent<CanvasGroup>().alpha = 1;
|
||||
await Awaiters.NextFrame;
|
||||
await DOTween.To(() => fly.transform.position,
|
||||
value => fly.transform.position = value, transform.position, 1.1f)
|
||||
.AsyncWaitForCompletion();
|
||||
rewardStashButton.PlayReceiveAnimationWithDelay(0f);
|
||||
EventBreakAct.EventAggregator.Publish(new EventBreakBlockInput(EEventBreakBlockInputOperation.Unblock));
|
||||
Destroy(fly.gameObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
fly.GetComponent<Animation>().Play("reward_common_open");
|
||||
await System.Threading.Tasks.Task.Delay(TimeSpan.FromSeconds(jiandaRewardShowDuration));
|
||||
fly.GetComponent<Animation>().Play("reward_common_close");
|
||||
await System.Threading.Tasks.Task.Delay(16 * 1000 / 60);
|
||||
rewardStashButton.PlayReceiveAnimationWithDelay(1f);
|
||||
await Awaiters.NextFrame;
|
||||
await fly.ParticleAttractor();
|
||||
// await System.Threading.Tasks.Task.Delay(TimeSpan.FromSeconds(1.1f));
|
||||
EventBreakAct.EventAggregator.Publish(new EventBreakBlockInput(EEventBreakBlockInputOperation.Unblock));
|
||||
Destroy(fly.gameObject);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.Log($"[EventBreak] BreakBlockError: {ex.Message}\n{ex.StackTrace}");
|
||||
}
|
||||
}
|
||||
|
||||
private async System.Threading.Tasks.Task PlayFishCardBundleAudio()
|
||||
{
|
||||
GContext.Publish(new EventUISound("audio_ui_break_rewardfly"));
|
||||
await System.Threading.Tasks.Task.Delay(TimeSpan.FromSeconds(0.25f));
|
||||
GContext.Publish(new EventUISound("audio_ui_break_rewardget"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9ae501860857eba468577bb6fecac35b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
110
Assets/Scripts/EventBreak/EventBreakSystem.cs
Normal file
110
Assets/Scripts/EventBreak/EventBreakSystem.cs
Normal file
@@ -0,0 +1,110 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using asap.core;
|
||||
using GameCore;
|
||||
using UnityEngine;
|
||||
|
||||
public class DrillSystem
|
||||
{
|
||||
private readonly EventBreakTableContext _drillDataHub;
|
||||
private readonly PlayerItemData _playerItemData = GContext.container.Resolve<PlayerItemData>();
|
||||
private int _evTunnel, _evTicketConsume, _evGemGet, _evTaskId;
|
||||
private string _evReward;
|
||||
private Dictionary<int, int> _evNormalRewardDic;
|
||||
|
||||
public DrillSystem(EventBreakTableContext drillDataHub)
|
||||
{
|
||||
_drillDataHub = drillDataHub;
|
||||
}
|
||||
|
||||
public bool DoDrillJob(int jobIdx)
|
||||
{
|
||||
var _drillModel = GContext.container.Resolve<DrillModel>();
|
||||
var jobData = _drillModel.DrillJobList[jobIdx];
|
||||
if (!_drillModel.AddTicket(-jobData.Cost))
|
||||
{
|
||||
Debug.Log("[EventBreak] Insufficient ticket.");
|
||||
return false;
|
||||
}
|
||||
|
||||
_evTunnel = jobIdx + 1;
|
||||
_evTicketConsume = jobData.Cost;
|
||||
_evGemGet = 0;
|
||||
_evNormalRewardDic = new Dictionary<int, int>();
|
||||
_evReward = "";
|
||||
_evTaskId = 0;
|
||||
|
||||
ProcessBlocks(ref _drillModel.TaskInfoList[jobIdx], jobData.Blocks);
|
||||
|
||||
/*
|
||||
Debug.Log($"[EventBreak]<color=#fe231b>Event tracking:</color>");
|
||||
Debug.Log($"[EventBreak]<color=#fe231b> tunnel: {_evTunnel}</color>");
|
||||
Debug.Log($"[EventBreak]<color=#fe231b> item_consume: {_evTicketConsume}</color>");
|
||||
Debug.Log($"[EventBreak]<color=#fe231b> gem_count: {_evGemGet}</color>");
|
||||
Debug.Log($"[EventBreak]<color=#fe231b> reward_normal: {_evReward}</color>");
|
||||
Debug.Log($"[EventBreak]<color=#fe231b> milestone_task: {_evTaskId}</color>");
|
||||
*/
|
||||
#if AGG
|
||||
using (var e = GEvent.GameEvent("event_drill"))
|
||||
{
|
||||
e.AddContent("tunnel", _evTunnel)
|
||||
.AddContent("item_consume", _evTicketConsume)
|
||||
.AddContent("gem_count", _evGemGet)
|
||||
.AddContent("reward_normal", _evReward)
|
||||
.AddContent("milestone_task", _evTaskId);
|
||||
}
|
||||
#endif
|
||||
_drillModel.UpdateSeed(jobIdx);
|
||||
_drillModel.DrillJobList[jobIdx] = _drillDataHub.GetDrillJob(jobIdx, _drillModel.DrillJobSeeds[jobIdx]);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void ProcessBlocks(ref EventBreakTaskInfo taskInfo, IEnumerable<DrillBlockData> blocks)
|
||||
{
|
||||
var _drillModel = GContext.container.Resolve<DrillModel>();
|
||||
foreach (var block in blocks)
|
||||
{
|
||||
if (block.IsEmpty)
|
||||
continue;
|
||||
if (block.Item.id != taskInfo.TargetItemId)
|
||||
{
|
||||
GrantPlayerReward(block.Item);
|
||||
if (!_evNormalRewardDic.TryAdd(block.Item.id, (int) block.Item.count))
|
||||
_evNormalRewardDic[block.Item.id] += (int) block.Item.count;
|
||||
continue;
|
||||
}
|
||||
taskInfo.CurrentGemProgress += (int)block.Item.count;
|
||||
_evGemGet++;
|
||||
if (taskInfo.CurrentGemProgress < taskInfo.TotalGemRequired)
|
||||
continue;
|
||||
GrantPlayerReward(taskInfo.Reward);
|
||||
_evTaskId = taskInfo.TaskId;
|
||||
taskInfo = _drillDataHub.GetNextTaskInfo(taskInfo);
|
||||
}
|
||||
_evReward = SerializeRewardDic(_evNormalRewardDic);
|
||||
_drillModel.ToPlayfabData().Save();
|
||||
}
|
||||
|
||||
private string SerializeRewardDic(Dictionary<int, int> d)
|
||||
{
|
||||
var res = new StringBuilder();
|
||||
if (d == null || d.Count <= 0)
|
||||
return "";
|
||||
foreach (var kv in d)
|
||||
{
|
||||
res.Append("(");
|
||||
res.Append(kv.Key);
|
||||
res.Append(",");
|
||||
res.Append(kv.Value);
|
||||
res.Append("),");
|
||||
}
|
||||
return res.ToString();
|
||||
}
|
||||
|
||||
public void GrantPlayerReward(ItemData item)
|
||||
{
|
||||
// Debug.Log($"[Drill] Add rewards: id {item.id} count {item.count}");
|
||||
// _playerItemData.AddItem(item);
|
||||
GContext.Publish(new DeferredRewardStashService.EventStashItem {Item = item});
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/EventBreak/EventBreakSystem.cs.meta
Normal file
11
Assets/Scripts/EventBreak/EventBreakSystem.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8b34217bbd36cf44c86b9707f3fb56e7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
420
Assets/Scripts/EventBreak/EventBreakTableContext.cs
Normal file
420
Assets/Scripts/EventBreak/EventBreakTableContext.cs
Normal file
@@ -0,0 +1,420 @@
|
||||
using cfg;
|
||||
using asap.core;
|
||||
using GameCore;
|
||||
using SystemRandom = System.Random;
|
||||
using UnityEngine;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.Assertions;
|
||||
using System;
|
||||
using Castle.Core.Internal;
|
||||
|
||||
public class EventBreakTableContext
|
||||
{
|
||||
#region Private Table References
|
||||
private readonly EventDrillMain _tableMain;
|
||||
private readonly EventDrillTunnel[] _tableTunnels;
|
||||
private readonly TbEventDrillReward _tableTask;
|
||||
private readonly FishingEvent _tableEvent;
|
||||
private readonly FishingEventCycleItem2 _tableCycle;
|
||||
private readonly Tables _tables = GContext.container.Resolve<Tables>();
|
||||
#endregion
|
||||
public int TunnelCount => _tableTunnels.Length;
|
||||
private readonly PlayerItemData _playerItemData = GContext.container.Resolve<PlayerItemData>();
|
||||
public SystemRandom Random;
|
||||
public readonly int BlockCountPerTunnel = 8;
|
||||
|
||||
private EventBreakTableContext(EventDrillMain tableMain, EventDrillTunnel[] tableTunnels, TbEventDrillReward tableTask, FishingEvent tableEvent, FishingEventCycleItem2 tableCycle, Tables tables)
|
||||
{
|
||||
_tableMain = tableMain;
|
||||
_tableTunnels = tableTunnels;
|
||||
_tableTask = tableTask;
|
||||
_tableEvent = tableEvent;
|
||||
_tableCycle = tableCycle;
|
||||
_tables = tables;
|
||||
}
|
||||
|
||||
public static EventBreakTableContext ReadTables(int eventId, Tables tables)
|
||||
{
|
||||
int redirectId, cycleId;
|
||||
cycleId = tables.TbFishingEvent[eventId].RedirectID;
|
||||
redirectId = tables.TbFishingEventCycleItem2[cycleId].RedirectID;
|
||||
var tableEvent = tables.TbFishingEvent[eventId];
|
||||
var tableCycle = tables.TbFishingEventCycleItem2[cycleId];
|
||||
var tableMain = tables.TbEventDrillMain[redirectId];
|
||||
var tableTunnels = tables.TbEventDrillTunnel.DataList.Where(t => tableMain.TunnelList.Contains(t.Tunnel)).ToArray();
|
||||
var tableTask = tables.TbEventDrillReward;
|
||||
return new EventBreakTableContext(tableMain, tableTunnels, tableTask, tableEvent, tableCycle, tables);
|
||||
}
|
||||
|
||||
#region TaskInfoProcess
|
||||
|
||||
public EventBreakTaskInfo GetTaskInfo(int taskId, int tunnelIdx, int gemProgress = 0)
|
||||
{
|
||||
if (!_tableTask.DataMap.TryGetValue(taskId, out var taskTableData))
|
||||
{
|
||||
Debug.Log($"[EventBreak]Task id {taskId} not found in table.");
|
||||
return null;
|
||||
}
|
||||
int targetItemId = GetItemIdFromDrop(_tableTunnels[tunnelIdx].DropGem);
|
||||
if (targetItemId == -1)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
// var taskReward = GetBlockDataFromDropId(_tableTask[taskId].DropGem);
|
||||
var taskReward = _playerItemData.GetItemDataByDropId(_tableTask[taskId].DropGem)[0];
|
||||
return new EventBreakTaskInfo
|
||||
{
|
||||
TaskId = taskTableData.TaskID,
|
||||
TargetItemId = targetItemId,
|
||||
Reward = taskReward,
|
||||
TotalGemRequired = _tableTask[taskId].TokenRequired,
|
||||
CurrentGemProgress = gemProgress
|
||||
};
|
||||
}
|
||||
|
||||
public EventBreakTaskInfo GetNextTaskInfo(EventBreakTaskInfo taskInfo)
|
||||
{
|
||||
Assert.IsTrue(taskInfo.CurrentGemProgress >= taskInfo.TotalGemRequired, "[EventBreak]Current gem progress is less than total gem required.");
|
||||
var dataFlag = _tables.TbEventDrillReward.DataMap.TryGetValue(taskInfo.TaskId, out var taskTableData);
|
||||
if (!dataFlag)
|
||||
{
|
||||
Debug.Log($"[Drill]Task id {taskInfo.TaskId} not found in reward table.");
|
||||
return null;
|
||||
}
|
||||
var nextTaskId = taskTableData.NextTarget;
|
||||
dataFlag = _tables.TbEventDrillReward.DataMap.TryGetValue(nextTaskId, out var nextTaskTableData);
|
||||
if (!dataFlag)
|
||||
{
|
||||
Debug.Log($"[Drill]Next task id {nextTaskId} not found in reward table, end of mission chain.");
|
||||
return null;
|
||||
}
|
||||
// var taskReward = GetBlockDataFromDropId(nextTaskTableData.DropGem);
|
||||
var taskReward = _playerItemData.GetItemDataByDropId(nextTaskTableData.DropGem)[0];
|
||||
return new EventBreakTaskInfo
|
||||
{
|
||||
TaskId = nextTaskId,
|
||||
TargetItemId = taskInfo.TargetItemId,
|
||||
Reward = taskReward,
|
||||
TotalGemRequired = nextTaskTableData.TokenRequired,
|
||||
CurrentGemProgress = taskInfo.CurrentGemProgress - taskInfo.TotalGemRequired
|
||||
};
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void GetFreshNewModelData(int[] jobSeeds, out int welcomeGift, out DrillJobModel[] drillJobs, out EventBreakTaskInfo[] taskInfoList)
|
||||
{
|
||||
welcomeGift = _tableCycle.WelcomeGift;
|
||||
drillJobs = new DrillJobModel[TunnelCount];
|
||||
taskInfoList = new EventBreakTaskInfo[TunnelCount];
|
||||
var defaultTaskIds = _tableTunnels.Select(t => t.TaskList).ToArray();
|
||||
for (int i = 0; i < TunnelCount; i++)
|
||||
{
|
||||
drillJobs[i] = GetDrillJob(i, jobSeeds[i]);
|
||||
taskInfoList[i] = GetTaskInfo(_tableTunnels[i].TaskList, i);
|
||||
}
|
||||
}
|
||||
|
||||
public int GetEntranceRedDotTicketThreshold()
|
||||
{
|
||||
return _tableCycle.RedDot;
|
||||
}
|
||||
|
||||
public DrillJobModel[] GetDrillJobModels(int[] seeds)
|
||||
{
|
||||
var res = new DrillJobModel[seeds.Length];
|
||||
for (int i = 0; i < seeds.Length; i++)
|
||||
res[i] = GetDrillJob(i, seeds[i]);
|
||||
return res;
|
||||
}
|
||||
|
||||
public EventBreakTaskInfo[] GetTaskInfoArray((int id, int progress)[] taskData)
|
||||
{
|
||||
var res = new EventBreakTaskInfo[taskData.Length];
|
||||
for (int i = 0; i < taskData.Length; i++)
|
||||
{
|
||||
// Debug.Log($"[EventBreak]Task init: id {taskData[i].id}, progress {taskData[i].progress}");
|
||||
res[i] = GetTaskInfo(taskData[i].id, i, taskData[i].progress);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get DrillJob. Before calling this, do save the seed if necessarry.
|
||||
/// </summary>
|
||||
/// <param name="idx">In which tunnel</param>
|
||||
/// <param name="seed">By what rng seed. If seed is less than table threshold, fallback into initial fixed drops.</param>
|
||||
/// <returns>The drill job</returns>
|
||||
public DrillJobModel GetDrillJob(int idx, int seed)
|
||||
{
|
||||
var tunnelData = _tableTunnels[idx];
|
||||
var res = new DrillJobModel
|
||||
{
|
||||
Cost = tunnelData.ItemRequired,
|
||||
};
|
||||
var rewardBlockDatas = new List<DrillBlockData>();
|
||||
var blockDatas = new List<DrillBlockData>();
|
||||
for (int i = 0; i < BlockCountPerTunnel; i++)
|
||||
blockDatas.Add(DrillBlockData.CreateEmpty());
|
||||
SystemRandom rng;
|
||||
var gemId = GetItemIdFromDrop(tunnelData.DropGem);
|
||||
if (IsSeedFixed(idx, seed))
|
||||
{
|
||||
rng = new SystemRandom(seed + idx);
|
||||
var dropId = tunnelData.FixDropId[seed];
|
||||
var items = _playerItemData.GetItemDataByDropId(dropId);
|
||||
foreach (var item in items)
|
||||
{
|
||||
if (item.id == gemId)
|
||||
{
|
||||
int n = (int)item.count;
|
||||
while (n > 0)
|
||||
{
|
||||
rewardBlockDatas.Add(new DrillBlockData { Item = new ItemData(item.id, 1) });
|
||||
n--;
|
||||
}
|
||||
}
|
||||
else
|
||||
rewardBlockDatas.Add(new DrillBlockData { Item = item });
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rng = new SystemRandom(seed);
|
||||
Assert.IsTrue(idx >= 0 && idx < _tableTunnels.Length, $"Tunnel Index {idx} not within range [0, {_tableTunnels.Length - 1}].");
|
||||
var dropIds = GetTunnelDropIds(_tableTunnels[idx], rng);
|
||||
Assert.IsTrue(dropIds.Count <= BlockCountPerTunnel, "[EventBreak]Reward count is greater than block count");
|
||||
foreach (var dropId in dropIds)
|
||||
rewardBlockDatas.AddRange(GetBlockDataFromDropId(dropId, rng, gemId));
|
||||
}
|
||||
var itemCount = rewardBlockDatas.Count;
|
||||
// int i = itemCount;
|
||||
// while (i < BlockCountPerTunnel)
|
||||
// {
|
||||
// blockDatas.Add(DrillBlockData.CreateEmpty());
|
||||
// i++;
|
||||
// }
|
||||
rewardBlockDatas = rewardBlockDatas.OrderBy(x => rng.Next()).ToList();
|
||||
if (rewardBlockDatas.IsNullOrEmpty())
|
||||
{
|
||||
Debug.LogError($"[EventBreak] No reward found in tunnel {idx}");
|
||||
res.Blocks = blockDatas.ToArray();
|
||||
return res;
|
||||
}
|
||||
var indicesToPick = Enumerable.Range(0, BlockCountPerTunnel).ToList();
|
||||
int idxPicked = rng.Next(0, BlockCountPerTunnel);
|
||||
blockDatas[idxPicked] = rewardBlockDatas[0];
|
||||
indicesToPick.Remove(idxPicked);
|
||||
indicesToPick.Remove(idxPicked + 1);
|
||||
indicesToPick.Remove(idxPicked - 1);
|
||||
for (int i = 1; i < rewardBlockDatas.Count; i++)
|
||||
{
|
||||
idxPicked = indicesToPick[rng.Next(0, indicesToPick.Count)];
|
||||
blockDatas[idxPicked] = rewardBlockDatas[i];
|
||||
indicesToPick.Remove(idxPicked);
|
||||
}
|
||||
res.Blocks = blockDatas.ToArray();
|
||||
return res;
|
||||
}
|
||||
|
||||
public bool IsSeedFixed(int idx, int seed)
|
||||
{
|
||||
return seed >= 0 && seed < _tableTunnels[idx].FixDropId.Count;
|
||||
}
|
||||
|
||||
public bool DoesSeedNeedInc(int idx, int seed)
|
||||
{
|
||||
return seed >= 0 && seed < _tableTunnels[idx].FixDropId.Count - 1;
|
||||
}
|
||||
|
||||
private List<ItemData> GetInitTunnelDropIds(EventDrillTunnel tunnel, int fixedDropIdx)
|
||||
{
|
||||
if (fixedDropIdx < 0 || fixedDropIdx >= tunnel.FixDropId.Count)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return _playerItemData.GetItemDataByDropId(tunnel.FixDropId[fixedDropIdx]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the drop ids for the tunnel. First drop is the the gem of the tunnel.
|
||||
/// </summary>
|
||||
/// <param name="tunnel">tunnel data from table</param>
|
||||
/// <returns>The dropIds for the tunnel.</returns>
|
||||
private List<int> GetTunnelDropIds(EventDrillTunnel tunnel, SystemRandom rng)
|
||||
{
|
||||
var dropIds = new List<int>();
|
||||
dropIds.Add(tunnel.DropGem);
|
||||
var count = tunnel.DropCountList[FtMathUtils.GetRandomIdxFromWeightList(tunnel.DropWeightList, rng)];
|
||||
while (count > 0)
|
||||
{
|
||||
dropIds.Add(tunnel.DropItemId);
|
||||
count--;
|
||||
}
|
||||
return dropIds;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assuming that Random state is set before calling. Will seperate gem.
|
||||
/// </summary>
|
||||
/// <param name="dropId">The drop id that represents a weighted random item.</param>
|
||||
/// <returns>The actual item id and count.</returns>
|
||||
private DrillBlockData[] GetBlockDataFromDropId(int dropId, SystemRandom rng, int gemId)
|
||||
{
|
||||
ItemData item;
|
||||
var res = new List<DrillBlockData>();
|
||||
if (!_tables.TbDrop.DataMap.TryGetValue(dropId, out var drop))
|
||||
{
|
||||
Debug.Log($"[EventBreak]Drop id {dropId} not found.");
|
||||
return res.ToArray();
|
||||
}
|
||||
if (drop.Type != DropType.Weight)
|
||||
{
|
||||
Debug.Log($"[EventBreak]Unsupported drop type {drop.Type} from drop Id {dropId}.");
|
||||
return res.ToArray();
|
||||
}
|
||||
if (rng == null)
|
||||
{
|
||||
Debug.Log($"[EventBreak]Need random number generator for this drop type.");
|
||||
return res.ToArray();
|
||||
}
|
||||
try
|
||||
{
|
||||
var idx = FtMathUtils.GetRandomIdxFromWeightList(drop.DropList.DropProbList, rng);
|
||||
item = new ItemData(drop.DropList.DropIDList[idx], drop.DropList.DropCountList[idx]);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"[EventBreak]Invalid drop id {drop}: {e.Message}\n{e.StackTrace}");
|
||||
return res.ToArray();
|
||||
}
|
||||
_playerItemData.ItemTransition(item);
|
||||
if (item.id == gemId)
|
||||
for (int i = 0; i < (int)item.count; i++)
|
||||
res.Add(new DrillBlockData { Item = new ItemData(id: gemId, count: 1) });
|
||||
else
|
||||
res.Add(new DrillBlockData { Item = item });
|
||||
return res.ToArray();
|
||||
}
|
||||
|
||||
private int GetItemIdFromDrop(int dropId)
|
||||
{
|
||||
if (!_tables.TbDrop.DataMap.TryGetValue(dropId, out var drop))
|
||||
{
|
||||
Debug.Log($"[EventBreak]Drop id {dropId} not found.");
|
||||
return -1;
|
||||
}
|
||||
return drop.DropList.DropIDList[0];
|
||||
}
|
||||
|
||||
public EventBreakEntranceData GetEntranceButtonData()
|
||||
{
|
||||
var res = new EventBreakEntranceData();
|
||||
res.BtnIconUrl = _tableMain.Icon;
|
||||
res.RedPointTicketThreshold = _tableCycle.RedDot;
|
||||
var et = new DateTime();
|
||||
var st = new DateTime();
|
||||
try
|
||||
{
|
||||
et = DateTime.Parse((_tableEvent.TimeDefinition as LimitedTime).EndTime);
|
||||
st = DateTime.Parse((_tableEvent.TimeDefinition as LimitedTime).StartTime);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Log($"[EventBreak] {e.Message}\n{e.StackTrace}");
|
||||
return null;
|
||||
}
|
||||
finally
|
||||
{
|
||||
res.ExpiryTime = et;
|
||||
res.StartTime = st;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public EventBreakUIData GetUIData()
|
||||
{
|
||||
return new EventBreakUIData
|
||||
{
|
||||
MainPanelUrl = _tableMain.UIPanel,
|
||||
InfoPanelUrl = _tableMain.InfoPanel,
|
||||
ChainPackPanelUrl = _tableMain.ChainPackPanel,
|
||||
NormalPackPanelUrl = _tableMain.PackPanel,
|
||||
RewardPanelUrl = _tableMain.RewardPanel
|
||||
};
|
||||
}
|
||||
|
||||
public EventChainPackInfo GetPackData()
|
||||
{
|
||||
var chianList = _tables.TbEventPackManager[_tableMain.PackId].VIPPackList[0];
|
||||
var expireTime = new DateTime();
|
||||
try
|
||||
{
|
||||
expireTime = DateTime.Parse((_tableEvent.TimeDefinition as LimitedTime).EndTime);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Log($"[EventBreak] {e.Message}\n{e.StackTrace}");
|
||||
return null;
|
||||
}
|
||||
var chainListIdSet = chianList.ToHashSet();
|
||||
var packs = _tables.TbPack.DataList.Where(p => chainListIdSet.Contains(p.ID)).ToArray();//?
|
||||
return new EventChainPackInfo()
|
||||
{
|
||||
ChainList = chianList,
|
||||
ExpireTime = expireTime,
|
||||
Packs = packs,
|
||||
RedPointKey = "eventbreak.pack"
|
||||
};
|
||||
}
|
||||
|
||||
public bool[] IsTicketEnough(int ticketCount)
|
||||
{
|
||||
return _tableTunnels.Select(t => ticketCount >= t.ItemRequired).ToArray();
|
||||
}
|
||||
|
||||
public bool IsItemGem(ItemData item)
|
||||
{
|
||||
return _tableTunnels.Any(t => GetItemIdFromDrop(t.DropGem) == item.id);
|
||||
}
|
||||
|
||||
public int GetGemIdx(int gemId)
|
||||
{
|
||||
int idx = 0;
|
||||
while (idx < _tableTunnels.Length)
|
||||
{
|
||||
if (GetItemIdFromDrop(_tableTunnels[idx].DropGem) == gemId)
|
||||
return idx;
|
||||
idx++;
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
public EventBreakNormalPackInfo GetNormalPackInfo()
|
||||
{
|
||||
var expireTime = new DateTime();
|
||||
try
|
||||
{
|
||||
expireTime = DateTime.Parse((_tableEvent.TimeDefinition as LimitedTime).EndTime);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Log($"[EventBreak] {e.Message}\n{e.StackTrace}");
|
||||
return null;
|
||||
}
|
||||
var packList = _tables.TbEventPackManager[_tableMain.PackId2].VIPPackList[0];
|
||||
return new EventBreakNormalPackInfo
|
||||
{
|
||||
EventId = _tableEvent.ID,
|
||||
PackLeft = _tables.TbPack[packList[0]],
|
||||
PackRight = _tables.TbPack[packList[1]],
|
||||
ExpireTime = expireTime,
|
||||
};
|
||||
}
|
||||
|
||||
public bool IsItemFishCard(ItemData item)
|
||||
{
|
||||
return _tables.TbItem[item.id].Type == 5;
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/EventBreak/EventBreakTableContext.cs.meta
Normal file
11
Assets/Scripts/EventBreak/EventBreakTableContext.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5a4bd40c59bedb24295904fe5250e695
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
40
Assets/Scripts/EventBreak/EventBreakTaskRewardPopupPanel.cs
Normal file
40
Assets/Scripts/EventBreak/EventBreakTaskRewardPopupPanel.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using GameCore;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class EventBreakTaskRewardPopupPanel : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private RewardItemNew reward;
|
||||
[SerializeField] private GameObject[] gemBanners;
|
||||
[SerializeField] private Button btnClaim;
|
||||
private Action _action;
|
||||
|
||||
public void Init(ItemData rewardItem, int tunnelIdx, Action claimMark = null)
|
||||
{
|
||||
// Debug.Log($"[EventBreak] Init!!!!!!!!!!", this);
|
||||
reward.SetData(rewardItem, abbr: true);
|
||||
for (int i = 0; i < gemBanners.Length; i++)
|
||||
gemBanners[i].SetActive(i == tunnelIdx);
|
||||
btnClaim.onClick.AddListener(OnClaim);
|
||||
_action = claimMark;
|
||||
}
|
||||
|
||||
private async void OnClaim()
|
||||
{
|
||||
try
|
||||
{
|
||||
// Debug.Log($"[EventBreak] Claim!!!!!!!!!!", this);
|
||||
btnClaim.onClick.RemoveAllListeners();
|
||||
_ = reward.ParticleAttractor();
|
||||
await System.Threading.Tasks.Task.Delay(TimeSpan.FromSeconds(1.2f));
|
||||
UIManager.Instance.DestroyUI(UITypes.EventBreakRewardPopupPanel);
|
||||
_action?.Invoke();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError(e);
|
||||
btnClaim.onClick.AddListener(OnClaim);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0af9cbdb7d76cfd4e99a73bff3544cba
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
178
Assets/Scripts/EventBreak/EventBreakTaskView.cs
Normal file
178
Assets/Scripts/EventBreak/EventBreakTaskView.cs
Normal file
@@ -0,0 +1,178 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using asap.core;
|
||||
using DG.Tweening;
|
||||
using GameCore;
|
||||
using TMPro;
|
||||
using UniRx;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class EventBreakTaskView : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private RewardItemNew reward;
|
||||
[SerializeField] private Image barProgress;
|
||||
[SerializeField] private TMP_Text textProgress;
|
||||
[SerializeField] private Transform rewardFlyTarget;
|
||||
[SerializeField] private GameObject fxGem, fxBar;
|
||||
[SerializeField] private Animation aniTask;
|
||||
private int _targetItemId, _taskId;
|
||||
private float _taskChangeDuration, _barFlashDuration, _rewardFlyDuration, _rewardShowDuration;
|
||||
private GameObject _rewardFly;
|
||||
private ItemData _rewardItemData;
|
||||
private bool _isUpdatingTaskDisplay = false;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
EventBreakAct.EventAggregator.GetEvent<EventBreakBlockBreak>().Subscribe(OnBlockBreak).AddTo(this);
|
||||
}
|
||||
|
||||
public void Init(EventBreakTaskInfo info, float taskChangeDuration, float barFlashDuration, float rewardFlyDuration, GameObject rewardFly, float rewardShowDuration)
|
||||
{
|
||||
reward.SetData(info.Reward, abbr: true);
|
||||
barProgress.fillAmount = (float)info.CurrentGemProgress / info.TotalGemRequired;
|
||||
textProgress.text = $"{info.CurrentGemProgress}/{info.TotalGemRequired}";
|
||||
_targetItemId = info.TargetItemId;
|
||||
// Debug.Log($"[EventBreak] target item id:{_targetItemId}", this);
|
||||
_taskId = info.TaskId;
|
||||
_taskChangeDuration = taskChangeDuration;
|
||||
_barFlashDuration = barFlashDuration;
|
||||
_rewardFly = rewardFly;
|
||||
_rewardItemData = info.Reward;
|
||||
_rewardFlyDuration = rewardFlyDuration;
|
||||
_rewardShowDuration = rewardShowDuration;
|
||||
}
|
||||
|
||||
private async void OnBlockBreak(EventBreakBlockBreak e)
|
||||
{
|
||||
try
|
||||
{
|
||||
var drillModel = GContext.container.Resolve<DrillModel>();
|
||||
if (e.Item.id != _targetItemId)
|
||||
return;
|
||||
await MakeRewardFly(e);
|
||||
var info = drillModel.TaskInfoList.First(i => i.TargetItemId == _targetItemId);
|
||||
UpdateDisplay(info);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.Log($"[EventBreak] BreakBlockError: {ex.Message}\n{ex.StackTrace}");
|
||||
}
|
||||
}
|
||||
|
||||
private async Task MakeRewardFly(EventBreakBlockBreak e)
|
||||
{
|
||||
try
|
||||
{
|
||||
var rewardFly = Instantiate(_rewardFly, transform.parent).GetComponent<RewardItemNew>();
|
||||
rewardFly.SetRewardPopupData(e.Item);
|
||||
rewardFly.transform.position = e.BreakPos;
|
||||
rewardFly.gameObject.SetActive(true);
|
||||
var t = rewardFly.transform.Find("fx_eventbreakdrill_reward_show");
|
||||
if (t != null)
|
||||
t.gameObject.SetActive(true);
|
||||
t = rewardFly.transform.Find("fx_eventbreakdrill_reward_fly");
|
||||
if (t != null)
|
||||
t.gameObject.SetActive(true);
|
||||
rewardFly.GetComponent<Animation>().Play("reward_common_open");
|
||||
await Task.Delay(TimeSpan.FromSeconds(_rewardShowDuration));
|
||||
rewardFly.GetComponent<Animation>().Play("reward_common_close");
|
||||
await Task.Delay(24 * 1000 / 60);
|
||||
rewardFly.GetComponent<CanvasGroup>().alpha = 1;
|
||||
rewardFly.text_num.gameObject.SetActive(false);
|
||||
rewardFly.transform.localScale = Vector3.one * 0.64f;
|
||||
await Awaiters.NextFrame;
|
||||
// _ = rewardFly.ParticleAttractor();
|
||||
await Task.Delay(TimeSpan.FromSeconds(_rewardFlyDuration));
|
||||
await rewardFly.transform.DOMove(rewardFlyTarget.position, _rewardFlyDuration).AsyncWaitForCompletion();
|
||||
Destroy(rewardFly.gameObject);
|
||||
// UIManager.BlockInput(5f);
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.Log($"[EventBreak] BreakBlockError: {ex.Message}\n{ex.StackTrace}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// will never be running twice at the same time.
|
||||
/// </summary>
|
||||
/// <param name="info">current task info, the actual one</param>
|
||||
public async void UpdateDisplay(EventBreakTaskInfo info)
|
||||
{
|
||||
if (_isUpdatingTaskDisplay)
|
||||
return;
|
||||
try
|
||||
{
|
||||
// UIManager.BlockInput(5f);
|
||||
_isUpdatingTaskDisplay = true;
|
||||
PlayGemFx();
|
||||
var s = textProgress.text.Split("/");
|
||||
var currentCount = int.Parse(s[0]);
|
||||
var totalCount = int.Parse(s[1]);
|
||||
if (_taskId != info.TaskId)
|
||||
{
|
||||
await DOTween.To(() => currentCount, v => currentCount = v, totalCount, _taskChangeDuration)
|
||||
.OnUpdate(() =>
|
||||
{
|
||||
barProgress.fillAmount = (float)currentCount / totalCount;
|
||||
textProgress.text = $"{currentCount}/{totalCount}";
|
||||
})
|
||||
.AsyncWaitForCompletion();
|
||||
await PlayProgressBarFx();
|
||||
var panel = await UIManager.Instance.ShowUINotLoading(UITypes.EventBreakRewardPopupPanel);
|
||||
var t = new TaskCompletionSource<int>();
|
||||
panel.GetComponent<EventBreakTaskRewardPopupPanel>().Init(_rewardItemData, EventBreakAct.Ctx.GetGemIdx(gemId: _targetItemId), () => t.SetResult(1));
|
||||
await t.Task;
|
||||
EventBreakAct.EventAggregator.Publish(new EventBreakBlockInput(EEventBreakBlockInputOperation.StrongUnblock));
|
||||
await Awaiters.NextFrame;
|
||||
currentCount = 0;
|
||||
totalCount = info.TotalGemRequired;
|
||||
aniTask.Play("reward_refresh");
|
||||
await Awaiters.NextFrame;
|
||||
reward.SetData(info.Reward, abbr: true);
|
||||
barProgress.fillAmount = 0f;
|
||||
textProgress.text = $"0/{info.TotalGemRequired}";
|
||||
_taskId = info.TaskId;
|
||||
_rewardItemData = info.Reward;
|
||||
await Awaiters.NextFrame;
|
||||
}
|
||||
await DOTween.To(() => currentCount, v => currentCount = v, info.CurrentGemProgress, _taskChangeDuration)
|
||||
.OnUpdate(() =>
|
||||
{
|
||||
barProgress.fillAmount = (float)currentCount / totalCount;
|
||||
textProgress.text = $"{currentCount}/{totalCount}";
|
||||
})
|
||||
.AsyncWaitForCompletion();
|
||||
_isUpdatingTaskDisplay = false;
|
||||
EventBreakAct.EventAggregator.Publish(new EventBreakBlockInput(EEventBreakBlockInputOperation.Unblock));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.Log($"[EventBreak] TaskView: {ex.Message}\n{ex.StackTrace}", this);
|
||||
_isUpdatingTaskDisplay = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void PlayGemFx()
|
||||
{
|
||||
fxGem.SetActive(false);
|
||||
fxGem.SetActive(true);
|
||||
}
|
||||
|
||||
private async Task PlayProgressBarFx()
|
||||
{
|
||||
fxBar.SetActive(false);
|
||||
fxBar.SetActive(true);
|
||||
await Task.Delay(TimeSpan.FromSeconds(_taskChangeDuration));
|
||||
fxBar.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
public class EventBreakBlockBreak
|
||||
{
|
||||
public Vector2 BreakPos { get; set; }
|
||||
public ItemData Item {get; set;}
|
||||
}
|
||||
11
Assets/Scripts/EventBreak/EventBreakTaskView.cs.meta
Normal file
11
Assets/Scripts/EventBreak/EventBreakTaskView.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 786901d4c8f5aed4f9c4d8c881d75402
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
185
Assets/Scripts/EventBreak/EventBreakTunnelView.cs
Normal file
185
Assets/Scripts/EventBreak/EventBreakTunnelView.cs
Normal file
@@ -0,0 +1,185 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using DG.Tweening;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Assertions;
|
||||
using UnityEngine.UI;
|
||||
using TMPro;
|
||||
using System.Collections.Generic;
|
||||
using asap.core;
|
||||
using Game;
|
||||
|
||||
public class EventBreakTunnelView : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private EventBreakBlock[] blocks;
|
||||
[SerializeField] private Button btnDrill;
|
||||
[SerializeField] private Transform endPivot, drillStartPivot;
|
||||
[SerializeField] private EventBreakDrillDisplay drillDisplay;
|
||||
[SerializeField] private GameObject fxButtonGlitter;
|
||||
[SerializeField] private TMP_Text textCost;
|
||||
[SerializeField] private Animator aniBtnDrill;
|
||||
private float _spawnInterval = 0.1f, _dropDuration = 0.5f, _drillDuration = 0.8f, _dropHeight = 1680,
|
||||
_drillReadyDuration = 0.5f, _resetTunnelDelay = 10f, _btnPressedDuration = 0.3f, _drillDetectionRange = 50f,
|
||||
_blockDropSfxDelay = 0.1f;
|
||||
private AnimationCurve _easeCurve;
|
||||
private int _tunnelIdx;
|
||||
private List<Vector3> _blockEndPoints;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
btnDrill.onClick.AddListener(async () => await StartDrilling());
|
||||
// foreach (var block in blocks)
|
||||
// Debug.Log($"[EventBreak] block height: {block.name} at {block.transform.position.y}");
|
||||
}
|
||||
|
||||
public void Init(EventBreakTunnelViewInitInfo info)
|
||||
{
|
||||
_blockEndPoints = new List<Vector3>();
|
||||
foreach (var block in blocks)
|
||||
{
|
||||
block.gameObject.SetActive(false);
|
||||
_blockEndPoints.Add(block.transform.position);
|
||||
}
|
||||
drillDisplay.Init(info.Idx);
|
||||
_spawnInterval = info.SpawnInterval;
|
||||
_dropDuration = info.DropDuration;
|
||||
_drillDuration = info.DrillDuration;
|
||||
_tunnelIdx = info.Idx;
|
||||
_dropHeight = info.DropHeight;
|
||||
textCost.text = info.Job.Cost.ToString();
|
||||
_easeCurve = info.EaseCurve;
|
||||
_drillReadyDuration = info.DrillReadyDuration;
|
||||
_resetTunnelDelay = info.ResetTunnelDelay;
|
||||
_btnPressedDuration = info.ButtonPressedDuration;
|
||||
_drillDetectionRange = info.DrillDetectionRange;
|
||||
_blockDropSfxDelay = info.BlockDropSfxDelay;
|
||||
SetTunnel(info.Job);
|
||||
}
|
||||
|
||||
public async void SetTunnel(DrillJobModel job)
|
||||
{
|
||||
try
|
||||
{
|
||||
EventBreakAct.EventAggregator.Publish(new EventBreakBlockInput(EEventBreakBlockInputOperation.Block));
|
||||
aniBtnDrill.Play("Normal");
|
||||
int jobCount = job.Blocks.Length, blockCount = blocks.Length;
|
||||
Assert.IsTrue(jobCount == blockCount, $"[EventBreak]Block count mismatch. Got {jobCount} jobs and {blockCount} blocks");
|
||||
drillDisplay.PlayEnter(drillStartPivot.position);
|
||||
PlayBlockFallSfx(_blockDropSfxDelay);
|
||||
for (int i = blocks.Length - 1; i >= 0; i--)
|
||||
{
|
||||
blocks[i].Appear(job.Blocks[i], dropHeight: _dropHeight, endPoint: _blockEndPoints[i], dropTime: _dropDuration, easeCurve: _easeCurve);
|
||||
await Task.Delay(TimeSpan.FromSeconds(_spawnInterval));
|
||||
}
|
||||
await Task.Delay(TimeSpan.FromSeconds(_dropDuration + 0.1f));
|
||||
EventBreakAct.EventAggregator.Publish(new EventBreakBlockInput(EEventBreakBlockInputOperation.Unblock));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Log($"[EventBreak] TunnelInitiationError: {e.Message}\n{e.StackTrace}");
|
||||
}
|
||||
}
|
||||
|
||||
private async void PlayBlockFallSfx(float delay = 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
await Task.Delay(TimeSpan.FromSeconds(delay));
|
||||
GContext.Publish(new EventUISound("audio_ui_drill_brick_falling", 0));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Log($"[EventBreak] SFX error: {e.Message}\n{e.StackTrace}");
|
||||
}
|
||||
}
|
||||
public async Task StartDrilling()
|
||||
{
|
||||
// Debug.Log($"[EventBreak] Click No.{_tunnelIdx}!", this);
|
||||
if (EventBreakAct.DrillSystem.DoDrillJob(_tunnelIdx))
|
||||
{
|
||||
EventBreakAct.EventAggregator.Publish(new EventBreakBlockInput(EEventBreakBlockInputOperation.Block));
|
||||
PlayBtnPressed();
|
||||
drillDisplay.PlayDrill();
|
||||
await Task.Delay(TimeSpan.FromSeconds(_drillReadyDuration));
|
||||
drillDisplay.GetDrillTween(endPivot.transform.position, _drillDuration)
|
||||
.OnUpdate(DrillBlocks)
|
||||
.OnComplete(OnDrillComplete);
|
||||
}
|
||||
else
|
||||
{
|
||||
EventBreakAct.EventAggregator.Publish(new EventBreakInsufficientTicket());
|
||||
}
|
||||
}
|
||||
public void StartDrillingTest()
|
||||
{
|
||||
// Debug.Log($"[EventBreak] Click No.{_tunnelIdx}!", this);
|
||||
drillDisplay.PlayDrill();
|
||||
drillDisplay.GetDrillTween(endPivot.transform.position, _drillDuration)
|
||||
.OnUpdate(DrillBlocks);
|
||||
// .OnComplete(OnDrillComplete);
|
||||
}
|
||||
|
||||
private async void OnDrillComplete()
|
||||
{
|
||||
try
|
||||
{
|
||||
await Task.Delay(TimeSpan.FromSeconds(_resetTunnelDelay));
|
||||
var dm = GContext.container.Resolve<DrillModel>();
|
||||
SetTunnel(dm.DrillJobList[_tunnelIdx]);
|
||||
EventBreakAct.EventAggregator.Publish(new EventBreakBlockInput(EEventBreakBlockInputOperation.Unblock));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Log($"[EventBreak] ResetTunnelError: {e.Message}\n{e.StackTrace}");
|
||||
}
|
||||
}
|
||||
|
||||
private void DrillBlocks()
|
||||
{
|
||||
foreach (var b in blocks)
|
||||
{
|
||||
if (b.gameObject.activeSelf == false)
|
||||
continue;
|
||||
var delta = b.transform.position.y - drillDisplay.Y;
|
||||
if (delta > _drillDetectionRange)
|
||||
continue;
|
||||
b.Break();
|
||||
}
|
||||
}
|
||||
public void SetAvailabilityDisplay(bool doesShow)
|
||||
{
|
||||
fxButtonGlitter.SetActive(doesShow);
|
||||
textCost.color = doesShow ? Color.white : Color.red;
|
||||
}
|
||||
private async void PlayBtnPressed()
|
||||
{
|
||||
var isFxOn = fxButtonGlitter.activeInHierarchy;
|
||||
try
|
||||
{
|
||||
aniBtnDrill.Play("Pressed");
|
||||
fxButtonGlitter.SetActive(false);
|
||||
await Task.Delay(TimeSpan.FromSeconds(_btnPressedDuration));
|
||||
aniBtnDrill.Play("Normal");
|
||||
fxButtonGlitter.SetActive(isFxOn);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Log($"[EventBreak] Button Error: {e.Message}\n{e.StackTrace}");
|
||||
}
|
||||
}
|
||||
}
|
||||
public class EventBreakTunnelViewInitInfo
|
||||
{
|
||||
public DrillJobModel Job { get; set; }
|
||||
public float SpawnInterval { get; set; }
|
||||
public float DropDuration { get; set; }
|
||||
public float DrillDuration { get; set; }
|
||||
public float DropHeight { get; set; }
|
||||
public float DrillReadyDuration { get; set; }
|
||||
public float ResetTunnelDelay { get; set; }
|
||||
public float ButtonPressedDuration { get; set; }
|
||||
public float DrillDetectionRange { get; set; }
|
||||
public float BlockDropSfxDelay { get; set; }
|
||||
public int Idx { get; set; }
|
||||
public AnimationCurve EaseCurve { get; set; }
|
||||
}
|
||||
11
Assets/Scripts/EventBreak/EventBreakTunnelView.cs.meta
Normal file
11
Assets/Scripts/EventBreak/EventBreakTunnelView.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 13d60a249f47f7e478c90e59a9eb9c90
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user