Files
ft/Client/Assets/Scripts/EventCubeMelt/Data/EventCubeMeltManager.cs
2026-06-29 21:18:33 +08:00

1714 lines
55 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// EventCubeMeltManager.cs
// 锻刀大赛
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using asap.core;
using cfg;
using EventCubeMelt;
using EventCubeMelt.Data;
using EventCubeMelt.ShapePlacement;
using EventCubeMelt.UI;
using EventCubeMelt.Utils;
using game;
using GameCore;
using Newtonsoft.Json;
using UnityEngine;
using Random = UnityEngine.Random;
public class EventCubeMeltManager
{
//
public const string SaveKey = "EventCubeMeltData";
#region
public void UpdateEventData(FishingEvent fishingEvent)
{
_fishingEvent = fishingEvent;
if (EventData != null && _fishingEvent != null && _fishingEvent.ID != EventData.EventId)
{
ClearData();
}
if (!_isInit || EventData == null)
{
_isInit = false;
Init();
}
else
{
UpdateTime();
SetRedPoint();
UpdateLocalData();
}
}
public void LoadData(string dataValue)
{
ELog($"LoadData-> {dataValue}");
if (!string.IsNullOrEmpty(dataValue))
{
EventData = JsonConvert.DeserializeObject<EventCubeMeltData>(dataValue);
// 可调试的在这里放数据
if (true)
{
// EventData.CurrentStagetId = 15;
// EventData.IsFinished = false;
// EventData.BoardData = new List<int>
// {
// 0,99,0,99,99,0,99,0,
// 99,0,99,99,0,99,0,99,
// 0,99,0,99,99,0,99,99,
// 99,0,99,0,99,0,99,99,
// 0,99,99,99,99,99,99,99,
// 99,0,99,99,99,99,99,99,
// 0,99,99,99,99,99,99,99,
// 99,0,99,0,99,99,5,99
// };
// EventData.CollectRewardsId.Remove(14);
// EventData.IsFinalRewardGet = false;
// EventData.CollectItems = new List<CollectItem>
// {
// new()
// {
// ItemId = 1, Count = 20, MaxCount = 20, Icon = null,
// },
// new()
// {
// ItemId = 4, Count = 15, MaxCount = 15, Icon = null,
// },
// new()
// {
// ItemId = 5, Count = 10, MaxCount = 10, Icon = null,
// }
// };
// EventData.BoardData = new List<int>()
// {
// 0, 0, 99, 99, 99, 0, 0, 0,
// 1, 0, 99, 0, 0, 99, 99, 2,
// 99, 99, 99, 88, 88, 2, 0, 99,
// 99, 2, 99, 99, 99, 99, 0, 99,
// 99, 99, 2, 99, 99, 0, 0, 0,
// 0,0,0,0, 0, 2, 0, 0,
// 99, 0, 0, 99, 99, 99, 2, 0,
// 99, 0, 0, 99, 99, 99, 2, 0
// };
// EventData.BoardData = new List<int>
// {
// 99, 99, 99, 99, 0, 99, 0, 0,
// 99, 99, 99, 99, 0, 99, 0, 0,
// 99, 99, 99, 99, 0, 99, 0, 0,
// 99, 99, 99, 99, 0, 99, 0, 0,
// 99, 99, 99, 99, 0, 99, 0, 0,
// 0,0,0,0, 0, 0, 0, 0,
// 99, 99, 99, 99, 0, 99, 0, 0,
// 99, 99, 99, 99, 0, 99, 0, 0,
// };
// EventData.PieceDatas = new List<List<int>>
// {
// new() {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,99,99,99,99,99},
// new() {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0},
// new() {0,0,0,0,0,0,0,0,0,0,0,0,99,99,0,0,0,99,0,0,0,0,99,0,0},
// };
}
}
}
public void ClearData()
{
EventData = null;
_isInit = false;
SaveData();
}
private void SaveData()
{
var eventDataJson = JsonConvert.SerializeObject(EventData);
if (ShouldBuildELog())
{
ELog($"SaveData()-> {eventDataJson}");
}
PlayFabMgr.Instance.UpdateUserDataValue(SaveKey, eventDataJson);
}
public void AddTicket(int costValue)
{
if (EventData != null)
{
EventData.TicketCount += costValue;
if (EventData.TicketCount < 0)
{
EventData.TicketCount = 0;
}
GContext.container.Resolve<FishingEventData>().SaveTransitionData(EventData.EventId, EventData.TicketCount);
GContext.Publish(new EventCubeMeltUpdateTicketCount());
SaveData();
}
SetRedPoint();
}
public int GetTicketCount()
{
return EventData.TicketCount;
}
#endregion
private bool _isInit;
private FishingEvent _fishingEvent;
[Inject] public Tables _tables { get; set; }
public EventCubeMeltData EventData { get; private set; }
public FishingEvent FishingEvent {get => _fishingEvent;set => _fishingEvent = value;}
// 锻刀大赛数据
public EventCubeMeltMain EventCubeMeltMainData { get; private set; }
// 配置
private List<List<int>> EventCubeMeltConfig { get; set; }
// 当前的配置数据
public EventCubeMeltStage EventCubeMeltStageData { get; private set; }
// 当前收集数据
public EventCubeMeltCollection EventCubeMeltCollectionData { get; private set; }
// 当前的Piece
public List<EventCubeMeltPiece> EventCubeMeltPieces { get; private set; }
//
// 读取表格生成所有的Piece
private List<PieceItem> EventCubeMeltPieceItems { get; set; } = new();
// 当前的Item
public List<EventCubeMeltItem> EventCubeMeltItems { get; private set; }
// 收集的列表
public List<EventCubeMeltCollection> EventCubeMeltCollections { get; private set; }
//- 当前的StageList
public List<int> EventStageList { get; private set; }
//
public int StageCount { get; set; }
//-
// public Vector2Int BoardViewSize { get; private set; }
public DateTime StartTime;
// 结束时间
public DateTime EndTime;
public void Init()
{
if (_fishingEvent == null)
return;
if (_isInit)
return;
ELog("Init()-> ");
if (EventData == null)
{
CreateNewData();
}
UpdateLocalData();
UpdateTime();
SetRedPoint();
_isInit = true;
}
public void SetRedPoint()
{
if (EventData != null)
{
RedPointManager.Instance.SetRedPointState(RedPointName.Home_CubeMelt, EventData.TicketCount > 0,
EventData.TicketCount);
}
else
{
RedPointManager.Instance.SetRedPointState(RedPointName.Home_CubeMelt, false);
}
}
private void UpdateTime()
{
if (_fishingEvent != null)
{
var limitedTime = (LimitedTime)_fishingEvent.TimeDefinition;
var startTime = GlobalUtils.TryParseDateTime(limitedTime.StartTime, ZZTimeHelper.UtcNow());
var endTime = GlobalUtils.TryParseDateTime(limitedTime.EndTime, ZZTimeHelper.UtcNow().AddDays(-1));
if (EventData != null)
{
if (EventData.EventId == _fishingEvent.ID)
{
EventData.StartTime = startTime;
EventData.EndTime = endTime;
}
else
{
EventData.EndTime = DateTime.Now.AddDays(-1);
}
}
EndTime = endTime;
StartTime = startTime;
}
}
private void UpdateLocalData()
{
ELog("UpdateLocalData() -> ");
if (_fishingEvent == null)
return;
var fishingEventRedirectID = _fishingEvent.RedirectID;
var cycleItemData = _tables.TbFishingEventCycleItem.GetOrDefault(fishingEventRedirectID);
var dataList = _tables.TbEventCubeMeltMain.DataList;
// 设置内容
EventCubeMeltMainData = dataList.FirstOrDefault(data => data.ID == cycleItemData.RedirectID);
// 道具
EventCubeMeltItems = _tables.TbEventCubeMeltItem.DataList;
EventCubeMeltPieces = _tables.TbEventCubeMeltPiece.DataList;
EventCubeMeltCollections = _tables.TbEventCubeMeltCollection.DataList;
//- StageList
EventStageList = EventData.Cycle == 0 ? EventCubeMeltMainData?.StageFirstList :EventCubeMeltMainData?.StageLoopList ?? new List<int>();
// var stageListCount = EventData.Cycle == 0 ? EventCubeMeltMainData?.StageFirstList.Count : EventCubeMeltMainData?.StageLoopList.Count;
// var stageListCount = EventStageList ?.Count ?? 0;
StageCount = EventStageList ?.Count ?? 0;
// PieceItems
InitPieceItems();
SyncEventDataChange();
}
private void SyncEventDataChange()
{
//- EventData 结构变化了,放在 这里
if (EventData.CollectRewardsId is not { Count: > 0 })
{
EventData.CollectRewardsId = new List<int>();
SaveData();
}
}
public async Task PrepareData()
{
ELog("PrepareData-> ");
if(EventData.CurrentStagetId > 0)
SetIsInGuideAnim(false);
// if (true)
// {
// if (EventData.CurrentStagetId == 2)
// {
// EventData.CurrentStagetId = 1;
// GenerateNextStageData();
// }
// }
FixOverStage();
UpdateCurrentStage();
await UpdateBoardData();
}
private async Task UpdateBoardData()
{
var isSaveDataRequired = false;
if (EventData.BoardData is not { Count: > 0 })
{
CreateNewBoard();
isSaveDataRequired = true;
}
// if (EventData.PieceItems is not { Count: > 0 })
if(EventData.PieceDatas is not {Count: > 0})
{
await CreateNewPieces();
isSaveDataRequired = true;
}
if (EventData.CollectItems is not { Count: > 0 })
{
UpdateNewCollect();
isSaveDataRequired = true;
}
if (isSaveDataRequired)
{
SaveData();
}
for (var i = CurrentPieceItems.Count; i < EventData.PieceDatas.Count; ++i)
{
CurrentPieceItems.Add(new PieceItem());
}
}
// 生成Item
private void InitPieceItems()
{
EventCubeMeltPieceItems.Clear();
foreach (var eventCubeMeltPiece in EventCubeMeltPieces)
{
foreach (var pc in eventCubeMeltPiece.PieceConfig)
{
EventCubeMeltPieceItems.Add(new PieceItem
{
MeltId = eventCubeMeltPiece.ID,
Weight = eventCubeMeltPiece.Weight,
PieceConfig = pc,
});
}
}
var valueBuilder = new StringBuilder();
foreach (var values in EventCubeMeltPieceItems)
{
valueBuilder.Append($"{values.MeltId},");
}
ELog($"UpdatePieceItems - >{valueBuilder}");
}
//TODO:CM 改成一次更新,多次返回的情况,每次更新 stageIndex 数据全部更新
/// <summary>
/// Key 为盘面 CellTypetypeItem.TypeValue 含配置 TypeKey 与需求数量。
/// </summary>
public Dictionary<int, EventCubeMeltCollectionItemInfo> GetCollectionItems()
{
var ls = new Dictionary<int, EventCubeMeltCollectionItemInfo>();
for (var i = 0; i < EventCubeMeltCollectionData!.CollectingCountRequirement.Count; ++i)
{
var typeKey = EventCubeMeltCollectionData.CollectingItemRequirement[i];
var typeItem = EventCubeMeltItems.FirstOrDefault(elem => elem.ID == typeKey);
if (typeItem is { Type: > 0 })
{
var count = EventCubeMeltCollectionData.CollectingCountRequirement[i];
ls[typeItem.Type] = new EventCubeMeltCollectionItemInfo(typeKey, count);
}
}
var valueBuilder = new StringBuilder();
foreach (var kv in ls)
{
valueBuilder.Append($"{kv.Key}(key:{kv.Value.TrueId}):{kv.Value.RequiredCount} ");
}
ELog($"GetCollectionItems - >{valueBuilder}");
return ls;
}
private void CreateNewBoard()
{
var idx = Random.Range(0, EventCubeMeltConfig.Count);
ELog($"CreateNewBoard {idx}");
EventData.BoardData = EventCubeMeltConfig[idx];
var size = EventCubeMeltStageData.BoardSize;
EventData.BoardViewSize= new Vector2Int(size[0], size[1]);
}
private readonly int _pieceCount = 3;
private List<PieceItem> CurrentPieceItems { get; set; } = new();
private async Task CreateNewPieces()
{
ELog("CreateNewPieces");
// EventData.PieceItems.Clear();
CurrentPieceItems.Clear();
EventData.PieceDatas ??= new List<List<int>>();
EventData.PieceDatas.Clear();
if (EventCubeMeltStageData.InitItem is { Count: > 0 })
{
//TODO:注意保证InitItem的有效
var pieceIds = EventCubeMeltStageData.InitItem[0];
var repValueIndexs = EventCubeMeltStageData.InitItem[1];
var ids = EventCubeMeltStageData.InitItem[2];
var hasPieceIds = new List<int>(pieceIds.Where(id => id != 0));
for (var i = 0; i < _pieceCount; ++i)
{
var validMeltPieces = await GetValidMeltPieceItem();
var pieceId = pieceIds?[i]??0;
if (pieceId == 0)
{
validMeltPieces = validMeltPieces.Where(item => !hasPieceIds.Contains(item.MeltId)).ToList();
validMeltPieces = DoFilterSecond(validMeltPieces, EventData.PieceDatas);
var randomItem = WeightedRandom(validMeltPieces);
pieceId = randomItem.MeltId;
hasPieceIds.Add(pieceId);
}
var pieceItems = validMeltPieces.Where(item => item.MeltId == pieceId).ToList();
if (pieceItems.Count == 0)
{
LogError($"CreateNewPiecesInvalid pieceId = {pieceId}");
pieceItems = await GetValidMeltPieceItem();
}
var repValueIndex = repValueIndexs[i] ;
if (repValueIndex >= pieceItems.Count)
{
LogError($"CreateNewPiecesInvalid pieceId = {pieceId} repValueIndex={repValueIndex} validItemCount={pieceItems.Count}");
}
if (repValueIndex >= 0 && repValueIndex < pieceItems.Count)
{
var entity = pieceItems[repValueIndex];
CurrentPieceItems.Add(entity);
}
else
{
var entity = pieceItems[Random.Range(0, pieceItems.Count)];
CurrentPieceItems.Add(entity);
}
EventData.PieceDatas.Add(GetMeltPieceReal(i,ids[i],isPowerSet:true));
}
}
else
{
var validMeltPieces = await GetValidMeltPieceItem();
var hasPieceIds = new List<int>();
for (var i = 0; i < _pieceCount; ++i)
{
validMeltPieces = validMeltPieces.Where(item => !hasPieceIds.Contains(item.MeltId)).ToList();
validMeltPieces = DoFilterSecond(validMeltPieces,EventData.PieceDatas);
var entity = WeightedRandom(validMeltPieces);
hasPieceIds.Add(entity.MeltId);
// var entity = validMeltPieces.FirstOrDefault(item => item.MeltId == pieceId);
// var entities = validMeltPieces.Where(item => item.MeltId == pieceId).ToList();
// var entity = entities[Random.Range(0, entities.Count)];
if (ShouldBuildELog())
{
ELog($"CreateNewPiece -> {entity?.MeltId} {string.Join(",", entity?.PieceConfig ?? new List<int>())}");
}
// EventData.PieceItems.Add(entity);
CurrentPieceItems.Add(entity);
EventData.PieceDatas.Add(GetMeltPieceReal(i));
}
}
// validMeltPieces = GetValidMeltPieceItem();
// for (var i = 0; i < _pieceCount; ++i)
// {
// validMeltPieces = DoFilterSecond(validMeltPieces,EventData.PieceDatas);
//
// var pieceId = WeightedRandom(validMeltPieces);
// // var entity = validMeltPieces.FirstOrDefault(item => item.MeltId == pieceId);
//
// var entities = validMeltPieces.Where(item => item.MeltId == pieceId).ToList();
// var entity = entities[Random.Range(0, entities.Count)];
// ELog($"CreateNewPiece -> {entity?.MeltId} {string.Join(",",entity?.PieceConfig ?? new List<int>())}");
// // EventData.PieceItems.Add(entity);
// CurrentPieceItems.Add(entity);
// EventData.PieceDatas.Add(GetMeltPieceReal(i));
// }
}
//-
private PieceItem WeightedRandom(List<PieceItem> pieceItems)
{
// return UnityEngine.Random.Range(0, pieceItems.Count);
// var totalWeight = pieceItems.Sum(pieceItem => pieceItem.Weight);
var totalWeight = pieceItems.Sum(item => item.ComplexityWeight);
// double min = 0.0;
// double max = 100.0;
var random = new System.Random();
double randomValue = (random.NextDouble() * (totalWeight - 0));
// var randomValue = Random.Range(0f, totalWeight);
var currentWeight = 0F;
foreach (var pieceItem in pieceItems)
{
currentWeight += (float)pieceItem.ComplexityWeight;
if (randomValue < currentWeight)
return pieceItem;
}
var item101 = pieceItems.Find(item => item.MeltId == 101);
// 默认返回一个点
// return 101 ; // 理论上不会执行到这里
return item101;
}
private void CreateNewData()
{
ELog("CreateNewData-> ");
var limitedTime = (LimitedTime)_fishingEvent.TimeDefinition;
var startTime = GlobalUtils.TryParseDateTime(limitedTime.StartTime, ZZTimeHelper.UtcNow());
var endTime = GlobalUtils.TryParseDateTime(limitedTime.EndTime, ZZTimeHelper.UtcNow());
var ticketCount = GContext.container.Resolve<FishingEventData>().GetInitWelcomeGift(_fishingEvent.ID);
// var ticketCount = GContext.container.Resolve<FishingEventData>().GetInitWelcomeGift(_fishingEvent.ID);
EventData = new EventCubeMeltData
{
FirstOpen = true,
EventId = _fishingEvent.ID,
TicketCount = ticketCount,
StartTime = startTime,
EndTime = endTime,
IsFinished = false,
CurrentStagetId = 0,
CollectItems = new List<CollectItem>(),
// PieceItems = new List<PieceItem>(),
PieceDatas = new List<List<int>>(),
CollectRewardsId = new List<int>(),
InflationRate = GContext.container.Resolve<PlayerData>().InflationRate
};
GContext.container.Resolve<FishingEventData>().SaveTransitionData(EventData.EventId, EventData.TicketCount);
// GContext.container.Resolve<GuideDataCenter>().ClearGuide(nameof(GroupName.Block01));
}
#region Log
private static void LogError(object message)
{
Debug.LogError($"<color=red>EventCubeMeltManager => {message} </color>");
}
private static bool ShouldBuildELog()
{
#if UNITY_EDITOR
return EventCubeMeltLogPolicy.EnableELog;
#else
return false;
#endif
}
private static void ELog(object message)
{
#if UNITY_EDITOR
if (!EventCubeMeltLogPolicy.EnableELog) return;
Debug.Log($"<color=orange> EventCubeMeltManager => {message} </color>");
#endif
}
#endregion
#region
public bool CheckOpen()
{
//
if (EventData == null)
return false;
//
if (!IsTimeAllow())
return false;
return true;
}
public bool IsTimeAllow()
{
var now = ZZTimeHelper.UtcNow();
return now >= StartTime && now <= EndTime;
}
public TimeSpan GetRemainingTime()
{
if (EventData == null)
return TimeSpan.Zero;
return EndTime - ZZTimeHelper.UtcNow();
}
#endregion
public void OnSettle()
{
//throw new NotImplementedException();
ELog("OnSettle");
}
private void AddItem(int itemId, int count)
{
if (EventData?.CollectItems == null)
return;
var item = EventData.CollectItems.FirstOrDefault(x => x.ItemId == itemId);
if (item != null)
{
item.Count += count;
if (item.Count >= item.MaxCount)
{
item.Count = item.MaxCount;
}
}
}
//- [0,1]
public float GetCollectProgress()
{
var iCount = EventData.CollectItems.Count;
var iMaxCount = 0;
var iCollCount = 0;
// for (var i = 0; i < iCount; ++i)
foreach (var item in EventData.CollectItems)
{
iCollCount += item.Count;
iMaxCount += item.MaxCount;
}
return iCollCount * 1f / iMaxCount;
}
// 获取数据
public async Task SpawnNewPieceData()
{
}
public async Task SpawnNewPiece(int index,int clearCount)
{
ELog("SpawnNewPiece-> ");
var validMeltPieces = await GetValidNewPiece(index,clearCount);
var pieceItem = WeightedRandom(validMeltPieces);
if (pieceItem != null && ShouldBuildELog())
{
ELog(
$"SpawnNewPiece slotIndex={index} meltId={pieceItem.MeltId} row={pieceItem?.Row} col={pieceItem?.Col} complexity={pieceItem?.Complexity} complexityWeight={pieceItem.ComplexityWeight} config={string.Join(",", pieceItem.PieceConfig)}");
}
// var entities = validMeltPieces.Where(item => item.MeltId == pieceId).ToList();
// var entity = entities[Random.Range(0, entities.Count)];
// var entity = validMeltPieces.Find(item => item.MeltId == pieceId);
// ELog($"TCM: SpawnNewPiece -> {index} {pieceId} ");
// EventData.PieceItems[index] = entity;
// await Task.Run(() =>
{
CurrentPieceItems[index] = pieceItem;
EventData.PieceDatas[index] = GetMeltPieceReal(index);
SaveData();
}
ELog("SpawnNewPiece-> Finished-> ");
}
private async Task<List<PieceItem>> GetValidNewPiece(int index,int clearCount)
{
var validMeltPieces = await GetValidMeltPieceItem(clearCount);
var lastMeltPiece = EventData.PieceDatas[index];
// 和上一个不同
var validMeltPieces1 = DoFilterFirst(validMeltPieces,lastMeltPiece);
if (validMeltPieces1.Count <= 0)
{
return validMeltPieces;
}
//- 和全部不同
var validMeltPieces2 = DoFilterSecond(validMeltPieces1, EventData.PieceDatas);
if (validMeltPieces2.Count <= 0)
{
return validMeltPieces1;
}
return validMeltPieces2;
}
private List<PieceItem> DoFilterFirst(List<PieceItem> pieceItems, List<int> ints)
{
var checkInts = ints.Select(value => value == 0 ? 0 : 99);
return pieceItems.Where(p => !p.PieceConfig.SequenceEqual(checkInts)).ToList();
}
private List<PieceItem> DoFilterSecond(List<PieceItem> pieceItems, List<List<int>> eventDataPieceDatas)
{
return pieceItems?.Where(p => !eventDataPieceDatas?.Any(target =>
{
var checkInts = target.Select(value => value == 0 ? 0 : 99);
return p.PieceConfig.SequenceEqual(checkInts);
}) ?? true)
.ToList() ?? new List<PieceItem>();
}
// private List<PieceItem> GetValidMeltPieceItemByInitItem(List<int> pieceId, List<int> repValues)
// {
// // throw new NotImplementedException();
// var list = new List<PieceItem>();
// var grid = ConvertListIntToShape(EventData.BoardData,_boardDimension.x ,_boardDimension.y);
//
// foreach (var piece in EventCubeMeltPieceItems)
// {
// if (CanPlace(grid, ConvertListIntToShape(piece.PieceConfig,_pieceDimension.x ,_pieceDimension.y),piece.MeltId,out var p ))
// {
// piece.Complexity = p.Complexity;
// list.Add(piece);
// }
// }
// return list;
// }
public static double GaussianWeight(float x, double center = 0.5, double sigma = 1.0)
{
var diff = x - center;
var exponent = -(diff * diff) / (2 * sigma * sigma);
return Math.Exp(exponent);
}
//[0,1]-> [1,100]
public static float CosineWeight(float x, float center = 0.5f, double frequency = 2.0 * Math.PI)
{
var scaledX = (x - center) * frequency;
var cosineWeight = (float)(Math.Cos(scaledX) + 1.0F) / 2.0F;
return cosineWeight * 99.0F + 1.0F;
}
private async Task<List<PieceItem>> GetValidMeltPieceItem(int clearCount = 0)
{
var list = new List<PieceItem>();
// this.BoardViewSize.x
var grid = ConvertListIntToShape(EventData.BoardData,EventData.BoardViewSize.x ,EventData.BoardViewSize.y);
ELog($"GetValidMeltPieceItem-> Count = {EventCubeMeltPieceItems.Count}");
var weightDifficultyParam = EventCubeMeltStageData.WeightDifficultyParam;
var wdParam1 = weightDifficultyParam[0];
var wdParam2 = weightDifficultyParam[1];
var wdParam3 = weightDifficultyParam[2];
var priorityList1 = EventCubeMeltPieceItems.Where(item => item.MeltId > 300).ToList();
await Task.Run(() =>
{
foreach (var piece in priorityList1)
{
if (CanPlace(grid,
ConvertListIntToShape(piece.PieceConfig, _pieceDimension.x, _pieceDimension.y),
piece.MeltId,
out var p))
{
piece.Complexity = p.Complexity;
piece.ComplexityWeight = piece.Weight +
(float)wdParam1 * Math.Exp(wdParam2 * p.Complexity + wdParam3 * clearCount);
piece.Row = p.Row;
piece.Col = p.Col;
list.Add(piece);
}
} //一次性返回
});
//
if (list.Count <= 0)
{
if (ShouldBuildELog())
{
ELog($"GetValidMeltPieceItem priority1Empty boardData={string.Join(",", EventData.BoardData)}");
}
// list.Add(EventCubeMeltPieceItems.Find(item => item.MeltId == 101));
var priorityList2 = EventCubeMeltPieceItems.Where(item => item.MeltId <= 300).ToList();
// foreach (var piece in priorityList2)
// {
// if (CanPlace(grid, ConvertListIntToShape(piece.PieceConfig,_pieceDimension.x ,_pieceDimension.y),piece.MeltId,out var p))
// {
// piece.Complexity = p.Complexity;
// piece.ComplexityWeight = piece.Weight + (float) wdParam1 * Math.Exp(wdParam2 * p.Complexity + wdParam3 * clearCount);
// piece.Row = p.Row;
// piece.Col = p.Col;
// list.Add(piece);
// }
// }
await Task.Run(() =>
{
// var tmp = new List<PieceOut>(); //线程内临时列表
foreach (var piece in priorityList2)
{
if (CanPlace(grid, ConvertListIntToShape(piece.PieceConfig, _pieceDimension.x, _pieceDimension.y),
piece.MeltId,
out var p))
{
piece.Complexity = p.Complexity;
piece.ComplexityWeight = piece.Weight +
(float)wdParam1 * Math.Exp(wdParam2 * p.Complexity + wdParam3 * clearCount);
piece.Row = p.Row;
piece.Col = p.Col;
list.Add(piece);
}
} //一次性返回
});
}
ELog($"ClearCount count={clearCount}");
// StringBuilder sb;
#if UNITY_EDITOR
var sb = new StringBuilder();
foreach (var item in list)
{
sb.Append(item.MeltId + $"({item.Complexity:F3} , {item.ComplexityWeight:F3}) " );
}
ELog($"TCM:GetValidMeltPieceItem-> {sb}");
#endif
return list;
}
private int[,] ConvertListIntToShape(List<int> listInt,int gridW,int gridH)
{
// var width = _pieceDimension.x;
// var height = _pieceDimension.y;
var width = gridW;
var height = gridH;
var shape = new int[height,width];
for (var row = 0; row < height; row++)
{
for (var col = 0; col < width; col++)
{
shape[row, col] = listInt[row * width + col];
}
}
return shape;
}
// private int[,] ConvertToShape(EventCubeMeltPiece piece)
// {
// var width = _pieceDimension.x;
// var height = _pieceDimension.y;
//
// var shape = new int[height,width];
// var pieceData = piece.PieceConfig[0];
// for (var row = 0; row < height; row++)
// {
// for (var col = 0; col < width; col++)
// {
// shape[row, col] = pieceData[row * width + col];
// }
// }
// return shape;
// }
// public void PrintShape(int[,] grid, string tag )
// {
// var sb = new StringBuilder();
// sb.Append(tag);
// var height = grid.GetLength(0);
// var width = grid.GetLength(1);
// for (var i = 0; i < height; i++)
// {
// sb.Append("<color=red>");
// for (var j = 0; j < width; j++)
// {
// sb.Append((int)grid[i,j]);
// if (j < width - 1)
// sb.Append(", ");
// }
// sb.Append("</color> \n");
// }
// Debug.Log(sb.ToString());
// }
// 方形的
// private bool CanPlaceDown(int[,] grid, int [,] shape)
// {
// ELog("CanPlaceDown -> ");
// var gridSize = grid.GetLength(0);
// var shapeSize = shape.GetLength(0);
// if (shapeSize > gridSize )
// return false;
//
// List<(int row, int col)> shapePositions = new();
// for (int i = 0; i < shapeSize; i++)
// {
// for (int j = 0; j < shapeSize; j++)
// {
// if (shape[i, j] != 0 )
// {
// shapePositions.Add((i, j));
// }
// }
// }
// // 如果形状是空的,总是可以放入
// if (shapePositions.Count == 0)
// return true;
//
// for (var gridRow = 0; gridRow < gridSize; gridRow++)
// {
// for (var gridCol = 0; gridCol < gridSize; gridCol++)
// {
// // 检查是否可以把形状放在某个位置,使得所有有效格子都在网格内且为空
// if (CanPlaceShapeAtPosition(grid, shapePositions, gridRow, gridCol))
// {
// return true;
// }
// }
// }
// return false;
// }
private bool CanPlace(int[,] grid, int[,] shape, int pieceId,out ShapePlacement bestPlacementResult)
{
ELog($" CanPlace -> {pieceId}");
var gridRow = grid.GetLength(0);
var gridCol = grid.GetLength(1);
var shapeRow = shape.GetLength(0);
var shapeCol = shape.GetLength(1);
// 收集形状中所有有效格子的位置
var cells = new List<(int r, int c)>(shapeRow * shapeCol);
int minR = int.MaxValue, maxR = int.MinValue;
int minC = int.MaxValue, maxC = int.MinValue;
for (int r = 0; r < shapeRow; r++)
{
for (int c = 0; c < shapeCol; c++)
{
if (shape[r, c] != 0)
{
cells.Add((r, c));
if (r < minR) minR = r;
if (r > maxR) maxR = r;
if (c < minC) minC = c;
if (c > maxC) maxC = c;
}
}
}
bestPlacementResult = new ShapePlacement()
{
Id = pieceId,
Shape = (int[,])shape.Clone(),
Col = int.MinValue,
Row = int.MinValue,
Weight = 0,
Complexity = float.MaxValue,
};
// 若形状没有有效格子,视为可放置
if (cells.Count == 0)
{
bestPlacementResult.Col = 0;
bestPlacementResult.Row = 0;
return true;
}
// 有效格子全部进网格的必要偏移范围:
// 0 <= r + dy <= gr-1 对所有有效 r
// 0 <= c + dx <= gc-1 对所有有效 c
var minDy = -minR;
var maxDy = (gridRow - 1) - maxR;
var minDx = -minC;
var maxDx = (gridCol - 1) - maxC;
// 无可行偏移的快速剪枝
if (minDy > maxDy || minDx > maxDx)
{
return false;
}
for (int offY = minDy; offY <= maxDy; offY++)
{
for (int offX = minDx; offX <= maxDx; offX++)
{
bool ok = true;
// 检查所有有效格子在该偏移下是否都落在空位(0)
for (int i = 0; i < cells.Count; i++)
{
var cell = cells[i];
int rr = cell.r + offY;
int cc = cell.c + offX;
// 这里不需要再做边界判断(已由范围剪枝保证)
if (grid[rr, cc] != 0)
{
ok = false;
break;
}
}
if (ok)
{
var p = CreateNewShapePlacement(offY,offX,shape,grid);
p.Id = pieceId;
// ELog($" CanPlace -> p = {p} best = {bestPlacementResult}");
if (p.Complexity < bestPlacementResult.Complexity)
bestPlacementResult = p;
}
}
}
// ELog($" CanPlace -> {pieceId} bestPlacementResult = {bestPlacementResult}");
if (bestPlacementResult.Complexity < float.MaxValue)
{
// ELog($" CanPlace -> {pieceId} bestPlacementResult = {bestPlacementResult}");
return true;
}
// dx = 0; dy = 0;
return false;
}
private ShapePlacement CreateNewShapePlacement(int row, int col,int[,] shape,int [,] grid)
{
var simulatedBoard = SimulatePlacement(grid,shape, row, col);
var pf1 = Calculate(grid);
var pf = Calculate(simulatedBoard);
return new ShapePlacement()
{
Row = row,
Col = col,
Shape = shape,
Weight = 1,
Complexity = pf - pf1
};
}
public static float Calculate(int[,] matrix)
{
if (matrix == null)
return 0;
int height = matrix.GetLength(0);
int width = matrix.GetLength(1);
// 创建带边框的矩阵便于计算
int[,] paddedMatrix = new int[height + 2, width + 2];
// 复制原矩阵到中心
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
paddedMatrix[i + 1, j + 1] = matrix[i, j];
}
}
// 计算边界长度相邻0-1边的数量
int boundaryEdges = 0;
for (int i = 1; i <= height; i++)
{
for (int j = 1; j <= width; j++)
{
if (paddedMatrix[i, j] != 0)
{
// 检查四个邻居
if (paddedMatrix[i - 1, j] == 0) boundaryEdges++; // 上
if (paddedMatrix[i + 1, j] == 0) boundaryEdges++; // 下
if (paddedMatrix[i, j - 1] == 0) boundaryEdges++; // 左
if (paddedMatrix[i, j + 1] == 0) boundaryEdges++; // 右
}
}
}
// 计算面积
int area = 0;
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
if (matrix[i, j] != 0)
area++;
}
}
var p = (float)Math.Sqrt(area)* 4F;
// var x = Math.Exp(p);
// 边界复杂度 = 边界长度 / 面积
return area > 0 ? (float)boundaryEdges / p : 0.0F;
}
private int[,] SimulatePlacement(int[,] board, int[,] shape, int row, int col)
{
// 创建棋盘的副本
int[,] simulatedBoard = (int[,])board.Clone();
var height = shape.GetLength(0);
var width = shape.GetLength(1);
var boardH = simulatedBoard.GetLength(0);
var boardW = simulatedBoard.GetLength(1);
// 放置形状
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
var rowI = row + i;
var colJ = col + j;
if (rowI < 0 || rowI >= boardH)
continue;
if (colJ < 0 || colJ >= boardW)
continue;
if (shape[i, j] != 0)
{
simulatedBoard[rowI, colJ] = 1; // 模拟形状,都放置成 1 先
}
}
}
return simulatedBoard;
}
private static bool CanPlaceShapeAtPosition(int[,] grid, List<(int row, int col)> validCells, int referenceRow, int referenceCol)
{
var gridSize = grid.GetLength(0);
// 我们尝试把形状的某个有效格子对齐到网格的(referenceRow, referenceCol)
// 然后检查其他有效格子是否都在网格内且为空
// 对第一个有效格子作为对齐点
var firstCell = validCells[0];
// 计算偏移量:如果要把这个有效格子放在(referenceRow, referenceCol)
// 那么形状的左上角应该在:
int startRow = referenceRow - firstCell.row;
int startCol = referenceCol - firstCell.col;
// 检查所有有效格子
foreach (var (shapeRow, shapeCol) in validCells)
{
int gridRow = startRow + shapeRow;
int gridCol = startCol + shapeCol;
// 检查是否在网格内
if (gridRow < 0 || gridRow >= gridSize || gridCol < 0 || gridCol >= gridSize)
{
return false;
}
// 检查网格位置是否为空
if (grid[gridRow, gridCol] != 0)
{
return false;
}
}
return true;
}
// 调试用,看看
public static List<(int row, int col)> FindAllPositions(int[,] grid, int[,] shape)
{
int M = grid.GetLength(0);
int N = shape.GetLength(0);
List<(int row, int col)> positions = new List<(int, int)>();
if (N > M) return positions;
// 预计算形状的非空位置
List<(int row, int col)> shapePositions = new List<(int, int)>();
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
if (shape[i, j] != 0)
{
shapePositions.Add((i, j));
}
}
}
// 遍历所有可能的放置位置
for (int i = 0; i <= M - N; i++)
{
for (int j = 0; j <= M - N; j++)
{
bool canPlace = true;
foreach (var (si, sj) in shapePositions)
{
int gi = i + si;
int gj = j + sj;
if (grid[gi, gj] != 0)
{
canPlace = false;
break;
}
}
if (canPlace)
{
positions.Add((i, j));
}
}
}
return positions;
}
public List<int> GetMeltPieceReal(int index,int isRepValue = 1,bool isPowerSet = false)
{
var pieceItem = CurrentPieceItems[index];
var meltPiece = EventCubeMeltPieces.FirstOrDefault(meltPiece => meltPiece.ID == pieceItem.MeltId );
ELog($"GetMeltPieceReal-> 12 {index} {meltPiece.ID} ,{meltPiece?.PieceConfig} {EventCubeMeltPieces.Count}");
var prop = EventCubeMeltCollectionData.CollectingItemProb;
var meltPieceConfig = pieceItem.PieceConfig;
var rate = meltPiece?.DoubleItemProb ?? 0;
var num = 1;
if (isPowerSet)
{
prop = new List<float> { 1 };
rate = 0;
}
if (rate > 0)
{
var r = Random.value; // [0,1)
if (r < rate)
{
num = 2;
}
}
var rand = GetRepValue();
var collectIds = GetCollectionIds();
// var randWeight = GetRepValuesWithWeight(rand);
// var thePieceData = (isRepValue == 0) ?meltPieceConfig : SlotsGenerator.GenerateSlots(num,prop,meltPieceConfig, rand);
var thePieceData2 = (isRepValue == 0) ?meltPieceConfig : SlotsGenerator.GenerateSlots2(num,prop,meltPieceConfig,rand,collectIds);
return thePieceData2;
//return meltPieceConfig;
}
public List<int> GetMeltPieceData(int index)
{
var pieceData = EventData.PieceDatas.ElementAtOrDefault(index);
return pieceData;
}
private List<int> GetCollectionIds()
{
var set = new HashSet<int>();
var collectionItems = GetCollectionItems();
foreach (var kv in collectionItems)
{
for (var i = 0; i < kv.Value.RequiredCount; ++i)
{
set.Add(kv.Key);
}
}
return set.ToList();
}
// 返回可替换的有效材料值
private List<int> GetRepValue()
{
var set = new HashSet<int>();
var collectionItems = GetCollectionItems();
foreach (var kv in collectionItems)
{
for (var i = 0; i < kv.Value.RequiredCount; ++i)
{
set.Add(kv.Key);
}
}
//
// 删除已经收集完的Item
var hasCollectItems = EventData.CollectItems;
foreach (var item in hasCollectItems.Where(item => item.Count >= item.MaxCount))
{
set.Remove(item.ItemId);
}
if (ShouldBuildELog())
{
ELog($"GetRepValue candidates={string.Join(",", set)}");
}
return set.ToList();
}
public void UpdateCurrentStage()
{
var isFirstLoop = EventData.Cycle == 0 ;
var stageList = isFirstLoop ? EventCubeMeltMainData?.StageFirstList : EventCubeMeltMainData?.StageLoopList ?? new List<int>();
var stageId = stageList?.ElementAtOrDefault(EventData.CurrentStagetId);
ELog($"UpdateCurrentStage -> {EventData.CurrentStagetId}, {stageId}");
EventCubeMeltStageData = _tables.TbEventCubeMeltStage.DataList.FirstOrDefault(data => data.ID == stageId);
EventCubeMeltCollectionData = _tables.TbEventCubeMeltCollection.DataList.FirstOrDefault(data => data.ID == stageId);
EventCubeMeltConfig = EventCubeMeltStageData?.StageConfig ?? new List<List<int>>();
EventStageList = stageList;
StageCount = EventStageList?.Count ?? 0;
var boardSize = EventCubeMeltStageData?.BoardSize;
if (boardSize == null)
{
LogError("Error Board No BoardSize ");
boardSize = new List<int>{8,8};
}
// BoardViewSize = new Vector2Int(boardSize[0], boardSize[1]);
}
private void UpdateNewCollect()
{
EventData.CollectItems.Clear();
var items = GetCollectionItems();
foreach (var kv in items)
{
EventData.CollectItems.Add(new CollectItem
{
ItemId = kv.Key,
ItemTrueId = kv.Value.TrueId,
Count = 0,
MaxCount = kv.Value.RequiredCount
});
}
}
public string GetCollectIconByType(int typeId)
{
var item = EventCubeMeltItems.FirstOrDefault(elem => elem.Type == typeId);
return item != null ? item.Icon : string.Empty;
}
public string GetCollectIconById(int typeId)
{
var item = EventCubeMeltItems.FirstOrDefault(elem => elem.ID == typeId);
return item != null ? item.Icon : string.Empty;
}
// 收集
public void AddCollect(Dictionary<int,int> values)
{
if (values is not { Count: > 0 })
{
return;
}
if (ShouldBuildELog())
{
var valueStrings = string.Join(", ", values.Select(kv => $"{kv.Key}: {kv.Value}"));
ELog($"LCM-> AddCollect -> {valueStrings}");
}
foreach (var kv in values)
{
AddItem(kv.Key, kv.Value);
}
}
public bool IsThisCollectFinished()
{
var items = EventData.CollectItems;
var isFinish = items.All(item => item.Count >= item.MaxCount);
return isFinish;
}
public bool IsGetStageReward()
{
var isGet = EventData.CollectRewardsId.Contains(EventData.CurrentStagetId);
return isGet;
}
public bool IsGetFinalReward()
{
return EventData.IsFinalRewardGet;
}
private async Task UpdateNextBoardAndPieces()
{
ELog("UpdateNextBoardAndPieces()");
CreateNewBoard();
await CreateNewPieces();
UpdateNewCollect();
SaveData();
}
public bool IsFinishAllStage() => EventData.CurrentStagetId >= StageCount - 1;
public async void UpdateToNextStage()
{
EventData.CurrentStagetId++;
if (EventData.CurrentStagetId > StageCount -1)
{
OnFinish();
return;
}
UpdateCurrentStage();
await UpdateNextBoardAndPieces();
GContext.Publish(new EventCubeMeltForNextStage());
}
public void GenerateNextStageData()
{
EventData.CurrentStagetId++;
if (EventData.CurrentStagetId > StageCount -1)
{
// ClearData();
// Init();
GenerateNewLoopFirstData();
}
UpdateCurrentStage();
_ = UpdateNextBoardAndPieces();
}
private void GenerateNewLoopFirstData()
{
var tickCount = EventData.TicketCount;
var cycle = EventData.Cycle;
ClearData();
Init();
EventData.TicketCount = tickCount;
EventData.FirstOpen = false;
EventData.Cycle = cycle + 1;
GContext.container.Resolve<FishingEventData>().SaveTransitionData(EventData.EventId, EventData.TicketCount);
SaveData();
}
public bool PlayGetStageReward()
{
ELog("AddStageRewards");
var dropId = EventCubeMeltCollectionData.CollectingReward;
var playerItemData = GContext.container.Resolve<PlayerItemData>();
var changeSource = new ChangeSource(EventData.EventId, "Event_Minigame1", "Event_Minigame1_Block", "StageReward");
playerItemData.AddItemByDropLureInflation(EventData.InflationRate,dropId,changeSource);
GContext.Publish(new ShowData());
EventData.CollectRewardsId.Add(EventData.CurrentStagetId);
SaveData();
return true;
}
// public bool PlayGetFinalRewards()
// {
// ELog("PlayGetFinalRewards-> ");
//
// var dropId = EventCubeMeltMainData.FinalReward;
// var playerItemData = GContext.container.Resolve<PlayerItemData>();
// var changeSource = new ChangeSource(EventData.EventId, "Event_Minigame1", "Event_Minigame1_Block", "StageReward");
// playerItemData.AddItemByDropLureInflation(null, dropId,changeSource);
// GContext.Publish(new ShowData());
//
// EventData.IsFinalRewardGet = true;
// SaveData();
// return true;
// }
public void OnFinish()
{
ELog("OnFinsish()");
ReOpen();
}
public void ReOpen()
{
GenerateNewLoopFirstData();
GContext.Publish(new EventCubemeltExitAct());
}
public void UpdateGridData(List<int> gridData)
{
EventData.BoardData = gridData;
SaveData();
}
//-
// private Vector2Int _boardDimension;
private Vector2Int _pieceDimension;
// public void SetBoardDimension(Vector2Int dimension)
// {
// _boardDimension = dimension;
// }
public void SetPieceDimension(Vector2Int dimension)
{
_pieceDimension = dimension;
}
private EventCubeMeltData PrevData { get; set; }
private EventCubeMeltData NextData { get; set; }
//-
private List<int> PrevBoardData { get; set; }
public List<List<int>> PrevPieceDatas { set; get; }
private List<int> CurrentBoardData { get; set; }
public List<List<int>> CurrentPieceDatas { set; get; }
// -当前的索引
public int GuideIndex { get; set; }
public void SaveDataForPrev()
{
// PrevData = EventData.ShallowClone();
//ELog($"SaveDataForPrev()-> {JsonConvert.SerializeObject(PrevData)}");
#if UNITY_EDITOR
PrevBoardData = EventData.BoardData.ToList();
PrevPieceDatas = EventData.PieceDatas.Select(innerList => new List<int>(innerList)).ToList();
#endif
}
public void SaveDataForNow()
{
#if UNITY_EDITOR
CurrentBoardData = EventData.BoardData.ToList();
CurrentPieceDatas = EventData.PieceDatas.Select(innerList => new List<int>(innerList)).ToList();
SaveData();
#endif
}
public void RestoreData()
{
EventData.BoardData = CurrentBoardData.ToList();
EventData.PieceDatas = CurrentPieceDatas.Select(innerList => new List<int>(innerList)).ToList();
SaveData();
}
public void LoadPrevData()
{
EventData.BoardData = PrevBoardData.ToList();
EventData.PieceDatas = PrevPieceDatas.Select(innerList => new List<int>(innerList)).ToList();
if (ShouldBuildELog())
{
ELog($"LoadPrevData()-> {JsonConvert.SerializeObject(EventData)}");
}
SaveData();
}
public bool IsUnCollectValue(int valueType)
{
var typeItem = EventCubeMeltItems.FirstOrDefault(elem => elem.Type == valueType);
var param = typeItem?.Param ?? 0;
return param > 1;
}
public List<int> ReplaceValue(int valueType)
{
var typeItem = EventCubeMeltItems.FirstOrDefault(elem => elem.Type == valueType);
var param = typeItem?.Param ?? 0;
if (param <= 1)
{
var values = new List<int> { valueType };
if (ShouldBuildELog())
{
ELog($"LCM-> ReplaceValue -> {valueType} -> {string.Join(", ", values)}");
}
return values;
}
// else
// {
// return new List<int>();
// }
var list = new List<int>();
var validList = GetRepValue();
for (var i = 0; i < param; i++)
{
var va = validList[Random.Range(0, validList.Count)];
list.Add(va);
}
if (ShouldBuildELog())
{
ELog($"LCM-> ReplaceValue -> {valueType} -> {string.Join(", ", list)}");
}
return list;
}
//-
public List<List<int>> GetBombValues(List<int> bombValues)
{
var p = new List<List<int>>();
foreach (var bombValue in bombValues)
{
p.Add(ReplaceValue(bombValue));
}
return p;
}
public void JumpToStage(int newStep)
{
// // var newStep = newDisStep - 1;
ELog($"JumpToStage -> {newStep }");
if (newStep < 0)
return;
EventData.CurrentStagetId = newStep - 1;
GContext.Publish(new EventCubeMeltStageFinish());
UpdateToNextStage();
// EventData.CurrentStagetId = newStep;
// if (EventData.CurrentStagetId > StageCount -1)
// {
// OnFinish();
// return;
// }
// //-
// EventData.IsFinished = false;
// UpdateCurrentStage();
// UpdateNextBoardAndPieces();
// GContext.Publish(new EventCubeMeltForNextStage());
}
//-检查当前管卡是否已经完
public bool IsOverStage()
{
return EventData.CurrentStagetId >= StageCount;
}
public void FixOverStage()
{
if (IsOverStage())
{
EventData.CurrentStagetId = StageCount - 1;
}
var isFinishThisStage = IsThisCollectFinished();
var isGetStageReward = IsGetStageReward();
if (EventData.CurrentStagetId < StageCount - 1)
{
if (isFinishThisStage && isGetStageReward)
{
GenerateNextStageData();
}
}
else
{
// var isFinalGet = IsGetFinalReward();
if (isFinishThisStage && isGetStageReward)
{
GenerateNextStageData();
}
}
}
public bool CheckCollectFinish(List<int> listItems)
{
var items = EventData.CollectItems;
return items.Any(item => listItems.Contains(item.ItemId) && item.Count == item.MaxCount);
}
public bool CheckBombFinsh(List<int> listBomb)
{
return true;
}
public bool IsInGuideAnim()
{
return EventData?.IsInGuide ?? false ;
}
public void SetIsInGuideAnim(bool isInGuide)
{
// IsInGuide = isInGuide;
EventData.IsInGuide = isInGuide;
SaveData();
}
public int GetFinalReward()
{
ELog("GetFinalReward");
var finalStage = StageCount - 1;
// var isFirstLoop = EventData.Cycle == 0 ;
// var stageList = isFirstLoop ? EventCubeMeltMainData?.StageFirstList : EventCubeMeltMainData?.StageLoopList;
// var stageId = stageList?.ElementAtOrDefault(finalStage);
var stageId = EventStageList?.ElementAtOrDefault(finalStage);
var cubeMeltData = _tables.TbEventCubeMeltCollection.DataList.FirstOrDefault(data => data.ID == stageId);
return cubeMeltData?.CollectingReward?? 0;
}
}