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

313 lines
12 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using asap.core;
using cfg;
using DataCenter;
using UnityEngine;
using Debug = UnityEngine.Debug;
using EventBuildBotAddScoreAction = EventPartnerData.EventBuildBotAddScoreAction;
using Random = UnityEngine.Random;
namespace EventPartnerGather
{
public class BuildPartner
{
public const char RobotIdentifier = 'R';
public int SlotId;
public string PartnerId;
public string AvatarUrl;
public string DisplayName;
public int ScoreSelfActual;
public int ScorePartnerActual;
public int ScorePartnerDisplay; // 保存的数据
public int ScoreSelfDisplay; // 自己的数据
private Tables _tables => GContext.container.Resolve<Tables>();
private EventPartnerGatherManager _manager = GContext.container.Resolve<EventPartnerGatherManager>();
public int MaxScore;
// 机器人
// ComponentIndex,
public int LastProgressReceived;
public int BotGrade;
public int BotIndex;
public int BotTargetScore;
public int WakingSeconds;
public DateTime WakeStartTime;
// Cache
public EventPartnerGatherCache Cache { get; set; }
public int RedirectID { get; set; }
//
public bool IsPartnerRobot => !string.IsNullOrEmpty(PartnerId) && PartnerId.EndsWith(RobotIdentifier);
public int Score => ScoreSelfActual + ScorePartnerActual;
public int DisplayScore => ScoreSelfDisplay + ScorePartnerDisplay;
//
public Queue<EventBuildBotAddScoreAction> BotActionQueue
{
get
{
Cache.ActionQ ??= new Dictionary<int, Queue<EventBuildBotAddScoreAction>>();
if (Cache.ActionQ.TryGetValue(SlotId, out var q))
return q;
q = new Queue<EventBuildBotAddScoreAction>();
Cache.ActionQ.Add(SlotId, q);
return q;
}
}
public void ClearData()
{
ScoreSelfActual = 0;
ScorePartnerActual = 0;
ScorePartnerActual = 0;
ScorePartnerDisplay = 0;
BotGrade = 0;
BotIndex = 0;
BotTargetScore = 0;
WakingSeconds = 0;
LastProgressReceived = 0;
}
public void SyncData()
{
ScoreSelfDisplay = ScoreSelfActual;
ScorePartnerDisplay = ScorePartnerActual;
}
public bool IsValid()
{
return !string.IsNullOrEmpty(PartnerId);
}
public bool IsFinished()
{
// var score = ScoreSelfActual + ScorePartnerActual;
// return score >= MaxScore;
return Score >= MaxScore;
}
public bool AddRobotScore()
{
// 加分
if (!BotActionQueue.TryPeek(out var action) || ZZTimeHelper.UtcNow() < action.Time)
{
return false;
}
ScorePartnerActual += action.Score;
BotActionQueue.Dequeue();
Log($"AddRobotScore slotId={SlotId} score={action.Score} partnerScore={ScorePartnerActual} time={ZZTimeHelper.UtcNow()}");
// Save
GContext.Publish(new EventSavePartnerInfoCache());
// GContext.Publish(new EventPartnerPartnerAddScore());
return true;
}
public void AddSelfScore(int newScore)
{
// if (Score + newScore > MaxScore)
// ScoreSelfActual = Score - MaxScore;
// else
ScoreSelfActual += newScore;
// return ScoreSelfActual;
}
public void SyncRobotScore()
{
Log($"SyncRobotScore slotId={SlotId}");
// _manager.SyncFromPartnerInfo();
// var builder = _manager.PartnerInfoManager.BuildPartners;
// var partners = PartnerInfoManager.BuildPartners;
var idx = SlotId;
var buildPartner = _manager.GatherData.BuilderPartnerScore[idx];
buildPartner.FriendScore = ScorePartnerActual;
_manager.GatherData.BuilderPartnerScore[idx] = buildPartner;
_manager.SaveData();
}
//
public void ScheduleBotScoreAction()
{
if (!IsPartnerRobot)
return;
// BotTargetScore = newBotTargetScore;
// var botScore = ScorePartnerActual;
// var gap = newBotTargetScore - botScore;
// gap = Mathf.Clamp(gap,0,gap);
var eventPartnerMineMainData = _manager.EventPartnerMineMainData;
var currentProgress = _manager.GetProgressBySlotId(SlotId);
Log($"ScheduleBotScoreAction slotId={SlotId} currentProgress={currentProgress}");
var tbEventPartnerConfig = _tables.TbEventPartnerConfig;
var newActionQ = new Queue<EventBuildBotAddScoreAction>();
if (BotGrade >= _tables.TbEventPartnerRobot.DataList.Count)
{
Log($"ScheduleBotScoreSkipped reason=GradeOutOfRange grade={BotGrade} max={_tables.TbEventPartnerRobot.DataList.Count}");
return;
}
var robotData = _tables.TbEventPartnerRobot.DataList[BotGrade];
var percentage = Random.Range(robotData.PointsRange[0], robotData.PointsRange[1]) / 100;
int newBotTargetScore = (int)(percentage * eventPartnerMineMainData.StagePoint[currentProgress]);
// int newBotTargetScore = (int)(percentage * tbEventPartnerConfig.RobotPointsMultiple2);
// RobotPointsMultiple
if (newBotTargetScore < BotTargetScore)
{
Log($"ScheduleBotScoreSkipped reason=TargetLessThanOld newTarget={newBotTargetScore} oldTarget={BotTargetScore}");
return;
}
if (newBotTargetScore < ScorePartnerActual)
{
Log($"ScheduleBotScoreSkipped reason=TargetLessThanCurrent newTarget={newBotTargetScore} currentScore={ScorePartnerActual}");
return;
}
var startTime = WakeStartTime + TimeSpan.FromSeconds( Random.Range(tbEventPartnerConfig.RobotDailyActiveTimeWindow[0], tbEventPartnerConfig.RobotDailyActiveTimeWindow[1]));
// while (startTime < ZZTimeHelper.UtcNow())
// {
// startTime += TimeSpan.FromDays(1);
// }
// var delatTay = ZZTimeHelper.UtcNow().Day - startTime.Day + 1;
if (startTime < ZZTimeHelper.UtcNow())
{
var diffDays = ZZTimeHelper.UtcNow() - startTime;
if (diffDays.Days < 1)
startTime += TimeSpan.FromDays(1);
else
startTime += TimeSpan.FromDays(diffDays.Days);
}
Log($"ScheduleBotTargetResolved slotId={SlotId} startTime={startTime} targetScore={newBotTargetScore}");
var scheduleDuration = Random.Range( tbEventPartnerConfig.RobotSingleAddPointsTimeWindow[0], tbEventPartnerConfig.RobotSingleAddPointsTimeWindow[1]);
var scheduleAmount = Random.Range( tbEventPartnerConfig.RobotSingleAddPointsOperations[0], tbEventPartnerConfig.RobotSingleAddPointsOperations[1]);
var timeSet = new HashSet<int>();
for (var i = 0; i < scheduleAmount; ++i)
{
timeSet.Add(Random.Range(1, scheduleDuration));
}
scheduleAmount = timeSet.Count;
// while (timeSet.Count < scheduleAmount)
// {
// var tRandom.Range( tbEventPartnerConfig.RobotSingleAddPointsTimeWindow[0], tbEventPartnerConfig.RobotSingleAddPointsTimeWindow[1]);
// timeSet.Add(Random.Range(1, scheduleDuration + 1));
// }
var timeList = timeSet.OrderBy(t => t).ToList();
BotTargetScore = newBotTargetScore;
var botScore = ScorePartnerActual;
var gap = newBotTargetScore - botScore;
gap = Mathf.Clamp(gap,0,gap);
if (gap <= 0)
{
return;
}
if (!FtUtils.RandomSplit(gap, scheduleAmount, out var scoreList))
LogWarning($"RandomSplitFailed slotId={SlotId} gap={gap} scheduleAmount={scheduleAmount}");
ELog($"ScheduleBotPlan slotId={SlotId} wakeTime={WakeStartTime} startTime={startTime} durationSec={scheduleDuration} gap={gap} scheduleAmount={scheduleAmount}");
ELog($"ScheduleBotActivation slotId={SlotId} activationDelay={startTime - WakeStartTime} botGrade={BotGrade}");
var minWheelNumber = tbEventPartnerConfig.RobotPointsMultiple2;
// 获得积分
// if (true)
// if(_manager.startTime > 0 && _manager.delta > 0)
// {
// startTime = ZZTimeHelper.UtcNow().AddSeconds(_manager.startTime);
//
// for (var i = 0; i < scheduleAmount; ++i)
// {
// timeList[i] = _manager.delta * (i + 1);
// }
// }
// if (true)
// {
//
// var startDelta = 5f;
// var deltaF = 2;
// startTime = ZZTimeHelper.UtcNow().AddSeconds(startDelta);
// for (var i = 0; i < timeList.Count; ++i)
// {
// timeList[i] = deltaF * (i + 1);
// }
// }
// var count = scoreList.Count;
for (int i = 0; i < scheduleAmount; i++)
{
FtUtils.ScaleByBase(scoreList[i], minWheelNumber, out var score);
newActionQ.Enqueue(new EventBuildBotAddScoreAction
{
Score = score,
Time = startTime + TimeSpan.FromSeconds(timeList[i])
});
}
Cache.ActionQ[SlotId] = newActionQ;
GContext.Publish(new EventSavePartnerInfoCache());
LogActions(newActionQ);
}
[Conditional("UNITY_EDITOR")]
private void LogActions(Queue<EventBuildBotAddScoreAction> newActionQ)
{
foreach (var a in newActionQ)
{
ELog($"ScheduleBotQueueAdd slotId={SlotId} score={a.Score} time={a.Time}");
}
}
private static void Log(string t)
{
Debug.Log($"<color=cyan>BuildParner-> {t} </color>");
}
private static void ELog(string t)
{
#if UNITY_EDITOR
Debug.Log($"<color=cyan>BuildParner-> {t} </color>");
#endif
}
private static void LogWarning(string t)
{
Debug.LogWarning($"<color=yellow>BuildParner-> {t} </color>");
}
public void UpdateRobotInfo(BotResult botResult)
{
if (PartnerId.Equals(botResult.playfabId))
{
BotGrade = botResult.grade;
WakeStartTime = botResult.wakeStartTime;
WakingSeconds = botResult.wakingSeconds;
}
}
public int GetExtraScore()
{
// return Score - ScorePartnerDisplay - ScoreSelfDisplay;
return Mathf.Clamp(ScorePartnerActual - ScorePartnerDisplay,0,MaxScore);
}
}
}