using UnityEngine; using GameCore; using asap.core; using System.Linq; public class EventLuckMagicSystem { public const int BoardSize = 6; private readonly PlayerItemData _playerItemData; public EventLuckMagicSystem() { _playerItemData = GContext.container.Resolve(); } /// /// Draw a random block from the ring. /// /// The index of chosen block. Will be -1 if this draw fails. /// The reward to be shown. Will be null if this draw fails. /// True if successfully get a index and reward. public bool Draw(EventLuckMagicRing ring, out EventLuckMagicSpinCtx spinCtx, out int targetBlockTableId) { var _model = GContext.container.Resolve(); spinCtx = new EventLuckMagicSpinCtx(); spinCtx.Ring = ring; spinCtx.Index = -1; spinCtx.Reward = null; targetBlockTableId = -1; if (ring.IsDepleted) { Debug.Log($"[EventLuckMagic] This ring is Depleted."); if (_model.IsGameDepleted) { _model.AddRoundCount(); _model.Reset(); } return false; } var dic = ring.Blocks.Select((block, index) => (block, index)) .Where(x => x.block.IsTaken == false) .ToDictionary(x => x.index, x => x.block.Weight); var keys = dic.Keys.ToArray(); var weights = dic.Values.ToArray(); spinCtx.Index = keys[FtMathUtils.GetRandomIdxFromWeightList(weights)]; spinCtx.Reward = ring.Blocks[spinCtx.Index].Reward; targetBlockTableId = ring.Blocks[spinCtx.Index].TableId; spinCtx.RoundCount = _model.RoundCount; return true; } public void GrantReward(EventLuckMagicSpinCtx spinCtx) { if (spinCtx == null || spinCtx.Reward == null) return; var _model = GContext.container.Resolve(); // Debug.Log($"[EventLuckMagic] Grant Reward {reward.id} * {reward.count}."); var reward = spinCtx.Reward; var sourceRing = spinCtx.Ring; var idx = spinCtx.Index; if (EventLuckMagicAct.TableContext.IsRewardRoadSign(reward.id, out var expireDuration, out int dropId, out _) && sourceRing.RingType != EEventLuckMagicRingType.InnerRing) { _model.LinkRings(); _model.HigherRingData.PointTo(sourceRing.HigherRing); _model.HigherRingData.Activate(expireDuration); // _playerItemData.AddItemByDrop(dropId); GContext.Publish(new DeferredRewardStashService.EventStashDrop {DropId = dropId}); } else if (EventLuckMagicAct.TableContext.IsRewardProgressItem(reward.id, spinCtx.RoundCount, out dropId)) { sourceRing.Blocks[idx].Take(); _model.LinkRings(); _model.HigherRingData.PointTo(sourceRing.HigherRing); // _playerItemData.AddItemByDrop(dropId, stash: true); _model.UpdateTaskProgress(reward.id); if (_model.IsTaskCompleted(reward.id)) { // var progressReward = _playerItemData.AddItemByDrop(dropId)[0]; GContext.Publish(new DeferredRewardStashService.EventStashDrop {DropId = dropId}); } } else { sourceRing.Blocks[idx].Take(); _model.LinkRings(); _model.HigherRingData.PointTo(sourceRing.HigherRing); // _playerItemData.AddItem(reward); GContext.Publish(new DeferredRewardStashService.EventStashItem { Item = reward }); } } } public class EventLuckMagicDrawEvent { public readonly EEventLuckMagicRingType Ring; public readonly int Index; public readonly ItemData Reward; public bool DoesReset = false; public EventLuckMagicDrawEvent(int index, ItemData reward, EEventLuckMagicRingType ring, bool reset = false) { Index = index; Reward = reward; Ring = ring; DoesReset = reset; } }