564 lines
18 KiB
C#
564 lines
18 KiB
C#
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;
|
||
}
|
||
}
|
||
} |