Files
ft/Client/Assets/Scripts/MatchGame/MatchGameManager.cs
2026-06-29 21:18:33 +08:00

498 lines
15 KiB
C#

using asap.core;
using cfg;
using GameCore;
using LitJson;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class MatchGameData
{
public int eventID;
public int index;
public int vip;
public float inflation;
public int seed;
public List<int> isOpenedList = new List<int>();
//连续翻开不同的次数
public int openCount;
//兔子交换记录,-1 表示无交换
public int swapFrom = -1;
public int swapTo = -1;
public int swapFrom2 = -1;
public int swapTo2 = -1;
public int tokenConsumed;
}
public enum FlipResult
{
// InsufficientTokens,
FirstHatFlipped,
NoMatch,
Match,
}
public class EventMatchGameManager
{
public string EventMatchGameDataKey => "EventMatchGameDataKey";
public int ItemSubType => 3;
public int ItemType => 6;
int EventType => 4;
int EventSubType => 13;
Tables tables;
FishingEventData fishingEventData;
TbFishingEvent tbFishingEvent;
TbFishingEventCycleItem tbCycleItem;
TbEventMatchInit tbEventMatchInit;
public EventMatchGameManager()
{
tables = GContext.container.Resolve<Tables>();
fishingEventData = GContext.container.Resolve<FishingEventData>();
tbFishingEvent = tables.TbFishingEvent;
tbCycleItem = tables.TbFishingEventCycleItem;
tbEventMatchInit = tables.TbEventMatchInit;
}
public MatchGameData GetEventData()
{
var matchGameData = new MatchGameData();
string data = PlayFabMgr.Instance.GetLocalData(EventMatchGameDataKey);
if (!string.IsNullOrEmpty(data))
{
try
{
matchGameData = Newtonsoft.Json.JsonConvert.DeserializeObject<MatchGameData>(data);
if (matchGameData.vip > 10)
{
matchGameData.vip = 10;
}
}
catch (Exception e)
{
Debug.LogError(e);
matchGameData = new MatchGameData();
}
}
return matchGameData;
}
public MatchGameData CheckEventData()
{
MatchGameData matchGameData = GetEventData();
FishingEvent tr = GetEvent();
if (tr == null)
{
return null;
}
else if (matchGameData.eventID != tr.ID)
{
FishingEventCycleItem cycleItem = tbCycleItem.GetOrDefault(tr.RedirectID);
matchGameData = new MatchGameData();
matchGameData.eventID = tr.ID;
matchGameData.inflation = GContext.container.Resolve<PlayerData>().InflationRate;
matchGameData.seed = new System.Random().Next();
matchGameData.index = 0;
matchGameData.vip = GContext.container.Resolve<PlayerData>().PriceLv;
if (matchGameData.vip > 10)
{
matchGameData.vip = 10;
}
SetTokens(tr.ID, cycleItem.WelcomeGift);
SaveData(matchGameData);
}
return matchGameData;
}
public bool CheckOpen()
{
var matchGameData = CheckEventData();
if (matchGameData == null || matchGameData.eventID == 0)
{
return false;
}
FishingEvent fishingEvent = tables.TbFishingEvent.GetOrDefault(matchGameData.eventID);
if (fishingEvent == null)
{
return false;
}
LimitedTime limitedTime = fishingEvent.TimeDefinition as LimitedTime;
var startTime = DateTime.Parse(limitedTime.StartTime);
var endTime = DateTime.Parse(limitedTime.EndTime);
var curTime = ZZTimeHelper.UtcNow();
if (curTime < startTime || curTime > endTime)
{
return false;
}
return true;
}
FishingEvent GetEvent()
{
return fishingEventData.GetEventByTypeAndSubType(EventType, EventSubType);
}
#region Tokens
public void AddTokens(int subType, int count)
{
if (subType == ItemSubType)
{
FishingEvent tr = GetEvent();
if (tr != null)
{
int tokens = GetTokenCount(tr.ID);
tokens += count;
SetTokens(tr.ID, tokens);
}
}
}
void SetTokens(int eventID, int count)
{
fishingEventData.SaveTransitionData(eventID, count);
}
public void RemoveTokens(int eventID, int count)
{
int tokens = GetTokenCount(eventID);
tokens -= count;
SetTokens(eventID, tokens);
}
public int GetTokenCount()
{
FishingEvent tr = GetEvent();
if (tr != null)
{
return GetTokenCount(tr.ID);
}
return 0;
}
public int GetTokenCount(int eventID)
{
return fishingEventData.GetTransitionDataCount(eventID);
}
#endregion Tokens
public FlipResult AddProgress(int eventID, MatchGameData data, List<int> eventSpecialItemList, int opened, List<int> board, out List<int> openPos)
{
openPos = new List<int>();
FlipResult idOpened = FlipResult.FirstHatFlipped;
RemoveTokens(eventID, 1);
data.tokenConsumed++;
int count = data.isOpenedList.Count;
if (count % 2 == 0)
{
data.isOpenedList.Add(opened);
openPos.Add(opened);
}
else
{
//做对比
int curOpened = data.isOpenedList[count - 1];
//获取 curOpened 的数据,对比 opened 的数据
int curId = board[curOpened];
int nextId = board[opened];
openPos.Add(curOpened);
openPos.Add(opened);
#if AGG
EventMatchInit matchInit = GetMatchInit(eventID);
if (matchInit != null)
{
EventMatchStage matchStage = GetMatchStage(data, matchInit);
int countR1 = matchInit.StageListRound1.Count;
int roundId = data.index < countR1 ? 1 : (data.index - countR1) / matchInit.StageListRound2.Count + 2;
using (var e = GEvent.GameEvent("event_match"))
{
e.AddContent("event_id", eventID)
.AddContent("round_id", roundId)
.AddContent("stage_id", matchStage.ID)
.AddContent("item_id1", curId)
.AddContent("item_id2", nextId);
}
}
#endif
if (curId == nextId)
{
//成功
data.isOpenedList.Add(opened);
data.openCount = 0;
idOpened = FlipResult.Match;
if (eventSpecialItemList.Contains(curId))
{
var spOpenPos = GetSpItemOpen(data, board);
if (spOpenPos.Count > 0)
{
data.isOpenedList.AddRange(spOpenPos);
openPos.AddRange(spOpenPos);
}
}
}
else
{
//失败
data.isOpenedList.RemoveAt(count - 1);
data.openCount++;
idOpened = FlipResult.NoMatch;
if (data.openCount >= 4)
{
var tipsPos = GetTipsItemOpen(data, board);
if (tipsPos.Count > 0)
{
openPos.AddRange(tipsPos);
}
data.openCount = 0;
}
}
}
GameDebug.Log("[EventMatch] ItemID " + string.Join(',', board) + " " + string.Join(',', data.isOpenedList));
SaveData(data);
return idOpened;
}
List<int> GetSpItemOpen(MatchGameData data, List<int> board)
{
List<int> openPos = new List<int>();
Dictionary<int, int> boardDic = new Dictionary<int, int>();
for (int i = 0; i < board.Count; i++)
{
if (!data.isOpenedList.Contains(i))
{
boardDic.Add(i, board[i]);
}
}
if (boardDic.Count <= 4)
{
openPos.AddRange(boardDic.Keys);
}
else
{
System.Random random = new System.Random();
// 执行两次随机选择
SelectAndRemoveGroup(boardDic, openPos, random);
SelectAndRemoveGroup(boardDic, openPos, random);
}
return openPos;
}
List<int> GetTipsItemOpen(MatchGameData data, List<int> board)
{
List<int> openPos = new List<int>();
Dictionary<int, int> dict = new Dictionary<int, int>();
for (int i = 0; i < board.Count; i++)
{
if (!data.isOpenedList.Contains(i))
{
dict.Add(i, board[i]);
}
}
System.Random random = new System.Random();
var keys = dict.Keys.ToList();
int key = keys[random.Next(keys.Count)];
int value = dict[key];
// 找到所有具有相同值的键
return dict.Where(kv => kv.Value == value).Select(kv => kv.Key).ToList();
}
void SelectAndRemoveGroup(Dictionary<int, int> dict, List<int> result, System.Random random)
{
var keys = dict.Keys.ToList();
int key = keys[random.Next(keys.Count)];
int value = dict[key];
// 找到所有具有相同值的键
var group = dict.Where(kv => kv.Value == value).Select(kv => kv.Key).ToList();
// 添加到结果列表
result.AddRange(group);
// 从字典中移除已选中的组
foreach (int k in group)
{
dict.Remove(k);
}
}
public int NextStage()
{
MatchGameData data = GetEventData();
EventMatchInit eventMatchInit = GetMatchInit(data.eventID);
EventMatchStage stage = GetMatchStage(data, eventMatchInit);
if (data.isOpenedList.Count == stage.ItemCount)
{
#if AGG
int countR1 = eventMatchInit.StageListRound1.Count;
int roundId = data.index < countR1 ? 1 : (data.index - countR1) / eventMatchInit.StageListRound2.Count + 2;
using (var e = GEvent.GameEvent("event_match_complete"))
{
e.AddContent("event_id", data.eventID)
.AddContent("round_id", roundId)
.AddContent("stage_id", stage.ID)
.AddContent("item_consume", data.tokenConsumed);
}
#endif
//领奖
ChangeSource changeSource = new ChangeSource(data.eventID, "Event_Minigame1", "Event_Minigame1_Match", "StageReward");
List<ItemData> itemData = GContext.container.Resolve<PlayerItemData>().AddItemByDropLureInflation(data.inflation, stage.DropId, changeSource);
//下一关
data.index++;
data.seed = new System.Random().Next();
data.isOpenedList.Clear();
data.swapFrom = -1;
data.swapTo = -1;
data.swapFrom2 = -1;
data.swapTo2 = -1;
data.tokenConsumed = 0;
SaveData(data);
if (stage.ID == eventMatchInit.StageListRound1[^1] || stage.ID == eventMatchInit.StageListRound2[^1])
{
return 2;
}
return 1;
}
return 0;
}
public List<int> GetBoardData(MatchGameData data)
{
EventMatchInit eventMatchInit = GetMatchInit(data.eventID);
EventMatchStage stage = GetMatchStage(data, eventMatchInit);
int count = stage.ItemCount / 2;
List<EventMatchItem> eventMatchItems = tables.TbEventMatchItem.DataList;
List<int> ids = new List<int>(eventMatchInit.EventItemList);
List<int> itemList = new List<int>(stage.ItemList);
List<int> itemID = new List<int>();
int id;
if (itemList.Count > 0)
{
count -= itemList.Count;
for (int i = 0; i < itemList.Count; i++)
{
id = eventMatchInit.EventItemList[itemList[i] - 1];
ids.Remove(id);
EventMatchItem eventMatchItem = tables.TbEventMatchItem.GetOrDefault(id);
if (eventMatchItem != null)
{
itemID.Add(id);
itemID.Add(id);
}
}
}
System.Random random = new System.Random(data.seed);
if (count > 0)
{
int index;
double spRoll = random.NextDouble();
if (spRoll < stage.SpItemProb)
{
var spItemIDs = eventMatchInit.EventSpecialItemList;
if (spItemIDs.Count > 0)
{
count--;
index = random.Next(spItemIDs.Count);
itemID.Add(spItemIDs[index]);
itemID.Add(spItemIDs[index]);
}
}
for (int i = 0; i < count; i++)
{
index = random.Next(ids.Count);
id = ids[index];
ids.Remove(id);
itemID.Add(id);
itemID.Add(id);
}
}
//itemID 打乱顺序
if (data.index == 0)
{
itemID[2] = itemID[0];
itemID[1] = itemID[3];
}
else
{
itemID = ConvertTools.Shuffle(itemID, random);
}
Debug.Log("[EventMatch] ItemID " + string.Join(',', itemID));
return itemID;
}
public async void ShowFestPack(int eventID)
{
try
{
var init = GetMatchInit(eventID);
if (init == null)
return;
var packData = new EventNeoNormalPackData
{
EventId = eventID,
PackId = init.PackId,
// Panel = init.PackPanel
};
await EventNeoNormalPackPanel.TryShowAsync(packData);
}
catch (Exception e)
{
Debug.LogError(e);
}
}
public EventMatchInit GetMatchInit(int eventID)
{
try
{
FishingEvent fishingEvent = tbFishingEvent.GetOrDefault(eventID);
FishingEventCycleItem cycleItem = tbCycleItem.GetOrDefault(fishingEvent.RedirectID);
return tbEventMatchInit[cycleItem.RedirectID];
}
catch (Exception e)
{
Debug.LogError(e);
}
return null;
}
public EventMatchInit GetMatchInitRedirectID(int redirectID)
{
try
{
FishingEventCycleItem cycleItem = tbCycleItem.GetOrDefault(redirectID);
return tbEventMatchInit[cycleItem.RedirectID];
}
catch (Exception e)
{
Debug.LogError(e);
}
return null;
}
public EventMatchStage GetMatchStage(MatchGameData data, EventMatchInit eventMatchInit)
{
int stageID;
int countRound1 = eventMatchInit.StageListRound1.Count;
if (data.index < countRound1)
{
stageID = eventMatchInit.StageListRound1[data.index];
}
else
{
int index = data.index - countRound1;
index %= eventMatchInit.StageListRound2.Count;
stageID = eventMatchInit.StageListRound2[index];
}
return tables.TbEventMatchStage.GetOrDefault(stageID);
}
public void SaveData(MatchGameData matchGameData)
{
PlayFabMgr.Instance.UpdateUserDataValue(EventMatchGameDataKey, JsonMapper.ToJson(matchGameData));
}
}