214 lines
7.1 KiB
C#
214 lines
7.1 KiB
C#
using UnityEngine;
|
|
|
|
public static class GameSaveManager {
|
|
private const string SaveKey = "UniRun.SaveData.v1";
|
|
private const string LegacyTotalMileageKey = "UniRun.TotalMileage";
|
|
|
|
public static GameSaveData Load() {
|
|
if(PlayerPrefs.HasKey(SaveKey))
|
|
{
|
|
string json = PlayerPrefs.GetString(SaveKey);
|
|
GameSaveData loadedData = JsonUtility.FromJson<GameSaveData>(json);
|
|
|
|
if(loadedData != null)
|
|
{
|
|
Normalize(loadedData);
|
|
return loadedData;
|
|
}
|
|
}
|
|
|
|
GameSaveData saveData = GameSaveData.CreateDefault();
|
|
saveData.totalMileage = PlayerPrefs.GetInt(LegacyTotalMileageKey, 0);
|
|
Normalize(saveData);
|
|
Save(saveData);
|
|
return saveData;
|
|
}
|
|
|
|
public static void Save(GameSaveData saveData) {
|
|
Normalize(saveData);
|
|
string json = JsonUtility.ToJson(saveData);
|
|
PlayerPrefs.SetString(SaveKey, json);
|
|
PlayerPrefs.SetInt(LegacyTotalMileageKey, saveData.totalMileage);
|
|
PlayerPrefs.Save();
|
|
}
|
|
|
|
public static GameSaveData ResetSave() {
|
|
PlayerPrefs.DeleteKey(SaveKey);
|
|
GameSaveData saveData = GameSaveData.CreateDefault();
|
|
Save(saveData);
|
|
return saveData;
|
|
}
|
|
|
|
public static void AddMileage(GameSaveData saveData, int amount) {
|
|
if(saveData == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
saveData.totalMileage = Mathf.Max(0, saveData.totalMileage + amount);
|
|
Save(saveData);
|
|
}
|
|
|
|
public static void UnlockMap(GameSaveData saveData, MapId mapId) {
|
|
if(saveData == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
int mapIndex = MapDatabase.GetIndex(mapId);
|
|
saveData.unlockedMapIndex = Mathf.Max(saveData.unlockedMapIndex, mapIndex);
|
|
Save(saveData);
|
|
}
|
|
|
|
private static void Normalize(GameSaveData saveData) {
|
|
saveData.currentMapIndex = Mathf.Clamp(saveData.currentMapIndex, 0, MapDatabase.LastMapIndex);
|
|
saveData.unlockedMapIndex = Mathf.Clamp(saveData.unlockedMapIndex, 0, MapDatabase.LastMapIndex);
|
|
saveData.currentMapIndex = Mathf.Min(saveData.currentMapIndex, saveData.unlockedMapIndex);
|
|
saveData.totalMileage = Mathf.Max(0, saveData.totalMileage);
|
|
saveData.bagSlots = Mathf.Clamp(saveData.bagSlots, 1, 3);
|
|
saveData.lunchboxStock = Mathf.Max(0, saveData.lunchboxStock);
|
|
saveData.mileageCardStock = Mathf.Max(0, saveData.mileageCardStock);
|
|
saveData.supplementPurchases = Mathf.Clamp(saveData.supplementPurchases, 0, 4);
|
|
saveData.dutyFreeLimitStageIndex = saveData.dutyFreeLimitStageIndex < 0
|
|
? -1
|
|
: Mathf.Clamp(saveData.dutyFreeLimitStageIndex, 0, MapDatabase.LastMapIndex);
|
|
NormalizeEquippedItems(saveData);
|
|
NormalizeDutyFreeStockCapacity(saveData);
|
|
NormalizeEquippedItems(saveData);
|
|
saveData.bestScore = Mathf.Max(0, saveData.bestScore);
|
|
}
|
|
|
|
private static void NormalizeDutyFreeStockCapacity(GameSaveData saveData) {
|
|
int bagSlots = Mathf.Clamp(saveData.bagSlots, 1, 3);
|
|
int equippedLunchboxes = CountEquippedItem(saveData, DutyFreeItemType.Lunchbox, bagSlots);
|
|
int equippedMileageCards = CountEquippedItem(saveData, DutyFreeItemType.MileageCard, bagSlots);
|
|
|
|
saveData.lunchboxStock = Mathf.Max(equippedLunchboxes, Mathf.Min(saveData.lunchboxStock, bagSlots));
|
|
saveData.mileageCardStock = Mathf.Max(equippedMileageCards, Mathf.Min(saveData.mileageCardStock, bagSlots));
|
|
|
|
while(saveData.lunchboxStock + saveData.mileageCardStock > bagSlots)
|
|
{
|
|
if(saveData.mileageCardStock > equippedMileageCards)
|
|
{
|
|
saveData.mileageCardStock--;
|
|
}
|
|
else if(saveData.lunchboxStock > equippedLunchboxes)
|
|
{
|
|
saveData.lunchboxStock--;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
private static int CountEquippedItem(GameSaveData saveData, DutyFreeItemType itemType, int bagSlots) {
|
|
int count = 0;
|
|
|
|
for(int i = 0; i < bagSlots; i++)
|
|
{
|
|
if(GetEquippedSlot(saveData, i) == itemType)
|
|
{
|
|
count++;
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
private static void NormalizeEquippedItems(GameSaveData saveData) {
|
|
int bagSlots = Mathf.Clamp(saveData.bagSlots, 1, 3);
|
|
if(bagSlots < 3)
|
|
{
|
|
saveData.equippedSlot3 = DutyFreeItemType.None;
|
|
}
|
|
|
|
if(bagSlots < 2)
|
|
{
|
|
saveData.equippedSlot2 = DutyFreeItemType.None;
|
|
}
|
|
|
|
saveData.equippedSlot1 = NormalizeItemType(saveData.equippedSlot1);
|
|
saveData.equippedSlot2 = NormalizeItemType(saveData.equippedSlot2);
|
|
saveData.equippedSlot3 = NormalizeItemType(saveData.equippedSlot3);
|
|
|
|
int lunchboxCount = 0;
|
|
int mileageCardCount = 0;
|
|
|
|
ClampEquippedSlot(saveData, 0, ref lunchboxCount, ref mileageCardCount);
|
|
ClampEquippedSlot(saveData, 1, ref lunchboxCount, ref mileageCardCount);
|
|
ClampEquippedSlot(saveData, 2, ref lunchboxCount, ref mileageCardCount);
|
|
}
|
|
|
|
private static DutyFreeItemType NormalizeItemType(DutyFreeItemType itemType) {
|
|
switch(itemType)
|
|
{
|
|
case DutyFreeItemType.Lunchbox:
|
|
case DutyFreeItemType.MileageCard:
|
|
return itemType;
|
|
default:
|
|
return DutyFreeItemType.None;
|
|
}
|
|
}
|
|
|
|
private static void ClampEquippedSlot(
|
|
GameSaveData saveData,
|
|
int slotIndex,
|
|
ref int lunchboxCount,
|
|
ref int mileageCardCount) {
|
|
DutyFreeItemType itemType = GetEquippedSlot(saveData, slotIndex);
|
|
if(itemType == DutyFreeItemType.None)
|
|
{
|
|
return;
|
|
}
|
|
|
|
bool overStock = false;
|
|
switch(itemType)
|
|
{
|
|
case DutyFreeItemType.Lunchbox:
|
|
overStock = lunchboxCount >= saveData.lunchboxStock;
|
|
lunchboxCount++;
|
|
break;
|
|
case DutyFreeItemType.MileageCard:
|
|
overStock = mileageCardCount >= saveData.mileageCardStock;
|
|
mileageCardCount++;
|
|
break;
|
|
}
|
|
|
|
if(overStock)
|
|
{
|
|
SetEquippedSlot(saveData, slotIndex, DutyFreeItemType.None);
|
|
}
|
|
}
|
|
|
|
private static DutyFreeItemType GetEquippedSlot(GameSaveData saveData, int slotIndex) {
|
|
switch(slotIndex)
|
|
{
|
|
case 0:
|
|
return saveData.equippedSlot1;
|
|
case 1:
|
|
return saveData.equippedSlot2;
|
|
case 2:
|
|
return saveData.equippedSlot3;
|
|
default:
|
|
return DutyFreeItemType.None;
|
|
}
|
|
}
|
|
|
|
private static void SetEquippedSlot(GameSaveData saveData, int slotIndex, DutyFreeItemType itemType) {
|
|
switch(slotIndex)
|
|
{
|
|
case 0:
|
|
saveData.equippedSlot1 = itemType;
|
|
break;
|
|
case 1:
|
|
saveData.equippedSlot2 = itemType;
|
|
break;
|
|
case 2:
|
|
saveData.equippedSlot3 = itemType;
|
|
break;
|
|
}
|
|
}
|
|
}
|