feat(upserver): 保存M2客户端KV迁移至本人统计写检查点
保存独立KV用户服务、固定会话存档与原业务接线,以及C3d资料缓存和C3e本人统计写。 保留原PF/AGG路线、业务公式和时序;榜单读取、好友资料、公告、匹配及首场景闸仍待完成。 验证:ServiceHost两条件各33组646断言;Unity CLI Loop编译0错误269警告。 包含相关方案、评审裁决、测试及状态文档。未操作服务器、正式账号或打包。
This commit is contained in:
@@ -0,0 +1,993 @@
|
||||
using asap.core;
|
||||
using cfg;
|
||||
using GameCore;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
|
||||
namespace game
|
||||
{
|
||||
public class EventPinballDataManager
|
||||
{
|
||||
[asap.core.Inject] public game.PlayerDataStorage.IPlayerSaveStore playerSaveStore { get; set; }
|
||||
|
||||
#if UNITY_EDITOR
|
||||
private bool m_IsCheckCondition = true;
|
||||
private bool m_IsSyncData = true;
|
||||
private int m_DefaultToken = 100;
|
||||
#else
|
||||
private bool m_IsCheckCondition = true;
|
||||
private bool m_IsSyncData = true;
|
||||
private int m_DefaultToken = 0;
|
||||
#endif
|
||||
|
||||
#region 奖励次数相关
|
||||
private int m_BonusResponseNumber = 10; // 相应次数
|
||||
public int BonusResponseNumber { set => m_BonusResponseNumber = value; }
|
||||
private int m_CumulativeResponseNumber = 0;
|
||||
public int CumulativeResponseNumber
|
||||
{
|
||||
get => m_CumulativeResponseNumber;
|
||||
set
|
||||
{
|
||||
m_CumulativeResponseNumber = value;
|
||||
FishingPinballAct.Publish(new EventPinballUpdateBonusCircularProgress());
|
||||
}
|
||||
}
|
||||
public bool IsAddScoreValid()
|
||||
{
|
||||
return m_CumulativeResponseNumber < m_BonusResponseNumber;
|
||||
}
|
||||
public float GetBonusResponseRatio()
|
||||
{
|
||||
if (m_BonusResponseNumber <= 0) return 0f;
|
||||
|
||||
return (float)m_CumulativeResponseNumber / m_BonusResponseNumber;
|
||||
}
|
||||
|
||||
private int m_AccumulatedTriggerCount = 0; // 埋点用
|
||||
public int AccumulatedTriggerCount
|
||||
{
|
||||
get => m_AccumulatedTriggerCount;
|
||||
set => m_AccumulatedTriggerCount = value;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 代币相关
|
||||
public int GetToken()
|
||||
{
|
||||
if (m_PinballData != null)
|
||||
return m_PinballData.Token;
|
||||
return 0;
|
||||
}
|
||||
public void SetRedPoint()
|
||||
{
|
||||
if (m_PinballData != null)
|
||||
{
|
||||
RedPointManager.Instance.SetRedPointState(RedPointName.Home_Pinball, m_PinballData.Token > 0, m_PinballData.Token);
|
||||
}
|
||||
else
|
||||
{
|
||||
RedPointManager.Instance.SetRedPointState(RedPointName.Home_Pinball, false);
|
||||
}
|
||||
}
|
||||
public void AddToken(int count)
|
||||
{
|
||||
if (m_PinballData != null)
|
||||
{
|
||||
m_PinballData.Token += count;
|
||||
}
|
||||
else
|
||||
{
|
||||
GetFreshPinballData();
|
||||
if (m_PinballData == null) return;
|
||||
m_PinballData.Token += count;
|
||||
}
|
||||
|
||||
|
||||
SetRedPoint();
|
||||
FishingPinballAct.Publish<EventPinballTokenUpdateData>(new EventPinballTokenUpdateData());
|
||||
|
||||
GContext.container.Resolve<FishingEventData>().SaveTransitionData(m_PinballData.EventID, m_PinballData.Token);
|
||||
|
||||
SyncData();
|
||||
}
|
||||
//public bool ConsumeTokensDefault()
|
||||
//{
|
||||
// EventPinballMain pinballMain = GetCurrentEventPinballMain();
|
||||
|
||||
// int magnification = GetCurMagnification();
|
||||
// bool isEnough = ConsumeTokens(pinballMain.SpinRequire * magnification);
|
||||
// if (isEnough == false)
|
||||
// {
|
||||
// ToastPanel.Show(LocalizationMgr.GetText("UI_ToastPanel_103"));
|
||||
// }
|
||||
// return isEnough;
|
||||
//}
|
||||
public bool ConsumeTokens(int count)
|
||||
{
|
||||
bool isEnough = IsEnough(count);
|
||||
if (isEnough == false) return false;
|
||||
|
||||
m_PinballData.ConsumedToken += count;
|
||||
AddToken(-count);
|
||||
return isEnough;
|
||||
}
|
||||
|
||||
public bool IsEnough(int spend)
|
||||
{
|
||||
if (m_PinballData == null) return false;
|
||||
return (m_PinballData.Token - spend) >= 0;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 每一局的临时数据
|
||||
public void ClearTemporaryData()
|
||||
{
|
||||
m_IsMultipleMax = false;
|
||||
|
||||
CumulativeResponseNumber = 0;
|
||||
AccumulatedTriggerCount = 0;
|
||||
|
||||
ClearTemporaryScore();
|
||||
ClearTemporaryConsumedToken();
|
||||
}
|
||||
|
||||
private int m_TemporaryScore = 0;
|
||||
public int TemporaryScore { get => m_TemporaryScore; }
|
||||
|
||||
public void ClearTemporaryScore()
|
||||
{
|
||||
m_TemporaryScore = 0;
|
||||
}
|
||||
public void AddTemporaryScore(int score)
|
||||
{
|
||||
m_TemporaryScore += score;
|
||||
}
|
||||
public void MultiplyTemporaryScore(int multiple)
|
||||
{
|
||||
m_TemporaryScore *= multiple;
|
||||
}
|
||||
|
||||
public void ReturnConsumedToken()
|
||||
{
|
||||
AddToken(m_TemporaryConsumedToken);
|
||||
}
|
||||
private int m_TemporaryConsumedToken = 0;
|
||||
public int TemporaryConsumedToken { get => m_TemporaryConsumedToken; }
|
||||
public void ClearTemporaryConsumedToken()
|
||||
{
|
||||
m_TemporaryConsumedToken = 0;
|
||||
}
|
||||
public bool ConsumeTemporaryTokensDefault()
|
||||
{
|
||||
EventPinballMain pinballMain = GetCurrentEventPinballMain();
|
||||
|
||||
int magnification = GetCurMagnification();
|
||||
bool isEnough = ConsumeTemporaryTokens(pinballMain.SpinRequire * magnification);
|
||||
//if (isEnough == false)
|
||||
//{
|
||||
// ToastPanel.Show(LocalizationMgr.GetText("UI_ToastPanel_103"));
|
||||
//}
|
||||
return isEnough;
|
||||
}
|
||||
public bool ConsumeTemporaryTokens(int count)
|
||||
{
|
||||
bool isEnough = IsEnough(count);
|
||||
if (isEnough == false) return false;
|
||||
|
||||
ConsumeTokens(count);
|
||||
|
||||
m_TemporaryConsumedToken += count;
|
||||
FishingPinballAct.Publish<EventPinballTokenUpdateData>(new EventPinballTokenUpdateData());
|
||||
return isEnough;
|
||||
}
|
||||
|
||||
private bool m_IsMultipleMax = false;
|
||||
public bool IsMultipleMax { get => m_IsMultipleMax; set => m_IsMultipleMax = value; }
|
||||
#endregion
|
||||
|
||||
#region 分数相关
|
||||
private int m_MagnificationListIndex = 0;
|
||||
public void ResetMagnification()
|
||||
{
|
||||
EventPinballMain pinballMain = GetCurrentEventPinballMain();
|
||||
List<int> MagnificationList = pinballMain.SpinMag;
|
||||
int magnification = GetCurMagnification();
|
||||
bool isEnough = IsEnough(pinballMain.SpinRequire * magnification);
|
||||
|
||||
if (isEnough == false)
|
||||
{
|
||||
int count = MagnificationList.Count;
|
||||
int index = 0;
|
||||
for (int i = count - 1; i >= 0; --i)
|
||||
{
|
||||
int tmpMagnification = MagnificationList[i];
|
||||
if (IsEnough(pinballMain.SpinRequire * tmpMagnification))
|
||||
{
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_MagnificationListIndex = index;
|
||||
}
|
||||
|
||||
FishingPinballAct.Publish(new EventPinballResetMagnification());
|
||||
}
|
||||
public int GetCurMagnification()
|
||||
{
|
||||
if (m_PinballData == null) return -1;
|
||||
EventPinballMain pinballMain = GetCurrentEventPinballMain();
|
||||
List<int> MagnificationList = pinballMain.SpinMag;
|
||||
return MagnificationList[m_MagnificationListIndex];
|
||||
}
|
||||
public bool IsMaxMagnification()
|
||||
{
|
||||
if (m_PinballData == null) return false;
|
||||
|
||||
return IsCurMaxMagnification();// m_MagnificationListIndex == (m_PinballData.MagnificationList.Count - 1);
|
||||
}
|
||||
bool IsCurMaxMagnification()
|
||||
{
|
||||
if (m_PinballData == null) return false;
|
||||
EventPinballMain pinballMain = GetCurrentEventPinballMain();
|
||||
List<int> MagnificationList = pinballMain.SpinMag;
|
||||
int count = MagnificationList.Count;
|
||||
|
||||
int tmpIndex = m_MagnificationListIndex + 1;
|
||||
|
||||
if (tmpIndex >= count)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int magnification = MagnificationList[tmpIndex];
|
||||
return !IsEnough(pinballMain.SpinRequire * magnification);
|
||||
}
|
||||
public void ScrollToTheNextMagnification()
|
||||
{
|
||||
if (m_PinballData == null) return;
|
||||
|
||||
EventPinballMain pinballMain = GetCurrentEventPinballMain();
|
||||
List<int> MagnificationList = pinballMain.SpinMag;
|
||||
|
||||
int count = MagnificationList.Count;
|
||||
|
||||
int tmpIndex = m_MagnificationListIndex + 1;
|
||||
|
||||
if (tmpIndex >= count)
|
||||
{
|
||||
tmpIndex = 0;
|
||||
}
|
||||
|
||||
int magnification = MagnificationList[tmpIndex];
|
||||
bool isEnough = IsEnough(pinballMain.SpinRequire * magnification);
|
||||
|
||||
if (isEnough)
|
||||
{
|
||||
m_MagnificationListIndex = tmpIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_MagnificationListIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private List<float> m_RewardList = new List<float>();
|
||||
public List<float> RewardList { get => m_RewardList; }
|
||||
public void InitRewardList()
|
||||
{
|
||||
m_RewardList.Clear();
|
||||
|
||||
int count = m_TbEventPinballReward.DataList.Count;
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
var item = m_TbEventPinballReward.DataList[i];
|
||||
m_RewardList.Add(item.SpinPoint);
|
||||
}
|
||||
if (m_PinballData != null)
|
||||
{
|
||||
if (m_PinballData.Scores >= m_RewardList[^1])
|
||||
{
|
||||
m_PinballData.Scores = 0;
|
||||
}
|
||||
m_PinballData.RewardIndex = FindInsertionIndex(m_RewardList, m_PinballData.Scores);
|
||||
}
|
||||
}
|
||||
//private int m_RewardIndex, m_RewardMaxIndex;
|
||||
//public int RewardIndex { get => m_RewardIndex; }
|
||||
//public int RewardMaxIndex { get => m_RewardMaxIndex; }
|
||||
//public void CalculateReward()
|
||||
//{
|
||||
// if (m_PinballData == null) return;
|
||||
|
||||
// m_RewardIndex = FindInsertionIndex(m_RewardList, m_PinballData.Scores);
|
||||
// m_RewardMaxIndex = m_TbEventPinballReward.DataList.Count - 1;
|
||||
//}
|
||||
//public void AddScore(int score)
|
||||
//{
|
||||
// if (m_PinballData == null) return;
|
||||
|
||||
// m_PinballData.Scores += score;
|
||||
// m_PinballData.TotalScores += score;
|
||||
//}
|
||||
#endregion
|
||||
|
||||
#region 活动相关
|
||||
public void ActivateEvent(FishingEvent fishingEvent)
|
||||
{
|
||||
if (fishingEvent == null) return;
|
||||
|
||||
if (!Init()) return;
|
||||
|
||||
if (m_PinballData != null) FixPinballData();
|
||||
if (m_PinballData == null) GetFreshPinballData();
|
||||
}
|
||||
|
||||
public void GetDataFromServer(string json)
|
||||
{
|
||||
if (string.IsNullOrEmpty(json))
|
||||
{
|
||||
GameDebug.LogWarning("EventPinball get data from server has encountered empty data.");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
m_PinballData = Newtonsoft.Json.JsonConvert.DeserializeObject<EventPinballData>(json);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
GameDebug.LogWarning("EventPinball deserialize data has failed. Exception: " + e.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Init()) return;
|
||||
}
|
||||
public int FixPinballData()
|
||||
{
|
||||
if (m_PinballData == null) return 0;
|
||||
|
||||
// 获取当前开放并符合解锁条件的弹珠活动ID
|
||||
FishingEventData fishingEventData = GContext.container.Resolve<FishingEventData>();
|
||||
FishingEvent fishingEvent = fishingEventData.GetEventByTypeAndSubType(4, 6, m_IsCheckCondition);
|
||||
if (fishingEvent == null) return ClearData();
|
||||
int eventID = fishingEvent.ID;
|
||||
int pinballMainID = fishingEvent.RedirectID;
|
||||
if (pinballMainID < 0) return ClearData();
|
||||
|
||||
if (eventID != m_PinballData.EventID || pinballMainID != m_PinballData.PinballMainID) return ClearData();
|
||||
|
||||
return 0;
|
||||
}
|
||||
public TimeSpan RemainingTime
|
||||
{
|
||||
get => DateTime.Parse((m_Tables.TbFishingEvent[m_PinballData.EventID].TimeDefinition as LimitedTime).EndTime)
|
||||
- ZZTimeHelper.UtcNow();
|
||||
}
|
||||
public int ClearData()
|
||||
{
|
||||
if (m_PinballData == null) return 0;
|
||||
m_PinballData = null;
|
||||
return 0;
|
||||
}
|
||||
public void SyncData()
|
||||
{
|
||||
if (!m_IsSyncData) return;
|
||||
playerSaveStore.Write(EventPinballConfig.SAVE_DATA_KEY, Newtonsoft.Json.JsonConvert.SerializeObject(m_PinballData)).RequireAccepted();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 生命周期
|
||||
public bool Init()
|
||||
{
|
||||
InitTables();
|
||||
|
||||
m_IsSimulatorMode = false;
|
||||
return true;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Table Data
|
||||
private Tables m_Tables;
|
||||
private TbEventPinballMain m_TbEventPinballMain;
|
||||
private TbEventPinballPoint m_TbEventPinballPoint;
|
||||
private TbEventPinballReward m_TbEventPinballReward;
|
||||
private void InitTables()
|
||||
{
|
||||
m_Tables = GContext.container.Resolve<Tables>();
|
||||
if (m_Tables == null) return;
|
||||
m_TbEventPinballMain = m_Tables.TbEventPinballMain;
|
||||
m_TbEventPinballPoint = m_Tables.TbEventPinballPoint;
|
||||
m_TbEventPinballReward = m_Tables.TbEventPinballReward;
|
||||
|
||||
InitRewardList();
|
||||
}
|
||||
public EventPinballReward GetEventPinballReward(int index)
|
||||
{
|
||||
return m_TbEventPinballReward.DataList[index];
|
||||
}
|
||||
|
||||
public int GetTicketItemId()
|
||||
{
|
||||
return m_Tables.TbFishingEventCycleItem[m_Tables.TbFishingEvent[m_PinballData.EventID].RedirectID].ItemId;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region UI 设置相关
|
||||
private UIType m_UIPanel = null, m_InfoPanel = null;
|
||||
public void ClearUIData()
|
||||
{
|
||||
m_UIPanel = null;
|
||||
m_InfoPanel = null;
|
||||
}
|
||||
public void InitUIData()
|
||||
{
|
||||
GetUIPanel();
|
||||
GetInfoPanel();
|
||||
}
|
||||
public UIType GetUIPanel()
|
||||
{
|
||||
if (m_UIPanel == null)
|
||||
{
|
||||
var data = GetCurrentEventPinballMain();
|
||||
m_UIPanel = new UIType(data.UIPanel);
|
||||
}
|
||||
return m_UIPanel;
|
||||
}
|
||||
public UIType GetInfoPanel()
|
||||
{
|
||||
if (m_InfoPanel == null)
|
||||
{
|
||||
var data = GetCurrentEventPinballMain();
|
||||
m_InfoPanel = new UIType(data.InfoPanel);//EventPinballRewardPoupPanel
|
||||
}
|
||||
return m_InfoPanel;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 数据相关
|
||||
private EventPinballData m_PinballData;
|
||||
internal bool IsInactiveForKVValidation => m_Tables==null && m_TbEventPinballMain==null && m_TbEventPinballPoint==null &&
|
||||
m_TbEventPinballReward==null && m_UIPanel==null && m_InfoPanel==null && m_RewardList.Count==0 &&
|
||||
m_PointWeightList.Count==0 && !m_IsSimulatorMode && !m_IsMultipleMax && m_CumulativeResponseNumber==0 &&
|
||||
m_AccumulatedTriggerCount==0 && m_TemporaryScore==0 && m_TemporaryConsumedToken==0 && m_MagnificationListIndex==0 && m_BonusResponseNumber==10;
|
||||
|
||||
internal static game.PlayerDataStorage.PlayerKVPinballState DecodeForKVLoad(IReadOnlyDictionary<string,string> raw,
|
||||
game.PlayerDataStorage.PlayerKVSchemaSnapshot snapshot,game.PlayerDataStorage.PlayerKVSchemaDiagnostics errors) =>
|
||||
game.PlayerDataStorage.PlayerKVSaveSchema.DecodePinball(raw,snapshot,errors);
|
||||
internal void ResetForKVLoad()
|
||||
{
|
||||
m_PinballData=null; m_BonusResponseNumber=10; m_CumulativeResponseNumber=m_AccumulatedTriggerCount=m_TemporaryScore=m_TemporaryConsumedToken=m_MagnificationListIndex=0;
|
||||
m_IsMultipleMax=false; m_IsSimulatorMode=false; m_RewardList=new List<float>(); m_PointWeightList=new List<float>(); m_UIPanel=m_InfoPanel=null;
|
||||
m_Tables=null; m_TbEventPinballMain=null; m_TbEventPinballPoint=null; m_TbEventPinballReward=null;
|
||||
}
|
||||
internal void ReplaceFromKVDecoded(game.PlayerDataStorage.PlayerKVPinballState state)
|
||||
{
|
||||
if(state==null) throw new ArgumentNullException(nameof(state));
|
||||
m_PinballData=!state.IsPresent ? null : new EventPinballData
|
||||
{
|
||||
EventID=state.EventID,
|
||||
PinballMainID=state.PinballMainID,
|
||||
SpinPoint=state.SpinPoint,
|
||||
Scores=state.Scores,
|
||||
Multiple=state.Multiple,
|
||||
Token=state.Token,
|
||||
ConsumedToken=state.ConsumedToken,
|
||||
RewardIndex=state.RewardIndex,
|
||||
Force=state.Force,
|
||||
LuckyValue=state.LuckyValue,
|
||||
InflationRate=state.InflationRate
|
||||
};
|
||||
}
|
||||
public EventPinballData PinballData { get { return m_PinballData; } }
|
||||
public int RewardMaxIndex
|
||||
{
|
||||
get { return m_TbEventPinballReward.DataList.Count - 1; }
|
||||
}
|
||||
public EventPinballMain GetFreshPinballData()
|
||||
{
|
||||
// 获取当前开放并符合解锁条件的弹珠活动ID
|
||||
FishingEventData fishingEventData = GContext.container.Resolve<FishingEventData>();
|
||||
FishingEvent fishingEvent = fishingEventData.GetEventByTypeAndSubType(4, 6, m_IsCheckCondition);
|
||||
if (fishingEvent == null) return null;
|
||||
int eventID = fishingEvent.ID;
|
||||
int pinballMainID = fishingEvent.RedirectID;
|
||||
if (pinballMainID < 0) return null;
|
||||
|
||||
// 获取当前弹珠活动数据
|
||||
EventPinballMain pinballMain = m_TbEventPinballMain.GetOrDefault(pinballMainID);
|
||||
if (pinballMain == null) return null;
|
||||
|
||||
int token = m_DefaultToken;
|
||||
m_PinballData = null;
|
||||
|
||||
token = GContext.container.Resolve<FishingEventData>().GetInitWelcomeGift(eventID);
|
||||
|
||||
m_PinballData = new EventPinballData();
|
||||
|
||||
m_PinballData.InflationRate = GContext.container.Resolve<PlayerData>().InflationRate;
|
||||
Debug.Log("m_PinballData.InflationRate " + GContext.container.Resolve<PlayerData>().InflationRate);
|
||||
m_PinballData.EventID = eventID;
|
||||
m_PinballData.PinballMainID = pinballMainID;
|
||||
m_PinballData.Force = 0f;
|
||||
m_PinballData.SpinPoint = 0;
|
||||
m_PinballData.Scores = 0;
|
||||
m_PinballData.Multiple = 0;
|
||||
|
||||
m_PinballData.Token = token;
|
||||
m_PinballData.ConsumedToken = 0;
|
||||
|
||||
m_PinballData.LuckyValue = (float)pinballMain.InitialLuck;
|
||||
|
||||
m_PinballData.RewardIndex = 0;
|
||||
|
||||
GContext.container.Resolve<FishingEventData>().SaveTransitionData(m_PinballData.EventID, m_PinballData.Token);
|
||||
|
||||
|
||||
UpdateLuckyValueAndWeight();
|
||||
|
||||
GContext.container.Resolve<GuideDataCenter>().ClearGuide("");
|
||||
SetRedPoint();
|
||||
|
||||
// 同步数据
|
||||
SyncData();
|
||||
return pinballMain;
|
||||
}
|
||||
public EventPinballMain GetNextPinballData()
|
||||
{
|
||||
// 获取当前开放并符合解锁条件的弹珠活动ID
|
||||
FishingEventData fishingEventData = GContext.container.Resolve<FishingEventData>();
|
||||
FishingEvent fishingEvent = fishingEventData.GetEventByTypeAndSubType(4, 6, m_IsCheckCondition);
|
||||
if (fishingEvent == null) return null;
|
||||
int eventID = fishingEvent.ID;
|
||||
int pinballMainID = fishingEvent.RedirectID;
|
||||
if (pinballMainID < 0) return null;
|
||||
|
||||
if (eventID != m_PinballData.EventID || pinballMainID != m_PinballData.PinballMainID) return GetFreshPinballData();
|
||||
|
||||
// 获取当前弹珠活动数据
|
||||
EventPinballMain pinballMain = m_TbEventPinballMain.GetOrDefault(pinballMainID);
|
||||
if (pinballMain == null) return null;
|
||||
|
||||
m_PinballData.EventID = eventID;
|
||||
m_PinballData.PinballMainID = pinballMainID;
|
||||
|
||||
m_PinballData.ConsumedToken = 0;
|
||||
|
||||
UpdateLuckyValueAndWeight();
|
||||
|
||||
// 同步数据
|
||||
SyncData();
|
||||
return pinballMain;
|
||||
}
|
||||
public EventPinballMain ContinueGame()
|
||||
{
|
||||
if (m_PinballData == null) return GetFreshPinballData();
|
||||
|
||||
// 获取当前开放并符合解锁条件的弹珠活动ID
|
||||
FishingEventData fishingEventData = GContext.container.Resolve<FishingEventData>();
|
||||
FishingEvent fishingEvent = fishingEventData.GetEventByTypeAndSubType(4, 6, m_IsCheckCondition);
|
||||
if (fishingEvent == null) return null;
|
||||
int eventID = fishingEvent.ID;
|
||||
int pinballMainID = fishingEvent.RedirectID;
|
||||
if (pinballMainID < 0) return null;
|
||||
|
||||
if (eventID != m_PinballData.EventID || pinballMainID != m_PinballData.PinballMainID) return GetFreshPinballData();
|
||||
|
||||
// 获取当前弹珠活动数据
|
||||
EventPinballMain pinballMain = m_TbEventPinballMain.GetOrDefault(pinballMainID);
|
||||
if (pinballMain == null) return null;
|
||||
|
||||
//UpdateLuckyValueAndWeight();
|
||||
|
||||
return pinballMain;
|
||||
}
|
||||
public List<float> m_PointWeightList = new List<float>();
|
||||
public EventPinballPoint UpdateLuckyValueAndWeight()
|
||||
{
|
||||
if (m_TbEventPinballPoint == null) return null;
|
||||
|
||||
m_PointWeightList.Clear();
|
||||
|
||||
float luckyValue = m_PinballData.LuckyValue;
|
||||
int count = m_TbEventPinballPoint.DataList.Count;
|
||||
|
||||
float total = 0;
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
EventPinballPoint item = m_TbEventPinballPoint.DataList[i];
|
||||
|
||||
float weight = item.Weight + luckyValue * item.LuckParameter;
|
||||
total += weight;
|
||||
float tmp = total;
|
||||
m_PointWeightList.Add(tmp);
|
||||
}
|
||||
|
||||
float randomValue = UnityEngine.Random.Range(0f, total);
|
||||
int index = FindInsertionIndex(m_PointWeightList, randomValue);
|
||||
|
||||
EventPinballPoint target = m_TbEventPinballPoint.DataList[index];
|
||||
if (float.MaxValue - target.DeltaLuck <= m_PinballData.LuckyValue)
|
||||
{
|
||||
m_PinballData.LuckyValue = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_PinballData.LuckyValue += target.DeltaLuck;
|
||||
if (m_PinballData.LuckyValue < 0f)
|
||||
{
|
||||
m_PinballData.LuckyValue = 0f;
|
||||
}
|
||||
}
|
||||
|
||||
m_PinballData.SpinPoint = target.SpinPoint;
|
||||
|
||||
return target;
|
||||
}
|
||||
public int FindInsertionIndex(List<float> sortedList, float target)
|
||||
{
|
||||
if (sortedList == null || sortedList.Count == 0)
|
||||
{
|
||||
Debug.LogError("---- EventPinballDataManager->FindInsertionIndex 数组为空");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (target < sortedList[0])
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (target >= sortedList[sortedList.Count - 1])
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 使用二分查找算法
|
||||
int left = 0;
|
||||
int right = sortedList.Count - 1;
|
||||
int result = -1;
|
||||
|
||||
while (left <= right)
|
||||
{
|
||||
int mid = left + (right - left) / 2;
|
||||
|
||||
if (sortedList[mid] > target)
|
||||
{
|
||||
if (mid > 0 && target > sortedList[mid - 1] && target < sortedList[mid])
|
||||
{
|
||||
result = mid;
|
||||
break;
|
||||
}
|
||||
right = mid - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mid < sortedList.Count - 1 && target >= sortedList[mid] && target < sortedList[mid + 1])
|
||||
{
|
||||
result = mid + 1;
|
||||
break;
|
||||
}
|
||||
left = mid + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public float GetRandomForce(float ratio)
|
||||
{
|
||||
EventPinballPoint target = m_TbEventPinballPoint.GetOrDefault(m_PinballData.SpinPoint);
|
||||
EventPinballMain pinballMain = GetCurrentEventPinballMain();
|
||||
float failMaxDist = pinballMain.FailMaxDist;
|
||||
if (ratio <= failMaxDist)
|
||||
{
|
||||
return pinballMain.FailMaxForce;
|
||||
}
|
||||
int count = target.ForceLv.Count;
|
||||
|
||||
List<float> forceList = target.ForceLv[count - 1];
|
||||
ratio = (ratio - failMaxDist) / 1 - failMaxDist; // 归一化到0-1之间
|
||||
float subRatio = 1f / count; // 每个等级的比例
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
if (ratio <= subRatio * (i + 1))
|
||||
{
|
||||
forceList = target.ForceLv[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
count = forceList.Count;
|
||||
int index = UnityEngine.Random.Range(0, count);
|
||||
return forceList[index];
|
||||
}
|
||||
|
||||
public void InitGameRound()
|
||||
{
|
||||
//SetRewardList();
|
||||
//CalculateReward();
|
||||
ResetMagnification();
|
||||
ClearTemporaryData();
|
||||
|
||||
m_PinballData.Force = 0f;
|
||||
PinballData.Multiple = 0;
|
||||
}
|
||||
|
||||
public EventPinballMain GetCurrentEventPinballMain()
|
||||
{
|
||||
if (m_PinballData == null) return GetFreshPinballData();
|
||||
|
||||
return m_TbEventPinballMain.GetOrDefault(m_PinballData.PinballMainID);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 本地存储数据相关
|
||||
public string GetSaveKey(string key)
|
||||
{
|
||||
if (m_PinballData == null) return key;
|
||||
return m_PinballData.EventID + "-" + m_PinballData.PinballMainID + "-" + key;
|
||||
}
|
||||
public bool HasSaveKey(string key)
|
||||
{
|
||||
return PlayerPrefs.HasKey(GetSaveKey(key));
|
||||
}
|
||||
public void SaveData(string key, string value)
|
||||
{
|
||||
PlayerPrefs.SetString(GetSaveKey(key), value);
|
||||
PlayerPrefs.Save();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 红点相关
|
||||
public bool IsRedDotDisplayed()
|
||||
{
|
||||
if (m_PinballData == null) return false;
|
||||
return m_PinballData.Token > 0;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 运行模式相关(模拟数据模式/正常玩家模式)
|
||||
public bool m_IsSimulatorMode = false;
|
||||
public bool IsSimulatorMode
|
||||
{
|
||||
get => m_IsSimulatorMode;
|
||||
set
|
||||
{
|
||||
if (m_IsSimulatorMode != value)
|
||||
{
|
||||
m_IsSimulatorMode = value;
|
||||
FishingPinballAct.Publish(new EventPinballSyncOperatingModeData()
|
||||
{
|
||||
IsSimulatorMode = value
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region IO
|
||||
public string GetSaveFilepath(string filename)
|
||||
{
|
||||
return Path.Combine(Application.persistentDataPath, filename);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class EventPinballData
|
||||
{
|
||||
public int EventID { get; set; }
|
||||
public int PinballMainID { get; set; }
|
||||
public float Force { get; set; }
|
||||
public int SpinPoint { get; set; }
|
||||
public int Scores { get; set; }
|
||||
public int Multiple { get; set; }
|
||||
|
||||
public int Token { get; set; }
|
||||
public int ConsumedToken { get; set; }
|
||||
|
||||
public float LuckyValue { get; set; }
|
||||
|
||||
public int RewardIndex { get; set; }
|
||||
|
||||
public float InflationRate { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public enum EventPinballBonusType
|
||||
{
|
||||
TypeScore,
|
||||
TypeMultiple
|
||||
}
|
||||
|
||||
public enum EventPinballTrackType
|
||||
{
|
||||
TypeEnter,
|
||||
TypeExit
|
||||
}
|
||||
|
||||
public enum EventPinballState
|
||||
{
|
||||
Prepare,
|
||||
Running,
|
||||
Ended
|
||||
}
|
||||
|
||||
public enum EventPinballSwitcherState
|
||||
{
|
||||
Open,
|
||||
Close
|
||||
}
|
||||
|
||||
public class EventPinballSwitcherOpen
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class EventPinballSwitcherClose
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class EventPinballEnergyArrowData
|
||||
{
|
||||
public float Energy;
|
||||
}
|
||||
|
||||
public class EventPinballEnergyArrowRestoreData
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class EventPinballUpdateBonusCircularProgress
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class EventPinballTokenUpdateData
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class EventPinballBasicScore
|
||||
{
|
||||
public int Score;
|
||||
}
|
||||
public class EventPinballBasicScoreHideData
|
||||
{
|
||||
|
||||
}
|
||||
public class EventPinballBasicScoreShowData
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class EventPinballResetMagnification
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class EventPinballRewardUpdateData
|
||||
{
|
||||
public int Scores;
|
||||
}
|
||||
|
||||
public class EventPinballSpringUpdateData
|
||||
{
|
||||
public float Ratio;
|
||||
}
|
||||
|
||||
public class EventPinballPlayArrowBreathAnimData
|
||||
{
|
||||
|
||||
}
|
||||
public class EventPinballStopArrowBreathAnimData
|
||||
{
|
||||
|
||||
}
|
||||
public class EventPinballPlayLightOnAnimData
|
||||
{
|
||||
|
||||
}
|
||||
public class EventPinballResumePelletData
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class EventPinballResetPelletStatusData
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class EventPinballLaunchPelletData
|
||||
{
|
||||
public float Force;
|
||||
}
|
||||
|
||||
public class EventPinballShowPopupData
|
||||
{
|
||||
public int Scores;
|
||||
public EventPinballBonusType BonusType;
|
||||
public bool IsMultipleMax;
|
||||
}
|
||||
public class EventPinballHidePopupData
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class EventPinballShowMultipleTextData
|
||||
{
|
||||
public EventPinballBonusType BonusType;
|
||||
public Vector3 Position;
|
||||
public string Tips;
|
||||
public int Scores;
|
||||
public bool IsMultipleMax;
|
||||
}
|
||||
|
||||
public class EventPinballRewardDisplayUpdateData
|
||||
{
|
||||
public int RewardIndex;
|
||||
public int TargetScore;
|
||||
public int LevelScore;
|
||||
public float FromRatio;
|
||||
public float TargetRatio;
|
||||
public int DropId;
|
||||
public int RewardDisplayDropId;
|
||||
}
|
||||
|
||||
public class EventPinballSyncOperatingModeData
|
||||
{
|
||||
public bool IsSimulatorMode;
|
||||
}
|
||||
|
||||
public class EventPinballHideWidgetMultipleEffectData
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class EventPinballShowWidgetScoreEffect2Data
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class EventPinballHideFiringPinData
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class EventPinballShowFiringPinData
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class EventPinballHideCircularRotationalAnim
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class EventPinballShowCircularRotationalAnim
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class EventPinballLaunchPelletStatusData
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class EventPinballSetDummyPelletData
|
||||
{
|
||||
public PinballPellet Pellet;
|
||||
}
|
||||
|
||||
public class EventPinballConfig
|
||||
{
|
||||
public const string CSVFileName = "pinball.csv";
|
||||
|
||||
public const string SAVE_DATA_KEY = "epbdk"; // event pinball data key
|
||||
|
||||
public const int MultipleMax = 10;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user