using System; using System.Collections.Generic; using System.Linq; using asap.core; using cfg; using game; using GameCore; using UniRx; using UnityEngine; using Random = UnityEngine.Random; namespace EventMowForTreasure { public class EventMowForTreasureManager : AEventDataManager { public EventMowForTreasureManager(PlayerItemData playerItemData) { _playerItemData = playerItemData; GContext.OnEvent().Subscribe(_ => { SaveData(); SetRedPoint(); SetRedPoint_chainPack(); }).AddTo(Disposables); } #region event protected override int EventType => 7; protected override int EventSubType => 6; #endregion event #region data private readonly PlayerItemData _playerItemData; private readonly List _itemDatas = new List(); protected override void RefreshData(int eventId) { base.RefreshData(eventId); RefreshToolToken(); } protected override void InitData(int eventId) { base.InitData(eventId); Data.SetChainPackID(); Data.RefreshCache(); InitToolAmount(); var welcomeGift = GContext.container.Resolve().GetInitWelcomeGift(eventId); AddToken(welcomeGift); SaveData(); } protected override void SaveData() { base.SaveData(); GContext.Publish(new EventMowForTreasureGuideRefresh()); } #endregion data #region Stage public List GetItemDataForCell() { var dropID = GetCurrentStage()?.BreakDropID ?? 0; if (dropID <= 0) return null; var dropItems = _playerItemData.GetItemDataByDropIdAndTypeLureInflation(Data.InflationRate, dropID); if (dropItems == null || dropItems.Count == 0) return null; return dropItems.Where(x => x.count > 0).ToList(); } public List AddItemDataForCell() { var dropID = GetCurrentStage()?.BreakDropID ?? 0; if (dropID <= 0) return null; ChangeSource changeSource = new ChangeSource(Data.EventId, "Event_Minigame2", "Event_Minigame2_Mow", "DirectReward"); var dropItems = _playerItemData.AddItemByDropLureInflation(Data.InflationRate, dropID, changeSource, false); if (dropItems == null || dropItems.Count == 0) return null; _itemDatas.AddRange(dropItems); return dropItems.Where(x => x.count > 0).ToList(); } public void ShowAllBrokeDropItems() { if (_itemDatas is { Count: <= 0 }) return; //// 合并重复物品ID,避免显示多个相同物品 var mergedItems = _itemDatas .GroupBy(item => item.id) .Select(group => new ItemData { id = group.Key, count = group.Sum(item => item.count) }).ToList(); GContext.Publish(new ShowData(mergedItems)); GContext.Publish(new ShowData()); _itemDatas.Clear(); } public EventMowForTreasureObstacleData GetObstacleData(Vector2Int coordinate, int columnAmount) { var index = columnAmount * (coordinate.y - 1) + coordinate.x; if (index < 0 || index >= Data.ObstacleList.Count) return null; return Data.ObstacleList[index]; } private int GetFixedStageID() { if (Data.FixedStageList.Count == Data.EventMain.FixedStageList.Count) return -1; return Data.EventMain.FixedStageList[Data.FixedStageList.Count]; } private EventMowForTreasureStage GetFixedStageConfig() { var id = GetFixedStageID(); return Tables.TbEventMowForTreasureStage.GetOrDefault(id); } private EventMowForTreasureStage GetRelevantLoopStageByFixed() { if (Data.IsCompletedFixedStage) return null; var id = Data.EventMain.LoopStageList.ElementAt(Data.FixedStageList.Count); return Tables.TbEventMowForTreasureStage.GetOrDefault(id); } private int GetLoopStageID() { var loopProgress = Data.CompletedStageAmount - Data.FixedStageList.Count; var targetIndex = loopProgress % Data.EventMain.LoopStageList.Count; return Data.EventMain.LoopStageList.ElementAt(targetIndex); } private EventMowForTreasureStage GetLoopStageConfig() { var id = GetLoopStageID(); return Tables.TbEventMowForTreasureStage.GetOrDefault(id); } private EventMowForTreasureStage GetCurrentStage() { return Data.IsCompletedFixedStage ? GetLoopStageConfig() : GetFixedStageConfig(); } public string GetCurrentStageAct() { return Data.IsCompletedFixedStage ? GetCurrentStage()?.StageBgPrefab : GetRelevantLoopStageByFixed()?.StageBgPrefab; } public Dictionary GetCurrentStageItemDir() { return Data.IsCompletedFixedStage ? GetLoopStageConfig()?.StageItemList : GetRelevantLoopStageByFixed()?.StageItemList; } private Dictionary GetCurrentStageItemDrop() { return Data.IsCompletedFixedStage ? GetLoopStageConfig()?.StageItemProb : GetRelevantLoopStageByFixed()?.StageItemProb; } public void InitStageAllObstacle(Vector2Int startCoordinate, Vector2Int endCoordinate) { InitDataStarAndEndData(startCoordinate, endCoordinate); InitStageObstacleListDatas(); } private void InitStageObstacleListDatas() { if (Data.ObstacleList is { Count: > 0 }) return; var stageConfig = GetCurrentStage(); var randomStageIndex = Random.Range(0, stageConfig.StageConfig.Count); var randomStageObstacles = stageConfig.StageConfig[randomStageIndex]; var currentItemDrop = GetCurrentStageItemDrop(); var datas = new List(); foreach (var t in randomStageObstacles) { var type = t; if (currentItemDrop.TryGetValue(type, out var probability)) { var random = Random.value; if (random > probability) type = (int)EEventMowForTreasureObstacleType.CommonObstacle; } var data = new EventMowForTreasureObstacleData { Type = (EEventMowForTreasureObstacleType)type }; datas.Add(data); } Data.ObstacleList = datas; SaveData(); } private void InitDataStarAndEndData(Vector2Int startCoordinate, Vector2Int endCoordinate) { if (Data.StartObstacle != null) { Data.StartObstacle.Coordinate = startCoordinate; } else { Data.StartObstacle = new EventMowForTreasureObstacleData { Type = EEventMowForTreasureObstacleType.None, Coordinate = startCoordinate, IsBroke = true }; } if (Data.EndObstacle != null) { Data.EndObstacle.Coordinate = endCoordinate; } else { Data.EndObstacle = new EventMowForTreasureObstacleData { Coordinate = endCoordinate, Type = EEventMowForTreasureObstacleType.FinalReward }; } } public List GetCurrentStageFinalReward() { var stageConfig = GetCurrentStage(); return GContext.container.Resolve() .GetItemDataByDropIdAndTypeLureInflation(Data.InflationRate, stageConfig.FinalRewardDropID); } public void SetCompleteStageAndSendReward() { var stageConfig = GetCurrentStage(); if (!Data.IsCompletedFixedStage) Data.FixedStageList.Add(stageConfig.ID); Data.CompletedStageAmount += 1; Data.ObstacleList?.Clear(); Data.ObstacleList = null; Data.EndObstacle = null; Data.StartObstacle = null; AggStageComplete(GetCurrentStage().ID); SaveData(); ChangeSource changeSource = new ChangeSource(Data.EventId, "Event_Minigame2", "Event_Minigame2_Mow", "StageReward"); GContext.container.Resolve() .AddItemByDropLureInflation(Data.InflationRate, stageConfig.FinalRewardDropID, changeSource); GContext.Publish(new ShowData()); } public void ProcessSingleCellBreak(EventMowForTreasureObstacleCell cell, Func> getSpecialRewardBreakCells, ref int specialRewardBrokeCount) { if (!cell) return; var data = cell.GetData(); if (data == null) return; if (data.IsBroke) return; if (data.IsCollectionReward) TryCollectCollection(data, out _); else if (data.IsSpecialReward) { var cells = getSpecialRewardBreakCells?.Invoke(cell); if (cells == null) return; specialRewardBrokeCount += cells.Count(c => !c.GetData().IsBroke); int brokeCount = 0; foreach (var c in cells) ProcessSingleCellBreak(c, getSpecialRewardBreakCells, ref specialRewardBrokeCount); } else if (data.IsObstacleCell) ObstacleBreakItemDrop(data); data.IsBroke = true; SaveData(); } private void ObstacleBreakItemDrop(EventMowForTreasureObstacleData data) { var itemDatas = AddItemDataForCell(); if (itemDatas is not { Count: > 0 }) return; data.ItemData = itemDatas.First(); } #endregion #region Tool private void InitToolAmount() { if (Data.EventMain.ToolConfigList.Count != Data.EventMain.ToolInitCount.Count) { Debug.LogError($"InitToolAmount 数量不一致 ToolConfigList {Data.EventMain.ToolConfigList.Count} ToolInitCount {Data.EventMain.ToolInitCount.Count}"); return; } for (int i = 0; i < Data.EventMain.ToolConfigList.Count; i++) { var toolID = Data.EventMain.ToolConfigList[i]; var amount = Data.EventMain.ToolInitCount[i]; if (IsDefaultTool(toolID)) { AddToken(amount); continue; } if (!Data.ToolAmountPairs.TryAdd(toolID, amount)) { Debug.LogWarning($" InitToolAmount 添加失败 toolID {toolID} amount {amount}"); } } SetRedPoint(); } public EEventMowForTreasureToolType GetToolTypeByConfig(EventMowForTreasureTool tool) { return (EEventMowForTreasureToolType)Data.EventMain.ToolConfigList.IndexOf(tool.ID); } public EventMowForTreasureTool GetToolConfigByIndex(int index) { var isValidIndex = index >= 0 && index < Data.EventMain.ToolConfigList.Count; return !isValidIndex ? null : Tables.TbEventMowForTreasureTool.GetOrDefault(Data.EventMain.ToolConfigList[index]); } public bool TryGetToolAmount(int toolID, out int toolAmount) { return Data.ToolAmountPairs.TryGetValue(toolID, out toolAmount); } private int GetDefaultToolID() { return Data.EventMain.ToolConfigList.FirstOrDefault(); } public bool IsDefaultTool(int toolID) { return toolID == GetDefaultToolID(); } public EventMowForTreasureTool GetDefaultToolConfig() { return Data.Tables.TbEventMowForTreasureTool.GetOrDefault(GetDefaultToolID()); } public bool GetCanUseDefaultTool() { return GetCanUseTool(GetDefaultToolID()); } public bool GetCanUseTool(int toolID) { if (!Data.ToolAmountPairs.TryGetValue(toolID, out var toolAmount)) return false; return toolAmount > 0; } public void ConsumeTool(int toolID) { var isDefault = IsDefaultTool(toolID); if (isDefault) RemoveToken(1); else Data.ToolAmountPairs[toolID]--; GContext.Publish(new EventMowForTreasureToolAmountChange()); SetRedPoint(); SaveData(); } public bool TryExchangeTool(int exchangeNum, int exchangeRate, int toolConfigID) { var defaultToolID = GetDefaultToolID(); if (defaultToolID == 0) return false; Data.ToolAmountPairs.TryGetValue(defaultToolID, out var ownAmount); var needAmount = exchangeNum * exchangeRate; if (needAmount > ownAmount) { ShowFestPackPanel(); return false; } RemoveToken(needAmount); if (!Data.ToolAmountPairs.TryAdd(toolConfigID, exchangeNum)) Data.ToolAmountPairs[toolConfigID] += exchangeNum; SaveData(); SetRedPoint(); GContext.Publish(new EventMowForTreasureToolAmountChange()); return true; } #endregion #region Collection public bool IsCanObtainCollectionReward(EventMowForTreasureCollectionData collectionData, int collectionAmount) { if (collectionData?.CollectionConfig == null) return false; if (collectionAmount < collectionData.CollectionConfig.CollectingRequirement) return false; ChangeSource changeSource = new ChangeSource(Data.EventId, "Event_Minigame2", "Event_Minigame2_Mow", "TaskReward"); GContext.container.Resolve() .AddItemByDropLureInflation(Data.InflationRate, collectionData.GerRewardDropID(), changeSource); collectionData.Amount = collectionAmount - collectionData.CollectionConfig.CollectingRequirement; collectionData.Round++; SaveData(); return true; } private List GetCollectionReward(EventMowForTreasureCollectionData collectionData) { return GContext.container.Resolve() .GetItemDataByDropIdAndTypeLureInflation(Data.InflationRate, collectionData.GerRewardDropID()); } public EventMowForTreasureCollectionData GetCollectionDataByType(int type) { return TryGetCollectionIDByType(type, out var collectionID) ? GetCollectionData(collectionID) : null; } public bool TryCollectCollection(EventMowForTreasureObstacleData cellData, out EventMowForTreasureCollectionData collectionData) { collectionData = null; if (!TryGetCollectionIDByType((int)cellData.Type, out var collectionID)) return false; collectionData = GetCollectionData(collectionID); if (collectionData != null) collectionData.Amount += 1; else Data.CollectionProgressPairs.Add(collectionID, new EventMowForTreasureCollectionData(Tables, collectionID, 1)); cellData.IsBroke = true; SaveData(); AggCollection((int)cellData.Type, GetCurrentStage().ID); return true; } private bool TryGetCollectionIDByType(int type, out int collectionID) { return GetCurrentStageItemDir().TryGetValue(type, out collectionID); } private EventMowForTreasureCollectionData GetCollectionData(int collectionID) { if (Data.CollectionProgressPairs.TryGetValue(collectionID, out var collectionData)) { if (collectionData.CollectionID == 0) collectionData.CollectionID = collectionID; return collectionData; } collectionData = new EventMowForTreasureCollectionData(Tables, collectionID, 0); Data.CollectionProgressPairs.Add(collectionID, collectionData); SaveData(); return collectionData; } public EventMowForTreasureCollectionData GetCollectionDataAndRewardByIndex(int index, out List rewards) { rewards = null; var isValidIndex = index >= 0 && index < Data.EventMain.CollectionID.Count; if (!isValidIndex) return null; var collectionID = Data.EventMain.CollectionID[index]; var collectionData = GetCollectionData(collectionID); rewards = GetCollectionReward(collectionData); return collectionData; } #endregion #region FestPack public async void ShowFestPackPanel() { try { if (Data?.EventMain == null) return; GameObject go; var chainPackData = GenericChainPackData.Create(Data, GetPackData()); if (chainPackData.ChainProgress >= chainPackData.ChainListCount) { var packManagerConfig = Data.Tables.TbEventPackManager.GetOrDefault(Data.EventMain.PackPackID); UITypes.EventMowForTreasureFestPackPanle.SetType(Data.EventMain.PackPanel); go = await UIManager.Instance.ShowUILoad(UITypes.EventMowForTreasureFestPackPanle); var vipLevel = GContext.container.Resolve().PriceLv; var packManager = Tables.TbEventPackManager.GetOrDefault(Data.EventMain.PackPackID); var packIDs = packManager.VIPPackList[vipLevel]; if (packIDs.Count != 2) { Debug.LogError($"配置错误 packIDs.Count not 2 packManager id {packManager.ID} vipLevel{vipLevel}"); return; } var packLeft = Tables.TbPack.GetOrDefault(packIDs[0]); var packRight = Tables.TbPack.GetOrDefault(packIDs[1]); go.GetOrAddComponent()? .Init(new GeneralEventNormalPackInfo() { EventId = Data.EventID, PackLeft = packLeft, PackRight = packRight, ExpireTime = ZZTimeHelper.UtcNow().Add(Data.RemainingTime), InflationRate = Data.InflationRate }); return; } UITypes.EventMowForTreasureFestPackChainPanle.SetType(Data.EventMain.ChainPackPanel); go = await UIManager.Instance.ShowUILoad(UITypes.EventMowForTreasureFestPackChainPanle); var panel = go.GetComponent(); panel.Init(chainPackData); } catch (Exception e) { Debug.LogError($"jsd {e}"); } } public async void ShowExchangeToolPanel(int toolID) { try { var toolIndex = Data.EventMain.ToolConfigList.IndexOf(toolID); var rateCount = Data.EventMain.ToolExchangeRate.Count; if (toolIndex >= rateCount) { Debug.LogError($"参数错误 _toolConfig.ID {toolID} toolIndex {toolIndex} RateCount {rateCount}"); return; } var toolRate = Data.EventMain.ToolExchangeRate[toolIndex]; var go = await UIManager.Instance.ShowUILoad(UITypes.EventMowForTreasureExchangePanel); go.GetOrAddComponent()? .SetData(toolID, toolRate); } catch (Exception e) { Debug.LogError(e); } } private EventChainPackInfo GetPackData() { var chainList = GetChainPackManager().GetPackIDsByCurrentVipLevel(); var packs = Tables.TbPack.DataList.Where(p => chainList.ToHashSet().Contains(p.ID)).ToArray(); return new EventChainPackInfo { ChainList = chainList, ExpireTime =ZZTimeHelper.UtcNow().Add(Data.RemainingTime), Packs = packs, RedPointKey = GetRedPointKey_chainPack() }; } private EventPackManager GetChainPackManager() { return Tables.TbEventPackManager[Data.ChainPackID]; } public void AddChainPackProgress(int count = 1) { if (Data == null) return; var currentCount = Data.GetChainProgress(); var totalCount = currentCount + count; Data.SetChainProgress(totalCount); SaveData(); } #endregion #region Token public override void AddToken(int count) { base.AddToken(count); RefreshToolToken(); GContext.Publish(new EventMowForTreasureToolAmountChange()); } protected override void RemoveToken(int count) { base.RemoveToken(count); RefreshToolToken(); GContext.Publish(new EventMowForTreasureToolAmountChange()); } private void RefreshToolToken() { var defaultConfigID = GetDefaultToolID(); if (!Data.ToolAmountPairs.TryAdd(defaultConfigID, GetTokenCount())) Data.ToolAmountPairs[defaultConfigID] = GetTokenCount(); SetRedPoint(); SaveData(); } #endregion #region Guide public void AddGuideStep(int step = 1) { Data.GuideStep += step; SaveData(); } public void TryShowGuide() { if (Data.IsCompleteGuide) return; switch (Data.GuideStep) { case 1: UITypes.EventMowForTreasureInfoPopup.SetType(Data.EventMain.InfoPanel); _ = UIManager.Instance.ShowUILoad(UITypes.EventMowForTreasureInfoPopup); Data.GuideStep++; break; case >= 2 and <= 4: UITypes.EventMowForTreasureGuidePopup.SetType(Data.EventMain.GuidePanel); _ = UIManager.Instance.ShowUILoad(UITypes.EventMowForTreasureGuidePopup); break; default: GContext.container.Resolve().InspectTriggerGuide("EventMowForTreasurePanel"); Data.IsCompleteGuide = true; break; } SaveData(); } public void ClearGuide() { Data.IsCompleteGuide = false; Data.GuideStep = 1; SaveData(); } #endregion #region Red private string GetRedPointKey_chainPack() { return "eventMowForTreasureChainPack.red"; } private bool GetRedPointState_chainPack() { return GetRedPointCount_chainPack()>0; } private int GetRedPointCount_chainPack() { return GenericChainPackData.Create(Data, GetPackData())?.RedPointIndex??0;; } public void SetRedPoint_chainPack() { RedPointManager.Instance?.SetRedPointState(GetRedPointKey_chainPack(), GetRedPointState_chainPack(),GetRedPointCount_chainPack()); } private string GetRedPointKey() { return "eventMowForTreasure.red"; } private bool GetRedPointState() { return GetRedPointCount()>0; } private int GetRedPointCount() { var chainPackData = GenericChainPackData.Create(Data, GetPackData()); return Data.ToolAmountPairs.Values.Sum()+chainPackData?.RedPointIndex??0; } private void SetRedPoint() { RedPointManager.Instance?.SetRedPointState(GetRedPointKey(), GetRedPointState(),GetRedPointCount()); } #endregion #region Agg private void AggCollection(int collection_type, int stage_id) { #if UNITY_EDITOR Debug.Log($"event_mowfortreasure_collection collection_type {collection_type} stage_id {stage_id}"); #endif #if AGG using (var e = GEvent.GameEvent("event_mowfortreasure_collection")) { e.AddContent(nameof(collection_type),collection_type) .AddContent(nameof(stage_id), stage_id); } #endif } private void AggStageComplete(int stage_id) { #if UNITY_EDITOR Debug.Log($"event_mowfortreasure_complete stage_id {stage_id}"); #endif #if AGG using (var e = GEvent.GameEvent("event_mowfortreasure_complete")) { e.AddContent(nameof(stage_id), stage_id); } #endif } public void AggItem(int item_type, bool is_knife, int block_break_count) { var stage_id = GetCurrentStage().ID; #if UNITY_EDITOR Debug.Log($"event_mowfortreasure_item item_type {item_type} is_knife {is_knife} block_break_count {block_break_count} stage_id {stage_id}"); #endif #if AGG using (var e = GEvent.GameEvent("event_mowfortreasure_item")) { e.AddContent(nameof(item_type), item_type) .AddContent(nameof(is_knife), is_knife) .AddContent(nameof(block_break_count), block_break_count) .AddContent(nameof(stage_id), stage_id); } #endif } #endregion } }