using UnityEngine; using GameCore; using asap.core; using System.Linq; using System.Collections.Generic; 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[FtUtils.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(); float Inflate = _model.DicTasks.GetValueOrDefault(-3, 0) / 100f; // 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); ChangeSource changeSource = new ChangeSource(_model.EventId, "Event_Minigame3", "Event_Minigame3_LuckMagic", "DirectReward"); GContext.Publish(new DeferredRewardStashService.EventStashDrop { Inflate = Inflate, DropId = dropId, changeSource = changeSource }); } 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)) { ChangeSource changeSource = new ChangeSource(_model.EventId, "Event_Minigame3", "Event_Minigame3_LuckMagic", "CollectReward"); // var progressReward = _playerItemData.AddItemByDrop(dropId)[0]; GContext.Publish(new DeferredRewardStashService.EventStashDrop { Inflate = Inflate, DropId = dropId, changeSource = changeSource }); } } else { sourceRing.Blocks[idx].Take(); _model.LinkRings(); _model.HigherRingData.PointTo(sourceRing.HigherRing); // _playerItemData.AddItem(reward); reward.changeSource = new ChangeSource(_model.EventId, "Event_Minigame3", "Event_Minigame3_LuckMagic", "DirectReward"); 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; } }