739 lines
28 KiB
C#
739 lines
28 KiB
C#
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using asap.core;
|
|
using cfg;
|
|
using UnityEngine;
|
|
using System.Linq;
|
|
using System;
|
|
using GameCore;
|
|
using ScrollViewItemInfo = EventPartnerScrollViewItem.ScrollViewItemInfo;
|
|
using EScrollViewType = EventPartnerScrollViewItem.EScrollViewType;
|
|
using EventPartner;
|
|
using EventPartnerGather;
|
|
using game;
|
|
using EventPartnerGatherRequests;
|
|
using UniRx;
|
|
using AutoMatchStatusResponse = EventPartnerGatherRequests.AutoMatchStatusResponse;
|
|
using AutoMatchToggleResponse = EventPartnerGatherRequests.AutoMatchToggleResponse;
|
|
using Robot = EventPartner.Robot;
|
|
|
|
public class EventPartnerStatueArc : IEventPartnerArchitecture, IAutoMatchManagerContext, IDisposable
|
|
{
|
|
public IEventAggregator EventAggregator { get; set; } = new EventAggregator();
|
|
// private bool _isWhole = false;
|
|
|
|
#region Models
|
|
public EventPartnerStatueTableContext TableContext;
|
|
public ITableContext Ctx => TableContext;
|
|
private Model _model;
|
|
public InvitationData InvitationData { get; set; }
|
|
public PlayerInfoPool PlayerInfoPool = new PlayerInfoPool();
|
|
public RobotDataManager RobotData;
|
|
public EventPartnerStatueBuff Buff = new EventPartnerStatueBuff();
|
|
#endregion
|
|
|
|
public Model Model => _model;
|
|
private IDisposable _botAddSub;
|
|
public bool IsFirstTime { get; set; }
|
|
|
|
public EventPartnerStatueArc()
|
|
{
|
|
_botAddSub = EventAggregator.GetEvent<EventBotAdd>().Subscribe(OnBotAdd);
|
|
}
|
|
|
|
#region DataStorage
|
|
|
|
private DateTime _lastDetailRefreshTime = DateTime.MinValue;
|
|
public bool DoRefreshDetail => ZZTimeHelper.UtcNow() - _lastDetailRefreshTime > TimeSpan.FromSeconds(15);
|
|
public static async void Load(cfg.FishingEvent e)
|
|
{
|
|
try
|
|
{
|
|
var arc = GContext.container.Resolve<EventPartnerStatueArc>();
|
|
if (arc == null)
|
|
{
|
|
GContext.container.Register<EventPartnerStatueArc>().AsSingleton();
|
|
arc = GContext.container.Resolve<EventPartnerStatueArc>();
|
|
}
|
|
arc.TableContext = new EventPartnerStatueTableContext(e.ID);
|
|
arc.SetUiData();
|
|
var ppData = EventPartnerStatuePlayerPreferenceCache.Load(e.ID);
|
|
var pfData = EventPartnerStatuePlayfabData.Load();
|
|
if (pfData == null || pfData.EventId != e.ID) // new event
|
|
{
|
|
arc._model = new Model(arc);
|
|
arc.Model.SetTicketCount(arc.TableContext.GetInitGift());
|
|
arc.Model.LureInflationRate = GContext.container.Resolve<PlayerData>().InflationRate;
|
|
arc.Model.ComponentList = new List<BuildComponent>();
|
|
arc.Model.IsFinalRewardClaimed = false;
|
|
|
|
arc.InvitationData = new InvitationData(arc);
|
|
arc.InvitationData.Init(ppData.RecommendCache.RefusePfIds.ToHashSet(), ppData.RecommendCache);
|
|
|
|
arc.PlayerInfoPool = new PlayerInfoPool();
|
|
arc.PlayerInfoPool.Init(arc);
|
|
|
|
arc.RobotData = new RobotDataManager(arc);
|
|
|
|
arc.Buff = new EventPartnerStatueBuff();
|
|
arc.Buff.Init(arc);
|
|
|
|
arc.Requests ??= new RequestSystem();
|
|
arc.Requests.Init(e.ID);
|
|
|
|
arc.RtSystem ??= new RtSystem();
|
|
// arc.RtSystem = new RtSystem();
|
|
|
|
arc.EventTrackingSystem = new EventPartnerStatueEventTrackingSystem();
|
|
|
|
arc.IsFirstTime = true;
|
|
arc._isAutoMatchEnabled = false;
|
|
arc._lastAutoMatchTimeUtc = DateTime.MinValue;
|
|
|
|
arc.SavePlayfab();
|
|
}
|
|
else // old event
|
|
{
|
|
arc._model ??= new Model(arc);
|
|
arc.Model.SetTicketCount(pfData.TicketCount);
|
|
arc.Model.LureInflationRate = pfData.LureInflationRate;
|
|
arc.Model.IsFinalRewardClaimed = pfData.IsFinalRewardClaimed;
|
|
|
|
arc.InvitationData ??= new InvitationData(arc);
|
|
arc.InvitationData.Init(ppData.RecommendCache.RefusePfIds.ToHashSet(), ppData.RecommendCache);
|
|
|
|
arc.PlayerInfoPool = new PlayerInfoPool();
|
|
arc.PlayerInfoPool.Init(arc);
|
|
|
|
arc.RobotData ??= new RobotDataManager(arc);
|
|
arc.RobotData.RobotList = ppData.RobotDataCache.ToDictionary(kv => kv.Key, kv => new Robot(kv.Value, arc));
|
|
arc.RobotData.RobotInvitationBuffer = ppData.RobotInvitationCache;
|
|
|
|
arc.Buff ??= new EventPartnerStatueBuff();
|
|
arc.Buff.Init(arc);
|
|
|
|
arc.Requests ??= new RequestSystem();
|
|
arc.Requests.Init(e.ID);
|
|
|
|
arc.RtSystem ??= new RtSystem();
|
|
// arc.RtSystem = new RtSystem();
|
|
|
|
arc.IsFirstTime = ppData.IsFirstTime;
|
|
arc._isAutoMatchEnabled = pfData.IsEnableAutoMatch;
|
|
arc._lastAutoMatchTimeUtc = pfData.LastAutoMatchTimeUtc;
|
|
|
|
arc.EventTrackingSystem = new EventPartnerStatueEventTrackingSystem();
|
|
}
|
|
// GContext.container.Resolve<OfferRushDataProvider>().EventRefresh(e, arc.TableContext.GetRushId(), RushType.OneDataKey);
|
|
var detail = await arc.Requests.GetDetail();
|
|
if (detail == null)
|
|
{
|
|
Debug.LogWarning("[EventPartnerStatue]: Get Detail failed.");
|
|
return;
|
|
}
|
|
arc.ResolveWithDetail(detail, pfData);
|
|
arc.RobotData.StartRobotLoop();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.LogError(ex);
|
|
}
|
|
}
|
|
|
|
public static void EnsureTokenExchangeContextRegistered(EventPartnerStatueArc arc)
|
|
{
|
|
var context = GContext.container.Resolve<IEventPartnerTokenExchangeContext>();
|
|
if (context == null || context is not EventPartnerStatueTokenExchangeArcContext)
|
|
{
|
|
GContext.container.Unregister<IEventPartnerTokenExchangeContext>();
|
|
GContext.container.Register<IEventPartnerTokenExchangeContext, EventPartnerStatueTokenExchangeArcContext>().AsSingleton();
|
|
context = GContext.container.Resolve<IEventPartnerTokenExchangeContext>();
|
|
}
|
|
if (context is EventPartnerStatueTokenExchangeArcContext tokenExchangeContext)
|
|
tokenExchangeContext.BindArc(arc);
|
|
// EventPartnerTokenExchangeContextRegistry.Context = context;
|
|
}
|
|
|
|
private void SetUiData()
|
|
{
|
|
UITypes.EventPartnerStatuePanel.SetType(TableContext.GetMainPanelUrl());
|
|
UITypes.EventPartnerStatueBuildPanel.SetType(TableContext.GetBuildPanelUrl());
|
|
UITypes.EventPartnerStatueInfoPopupPanel.SetType(TableContext.GetInfoPanelUrl());
|
|
UITypes.EventPartnerStatuePackPanel.SetType(TableContext.GetPackPanelUrl());
|
|
// UITypes.EventPartnerStatueInvitationPanel.SetType(arc.TableContext.GetInvitePanelUrl());
|
|
}
|
|
|
|
public void ResolveWithDetail(EventPartnerGatherRequests.EventPartnerGatherDetail detail, EventPartnerStatuePlayfabData pfData)
|
|
{
|
|
var selfPfId = GContext.container.Resolve<IUserService>().UserId;
|
|
var maxScore = TableContext.GetMaxScore();
|
|
|
|
_model.ComponentList = new List<BuildComponent>();
|
|
for (int i = 0; i < detail.Partners.Count; i++)
|
|
{
|
|
var playfabId = detail.Partners[i].PlayFabId;
|
|
int scoreSelf, scorePartner;
|
|
if (RobotDataManager.IsRobot(playfabId))
|
|
{
|
|
if (pfData == null || pfData.RobotScoreMap == null)
|
|
{
|
|
scoreSelf = 0;
|
|
scorePartner = 0;
|
|
}
|
|
else
|
|
(scoreSelf, scorePartner) = pfData.RobotScoreMap.TryGetValue(playfabId, out var score) ? score : (0, 0);
|
|
if (!RobotData.RobotList.ContainsKey(playfabId))
|
|
{
|
|
RobotData.CreateBotDataToRobotList(playfabId);
|
|
RobotData.RobotList[playfabId].Schedule(scorePartner, scorePartner + scoreSelf);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
scoreSelf = detail.Scores[i].TryGetValue(selfPfId, out var s) ? s : 0;
|
|
scorePartner = detail.Scores[i].TryGetValue(playfabId, out s) ? s : 0;
|
|
}
|
|
(scoreSelf, scorePartner) = MaxScoreExceedingCheck(scoreSelf, scorePartner, TableContext.GetMaxScore());
|
|
|
|
(int displaySelf, int displayPartner) = pfData != null && pfData.DisplayScoreMap.TryGetValue(playfabId, out var display) ? display : (0, 0);
|
|
var scoreSelfDisplay = Mathf.Min(displaySelf, scoreSelf);
|
|
var scorePartnerDisplay = Mathf.Min(displayPartner, scorePartner);
|
|
|
|
_model.ComponentList.Add(new BuildComponent(i, maxScore, this, playfabId, scoreSelf, scorePartner, scoreSelfDisplay, scorePartnerDisplay));
|
|
}
|
|
|
|
PlayerInfoPool.FillInDetail(detail);
|
|
|
|
InvitationData.FillInDetail(_model.PartnerIdSet, detail);
|
|
// _isWhole = true;
|
|
_lastDetailRefreshTime = ZZTimeHelper.UtcNow();
|
|
|
|
SavePlayfab();
|
|
}
|
|
|
|
private (int scoreSelfAfter, int scorePartnerAfter) MaxScoreExceedingCheck(int scoreSelf, int scorePartner, int maxScore)
|
|
{
|
|
int scoreSelfAfter = Mathf.Clamp(scoreSelf, 0, maxScore);
|
|
int scorePartnerAfter = Mathf.Clamp(scorePartner, 0, maxScore);
|
|
if (scoreSelfAfter + scorePartnerAfter > maxScore)
|
|
{
|
|
scorePartnerAfter = maxScore - scoreSelfAfter;
|
|
}
|
|
return (scoreSelfAfter, scorePartnerAfter);
|
|
}
|
|
|
|
// public void UpdateScoreWithDetail
|
|
|
|
public EventPartnerStatuePlayfabData ToPlayfabData()
|
|
{
|
|
var data = new EventPartnerStatuePlayfabData();
|
|
data.EventId = TableContext.EventId;
|
|
data.TicketCount = Model.TicketCount;
|
|
data.BuffFreeMultiplier = Buff.FreeMultiplier == null ? -1 : Buff.FreeMultiplier.Value;
|
|
data.BuffPointExpiryTime = Buff.PointBonusExpiryTime == null ? ZZTimeHelper.UtcNow() - TimeSpan.FromDays(365) : Buff.PointBonusExpiryTime.Value;
|
|
data.DisplayScoreMap = Model.ComponentList.ToDictionary(x => x.PartnerId, x => (x.ScoreSelfDisplay, x.ScorePartnerDisplay));
|
|
data.RobotScoreMap = Model.ComponentList.Where(x => RobotDataManager.IsRobot(x.PartnerId))
|
|
.ToDictionary(x => x.PartnerId, x => (x.ScoreSelfActual, x.ScorePartnerActual));
|
|
data.LureInflationRate = Model.LureInflationRate;
|
|
data.IsFinalRewardClaimed = Model.IsFinalRewardClaimed;
|
|
data.IsEnableAutoMatch = _isAutoMatchEnabled;
|
|
data.LastAutoMatchTimeUtc = _lastAutoMatchTimeUtc;
|
|
return data;
|
|
}
|
|
|
|
public EventPartnerStatuePlayerPreferenceCache ToPlayerPreferenceCache()
|
|
{
|
|
var cache = new EventPartnerStatuePlayerPreferenceCache(TableContext.EventId);
|
|
cache.RecommendCache = InvitationData.ToCache();
|
|
cache.RobotDataCache = RobotData.RobotList.ToDictionary(kv => kv.Key, kv => kv.Value.ToPpData());
|
|
cache.RobotInvitationCache = RobotData.RobotInvitationBuffer;
|
|
cache.Buff = Buff;
|
|
cache.IsFirstTime = IsFirstTime;
|
|
return cache;
|
|
}
|
|
|
|
public void SavePlayerPreference()
|
|
{
|
|
ToPlayerPreferenceCache().Save();
|
|
}
|
|
|
|
public void SavePlayfab()
|
|
{
|
|
ToPlayfabData().Save();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region UIData
|
|
public EventPartnerStatueMainPanelData GetEventPartnerStatueMainPanelData()
|
|
{
|
|
var res = new EventPartnerStatueMainPanelData();
|
|
res.TicketCount = Model.TicketCount;
|
|
var partnerCount = TableContext.GetMaxPartnerCount();
|
|
res.SlotViewDataList = new EventPartnerStatueSlotViewData[partnerCount];
|
|
for (int i = 0; i < partnerCount; i++)
|
|
{
|
|
if (i < Model.ComponentList.Count)
|
|
{
|
|
var component = Model.ComponentList[i];
|
|
var playerInfo = PlayerInfoPool.Get(component.PartnerId);
|
|
var stage = TableContext.GetStageFromTotalScore(component.ScoreDisplayTotal);
|
|
var progress = TableContext.GetPercentageWithinStage(component.ScoreDisplayTotal);
|
|
var reward = TableContext.GetNextRewardFromScore(component.ScoreDisplayTotal);
|
|
if (stage >= TableContext.GetScoreStageList().Count) // Show Final Reaward for this component, not actual reward.
|
|
reward = null;
|
|
var scoreToAdd = component.ScorePartnerActual - component.ScorePartnerDisplay;
|
|
var isClaimed = component.IsRewardClaimed;
|
|
res.SlotViewDataList[i] = new EventPartnerStatueSlotViewData
|
|
{
|
|
Index = i,
|
|
IsEmpty = false,
|
|
Info = playerInfo,
|
|
Stage = stage,
|
|
Progress = progress,
|
|
Reward = reward,
|
|
ScoreToAdd = scoreToAdd,
|
|
IsClaimed = isClaimed
|
|
};
|
|
}
|
|
else
|
|
{
|
|
var hasInvitation = InvitationData != null && InvitationData.RequestPfIdSet != null && InvitationData.RequestPfIdSet.Count > 0 && !IsFull();
|
|
res.SlotViewDataList[i] = new EventPartnerStatueSlotViewData { IsEmpty = true, Index = i, HasInvitation = hasInvitation };
|
|
}
|
|
}
|
|
var (StartTime, EndTime) = TableContext.GetEventTimeLimit();
|
|
res.TimerContext = new TimerContext
|
|
{
|
|
StartTime = StartTime,
|
|
ExpiryTime = EndTime,
|
|
};
|
|
res.GrandRewardList = TableContext.GetFinalRewardList();
|
|
res.BuildStatus = Model.BuildStatus;
|
|
return res;
|
|
}
|
|
|
|
public EventPartnerStatueBuildPanelData GetEventPartnerStatueBuildPanelData(int slotIdx)
|
|
{
|
|
var _userService = GContext.container.Resolve<IUserService>();
|
|
var res = new EventPartnerStatueBuildPanelData();
|
|
res.InfoSelf = new PlayerInfo
|
|
{
|
|
PlayFabId = _userService.UserId,
|
|
DisplayName = _userService.DisplayName,
|
|
AvatarUrl = _userService.AvatarUrl,
|
|
};
|
|
res.InfoPartner = PlayerInfoPool.Get(Model.ComponentList[slotIdx].PartnerId);
|
|
res.ScoreSelf = Model.ComponentList[slotIdx].ScoreSelfDisplay;
|
|
res.ScorePartner = Model.ComponentList[slotIdx].ScorePartnerDisplay;
|
|
res.ProgressData = new EventPartnerStatueBuildProgressData
|
|
{
|
|
Stage = TableContext.GetStageFromTotalScore(Model.ComponentList[slotIdx].ScoreDisplayTotal),
|
|
Scores = TableContext.GetScoreStageList().ToArray(),
|
|
Progress = TableContext.GetPercentageWithinStage(Model.ComponentList[slotIdx].ScoreDisplayTotal),
|
|
RewardList = TableContext.GetRewardList(),
|
|
};
|
|
res.TicketCount = Model.TicketCount;
|
|
res.SlotIdx = slotIdx;
|
|
return res;
|
|
}
|
|
|
|
public EventPartnerStatueBuildSceneData GetEventPartnerStatueBuildSceneData(int slotIdx)
|
|
{
|
|
return new EventPartnerStatueBuildSceneData()
|
|
{
|
|
SlotIdx = slotIdx,
|
|
Stage = TableContext.GetStageFromTotalScore(Model.ComponentList[slotIdx].ScoreDisplayTotal),
|
|
MaxStage = TableContext.GetScoreStageList().Count,
|
|
};
|
|
}
|
|
|
|
public EventPartnerStatueEntranceData GetEntranceData()
|
|
{
|
|
var res = new EventPartnerStatueEntranceData();
|
|
var (StartTime, EndTime) = TableContext.GetEventTimeLimit();
|
|
res.TimerContext = new TimerContext
|
|
{
|
|
StartTime = StartTime,
|
|
ExpiryTime = EndTime,
|
|
};
|
|
res.IconUrl = TableContext.GetEntranceIconUrl();
|
|
res.TicketCount = Model.TicketCount;
|
|
res.HasInvitation = InvitationData != null && InvitationData.RequestPfIdSet != null && InvitationData.RequestPfIdSet.Count > 0 && !IsFull();
|
|
res.HasPartnerScore = Model != null && Model.ComponentList != null && Model.ComponentList.Any(c => c.ScorePartnerActual > c.ScorePartnerDisplay)
|
|
&& !Model.ComponentList.All(c => c.IsRewardClaimed);
|
|
return res;
|
|
}
|
|
|
|
public bool IsActive
|
|
{
|
|
get
|
|
{
|
|
var (StartTime, EndTime) = TableContext.GetEventTimeLimit();
|
|
var now = ZZTimeHelper.UtcNow();
|
|
return now >= StartTime && now <= EndTime;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region IAutoMatchManagerContext
|
|
|
|
public int EventId => TableContext?.EventId ?? -1;
|
|
public bool ShouldCloseAutoMatch => IsFull();
|
|
public bool IsAutoMatchEnabled => _isAutoMatchEnabled;
|
|
private bool _isAutoMatchEnabled;
|
|
private DateTime _lastAutoMatchTimeUtc = DateTime.MinValue;
|
|
|
|
public void SetLastAutoMatchTimeUtc(DateTime utc)
|
|
{
|
|
_lastAutoMatchTimeUtc = utc;
|
|
SavePlayfab();
|
|
}
|
|
|
|
/// <summary>与 EventPartnerGatherManager.CanStopAutoMatch 一致:未满员且距上次开启未满 AutoMatchCD 时不可关闭。</summary>
|
|
public bool CanStopAutoMatch(out int leftTimes)
|
|
{
|
|
leftTimes = -1;
|
|
if (IsFull())
|
|
return false;
|
|
|
|
var cooldownSeconds = GContext.container.Resolve<Tables>().TbEventPartnerConfig.AutoMatchCD;
|
|
var elapsed = (DateTime.UtcNow - _lastAutoMatchTimeUtc).TotalSeconds;
|
|
leftTimes = (int)Math.Floor(cooldownSeconds - elapsed);
|
|
leftTimes = leftTimes > 0 ? leftTimes : 0;
|
|
return elapsed >= cooldownSeconds;
|
|
}
|
|
|
|
public void SetAutoMatchEnabled(bool enabled)
|
|
{
|
|
_isAutoMatchEnabled = enabled;
|
|
SavePlayfab();
|
|
}
|
|
|
|
public async Task<AutoMatchStatusResponse> FetchAndProcessAutoMatchStatus(bool force = true)
|
|
{
|
|
var response = await Requests.GetAutoMatchStatus();
|
|
if (response?.State == EEventBuildState.Success && response?.Partners is { Count: > 0 } && !ShouldCloseAutoMatch)
|
|
{
|
|
var addedAny = false;
|
|
var maxPartners = TableContext.GetMaxPartnerCount();
|
|
for (var i = 0; i < response.Partners.Count; ++i)
|
|
{
|
|
if (IsFull()) break;
|
|
if (i >= maxPartners) break;
|
|
var partner = response.Partners[i];
|
|
if (partner == null || RobotDataManager.IsRobot(partner.PlayFabId)) continue;
|
|
if (Model.ComponentList.Any(c => c.PartnerId == partner.PlayFabId)) continue;
|
|
PlayerInfoPool.Add(partner);
|
|
var idx = AddPartner(partner.PlayFabId);
|
|
if (idx >= 0)
|
|
addedAny = true;
|
|
}
|
|
if (addedAny)
|
|
SavePlayfab();
|
|
}
|
|
return response;
|
|
}
|
|
|
|
public async Task<AutoMatchToggleResponse> ControlAutoMatch(bool enable)
|
|
{
|
|
return await Requests.ControlAutoMatch(enable);
|
|
}
|
|
|
|
public void NotifyAutoMatchStopped()
|
|
{
|
|
GContext.Publish(new EventForAutoMatchChangeStage { State = AutoMatchState.AutoMatchOff });
|
|
}
|
|
|
|
public void NotifyAutoMatchFailed(string reason)
|
|
{
|
|
GContext.Publish(new EventAutoMatchFailed { Reason = reason });
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region System
|
|
public RequestSystem Requests { get; set; }
|
|
public RtSystem RtSystem { get; set; }
|
|
public EventPartnerStatueEventTrackingSystem EventTrackingSystem { get; set; }
|
|
/// <summary>
|
|
/// Roll with a cost. Returns the point and combination.
|
|
/// </summary>
|
|
/// <param name="cost">The cose of this roll and the multiplier as well.</param>
|
|
/// <returns>Result point and combination</returns>
|
|
public (int point, (int c1, int c2, int c3)) Roll(int cost)
|
|
{
|
|
var freeMultiplier = Buff.ConsumeFreeBuff();
|
|
if (freeMultiplier != -1)
|
|
{
|
|
cost = freeMultiplier;
|
|
EventTrackingSystem.RollIsFree = 1;
|
|
}
|
|
else
|
|
{
|
|
var res = Model.AddTicket(-cost);
|
|
if (!res)
|
|
{
|
|
Debug.Log($"[EventPartner] Failed to add ticket. Cost: {cost}, Current: {Model.TicketCount}");
|
|
return (-1, (-1, -1, -1));
|
|
}
|
|
EventTrackingSystem.RollIsFree = 0;
|
|
}
|
|
EventTrackingSystem.RollMultiplier = cost;
|
|
(var point, var combination) = TableContext.GenerateSpinResult();
|
|
EventTrackingSystem.RollIsMore = Buff.GetMoreBuff() > 0 ? 1 : 0;
|
|
point = FtUtils.RoundToInt(point * (1 + Buff.GetMoreBuff()));
|
|
if (combination == TableContext.GetFreeDisplayCombination())
|
|
Buff.CreateFreeBuff(cost);
|
|
else if (combination == TableContext.GetMoreDisplayCombination())
|
|
Buff.CreateMoreBuff();
|
|
point *= cost;
|
|
return (point, combination);
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
public (int point, (int c1, int c2, int c3)) RollTest(int point, (int c1, int c2, int c3) c, int cost)
|
|
{
|
|
var freeMultiplier = Buff.ConsumeFreeBuff();
|
|
point = FtUtils.RoundToInt(point * (1 + Buff.GetMoreBuff()));
|
|
if (c == TableContext.GetFreeDisplayCombination())
|
|
Buff.CreateFreeBuff(cost);
|
|
else if (c == TableContext.GetMoreDisplayCombination())
|
|
Buff.CreateMoreBuff();
|
|
point *= cost;
|
|
return (point, c);
|
|
}
|
|
#endif
|
|
|
|
public List<ItemData> TryGetStageReward(string partnerId)
|
|
{
|
|
for (int i = 0; i < Model.ComponentList.Count; i++)
|
|
{
|
|
if (Model.ComponentList[i].PartnerId == partnerId)
|
|
return TryGetStageReward(i);
|
|
}
|
|
return new List<ItemData>();
|
|
}
|
|
|
|
public List<ItemData> TryGetStageReward(int slotIdx)
|
|
{
|
|
var c = Model.ComponentList[slotIdx];
|
|
var currentStage = TableContext.GetStageFromTotalScore(c.ScoreTotal);
|
|
var displayStage = TableContext.GetStageFromTotalScore(c.ScoreDisplayTotal);
|
|
var ids = new List<int>();
|
|
var res = new List<ItemData>();
|
|
if (displayStage >= currentStage)
|
|
return res;
|
|
for (int s = displayStage + 1; s <= currentStage; s++)
|
|
{
|
|
var dropId = TableContext.GetRewardDropIdFromStage(s);
|
|
ids.Add(dropId);
|
|
}
|
|
Debug.Log($"[EventPartnerStatue] Add reward drop id list: {Newtonsoft.Json.JsonConvert.SerializeObject(ids)}");
|
|
if (RobotDataManager.IsRobot(c.PartnerId) && currentStage < TableContext.GetScoreStageList().Count)
|
|
{
|
|
RobotData.RobotList[c.PartnerId].Schedule(c.ScorePartnerActual, c.ScoreTotal);
|
|
}
|
|
res = GContext.container.Resolve<PlayerItemData>().GetItemDataListFromListOfSingleDropId(ids);
|
|
GContext.container.Resolve<PlayerItemData>().LureInflation(res, Model.LureInflationRate);
|
|
return res;
|
|
}
|
|
|
|
public void TryGrantFinalReward()
|
|
{
|
|
if (Model.IsFinalRewardClaimed)
|
|
return;
|
|
if (Model.ComponentList.Count < TableContext.GetMaxPartnerCount()
|
|
|| Model.ComponentList.Any(x => !x.IsDone))
|
|
return;
|
|
if (Model.ComponentList.Any(x => !x.IsRewardClaimed)) // Not the time yet
|
|
return;
|
|
|
|
ChangeSource changeSource = new ChangeSource(TableContext.EventId, "Event_Minigame4", "Event_Minigame4_Partner", "GrandReward");
|
|
var rewardItems = GContext.container.Resolve<PlayerItemData>().AddItemByDropLureInflation(Model.LureInflationRate, TableContext.GetFinalRewardDropId(), changeSource);
|
|
GContext.Publish(new ShowData());
|
|
Model.IsFinalRewardClaimed = true;
|
|
|
|
EventTrackingSystem.RewardPartnerId = "final";
|
|
EventTrackingSystem.RewardSlotId = 99;
|
|
EventTrackingSystem.RewardStageId = 99;
|
|
EventTrackingSystem.RewardHook = rewardItems.Where(r => r.id == 1001).Sum(r => r.count);
|
|
EventTrackingSystem.ReportReward();
|
|
|
|
SavePlayfab();
|
|
}
|
|
|
|
public bool IsFull()
|
|
{
|
|
return Model.ComponentList.Count >= TableContext.GetMaxPartnerCount();
|
|
}
|
|
|
|
public int AddPartner(string partnerId)
|
|
{
|
|
var maxScore = TableContext.GetMaxScore();
|
|
var idx = Model.ComponentList.Count;
|
|
if (idx >= TableContext.GetMaxPartnerCount())
|
|
{
|
|
Debug.LogError("[EventPartner] Max partner count reached.");
|
|
return -1;
|
|
}
|
|
Model.ComponentList.Add(new BuildComponent(idx, maxScore, this, partnerId));
|
|
var d = new EventPartnerStatueSlotViewData
|
|
{
|
|
Index = idx,
|
|
IsEmpty = false,
|
|
Info = PlayerInfoPool.Get(partnerId),
|
|
Stage = 0,
|
|
Progress = 0,
|
|
Reward = TableContext.GetNextRewardFromScore(0),
|
|
ScoreToAdd = 0
|
|
};
|
|
EventAggregator.Publish(d);
|
|
return idx;
|
|
}
|
|
|
|
public (bool isMax, int idx, int multiplier) GetCurrentMultiplier(int currentIdx)
|
|
{
|
|
var ticketCount = Model.TicketCount;
|
|
var list = TableContext.GetMultiplierList();
|
|
bool isMax = false;
|
|
currentIdx %= list.Count;
|
|
var multiplier = list[currentIdx];
|
|
while (multiplier > ticketCount && currentIdx > 0)
|
|
{
|
|
currentIdx--;
|
|
multiplier = list[currentIdx];
|
|
}
|
|
if (currentIdx == list.Count - 1)
|
|
isMax = true;
|
|
if (multiplier >= ticketCount)
|
|
isMax = true;
|
|
return (isMax, currentIdx, multiplier);
|
|
}
|
|
|
|
public (bool isMax, int idx, int multiplier) GetNextMultiplier(int currentIdx)
|
|
{
|
|
var ticketCount = Model.TicketCount;
|
|
var list = TableContext.GetMultiplierList();
|
|
bool isMax = false;
|
|
currentIdx = (currentIdx + 1) % list.Count;
|
|
var multiplier = list[currentIdx];
|
|
if (multiplier > ticketCount)
|
|
{
|
|
currentIdx = 0;
|
|
multiplier = list[0];
|
|
}
|
|
if (currentIdx >= list.Count - 1)
|
|
isMax = true;
|
|
else if (list[currentIdx + 1] > ticketCount)
|
|
isMax = true;
|
|
return (isMax, currentIdx, multiplier);
|
|
}
|
|
|
|
public (bool isMax, int idx, int multiplier) GetInitMultiplier()
|
|
{
|
|
var ticketCount = Model.TicketCount;
|
|
var list = TableContext.GetMultiplierList();
|
|
bool isMax = true;
|
|
var currentIdx = list.Count - 1;
|
|
while (currentIdx > 0 && list[currentIdx] > ticketCount)
|
|
currentIdx--;
|
|
return (isMax, currentIdx, list[currentIdx]);
|
|
}
|
|
|
|
public ScrollViewItemInfo GetScrollViewItemInfo(string partnerId, EScrollViewType type)
|
|
{
|
|
var partner = PlayerInfoPool.Get(partnerId);
|
|
return new ScrollViewItemInfo
|
|
{
|
|
Type = type,
|
|
PlayfabId = partnerId,
|
|
DisplayName = partner.DisplayName,
|
|
AvatarUrl = partner.AvatarUrl,
|
|
Level = partner.Level,
|
|
};
|
|
}
|
|
|
|
public void OnPartnerChange(EventPartnerGatherPartnerEvt e)
|
|
{
|
|
var arc = GContext.container.Resolve<EventPartnerStatueArc>();
|
|
PlayerInfoPool.Add(e.PartnerInfo);
|
|
switch (e.EvtType)
|
|
{
|
|
// invite
|
|
case 0:
|
|
InvitationData.OnRequest(e.PartnerInfo.PlayFabId);
|
|
break;
|
|
// accept
|
|
case 1:
|
|
var slotId = AddPartner(e.PartnerInfo.PlayFabId);
|
|
|
|
arc.EventTrackingSystem.InvitePartnerId = RobotDataManager.IsRobot(e.PartnerInfo.PlayFabId) ? "Robot" : e.PartnerInfo.PlayFabId;
|
|
arc.EventTrackingSystem.InviteSlotId = slotId;
|
|
arc.EventTrackingSystem.InviteId = 1;
|
|
arc.EventTrackingSystem.ReportInvite();
|
|
|
|
break;
|
|
// reject
|
|
case -1:
|
|
InvitationData.OnRefuse(e.PartnerInfo.PlayFabId);
|
|
break;
|
|
}
|
|
}
|
|
|
|
public void OnScore(EventPartnerGatherScoreEvt e)
|
|
{
|
|
var c = Model.ComponentList.FirstOrDefault(x => x.PartnerId == e.PartnerId);
|
|
if (c == null)
|
|
{
|
|
Debug.Log($"[EventPartnerStatue] Partner in score event not found: {e.PartnerId}");
|
|
return;
|
|
}
|
|
c.UpdatePartnerScore(e.Score);
|
|
}
|
|
|
|
public string GetRedPointKey()
|
|
{
|
|
return "partner.statue";
|
|
}
|
|
|
|
public bool HasPartnerScore()
|
|
{
|
|
foreach (var c in Model.ComponentList)
|
|
{
|
|
if (c.ScorePartnerActual > c.ScorePartnerDisplay)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private void OnBotAdd(EventBotAdd e)
|
|
{
|
|
EventTrackingSystem.InvitePartnerId = "Robot";
|
|
EventTrackingSystem.InviteSlotId = e.SlotId;
|
|
EventTrackingSystem.InviteId = 1;
|
|
EventTrackingSystem.ReportInvite();
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_botAddSub?.Dispose();
|
|
}
|
|
#endregion
|
|
}
|
|
|
|
|
|
public interface IEventPartnerArchitecture
|
|
{
|
|
public RequestSystem Requests { get; }
|
|
public ITableContext Ctx { get; }
|
|
public Model Model { get; }
|
|
public InvitationData InvitationData { get; }
|
|
public IEventAggregator EventAggregator { get; }
|
|
public bool IsFull();
|
|
public int AddPartner(string partnerId);
|
|
public void SavePlayerPreference();
|
|
public void SavePlayfab();
|
|
public string GetRedPointKey();
|
|
}
|