86 lines
3.5 KiB
C#
86 lines
3.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
// Сохранение 3D-поселения: секция "settlement3d" (05.11, Валдемар). 2D-город сохраняется отдельно ("settlement"),
|
|
// поэтому 3D-сцена его не трогает. Здания: id, тип, клетка, поворот, уровень, стройка или улучшение, которое идёт;
|
|
// Ратуша: уровень и её улучшение; расчищенные деревья и валуны.
|
|
// Регистрирует App/GameModules. Пока сцена City3D открыта, данные берутся у неё (Live), иначе -- последние известные.
|
|
public sealed class City3DSave : ISaveParticipant
|
|
{
|
|
[Serializable]
|
|
public class Entry
|
|
{
|
|
public string id;
|
|
public string type; // тип 3D-сцены: "Ратуша", "Дом", "Ферма"...
|
|
public int x, y, rot;
|
|
public int level = 1;
|
|
public int timerKind; // 0 -- нет, 1 -- постройка, 2 -- улучшение (BuildTimer.Kind)
|
|
public long timerStartMs, timerEndMs;
|
|
public int timerTargetLevel;
|
|
}
|
|
|
|
[Serializable]
|
|
public class Data
|
|
{
|
|
public int nextId = 1;
|
|
public List<Entry> buildings = new List<Entry>();
|
|
public List<string> cleared = new List<string>();
|
|
}
|
|
|
|
public interface ILive
|
|
{
|
|
Data CaptureState();
|
|
void OnSaveLoaded(); // загрузили другое сохранение или сбросили -- сцена должна перестроиться
|
|
}
|
|
|
|
public static readonly City3DSave Instance = new City3DSave();
|
|
public static Data Cached { get; private set; }
|
|
public static ILive Live;
|
|
|
|
public string SaveKey => "settlement3d";
|
|
|
|
public string Capture()
|
|
{
|
|
if (Live != null) Cached = Live.CaptureState();
|
|
return Cached != null ? JsonUtility.ToJson(Cached) : null;
|
|
}
|
|
|
|
public void Restore(string json)
|
|
{
|
|
Cached = string.IsNullOrEmpty(json) ? null : JsonUtility.FromJson<Data>(json);
|
|
if (Cached != null)
|
|
{
|
|
if (Cached.buildings == null) Cached.buildings = new List<Entry>();
|
|
if (Cached.cleared == null) Cached.cleared = new List<string>();
|
|
}
|
|
Live?.OnSaveLoaded();
|
|
}
|
|
|
|
public void ResetState()
|
|
{
|
|
Cached = null;
|
|
Live?.OnSaveLoaded();
|
|
}
|
|
|
|
// Запись таймера здания в Entry и обратно
|
|
public static void WriteTimer(Entry e, GameObject view)
|
|
{
|
|
var t = BuildTimer.Of(view);
|
|
bool on = t != null && BuildTimer.All.Contains(t);
|
|
e.timerKind = on ? (int)t.kind : 0;
|
|
e.timerStartMs = on ? t.startMs : 0;
|
|
e.timerEndMs = on ? t.endMs : 0;
|
|
e.timerTargetLevel = on ? t.targetLevel : 0;
|
|
}
|
|
|
|
// Таймер из файла -- только осмысленный: постройка у 1 уровня, улучшение до уровня выше текущего
|
|
public static void ReadTimer(Entry e, GameObject view)
|
|
{
|
|
bool build = e.timerKind == (int)BuildTimer.Kind.Build && e.level <= 1;
|
|
bool upgrade = e.timerKind == (int)BuildTimer.Kind.Upgrade && e.timerTargetLevel > Mathf.Max(1, e.level);
|
|
if ((build || upgrade) && e.timerEndMs > 0)
|
|
BuildTimer.Begin(view, (BuildTimer.Kind)e.timerKind, Mathf.Max(1, e.timerTargetLevel), e.timerStartMs, e.timerEndMs);
|
|
}
|
|
}
|