feat: add some config

This commit is contained in:
Anna 2022-05-09 22:43:21 -04:00
parent a3ae2629ef
commit 246c1e12d7
6 changed files with 191 additions and 16 deletions

View File

@ -9,7 +9,8 @@ namespace NominaOcculta;
internal class AppearanceRepository {
private Plugin Plugin { get; }
private List<ENpcBase> Npcs { get; }
private int Salt { get; } = new Random().Next();
private List<ENpcBase> 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)];
}
}

View File

@ -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;
}

View File

@ -16,6 +16,10 @@
<Dalamud>$(AppData)\XIVLauncher\addon\Hooks\dev</Dalamud>
</PropertyGroup>
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))'">
<Dalamud>$(DALAMUD_HOME)</Dalamud>
</PropertyGroup>
<PropertyGroup Condition="'$(IsCI)' == 'true'">
<Dalamud>$(HOME)/dalamud</Dalamud>
</PropertyGroup>

View File

@ -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),

View File

@ -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<Race>()!) {
var tribe1 = this.Plugin.DataManager.GetExcelSheet<Tribe>()!.GetRow(race.RowId * 2 - 1)!;
var tribe2 = this.Plugin.DataManager.GetExcelSheet<Tribe>()!.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();
}
}

9
NominaOcculta/Sex.cs Normal file
View File

@ -0,0 +1,9 @@
using System;
namespace NominaOcculta;
[Flags]
internal enum Sex {
Male = 1 << 1,
Female = 1 << 2,
}