Files
2026-05-26 16:15:54 +08:00

503 lines
17 KiB
C#
Raw Permalink 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.
using asap.core;
using cfg;
using game;
using GameCore;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class LuckyCardsSystem
{
public const int ItemID = -1; // -1表示倍率卡,其他为奖励ID
public EventLuckyGameModel model { get; private set; }
EventLuckyCardsMain cardsMain;
public EventLuckyCardsMain CardsMain => cardsMain;
public TimeSpan RemainingTime => model.RemainingTime;
public int TicketCount => model.TicketCount;
LuckyCardsData luckyCardsData;
public LuckyCardsData LuckyCardsData => luckyCardsData;
Tables tables;
int wishPrizeIndex;
//预览位置
public List<int> previewPos = new List<int>();
public List<CardRewardShowData> cardRewardShowDatas = new List<CardRewardShowData>();
public EventLuckyCardsConfig config;
public ProgressMilestone progressMilestone;
public void Init()
{
tables = GContext.container.Resolve<Tables>();
model = GContext.container.Resolve<EventLuckyGameModel>();
cardsMain = tables.TbEventLuckyCardsMain.GetOrDefault(model.cycle.RedirectID);
string json = model.EventGameData;
progressMilestone = new ProgressMilestone();
progressMilestone.oldProgress = progressMilestone.progress = model.Progress;
progressMilestone.rewardIndex = new List<int>(); // 初始化奖励索引为-1表示未触发奖励
try
{
luckyCardsData = Newtonsoft.Json.JsonConvert.DeserializeObject<LuckyCardsData>(json);
}
catch (System.Exception e)
{
UnityEngine.Debug.LogWarning($"Error parsing LuckyCardsSystem JSON: {e.Message}");
}
if (luckyCardsData == null || luckyCardsData.rewardData == null || luckyCardsData.rewardData.Count == 0)
{
RefreshReward(); // 如果没有数据,开始新游戏
}
else
{
wishPrizeIndex = GetWishPrizeIndex();
SetPreviewPos();
SetCardRewardShowData();
}
SetConfig();
}
public async void OnClickPack()
{
EventPackManager eventPack = GContext.container.Resolve<Tables>().TbEventPackManager.GetOrDefault(cardsMain.PackId);
GameObject go = await UIManager.Instance.ShowUINotLoading(new UIType(eventPack.Panel));
if (go == null)
{
return;
}
EventLuckyTriplePackPanel triple = go.GetComponent<EventLuckyTriplePackPanel>();
triple.Init(EventLuckyTriplePackData.Create(model.EventId, cardsMain.PackId));
}
public ItemData OnClickCard(int index)
{
if (luckyCardsData == null || luckyCardsData.rewardData.Count == 0)
{
return null;
}
if (model.TicketCount < config.ItemCost)
{
OnClickPack();
return null;
}
luckyCardsData.pos.Add(index);
int rewardIndex = luckyCardsData.pos.Count - 1;
int dropId = Cost(config.ItemCost);
CardRewardShowData cardRewardData = cardRewardShowDatas[rewardIndex];
ItemData itemData = new ItemData(cardRewardData.id, cardRewardData.num);
int wishprize_multiple = 1;
if (cardRewardData.multiplier > 0)
{
wishprize_multiple = cardRewardData.multiplier;
itemData.count *= cardRewardData.multiplier;
}
if (cardRewardData.id != ItemID)
{
var e = new DeferredRewardStashService.EventStashItem { Item = itemData };
GContext.Publish(e);
}
#if AGG
using (var e = GEvent.GameEvent("event_luckycards"))
{
e.AddContent("is_wishprize", rewardIndex == wishPrizeIndex)
.AddContent("item_cost", config.ItemCost)
.AddContent("reward", $"{itemData.id},{itemData.count}")
.AddContent("round", luckyCardsData.count)
.AddContent("milestone_reward", dropId)
;
}
#endif
//如果抽取大奖位置,直接结束
if (rewardIndex == wishPrizeIndex)
{
int multiple_cards_number = 0;
for (int i = 0; i < rewardIndex; i++)
{
if (luckyCardsData.rewardData[i].id == ItemID)
{
multiple_cards_number++;
}
}
luckyCardsData.rewardData.Clear();
#if AGG
using (var e = GEvent.GameEvent("event_luckycards_wishprize"))
{
e.AddContent("number", wishPrizeIndex + 1)
.AddContent("round", luckyCardsData.count)
.AddContent("wishprize_multiple", wishprize_multiple)
.AddContent("multiple_cards_number", multiple_cards_number);
}
#endif
luckyCardsData.count++;
model.InitDicTasks();
}
SaveData();
SetConfig();
return itemData;
}
void SetConfig()
{
if (luckyCardsData == null || luckyCardsData.pos == null || luckyCardsData.pos.Count == 0)
{
config = tables.TbEventLuckyCardsConfig.GetOrDefault(1);
return;
}
config = tables.TbEventLuckyCardsConfig.GetOrDefault(luckyCardsData.pos.Count + 1);
if (config == null)
config = tables.TbEventLuckyCardsConfig.GetOrDefault(1); // 默认配置
}
public List<ItemData> GetWishPrizeReward()
{
int index = luckyCardsData.count - 1;
if (index < 0 || index >= cardsMain.WishPrize.Count)
{
index = cardsMain.WishPrize.Count - 1; // 确保索引在有效范围内
}
int wishPrizeId = cardsMain.WishPrize[index];
return GContext.container.Resolve<PlayerItemData>().GetItemDataByDropId(wishPrizeId);
}
public CardRewardShowData GetWishPrizeShow()
{
if (wishPrizeIndex < 0 || wishPrizeIndex >= cardRewardShowDatas.Count)
{
Debug.LogError($"[LuckyCardsSystem]: Invalid wish prize index: {wishPrizeIndex}");
return null;
}
return cardRewardShowDatas[wishPrizeIndex];
}
public void OnConfirmWishPrize(int selectedWishPrizeIndex)
{
if (selectedWishPrizeIndex < 0)
{
return;
}
List<ItemData> reward = GetWishPrizeReward();
if (reward == null || selectedWishPrizeIndex >= luckyCardsData.rewardData.Count)
{
Debug.LogError($"[LuckyCardsSystem]: Invalid wish prize index: {selectedWishPrizeIndex}");
return;
}
CardRewardShowData cardRewardShowData = cardRewardShowDatas[wishPrizeIndex];
CardRewardData wishRewardData = luckyCardsData.rewardData[wishPrizeIndex];
ItemData itemData = reward[selectedWishPrizeIndex];
cardRewardShowData.id = wishRewardData.id = itemData.id;
cardRewardShowData.num = wishRewardData.num = itemData.count;
SaveData();
#if AGG
using (var e = GEvent.GameEvent("event_luckycards_select_wishprize"))
{
e.AddContent("reward", itemData.id)
.AddContent("round", luckyCardsData.count)
.AddContent("reward_count", itemData.count);
}
#endif
}
public void RefreshReward()
{
if (luckyCardsData == null)
{
luckyCardsData = new LuckyCardsData();
luckyCardsData.count++;
}
else
{
luckyCardsData.rewardData.Clear();
luckyCardsData.pos.Clear();
}
if (luckyCardsData.count < cardsMain.WishPrize.Count)
{
luckyCardsData.seed = cardsMain.RandomSeedRound1[UnityEngine.Random.Range(0, cardsMain.RandomSeedRound1.Count)];
}
else
{
luckyCardsData.seed = (int)DateTime.UtcNow.Ticks; // 使用当前时间的Ticks作为随机种子
}
Debug.Log($"[LuckyCardsSystem]: Refreshing rewards with seed: {luckyCardsData.seed}, count: {luckyCardsData.count}");
//先随大奖位置
wishPrizeIndex = GetWishPrizeIndex();
SetRewardData();
SetPreviewPos();
//保存
SaveData();
SetCardRewardShowData();
SetConfig();
}
void SetRewardData()
{
System.Random random = new System.Random(luckyCardsData.seed);
List<EventLuckyCardsPrizePool> pools = tables.TbEventLuckyCardsPrizePool.DataList;
Dictionary<int, int> poolWeight = new Dictionary<int, int>();
foreach (var pool in pools)
{
poolWeight[pool.ID] = pool.Weight;
}
int multiplierCount = 0;
for (int i = 0; i < 9; i++)
{
//出现在心愿大奖之后权重变为X且不受权重下降的影响
if (i == wishPrizeIndex)
{
poolWeight = WishPrizeNewDic(poolWeight);
}
int selectedPoolId = GetSelectedPoolId(poolWeight, random);
EventLuckyCardsPrizePool selectedPool = tables.TbEventLuckyCardsPrizePool.GetOrDefault(selectedPoolId);
if (selectedPool == null)
{
UnityEngine.Debug.LogError($"[LuckyCardsSystem]: Selected pool not found for ID: {selectedPoolId}");
}
CardRewardData cardRewardData = new CardRewardData();
cardRewardData.id = selectedPool.Item;
cardRewardData.num = selectedPool.Count;
if (selectedPool.Item == 1002)
{
cardRewardData.num = GContext.container.Resolve<PlayerItemData>().GetExtraCoinMag(selectedPool.Count);
}
luckyCardsData.rewardData.Add(cardRewardData);
if (i < wishPrizeIndex || selectedPool.AdjustWeight2 == 0)
{
poolWeight[selectedPoolId] = selectedPool.AdjustWeight;
}
if (selectedPool.Item == ItemID)
{
multiplierCount++;
if (multiplierCount >= cardsMain.MaxMultipleCardsCount)
{
poolWeight = MaxMultipleNewDic(poolWeight);
}
}
}
CardRewardData wishRewardData = new CardRewardData();
luckyCardsData.rewardData.Insert(wishPrizeIndex, wishRewardData);
}
int GetSelectedPoolId(Dictionary<int, int> poolWeight, System.Random random)
{
int weightSum = poolWeight.Values.Sum();
int randomValue = random.Next(0, weightSum);
int cumulativeWeight = 0;
int selectedPoolId = 0;
foreach (var kvp in poolWeight)
{
if (kvp.Value == 0)
{
continue;
}
cumulativeWeight += kvp.Value;
if (randomValue < cumulativeWeight)
{
selectedPoolId = kvp.Key;
break;
}
}
return selectedPoolId;
}
Dictionary<int, int> WishPrizeNewDic(Dictionary<int, int> poolWeight)
{
var oldPoolWeight = poolWeight;
poolWeight = new Dictionary<int, int>();
EventLuckyCardsPrizePool selectedPool;
foreach (var kvp in oldPoolWeight)
{
if (kvp.Value == 0)
{
continue;
}
selectedPool = tables.TbEventLuckyCardsPrizePool.GetOrDefault(kvp.Key);
if (selectedPool.AdjustWeight2 > 0)
{
poolWeight[kvp.Key] = selectedPool.AdjustWeight2;
}
else
{
poolWeight[kvp.Key] = kvp.Value;
}
}
return poolWeight;
}
Dictionary<int, int> MaxMultipleNewDic(Dictionary<int, int> poolWeight)
{
var oldPoolWeight = poolWeight;
poolWeight = new Dictionary<int, int>();
EventLuckyCardsPrizePool selectedPool;
foreach (var kvp in oldPoolWeight)
{
if (kvp.Value == 0)
{
continue;
}
selectedPool = tables.TbEventLuckyCardsPrizePool.GetOrDefault(kvp.Key);
if (selectedPool.Item != ItemID)
{
poolWeight[kvp.Key] = kvp.Value;
}
}
return poolWeight;
}
/// <summary>
/// 使用随机种子
/// </summary>
/// <param name="random"></param>
/// <returns></returns>
int GetWishPrizeIndex()
{
System.Random random = new System.Random(luckyCardsData.seed);
List<EventLuckyCardsConfig> configs = GContext.container.Resolve<Tables>().TbEventLuckyCardsConfig.DataList;
//权重随机
int weightSum = configs.Select(c => c.WishPrizeWeight).Sum();
int randomValue = random.Next(0, weightSum);
int cumulativeWeight = 0;
int wishPrizeIndex = 0;
for (int i = 0; i < configs.Count; i++)
{
cumulativeWeight += configs[i].WishPrizeWeight;
if (randomValue < cumulativeWeight)
{
wishPrizeIndex = i;
break;
}
}
//Debug.Log($"[LuckyCardsSystem]:Wish Prize Index: {wishPrizeIndex}, Seed: {luckyCardsData.seed}");
return wishPrizeIndex;
}
void SetPreviewPos()
{
previewPos.Clear();
System.Random random = new System.Random(luckyCardsData.seed);
List<int> availablePositions = Enumerable.Range(0, 10).ToList();
for (int i = 0; i < 10; i++)
{
int index = random.Next(availablePositions.Count);
previewPos.Add(availablePositions[index]);
availablePositions.RemoveAt(index);
}
previewPos.Remove(wishPrizeIndex);
// 将大奖位置放在最前面
previewPos.Insert(0, wishPrizeIndex);
//Debug.Log($"[LuckyCardsSystem]:Preview Positions: {string.Join(", ", previewPos)}");
}
void SaveData()
{
string json = Newtonsoft.Json.JsonConvert.SerializeObject(luckyCardsData);
//Debug.Log($"[LuckyCardsSystem]:Saving LuckyCardsData: {json}");
model.SetEventGameData(json);
}
int Cost(int count)
{
model.AddTicket(-count);
//增加进度
int oldProgress = model.Progress;
progressMilestone.oldProgress = oldProgress;
List<int> milestoneList = cardsMain.MilestoneList;
if (oldProgress >= milestoneList[^1])
{
return 0;
}
List<int> milestoneRewardList = cardsMain.MilestoneRewardList;
model.AddProgress(count);
//计算奖励
int newProgress = model.Progress;
progressMilestone.rewardIndex.Clear();
int dropId = 0;
for (int i = 0; i < milestoneList.Count; i++)
{
if (oldProgress < milestoneList[i] && newProgress >= milestoneList[i])
{
// 触发奖励
dropId = milestoneRewardList[i];
var rewardItem = GContext.container.Resolve<PlayerItemData>().GetItemDataOne(dropId);
if (rewardItem != null)
{
var e = new DeferredRewardStashService.EventStashItem { Item = rewardItem };
GContext.Publish(e);
}
progressMilestone.rewardIndex.Add(i); // 添加奖励索引
}
}
progressMilestone.progress = newProgress;
return dropId;
}
/// <summary>
/// 显示用的数据
/// </summary>
void SetCardRewardShowData()
{
cardRewardShowDatas.Clear();
int multiplier = 0;
for (int i = 0; i < luckyCardsData.rewardData.Count; i++)
{
CardRewardData rewardData = luckyCardsData.rewardData[i];
CardRewardShowData showData = new CardRewardShowData
{
id = rewardData.id,
num = rewardData.num,
isHas = i < luckyCardsData.pos.Count,
isWishPrize = i == wishPrizeIndex, // 判断是否为大奖位置
};
if (rewardData.id == ItemID)
{
multiplier += rewardData.num;
}
else
{
showData.multiplier = multiplier;
multiplier = 0; // 重置倍率
}
cardRewardShowDatas.Add(showData);
}
}
}
public class LuckyCardsData
{
// 奖励抽奖顺序
public List<CardRewardData> rewardData = new List<CardRewardData>();
// 玩家抽取顺序随机种子,计算展示顺序
public int seed;
// 玩家抽取的位置顺序,可以计算倍率
public List<int> pos = new List<int>();
public int count = 0; // 玩家抽取的次数
}
public class CardRewardData
{
public int id;
public int num;
}
public class CardRewardShowData
{
public int id; // 奖励ID
public int num; // 奖励数量
public int multiplier;
public bool isHas;
public bool isWishPrize;
}
public struct ProgressMilestone
{
public int oldProgress; // 旧的进度
public int progress;
public List<int> rewardIndex;
}