diff --git a/ModiBuff/ModiBuff.Extensions.Serialization.Json/ModiBuff.Extensions.Serialization.Json.csproj b/ModiBuff/ModiBuff.Extensions.Serialization.Json/ModiBuff.Extensions.Serialization.Json.csproj index ad293bc..204d58c 100644 --- a/ModiBuff/ModiBuff.Extensions.Serialization.Json/ModiBuff.Extensions.Serialization.Json.csproj +++ b/ModiBuff/ModiBuff.Extensions.Serialization.Json/ModiBuff.Extensions.Serialization.Json.csproj @@ -6,7 +6,7 @@ - + @@ -14,4 +14,4 @@ - + \ No newline at end of file diff --git a/ModiBuff/ModiBuff.Tests/SaveLoadRecipeTests.cs b/ModiBuff/ModiBuff.Tests/SaveLoadRecipeTests.cs index 72c3848..e434605 100644 --- a/ModiBuff/ModiBuff.Tests/SaveLoadRecipeTests.cs +++ b/ModiBuff/ModiBuff.Tests/SaveLoadRecipeTests.cs @@ -238,7 +238,7 @@ public void SaveRemoveCallbackUnitRecipeLoad() { var saveRecipes = new ModifierRecipes(IdManager, EffectTypeIdManager); saveRecipes.Add("InitAddDamageRevertibleCallback") - .Tag(ModiBuff.Core.Units.TagType.StrongDispel) + .Dispel(DispelType.Strong) .Effect(new AddDamageEffect(5, EffectState.IsRevertible), EffectOn.Init) .Remove(RemoveEffectOn.CallbackUnit) .CallbackUnit(CallbackUnitType.StrongDispel); @@ -246,8 +246,7 @@ public void SaveRemoveCallbackUnitRecipeLoad() SaveLoadStateAndSetup(saveRecipes); Unit.AddModifierSelf("InitAddDamageRevertibleCallback"); - Assert.AreEqual(UnitDamage + 5, Unit.Damage); - Unit.StrongDispel(Unit); + Unit.Dispel(DispelType.Strong, Unit); Assert.AreEqual(UnitDamage, Unit.Damage); } diff --git a/ModiBuff/ModiBuff.Units/ModiBuff.Units.csproj b/ModiBuff/ModiBuff.Units/ModiBuff.Units.csproj index 5fa6a7f..e200efe 100644 --- a/ModiBuff/ModiBuff.Units/ModiBuff.Units.csproj +++ b/ModiBuff/ModiBuff.Units/ModiBuff.Units.csproj @@ -39,7 +39,7 @@ - + \ No newline at end of file diff --git a/ModiBuff/ModiBuff/Core/Modifier/Creation/Recipe/ModifierRecipeSaveLoad.cs b/ModiBuff/ModiBuff/Core/Modifier/Creation/Recipe/ModifierRecipeSaveLoad.cs index 9036243..c220f23 100644 --- a/ModiBuff/ModiBuff/Core/Modifier/Creation/Recipe/ModifierRecipeSaveLoad.cs +++ b/ModiBuff/ModiBuff/Core/Modifier/Creation/Recipe/ModifierRecipeSaveLoad.cs @@ -1,6 +1,5 @@ using System; using System.Linq; -using System.Reflection; namespace ModiBuff.Core { @@ -38,67 +37,65 @@ public void LoadState(SaveData saveData) break; case SaveInstruction.Interval.Id: #if MODIBUFF_SYSTEM_TEXT_JSON - Interval(instruction.Values.GetDataFromJsonObject()); + Interval(((SaveInstruction.Interval)instruction).Value); #endif break; case SaveInstruction.Duration.Id: #if MODIBUFF_SYSTEM_TEXT_JSON - Duration(instruction.Values.GetDataFromJsonObject()); + Duration(((SaveInstruction.Duration)instruction).Value); #endif break; case SaveInstruction.Remove.Id: #if MODIBUFF_SYSTEM_TEXT_JSON - var removeType = - (SaveInstruction.Remove.Type)instruction.GetValues(typeof(SaveInstruction.Remove.Type))[0]; - switch (removeType) + var remove = (SaveInstruction.Remove)instruction; + switch (remove.RemoveType) { case SaveInstruction.Remove.Type.RemoveOn: - Remove(((EffectOn)instruction.GetValues(typeof(SaveInstruction.Remove.Type), - typeof(EffectOn))[1]).ToRemoveEffectOn()); + Remove(remove.EffectOn.ToRemoveEffectOn()); break; case SaveInstruction.Remove.Type.Duration: - Remove((float)instruction - .GetValues(typeof(SaveInstruction.Remove.Type), typeof(float))[1]); + Remove(remove.Duration); break; default: - Logger.LogError($"[ModiBuff] Loaded remove instruction with unknown type {removeType}"); + Logger.LogError( + $"[ModiBuff] Loaded remove instruction with unknown type {remove.RemoveType}"); break; } #endif break; case SaveInstruction.Refresh.Id: #if MODIBUFF_SYSTEM_TEXT_JSON - Refresh(instruction.Values.GetDataFromJsonObject()); + Refresh(((SaveInstruction.Refresh)instruction).RefreshType); #endif break; case SaveInstruction.Stack.Id: #if MODIBUFF_SYSTEM_TEXT_JSON - object[] stackValues = instruction.GetValues(typeof(WhenStackEffect), typeof(int), typeof(int), - typeof(float), typeof(float)); - Stack((WhenStackEffect)stackValues[0], (int)stackValues[1], (int)stackValues[2], - (float)stackValues[3], (float)stackValues[4]); + var stack = (SaveInstruction.Stack)instruction; + Stack(stack.WhenStackEffect, stack.MaxStacks, stack.EveryXStacks, stack.SingleStackTime, + stack.IndependentStackTime); #endif break; case SaveInstruction.Dispel.Id: #if MODIBUFF_SYSTEM_TEXT_JSON - Dispel(instruction.Values.GetDataFromJsonObject()); + Dispel(((SaveInstruction.Dispel)instruction).Type); #endif break; case SaveInstruction.Tag.Id: #if MODIBUFF_SYSTEM_TEXT_JSON - object[] tagValues = instruction.GetValues(typeof(SaveInstruction.Tag.Type), typeof(TagType)); - _ = (SaveInstruction.Tag.Type)tagValues[0] switch + var tag = (SaveInstruction.Tag)instruction; + _ = tag.InstructionTagType switch { - SaveInstruction.Tag.Type.Add => Tag((TagType)tagValues[1]), - SaveInstruction.Tag.Type.Remove => RemoveTag((TagType)tagValues[1]), - SaveInstruction.Tag.Type.Set => SetTag((TagType)tagValues[1]), + SaveInstruction.Tag.Type.Add => Tag(tag.TagType), + SaveInstruction.Tag.Type.Remove => RemoveTag(tag.TagType), + SaveInstruction.Tag.Type.Set => SetTag(tag.TagType), _ => throw new ArgumentOutOfRangeException() }; #endif break; case SaveInstruction.CallbackUnit.Id: #if MODIBUFF_SYSTEM_TEXT_JSON - CallbackUnit(instruction.Values.GetDataFromJsonObject()); + CallbackUnit( + (TUnitCallback)(object)((SaveInstruction.CallbackUnit)instruction).CallbackUnitType); #endif break; case SaveInstruction.Effect.Id: @@ -110,8 +107,8 @@ public void LoadState(SaveData saveData) break; case SaveInstruction.ModifierAction.Id: #if MODIBUFF_SYSTEM_TEXT_JSON - object[] actionValues = instruction.GetValues(typeof(ModifierAction), typeof(EffectOn)); - ModifierAction((ModifierAction)actionValues[0], (EffectOn)actionValues[1]); + var action = (SaveInstruction.ModifierAction)instruction; + ModifierAction(action.ModifierActionFlags, action.EffectOn); #endif break; default: @@ -123,79 +120,57 @@ public void LoadState(SaveData saveData) #if MODIBUFF_SYSTEM_TEXT_JSON (IEffect, EffectOn) HandleEffect(SaveInstruction instruction) { - var values = ((System.Text.Json.JsonElement)instruction.Values).EnumerateObject(); + var effect = (SaveInstruction.Effect)instruction; bool failed = false; - int? effectId = null; - ConstructorInfo constructor = null; - object[] effectStates = null; - EffectOn? effectOn = null; - foreach (var value in values) - { - //TODO Not hardcode/dynamic order? - if (value.NameEquals("Item1")) - { - effectId = value.Value.GetInt32(); - } - - if (value.NameEquals("Item2")) - { - if (effectId == null) - { - Logger.LogWarning( - $"[ModiBuff] Couldn't extract recipe save data because of missing effect id for {Name}"); - continue; - } - var effectType = _effectTypeIdManager.GetEffectType(effectId.Value); - //TODO Find constructor by saved types? Prob not worth - constructor = effectType.GetConstructors()[0]; + int effectId = effect.EffectId; + EffectOn effectOn = effect.EffectOn; - var parameters = constructor.GetParameters(); - effectStates = new object[parameters.Length]; - int i = 0; - foreach (var property in value.Value.EnumerateObject()) - { - effectStates[i] = property.Value.GetDataFromJsonObject(parameters[i].ParameterType); - i++; - } - } + var effectType = _effectTypeIdManager.GetEffectType(effectId); + //TODO Find constructor by saved types? Prob not worth + var constructor = effectType.GetConstructors()[0]; - if (value.NameEquals("Item3")) + var parameters = constructor.GetParameters(); + object[] effectStates = new object[parameters.Length]; + int i = 0; + foreach (var property in ((System.Text.Json.JsonElement)effect.SaveData).EnumerateObject()) + { + object value = property.Value.ToValue(parameters[i].ParameterType); + if (value == null) { - effectOn = (EffectOn)value.Value.GetInt32(); + Logger.LogError( + $"[ModiBuff] Failed to load effect state from save data by {Name} for effect {effectId}"); + failed = true; } - } - - if (effectStates == null) - { - Logger.LogError( - $"[ModiBuff] Failed to load effect state from save data by {Name} {(effectId != -1 ? $"for effect {effectId}" : "")}"); - failed = true; - } - if (effectOn == null) - { - Logger.LogError($"[ModiBuff] Failed to load effect on from save data by {Name}"); - failed = true; - } - - if (effectId == null) - { - Logger.LogError($"[ModiBuff] Failed to load effect id from save data by {Name}"); - failed = true; + effectStates[i] = value; + i++; } if (failed) return (null, EffectOn.None); - return ((IEffect)constructor.Invoke(effectStates), effectOn.Value); + return ((IEffect)constructor.Invoke(effectStates), effectOn); } #endif } +#if MODIBUFF_SYSTEM_TEXT_JSON + [System.Text.Json.Serialization.JsonPolymorphic] + [System.Text.Json.Serialization.JsonDerivedType(typeof(Initialize), Initialize.Id)] + [System.Text.Json.Serialization.JsonDerivedType(typeof(Interval), Interval.Id)] + [System.Text.Json.Serialization.JsonDerivedType(typeof(Duration), Duration.Id)] + [System.Text.Json.Serialization.JsonDerivedType(typeof(Remove), Remove.Id)] + [System.Text.Json.Serialization.JsonDerivedType(typeof(Refresh), Refresh.Id)] + [System.Text.Json.Serialization.JsonDerivedType(typeof(Stack), Stack.Id)] + [System.Text.Json.Serialization.JsonDerivedType(typeof(Dispel), Dispel.Id)] + [System.Text.Json.Serialization.JsonDerivedType(typeof(Tag), Tag.Id)] + [System.Text.Json.Serialization.JsonDerivedType(typeof(CallbackUnit), CallbackUnit.Id)] + [System.Text.Json.Serialization.JsonDerivedType(typeof(Effect), Effect.Id)] + [System.Text.Json.Serialization.JsonDerivedType(typeof(ModifierAction), ModifierAction.Id)] +#endif public record SaveInstruction { - public readonly object Values; public readonly int InstructionId; private const int BaseId = 0; @@ -203,25 +178,27 @@ public record SaveInstruction #if MODIBUFF_SYSTEM_TEXT_JSON [System.Text.Json.Serialization.JsonConstructor] #endif - public SaveInstruction(object values, int instructionId) + public SaveInstruction(int instructionId) { - Values = values; InstructionId = instructionId; } -#if MODIBUFF_SYSTEM_TEXT_JSON - public object[] GetValues(params Type[] types) => ((System.Text.Json.JsonElement)Values).GetValues(types); -#endif public sealed record Initialize : SaveInstruction { public const int Id = BaseId; + public readonly string Name; + public readonly string DisplayName; + public readonly string Description; + #if MODIBUFF_SYSTEM_TEXT_JSON [System.Text.Json.Serialization.JsonConstructor] #endif - public Initialize(string name, string displayName, string description) - : base((name, displayName, description), Id) + public Initialize(string name, string displayName, string description) : base(Id) { + Name = name; + DisplayName = displayName; + Description = description; } } @@ -229,11 +206,14 @@ public sealed record Interval : SaveInstruction { public const int Id = Initialize.Id + 1; + public readonly float Value; + #if MODIBUFF_SYSTEM_TEXT_JSON [System.Text.Json.Serialization.JsonConstructor] #endif - public Interval(float interval) : base(interval, Id) + public Interval(float value) : base(Id) { + Value = value; } } @@ -241,17 +221,24 @@ public sealed record Duration : SaveInstruction { public const int Id = Interval.Id + 1; + public readonly float Value; + #if MODIBUFF_SYSTEM_TEXT_JSON [System.Text.Json.Serialization.JsonConstructor] #endif - public Duration(float duration) : base(duration, Id) + public Duration(float value) : base(Id) { + Value = value; } } public sealed record Remove : SaveInstruction { - public const int Id = Duration.Id + 1; + public const int Id = SaveInstruction.Duration.Id + 1; + + public readonly Type RemoveType; + public readonly EffectOn EffectOn; + public readonly float Duration; public enum Type { @@ -262,14 +249,11 @@ public enum Type #if MODIBUFF_SYSTEM_TEXT_JSON [System.Text.Json.Serialization.JsonConstructor] #endif - public Remove(Type type, EffectOn effectOn, float duration = 0) - : base(type switch - { - Type.RemoveOn => (type, effectOn), - Type.Duration => (type, duration), - _ => throw new ArgumentOutOfRangeException() - }, Id) + public Remove(Type removeType, EffectOn effectOn, float duration = 0) : base(Id) { + RemoveType = removeType; + EffectOn = effectOn; + Duration = duration; } } @@ -277,11 +261,14 @@ public sealed record Refresh : SaveInstruction { public const int Id = Remove.Id + 1; + public readonly RefreshType RefreshType; + #if MODIBUFF_SYSTEM_TEXT_JSON [System.Text.Json.Serialization.JsonConstructor] #endif - public Refresh(RefreshType type) : base(type, Id) + public Refresh(RefreshType refreshType) : base(Id) { + RefreshType = refreshType; } } @@ -289,13 +276,23 @@ public sealed record Stack : SaveInstruction { public const int Id = Refresh.Id + 1; + public readonly WhenStackEffect WhenStackEffect; + public readonly int MaxStacks; + public readonly int EveryXStacks; + public readonly float SingleStackTime; + public readonly float IndependentStackTime; + #if MODIBUFF_SYSTEM_TEXT_JSON [System.Text.Json.Serialization.JsonConstructor] #endif - public Stack(WhenStackEffect when, int maxStacks, int everyXStacks, - float singleStackTime, float independentStackTime) - : base((when, maxStacks, everyXStacks, singleStackTime, independentStackTime), Id) + public Stack(WhenStackEffect whenStackEffect, int maxStacks, int everyXStacks, float singleStackTime, + float independentStackTime) : base(Id) { + WhenStackEffect = whenStackEffect; + MaxStacks = maxStacks; + EveryXStacks = everyXStacks; + SingleStackTime = singleStackTime; + IndependentStackTime = independentStackTime; } } @@ -303,12 +300,12 @@ public sealed record Dispel : SaveInstruction { public const int Id = Stack.Id + 1; + public readonly DispelType Type; + #if MODIBUFF_SYSTEM_TEXT_JSON [System.Text.Json.Serialization.JsonConstructor] #endif - public Dispel(DispelType type) : base(type, Id) - { - } + public Dispel(DispelType type) : base(Id) => Type = type; } public sealed record Tag : SaveInstruction @@ -322,11 +319,16 @@ public enum Type Set, } + public readonly Type InstructionTagType; + public readonly TagType TagType; + #if MODIBUFF_SYSTEM_TEXT_JSON [System.Text.Json.Serialization.JsonConstructor] #endif - public Tag(Type type, TagType tagType) : base((type, tagType), Id) + public Tag(Type instructionTagType, TagType tagType) : base(Id) { + InstructionTagType = instructionTagType; + TagType = tagType; } } @@ -334,11 +336,14 @@ public sealed record CallbackUnit : SaveInstruction { public const int Id = Tag.Id + 1; + public readonly int CallbackUnitType; + #if MODIBUFF_SYSTEM_TEXT_JSON [System.Text.Json.Serialization.JsonConstructor] #endif - public CallbackUnit(int callbackUnit) : base(callbackUnit, Id) + public CallbackUnit(int callbackUnitType) : base(Id) { + CallbackUnitType = callbackUnitType; } } @@ -346,12 +351,18 @@ public sealed record Effect : SaveInstruction { public const int Id = CallbackUnit.Id + 1; + public readonly int EffectId; + public readonly object SaveData; + public readonly EffectOn EffectOn; + #if MODIBUFF_SYSTEM_TEXT_JSON [System.Text.Json.Serialization.JsonConstructor] #endif - public Effect(int effectId, object saveData, EffectOn effectOn) - : base((effectId, saveData, effectOn), Id) + public Effect(int effectId, object saveData, EffectOn effectOn) : base(Id) { + EffectId = effectId; + SaveData = saveData; + EffectOn = effectOn; } } @@ -359,12 +370,16 @@ public sealed record ModifierAction : SaveInstruction { public const int Id = Effect.Id + 1; + public readonly ModiBuff.Core.ModifierAction ModifierActionFlags; + public readonly EffectOn EffectOn; + #if MODIBUFF_SYSTEM_TEXT_JSON [System.Text.Json.Serialization.JsonConstructor] #endif - public ModifierAction(ModiBuff.Core.ModifierAction modifierAction, EffectOn effectOn) - : base((modifierAction, effectOn), Id) + public ModifierAction(ModiBuff.Core.ModifierAction modifierActionFlags, EffectOn effectOn) : base(Id) { + ModifierActionFlags = modifierActionFlags; + EffectOn = effectOn; } } } diff --git a/ModiBuff/ModiBuff/Core/Modifier/Creation/Recipe/ModifierRecipes.cs b/ModiBuff/ModiBuff/Core/Modifier/Creation/Recipe/ModifierRecipes.cs index 7df0f18..5fdb711 100644 --- a/ModiBuff/ModiBuff/Core/Modifier/Creation/Recipe/ModifierRecipes.cs +++ b/ModiBuff/ModiBuff/Core/Modifier/Creation/Recipe/ModifierRecipes.cs @@ -214,9 +214,9 @@ public void LoadState(SaveData saveData) continue; #if MODIBUFF_SYSTEM_TEXT_JSON - object[] values = instruction.GetValues(typeof(string), typeof(string), typeof(string)); + var init = instruction as ModifierRecipe.SaveInstruction.Initialize; - if (values[0] == null) + if (init == null || init.Name == null) { //TODO Identification Logger.LogError( @@ -224,7 +224,7 @@ public void LoadState(SaveData saveData) break; } - recipe = Add((string)values[0], (string)values[1], (string)values[2]); + recipe = Add(init.Name, init.DisplayName, init.Description); #endif break; } diff --git a/ModiBuff/ModiBuff/Core/SerializationExtensions.cs b/ModiBuff/ModiBuff/Core/SerializationExtensions.cs index a756eac..c38eceb 100644 --- a/ModiBuff/ModiBuff/Core/SerializationExtensions.cs +++ b/ModiBuff/ModiBuff/Core/SerializationExtensions.cs @@ -62,11 +62,6 @@ public static T GetDataFromJsonObject(this object fromLoad) return TryGetDataFromJsonObject(fromLoad, out T data) ? data : default; } - public static object GetDataFromJsonObject(this object fromLoad, Type type) - { - return fromLoad is not System.Text.Json.JsonElement jsonElement ? null : jsonElement.ToValue(type); - } - private static readonly List valuesHolder = new List(); public static object[] GetValues(this System.Text.Json.JsonElement element, params Type[] types) @@ -95,7 +90,7 @@ public static object[] GetValues(this System.Text.Json.JsonElement element, para return values; } - private static object ToValue(this System.Text.Json.JsonElement element, Type type) + public static object ToValue(this System.Text.Json.JsonElement element, Type type) { if (type == typeof(int)) return element.GetInt32();