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

564 lines
18 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 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<TItem> Items;
public List<int> 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<EventOfferDiscoPartyReward> OfferDiscoPartyRewards { get; private set; }
public TOfferDiscoPartyData OfferDiscoPartyData { get; private set; }
public List<int> 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<TOfferDiscoPartyData.TItem>(),
RewardList = new List<int>()
};
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<IFaceUIService>().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($"<color=orange>OfferDiscoPartyManager -> {t} </color>");
}
private static void ELog(object t)
{
#if UNITY_EDITOR
Debug.Log($"<color=yellow>OfferDiscoPartyManager -> {t} </color>");
#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<TOfferDiscoPartyData>(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<T>(Dictionary<T, int> 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<PlayerItemData>()
// .GetItemDropPackageItemList(item.RedirectID, 1);
// GContext.container.Resolve<PlayerItemData>().LureInflation(itemFinal, null);
// GContext.container.Resolve<PlayerItemData>().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;
}
}
}