356 lines
12 KiB
C#
356 lines
12 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using asap.core;
|
|
using cfg;
|
|
using UnityEngine;
|
|
using UnityEngine.Assertions;
|
|
using GameCore;
|
|
|
|
public class EventShootingRangeData : IChainPackData
|
|
{
|
|
private RawData _data = new RawData();
|
|
private readonly Tables _tables = GContext.container.Resolve<Tables>();
|
|
private readonly TbPack _pack = GContext.container.Resolve<Tables>().TbPack;
|
|
private readonly TbEventPackManager _eventPackManager = GContext.container.Resolve<Tables>().TbEventPackManager;
|
|
|
|
private readonly TbEventShootingRangeMain _shootingRangeMainTable =
|
|
GContext.container.Resolve<Tables>().TbEventShootingRangeMain;
|
|
|
|
public const string Key = "EventShootingRangeData",
|
|
PackRedPointId = "EventShooting.Pack",
|
|
EntranceRedPointId = "EventShooting.Enter";
|
|
|
|
private const int SlotCount = 6;
|
|
public int EventId => _data.EventId;
|
|
public int RedirectId => _data.RedirectId;
|
|
public int AmmoCount => _data.AmmoCount;
|
|
|
|
public bool HasBeenOpened
|
|
{
|
|
get => _data.HasBeenOpened;
|
|
set => _data.HasBeenOpened = value;
|
|
}
|
|
|
|
public TimeSpan RemainingTime =>
|
|
DateTime.Parse((_tables.TbFishingEvent[_data.EventId].TimeDefinition as LimitedTime)?.EndTime) -
|
|
ZZTimeHelper.UtcNow();
|
|
|
|
public bool IsActive => _tables.TbFishingEvent.DataMap.ContainsKey(_data.EventId) &&
|
|
_tables.TbFishingEventCycleItem2.DataMap.ContainsKey(_data.CycleId) &&
|
|
_tables.TbEventShootingRangeMain.DataMap.ContainsKey(_data.RedirectId) &&
|
|
_tables.TbEventPackManager.DataMap.ContainsKey(_tables
|
|
.TbEventShootingRangeMain[_data.RedirectId].PackId) &&
|
|
RemainingTime.TotalSeconds > 0 &&
|
|
ZZTimeHelper.UtcNow() >=
|
|
DateTime.Parse((_tables.TbFishingEvent[_data.EventId].TimeDefinition as LimitedTime)
|
|
?.StartTime);
|
|
|
|
public EventShootingRangeMain EventShootingRange =>
|
|
GContext.container.Resolve<Tables>().TbEventShootingRangeMain[RedirectId];
|
|
|
|
public EventShootingRangeStage CurrentStage =>
|
|
_tables.TbEventShootingRangeStage[EventShootingRange.StageList[CurrentStageIdx]];
|
|
|
|
public int CurrentStageIdx => _data.CurrentStageIdx % EventShootingRange.StageList.Count;
|
|
public int RoundCount => _data.CurrentStageIdx / EventShootingRange.StageList.Count;
|
|
|
|
// public bool IsGameDepleted =>
|
|
// _data.CurrentStageIdx < 0 || _data.CurrentStageIdx >= EventShootingRange.StageList.Count;
|
|
|
|
public bool IsGrandPrizeAllowed => CurrentStageShootCount >= CurrentStage.MinAttempts - 1;
|
|
public bool IsFinalStage => CurrentStageIdx == EventShootingRange.StageList.Count - 1;
|
|
|
|
public int CurrentStageShootCount
|
|
{
|
|
get
|
|
{
|
|
int count = 0;
|
|
var flag = _data.RewardFlag;
|
|
while (flag > 0)
|
|
{
|
|
count += (int)(flag & 1);
|
|
flag >>= 1;
|
|
}
|
|
|
|
return count;
|
|
}
|
|
}
|
|
|
|
private List<int> ChainList => _tables.TbEventPackManager[_tables.TbEventShootingRangeMain[_data.RedirectId].PackId]
|
|
.VIPPackList[0];
|
|
|
|
public int ChainListCount => ChainList.Count;
|
|
public bool IsChainPackDepleted => _data.ChainProgress >= ChainListCount;
|
|
public bool IsEndGame => _data.ChainProgress > ChainList.Count - SlotCount;
|
|
|
|
public bool DoNeedPackRedPoint
|
|
{
|
|
get
|
|
{
|
|
if (!IsChainPackDepleted && ChainProgress < ChainListCount)
|
|
return _pack[_eventPackManager[EventShootingRange.PackId].VIPPackList[0][ChainProgress]].IAPID == 0;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public bool DoNeedEntranceRedPoint => !HasBeenOpened || _data.AmmoCount >= CycleItem.RedDot;
|
|
|
|
public int ChainProgress
|
|
{
|
|
get => _data.ChainProgress;
|
|
set => _data.ChainProgress = value;
|
|
}
|
|
|
|
public Pack[] NormalPacks
|
|
{
|
|
get
|
|
{
|
|
// return [_tables.TbPack[EventShootingRange.PackId2], _tables.TbPack[EventShootingRange.PackId2 + 1]
|
|
var normalPackIds = _tables.TbEventPackManager[EventShootingRange.PackId2].VIPPackList[0];
|
|
var packs = new Pack[normalPackIds.Count];
|
|
for (int i = 0; i < normalPackIds.Count; i++)
|
|
{
|
|
packs[i] = _tables.TbPack[normalPackIds[i]];
|
|
}
|
|
|
|
return packs;
|
|
}
|
|
}
|
|
|
|
public string AmmoIconUrl => GContext.container.Resolve<Tables>().TbItem[CycleItem.ID].Icon;
|
|
public string AmmoNameUrl => GContext.container.Resolve<Tables>().TbItem[CycleItem.ID].Name_l10n_key;
|
|
|
|
public List<int> GetTokenProgressRewardAfterAddingToken(int tokenAdded)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public FishingEventCycleItem2 CycleItem => _tables.TbFishingEventCycleItem2[_data.CycleId];
|
|
|
|
#region UI Resources
|
|
public string ChainPackPanelUrl => _shootingRangeMainTable[RedirectId].ChainPackPanel;
|
|
public string PackPanelUrl => _shootingRangeMainTable[RedirectId].PackPanel;
|
|
public string InfoPanelUrl => _shootingRangeMainTable[RedirectId].InfoPanel;
|
|
public string MainPanelUrl => _shootingRangeMainTable[RedirectId].EventPanel;
|
|
public string RewardPanelUrl => _shootingRangeMainTable[RedirectId].EventRewardPanel;
|
|
public string ShootingRangeAct => _shootingRangeMainTable[RedirectId].Scene;
|
|
public string EntranceIcon => _shootingRangeMainTable[RedirectId].IconEvent;
|
|
public string PackIcon => _shootingRangeMainTable[RedirectId].IconPackage;
|
|
public string TransitionPanelUrl => _shootingRangeMainTable[RedirectId].TransPanel;
|
|
|
|
#endregion
|
|
public int AmmoId => CycleItem.ItemId;
|
|
|
|
public string RedPointKey => throw new NotImplementedException();
|
|
|
|
public int GetChainProgressBySlotIdx(int slotIdx)
|
|
{
|
|
// Debug.Log($"<color=#f18c0a>Progress: {ChainProgress}</color>");
|
|
int res;
|
|
if (_data.ChainProgress > ChainList.Count - SlotCount)
|
|
res = ChainList.Count - SlotCount + slotIdx;
|
|
else
|
|
res = _data.ChainProgress + slotIdx;
|
|
Assert.IsTrue(res < ChainList.Count, $"Progress {res} out of range: {ChainListCount}");
|
|
return res;
|
|
}
|
|
|
|
public void UpdateData(FishingEvent e)
|
|
{
|
|
if (EventId == e.ID)
|
|
return;
|
|
_data = new RawData
|
|
{
|
|
EventId = e.ID,
|
|
CycleId = e.RedirectID,
|
|
RedirectId = _tables.TbFishingEventCycleItem2[e.RedirectID].RedirectID,
|
|
AmmoCount = _tables.TbFishingEventCycleItem2[e.RedirectID].WelcomeGift,
|
|
HasBeenOpened = false
|
|
};
|
|
UploadData();
|
|
}
|
|
|
|
public void LoadData(string s)
|
|
{
|
|
_data = Newtonsoft.Json.JsonConvert.DeserializeObject<RawData>(s);
|
|
// _data.EventId = 0;
|
|
// Debug.Log($"<color=#4d90fe>ShootingRangeDataLoaded: {s}</color>");
|
|
}
|
|
|
|
public void UploadData()
|
|
{
|
|
var message = Newtonsoft.Json.JsonConvert.SerializeObject(_data);
|
|
// Debug.Log($"<color=#4d90fe>ShootingRangeDataUploaded: {message}</color>");
|
|
PlayFabMgr.Instance.UpdateUserDataValue(Key, message);
|
|
}
|
|
|
|
public void AddAmmo(int count)
|
|
{
|
|
_data.AmmoCount += count;
|
|
GContext.container.Resolve<FishingEventData>().SaveTransitionData(_data.EventId, _data.AmmoCount);
|
|
UploadData();
|
|
}
|
|
|
|
public int PickRandomIndex(IList<int> weightList)
|
|
{
|
|
Assert.IsTrue(weightList is { Count: >= 1 }, "WeightList contains no weight.");
|
|
var acc = new List<int> { weightList[0] };
|
|
for (int i = 1; i < weightList.Count; i++)
|
|
acc.Add(weightList[i] + acc[i - 1]);
|
|
int random = UnityEngine.Random.Range(0, acc[^1]);
|
|
for (int i = 0; i < acc.Count; i++)
|
|
{
|
|
if (random < acc[i])
|
|
{
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Checkout to next stage.
|
|
/// </summary>
|
|
/// <returns>False if next stage is out of range.</returns>
|
|
public void SwitchToNextStage()
|
|
{
|
|
_data.CurrentStageIdx++;
|
|
// _data.CurrentStageIdx %= EventShootingRange.StageList.Count;
|
|
ResetRewardFlag();
|
|
ResetTargetFlag();
|
|
// return _data.CurrentStageIdx < EventShootingRange.StageList.Count;
|
|
}
|
|
|
|
public void SwitchToStage(int n)
|
|
{
|
|
_data.CurrentStageIdx = n;
|
|
ResetRewardFlag();
|
|
ResetTargetFlag();
|
|
}
|
|
|
|
public Pack GetChainPackByChainProgress(int chainProgress)
|
|
{
|
|
return _tables.TbPack[ChainList[chainProgress]];
|
|
}
|
|
|
|
public void OnBuySuccess()
|
|
{
|
|
if (ChainProgress >= ChainListCount)
|
|
{
|
|
Debug.LogError($"Trying to buy pack no.{ChainProgress} while there are/is only {ChainListCount} packs.");
|
|
return;
|
|
}
|
|
|
|
_data.ChainProgress++;
|
|
}
|
|
#if UNITY_EDITOR
|
|
public void ResetData()
|
|
{
|
|
_data.AmmoCount = 200;
|
|
ResetRewardFlag();
|
|
ResetTargetFlag();
|
|
_data.CurrentStageIdx = 11;
|
|
UploadData();
|
|
Debug.Log("<color=#4d90fe>Data reset.</color>");
|
|
}
|
|
#endif
|
|
|
|
#region Flags
|
|
|
|
public void ResetRewardFlag()
|
|
{
|
|
_data.RewardFlag = 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check if reward No.idx in current stage is claimed.
|
|
/// </summary>
|
|
/// <param name="idx">Index of current reward. Starts with 0.</param>
|
|
/// <returns>True if this reward is collected.</returns>
|
|
public bool IsRewardCollected(int idx)
|
|
{
|
|
Assert.IsTrue(idx < CurrentStage.DropId.Count,
|
|
$"Attempting to get reward{idx} status, while we have only {CurrentStage.DropId.Count} rewards.");
|
|
long idxFlag = (long)1 << idx;
|
|
return (_data.RewardFlag & idxFlag) == idxFlag;
|
|
}
|
|
|
|
public void SetRewardCollected(int idx)
|
|
{
|
|
Assert.IsTrue(idx < CurrentStage.DropId.Count,
|
|
$"Attempting to set reward{idx} as got, while we have only {CurrentStage.DropId.Count} rewards.");
|
|
_data.RewardFlag |= (long)1 << idx;
|
|
}
|
|
|
|
public void ResetTargetFlag()
|
|
{
|
|
_data.TargetFlag = 0;
|
|
}
|
|
|
|
public bool IsTargetHit(int idx)
|
|
{
|
|
/*Assert.IsTrue(idx < CurrentStage.DropId.Count,
|
|
$"Attempting to get target{idx} status, while we have only {CurrentStage.DropId.Count} targets.");
|
|
Assert.IsTrue(false, "JP wins!");
|
|
Assert.IsTrue(false,
|
|
$"Attempting to get target{idx} status, while we have only {CurrentStage.DropId.Count} targets.");*/
|
|
if (idx >= CurrentStage.DropId.Count)
|
|
Debug.LogWarning($"尝试获取{idx}号靶子的状态,但是咱只有{CurrentStage.DropId.Count}个Drop。这很奇怪。");
|
|
long idxFlag = (long)1 << idx;
|
|
return (_data.TargetFlag & idxFlag) == idxFlag;
|
|
}
|
|
|
|
public void SetTargetHit(int idx)
|
|
{
|
|
// Assert.IsTrue(idx < CurrentStage.DropId.Count,
|
|
// $"Attempting to get target{idx} status, while we have only {CurrentStage.DropId.Count} targets.");
|
|
if (idx >= CurrentStage.DropId.Count)
|
|
Debug.LogWarning($"尝试打击{idx}号靶子,但是咱只有{CurrentStage.DropId.Count}个Drop。这很奇怪。");
|
|
_data.TargetFlag |= ((long)1 << idx);
|
|
}
|
|
|
|
public int GetHitTargetCount()
|
|
{
|
|
int count = 0;
|
|
long num = _data.TargetFlag;
|
|
while (num != 0)
|
|
{
|
|
num &= num - 1;
|
|
count++;
|
|
}
|
|
return count;
|
|
}
|
|
|
|
public List<ItemData> GetItemsByPackDropId(int dropId)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
#endregion
|
|
|
|
private struct RawData
|
|
{
|
|
public int EventId;
|
|
public int CycleId;
|
|
public int RedirectId;
|
|
public int AmmoCount;
|
|
|
|
/// <summary>
|
|
/// Used in flag fashion.
|
|
/// </summary>
|
|
public long RewardFlag;
|
|
|
|
/// <summary>
|
|
/// Used in flag fashion.
|
|
/// </summary>
|
|
public long TargetFlag;
|
|
|
|
/// <summary>
|
|
/// Stage index that starts from 0. May exceed total stage count, indicating how many rounds player has counted.
|
|
/// </summary>
|
|
public int CurrentStageIdx;
|
|
public int ChainProgress;
|
|
public bool HasBeenOpened;
|
|
}
|
|
} |