using System; using System.Collections.Generic; using System.Linq; using asap.core; using cfg; using GameCore; using Newtonsoft.Json; using UnityEngine; namespace DataCenter { // 数据保存 public enum TItemStatues { Valid = 0, HighLight = 1, Done = 2, } public class TOfferDiscoPartyData { public class TItem { public int Id; public int Item; public int Number; // 0 可选,1 高亮 2 糊了 ,锁链隐藏 应该转换成Enum public TItemStatues Status; } public bool FirstOpen; // 是否首次打开 public int EventId; // 默认存一下ID public DateTime StartTime; // 开始时间 public DateTime EndTime; // 结束时间 public int ItemId = -1; public int LotteryNum; // public bool Finished; // 这个看看能否删掉,只保留状态 public List Items; public List RewardList; // 当前获得的奖励Item } // Disco Manager public class OfferDiscoPartyManager { public const string SaveKey = "OfferDiscoPartyManager"; // 免费抽奖次数 public int FreeTime = 1; [Inject] public Tables _tables { get; set; } #region 数据 private FishingEvent _fishingEvent; public EventOfferDiscoParty OfferDiscoParty { get; private set; } public List OfferDiscoPartyRewards { get; private set; } public TOfferDiscoPartyData OfferDiscoPartyData { get; private set; } public List ValidIds; // #endregion public bool IsFirstOpen { get => OfferDiscoPartyData?.FirstOpen?? false; set { if (OfferDiscoPartyData?.FirstOpen??false) { OfferDiscoPartyData.FirstOpen = false; SaveData(); } } } public void UpdateEventData(FishingEvent fishingEvent) { ELog($"UpdateEventData - > {fishingEvent}"); _fishingEvent = fishingEvent; UpdateLocalData(); } private void UpdateLocalData() { //选择当前的 Main var redirectId = _fishingEvent.RedirectID; var configList = _tables.TbEventOfferDiscoParty.DataList; foreach (var eventChallenge in configList.Where(eventChallenge => eventChallenge.ID == redirectId)) { OfferDiscoParty = eventChallenge; break; } FreeTime = OfferDiscoParty.Free; var rewardList = OfferDiscoParty.RewardList; // OfferDiscoPartyRewards = _tables.TbEventOfferDiscoPartyReward.DataList; var list = _tables.TbEventOfferDiscoPartyReward.DataList; //TODO:LF 这个筛选未应用到程序中,看策划的应用 // OfferDiscoPartyRewards = list.Where(item => rewardList.Contains(item.ID)).ToList(); OfferDiscoPartyRewards.Sort((a,b) => a.ID.CompareTo(b.ID)); //添加拍脸 // _tables.TbEventOfferDiscoParty } private bool _isInit = false; public void Init() { ELog("Init-> "); if (_fishingEvent == null) return; if (_fishingEvent.ID != OfferDiscoPartyData?.EventId) { ClearOfferDiscoPartyData(); } if (_isInit) return; if (OfferDiscoPartyData == null) { if (_fishingEvent == null) // 不存在Event { return; } InitOfferDiscoPartyData(); } UpdateOfferDiscoPartyData(); _isInit = true; ELog("初始化完成-> "); } private void ProcessLastOne() { if (OfferDiscoPartyData != null) { Settle(); // if (!IsTimeAllow()) // { // Settle(); // ClearOfferDiscoPartyData(); // } // else if (IsFinished()) // { // Settle(); // 补充一下最终大奖 // } } } private void InitOfferDiscoPartyData() { var limitedTime = (LimitedTime)_fishingEvent.TimeDefinition; var startTime = GlobalUtils.TryParseDateTime(limitedTime.StartTime, ZZTimeHelper.UtcNow()); var endTime = GlobalUtils.TryParseDateTime(limitedTime.EndTime, ZZTimeHelper.UtcNow()); OfferDiscoPartyData = new TOfferDiscoPartyData { FirstOpen = true, EventId = _fishingEvent.ID, StartTime = startTime, EndTime = endTime, Items = new List(), RewardList = new List() }; for (var i = 0; i < OfferDiscoPartyRewards.Count; ++i) { var item = new TOfferDiscoPartyData.TItem { Id = OfferDiscoPartyRewards[i].ID, Item = OfferDiscoPartyRewards[i].Item, Number = OfferDiscoPartyRewards[i].Number, Status = 0, }; OfferDiscoPartyData.Items.Add(item); } } private void UpdateOfferDiscoPartyData() { ELog("UpdateOfferDiscoPartyData"); // 更新可用数据 OfferDiscoPartyData.EventId = _fishingEvent?.ID ?? OfferDiscoPartyData.EventId; UpdateTime(); UpdateOfferDiscoPartyItems(); UpdateValidIds(); // UpdateLotteryItemId(); GetLotteryItemId(); if (_fishingEvent != null) { GContext.container.Resolve().AddGiftFaceUI(_fishingEvent.ID, new UIType(OfferDiscoParty.UIPanel), 0); } } public bool IsTimeAllow() { var now = ZZTimeHelper.UtcNow(); var startTime = OfferDiscoPartyData.StartTime; var endTime = OfferDiscoPartyData.EndTime; #if UNITY_EDITOR var timeOpened = (now - startTime).TotalSeconds; var timeEnded = (endTime - now).TotalSeconds; ELog( $"StartTime: {startTime} Now: {now} EndTime:{endTime} TimeOpened:{timeOpened} TimeToEnd:{timeEnded} Other: {1800000 - timeOpened} IsTimeAllow => {now <= endTime}"); #endif return now >= startTime && now <= endTime; } public void CheckInit() { ELog("CheckInit-> "); ProcessLastOne(); Init(); } private static void Log(object t) { Debug.Log($"OfferDiscoPartyManager -> {t} "); } private static void ELog(object t) { #if UNITY_EDITOR Debug.Log($"OfferDiscoPartyManager -> {t} "); #endif } public bool CheckOpen() { // if (OfferDiscoPartyData == null) return false; // if (!IsTimeAllow()) return false; if (OfferDiscoParty == null) { return false; } if (IsFinished()) { return false; } return true; } public bool IsFinished() { // return OfferDiscoPartyData?.Finished ?? false; return OfferDiscoPartyData.LotteryNum >= OfferDiscoPartyData.Items.Count; } private void SaveData() { PlayFabMgr.Instance.UpdateUserDataValue(SaveKey, JsonConvert.SerializeObject(OfferDiscoPartyData)); } public void LoadData(string dataValue) { ELog($"LoadData- {dataValue}"); OfferDiscoPartyData = JsonConvert.DeserializeObject(dataValue); // // if (true) // { // OfferDiscoPartyData.EventId = 1001; // SaveData(); // } } public async void OnEnterGameAct() { ELog("OnEnterGameAct()"); IsFirstOpen = false; await UIManager.Instance.ShowUI(new UIType(OfferDiscoParty.UIPanel)); } public static T WeightedRandom(Dictionary weightTable) { // 1. 计算总权重 var totalWeight = weightTable.Values.Sum(); // 2. 生成随机数 var randomValue = UnityEngine.Random.Range(0, totalWeight); // 3. 线性遍历选择 var currentWeight = 0; foreach (var (key, value) in weightTable) { currentWeight += value; if (randomValue < currentWeight) return key; } return default; // 理论上不会执行到这里 } private int CalcLotteryItemId() { // UpdateValidIds(); var lotteryNum = OfferDiscoPartyData.LotteryNum; if (ValidIds.Count <= 0) { return -1; } if (OfferDiscoPartyRewards == null) { return -1; } // // while (true) // { var dict = OfferDiscoPartyRewards .Where(item => ValidIds.Contains(item.ID) && lotteryNum >= (item.LimitConfig - 1)) .ToDictionary(elem => (elem.ID, elem.LimitConfig), elem => elem.Weight); if (dict?.Count <= 0) return -1; var (elemId, limitConfig) = WeightedRandom(dict); ELog($"CalcLotteryItemId -> {lotteryNum} {elemId} {limitConfig}"); // if (limitConfig >0 && lotteryNum > limitConfig ) return elemId; // } } private void UpdateValidIds() { ValidIds = (from item in OfferDiscoPartyData?.Items where item.Status == 0 select item.Id).ToList(); // return lotteryNum; } public int GetLotteryItemId() { ELog($"GetLotteryItemId -> {OfferDiscoPartyData.ItemId}"); if (OfferDiscoPartyData.ItemId == -1 || !ValidIds.Contains(OfferDiscoPartyData.ItemId)) { UpdateLotteryItemId(); } return OfferDiscoPartyData.ItemId; } private void UpdateOfferDiscoPartyItems() { ELog("UpdateOfferDiscoPartyItems-> "); if (OfferDiscoPartyData != null && _fishingEvent != null && OfferDiscoPartyData.EventId == _fishingEvent.ID) { var items = OfferDiscoPartyData.Items; if (OfferDiscoPartyRewards is { Count: > 0 }) { for (int i = 0; i < items.Count; ++i) { EventOfferDiscoPartyReward reward = null; if (i < OfferDiscoPartyRewards.Count) { reward = OfferDiscoPartyRewards[i]; } if (reward != null) { items[i].Id = reward.ID; items[i].Item = reward.Item; items[i].Number = reward.Number; } } } } } private void UpdateTime() { if (OfferDiscoPartyData != null && _fishingEvent != null && OfferDiscoPartyData.EventId == _fishingEvent.ID) { var limitedTime = (LimitedTime)_fishingEvent.TimeDefinition; var startTime = GlobalUtils.TryParseDateTime(limitedTime.StartTime, ZZTimeHelper.UtcNow()); var endTime = GlobalUtils.TryParseDateTime(limitedTime.EndTime, ZZTimeHelper.UtcNow().AddDays(-1)); OfferDiscoPartyData.StartTime = startTime; OfferDiscoPartyData.EndTime = endTime; } } private void UpdateLotteryItemId() { var targetId = CalcLotteryItemId(); OfferDiscoPartyData.ItemId = targetId; SaveData(); ELog($"UpdateLotteryItemId -> {targetId}"); } public void FinishLottery(int targetId) { ELog($"FinishLottery -> {targetId}"); var lastItem = OfferDiscoPartyData.Items.SingleOrDefault(it => it.Id == targetId); if (lastItem is { Status: not TItemStatues.Done }) { lastItem.Status = TItemStatues.Done; UpdateForNextLottery(); } } //- 开始下一轮数据 public void UpdateForNextLottery() { UpdateValidIds(); UpdateLotteryItemId(); } public void ClearOfferDiscoPartyData() { OfferDiscoPartyData = null; _isInit = false; SaveData(); } public TOfferDiscoPartyData.TItem GetTItemById(int targetId) { var lastItem = OfferDiscoPartyData.Items.FirstOrDefault(it => it.Id == targetId); return lastItem; } public int GetDropIdById(int id) { var item = GetTItemById(id); var itemData = _tables.TbItem.GetOrDefault(item.Item); return itemData.RedirectID; } public void OnSettleFinalEvent() { // var item = _tables.TbItem.GetOrDefault(OfferDiscoParty.ChestReward); // var item = _tables.TbItem.GetOrDefault(OfferDiscoPartyData.ChestReward); // var itemFinal = GContext.container.Resolve() // .GetItemDropPackageItemList(item.RedirectID, 1); // GContext.container.Resolve().LureInflation(itemFinal, null); // GContext.container.Resolve().AddItem(itemFinal); // GContext.Publish(new ShowData(itemFinal)); // GContext.Publish(new ShowData()); // OfferDiscoPartyData.Finished = true; SaveData(); GContext.Publish(new OfferDiscoPartyRefreshEvent()); } public float GetProbability(int id) { var theIdWeight = OfferDiscoPartyRewards.FirstOrDefault(item => item.ID == id)?.Weight ?? 0; var weightTable = OfferDiscoPartyRewards .Where(item => !IsItemFinished(item.ID)) .Select(item => item.Weight).ToList(); var totalWeight = weightTable.Sum(); return (float)Math.Round((float)theIdWeight / totalWeight * 100, 2); } private bool IsItemFinished(int itemID) { var lastItem = OfferDiscoPartyData.Items.SingleOrDefault(it => it.Id == itemID); return lastItem?.Status == TItemStatues.Done; } public TimeSpan GetTimeRemain() { if (OfferDiscoPartyData != null) { return OfferDiscoPartyData.EndTime - ZZTimeHelper.UtcNow(); } // 活动未开始 return ZZTimeHelper.UtcNow().AddDays(-1) - ZZTimeHelper.UtcNow(); } public void Settle() { if (IsFinished()) { OnSettleFinalEvent(); } } public bool UIRunning { get; set; } = false; // private bool IsCanGetFinalReward() // { // // return OfferDiscoPartyData.LotteryNum >= OfferDiscoPartyData.Items.Count; // // && !OfferDiscoPartyData.Finished; // } public void OnBuySuccess() { ELog("OnBuySuccess -> "); OfferDiscoPartyData.RewardList.Add(OfferDiscoPartyData.ItemId); OfferDiscoPartyData.LotteryNum += 1; FinishLottery(OfferDiscoPartyData.ItemId); SaveData(); EventTracking(); //NEXT TURN if (UIRunning) { // 播放动画逻辑,交给UI return; } // FinishLottery(OfferDiscoPartyData.ItemId); UpdateForNextLottery(); Settle(); } public void EventTracking() { var iapItemIdx = OfferDiscoPartyData.LotteryNum - 1 - FreeTime; var price = GetIapItemListThisTime(iapItemIdx)?.PaymentAmount ?? 0F; // var itemEnt = GetTItemById(OfferDiscoPartyData.ItemId); // var rewardStr = string.Join(',', OfferDiscoPartyData.RewardList); var number = OfferDiscoPartyData.LotteryNum; #if AGG using (var e = GEvent.TackEvent("offer_discoparty")) { e.AddContent("event_id", OfferDiscoPartyData.EventId); e.AddContent("number",number); e.AddContent("price", price); e.AddContent("reward",OfferDiscoPartyData.ItemId); } #endif ELog($"EventTracking: event_id: {OfferDiscoPartyData.EventId} number: {number} price: {price} " + $"reward :{OfferDiscoPartyData.ItemId} "); } public IAPItemList GetIapItemListThisTime() { return GetIapItemListThisTime(OfferDiscoPartyData.LotteryNum - FreeTime); } private IAPItemList GetIapItemListThisTime(int index) { // index -= FreeTime; // index = Mathf.Clamp(index, 0, OfferDiscoParty.IapList.Count - 1); if (index < 0 || index > OfferDiscoParty.IapList.Count - 1) return null; var iapId = OfferDiscoParty.IapList[index]; var iAPItemList = _tables.TbIAPItemList.GetOrDefault(iapId); return iAPItemList; } } }