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

419 lines
16 KiB
C#

using UnityEngine;
using cfg;
using asap.core;
using System.Linq;
using GameCore;
using System.Collections.Generic;
namespace PinballUncountable
{
public class TableContext
{
private int _eventId, _cycleId, _redirectId;
private Tables _tables;
private EventPinballCountlessMain _tableMain;
private TbEventPinballCountlessPoint _tableTrajectory;
private TbEventPinballCountlessExit _tableExit;
private TbEventPinballCountlessReward _tableReward;
private TbEventPackManager _tableEventPackManager;
public int EventId => _eventId;
public TableContext() { }
public TableContext(int eventId)
{
_tables = GContext.container.Resolve<Tables>();
_eventId = eventId;
_cycleId = _tables.TbFishingEvent[_eventId].RedirectID;
_redirectId = _tables.TbFishingEventCycleItem[_cycleId].RedirectID;
_tableMain = _tables.TbEventPinballCountlessMain[_redirectId];
_tableTrajectory = _tables.TbEventPinballCountlessPoint;
_tableExit = _tables.TbEventPinballCountlessExit;
_tableReward = _tables.TbEventPinballCountlessReward;
_tableEventPackManager = _tables.TbEventPackManager;
}
public static TableContext InitTest()
{
var res = new TableContext();
res._eventId = 114514;
res._cycleId = 114514;
res._redirectId = 101;
res._tables = GContext.container.Resolve<Tables>();
res._tableMain = res._tables.TbEventPinballCountlessMain[res._redirectId];
res._tableTrajectory = res._tables.TbEventPinballCountlessPoint;
res._tableExit = res._tables.TbEventPinballCountlessExit;
res._tableReward = res._tables.TbEventPinballCountlessReward;
res._tableEventPackManager = res._tables.TbEventPackManager;
return res;
}
public int[] GetTrajectoryArrayFromEntranceIndex(int entranceIdx, int multiplier)
{
var res = new int[multiplier];
for (int i = 0; i < multiplier; i++)
{
var idx = FtUtils.GetRandomIdxFromWeightList(_tableTrajectory.DataList.Select(x => (int)x.Weight));
var idList = _tableTrajectory.DataList[idx].RoutineList[entranceIdx];
res[i] = idList[Random.Range(0, idList.Count)];
}
return res;
}
public int[] GetMultiplierArray()
{
return _tableMain.SpinMag.ToArray();
}
/// <summary>
/// Check point for specific exit
/// </summary>
/// <param name="idx">Index of exit, 0-based.</param>
/// <returns>Points</returns>
public int GetPointMagFromExitIndex(int idx)
{
var cIdx = Mathf.Clamp(idx, 0, _tableExit.DataList.Count - 1);
return _tableExit.DataList[cIdx].PointMag;
}
public int[] GetMaxDiscCount()
{
return _tableMain.DiscCollisionCount.ToArray();
}
public ItemData GetItemFromScore(int score, float inflationRate)
{
// var progressReward = _tableReward.DataList[^1].SpinPoint;
var rewardList = GetRewardListByScore(score);
var progressReward = rewardList[^1].SpinPoint;
var validPoint = score % progressReward;
int dropId = -1;
for (int i = 0; i < rewardList.Count; i++)
{
if (validPoint < rewardList[i].SpinPoint)
{
dropId = rewardList[i].DropID;
break;
}
}
if (dropId == -1)
return null;
Debug.Log($"[PinballUncountable] Get item by drop id {dropId}.");
var item = GContext.container.Resolve<PlayerItemData>().GetItemDataByDropIdAndTypeLureInflation(inflationRate, dropId)[0];
return item;
}
/// <summary>
/// Get reward to show on disc from total hit count
/// </summary>
/// <param name="hitCount">Total hit count</param>
/// <param name="idx">Index of disc</param>
/// <returns>Reward.</returns>
public ItemData GetItemFromHitCount(int hitCount, int idx, float inflationRate)
{
var dropList = _tableMain.DiscCollisionReward[idx];
var maxCount = _tableMain.DiscCollisionCount[idx];
var dropIdx = hitCount / maxCount % dropList.Count;
var item = GContext.container.Resolve<PlayerItemData>().GetItemDataByDropIdAndTypeLureInflation(inflationRate, dropList[dropIdx])[0];
return item;
}
public List<int> GetRewardDropIdListFromHitCount(int idx, int oldHitCount, int newHitCount)
{
var dropList = _tableMain.DiscCollisionReward[idx];
var maxCount = _tableMain.DiscCollisionCount[idx];
int oldRewardCount = oldHitCount / maxCount;
int newRewardCount = newHitCount / maxCount;
var res = new List<int>();
for (int i = oldRewardCount; i < newRewardCount; i++)
{
res.Add(dropList[i % dropList.Count]);
}
return res;
}
public (List<int> dropList, List<int> roundList) GetRewardDropIdListFromScore(int oldScore, int newScore)
{
var oldMaxScore = GetCurrentMaxScore(oldScore);
var newMaxScore = GetCurrentMaxScore(newScore);
var oldIdx = GetAbsoluteIndexFromScore(oldScore);
var newIdx = GetAbsoluteIndexFromScore(newScore);
int oldRound = GetRoundFromScore(oldScore);
int newRound = GetRoundFromScore(newScore);
var res = new List<int>();
var roundList = new List<int>();
// Different score list.
if (oldMaxScore != newMaxScore)
{
var oldDropList = GetRewardListByScore(oldScore);
var newDropList = GetRewardListByScore(newScore);
for (int i = oldIdx; i < oldDropList.Count; i++)
{
res.Add(oldDropList[i % oldDropList.Count].DropID);
roundList.Add(oldRound);
}
for (int i = 0; i < newIdx; i++)
{
res.Add(newDropList[i % newDropList.Count].DropID);
roundList.Add(newRound);
}
return (res, roundList);
}
// Same score list.
var dropList = GetRewardListByScore(oldScore);
for (int i = oldIdx; i < newIdx; i++)
{
res.Add(dropList[i % dropList.Count].DropID);
roundList.Add(oldRound);
}
return (res, roundList);
}
public int GetAbsoluteIndexFromScore(int score)
{
var firstRewardList = _tableMain.RewardFirst;
var loopRewardList = _tableMain.RewardLoop;
var firstMaxScore = _tableReward.DataMap[firstRewardList[^1]].SpinPoint;
var loopMaxScore = _tableReward.DataMap[loopRewardList[^1]].SpinPoint;
if (score <= firstMaxScore)
{
for (int i = 0; i < firstRewardList.Count; i++)
{
if (score < _tableReward.DataMap[firstRewardList[i]].SpinPoint)
{
return i;
}
}
return firstRewardList.Count;
}
else
{
score -= firstMaxScore;
var idx = score / _tableReward.DataMap[loopRewardList[^1]].SpinPoint * loopRewardList.Count;
score %= loopMaxScore;
for (int i = 0; i < loopRewardList.Count; i++)
{
if (score < _tableReward.DataMap[loopRewardList[i]].SpinPoint)
{
return i + idx;
}
}
return loopRewardList.Count + idx;
}
}
public int GetRewardIndexFromScore(int score)
{
var firstRewardList = _tableMain.RewardFirst;
var loopRewardList = _tableMain.RewardLoop;
var firstMaxScore = _tableReward.DataMap[firstRewardList[^1]].SpinPoint;
var loopMaxScore = _tableReward.DataMap[loopRewardList[^1]].SpinPoint;
if (score <= firstMaxScore)
{
for (int i = 0; i < firstRewardList.Count; i++)
{
if (score < _tableReward.DataMap[firstRewardList[i]].SpinPoint)
{
return i;
}
}
return firstRewardList.Count;
}
else
{
score -= firstMaxScore;
score %= loopMaxScore;
for (int i = 0; i < loopRewardList.Count; i++)
{
if (score < _tableReward.DataMap[loopRewardList[i]].SpinPoint)
{
return i;
}
}
return loopRewardList.Count;
}
// var dropList = GetRewardListByScore(score);
// int idx = score / dropList[^1].SpinPoint * dropList.Count;
// var scoreMod = score % dropList[^1].SpinPoint;
// for (int i = 0; i < dropList.Count; i++)
// if (scoreMod < dropList[i].SpinPoint)
// return i + idx;
// Debug.LogError("[PinballUncountable] This place is not supposed to be reached!");
// return -1;
}
/// <summary>
/// Get data for progress bar from certain score.
/// </summary>
/// <param name="score">Score. Can escape scope.</param>
/// <returns>index and corrosponding percentage.</returns>
public (int idx, float percentage) GetBarProgressDataFromScore(int score)
{
var dropList = GetRewardListByScore(score);
var scopedScore = GetScopeScoreFromActualScore(score);
for (int i = 0; i < dropList.Count; i++)
{
if (scopedScore < dropList[i].SpinPoint)
{
var idx = i;
var percentage = i == 0 ?
(float)scopedScore / dropList[i].SpinPoint
: (float)(scopedScore - dropList[i - 1].SpinPoint) / (dropList[i].SpinPoint - dropList[i - 1].SpinPoint);
return (idx, percentage);
}
}
// Debug.LogError("[PinballUncountable] This place is not supposed to be reached!");
// The score is first max here.
return (dropList.Count - 1, 1);
}
public List<PinballUncountableProgressRewardData> GetRewardsData(float inflationRate, int currentScore)
{
var currentIdx = GetRewardIndexFromScore(currentScore);
var dropList = GetRewardListByScore(currentScore);
var res = dropList.Select(
(x, i) => new PinballUncountableProgressRewardData
{
Item = GContext.container.Resolve<PlayerItemData>().GetItemDataByDropIdAndTypeLureInflation(inflationRate, x.DropID)[0],
Score = x.SpinPoint,
IsReceived = i < currentIdx
}).ToList();
return res;
}
public int GetScoreFromExitIndex(int index)
{
return _tableExit.DataList[index].PointMag;
}
public List<EventPinballCountlessReward> GetRewardListByScore(int currentScore)
{
var firstRewardList = _tableMain.RewardFirst;
var loopRewardList = _tableMain.RewardLoop;
var firstMaxScore = _tableReward.DataMap[firstRewardList[^1]].SpinPoint;
if (currentScore <= firstMaxScore)
return firstRewardList.Select(id => _tableReward.DataMap[id]).ToList();
return loopRewardList.Select(id => _tableReward.DataMap[id]).ToList();
}
/// <summary>
/// Range: [0(included), maxScore(included)]
/// </summary>
/// <param name="actualScore"></param>
/// <returns></returns>
public int GetScopeScoreFromActualScore(int actualScore)
{
var firstRewardList = _tableMain.RewardFirst;
var loopRewardList = _tableMain.RewardLoop;
var firstMaxScore = _tableReward.DataMap[firstRewardList[^1]].SpinPoint;
var loopMaxScore = _tableReward.DataMap[loopRewardList[^1]].SpinPoint;
if (actualScore <= firstMaxScore)
return actualScore;
var res = actualScore - firstMaxScore;
res %= loopMaxScore;
return res;
}
public int GetScoreRoundCount(int score)
{
var firstRewardList = _tableMain.RewardFirst;
var loopRewardList = _tableMain.RewardLoop;
var firstMaxScore = _tableReward.DataMap[firstRewardList[^1]].SpinPoint;
var loopMaxScore = _tableReward.DataMap[loopRewardList[^1]].SpinPoint;
if (score <= firstMaxScore)
return 0;
return (score - firstMaxScore) / loopMaxScore + 1;
}
// Vert wierd and ugly. Feels wrong as f.
public int GetPreviousMaxScore(int score)
{
var firstRewardList = _tableMain.RewardFirst;
var loopRewardList = _tableMain.RewardLoop;
var firstMaxScore = _tableReward.DataMap[firstRewardList[^1]].SpinPoint;
var loopMaxScore = _tableReward.DataMap[loopRewardList[^1]].SpinPoint;
if (score < firstMaxScore + loopMaxScore)
return firstMaxScore;
return loopMaxScore;
}
public int GetCurrentMaxScore(int score)
{
var firstRewardList = _tableMain.RewardFirst;
var loopRewardList = _tableMain.RewardLoop;
var firstMaxScore = _tableReward.DataMap[firstRewardList[^1]].SpinPoint;
if (score <= firstMaxScore)
return firstMaxScore;
return _tableReward.DataMap[loopRewardList[^1]].SpinPoint;
}
public int GetInitWelcomeGift()
{
return _tables.TbFishingEventCycleItem[_cycleId].WelcomeGift;
}
public TimerContext GetTimerContext()
{
var res = new TimerContext();
(res.StartTime, res.ExpiryTime) = FtUtils.GetEventTimeLimit(_eventId);
res.OnExpire = null;
return res;
}
public string GetPanelUrl()
{
return _tableMain.UIPanel;
}
public string GetInfoPanelUrl()
{
return _tableMain.InfoPanel;
}
public string GetIconUrl()
{
return _tableMain.Icon;
}
public string GetActUrl()
{
return _tableMain.PinballAct;
}
public string GetNormalPackPanelUrl()
{
return _tableEventPackManager[_tableMain.PackId].Panel;
}
public EventNeoNormalPackData GetNormalPackData()
{
return new EventNeoNormalPackData
{
EventId = _eventId,
PackId = _tableMain.PackId,
// Panel = _tableMain.PackPanel
};
}
public int GetRoundFromScore(int score)
{
var firstRewardList = _tableMain.RewardFirst;
var loopRewardList = _tableMain.RewardLoop;
var firstMaxScore = _tableReward.DataMap[firstRewardList[^1]].SpinPoint;
var loopMaxScore = _tableReward.DataMap[loopRewardList[^1]].SpinPoint;
if (score <= firstMaxScore)
return 0;
score -= firstMaxScore;
return score / loopMaxScore + 1;
}
}
}