419 lines
16 KiB
C#
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;
|
|
}
|
|
}
|
|
} |