Files
back_cantanBuilding/Assets/Scripts/DataCenter/EventPartnerGatherManager.cs
2026-05-26 16:15:54 +08:00

600 lines
20 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 System.Threading.Tasks;
using asap.core;
using cfg;
using game;
using GameCore;
using Newtonsoft.Json;
using UnityEngine;
namespace DataCenter
{
// EventPartnerGather 游戏数据结构
public class EventPartnerGatherData
{
public bool FirstOpen = true;
public int EventId;
public DateTime StartTime;
public DateTime EndTime;
// 核心游戏数据
public int CurrentPoints = 0; // 当前积分
public int CurrentMiningProgress = 0; // 挖矿进度
public int TrainProgress = 0; // 火车进度 (0-5节点)
public List<int> CompletedNodes = new List<int>(); // 已完成的节点
// 好友系统数据(第二阶段)
public List<FriendData> Friends = new List<FriendData>();
public int InvitedCount = 0;
// 奖励记录
public List<int> CollectedRewards = new List<int>();
public bool IsFinished = false;
public float BonusPercent = 0f;
public DateTime BonusExpireUtc = DateTime.MinValue;
public class FriendData
{
public string Id;
public string Name;
public int MiningProgress;
public int ContributionPoints;
public bool IsActive;
}
}
// EventPartnerGather 管理器
public class EventPartnerGatherManager
{
public const string SaveKey = "EventPartnerGatherData";
[Inject] public Tables _tables { get; set; }
private FishingEvent _fishingEvent;
// 检查数据是否改变过
private bool _isEventDataChanged = false;
public EventPartnerGatherData GatherData { get; private set; }
// 数据
public EventPartnerMain2 EventPartnerMain2Data { get; private set; }
// 抽奖数据
public List<EventPartnerSpinPoint> EventPartnerSpinPointList { get; private set; }
// 模型数据,目前开来需要构造模型从表里读取
public EventPartnerInit EventPartnerInitData { get; private set; }
// 累分状态
private readonly List<int> _nodeCumulativeSteps = new List<int>();
// 配置数据(后续从表格读取)
public int MaxTrainNodes => 5;
public int PointsPerMining => 10;
public int PointsPerNode => 100;
public bool IsFirstOpen
{
get => GatherData?.FirstOpen ?? false;
set
{
if (GatherData != null && GatherData.FirstOpen)
{
GatherData.FirstOpen = false;
SaveData();
}
}
}
public void UpdateEventData(FishingEvent fishingEvent)
{
Log($"UpdateEventData: {fishingEvent?.ID}");
_fishingEvent = fishingEvent;
InitializeData();
// }
}
public void CheckInit()
{
Init();
}
public void Init()
{
Log("Init()-> ");
if (GatherData == null && _fishingEvent != null)
{
CreateNewData();
}
//TODO:LF 等上面触发完成之后,移走
//TODO:LF:后面优化 2025-09-17
InitializeData();
ValidateAndUpdateData();
}
private void CreateNewData()
{
var limitedTime = (LimitedTime)_fishingEvent.TimeDefinition;
var startTime = GlobalUtils.TryParseDateTime(limitedTime.StartTime, ZZTimeHelper.UtcNow());
var endTime = GlobalUtils.TryParseDateTime(limitedTime.EndTime, ZZTimeHelper.UtcNow());
GatherData = new EventPartnerGatherData
{
FirstOpen = true,
EventId = _fishingEvent.ID,
StartTime = startTime,
EndTime = endTime,
CurrentPoints = 0,
CurrentMiningProgress = 0,
TrainProgress = 0
};
SaveData();
}
private void InitializeData()
{
Log("InitializeData() -> ");
if (_fishingEvent == null) return;
var redirectId = _fishingEvent.RedirectID;
var eventPartnerDataList = _tables.TbEventPartnerMain2.DataList;
EventPartnerMain2Data = eventPartnerDataList.FirstOrDefault(data => data.ID == redirectId);
var allSpinPoints = _tables.TbEventPartnerSpinPoint.DataList;
var ids = EventPartnerMain2Data?.SpinPoint;
if (ids != null && ids.Count > 0)
{
var filtered = new List<EventPartnerSpinPoint>();
foreach (var id in ids)
{
var sp = _tables.TbEventPartnerSpinPoint.GetOrDefault(id);
if (sp != null) filtered.Add(sp);
}
EventPartnerSpinPointList = filtered;
}
else
{
EventPartnerSpinPointList = new List<EventPartnerSpinPoint>();
}
_nodeCumulativeSteps.Clear();
if (EventPartnerMain2Data?.StagePoint != null && EventPartnerMain2Data.StagePoint.Count > 0)
{
int sum = 0;
for (int i = 0; i < EventPartnerMain2Data.StagePoint.Count; i++)
{
sum += EventPartnerMain2Data.StagePoint[i];
_nodeCumulativeSteps.Add(sum);
}
}
var eventPartnerInitDataList = _tables.TbEventPartnerInit.DataList;
// foreach (var eventPartnerInitData in eventPartnerInitDataList.Where(data => data.ID == redirectId))
// {
// EventPartnerInitData = eventPartnerInitData;
// }
EventPartnerInitData = eventPartnerInitDataList.FirstOrDefault(data => data.ID == redirectId);
// 检查是否需要重置数据
if (GatherData != null && !IsTimeValid())
{
HandleEventEnd();
GatherData = null;
}
}
private void ValidateAndUpdateData()
{
if (GatherData == null) return;
// 验证时间有效性
if (!IsTimeValid())
{
HandleEventEnd();
}
}
public bool IsTimeValid()
{
if (GatherData == null) return false;
var now = ZZTimeHelper.UtcNow();
return now >= GatherData.StartTime && now <= GatherData.EndTime;
}
public TimeSpan GetRemainingTime()
{
if (GatherData == null)
return TimeSpan.Zero;
return GatherData.EndTime - ZZTimeHelper.UtcNow();
}
public bool CheckOpen()
{
if (GatherData == null) return false;
if (!IsTimeValid()) return false;
if (GatherData.IsFinished) return false;
return true;
}
// 核心游戏逻辑
// 抽奖数据
public EventPartnerSpinPoint GetSpinPointElem()
{
// if (EventPartnerSpinPointList is { Count: > 0 })
// {
// // 根据权重,生成字典
// var dict = EventPartnerSpinPointList.ToDictionary(elem => elem, elem => elem.Weight);
// var elem = OfferChainsChestManager.WeightedRandom(dict);
// Log($"GetSpinPointElem -> {elem.ID}");
// return elem;
// }
return null;
}
public void AddPoints(int points)
{
if (GatherData == null)
{
Log("错误GatherData 为空,无法添加积分");
return;
}
if (GatherData.IsFinished)
{
Log("警告:游戏已结束,无法添加积分");
return;
}
if (points <= 0)
{
Log($"警告:尝试添加无效积分值:{points}");
return;
}
EnsureBonusValid();
float mult = 1f + Mathf.Max(0f, GatherData.BonusPercent);
int eff = Mathf.Max(0, Mathf.RoundToInt(points * mult));
// 防止积分溢出
long newPoints = (long)GatherData.CurrentPoints + eff;
if (newPoints > int.MaxValue)
{
Log($"警告:积分即将溢出,限制在最大值");
GatherData.CurrentPoints = int.MaxValue;
}
else
{
GatherData.CurrentPoints += eff;
}
Log($"AddPoints: {eff}, TotalPoints: {GatherData.CurrentPoints}");
SaveData();
GContext.Publish(new EventPartnerGatherPointsUpdate { Points = GatherData.CurrentPoints });
// 检查是否需要触发自动挖矿
CheckAutoMining();
}
private void CheckAutoMining()
{
// 每累积一定积分自动触发挖矿
bool dataChanged = false;
while (GatherData.CurrentPoints >= PointsPerMining)
{
GatherData.CurrentPoints -= PointsPerMining;
GatherData.CurrentMiningProgress++;
dataChanged = true;
// 检查节点完成
CheckNodeProgress();
}
// 如果数据有变化,发布更新事件
if (dataChanged)
{
SaveData();
PublishDataUpdateEvents();
}
}
private void CheckNodeProgress()
{
int completedNodes = 0;
if (_nodeCumulativeSteps != null && _nodeCumulativeSteps.Count > 0)
{
for (int i = 0; i < _nodeCumulativeSteps.Count; i++)
{
if (GatherData.CurrentMiningProgress >= _nodeCumulativeSteps[i]) completedNodes++;
else break;
}
}
if (completedNodes > GatherData.TrainProgress)
{
int target = Mathf.Min(completedNodes, MaxTrainNodes);
for (int idx = GatherData.TrainProgress; idx < target; idx++)
{
CompleteTrainNode(idx);
}
GatherData.TrainProgress = target;
if (GatherData.TrainProgress >= MaxTrainNodes)
{
HandleGameComplete();
}
}
}
private void CompleteTrainNode(int nodeIndex)
{
Log($"CompleteNode: {nodeIndex}");
if (!GatherData.CompletedNodes.Contains(nodeIndex))
{
GatherData.CompletedNodes.Add(nodeIndex);
// 发放节点奖励
DistributeNodeReward(nodeIndex);
}
}
private void DistributeNodeReward(int nodeIndex)
{
// 使用现有的奖励系统
var dropId = GetNodeRewardDropId(nodeIndex);
if (dropId > 0)
{
var playerItemData = GContext.container.Resolve<PlayerItemData>();
var rewards = playerItemData.GetItemDataByDropId(dropId);
playerItemData.AddItem(rewards);
GContext.Publish(new ShowData(rewards));
GatherData.CollectedRewards.Add(dropId);
SaveData();
}
}
private int GetNodeRewardDropId(int nodeIndex)
{
// 根据节点返回对应的掉落ID后续从配置表读取
return 10000 + nodeIndex;
}
private void HandleGameComplete()
{
Log("Game Complete!");
GatherData.IsFinished = true;
// 发放最终大奖
DistributeFinalReward();
SaveData();
GContext.Publish(new EventPartnerGatherComplete());
}
private void DistributeFinalReward()
{
var dropId = GetFinalRewardDropId();
if (dropId > 0)
{
var playerItemData = GContext.container.Resolve<PlayerItemData>();
var rewards = playerItemData.GetItemDataByDropId(dropId);
playerItemData.AddItem(rewards);
GContext.Publish(new ShowData(rewards));
}
}
private int GetFinalRewardDropId()
{
// 最终奖励掉落ID后续从配置表读取
return 99999;
}
private void HandleEventEnd()
{
if (GatherData == null || GatherData.IsFinished) return;
Log("Event Ended");
// 结算未领取的奖励
if (GatherData.TrainProgress >= MaxTrainNodes && !GatherData.IsFinished)
{
HandleGameComplete();
}
ClearData();
}
public int ResolveSpinAndGetPoints(EventPartnerSpinPoint p)
{
if (p == null || p.SpinPointParam == null) return 0;
switch (p.SpinPointParam)
{
case NormalSpinPoint n:
return Mathf.Max(0, n.SpinPoints);
case FreeSpinPoint f:
return Mathf.Max(0, f.SpinPoints);
case MoreSpinPoint m:
ApplyBonus(m.BonusPercent, m.BonusDuration);
return 0;
}
return 0;
}
private void ApplyBonus(float percent, int durationSec)
{
if (GatherData == null) return;
GatherData.BonusPercent = Mathf.Max(0f, percent);
GatherData.BonusExpireUtc = ZZTimeHelper.UtcNow().AddSeconds(Mathf.Max(0, durationSec));
SaveData();
GContext.Publish(new EventPartnerGatherRefreshEvent());
}
private void EnsureBonusValid()
{
if (GatherData == null) return;
if (GatherData.BonusPercent > 0f && ZZTimeHelper.UtcNow() > GatherData.BonusExpireUtc)
{
GatherData.BonusPercent = 0f;
GatherData.BonusExpireUtc = DateTime.MinValue;
SaveData();
GContext.Publish(new EventPartnerGatherRefreshEvent());
}
}
public bool IsBonusActive()
{
return GatherData != null && GatherData.BonusPercent > 0f && ZZTimeHelper.UtcNow() <= GatherData.BonusExpireUtc;
}
private void SaveData()
{
if (GatherData != null)
{
PlayFabMgr.Instance.UpdateUserDataValue(SaveKey, JsonConvert.SerializeObject(GatherData));
}
}
public void LoadData(string dataValue)
{
if (!string.IsNullOrEmpty(dataValue))
{
GatherData = JsonConvert.DeserializeObject<EventPartnerGatherData>(dataValue);
}
}
private void ClearData()
{
GatherData = null;
SaveData();
}
// 进入游戏场景
public void EnterGatherScene()
{
Log("EnterGatherScene() ");
IsFirstOpen = false;
GContext.Publish(new UnloadActToNextAct("EventPartnerGatherAct", UITypes.CloudTransitionPanel, 0.5f));
}
// 开始采矿
public void StartMining()
{
// throw new NotImplementedException();
Log("StartMining()");
((EventPartnerGatherAct)_act)?.OnEnterGather();
}
private static void Log(object t)
{
Debug.Log($"<color=cyan>EventPartnerGatherManager-> {t} </color>");
}
private AGameAct _act;
public void SetGameAct(AGameAct act)
{
_act = act;
}
// 组件绑定管理
private UI.PartnerGather.Mining.EventPartnerMiningSceneController _miningController;
private UI.PartnerGather.Mining.EventPartnerDrawMiningPanel _drawPanel;
/// <summary>
/// 设置挖矿场景控制器引用
/// </summary>
public void SetMiningController(UI.PartnerGather.Mining.EventPartnerMiningSceneController controller)
{
_miningController = controller;
Log($"设置挖矿控制器: {controller?.name ?? "null"}");
}
/// <summary>
/// 设置抽奖UI面板引用
/// </summary>
public void SetDrawPanel(UI.PartnerGather.Mining.EventPartnerDrawMiningPanel panel)
{
_drawPanel = panel;
Log($"设置抽奖面板: {panel?.name ?? "null"}");
}
/// <summary>
/// 获取挖矿控制器引用
/// </summary>
public UI.PartnerGather.Mining.EventPartnerMiningSceneController GetMiningController()
{
return _miningController;
}
/// <summary>
/// 获取抽奖面板引用
/// </summary>
public UI.PartnerGather.Mining.EventPartnerDrawMiningPanel GetDrawPanel()
{
return _drawPanel;
}
/// <summary>
/// 通知所有绑定组件刷新数据显示
/// </summary>
public void RefreshAllUI()
{
if (GatherData == null) return;
// 刷新抽奖面板
if (_drawPanel != null)
{
_drawPanel.SetPoints(GatherData.CurrentPoints);
_drawPanel.SetMiningProgress(GatherData.CurrentMiningProgress);
_drawPanel.SetTrainProgress(GatherData.TrainProgress, MaxTrainNodes);
}
Log("已刷新所有UI组件数据");
}
/// <summary>
/// 发布所有相关的数据更新事件
/// </summary>
private void PublishDataUpdateEvents()
{
if (GatherData == null) return;
// 发布积分更新事件
GContext.Publish(new EventPartnerGatherPointsUpdate { Points = GatherData.CurrentPoints });
// 发布挖矿进度更新事件
GContext.Publish(new EventPartnerGatherMiningProgressUpdate { Progress = GatherData.CurrentMiningProgress });
// 发布火车进度更新事件
GContext.Publish(new EventPartnerGatherTrainProgressUpdate { Progress = GatherData.TrainProgress, MaxNodes = MaxTrainNodes });
// 刷新绑定的UI组件
RefreshAllUI();
Log($"已发布数据更新事件 - 积分:{GatherData.CurrentPoints}, 挖矿进度:{GatherData.CurrentMiningProgress}, 火车进度:{GatherData.TrainProgress}");
}
// 有可能会激活不应该在OnEnable 中调用Init();
public void CheckForOnEnable()
{
//throw new NotImplementedException();
}
}
// 事件定义
public class EventPartnerGatherPointsUpdate
{
public int Points;
}
public class EventPartnerGatherMiningProgressUpdate
{
public int Progress;
}
public class EventPartnerGatherTrainProgressUpdate
{
public int Progress;
public int MaxNodes;
}
public class EventPartnerGatherComplete { }
public class EventPartnerGatherRefreshEvent { }
}