diff --git a/VoidBox/Assets/BuiltinEnvs.json b/VoidBox/Assets/BuiltinEnvs.json new file mode 100644 index 0000000..0501641 --- /dev/null +++ b/VoidBox/Assets/BuiltinEnvs.json @@ -0,0 +1,526 @@ +[ + { + "$type": "VoidBox.SavedEnv, VoidBox", + "Id": "8d6fbf26-2657-4376-9c7f-c319f5c58787", + "Name": "Gold Saucer", + "Env": { + "$type": "System.Nullable`1[[Ktisis.Structs.Env.EnvState, VoidBox]], System.Private.CoreLib", + "SkyId": 115, + "Lighting": { + "$type": "Ktisis.Structs.Env.Weather.EnvLighting, VoidBox", + "SunLightColor": { + "$type": "System.Numerics.Vector3, System.Private.CoreLib", + "X": 0.0, + "Y": 0.0, + "Z": 0.0 + }, + "MoonLightColor": { + "$type": "System.Numerics.Vector3, System.Private.CoreLib", + "X": 0.0, + "Y": 0.0, + "Z": 0.0 + }, + "Ambient": { + "$type": "System.Numerics.Vector3, System.Private.CoreLib", + "X": 0.2, + "Y": 0.18274511, + "Z": 0.13960785 + }, + "_unk1": 0.5, + "AmbientSaturation": 1.0, + "Temperature": 1.0, + "_unk2": 0.0, + "_unk3": 75.0, + "_unk4": 0.75 + }, + "Stars": { + "$type": "Ktisis.Structs.Env.Weather.EnvStars, VoidBox", + "ConstellationIntensity": 0.0, + "Constellations": 0.0, + "Stars": 0.0, + "GalaxyIntensity": 0.0, + "StarIntensity": 0.0, + "MoonColor": { + "$type": "System.Numerics.Vector4, System.Private.CoreLib", + "X": 0.0, + "Y": 0.0, + "Z": 0.0, + "W": 1.0 + }, + "MoonBrightness": 0.0 + }, + "Fog": { + "$type": "Ktisis.Structs.Env.Weather.EnvFog, VoidBox", + "Color": { + "$type": "System.Numerics.Vector4, System.Private.CoreLib", + "X": 0.14901961, + "Y": 0.11764706, + "Z": 0.043137256, + "W": 0.8980392 + }, + "Distance": 30.0, + "Thickness": 3.0, + "_unk1": 1000.0, + "_unk2": 1.0, + "Opacity": 0.0, + "SkyVisibility": 1.0 + }, + "Clouds": { + "$type": "Ktisis.Structs.Env.Weather.EnvClouds, VoidBox", + "CloudColor": { + "$type": "System.Numerics.Vector3, System.Private.CoreLib", + "X": 1.0, + "Y": 1.0, + "Z": 1.0 + }, + "Color2": { + "$type": "System.Numerics.Vector3, System.Private.CoreLib", + "X": 1.0, + "Y": 1.0, + "Z": 1.0 + }, + "Gradient": 0.5, + "SideHeight": 0.0, + "CloudTexture": 0, + "CloudSideTexture": 0 + }, + "Rain": { + "$type": "Ktisis.Structs.Env.Weather.EnvRain, VoidBox", + "Raindrops": 0.0, + "Intensity": 0.0, + "Weight": 0.0, + "Scatter": 0.0, + "_unk1": 0.0, + "Size": 1.0, + "Color": { + "$type": "System.Numerics.Vector4, System.Private.CoreLib", + "X": 0.0, + "Y": 0.0, + "Z": 0.0, + "W": 0.0 + }, + "_unk2": 0.0, + "_unk3": 0.0, + "_unk4": 0 + }, + "Dust": { + "$type": "Ktisis.Structs.Env.Weather.EnvDust, VoidBox", + "_unk1": 0.0, + "Intensity": 0.0, + "Weight": 0.0, + "Spread": 0.0, + "Speed": 0.0, + "Size": 1.0, + "Color": { + "$type": "System.Numerics.Vector4, System.Private.CoreLib", + "X": 0.0, + "Y": 0.0, + "Z": 0.0, + "W": 0.0 + }, + "Glow": 0.0, + "Spin": 0.0, + "TextureId": 0 + }, + "Wind": { + "$type": "Ktisis.Structs.Env.Weather.EnvWind, VoidBox", + "Direction": 0.0, + "Angle": 0.0, + "Speed": 0.02118928 + } + } + }, + { + "$type": "VoidBox.SavedEnv, VoidBox", + "Id": "da23edec-abbe-4453-a2a0-6b0e22cbd0cf", + "Name": "Sylphstep", + "Env": { + "$type": "System.Nullable`1[[Ktisis.Structs.Env.EnvState, VoidBox]], System.Private.CoreLib", + "SkyId": 2, + "Lighting": { + "$type": "Ktisis.Structs.Env.Weather.EnvLighting, VoidBox", + "SunLightColor": { + "$type": "System.Numerics.Vector3, System.Private.CoreLib", + "X": 1.4, + "Y": 1.3890195, + "Z": 1.3341175 + }, + "MoonLightColor": { + "$type": "System.Numerics.Vector3, System.Private.CoreLib", + "X": 0.0, + "Y": 0.0, + "Z": 0.0 + }, + "Ambient": { + "$type": "System.Numerics.Vector3, System.Private.CoreLib", + "X": 0.0, + "Y": 0.0, + "Z": 0.0 + }, + "_unk1": 0.5, + "AmbientSaturation": 1.4, + "Temperature": 1.0, + "_unk2": 0.0, + "_unk3": 0.0, + "_unk4": 0.1 + }, + "Stars": { + "$type": "Ktisis.Structs.Env.Weather.EnvStars, VoidBox", + "ConstellationIntensity": 0.0, + "Constellations": 0.0, + "Stars": 0.0, + "GalaxyIntensity": 0.0, + "StarIntensity": 0.0, + "MoonColor": { + "$type": "System.Numerics.Vector4, System.Private.CoreLib", + "X": 1.296732, + "Y": 1.290196, + "Z": 1.5416666, + "W": 0.044934645 + }, + "MoonBrightness": 0.19999999 + }, + "Fog": { + "$type": "Ktisis.Structs.Env.Weather.EnvFog, VoidBox", + "Color": { + "$type": "System.Numerics.Vector4, System.Private.CoreLib", + "X": 0.09019608, + "Y": 0.40784314, + "Z": 0.6666667, + "W": 0.49803922 + }, + "Distance": 100.0, + "Thickness": 1.0, + "_unk1": 1000.0, + "_unk2": 1.0, + "Opacity": 0.0, + "SkyVisibility": 1.0 + }, + "Clouds": { + "$type": "Ktisis.Structs.Env.Weather.EnvClouds, VoidBox", + "CloudColor": { + "$type": "System.Numerics.Vector3, System.Private.CoreLib", + "X": 0.84313726, + "Y": 0.9647059, + "Z": 1.0 + }, + "Color2": { + "$type": "System.Numerics.Vector3, System.Private.CoreLib", + "X": 0.5137255, + "Y": 0.7137255, + "Z": 0.75686276 + }, + "Gradient": 1.5, + "SideHeight": 0.75, + "CloudTexture": 0, + "CloudSideTexture": 17 + }, + "Rain": { + "$type": "Ktisis.Structs.Env.Weather.EnvRain, VoidBox", + "Raindrops": 0.0, + "Intensity": 0.0, + "Weight": 0.0, + "Scatter": 0.0, + "_unk1": 0.0, + "Size": 1.0, + "Color": { + "$type": "System.Numerics.Vector4, System.Private.CoreLib", + "X": 0.0, + "Y": 0.0, + "Z": 0.0, + "W": 0.0 + }, + "_unk2": 0.0, + "_unk3": 0.0, + "_unk4": 0 + }, + "Dust": { + "$type": "Ktisis.Structs.Env.Weather.EnvDust, VoidBox", + "_unk1": 0.002, + "Intensity": 0.002, + "Weight": 1.0, + "Spread": 5.0, + "Speed": 0.5, + "Size": 20.0, + "Color": { + "$type": "System.Numerics.Vector4, System.Private.CoreLib", + "X": 1.0, + "Y": 1.0, + "Z": 1.0, + "W": 1.0 + }, + "Glow": 0.0, + "Spin": 0.75, + "TextureId": 4 + }, + "Wind": { + "$type": "Ktisis.Structs.Env.Weather.EnvWind, VoidBox", + "Direction": 0.0, + "Angle": 0.0, + "Speed": 0.17609125 + } + } + }, + { + "$type": "VoidBox.SavedEnv, VoidBox", + "Id": "9cf79923-aa7f-4edd-b7b0-f9ff5c4d50dc", + "Name": "Sylphstep (Foggy)", + "Env": { + "$type": "System.Nullable`1[[Ktisis.Structs.Env.EnvState, VoidBox]], System.Private.CoreLib", + "SkyId": 2, + "Lighting": { + "$type": "Ktisis.Structs.Env.Weather.EnvLighting, VoidBox", + "SunLightColor": { + "$type": "System.Numerics.Vector3, System.Private.CoreLib", + "X": 0.6243137, + "Y": 0.61803925, + "Z": 0.8 + }, + "MoonLightColor": { + "$type": "System.Numerics.Vector3, System.Private.CoreLib", + "X": 0.0, + "Y": 0.0, + "Z": 0.0 + }, + "Ambient": { + "$type": "System.Numerics.Vector3, System.Private.CoreLib", + "X": 0.0, + "Y": 0.0, + "Z": 0.0 + }, + "_unk1": 0.5, + "AmbientSaturation": 1.0, + "Temperature": 1.0, + "_unk2": 1.5, + "_unk3": 0.0, + "_unk4": 0.1 + }, + "Stars": { + "$type": "Ktisis.Structs.Env.Weather.EnvStars, VoidBox", + "ConstellationIntensity": 0.0, + "Constellations": 0.0, + "Stars": 0.0, + "GalaxyIntensity": 0.0, + "StarIntensity": 0.0, + "MoonColor": { + "$type": "System.Numerics.Vector4, System.Private.CoreLib", + "X": 1.296732, + "Y": 1.290196, + "Z": 1.5416666, + "W": 0.044934645 + }, + "MoonBrightness": 0.19999999 + }, + "Fog": { + "$type": "Ktisis.Structs.Env.Weather.EnvFog, VoidBox", + "Color": { + "$type": "System.Numerics.Vector4, System.Private.CoreLib", + "X": 0.09019608, + "Y": 0.12156863, + "Z": 0.40784314, + "W": 0.8980392 + }, + "Distance": 40.0, + "Thickness": 2.5, + "_unk1": 1000.0, + "_unk2": 1.0, + "Opacity": 0.75, + "SkyVisibility": 0.25 + }, + "Clouds": { + "$type": "Ktisis.Structs.Env.Weather.EnvClouds, VoidBox", + "CloudColor": { + "$type": "System.Numerics.Vector3, System.Private.CoreLib", + "X": 0.2602941, + "Y": 0.3637255, + "Z": 0.5730392 + }, + "Color2": { + "$type": "System.Numerics.Vector3, System.Private.CoreLib", + "X": 0.09019608, + "Y": 0.14117648, + "Z": 0.2 + }, + "Gradient": 1.5, + "SideHeight": 0.75, + "CloudTexture": 0, + "CloudSideTexture": 17 + }, + "Rain": { + "$type": "Ktisis.Structs.Env.Weather.EnvRain, VoidBox", + "Raindrops": 0.0, + "Intensity": 0.0, + "Weight": 0.0, + "Scatter": 0.0, + "_unk1": 0.0, + "Size": 1.0, + "Color": { + "$type": "System.Numerics.Vector4, System.Private.CoreLib", + "X": 0.0, + "Y": 0.0, + "Z": 0.0, + "W": 0.0 + }, + "_unk2": 0.0, + "_unk3": 0.0, + "_unk4": 0 + }, + "Dust": { + "$type": "Ktisis.Structs.Env.Weather.EnvDust, VoidBox", + "_unk1": 0.002, + "Intensity": 0.002, + "Weight": 1.0, + "Spread": 5.0, + "Speed": 0.5, + "Size": 20.0, + "Color": { + "$type": "System.Numerics.Vector4, System.Private.CoreLib", + "X": 1.0, + "Y": 1.0, + "Z": 1.0, + "W": 1.0 + }, + "Glow": 0.0, + "Spin": 0.75, + "TextureId": 4 + }, + "Wind": { + "$type": "Ktisis.Structs.Env.Weather.EnvWind, VoidBox", + "Direction": 0.0, + "Angle": 0.0, + "Speed": 0.17609125 + } + } + }, + { + "$type": "VoidBox.SavedEnv, VoidBox", + "Id": "d30f1b8d-2076-41f7-b53c-4d1145456c52", + "Name": "Opinionated", + "Env": { + "$type": "System.Nullable`1[[Ktisis.Structs.Env.EnvState, VoidBox]], System.Private.CoreLib", + "SkyId": 1, + "Lighting": { + "$type": "Ktisis.Structs.Env.Weather.EnvLighting, VoidBox", + "SunLightColor": { + "$type": "System.Numerics.Vector3, System.Private.CoreLib", + "X": 0.86194694, + "Y": 0.69091094, + "Z": 0.68265486 + }, + "MoonLightColor": { + "$type": "System.Numerics.Vector3, System.Private.CoreLib", + "X": 0.2848343, + "Y": 0.36279023, + "Z": 0.7 + }, + "Ambient": { + "$type": "System.Numerics.Vector3, System.Private.CoreLib", + "X": 0.5, + "Y": 0.45294118, + "Z": 0.4 + }, + "_unk1": 0.5, + "AmbientSaturation": 1.0, + "Temperature": 1.0, + "_unk2": 3.774338, + "_unk3": 75.0, + "_unk4": 0.75 + }, + "Stars": { + "$type": "Ktisis.Structs.Env.Weather.EnvStars, VoidBox", + "ConstellationIntensity": 0.88, + "Constellations": 3.162, + "Stars": 14.305, + "GalaxyIntensity": 5.314, + "StarIntensity": 0.308, + "MoonColor": { + "$type": "System.Numerics.Vector4, System.Private.CoreLib", + "X": 1.0, + "Y": 1.0, + "Z": 1.0, + "W": 1.0 + }, + "MoonBrightness": 0.41 + }, + "Fog": { + "$type": "Ktisis.Structs.Env.Weather.EnvFog, VoidBox", + "Color": { + "$type": "System.Numerics.Vector4, System.Private.CoreLib", + "X": 0.44186044, + "Y": 0.44186044, + "Z": 0.44186044, + "W": 1.0 + }, + "Distance": 50.0, + "Thickness": 5.0, + "_unk1": 1000.0, + "_unk2": 1.0, + "Opacity": 0.11, + "SkyVisibility": 0.133 + }, + "Clouds": { + "$type": "Ktisis.Structs.Env.Weather.EnvClouds, VoidBox", + "CloudColor": { + "$type": "System.Numerics.Vector3, System.Private.CoreLib", + "X": 0.38139534, + "Y": 0.38139534, + "Z": 0.38139534 + }, + "Color2": { + "$type": "System.Numerics.Vector3, System.Private.CoreLib", + "X": 0.9906977, + "Y": 0.9906977, + "Z": 0.9906977 + }, + "Gradient": 0.5, + "SideHeight": 2.0, + "CloudTexture": 10, + "CloudSideTexture": 48 + }, + "Rain": { + "$type": "Ktisis.Structs.Env.Weather.EnvRain, VoidBox", + "Raindrops": 0.0, + "Intensity": 0.0, + "Weight": 0.0, + "Scatter": 0.0, + "_unk1": 0.0, + "Size": 1.0, + "Color": { + "$type": "System.Numerics.Vector4, System.Private.CoreLib", + "X": 0.0, + "Y": 0.0, + "Z": 0.0, + "W": 0.0 + }, + "_unk2": 0.0, + "_unk3": 0.0, + "_unk4": 0 + }, + "Dust": { + "$type": "Ktisis.Structs.Env.Weather.EnvDust, VoidBox", + "_unk1": 0.0, + "Intensity": 0.0, + "Weight": 0.0, + "Spread": 0.0, + "Speed": 0.0, + "Size": 1.0, + "Color": { + "$type": "System.Numerics.Vector4, System.Private.CoreLib", + "X": 0.0, + "Y": 0.0, + "Z": 0.0, + "W": 0.0 + }, + "Glow": 0.0, + "Spin": 0.0, + "TextureId": 0 + }, + "Wind": { + "$type": "Ktisis.Structs.Env.Weather.EnvWind, VoidBox", + "Direction": 0.0, + "Angle": 0.0, + "Speed": 0.0 + } + } + } +] \ No newline at end of file diff --git a/VoidBox/Configuration.cs b/VoidBox/Configuration.cs index 14e90dc..acb82e5 100644 --- a/VoidBox/Configuration.cs +++ b/VoidBox/Configuration.cs @@ -1,26 +1,92 @@ using Dalamud.Configuration; using Dalamud.Plugin; +using Ktisis.Structs.Env; +using Newtonsoft.Json; using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Xml.Linq; namespace VoidBox; [Serializable] public class Configuration : IPluginConfiguration { + private static readonly JsonSerializer _jsonSerializer = JsonSerializer.CreateDefault(); + + [NonSerialized] + private DalamudPluginInterface? _pluginInterface; + + [JsonProperty] + private Guid _loginGuid; + [NonSerialized] + private SavedEnv? _loginEnv; + + [JsonProperty] + private Guid _housingGuid; + [NonSerialized] + private SavedEnv? _housingEnv; + public int Version { get; set; } = 0; public bool IsEnabled = true; - [NonSerialized] - private DalamudPluginInterface? pluginInterface; + public List Envs = []; + + [JsonIgnore] + public SavedEnv? LoginEnv + { + get => _loginEnv; + set + { + _loginEnv = value; + _loginGuid = value?.Id ?? default; + } + } + + [JsonIgnore] + public SavedEnv? HousingEnv + { + get => _housingEnv; + set + { + _housingEnv = value; + _housingGuid = value?.Id ?? default; + } + } internal void Initialize(DalamudPluginInterface pluginInterface) { - this.pluginInterface = pluginInterface; + _pluginInterface = pluginInterface; + + _loginEnv = Service.Envs.FirstOrDefault(v => v.Env.Id == _loginGuid).Env; + _housingEnv = Service.Envs.FirstOrDefault(v => v.Env.Id == _housingGuid).Env; } public void Save() { - pluginInterface!.SavePluginConfig(this); + _pluginInterface!.SavePluginConfig(this); } } + +public sealed record SavedEnv +{ + public static readonly SavedEnv Unchanged = new(default, "Unchanged", null); + + public SavedEnv(string name, EnvState env) + : this(Guid.NewGuid(), name, new EnvState?(env)) + { + } + + private SavedEnv(Guid id, string name, EnvState? env) + { + Id = id; + Name = name; + Env = env; + } + + public Guid Id { get; set; } + public string Name { get; set; } + public EnvState? Env { get; } +} diff --git a/VoidBox/EnvCollection.cs b/VoidBox/EnvCollection.cs new file mode 100644 index 0000000..d2acfeb --- /dev/null +++ b/VoidBox/EnvCollection.cs @@ -0,0 +1,156 @@ +using Dalamud.Hooking; +using Dalamud.IoC; +using Dalamud.Plugin; +using Dalamud.Utility.Signatures; +using Ktisis.Structs.Env; +using Newtonsoft.Json; +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Numerics; +using System.Reflection; + +namespace VoidBox; + +public record struct EnvCollectionEntry(SavedEnv Env, bool IsBuiltin); + +public sealed class EnvCollection : IList +{ + private static readonly JsonSerializer _jsonSerializer = JsonSerializer.CreateDefault(); + + public static List Config => Service.Config.Envs; + + private readonly List _builtin; + private readonly List _copy = []; + + public EnvCollection() + { + var asm = Assembly.GetExecutingAssembly(); + var path = $"{asm.GetName().Name}.Assets.BuiltinEnvs.json"; + + try + { + using var stream = asm.GetManifestResourceStream(path) ?? throw new FileNotFoundException(path); + using var streamReader = new StreamReader(stream); + using var reader = new JsonTextReader(streamReader); + _builtin = _jsonSerializer.Deserialize>(reader) ?? throw new NullReferenceException(); + } + catch (Exception e) + { + Service.PluginLog.Error($"Failed to parse builtin envs: {e}"); + _builtin = []; + } + + _builtin.Insert(0, SavedEnv.Unchanged); + } + + public EnvCollectionEntry this[int index] { + get + { + if (index < _builtin.Count) + { + return new(_builtin[index], true); + } + + index -= _builtin.Count; + + return new(Config[index], false); + } + set => throw new NotSupportedException(); + } + + public IReadOnlyList Builtin => _builtin; + + public int Count => throw new NotImplementedException(); + + public bool IsReadOnly => throw new NotImplementedException(); + + public void Add(EnvCollectionEntry item) + { + throw new NotSupportedException(); + } + + public void Clear() + { + throw new NotSupportedException(); + } + + public bool Contains(EnvCollectionEntry item) + { + return item.IsBuiltin ? _builtin.Contains(item.Env) : Config.Contains(item.Env); + } + + public void CopyTo(EnvCollectionEntry[] array, int arrayIndex) + { + throw new NotImplementedException(); + } + + public IEnumerator GetEnumerator() + { + foreach (var env in _builtin) + { + yield return new(env, true); + } + + foreach (var env in Config) + { + yield return new(env, false); + } + } + + public int IndexOf(EnvCollectionEntry item) + { + if (item.IsBuiltin) + { + var index = _builtin.IndexOf(item.Env); + if (index != -1) + { + return index; + } + } + else + { + var index = Config.IndexOf(item.Env); + if (index != -1) + { + return _builtin.Count + index; + } + } + + return -1; + } + + public void Insert(int index, EnvCollectionEntry item) + { + throw new NotSupportedException(); + } + + public bool Remove(EnvCollectionEntry item) + { + throw new NotSupportedException(); + } + + public void RemoveAt(int index) + { + throw new NotSupportedException(); + } + + public IEnumerable Copy() + { + _copy.Clear(); + + foreach (var env in this) + { + _copy.Add(env); + } + + return _copy; + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } +} diff --git a/VoidBox/Plugin.cs b/VoidBox/Plugin.cs index 797ae81..b324f1b 100644 --- a/VoidBox/Plugin.cs +++ b/VoidBox/Plugin.cs @@ -1,17 +1,12 @@ using Dalamud.Hooking; using Dalamud.IoC; using Dalamud.Plugin; -using Dalamud.Plugin.Services; using Dalamud.Utility.Signatures; using Ktisis.Structs.Env; -using Serilog; -using Serilog.Core; using System; using System.Collections.Generic; using System.Linq; using System.Numerics; -using System.Reflection.Emit; -using System.Runtime.Intrinsics.Arm; namespace VoidBox; @@ -25,11 +20,22 @@ public sealed unsafe class Plugin : IDalamudPlugin Service.Plugin = this; - Service.Config = Service.PluginInterface.GetPluginConfig() as Configuration ?? new(); - Service.Config.Initialize(Service.PluginInterface); + try + { + Service.Config = Service.PluginInterface.GetPluginConfig() as Configuration ?? new(); + } + catch (Exception e) + { + Service.PluginLog.Error($"Failed to load config: {e}"); + Service.Config = new(); + } Service.PluginUI = new(); + Service.Envs = new(); + + Service.Config.Initialize(Service.PluginInterface); + _cmds = typeof(Plugin).Assembly.GetTypes() .Where(t => !t.IsAbstract && typeof(Cmd).IsAssignableFrom(t)) .Select(t => (Cmd) Activator.CreateInstance(t)!) @@ -42,14 +48,17 @@ public sealed unsafe class Plugin : IDalamudPlugin Service.GameInteropProvider.InitializeFromAttributes(this); - EnvStateCopyHook?.Enable(); + _envStateCopyHook?.Enable(); } public string Name => "VoidBox"; + public EnvState Current { get; private set; } + public SavedEnv? Preview { get; set; } + public void Dispose() { - EnvStateCopyHook?.Dispose(); + _envStateCopyHook?.Dispose(); foreach (Cmd cmd in _cmds) { @@ -63,48 +72,100 @@ public sealed unsafe class Plugin : IDalamudPlugin private void Replace(EnvState* env) { - if (!Service.Config.IsEnabled) + var config = Service.Config; + if (!config.IsEnabled) { return; } - if (env->SkyId != 0) + var savedEnv = (Preview ?? (Service.ClientState.IsLoggedIn ? config.HousingEnv : config.LoginEnv))?.Env; + if (savedEnv == null) { return; } - env->SkyId = 1; - env->Clouds.CloudTexture = 10; - env->Clouds.CloudSideTexture = 48; - env->Clouds.CloudColor = new Vector3(0f, 0f, 0f); - env->Clouds.Color2 = new Vector3(1f, 1f, 1f); - env->Clouds.Gradient = 0.5f; - env->Clouds.SideHeight = 2f; + var savedEnvVal = savedEnv.Value; + Replace(env, &savedEnvVal); + } - env->Fog.Color = new Vector4(0.4f, 0.4f, 0.4f, 1f); - env->Fog.Distance = 50f; - env->Fog.Thickness = 5f; - env->Fog.Opacity = 0.231f; - env->Fog.SkyVisibility = 0.254f; + private void Replace(EnvState* to, EnvState* from) + { + to->SkyId = from->SkyId; - env->Stars.Stars = 20f; - env->Stars.StarIntensity = 1.104f; - env->Stars.Constellations = 4.686f; - env->Stars.ConstellationIntensity = 1.172f; - env->Stars.GalaxyIntensity = 5.628f; - env->Stars.MoonColor = new Vector4(1f, 1f, 1f, 1f); - env->Stars.MoonBrightness = 0.603f; + to->Lighting.SunLightColor = from->Lighting.SunLightColor; + to->Lighting.MoonLightColor = from->Lighting.MoonLightColor; + to->Lighting.Ambient = from->Lighting.Ambient; + to->Lighting._unk1 = from->Lighting._unk1; + to->Lighting.AmbientSaturation = from->Lighting.AmbientSaturation; + to->Lighting.Temperature = from->Lighting.Temperature; + to->Lighting._unk2 = from->Lighting._unk2; + to->Lighting._unk3 = from->Lighting._unk3; + to->Lighting._unk4 = from->Lighting._unk4; + + to->Stars.ConstellationIntensity = from->Stars.ConstellationIntensity; + to->Stars.Constellations = from->Stars.Constellations; + to->Stars.Stars = from->Stars.Stars; + to->Stars.GalaxyIntensity = from->Stars.GalaxyIntensity; + to->Stars.StarIntensity = from->Stars.StarIntensity; + to->Stars.MoonColor = from->Stars.MoonColor; + to->Stars.MoonBrightness = from->Stars.MoonBrightness; + + to->Fog.Color = from->Fog.Color; + to->Fog.Distance = from->Fog.Distance; + to->Fog.Thickness = from->Fog.Thickness; + to->Fog._unk1 = from->Fog._unk1; + to->Fog._unk2 = from->Fog._unk2; + to->Fog.Opacity = from->Fog.Opacity; + to->Fog.SkyVisibility = from->Fog.SkyVisibility; + + to->Clouds.CloudColor = from->Clouds.CloudColor; + to->Clouds.Color2 = from->Clouds.Color2; + to->Clouds.Gradient = from->Clouds.Gradient; + to->Clouds.SideHeight = from->Clouds.SideHeight; + to->Clouds.CloudTexture = from->Clouds.CloudTexture; + to->Clouds.CloudSideTexture = from->Clouds.CloudSideTexture; + + to->Rain.Raindrops = from->Rain.Raindrops; + to->Rain.Intensity = from->Rain.Intensity; + to->Rain.Weight = from->Rain.Weight; + to->Rain.Scatter = from->Rain.Scatter; + to->Rain._unk1 = from->Rain._unk1; + to->Rain.Size = from->Rain.Size; + to->Rain.Color = from->Rain.Color; + to->Rain._unk2 = from->Rain._unk2; + to->Rain._unk3 = from->Rain._unk3; + to->Rain._unk4 = from->Rain._unk4; + + to->Dust._unk1 = from->Dust._unk1; + to->Dust.Intensity = from->Dust.Intensity; + to->Dust.Weight = from->Dust.Weight; + to->Dust.Spread = from->Dust.Spread; + to->Dust.Speed = from->Dust.Speed; + to->Dust.Size = from->Dust.Size; + to->Dust.Color = from->Dust.Color; + to->Dust.Glow = from->Dust.Glow; + to->Dust.Spin = from->Dust.Spin; + to->Dust.TextureId = from->Dust.TextureId; + + to->Wind.Direction = from->Wind.Direction; + to->Wind.Angle = from->Wind.Angle; + to->Wind.Speed = from->Wind.Speed; } private unsafe delegate nint EnvStateCopyDelegate(EnvState* dest, EnvState* src); [Signature("E8 ?? ?? ?? ?? 49 3B F5", DetourName = nameof(EnvStateCopyDetour))] - private Hook EnvStateCopyHook = null!; + private Hook _envStateCopyHook = null!; private unsafe nint EnvStateCopyDetour(EnvState* dest, EnvState* src) { - var exec = EnvStateCopyHook.Original(dest, src); + Current = *dest; - Replace(dest); + var exec = _envStateCopyHook.Original(dest, src); + + if (dest->SkyId == 0) + { + Replace(dest); + } return exec; } diff --git a/VoidBox/PluginUI.cs b/VoidBox/PluginUI.cs index 41cf470..56219bd 100644 --- a/VoidBox/PluginUI.cs +++ b/VoidBox/PluginUI.cs @@ -21,11 +21,7 @@ public sealed class PluginUI : IDisposable public bool SettingsVisible { get => _configWindow.IsOpen; - set - { - _configWindow.IsOpen = value; - _configWindow.UpdateFromConfig(); - } + set => _configWindow.IsOpen = value; } public void Dispose() diff --git a/VoidBox/Service.cs b/VoidBox/Service.cs index 0936856..fc67256 100644 --- a/VoidBox/Service.cs +++ b/VoidBox/Service.cs @@ -2,6 +2,7 @@ using Dalamud.IoC; using Dalamud.Plugin; using Dalamud.Plugin.Services; +using Dalamud.Storage; namespace VoidBox; @@ -13,6 +14,8 @@ public sealed class Service public static PluginUI PluginUI { get; internal set; } = null!; + public static EnvCollection Envs { get; internal set; } = null!; + [PluginService] public static DalamudPluginInterface PluginInterface { get; private set; } = null!; diff --git a/VoidBox/VoidBox.csproj b/VoidBox/VoidBox.csproj index 558be80..96a7f3a 100644 --- a/VoidBox/VoidBox.csproj +++ b/VoidBox/VoidBox.csproj @@ -3,7 +3,7 @@ 0x0ade - 0.1.0.0 + 0.1.0.1 @@ -24,6 +24,14 @@ $(appdata)\XIVLauncher\addon\Hooks\dev\ + + + + + + + + diff --git a/VoidBox/Windows/ConfigWindow.cs b/VoidBox/Windows/ConfigWindow.cs index e4234da..8efaf48 100644 --- a/VoidBox/Windows/ConfigWindow.cs +++ b/VoidBox/Windows/ConfigWindow.cs @@ -1,5 +1,6 @@ using Dalamud.Interface.Windowing; using ImGuiNET; +using Ktisis.Structs.Env.Weather; using System; using System.Numerics; @@ -7,52 +8,194 @@ namespace VoidBox.Windows; public class ConfigWindow : Window, IDisposable { - private bool _configIsEnabled; + private string? _renamingName; + private SavedEnv? _renaming; public ConfigWindow() : base( "VoidBox", - ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoScrollbar | + ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoScrollWithMouse) { - Size = new Vector2(430, 184); - SizeCondition = ImGuiCond.Always; + SizeConstraints = new() + { + MinimumSize = new Vector2(430, 184) + }; - UpdateFromConfig(); + Size = SizeConstraints.Value.MinimumSize; + SizeCondition = ImGuiCond.FirstUseEver; } public void Dispose() { } - public void UpdateFromConfig() - { - var config = Service.Config; - - _configIsEnabled = config.IsEnabled; - } - - public void UpdateToConfig() - { - var config = Service.Config; - - config.IsEnabled = _configIsEnabled; - - config.Save(); - } - public override void Draw() { - var save = false; + var config = Service.Config; - ImGui.Checkbox("Enabled", ref _configIsEnabled); - - if (ImGui.Button("Save and apply")) + if (ImGui.Checkbox("Enabled", ref config.IsEnabled)) { - save = true; + config.Save(); } - if (save) + ImGui.Columns(2, "", false); + + if (ImGui.BeginListBox("", new Vector2(-1f, ImGui.GetContentRegionAvail().Y - ImGui.CalcTextSize("").Y - ImGui.GetStyle().ItemSpacing.Y * 2f))) { - UpdateToConfig(); + foreach (var entry in Service.Envs.Copy()) + { + AddMainEntry(entry); + } + + ImGui.EndListBox(); + } + + if (ImGui.Button("Add current")) + { + config.Envs.Add(new SavedEnv($"Saved #{config.Envs.Count + 1}", Service.Plugin.Current)); + config.Save(); + } + + ImGui.NextColumn(); + + if (ImGui.BeginCombo("Login", (config.LoginEnv ?? SavedEnv.Unchanged).Name)) + { + var env = config.LoginEnv; + foreach (var entry in Service.Envs) + { + if (AddComboEntry(entry, ref env)) + { + config.LoginEnv = env; + config.Save(); + } + } + ImGui.EndCombo(); + } + + if (ImGui.BeginCombo("Housing", (config.HousingEnv ?? SavedEnv.Unchanged).Name)) + { + var env = config.HousingEnv; + foreach (var entry in Service.Envs) + { + if (AddComboEntry(entry, ref env)) + { + config.HousingEnv = env; + config.Save(); + } + } + ImGui.EndCombo(); + } + + void AddMainEntry(EnvCollectionEntry entry) + { + (SavedEnv env, bool isBuiltin) = entry; + + bool isPreview = Service.Plugin.Preview == env; + bool isDefault = env.Env == null; + bool isRenaming = _renaming == env; + bool isStyled = false; + + if (isPreview) + { + ImGui.PushStyleColor(ImGuiCol.Text, new Vector4(0.8f, 0.3f, 0.9f, 1f)); + isStyled = true; + } + else if (isDefault) + { + ImGui.PushStyleColor(ImGuiCol.Text, new Vector4(0.8f, 0.3f, 0.3f, 1f)); + isStyled = true; + } + else if (isBuiltin) + { + ImGui.PushStyleColor(ImGuiCol.Text, new Vector4(0.6f, 0.7f, 0.8f, 1f)); + isStyled = true; + } + + if (_renaming == env) + { + ImGui.PushItemWidth(ImGui.GetContentRegionAvail().X); + if (ImGui.InputText("", ref _renamingName, 128, ImGuiInputTextFlags.EnterReturnsTrue)) + { + _renaming.Name = _renamingName; + _renaming = null; + config.Save(); + } + ImGui.PopItemWidth(); + } + else + { + ImGui.Selectable(env.Name, false, ImGuiSelectableFlags.None); + } + + if (isStyled) + { + ImGui.PopStyleColor(); + } + + bool isHovered = ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled); + bool isLMB = isHovered && ImGui.IsMouseClicked(ImGuiMouseButton.Left); + bool isRMB = isHovered && ImGui.IsMouseClicked(ImGuiMouseButton.Right); + + if (isHovered) + { + if (isDefault) + { + ImGui.SetTooltip("LMB to disable preview."); + } + else if (isBuiltin) + { + ImGui.SetTooltip("LMB to toggle preview. Built-in preset."); + } + else + { + ImGui.SetTooltip("LMB to toggle preview, RMB to rename, CTRL-RMB to remove."); + } + } + + if (isLMB && !isRenaming) + { + Service.Plugin.Preview = isPreview ? null : isDefault ? null : env; + } + + if (!isBuiltin && isRMB) + { + if (ImGui.IsKeyDown(ImGuiKey.ModCtrl)) + { + if (isRenaming) + { + _renaming = null; + } + else + { + if (isPreview) + { + Service.Plugin.Preview = null; + } + + config.Envs.Remove(env); + config.Save(); + } + } + else + { + _renamingName = env.Name; + _renaming = env; + } + } + } + + bool AddComboEntry(EnvCollectionEntry entry, ref SavedEnv? curr) + { + (SavedEnv env, bool isBuiltin) = entry; + + SavedEnv? set = env.Env == null ? null : env; + + if (ImGui.Selectable(env.Name, set == curr, ImGuiSelectableFlags.None)) + { + curr = set; + return true; + } + + return false; } } }