Files
ft/Client/Assets/Scripts/UI/PartnerStatue/EventPartnerStatueArc.cs
2026-06-29 21:18:33 +08:00

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();
}