装备系统完结,修复并加入很多
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public static class EquipmentConsumableCatalog
|
||||
@@ -6,7 +6,9 @@ public static class EquipmentConsumableCatalog
|
||||
private static readonly EquipmentConsumableDescriptor[] Descriptors =
|
||||
{
|
||||
new EquipmentConsumableDescriptor(EquipmentConsumableKind.Material78101, "eqc_78101", "装备升级材料78101"),
|
||||
new EquipmentConsumableDescriptor(EquipmentConsumableKind.Material78111, "eqc_78111", "装备突破材料78111")
|
||||
new EquipmentConsumableDescriptor(EquipmentConsumableKind.Material78111, "eqc_78111", "装备突破材料78111"),
|
||||
new EquipmentConsumableDescriptor(EquipmentConsumableKind.Material78121, "eqc_78121", "装备洗炼材料78121"),
|
||||
new EquipmentConsumableDescriptor(EquipmentConsumableKind.Material78131, "eqc_78131", "装备登顶材料78131")
|
||||
};
|
||||
|
||||
private static readonly Dictionary<EquipmentConsumableKind, EquipmentConsumableDescriptor> ByKind = BuildByKind();
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
public enum EquipmentConsumableKind
|
||||
{
|
||||
Material78101,
|
||||
Material78111
|
||||
Material78111,
|
||||
Material78121,
|
||||
Material78131
|
||||
}
|
||||
|
||||
@@ -0,0 +1,213 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
[Serializable]
|
||||
public class PlayerRksSaveData
|
||||
{
|
||||
public float bestOverallRks;
|
||||
}
|
||||
|
||||
public static class PlayerRksService
|
||||
{
|
||||
private const string SaveCategory = "player_rks";
|
||||
private const string SaveKey = "overall";
|
||||
private const float MaxScorePerChart = 1000000f;
|
||||
private const int TopChartCount = 20;
|
||||
|
||||
public static event Action<float> OnRksChanged;
|
||||
|
||||
private static bool loaded;
|
||||
private static float bestOverallRks;
|
||||
|
||||
public static void EnsureLoaded(Player_SO player = null)
|
||||
{
|
||||
if (loaded)
|
||||
{
|
||||
SyncPlayerSo(player);
|
||||
return;
|
||||
}
|
||||
|
||||
loaded = true;
|
||||
bestOverallRks = 0f;
|
||||
|
||||
PlayerRksSaveData saveData;
|
||||
if (SecureSaveVault.TryLoadJson(SaveCategory, SaveKey, out saveData) && saveData != null)
|
||||
{
|
||||
bestOverallRks = Mathf.Max(0f, saveData.bestOverallRks);
|
||||
}
|
||||
else if (player != null)
|
||||
{
|
||||
bestOverallRks = Mathf.Max(0f, player.URankingScore);
|
||||
}
|
||||
|
||||
SyncPlayerSo(player);
|
||||
}
|
||||
|
||||
public static float GetBestOverallRks(Player_SO player = null)
|
||||
{
|
||||
EnsureLoaded(player);
|
||||
return bestOverallRks;
|
||||
}
|
||||
|
||||
public static float GetNormalizedOverallRks100(Player_SO player = null)
|
||||
{
|
||||
EnsureLoaded(player);
|
||||
float maxConstant = Mathf.Max(1f, GetMaxChartConstant());
|
||||
return Mathf.Clamp(bestOverallRks / maxConstant * 100f, 0f, 100f);
|
||||
}
|
||||
|
||||
public static float RefreshAndPersist(Player_SO player = null)
|
||||
{
|
||||
EnsureLoaded(player);
|
||||
|
||||
float calculated = CalculateOverallRksRaw();
|
||||
if (calculated > bestOverallRks + 0.0001f)
|
||||
{
|
||||
bestOverallRks = calculated;
|
||||
SecureSaveVault.SaveJson(SaveCategory, SaveKey, new PlayerRksSaveData { bestOverallRks = bestOverallRks });
|
||||
SyncPlayerSo(player);
|
||||
OnRksChanged?.Invoke(bestOverallRks);
|
||||
}
|
||||
else
|
||||
{
|
||||
SyncPlayerSo(player);
|
||||
}
|
||||
|
||||
return bestOverallRks;
|
||||
}
|
||||
|
||||
public static void ClearPersistentState(Player_SO player = null)
|
||||
{
|
||||
loaded = true;
|
||||
bestOverallRks = 0f;
|
||||
SecureSaveVault.Delete(SaveCategory, SaveKey);
|
||||
SyncPlayerSo(player);
|
||||
OnRksChanged?.Invoke(bestOverallRks);
|
||||
}
|
||||
|
||||
private static void SyncPlayerSo(Player_SO player)
|
||||
{
|
||||
Player_SO target = player != null ? player : LoadDefaultPlayerSo();
|
||||
if (target != null && !Mathf.Approximately(target.URankingScore, bestOverallRks))
|
||||
{
|
||||
target.SetURankingScore(bestOverallRks);
|
||||
}
|
||||
}
|
||||
|
||||
private static Player_SO LoadDefaultPlayerSo()
|
||||
{
|
||||
Player_SO[] players = Resources.LoadAll<Player_SO>(string.Empty);
|
||||
if (players == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
for (int i = 0; i < players.Length; i++)
|
||||
{
|
||||
if (players[i] != null)
|
||||
{
|
||||
return players[i];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static float CalculateOverallRksRaw()
|
||||
{
|
||||
SongData[] songs = Resources.LoadAll<SongData>(string.Empty);
|
||||
if (songs == null || songs.Length == 0)
|
||||
{
|
||||
return 0f;
|
||||
}
|
||||
|
||||
List<float> chartRksValues = new List<float>(64);
|
||||
for (int i = 0; i < songs.Length; i++)
|
||||
{
|
||||
SongData song = songs[i];
|
||||
if (song == null || song.chartFiles == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int j = 0; j < song.chartFiles.Count; j++)
|
||||
{
|
||||
ChartFileEntry entry = song.chartFiles[j];
|
||||
if (entry == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int bestTotal = entry.totalPersonalRecordForThisDifficulty;
|
||||
if (bestTotal <= 0)
|
||||
{
|
||||
bestTotal = song.GetPersonalRecord(entry.difficulty) + song.GetIdolRecord(entry.difficulty);
|
||||
}
|
||||
|
||||
float chartRks = CalculateChartRks(entry.difficultyLEVEL, bestTotal);
|
||||
if (chartRks > 0f)
|
||||
{
|
||||
chartRksValues.Add(chartRks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (chartRksValues.Count == 0)
|
||||
{
|
||||
return 0f;
|
||||
}
|
||||
|
||||
chartRksValues.Sort((a, b) => b.CompareTo(a));
|
||||
int count = Mathf.Min(TopChartCount, chartRksValues.Count);
|
||||
float sum = 0f;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
sum += chartRksValues[i];
|
||||
}
|
||||
|
||||
return sum / Mathf.Max(1, count);
|
||||
}
|
||||
|
||||
private static float GetMaxChartConstant()
|
||||
{
|
||||
SongData[] songs = Resources.LoadAll<SongData>(string.Empty);
|
||||
float maxConstant = 0f;
|
||||
if (songs == null)
|
||||
{
|
||||
return 1f;
|
||||
}
|
||||
|
||||
for (int i = 0; i < songs.Length; i++)
|
||||
{
|
||||
SongData song = songs[i];
|
||||
if (song == null || song.chartFiles == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int j = 0; j < song.chartFiles.Count; j++)
|
||||
{
|
||||
ChartFileEntry entry = song.chartFiles[j];
|
||||
if (entry != null && entry.difficultyLEVEL > maxConstant)
|
||||
{
|
||||
maxConstant = entry.difficultyLEVEL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Mathf.Max(1f, maxConstant);
|
||||
}
|
||||
|
||||
private static float CalculateChartRks(float chartConstant, int totalScore)
|
||||
{
|
||||
if (chartConstant <= 0f || totalScore <= 0)
|
||||
{
|
||||
return 0f;
|
||||
}
|
||||
|
||||
float scoreRate = Mathf.Clamp01(totalScore / MaxScorePerChart);
|
||||
float quality = Mathf.Pow(scoreRate, 1.35f);
|
||||
return chartConstant * quality;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: de7dfff9eb545b94b906ac8a9690132f
|
||||
@@ -53,7 +53,13 @@ public static class StoreExpBottlePurchaseService
|
||||
}
|
||||
|
||||
var primaryCost = itemSO.costRequirements[0];
|
||||
if (primaryCost.currencyType != storeItemSO.CurrencyType.coins)
|
||||
if (itemSO.associatedSelectableEquipmentRewardSource != null)
|
||||
{
|
||||
failureMessage = "该物品需要通过选择器购买";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!IsSupportedCurrency(primaryCost.currencyType))
|
||||
{
|
||||
failureMessage = "不可购买";
|
||||
return false;
|
||||
@@ -89,13 +95,13 @@ public static class StoreExpBottlePurchaseService
|
||||
PlayerEconomyLedger.EnsureInstance().AttachPlayerData(playerData);
|
||||
StoreOwnershipLedger.EnsureInstance().InitializeIfNeeded();
|
||||
|
||||
if (!PlayerEconomyLedger.EnsureInstance().HasEnoughCoins(totalCost))
|
||||
if (!HasEnoughCurrency(primaryCost.currencyType, totalCost))
|
||||
{
|
||||
failureMessage = "货币不足";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!PlayerEconomyLedger.EnsureInstance().TrySpendCoins(totalCost))
|
||||
if (!TrySpendCurrency(primaryCost.currencyType, totalCost))
|
||||
{
|
||||
failureMessage = "货币不足";
|
||||
return false;
|
||||
@@ -103,7 +109,7 @@ public static class StoreExpBottlePurchaseService
|
||||
|
||||
if (!GrantPurchasedItem(playerData, itemSO, grantedCount, out failureMessage))
|
||||
{
|
||||
PlayerEconomyLedger.EnsureInstance().AddCoins(totalCost);
|
||||
RefundCurrency(primaryCost.currencyType, totalCost);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -328,4 +334,49 @@ public static class StoreExpBottlePurchaseService
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool IsSupportedCurrency(storeItemSO.CurrencyType currencyType)
|
||||
{
|
||||
return currencyType == storeItemSO.CurrencyType.coins
|
||||
|| currencyType == storeItemSO.CurrencyType.material;
|
||||
}
|
||||
|
||||
private static bool HasEnoughCurrency(storeItemSO.CurrencyType currencyType, int amount)
|
||||
{
|
||||
switch (currencyType)
|
||||
{
|
||||
case storeItemSO.CurrencyType.coins:
|
||||
return PlayerEconomyLedger.EnsureInstance().HasEnoughCoins(amount);
|
||||
case storeItemSO.CurrencyType.material:
|
||||
return PlayerEconomyLedger.EnsureInstance().HasEnoughMaterial(amount);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool TrySpendCurrency(storeItemSO.CurrencyType currencyType, int amount)
|
||||
{
|
||||
switch (currencyType)
|
||||
{
|
||||
case storeItemSO.CurrencyType.coins:
|
||||
return PlayerEconomyLedger.EnsureInstance().TrySpendCoins(amount);
|
||||
case storeItemSO.CurrencyType.material:
|
||||
return PlayerEconomyLedger.EnsureInstance().TrySpendMaterial(amount);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static void RefundCurrency(storeItemSO.CurrencyType currencyType, int amount)
|
||||
{
|
||||
switch (currencyType)
|
||||
{
|
||||
case storeItemSO.CurrencyType.coins:
|
||||
PlayerEconomyLedger.EnsureInstance().AddCoins(amount);
|
||||
break;
|
||||
case storeItemSO.CurrencyType.material:
|
||||
PlayerEconomyLedger.EnsureInstance().AddMaterial(amount);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user