From 246c1e12d72f7b5dbc5bd98f9081c051c6def2c1 Mon Sep 17 00:00:00 2001 From: Anna Date: Mon, 9 May 2022 22:43:21 -0400 Subject: [PATCH] feat: add some config --- NominaOcculta/AppearanceRepository.cs | 32 ++++++++++- NominaOcculta/Configuration.cs | 34 ++++++++++++ NominaOcculta/NominaOcculta.csproj | 4 ++ NominaOcculta/Obscurer.cs | 79 ++++++++++++++++++++++----- NominaOcculta/PluginUi.cs | 49 ++++++++++++++++- NominaOcculta/Sex.cs | 9 +++ 6 files changed, 191 insertions(+), 16 deletions(-) create mode 100644 NominaOcculta/Sex.cs diff --git a/NominaOcculta/AppearanceRepository.cs b/NominaOcculta/AppearanceRepository.cs index 2e04911..ed4cabb 100755 --- a/NominaOcculta/AppearanceRepository.cs +++ b/NominaOcculta/AppearanceRepository.cs @@ -9,7 +9,8 @@ namespace NominaOcculta; internal class AppearanceRepository { private Plugin Plugin { get; } private List Npcs { get; } - private int Salt { get; } = new Random().Next(); + private List PersonalNpcs { get; } + private int Salt { get; set; } = new Random().Next(); private static readonly string[] Exclude = { "Thancred", @@ -56,11 +57,40 @@ internal class AppearanceRepository { PluginLog.Log($"npcs: {this.Npcs.Count}"); } + internal void Reset() { + this.Salt = new Random().Next(); + } + + internal void RefilterPersonal() { + this.PersonalNpcs.Clear(); + this.PersonalNpcs.AddRange(this.Npcs + .Where(row => { + var sex = (Sex) (row.Gender + 1); + return this.Plugin.Config.PreferredSex.HasFlag(sex); + }) + .Where(row => { + var race = 1 << (int) row.Race.Row; + return (this.Plugin.Config.PreferredRaces & race) > 0; + }) + .Where(row => { + var tribe = 1 << (int) row.Tribe.Row; + return (this.Plugin.Config.PreferredTribes & tribe) > 0; + })); + } + private int GetNpcIndex(uint objectId) { return new Random((int) (objectId + this.Salt)).Next(0, this.Npcs.Count); } + + private int GetNpcIndexPersonal(uint objectId) { + return new Random((int) (objectId + this.Salt)).Next(0, this.PersonalNpcs.Count); + } internal ENpcBase GetNpc(uint objectId) { + if (objectId == this.Plugin.ClientState.LocalPlayer?.ObjectId) { + return this.PersonalNpcs[this.GetNpcIndexPersonal(objectId)]; + } + return this.Npcs[this.GetNpcIndex(objectId)]; } } diff --git a/NominaOcculta/Configuration.cs b/NominaOcculta/Configuration.cs index 887f698..4924eed 100755 --- a/NominaOcculta/Configuration.cs +++ b/NominaOcculta/Configuration.cs @@ -14,4 +14,38 @@ internal class Configuration : IPluginConfiguration { public bool Party; public bool Others; public bool ExcludeFriends; + + public bool ObscureAppearancesSelf; + public bool ObscureAppearancesParty; + public bool ObscureAppearancesOthers; + public bool ObscureAppearancesExcludeFriends; + + public Sex PreferredSex = Sex.Female | Sex.Male; + + public int PreferredRaces = 1 << 1 + | 1 << 2 + | 1 << 3 + | 1 << 4 + | 1 << 5 + | 1 << 6 + | 1 << 7 + | 1 << 8; + + public int PreferredTribes = 1 << 1 + | 1 << 2 + | 1 << 3 + | 1 << 4 + | 1 << 5 + | 1 << 6 + | 1 << 7 + | 1 << 8 + | 1 << 9 + | 1 << 10 + | 1 << 11 + | 1 << 12 + | 1 << 13 + | 1 << 14 + | 1 << 15 + | 1 << 16; + } diff --git a/NominaOcculta/NominaOcculta.csproj b/NominaOcculta/NominaOcculta.csproj index 9abb137..ee980a0 100755 --- a/NominaOcculta/NominaOcculta.csproj +++ b/NominaOcculta/NominaOcculta.csproj @@ -16,6 +16,10 @@ $(AppData)\XIVLauncher\addon\Hooks\dev + + $(DALAMUD_HOME) + + $(HOME)/dalamud diff --git a/NominaOcculta/Obscurer.cs b/NominaOcculta/Obscurer.cs index 3f776f7..483c9bc 100755 --- a/NominaOcculta/Obscurer.cs +++ b/NominaOcculta/Obscurer.cs @@ -8,7 +8,6 @@ using Dalamud.Game.ClientState.Objects.Enums; using Dalamud.Game.ClientState.Objects.Types; using Dalamud.Game.Text; using Dalamud.Game.Text.SeStringHandling; -using Dalamud.Logging; using XivCommon.Functions.NamePlates; using GameObject = FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject; @@ -79,7 +78,45 @@ internal class Obscurer : IDisposable { } } + private unsafe bool ShouldObscureAppearance(GameObject* gameObj) { + if (gameObj->ObjectKind != (byte) FFXIVClientStructs.FFXIV.Client.Game.Object.ObjectKind.Pc) { + return false; + } + + var gameObject = this.Plugin.ObjectTable.CreateObjectReference((IntPtr) gameObj)!; + return gameObject is Character chara && this.ShouldObscureAppearance(chara); + } + + private bool ShouldObscureAppearance(Character chara) { + if (!this.Plugin.Config.Enabled) { + return false; + } + + var name = chara.Name.TextValue; + var isFriend = this.Friends.Contains(name); + + if (this.Plugin.Config.ObscureAppearancesExcludeFriends && isFriend) { + return false; + } + + if (!this.Plugin.Config.ObscureAppearancesSelf && chara.ObjectId == this.Plugin.ClientState.LocalPlayer?.ObjectId) { + return false; + } + + var party = this.Plugin.PartyList.Select(member => member.ObjectId).ToArray(); + var inParty = party.Contains(chara.ObjectId); + if (!this.Plugin.Config.ObscureAppearancesParty && inParty) { + return false; + } + + return this.Plugin.Config.ObscureAppearancesOthers; + } + private unsafe void OnCharacterInitialise(GameObject* gameObj, IntPtr humanPtr, IntPtr customiseDataPtr) { + if (!this.ShouldObscureAppearance(gameObj)) { + return; + } + var npc = this.Plugin.AppearanceRepository.GetNpc(gameObj->ObjectID); var customise = (byte*) customiseDataPtr; @@ -111,7 +148,7 @@ internal class Obscurer : IDisposable { customise[(int) CustomizeIndex.FacepaintColor] = npc.FacePaintColor; } - private enum PlateSlot : uint { + private enum EquipSlot : uint { Head = 0, Body = 1, Hands = 2, @@ -130,20 +167,24 @@ internal class Obscurer : IDisposable { if (equipData == null) { return; } + + if (!this.ShouldObscureAppearance(gameObj)) { + return; + } var npc = this.Plugin.AppearanceRepository.GetNpc(gameObj->ObjectID); - var itemSlot = (PlateSlot) slot; + var itemSlot = (EquipSlot) slot; var info = itemSlot switch { - PlateSlot.Head => (npc.ModelHead, npc.DyeHead.Row), - PlateSlot.Body => (npc.ModelBody, npc.DyeBody.Row), - PlateSlot.Hands => (npc.ModelHands, npc.DyeHands.Row), - PlateSlot.Legs => (npc.ModelLegs, npc.DyeLegs.Row), - PlateSlot.Feet => (npc.ModelFeet, npc.DyeFeet.Row), - PlateSlot.Ears => (npc.ModelEars, npc.DyeEars.Row), - PlateSlot.Neck => (npc.ModelNeck, npc.DyeNeck.Row), - PlateSlot.Wrists => (npc.ModelWrists, npc.DyeWrists.Row), - PlateSlot.RightRing => (npc.ModelRightRing, npc.DyeRightRing.Row), - PlateSlot.LeftRing => (npc.ModelLeftRing, npc.DyeLeftRing.Row), + EquipSlot.Head => (npc.ModelHead, npc.DyeHead.Row), + EquipSlot.Body => (npc.ModelBody, npc.DyeBody.Row), + EquipSlot.Hands => (npc.ModelHands, npc.DyeHands.Row), + EquipSlot.Legs => (npc.ModelLegs, npc.DyeLegs.Row), + EquipSlot.Feet => (npc.ModelFeet, npc.DyeFeet.Row), + EquipSlot.Ears => (npc.ModelEars, npc.DyeEars.Row), + EquipSlot.Neck => (npc.ModelNeck, npc.DyeNeck.Row), + EquipSlot.Wrists => (npc.ModelWrists, npc.DyeWrists.Row), + EquipSlot.RightRing => (npc.ModelRightRing, npc.DyeRightRing.Row), + EquipSlot.LeftRing => (npc.ModelLeftRing, npc.DyeLeftRing.Row), _ => (uint.MaxValue, uint.MaxValue), }; @@ -325,7 +366,17 @@ internal class Obscurer : IDisposable { return changed; } - private static (byte race, byte clan, byte gender) GetInfo(Character chara) { + private (byte race, byte clan, byte gender) GetInfo(Character chara) { + if (this.ShouldObscureAppearance(chara)) { + var npc = this.Plugin.AppearanceRepository.GetNpc(chara.ObjectId); + return ( + (byte) npc.Race.Row, + (byte) ((npc.Tribe.Row - 1) % 2), + npc.Gender + ); + } + + Real: return ( chara.Customize[(byte) CustomizeIndex.Race], (byte) ((chara.Customize[(byte) CustomizeIndex.Tribe] - 1) % 2), diff --git a/NominaOcculta/PluginUi.cs b/NominaOcculta/PluginUi.cs index 202576a..cf9b303 100755 --- a/NominaOcculta/PluginUi.cs +++ b/NominaOcculta/PluginUi.cs @@ -1,6 +1,5 @@ using System; using Dalamud.Game.ClientState.Keys; -using Dalamud.Logging; using ImGuiNET; using Lumina.Excel.GeneratedSheets; @@ -50,6 +49,53 @@ internal class PluginUi : IDisposable { anyChanged |= ImGui.Checkbox("Obscure others", ref this.Plugin.Config.Others); anyChanged |= ImGui.Checkbox("Exclude friends", ref this.Plugin.Config.ExcludeFriends); + ImGui.Separator(); + + anyChanged |= ImGui.Checkbox("Obscure appearance of self", ref this.Plugin.Config.ObscureAppearancesSelf); + anyChanged |= ImGui.Checkbox("Obscure appearance of party members", ref this.Plugin.Config.ObscureAppearancesParty); + anyChanged |= ImGui.Checkbox("Obscure appearance of others", ref this.Plugin.Config.ObscureAppearancesOthers); + anyChanged |= ImGui.Checkbox("Exclude friends", ref this.Plugin.Config.ObscureAppearancesExcludeFriends); + + ImGui.Separator(); + + if (ImGui.CollapsingHeader("Personal appearance preferences")) { + ImGui.TextUnformatted("Sex"); + var sex = (int) this.Plugin.Config.PreferredSex; + anyChanged |= ImGui.CheckboxFlags("Female", ref sex, (int) Sex.Female); + anyChanged |= ImGui.CheckboxFlags("Male", ref sex, (int) Sex.Male); + + if (anyChanged) { + this.Plugin.Config.PreferredSex = (Sex) sex; + } + + ImGui.Separator(); + + ImGui.TextUnformatted("Race"); + foreach (var race in this.Plugin.DataManager.GetExcelSheet()!) { + var tribe1 = this.Plugin.DataManager.GetExcelSheet()!.GetRow(race.RowId * 2 - 1)!; + var tribe2 = this.Plugin.DataManager.GetExcelSheet()!.GetRow(race.RowId * 2)!; + + if (ImGui.CheckboxFlags(race.Feminine.RawString, ref this.Plugin.Config.PreferredRaces, 1 << (int) race.RowId)) { + anyChanged = true; + + if ((this.Plugin.Config.PreferredRaces & (1 << (int) race.RowId)) > 0) { + this.Plugin.Config.PreferredTribes |= 1 << (int) tribe1.RowId; + this.Plugin.Config.PreferredTribes |= 1 << (int) tribe2.RowId; + } else { + this.Plugin.Config.PreferredTribes &= ~(1 << (int) tribe1.RowId); + this.Plugin.Config.PreferredTribes &= ~(1 << (int) tribe2.RowId); + } + } + + ImGui.TreePush(); + + anyChanged |= ImGui.CheckboxFlags(tribe1.Feminine.RawString, ref this.Plugin.Config.PreferredTribes, 1 << (int) tribe1.RowId); + anyChanged |= ImGui.CheckboxFlags(tribe2.Feminine.RawString, ref this.Plugin.Config.PreferredTribes, 1 << (int) tribe2.RowId); + + ImGui.TreePop(); + } + } + if (anyChanged) { this.Plugin.SaveConfig(); } @@ -61,6 +107,7 @@ internal class PluginUi : IDisposable { this._debug ^= true; } else { this.Plugin.NameRepository.Reset(); + this.Plugin.AppearanceRepository.Reset(); } } diff --git a/NominaOcculta/Sex.cs b/NominaOcculta/Sex.cs new file mode 100644 index 0000000..48cf763 --- /dev/null +++ b/NominaOcculta/Sex.cs @@ -0,0 +1,9 @@ +using System; + +namespace NominaOcculta; + +[Flags] +internal enum Sex { + Male = 1 << 1, + Female = 1 << 2, +}