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(); _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(); 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(); } /// /// Check point for specific exit /// /// Index of exit, 0-based. /// Points 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().GetItemDataByDropIdAndTypeLureInflation(inflationRate, dropId)[0]; return item; } /// /// Get reward to show on disc from total hit count /// /// Total hit count /// Index of disc /// Reward. 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().GetItemDataByDropIdAndTypeLureInflation(inflationRate, dropList[dropIdx])[0]; return item; } public List 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(); for (int i = oldRewardCount; i < newRewardCount; i++) { res.Add(dropList[i % dropList.Count]); } return res; } public (List dropList, List 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(); var roundList = new List(); // 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; } /// /// Get data for progress bar from certain score. /// /// Score. Can escape scope. /// index and corrosponding percentage. 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 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().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 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(); } /// /// Range: [0(included), maxScore(included)] /// /// /// 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; } } }