Track Unity source, scenes, editable assets, licenses, tools and QA evidence. Exclude generated caches, Windows builds and raw runtime logs.
230 lines
7.5 KiB
C#
230 lines
7.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using UnityEngine;
|
|
|
|
namespace Ironspore
|
|
{
|
|
[Serializable]
|
|
public sealed class CargoStack
|
|
{
|
|
public string uid = Guid.NewGuid().ToString("N");
|
|
public string itemId;
|
|
public int count;
|
|
public CargoStack(string id, int amount)
|
|
{
|
|
itemId = id;
|
|
count = amount;
|
|
}
|
|
public string Name => GameLocalization.ItemName(itemId);
|
|
}
|
|
|
|
[Serializable]
|
|
public sealed class RunRecord
|
|
{
|
|
public string id;
|
|
public bool active;
|
|
public int seed;
|
|
public int stage;
|
|
public int branch;
|
|
public int biome;
|
|
public int chassis = 1;
|
|
public int[] equipment = { 0, 0, 0, 0 };
|
|
public float armor;
|
|
public float energy = 100;
|
|
public bool podUsed;
|
|
public bool objectiveDone;
|
|
public bool routeCompleted;
|
|
public int upgrades;
|
|
public float elapsed;
|
|
public float escortArmor = 250;
|
|
public List<CargoStack> cargo = new List<CargoStack>();
|
|
public List<string> searched = new List<string>();
|
|
}
|
|
|
|
[Serializable]
|
|
public sealed class GameSave
|
|
{
|
|
public int version = 1;
|
|
public int alloy;
|
|
public int cells;
|
|
public int sorties;
|
|
public int extractions;
|
|
public int completed;
|
|
public List<string> blueprints = new List<string>();
|
|
public List<string> unlocked = new List<string>();
|
|
public List<string> receipts = new List<string>();
|
|
public RunRecord run = new RunRecord();
|
|
}
|
|
|
|
public sealed class ProfileStore
|
|
{
|
|
readonly string path;
|
|
public GameSave Data
|
|
{
|
|
get; private set;
|
|
}
|
|
public string Error
|
|
{
|
|
get; private set;
|
|
}
|
|
|
|
public ProfileStore(string savePath)
|
|
{
|
|
path = savePath;
|
|
Data = Load(path) ?? Load(path + ".bak") ?? new GameSave();
|
|
}
|
|
|
|
static GameSave Load(string file)
|
|
{
|
|
try
|
|
{
|
|
if (!File.Exists(file))
|
|
return null;
|
|
var save = JsonUtility.FromJson<GameSave>(File.ReadAllText(file));
|
|
if (save == null || save.version != 1 || save.run == null || save.receipts == null || save.blueprints == null || save.unlocked == null)
|
|
return null;
|
|
if (save.run.cargo == null || save.run.equipment == null || save.run.equipment.Length != 4)
|
|
return null;
|
|
return save;
|
|
}
|
|
catch (Exception) { return null; }
|
|
}
|
|
|
|
public bool Commit(Func<GameSave, bool> change)
|
|
{
|
|
var candidate = JsonUtility.FromJson<GameSave>(JsonUtility.ToJson(Data));
|
|
if (!change(candidate))
|
|
return false;
|
|
try
|
|
{
|
|
Directory.CreateDirectory(Path.GetDirectoryName(path));
|
|
string temp = path + ".tmp";
|
|
using (var stream = new FileStream(temp, FileMode.Create, FileAccess.Write, FileShare.None))
|
|
{
|
|
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(JsonUtility.ToJson(candidate, true));
|
|
stream.Write(bytes, 0, bytes.Length);
|
|
stream.Flush(true);
|
|
}
|
|
if (File.Exists(path))
|
|
File.Replace(temp, path, path + ".bak");
|
|
else
|
|
File.Move(temp, path);
|
|
Data = candidate;
|
|
Error = null;
|
|
return true;
|
|
}
|
|
catch (Exception ex) { Error = ex.Message; return false; }
|
|
}
|
|
|
|
public bool Begin(int chassis, int[] equipment, float armor, int seed)
|
|
{
|
|
return Commit(s =>
|
|
{
|
|
s.run = new RunRecord { id = Guid.NewGuid().ToString("N"), active = true, seed = seed, chassis = chassis, equipment = (int[])equipment.Clone(), armor = armor };
|
|
s.sorties++;
|
|
return true;
|
|
});
|
|
}
|
|
|
|
public bool AddCargo(string id, int count, string sourceKey = "")
|
|
{
|
|
if (count <= 0)
|
|
return false;
|
|
return Commit(s =>
|
|
{
|
|
if (!s.run.active)
|
|
return false;
|
|
if (sourceKey.Length > 0 && s.run.searched.Contains(sourceKey))
|
|
return false;
|
|
foreach (var stack in s.run.cargo)
|
|
{
|
|
if (id.StartsWith("blueprint_") || stack.itemId != id || stack.count + count > 10)
|
|
continue;
|
|
stack.count += count;
|
|
if (sourceKey.Length > 0)
|
|
s.run.searched.Add(sourceKey);
|
|
return true;
|
|
}
|
|
if (s.run.cargo.Count >= 4 || (id.StartsWith("blueprint_") ? count != 1 : count > 10))
|
|
return false;
|
|
s.run.cargo.Add(new CargoStack(id, count));
|
|
if (sourceKey.Length > 0)
|
|
s.run.searched.Add(sourceKey);
|
|
return true;
|
|
});
|
|
}
|
|
|
|
static void Bank(GameSave s, CargoStack stack)
|
|
{
|
|
if (stack.itemId == "alloy")
|
|
s.alloy += stack.count;
|
|
else if (stack.itemId == "cells")
|
|
s.cells += stack.count;
|
|
else if (!s.blueprints.Contains(stack.itemId))
|
|
s.blueprints.Add(stack.itemId);
|
|
else
|
|
s.alloy += 2;
|
|
}
|
|
|
|
public bool SendCargo(IReadOnlyCollection<string> selection)
|
|
{
|
|
if (selection == null || selection.Count == 0 || selection.Count > 2)
|
|
return false;
|
|
var ids = new HashSet<string>(selection);
|
|
if (ids.Count != selection.Count)
|
|
return false;
|
|
return Commit(s =>
|
|
{
|
|
string receipt = s.run.id + ":cargo";
|
|
if (!s.run.active || s.run.armor <= 0 || s.run.podUsed || s.receipts.Contains(receipt))
|
|
return false;
|
|
var picked = s.run.cargo.FindAll(x => ids.Contains(x.uid));
|
|
if (picked.Count != ids.Count)
|
|
return false;
|
|
foreach (var stack in picked)
|
|
{
|
|
Bank(s, stack);
|
|
s.run.cargo.Remove(stack);
|
|
}
|
|
s.run.podUsed = true;
|
|
s.receipts.Add(receipt);
|
|
return true;
|
|
});
|
|
}
|
|
|
|
public bool Finish(bool destroyed)
|
|
{
|
|
return Commit(s =>
|
|
{
|
|
string receipt = s.run.id + ":return";
|
|
if (!s.run.active || s.receipts.Contains(receipt))
|
|
return false;
|
|
if (!destroyed)
|
|
{
|
|
foreach (var stack in s.run.cargo)
|
|
Bank(s, stack);
|
|
s.extractions++;
|
|
}
|
|
s.run.cargo.Clear();
|
|
s.run.active = false;
|
|
s.receipts.Add(receipt);
|
|
return true;
|
|
});
|
|
}
|
|
|
|
public bool CompleteRoute()
|
|
{
|
|
return Commit(s =>
|
|
{
|
|
if (!s.run.active || s.run.armor <= 0 || s.run.routeCompleted)
|
|
return false;
|
|
s.run.routeCompleted = true;
|
|
s.run.objectiveDone = true;
|
|
s.completed++;
|
|
return true;
|
|
});
|
|
}
|
|
}
|
|
}
|