Skip to content

Instantly share code, notes, and snippets.

@ninpl
Created December 24, 2025 12:56
Show Gist options
  • Select an option

  • Save ninpl/ccf06259867be4b5b4cf0f1ce62b3570 to your computer and use it in GitHub Desktop.

Select an option

Save ninpl/ccf06259867be4b5b4cf0f1ce62b3570 to your computer and use it in GitHub Desktop.
Example of asynchronous sequential save/load. (Unity)
#region Librerias
using UnityEngine;
using UnityEngine.SceneManagement;
using System;
using System.Threading;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using Cysharp.Threading.Tasks;
using Pandora.Nucleo;
#endregion
namespace Pandora
{
/// <summary>
/// <para>Hestia, guardiana del fuego eterno, conserva los recuerdos del mundo. Un sistema de guardado
/// centralizado asincrono en segundo plano. A traves de ella, los actos del jugador no se desvanecen,
/// sino que se graban en la llama. Gestiona el ciclo de guardado y carga, protegiendo lo que debe perdurar.</para>
/// </summary>
public class Hestia : MonoBehaviour
{
#region Constantes
/// <summary>
/// <para>Nombre de archivo de ajustes.</para>
/// </summary>
public const string ARCH_GUARDADO = "Alexandria.nvl";
#endregion
#region Variables Globales
/// <summary>
/// <para>Instancia de <see cref="Hestia"/>.</para>
/// </summary>
private static Hestia instancia = null;
#endregion
#region Variables Privadas
/// <summary>
/// <para>Cancelador del segundo plano.</para>
/// </summary>
private CancellationTokenSource _ctsGuardado;
/// <summary>
/// <para>Sistemas persistentes.</para>
/// </summary>
private readonly List<IPersistente> _sistemas = new();
#endregion
#region Propiedades
/// <summary>
/// <para>Instancia de <see cref="Hestia"/>.</para>
/// </summary>
public static Hestia I
{
get => instancia;
set => instancia = value;
}
#endregion
#region Inicializadores
/// <summary>
/// <para>Inicializador de <see cref="Hestia"/>.</para>
/// </summary>
public void Awake() => I = this;
#endregion
#region API
/// <summary>
/// <para>Guarda los datos del juego.</para>
/// </summary>
public void Guardar()
{
// Si hay una operación previa en curso, cancelarla
this._ctsGuardado?.Cancel();
this._ctsGuardado?.Dispose();
// Nuevo token para esta ejecución
this._ctsGuardado = new CancellationTokenSource();
this.EjecutarGuardadoSecuencial(this._ctsGuardado.Token).Forget();
}
/// <summary>
/// <para>Carga los datos del juego.</para>
/// </summary>
public void CargarSistemas()
{
if (ES3.KeyExists("CARDINAL", ARCH_GUARDADO))
{
ECardinal car = ES3.Load<ECardinal>("CARDINAL", ARCH_GUARDADO);
Cardinal c = Cardinal.I;
Alexandria.I.tiempoTotal = car.tiempoTotal;
c.modo.dificultad = car.dif;
c.modo.mapa = car.map;
c.registro.enCurso = car.enCurso;
c.registro.dia = car.dia;
c.lord = Atenea.I.Lords.Obtener(car.lord);
c.modo.cantidadRecompensas = car.cantidadRecompensas;
c.modo.cantidadReliqRecompensas = car.cantidadReliqRecompensas;
c.modo.cantidadReclutas = car.cantidadReclutas;
c.modo.cantidadSalas = car.cantidadSalas;
c.modo.cantidadEleccionReliquias = car.cantidadEleccionReliquias;
c.modo.cantidadBotin = car.cantidadBotin;
c.modo.puntuacion = car.puntuacion;
c.modo.enemigos = car.enemigos;
c.modo.campeones = car.campeones;
c.modo.jefes = car.jefes;
c.modo.eventos = car.eventos;
c.modo.botines = car.botines;
c.modo.objetos = car.objetos;
c.modo.reliquias = car.reliquias;
c.modo.salas = car.salas;
c.modo.unidades = car.unidades;
c.modo.agoge = car.agoge;
c.modo.comidas = car.comidas;
c.modo.trabajos = car.decretos;
c.renombre = car.renombre;
c.mejoras.mejora0 = car.mejora0;
c.mejoras.mejora1 = car.mejora1;
c.mejoras.mejora2 = car.mejora2;
c.mejoras.mejora3 = car.mejora3;
c.mejoras.mejora4 = car.mejora4;
c.mejoras.mejora5 = car.mejora5;
c.mejoras.mejora6 = car.mejora6;
c.mejoras.mejora7 = car.mejora7;
c.mejoras.mejora8 = car.mejora8;
c.mejoras.mejora9 = car.mejora9;
c.mejoras.mejora10 = car.mejora10;
c.mejoras.mejora11 = car.mejora11;
c.mejoras.mejora12 = car.mejora12;
c.mejoras.mejora13 = car.mejora13;
c.mejoras.mejora14 = car.mejora14;
c.mejoras.mejora15 = car.mejora15;
c.mejoras.mejora16 = car.mejora16;
c.mejoras.mejora17 = car.mejora17;
c.mejoras.mejora18 = car.mejora18;
c.mejoras.mejora19 = car.mejora19;
c.mejoras.mejora20 = car.mejora20;
c.mejoras.mejora21 = car.mejora21;
c.mejoras.mejora22 = car.mejora22;
c.mejoras.mejora23 = car.mejora23;
c.mejoras.mejora24 = car.mejora24;
c.mejoras.mejora25 = car.mejora25;
c.mejoras.mejora26 = car.mejora26;
c.mejoras.mejora27 = car.mejora27;
c.mejoras.mejora28 = car.mejora28;
c.mejoras.mejora29 = car.mejora29;
c.mejoras.mejora30 = car.mejora30;
c.mejoras.mejora31 = car.mejora31;
c.mejoras.mejora32 = car.mejora32;
c.mejoras.mejora33 = car.mejora33;
c.mejoras.mejora34 = car.mejora34;
c.preInicio = new PreInicio();
c.preInicio.cantidadUnidades = Mathf.Max(1, car.preInicio.cantidadUnidades);
c.preInicio.cantidadUnidadesEx = Mathf.Max(1,car.preInicio.cantidadUnidadesEx);
c.preInicio.cantidadSalas = Mathf.Max(1,car.preInicio.cantidadSalas);
c.preInicio.cantidadSalasEx = Mathf.Max(1,car.preInicio.cantidadSalasEx);
c.preInicio.unidadesIniciales = new List<PreInicio.UContenido>();
foreach (var ui in car.preInicio.unidadesIniciales)
{
c.preInicio.unidadesIniciales.Add(new PreInicio.UContenido(ui.uID, ui.uIDH, ui.nombre));
}
c.preInicio.salasIniciales = new List<int>();
foreach (var si in car.preInicio.salasIniciales)
{
c.preInicio.salasIniciales.Add(si);
}
c.preInicio.unidadesExcluidas = new List<int>();
foreach (var ue in car.preInicio.unidadesExcluidas)
{
c.preInicio.unidadesExcluidas.Add(ue);
}
c.preInicio.salasExcluidas = new List<int>();
foreach (var se in car.preInicio.salasExcluidas)
{
c.preInicio.salasExcluidas.Add(se);
}
c.preInicio.unidadesBolsa = new List<PreInicio.UContenido>();
foreach (var ub in car.preInicio.unidadesBolsa)
{
c.preInicio.unidadesBolsa.Add(new PreInicio.UContenido(ub.uID, ub.uIDH, ub.nombre));
}
c.preInicio.salasBolsa = new List<int>();
foreach (var sb in car.preInicio.salasBolsa)
{
c.preInicio.salasBolsa.Add(sb);
}
var mapaDif = car.dificultades.ToDictionary(x => x.uID, x => x.desbloq);
foreach (var d in Atenea.I.Dificultades.dificultades)
{
if (mapaDif.TryGetValue(d.uID, out bool desbloq)) d.desbloqueada = desbloq;
}
}
if (ES3.KeyExists("ORDINAL", ARCH_GUARDADO))
{
EOrdinal ord = ES3.Load<EOrdinal>("ORDINAL", ARCH_GUARDADO);
Ordinal o = Ordinal.I;
o.multiplicadorOro = ord.multiplicadorOro;
o.reduccionOro = ord.reduccionOro;
o.oroDiario = ord.oroDiario;
o.reintentos = ord.reintentos;
o.multiplicadorSalasBonus = ord.multiplicadorSalasBonus;
o.multiplicadorUnidadesBonus = ord.multiplicadorUnidadesBonus;
o.tiempoEsperaOleada = ord.tiempoEspera;
o.nocturnia = ord.nocturnia;
o.nigromante = ord.nigromante;
o.eventoJusticiaDivina = ord.eventoJusticiaDivina;
o.minimapa = ord.minimapa;
o.lordQuemadura = ord.lordQuemadura;
o.costeOroUnidad = ord.costeOroUnidad;
o.costeOroSala = ord.costeOroSala;
o.costeOroComprarUnidad = ord.costeOroComprarUnidad;
o.cantidadAccionesCampamento = ord.cantidadAccionesCampamento;
o.costeOroAgogeUnidad = ord.costeOroAgogeUnidad;
o.costeOroConsagrarHabilidad = ord.costeOroConsagrarHabilidad;
o.costeOroPurgarHabilidad = ord.costeOroPurgarHabilidad;
o.costeFormacion = ord.costeFormacion;
o.probabilidadAumentarAtri = ord.probabilidadAumentarAtri;
o.multiplicadorAturdimiento = ord.multiplicadorAturdimiento;
o.dpsExtraGeneral = ord.dpsExtraGeneral;
o.dpsExtraFisico = ord.dpsExtraFisico;
o.dpsExtraMagico = ord.dpsExtraMagico;
o.dpsExtraAventurero = ord.dpsExtraAventurero;
o.dpsExtraArquero = ord.dpsExtraArquero;
o.dpsExtraCaballero = ord.dpsExtraCaballero;
o.dpsExtraMagoBlanco = ord.dpsExtraMagoBlanco;
o.dpsExtraMagoNegro = ord.dpsExtraMagoNegro;
o.regeneracionBonusSala = ord.regeneracionBonusSala;
o.quemaduraBonusSala = ord.quemaduraBonusSala;
o.venenoBonusSala = ord.venenoBonusSala;
o.sangradoBonusSala = ord.sangradoBonusSala;
o.espinasBonusSala = ord.espinasBonusSala;
o.aumentoFuerza = ord.aumentoFuerza;
o.aumentoVitalidad = ord.aumentoVitalidad;
o.aumentoAgilidad = ord.aumentoAgilidad;
o.aumentoDestreza = ord.aumentoDestreza;
o.aumentoMagia = ord.aumentoMagia;
o.aumentoSuerte = ord.aumentoSuerte;
o.bonusGracia = ord.bonusGracia;
o.valorMano = ord.valorMano;
o.valorArch = ord.valorArch;
o.valorSabio = ord.valorSabio;
o.valorSombra = ord.valorSombra;
o.valorMaestro = ord.valorMaestro;
o.trabajoColoso = ord.trabajoColoso;
o.trabajoFenix = ord.trabajoFenix;
o.trabajoTalos = ord.trabajoTalos;
o.ulisesCapturado = ord.ulisesCapturado;
o.primeraHabGratis = ord.primeraHabGratis;
o.aumentarSaludDia = ord.aumentarSaludDia;
o.influenciaPoseidon = ord.influenciaPoseidon;
o.influenciaAtenea = ord.influenciaAtenea;
}
if (ES3.KeyExists("LORDS", ARCH_GUARDADO))
{
ELords lords = ES3.Load<ELords>("LORDS", ARCH_GUARDADO);
for (int n = 0; n < Atenea.I.Lords.lords.Count; n++)
{
Atenea.I.Lords.lords[n].nvl._nivel = lords.lords[n].nivel;
Atenea.I.Lords.lords[n].nvl._exp = lords.lords[n].xp;
Atenea.I.Lords.lords[n].nvl._expMaxima = lords.lords[n].xpMax;
Atenea.I.Lords.lords[n].aspecto = lords.lords[n].aspecto;
Atenea.I.Lords.lords[n].fases[0].Desbloqueada = lords.lords[n].fase0;
Atenea.I.Lords.lords[n].fases[1].Desbloqueada = lords.lords[n].fase1;
Atenea.I.Lords.lords[n].fases[2].Desbloqueada = lords.lords[n].fase2;
Atenea.I.Lords.lords[n].fases[3].Desbloqueada = lords.lords[n].fase3;
Atenea.I.Lords.lords[n].fases[4].Desbloqueada = lords.lords[n].fase4;
Atenea.I.Lords.lords[n].hitos.derrotas = lords.lords[n].hito0;
Atenea.I.Lords.lords[n].hitos.diaMaximo = lords.lords[n].hito1;
Atenea.I.Lords.lords[n].hitos.enemigosEliminados = lords.lords[n].hito2;
Atenea.I.Lords.lords[n].hitos.campeonesEliminados = lords.lords[n].hito3;
Atenea.I.Lords.lords[n].hitos.jefesEliminados = lords.lords[n].hito4;
Atenea.I.Lords.lords[n].hitos.maximaPuntuacion = lords.lords[n].hito5;
Atenea.I.Lords.lords[n].gestas[0].desbloqueado = lords.lords[n].gesta0;
Atenea.I.Lords.lords[n].gestas[1].desbloqueado = lords.lords[n].gesta1;
Atenea.I.Lords.lords[n].gestas[2].desbloqueado = lords.lords[n].gesta2;
Atenea.I.Lords.lords[n].gestas[3].desbloqueado = lords.lords[n].gesta3;
Atenea.I.Lords.lords[n].gestas[4].desbloqueado = lords.lords[n].gesta4;
Atenea.I.Lords.lords[n].gestas[5].desbloqueado = lords.lords[n].gesta5;
}
}
if (ES3.KeyExists("LINAJE", ARCH_GUARDADO))
{
ELinaje linaje = ES3.Load<ELinaje>("LINAJE", ARCH_GUARDADO);
var dicSalas = Atenea.I.Salas.salas.ToDictionary(s => s.uID);
foreach (var salaLinaje in linaje.salas)
{
if (dicSalas.TryGetValue(salaLinaje.uID, out var sala)) sala.desbloqueado = salaLinaje.desbloq;
}
var dicMapas = Atenea.I.Mapas.mapas.ToDictionary(s => s.uID);
foreach (var mapaLinaje in linaje.mapas)
{
if (dicMapas.TryGetValue(mapaLinaje.uID, out var mapa)) mapa.desbloqueado = mapaLinaje.desbloq;
}
/*var dicDifi = Atenea.I.Dificultades.dificultades.ToDictionary(s => s.uID);
foreach (var difLinaje in linaje.dif)
{
if (dicDifi.TryGetValue(difLinaje.uID, out var dif)) dif.desbloqueada = difLinaje.desbloq;
}*/
var dicUnid = Atenea.I.Unidades.unidades.ToDictionary(s => s.uID);
foreach (var unidLinaje in linaje.unidades)
{
if (dicUnid.TryGetValue(unidLinaje.uID, out var uni)) uni.desbloqueado = unidLinaje.desbloq;
}
var dicEven = Atenea.I.Eventos.eventos.ToDictionary(s => s.uID);
foreach (var evenLinaje in linaje.eventos)
{
if (dicEven.TryGetValue(evenLinaje.uID, out var eve)) eve.desbloqueado = evenLinaje.desbloq;
}
var dicObjs = Atenea.I.Objetos.objetos.ToDictionary(s => s.uID);
foreach (var objsLinaje in linaje.objetos)
{
if (dicObjs.TryGetValue(objsLinaje.uID, out var obj)) obj.desbloqueado = objsLinaje.desbloq;
}
var dicReliq = Atenea.I.Reliquias.reliquias.ToDictionary(s => s.uID);
foreach (var reliLinaje in linaje.reliquias)
{
if (dicReliq.TryGetValue(reliLinaje.uID, out var rel)) rel.desbloqueado = reliLinaje.desbloq;
}
if (linaje.equipos != null)
{
var dicEquip = Atenea.I.Equipos.equipos.ToDictionary(s => s.uID);
foreach (var eqliLinaje in linaje.equipos)
{
if (dicEquip.TryGetValue(eqliLinaje.uID, out var rel)) rel.desbloqueado = eqliLinaje.desbloq;
}
}
}
if (ES3.KeyExists("CRONICAS", ARCH_GUARDADO))
{
ECronicas cronicas = ES3.Load<ECronicas>("CRONICAS", ARCH_GUARDADO);
for (int n = 0; n < Atenea.I.Cronicas.cronicas.Count; n++)
{
Atenea.I.Cronicas.cronicas[n].completado = cronicas.cronicas[n].completado;
Atenea.I.Cronicas.cronicas[n].cantidadActual = cronicas.cronicas[n].progreso;
Atenea.I.Cronicas.cronicas[n].obtenido = cronicas.cronicas[n].obtenido;
}
}
this.CargarConfiguracion();
}
/// <summary>
/// <para>Carga los datos del juego.</para>
/// </summary>
public void CargarConfiguracion()
{
if (ES3.KeyExists("CONFIGURACION", ARCH_GUARDADO))
{
EConfiguracion con = ES3.Load<EConfiguracion>("CONFIGURACION", ARCH_GUARDADO);
Cardinal c = Cardinal.I;
Eco e = Eco.I;
e.mute = con.silenciado;
e.volGlobal = con.volGlobal;
e.volMusica = con.volMusica;
e.volSonido = con.volSonido;
e.volUI = con.volUI;
c.configuracion.idioma = con.idioma;
c.configuracion.mostrarDPS = con.mostrarDps;
c.configuracion.mostrarBarra = con.mostrarBarra;
c.configuracion.animTexto = con.animTexto;
c.configuracion.modoBrillo = con.modoBrillo;
c.configuracion.autoOro = con.autoOro;
c.configuracion.modoRapido = con.modoRapido;
c.configuracion.rectDatos = con.recDatos;
c.configuracion.resolucionAncho = con.anchores;
c.configuracion.resolucionAlto = con.altores;
c.configuracion.framerate = con.framerate;
c.configuracion.indiceMonitor = con.indiceMonitor;
c.configuracion.usarPantallaCompleta = con.usarPantallaCompleta;
c.configuracion.usarPantallaCompletaSinBordes = con.usarPantallaCompletaSinBordes;
c.configuracion.usarVSync = con.usarVSync;
}
}
/// <summary>
/// <para>Carga la partida del juego.</para>
/// </summary>
public void CargarPartida()
{
if (ES3.KeyExists("MAZMORRA", ARCH_GUARDADO))
{
EMazmorra maz = ES3.Load<EMazmorra>("MAZMORRA", ARCH_GUARDADO);
Mazmorra m = Cardinal.I.Mazmorra;
if (m != null)
{
m.Oro = maz.oro;
//m.expansiones = maz.expansiones;
m.tiempoTotal = maz.tiempoTotal;
//m.DeserializarSalas(maz.salas);
ETrono es = maz.trono;
foreach (var eus in es.unidades)
{
// Posición en la grilla
Vector2Int pos = Vector2Int.RoundToInt(eus.posSala);
// Instanciar el prefab o usar tu fábrica
UnidadDatos ud = Atenea.I.Unidades.Obtener(eus.unidad.uID);
IUnidad unidad = m.CrearUnidad(ud);
unidad.Datos.nivel = eus.unidad.nivel;
unidad.Datos.elite = eus.unidad.elite;
unidad.Datos.AsignarAtributosDesde(eus.unidad);
if (ud.elite)
{
unidad.transform.Find("Visual").GetComponent<SpriteRenderer>().sprite = m.elite;
var borde = unidad.transform.Find("Visual/Borde");
if (borde != null) borde.gameObject.SetActive(false);
var icono = unidad.transform.Find("Visual/Icono");
if (icono != null)
{
icono.GetComponent<SpriteRenderer>().sprite = unidad.Datos.avatarElite;
icono.localPosition = new Vector3(0.02f, 0f, 0.019f);
icono.localScale = new Vector3(0.2f, 0.2f, 1f);
}
var mascara = unidad.transform.Find("Visual/Mascara");
if (mascara != null) mascara.GetComponent<SpriteMask>().sprite = Cardinal.I.Mazmorra.campamento.spriteElite;
}
m.trono.AsignarUnidad(unidad, pos, false);
unidad.nombre = eus.unidad.nombre;
unidad.Salud = eus.unidad.saludActual;
unidad.Mana = (int)eus.unidad.manaActual;
unidad.gracia.Grado = eus.unidad.graciaGrado;
unidad.gracia.GraciaActual = eus.unidad.graciaActual;
unidad.gracia.GraciaMaxima = eus.unidad.graciaMaxima;
unidad.valorAumentadoPorSala = eus.unidad.valorAumentadoPorSala;
var unidadComp = unidad.GetComponent<Unidad>();
// Asegurarse de que la lista de habilidades tenga al menos 4 elementos
while (unidadComp.habilidades.Count < 4)
unidadComp.habilidades.Add(null);
for (int i = 0; i < 4; i++)
{
// Debug para ver estado de las listas
//Debug.Log($"[Debug Habilidades] i={i}, eus.unidad.habilidades.Count={eus.unidad.habilidades.Count}, valorId={eus.unidad.habilidades[i]}, unidad.habilidades.Count={unidadComp.habilidades.Count}");
if (eus.unidad.habilidades[i] != -1)
{
// Debug antes de asignar
// Debug.Log($"Asignando habilidad ID {eus.unidad.habilidades[i]} al slot {i}");
unidadComp.habilidades[i] = Atenea.I.Habilidades.ObtenerHabilidad(eus.unidad.habilidades[i]);
}
else
{
unidadComp.habilidades[i] = null;
}
}
// 🔹 Purga de nulls por seguridad (opcional, por si algo se coló)
unidadComp.habilidades = unidadComp.habilidades.Where(h => h != null).ToList();
if (eus.unidad.estadosHabilidades == null || eus.unidad.estadosHabilidades.Count == 0)
{
// Si no existe o está vacío, asignamos true por defecto
unidadComp.estadosHabilidades = new List<bool> { true, true, true, true, true };
}
else
{
// Asegurarse de que unidadComp tenga suficientes elementos
while (unidadComp.estadosHabilidades.Count < eus.unidad.estadosHabilidades.Count)
unidadComp.estadosHabilidades.Add(true); // valor por defecto
for (int n = 0; n < eus.unidad.estadosHabilidades.Count; n++)
{
// Si el valor en eus.unidad.estadosHabilidades[n] es null (si fuera nullable), asignamos true
unidadComp.estadosHabilidades[n] = eus.unidad.estadosHabilidades[n];
}
}
unidad.efectosEstado = new List<EfectoEstado>();
foreach (var e in eus.unidad.efectos.efectos)
{
EfectoEstado ef = new EfectoEstado(Atenea.I.Efectos.ObtenerEfectoEstado(e.uID));
ef.cargas = e.cargas;
ef.valor = e.valor;
unidad.efectosEstado.Add(ef);
}
unidad.idObjMano = eus.unidad.idObjMano;
unidad.idObjPecho = eus.unidad.idObjPecho;
unidad.idObjAcc = eus.unidad.idObjAcc;
if (eus.unidad.idObjMano != -1) Atenea.I.Equipos.ObtenerEquipo(eus.unidad.idObjMano).Equipar(unidad);
if (eus.unidad.idObjPecho != -1) Atenea.I.Equipos.ObtenerEquipo(eus.unidad.idObjPecho).Equipar(unidad);
if (eus.unidad.idObjAcc != -1) Atenea.I.Equipos.ObtenerEquipo(eus.unidad.idObjAcc).Equipar(unidad);
unidad.Salud = unidad.SaludMaxima;
unidad.Mana = unidad.ManaMax;
}
m.DeserializarObjetos(maz.objetos);
m.DeserializarRelicario(maz.reliquias);
m.DeserializarBaulEventos(maz.baulEventos);
m.DeserializarBaulObjetos(maz.baulObjetos);
m.DeserializarBaulReliMeno(maz.baulReliqMenores);
m.DeserializarBaulReliMayo(maz.baulReliqMayores);
m.campamento.CantidadUnidades = maz.cantidadUniOleadas;
m.campamento.tiempoEspera = maz.tiempoEsperaOleadas;
m.campamento.intervalo = maz.intervaloOleadas;
m.lord.GetComponent<Lord>().costeHabilidades[0] = maz.costeA;
m.lord.GetComponent<Lord>().costeHabilidades[1] = maz.costeB;
m.lord.GetComponent<Lord>().costeHabilidades[2] = maz.costeC;
m.lord.GetComponent<Lord>().costeHabilidades[3] = maz.costeD;
m.lord.Salud = maz.saludLord;
m.lord.Mana = maz.manaLord;
m.lord.ManaMax = maz.manaMaxLord;
m.lord.gracia.Grado = maz.graciaGradoLord;
m.lord.gracia.GraciaActual = maz.graciaActualLord;
m.lord.gracia.GraciaMaxima = maz.graciaMaximaLord;
m.lord.Datos.atributos.fuerza.valor = maz.fuerza;
m.lord.Datos.atributos.fuerza.valorOculto = maz.fuerzaInt;
m.lord.Datos.atributos.vitalidad.valor = maz.vitalidad;
m.lord.Datos.atributos.vitalidad.valorOculto = maz.vitalidadInt;
m.lord.Datos.atributos.destreza.valor = maz.destreza;
m.lord.Datos.atributos.destreza.valorOculto = maz.destrezaInt;
m.lord.Datos.atributos.agilidad.valor = maz.agilidad;
m.lord.Datos.atributos.agilidad.valorOculto = maz.agilidadInt;
m.lord.Datos.atributos.magia.valor = maz.magia;
m.lord.Datos.atributos.magia.valorOculto = maz.magiaInt;
m.lord.Datos.atributos.suerte.valor = maz.suerte;
m.lord.Datos.atributos.suerte.valorOculto = maz.suerteInt;
m.lord.efectosEstado = new List<EfectoEstado>();
foreach (var e in maz.efectosLord.efectos)
{
EfectoEstado ef = new EfectoEstado(Atenea.I.Efectos.ObtenerEfectoEstado(e.uID));
ef.cargas = e.cargas;
ef.valor = e.valor;
m.lord.efectosEstado.Add(ef);
}
m.lord.idObjMano = maz.lordidObjMano;
m.lord.idObjPecho = maz.lordidObjPecho;
m.lord.idObjAcc = maz.lordidObjAcc;
if (m.lord.idObjMano != -1) Atenea.I.Equipos.ObtenerEquipo(m.lord.idObjMano).Equipar(m.lord);
if (m.lord.idObjPecho != -1) Atenea.I.Equipos.ObtenerEquipo(m.lord.idObjPecho).Equipar(m.lord);
if (m.lord.idObjAcc != -1) Atenea.I.Equipos.ObtenerEquipo(m.lord.idObjAcc).Equipar(m.lord);
m.unidadesBuscando = new List<int>(maz.unidadesBuscando);
m.salasBuscando = new List<int>(maz.salasBuscando);
m.panelConsejo.consejo.manoDesbloqueada = maz.conseMano;
m.panelConsejo.consejo.archiDesbloqueado = maz.conseArchi;
m.panelConsejo.consejo.sabioDesbloqueado = maz.conseSabio;
m.panelConsejo.consejo.sombraDesbloqueado = maz.conseSombra;
m.panelConsejo.consejo.maestroDesbloqueado = maz.conseMaestro;
m.ComprobarConsejo();
}
}
if (ES3.KeyExists("TRAYECTO", ARCH_GUARDADO))
{
ETrayecto tra = ES3.Load<ETrayecto>("TRAYECTO", ARCH_GUARDADO);
Trayecto t = Cardinal.I.Trayecto;
if (t != null)
{
t.Dia = tra.dia;
t.Columna = tra.col;
t.Fila = tra.fil;
t.Nodos = t.DeserializarNodos(tra.nodos);
}
}
if (ES3.KeyExists("TESORO", ARCH_GUARDADO))
{
ETesoro tes = ES3.Load<ETesoro>("TESORO", ARCH_GUARDADO);
Tesoro t = Cardinal.I.Mazmorra.tesoro;
if (t != null)
{
t.DeserializarUnidades(tes.unidades);
t.DeserializarSalas(tes.salas);
t.DeserializarEquipos(tes.equipos);
}
}
}
#endregion
#region Metodos Privados
/// <summary>
/// <para>Ejecuta un guardado secuencial. Interno. No usar.</para>
/// </summary>
/// <param name="token"></param>
private async UniTask EjecutarGuardadoSecuencial(CancellationToken token)
{
try
{
Log.Nuevo(TipoLog.Info, "Guardado", "Inicio de guardado secuencial...");
ECardinal car = new ECardinal(Cardinal.I, Alexandria.I);
EOrdinal ord = new EOrdinal(Ordinal.I);
EConfiguracion con = new EConfiguracion(Eco.I, Cardinal.I.configuracion);
ELords lrd = new ELords(Atenea.I.Lords.lords);
ELinaje lin = new ELinaje(Atenea.I);
ECronicas cro = new ECronicas(Atenea.I.Cronicas.cronicas);
EMazmorra? maz = null;
ETrayecto? tra = null;
ETesoro? tes = null;
if (SceneManager.GetActiveScene().name == "juego")
{
maz = new EMazmorra(Cardinal.I.Mazmorra);
tra = new ETrayecto(Cardinal.I.Trayecto);
tes = new ETesoro(Cardinal.I.Mazmorra.tesoro);
}
await GuardadoInterno(token, car, ord, con, lrd, lin, cro);
if (SceneManager.GetActiveScene().name == "juego")
{
await GuardarPartidaInterno(token, maz.Value, tra.Value, tes.Value);
}
Log.Nuevo(TipoLog.Debug, "Guardar", "Guardado completado");
}
catch (OperationCanceledException)
{
Log.Nuevo(TipoLog.Advertencia, "Guardado", "Guardado cancelado por nueva llamada.");
}
catch (Exception ex)
{
Log.Nuevo(TipoLog.Error, "Guardado", $"Error durante guardado: {ex}");
}
}
/// <summary>
/// <para>Guarda los sistemas.</para>
/// </summary>
/// <param name="token"></param>
/// <param name="car"></param>
private async UniTask GuardadoInterno(CancellationToken token, ECardinal car, EOrdinal ord, EConfiguracion con, ELords lor, ELinaje lin, ECronicas cro)
{
// Comprobar cancelación antes de empezar
token.ThrowIfCancellationRequested();
// Cardinal
await UniTask.RunOnThreadPool(() =>
{
token.ThrowIfCancellationRequested();
try
{
ES3Settings aj = new ES3Settings(ARCH_GUARDADO);
ES3.Save("CARDINAL", car, aj);
}
catch (UnauthorizedAccessException ex)
{
// Error relacionado con permisos
Log.Nuevo(TipoLog.Error, "Guardar Sistemas", $"Permiso denegado al intentar guardar sistemas: {ex}");
}
catch (PathTooLongException ex)
{
// El nombre del archivo o la ruta es demasiado largo
Log.Nuevo(TipoLog.Error, "Guardar Sistemas", $"Ruta de archivo demasiado larga: {ex}");
}
catch (FileNotFoundException ex)
{
// El archivo no existe
Log.Nuevo(TipoLog.Error, "Guardar Sistemas", $"Archivo no encontrado: {ex}");
}
catch (IOException ex)
{
// Error de I/O general
Log.Nuevo(TipoLog.Error, "Guardar Sistemas", $"Error de I/O al guardar sistemas: {ex}");
}
catch (Exception ex)
{
// Cualquier otra excepción general
Log.Nuevo(TipoLog.Error, "Guardar Sistemas", $"Error inesperado al guardar sistemas: {ex}");
}
}, cancellationToken: token);
// Comprobar cancelación antes de la siguiente parte
token.ThrowIfCancellationRequested();
// Ordinal
await UniTask.RunOnThreadPool(() =>
{
token.ThrowIfCancellationRequested();
try
{
ES3Settings aj = new ES3Settings(ARCH_GUARDADO);
ES3.Save("ORDINAL", ord, aj);
}
catch (UnauthorizedAccessException ex)
{
// Error relacionado con permisos
Log.Nuevo(TipoLog.Error, "Guardar Sistemas", $"Permiso denegado al intentar guardar sistemas: {ex}");
}
catch (PathTooLongException ex)
{
// El nombre del archivo o la ruta es demasiado largo
Log.Nuevo(TipoLog.Error, "Guardar Sistemas", $"Ruta de archivo demasiado larga: {ex}");
}
catch (FileNotFoundException ex)
{
// El archivo no existe
Log.Nuevo(TipoLog.Error, "Guardar Sistemas", $"Archivo no encontrado: {ex}");
}
catch (IOException ex)
{
// Error de I/O general
Log.Nuevo(TipoLog.Error, "Guardar Sistemas", $"Error de I/O al guardar sistemas: {ex}");
}
catch (Exception ex)
{
// Cualquier otra excepción general
Log.Nuevo(TipoLog.Error, "Guardar Sistemas", $"Error inesperado al guardar sistemas: {ex}");
}
}, cancellationToken: token);
// Comprobar cancelación antes de la siguiente parte
token.ThrowIfCancellationRequested();
// Configuracion
await UniTask.RunOnThreadPool(() =>
{
token.ThrowIfCancellationRequested();
try
{
ES3Settings aj = new ES3Settings(ARCH_GUARDADO);
ES3.Save("CONFIGURACION", con, aj);
}
catch (UnauthorizedAccessException ex)
{
// Error relacionado con permisos
Log.Nuevo(TipoLog.Error, "Guardar Configuracion", $"Permiso denegado al intentar guardar configuracion: {ex}");
}
catch (PathTooLongException ex)
{
// El nombre del archivo o la ruta es demasiado largo
Log.Nuevo(TipoLog.Error, "Guardar Configuracion", $"Ruta de archivo demasiado larga: {ex}");
}
catch (FileNotFoundException ex)
{
// El archivo no existe
Log.Nuevo(TipoLog.Error, "Guardar Configuracion", $"Archivo no encontrado: {ex}");
}
catch (IOException ex)
{
// Error de I/O general
Log.Nuevo(TipoLog.Error, "Guardar Configuracion", $"Error de I/O al guardar configuracion: {ex}");
}
catch (Exception ex)
{
// Cualquier otra excepción general
Log.Nuevo(TipoLog.Error, "Guardar Configuracion", $"Error inesperado al guardar configuracion: {ex}");
}
}, cancellationToken: token);
// Comprobar cancelación antes de la siguiente parte
token.ThrowIfCancellationRequested();
// Lords
await UniTask.RunOnThreadPool(() =>
{
token.ThrowIfCancellationRequested();
try
{
ES3Settings aj = new ES3Settings(ARCH_GUARDADO);
ES3.Save("LORDS", lor, aj);
}
catch (UnauthorizedAccessException ex)
{
// Error relacionado con permisos
Log.Nuevo(TipoLog.Error, "Guardar Configuracion", $"Permiso denegado al intentar guardar configuracion: {ex}");
}
catch (PathTooLongException ex)
{
// El nombre del archivo o la ruta es demasiado largo
Log.Nuevo(TipoLog.Error, "Guardar Configuracion", $"Ruta de archivo demasiado larga: {ex}");
}
catch (FileNotFoundException ex)
{
// El archivo no existe
Log.Nuevo(TipoLog.Error, "Guardar Configuracion", $"Archivo no encontrado: {ex}");
}
catch (IOException ex)
{
// Error de I/O general
Log.Nuevo(TipoLog.Error, "Guardar Configuracion", $"Error de I/O al guardar configuracion: {ex}");
}
catch (Exception ex)
{
// Cualquier otra excepción general
Log.Nuevo(TipoLog.Error, "Guardar Configuracion", $"Error inesperado al guardar configuracion: {ex}");
}
}, cancellationToken: token);
// Comprobar cancelación antes de la siguiente parte
token.ThrowIfCancellationRequested();
// Linaje
await UniTask.RunOnThreadPool(() =>
{
token.ThrowIfCancellationRequested();
try
{
ES3Settings aj = new ES3Settings(ARCH_GUARDADO);
ES3.Save("LINAJE", lin, aj);
}
catch (UnauthorizedAccessException ex)
{
// Error relacionado con permisos
Log.Nuevo(TipoLog.Error, "Guardar Configuracion", $"Permiso denegado al intentar guardar configuracion: {ex}");
}
catch (PathTooLongException ex)
{
// El nombre del archivo o la ruta es demasiado largo
Log.Nuevo(TipoLog.Error, "Guardar Configuracion", $"Ruta de archivo demasiado larga: {ex}");
}
catch (FileNotFoundException ex)
{
// El archivo no existe
Log.Nuevo(TipoLog.Error, "Guardar Configuracion", $"Archivo no encontrado: {ex}");
}
catch (IOException ex)
{
// Error de I/O general
Log.Nuevo(TipoLog.Error, "Guardar Configuracion", $"Error de I/O al guardar configuracion: {ex}");
}
catch (Exception ex)
{
// Cualquier otra excepción general
Log.Nuevo(TipoLog.Error, "Guardar Configuracion", $"Error inesperado al guardar configuracion: {ex}");
}
}, cancellationToken: token);
// Comprobar cancelación antes de la siguiente parte
token.ThrowIfCancellationRequested();
// Cronicas
await UniTask.RunOnThreadPool(() =>
{
token.ThrowIfCancellationRequested();
try
{
ES3Settings aj = new ES3Settings(ARCH_GUARDADO);
ES3.Save("CRONICAS", cro, aj);
}
catch (UnauthorizedAccessException ex)
{
// Error relacionado con permisos
Log.Nuevo(TipoLog.Error, "Guardar Configuracion", $"Permiso denegado al intentar guardar configuracion: {ex}");
}
catch (PathTooLongException ex)
{
// El nombre del archivo o la ruta es demasiado largo
Log.Nuevo(TipoLog.Error, "Guardar Configuracion", $"Ruta de archivo demasiado larga: {ex}");
}
catch (FileNotFoundException ex)
{
// El archivo no existe
Log.Nuevo(TipoLog.Error, "Guardar Configuracion", $"Archivo no encontrado: {ex}");
}
catch (IOException ex)
{
// Error de I/O general
Log.Nuevo(TipoLog.Error, "Guardar Configuracion", $"Error de I/O al guardar configuracion: {ex}");
}
catch (Exception ex)
{
// Cualquier otra excepción general
Log.Nuevo(TipoLog.Error, "Guardar Configuracion", $"Error inesperado al guardar configuracion: {ex}");
}
}, cancellationToken: token);
}
/// <summary>
/// <para>Guarda la partida.</para>
/// </summary>
/// <param name="token"></param>
/// <param name="maz"></param>
/// <param name="tra"></param>
private async UniTask GuardarPartidaInterno(CancellationToken token, EMazmorra maz, ETrayecto tra, ETesoro tes)
{
// Comprobar cancelación antes de empezar
token.ThrowIfCancellationRequested();
// Cardinal
await UniTask.RunOnThreadPool(() =>
{
token.ThrowIfCancellationRequested();
try
{
ES3Settings aj = new ES3Settings(ARCH_GUARDADO);
ES3.Save("MAZMORRA", maz, aj);
}
catch (UnauthorizedAccessException ex)
{
// Error relacionado con permisos
Log.Nuevo(TipoLog.Error, "Guardar Mazmorra", $"Permiso denegado al intentar guardar mazmorra: {ex}");
}
catch (PathTooLongException ex)
{
// El nombre del archivo o la ruta es demasiado largo
Log.Nuevo(TipoLog.Error, "Guardar Mazmorra", $"Ruta de archivo demasiado larga: {ex}");
}
catch (FileNotFoundException ex)
{
// El archivo no existe
Log.Nuevo(TipoLog.Error, "Guardar Mazmorra", $"Archivo no encontrado: {ex}");
}
catch (IOException ex)
{
// Error de I/O general
Log.Nuevo(TipoLog.Error, "Guardar Mazmorra", $"Error de I/O al guardar mazmorra: {ex}");
}
catch (Exception ex)
{
// Cualquier otra excepción general
Log.Nuevo(TipoLog.Error, "Guardar Mazmorra", $"Error inesperado al guardar mazmorra: {ex}");
}
}, cancellationToken: token);
// Comprobar cancelación antes de la siguiente parte
token.ThrowIfCancellationRequested();
// Trayecto
await UniTask.RunOnThreadPool(() =>
{
token.ThrowIfCancellationRequested();
try
{
ES3Settings aj = new ES3Settings(ARCH_GUARDADO);
ES3.Save("TRAYECTO", tra, aj);
}
catch (UnauthorizedAccessException ex)
{
// Error relacionado con permisos
Log.Nuevo(TipoLog.Error, "Guardar Trayecto", $"Permiso denegado al intentar guardar trayecto: {ex}");
}
catch (PathTooLongException ex)
{
// El nombre del archivo o la ruta es demasiado largo
Log.Nuevo(TipoLog.Error, "Guardar Trayecto", $"Ruta de archivo demasiado larga: {ex}");
}
catch (FileNotFoundException ex)
{
// El archivo no existe
Log.Nuevo(TipoLog.Error, "Guardar Trayecto", $"Archivo no encontrado: {ex}");
}
catch (IOException ex)
{
// Error de I/O general
Log.Nuevo(TipoLog.Error, "Guardar Trayecto", $"Error de I/O al guardar trayecto: {ex}");
}
catch (Exception ex)
{
// Cualquier otra excepción general
Log.Nuevo(TipoLog.Error, "Guardar Trayecto", $"Error inesperado al guardar trayecto: {ex}");
}
}, cancellationToken: token);
// Tesoro
await UniTask.RunOnThreadPool(() =>
{
token.ThrowIfCancellationRequested();
try
{
ES3Settings aj = new ES3Settings(ARCH_GUARDADO);
ES3.Save("TESORO", tes, aj);
}
catch (UnauthorizedAccessException ex)
{
// Error relacionado con permisos
Log.Nuevo(TipoLog.Error, "Guardar Mazmorra", $"Permiso denegado al intentar guardar mazmorra: {ex}");
}
catch (PathTooLongException ex)
{
// El nombre del archivo o la ruta es demasiado largo
Log.Nuevo(TipoLog.Error, "Guardar Mazmorra", $"Ruta de archivo demasiado larga: {ex}");
}
catch (FileNotFoundException ex)
{
// El archivo no existe
Log.Nuevo(TipoLog.Error, "Guardar Mazmorra", $"Archivo no encontrado: {ex}");
}
catch (IOException ex)
{
// Error de I/O general
Log.Nuevo(TipoLog.Error, "Guardar Mazmorra", $"Error de I/O al guardar mazmorra: {ex}");
}
catch (Exception ex)
{
// Cualquier otra excepción general
Log.Nuevo(TipoLog.Error, "Guardar Mazmorra", $"Error inesperado al guardar mazmorra: {ex}");
}
}, cancellationToken: token);
// Comprobar cancelación antes de la siguiente parte
token.ThrowIfCancellationRequested();
}
#endregion
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment