503 lines
17 KiB
C#
503 lines
17 KiB
C#
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;
|
||
}
|
||
|
||
|
||
|