mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2025-12-12 18:27:24 +01:00
Rework codes and fun a bit.
This commit is contained in:
parent
1fa9afb9c6
commit
dd5c56de9d
9 changed files with 269 additions and 197 deletions
|
|
@ -113,7 +113,7 @@ public partial class CustomizationDrawer(DalamudPluginInterface pi, CustomizeSer
|
|||
|
||||
try
|
||||
{
|
||||
if (_codes.EnabledArtisan)
|
||||
if (_codes.Enabled(CodeService.CodeFlag.Artisan))
|
||||
return DrawArtisan();
|
||||
|
||||
DrawRaceGenderSelector();
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ public class EquipmentDrawer
|
|||
|
||||
if (_config.SmallEquip)
|
||||
DrawEquipSmall(equipDrawData);
|
||||
else if (!equipDrawData.Locked && _codes.EnabledArtisan)
|
||||
else if (!equipDrawData.Locked && _codes.Enabled(CodeService.CodeFlag.Artisan))
|
||||
DrawEquipArtisan(equipDrawData);
|
||||
else
|
||||
DrawEquipNormal(equipDrawData);
|
||||
|
|
@ -117,7 +117,7 @@ public class EquipmentDrawer
|
|||
|
||||
if (_config.SmallEquip)
|
||||
DrawWeaponsSmall(mainhand, offhand, allWeapons);
|
||||
else if (!mainhand.Locked && _codes.EnabledArtisan)
|
||||
else if (!mainhand.Locked && _codes.Enabled(CodeService.CodeFlag.Artisan))
|
||||
DrawWeaponsArtisan(mainhand, offhand);
|
||||
else
|
||||
DrawWeaponsNormal(mainhand, offhand, allWeapons);
|
||||
|
|
|
|||
|
|
@ -247,22 +247,17 @@ public class SettingsTab : ITab
|
|||
if (ImGui.Checkbox(code, ref state))
|
||||
{
|
||||
action(state);
|
||||
_config.Codes[i] = (code, state);
|
||||
_codeService.VerifyState();
|
||||
_config.Save();
|
||||
_codeService.SaveState();
|
||||
}
|
||||
}
|
||||
|
||||
if (_codeService.EnabledCaptain)
|
||||
{
|
||||
if (ImGui.Button("Who am I?!?"))
|
||||
_funModule.WhoAmI();
|
||||
if (ImGui.Button("Who am I?!?"))
|
||||
_funModule.WhoAmI();
|
||||
|
||||
ImGui.SameLine();
|
||||
ImGui.SameLine();
|
||||
|
||||
if (ImGui.Button("Who is that!?!"))
|
||||
_funModule.WhoIsThat();
|
||||
}
|
||||
if (ImGui.Button("Who is that!?!"))
|
||||
_funModule.WhoIsThat();
|
||||
}
|
||||
|
||||
private void DrawCodeHints()
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ public class UnlockOverview
|
|||
var icon = _customizations.Manager.GetIcon(customize.IconId);
|
||||
|
||||
ImGui.Image(icon.ImGuiHandle, iconSize, Vector2.Zero, Vector2.One,
|
||||
unlocked || _codes.EnabledShirts ? Vector4.One : UnavailableTint);
|
||||
unlocked || _codes.Enabled(CodeService.CodeFlag.Shirts) ? Vector4.One : UnavailableTint);
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
using var tt = ImRaii.Tooltip();
|
||||
|
|
@ -189,7 +189,7 @@ public class UnlockOverview
|
|||
|
||||
var (icon, size) = (iconHandle.ImGuiHandle, new Vector2(iconHandle.Width, iconHandle.Height));
|
||||
|
||||
ImGui.Image(icon, iconSize, Vector2.Zero, Vector2.One, unlocked || _codes.EnabledShirts ? Vector4.One : UnavailableTint);
|
||||
ImGui.Image(icon, iconSize, Vector2.Zero, Vector2.One, unlocked || _codes.Enabled(CodeService.CodeFlag.Shirts) ? Vector4.One : UnavailableTint);
|
||||
if (_favorites.Contains(item))
|
||||
ImGui.GetWindowDrawList().AddRect(ImGui.GetItemRectMin(), ImGui.GetItemRectMax(), ColorId.FavoriteStarOn.Value(),
|
||||
2 * ImGuiHelpers.GlobalScale, ImDrawFlags.RoundCornersAll, 4 * ImGuiHelpers.GlobalScale);
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ public class VisorService : IDisposable
|
|||
{
|
||||
Event = visorStateChanged;
|
||||
_setupVisorHook = interop.HookFromAddress<UpdateVisorDelegateInternal>((nint)Human.MemberFunctionPointers.SetupVisor, SetupVisorDetour);
|
||||
interop.InitializeFromAttributes(this);
|
||||
_setupVisorHook.Enable();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,23 +12,66 @@ public class CodeService
|
|||
private readonly Configuration _config;
|
||||
private readonly SHA256 _hasher = SHA256.Create();
|
||||
|
||||
public enum Sizing
|
||||
[Flags]
|
||||
public enum CodeFlag : ulong
|
||||
{
|
||||
None,
|
||||
Dwarf,
|
||||
Giant,
|
||||
Clown = 0x000001,
|
||||
Emperor = 0x000002,
|
||||
Individual = 0x000004,
|
||||
Dwarf = 0x000008,
|
||||
Giant = 0x000010,
|
||||
OopsHyur = 0x000020,
|
||||
OopsElezen = 0x000040,
|
||||
OopsLalafell = 0x000080,
|
||||
OopsMiqote = 0x000100,
|
||||
OopsRoegadyn = 0x000200,
|
||||
OopsAuRa = 0x000400,
|
||||
OopsHrothgar = 0x000800,
|
||||
OopsViera = 0x001000,
|
||||
Artisan = 0x002000,
|
||||
SixtyThree = 0x004000,
|
||||
Shirts = 0x008000,
|
||||
World = 0x010000,
|
||||
Elephants = 0x020000,
|
||||
}
|
||||
|
||||
public bool EnabledClown { get; private set; }
|
||||
public bool EnabledEmperor { get; private set; }
|
||||
public bool EnabledIndividual { get; private set; }
|
||||
public Sizing EnabledSizing { get; private set; }
|
||||
public Race EnabledOops { get; private set; }
|
||||
public bool EnabledArtisan { get; private set; }
|
||||
public bool EnabledCaptain { get; private set; }
|
||||
public bool Enabled63 { get; private set; }
|
||||
public bool EnabledShirts { get; private set; }
|
||||
public bool EnabledWorld { get; private set; }
|
||||
public const CodeFlag DyeCodes = CodeFlag.Clown | CodeFlag.World | CodeFlag.Elephants;
|
||||
public const CodeFlag GearCodes = CodeFlag.Emperor | CodeFlag.World | CodeFlag.Elephants;
|
||||
|
||||
public const CodeFlag RaceCodes = CodeFlag.OopsHyur
|
||||
| CodeFlag.OopsElezen
|
||||
| CodeFlag.OopsLalafell
|
||||
| CodeFlag.OopsMiqote
|
||||
| CodeFlag.OopsRoegadyn
|
||||
| CodeFlag.OopsAuRa
|
||||
| CodeFlag.OopsHrothgar;
|
||||
|
||||
public const CodeFlag SizeCodes = CodeFlag.Dwarf | CodeFlag.Giant;
|
||||
|
||||
private CodeFlag _enabled;
|
||||
|
||||
public bool Enabled(CodeFlag flag)
|
||||
=> _enabled.HasFlag(flag);
|
||||
|
||||
public bool AnyEnabled(CodeFlag flag)
|
||||
=> (_enabled & flag) != 0;
|
||||
|
||||
public CodeFlag Masked(CodeFlag mask)
|
||||
=> _enabled & mask;
|
||||
|
||||
public Race GetRace()
|
||||
=> (_enabled & RaceCodes) switch
|
||||
{
|
||||
CodeFlag.OopsHyur => Race.Hyur,
|
||||
CodeFlag.OopsElezen => Race.Elezen,
|
||||
CodeFlag.OopsLalafell => Race.Lalafell,
|
||||
CodeFlag.OopsMiqote => Race.Miqote,
|
||||
CodeFlag.OopsRoegadyn => Race.Roegadyn,
|
||||
CodeFlag.OopsAuRa => Race.AuRa,
|
||||
CodeFlag.OopsHrothgar => Race.Hrothgar,
|
||||
CodeFlag.OopsViera => Race.Viera,
|
||||
_ => Race.Unknown,
|
||||
};
|
||||
|
||||
public CodeService(Configuration config)
|
||||
{
|
||||
|
|
@ -69,92 +112,94 @@ public class CodeService
|
|||
}
|
||||
|
||||
public Action<bool>? CheckCode(string name)
|
||||
{
|
||||
var flag = GetCode(name);
|
||||
if (flag == 0)
|
||||
return null;
|
||||
|
||||
var badFlags = ~GetMutuallyExclusive(flag);
|
||||
return v => _enabled = v ? (_enabled | flag) & badFlags : _enabled & ~flag;;
|
||||
}
|
||||
|
||||
public CodeFlag GetCode(string name)
|
||||
{
|
||||
using var stream = new MemoryStream(Encoding.UTF8.GetBytes(name));
|
||||
var sha = (ReadOnlySpan<byte>)_hasher.ComputeHash(stream);
|
||||
return sha switch
|
||||
{
|
||||
_ when CodeClown.SequenceEqual(sha) => v => EnabledClown = v,
|
||||
_ when CodeEmperor.SequenceEqual(sha) => v => EnabledEmperor = v,
|
||||
_ when CodeIndividual.SequenceEqual(sha) => v => EnabledIndividual = v,
|
||||
_ when CodeCaptain.SequenceEqual(sha) => v => EnabledCaptain = v,
|
||||
_ when Code63.SequenceEqual(sha) => v => Enabled63 = v,
|
||||
_ when CodeDwarf.SequenceEqual(sha) => v => EnabledSizing = v ? Sizing.Dwarf : Sizing.None,
|
||||
_ when CodeGiant.SequenceEqual(sha) => v => EnabledSizing = v ? Sizing.Giant : Sizing.None,
|
||||
_ when CodeOops1.SequenceEqual(sha) => v => EnabledOops = v ? Race.Hyur : Race.Unknown,
|
||||
_ when CodeOops2.SequenceEqual(sha) => v => EnabledOops = v ? Race.Elezen : Race.Unknown,
|
||||
_ when CodeOops3.SequenceEqual(sha) => v => EnabledOops = v ? Race.Lalafell : Race.Unknown,
|
||||
_ when CodeOops4.SequenceEqual(sha) => v => EnabledOops = v ? Race.Miqote : Race.Unknown,
|
||||
_ when CodeOops5.SequenceEqual(sha) => v => EnabledOops = v ? Race.Roegadyn : Race.Unknown,
|
||||
_ when CodeOops6.SequenceEqual(sha) => v => EnabledOops = v ? Race.AuRa : Race.Unknown,
|
||||
_ when CodeOops7.SequenceEqual(sha) => v => EnabledOops = v ? Race.Hrothgar : Race.Unknown,
|
||||
_ when CodeOops8.SequenceEqual(sha) => v => EnabledOops = v ? Race.Viera : Race.Unknown,
|
||||
_ when CodeArtisan.SequenceEqual(sha) => v => EnabledArtisan = v,
|
||||
_ when CodeShirts.SequenceEqual(sha) => v => EnabledShirts = v,
|
||||
_ when CodeWorld.SequenceEqual(sha) => v => EnabledWorld = v,
|
||||
|
||||
_ => null,
|
||||
};
|
||||
foreach (var flag in Enum.GetValues<CodeFlag>())
|
||||
{
|
||||
if (sha.SequenceEqual(GetSha(flag)))
|
||||
return flag;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void VerifyState()
|
||||
/// <summary> Update all enabled states in the config. </summary>
|
||||
public void SaveState()
|
||||
{
|
||||
if (EnabledSizing == Sizing.None && EnabledOops == Race.Unknown)
|
||||
return;
|
||||
|
||||
for (var i = 0; i < _config.Codes.Count; ++i)
|
||||
{
|
||||
var (code, enabled) = _config.Codes[i];
|
||||
if (!enabled)
|
||||
continue;
|
||||
|
||||
using var stream = new MemoryStream(Encoding.UTF8.GetBytes(code));
|
||||
var sha = (ReadOnlySpan<byte>)_hasher.ComputeHash(stream);
|
||||
var _ = EnabledSizing switch
|
||||
var name = _config.Codes[i].Code;
|
||||
var flag = GetCode(name);
|
||||
if (flag == 0)
|
||||
{
|
||||
Sizing.Dwarf when sha.SequenceEqual(CodeGiant) => _config.Codes[i] = (code, false),
|
||||
Sizing.Giant when sha.SequenceEqual(CodeDwarf) => _config.Codes[i] = (code, false),
|
||||
_ => (string.Empty, false),
|
||||
};
|
||||
_config.Codes.RemoveAt(i--);
|
||||
continue;
|
||||
}
|
||||
|
||||
var race = OopsRace(sha);
|
||||
if (race is not Race.Unknown && race != EnabledOops)
|
||||
_config.Codes[i] = (code, false);
|
||||
_config.Codes[i] = (name, Enabled(flag));
|
||||
}
|
||||
|
||||
_config.Save();
|
||||
}
|
||||
|
||||
private static Race OopsRace(ReadOnlySpan<byte> sha)
|
||||
=> sha switch
|
||||
{
|
||||
_ when CodeOops1.SequenceEqual(sha) => Race.Hyur,
|
||||
_ when CodeOops2.SequenceEqual(sha) => Race.Elezen,
|
||||
_ when CodeOops3.SequenceEqual(sha) => Race.Lalafell,
|
||||
_ when CodeOops4.SequenceEqual(sha) => Race.Miqote,
|
||||
_ when CodeOops5.SequenceEqual(sha) => Race.Roegadyn,
|
||||
_ when CodeOops6.SequenceEqual(sha) => Race.AuRa,
|
||||
_ when CodeOops7.SequenceEqual(sha) => Race.Hrothgar,
|
||||
_ when CodeOops8.SequenceEqual(sha) => Race.Viera,
|
||||
_ => Race.Unknown,
|
||||
};
|
||||
|
||||
// @formatter:off
|
||||
private static ReadOnlySpan<byte> CodeClown => new byte[] { 0xC4, 0xEE, 0x1D, 0x6F, 0xC5, 0x5D, 0x47, 0xBE, 0x78, 0x63, 0x66, 0x86, 0x81, 0x15, 0xEB, 0xFA, 0xF6, 0x4A, 0x90, 0xEA, 0xC0, 0xE4, 0xEE, 0x86, 0x69, 0x01, 0x8E, 0xDB, 0xCC, 0x69, 0xD1, 0xBD };
|
||||
private static ReadOnlySpan<byte> CodeEmperor => new byte[] { 0xE2, 0x2D, 0x3E, 0x57, 0x16, 0x82, 0x65, 0x98, 0x7E, 0xE6, 0x8F, 0x45, 0x14, 0x7D, 0x65, 0x31, 0xE9, 0xD8, 0xDB, 0xEA, 0xDC, 0xBF, 0xEE, 0x2A, 0xBA, 0xD5, 0x69, 0x96, 0x78, 0x34, 0x3B, 0x57 };
|
||||
private static ReadOnlySpan<byte> CodeIndividual => new byte[] { 0x95, 0xA4, 0x71, 0xAC, 0xA3, 0xC2, 0x34, 0x94, 0xC1, 0x65, 0x07, 0xF3, 0x7F, 0x93, 0x57, 0xEE, 0xE3, 0x04, 0xC0, 0xE8, 0x1B, 0xA0, 0xE2, 0x08, 0x68, 0x02, 0x8D, 0xAD, 0x76, 0x03, 0x9B, 0xC5 };
|
||||
private static ReadOnlySpan<byte> CodeDwarf => new byte[] { 0x55, 0x97, 0xFE, 0xE9, 0x78, 0x64, 0xE8, 0x2F, 0xCD, 0x25, 0xD1, 0xAE, 0xDF, 0x35, 0xE6, 0xED, 0x03, 0x78, 0x54, 0x1D, 0x56, 0x22, 0x34, 0x75, 0x4B, 0x96, 0x6F, 0xBA, 0xAC, 0xEC, 0x00, 0x46 };
|
||||
private static ReadOnlySpan<byte> CodeGiant => new byte[] { 0x6E, 0xBB, 0x91, 0x1D, 0x67, 0xE3, 0x00, 0x07, 0xA1, 0x0F, 0x2A, 0xF0, 0x26, 0x91, 0x38, 0x63, 0xD3, 0x52, 0x82, 0xF7, 0x5D, 0x93, 0xE8, 0x83, 0xB1, 0xF6, 0xB9, 0x69, 0x78, 0x20, 0xC4, 0xCE };
|
||||
private static ReadOnlySpan<byte> CodeOops1 => new byte[] { 0x4C, 0x51, 0xE2, 0x38, 0xEF, 0xAD, 0x84, 0x0E, 0x4E, 0x11, 0x0F, 0x5E, 0xDE, 0x45, 0x41, 0x9F, 0x6A, 0xF6, 0x5F, 0x5B, 0xA8, 0x91, 0x64, 0x22, 0xEE, 0x62, 0x97, 0x3C, 0x78, 0x18, 0xCD, 0xAF };
|
||||
private static ReadOnlySpan<byte> CodeOops2 => new byte[] { 0x3D, 0x5B, 0xA9, 0x62, 0xCE, 0xBE, 0x52, 0xF5, 0x94, 0x2A, 0xF9, 0xB7, 0xCF, 0xD9, 0x24, 0x2B, 0x38, 0xC7, 0x4F, 0x28, 0x97, 0x29, 0x1D, 0x01, 0x13, 0x53, 0x44, 0x11, 0x15, 0x6F, 0x9B, 0x56 };
|
||||
private static ReadOnlySpan<byte> CodeOops3 => new byte[] { 0x85, 0x8D, 0x5B, 0xC2, 0x66, 0x53, 0x2E, 0xB9, 0xE9, 0x85, 0xE5, 0xF8, 0xD3, 0x75, 0x18, 0x7C, 0x58, 0x55, 0xD4, 0x8C, 0x8E, 0x5F, 0x58, 0x2E, 0xF3, 0xF1, 0xAE, 0xA8, 0xA0, 0x81, 0xC6, 0x0E };
|
||||
private static ReadOnlySpan<byte> CodeOops4 => new byte[] { 0x44, 0x73, 0x8C, 0x39, 0x5A, 0xF1, 0xDB, 0x5F, 0x62, 0xA1, 0x6E, 0x5F, 0xE6, 0x97, 0x9E, 0x90, 0xD7, 0x5C, 0x97, 0x67, 0xB6, 0xC7, 0x99, 0x61, 0x36, 0xCA, 0x34, 0x7E, 0xB9, 0xAC, 0xC3, 0x76 };
|
||||
private static ReadOnlySpan<byte> CodeOops5 => new byte[] { 0xB7, 0x25, 0x73, 0xDB, 0xBE, 0xD0, 0x49, 0xFB, 0xFF, 0x9C, 0x32, 0x21, 0xB0, 0x8A, 0x2C, 0x0C, 0x77, 0x46, 0xD5, 0xCF, 0x0E, 0x63, 0x2F, 0x91, 0x85, 0x8B, 0x55, 0x5C, 0x4D, 0xD2, 0xB9, 0xB8 };
|
||||
private static ReadOnlySpan<byte> CodeOops6 => new byte[] { 0x69, 0x93, 0xAF, 0xE4, 0xB8, 0xEC, 0x5F, 0x40, 0xEB, 0x8A, 0x6F, 0xD1, 0x9B, 0xD9, 0x56, 0x0B, 0xEA, 0x64, 0x79, 0x9B, 0x54, 0xA1, 0x41, 0xED, 0xBC, 0x3E, 0x6E, 0x5C, 0xF1, 0x23, 0x60, 0xF8 };
|
||||
private static ReadOnlySpan<byte> CodeOops7 => new byte[] { 0x41, 0xEC, 0x65, 0x05, 0x8D, 0x20, 0x68, 0x5A, 0xB7, 0xEB, 0x92, 0x15, 0x43, 0xCF, 0x15, 0x05, 0x27, 0x51, 0xFE, 0x20, 0xC9, 0xB6, 0x2B, 0x84, 0xD9, 0x6A, 0x49, 0x5A, 0x5B, 0x7F, 0x2E, 0xE7 };
|
||||
private static ReadOnlySpan<byte> CodeOops8 => new byte[] { 0x16, 0xFF, 0x63, 0x85, 0x1C, 0xF5, 0x34, 0x33, 0x67, 0x8C, 0x46, 0x8E, 0x3E, 0xE3, 0xA6, 0x94, 0xF9, 0x74, 0x47, 0xAA, 0xC7, 0x29, 0x59, 0x1F, 0x6C, 0x6E, 0xF2, 0xF5, 0x87, 0x24, 0x9E, 0x2B };
|
||||
private static ReadOnlySpan<byte> CodeArtisan => new byte[] { 0xDE, 0x01, 0x32, 0x1E, 0x7F, 0x22, 0x80, 0x3D, 0x76, 0xDF, 0x74, 0x0E, 0xEC, 0x33, 0xD3, 0xF4, 0x1A, 0x98, 0x9E, 0x9D, 0x22, 0x5C, 0xAC, 0x3B, 0xFE, 0x0B, 0xC2, 0x13, 0xB9, 0x91, 0x24, 0x61 };
|
||||
private static ReadOnlySpan<byte> CodeCaptain => new byte[] { 0x5E, 0x0B, 0xDD, 0x86, 0x8F, 0x24, 0xDA, 0x49, 0x1A, 0xD2, 0x59, 0xB9, 0x10, 0x38, 0x29, 0x37, 0x99, 0x9D, 0x53, 0xD9, 0x9B, 0x84, 0x91, 0x5B, 0x6C, 0xCE, 0x3E, 0x2A, 0x38, 0x06, 0x47, 0xE6 };
|
||||
private static ReadOnlySpan<byte> Code63 => new byte[] { 0xA1, 0x65, 0x60, 0x99, 0xB0, 0x9F, 0xBF, 0xD7, 0x20, 0xC8, 0x29, 0xF6, 0x7B, 0x86, 0x27, 0xF5, 0xBE, 0xA9, 0x5B, 0xB0, 0x20, 0x5E, 0x57, 0x7B, 0xFF, 0xBC, 0x1E, 0x8C, 0x04, 0xF9, 0x35, 0xD3 };
|
||||
private static ReadOnlySpan<byte> CodeShirts => new byte[] { 0xD1, 0x35, 0xD7, 0x18, 0xBE, 0x45, 0x42, 0xBD, 0x88, 0x77, 0x7E, 0xC4, 0x41, 0x06, 0x34, 0x4D, 0x71, 0x3A, 0xC5, 0xCC, 0xA4, 0x1B, 0x7D, 0x3F, 0x3B, 0x86, 0x07, 0xCB, 0x63, 0xD7, 0xF9, 0xDB };
|
||||
private static ReadOnlySpan<byte> CodeWorld => new byte[] { 0xFD, 0xA2, 0xD2, 0xBC, 0xD9, 0x8A, 0x7E, 0x2B, 0x52, 0xCB, 0x57, 0x6E, 0x3A, 0x2E, 0x30, 0xBA, 0x4E, 0xAE, 0x42, 0xEA, 0x5C, 0x57, 0xDF, 0x17, 0x37, 0x3C, 0xCE, 0x17, 0x42, 0x43, 0xAE, 0xD0 };
|
||||
// @formatter:on
|
||||
private static CodeFlag GetMutuallyExclusive(CodeFlag flag)
|
||||
=> flag switch
|
||||
{
|
||||
CodeFlag.Clown => DyeCodes & ~CodeFlag.Clown,
|
||||
CodeFlag.Emperor => GearCodes & ~CodeFlag.Emperor,
|
||||
CodeFlag.Individual => 0,
|
||||
CodeFlag.Dwarf => SizeCodes & ~CodeFlag.Dwarf,
|
||||
CodeFlag.Giant => SizeCodes & ~CodeFlag.Giant,
|
||||
CodeFlag.OopsHyur => RaceCodes & ~CodeFlag.OopsHyur,
|
||||
CodeFlag.OopsElezen => RaceCodes & ~CodeFlag.OopsElezen,
|
||||
CodeFlag.OopsLalafell => RaceCodes & ~CodeFlag.OopsLalafell,
|
||||
CodeFlag.OopsMiqote => RaceCodes & ~CodeFlag.OopsMiqote,
|
||||
CodeFlag.OopsRoegadyn => RaceCodes & ~CodeFlag.OopsRoegadyn,
|
||||
CodeFlag.OopsAuRa => RaceCodes & ~CodeFlag.OopsAuRa,
|
||||
CodeFlag.OopsHrothgar => RaceCodes & ~CodeFlag.OopsHrothgar,
|
||||
CodeFlag.OopsViera => RaceCodes & ~CodeFlag.OopsViera,
|
||||
CodeFlag.Artisan => 0,
|
||||
CodeFlag.SixtyThree => 0,
|
||||
CodeFlag.Shirts => 0,
|
||||
CodeFlag.World => (DyeCodes | GearCodes) & ~CodeFlag.World,
|
||||
CodeFlag.Elephants => (DyeCodes | GearCodes) & ~CodeFlag.Elephants,
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
private static ReadOnlySpan<byte> GetSha(CodeFlag flag)
|
||||
=> flag switch
|
||||
{
|
||||
CodeFlag.Clown => [ 0xC4, 0xEE, 0x1D, 0x6F, 0xC5, 0x5D, 0x47, 0xBE, 0x78, 0x63, 0x66, 0x86, 0x81, 0x15, 0xEB, 0xFA, 0xF6, 0x4A, 0x90, 0xEA, 0xC0, 0xE4, 0xEE, 0x86, 0x69, 0x01, 0x8E, 0xDB, 0xCC, 0x69, 0xD1, 0xBD ],
|
||||
CodeFlag.Emperor => [ 0xE2, 0x2D, 0x3E, 0x57, 0x16, 0x82, 0x65, 0x98, 0x7E, 0xE6, 0x8F, 0x45, 0x14, 0x7D, 0x65, 0x31, 0xE9, 0xD8, 0xDB, 0xEA, 0xDC, 0xBF, 0xEE, 0x2A, 0xBA, 0xD5, 0x69, 0x96, 0x78, 0x34, 0x3B, 0x57 ],
|
||||
CodeFlag.Individual => [ 0x95, 0xA4, 0x71, 0xAC, 0xA3, 0xC2, 0x34, 0x94, 0xC1, 0x65, 0x07, 0xF3, 0x7F, 0x93, 0x57, 0xEE, 0xE3, 0x04, 0xC0, 0xE8, 0x1B, 0xA0, 0xE2, 0x08, 0x68, 0x02, 0x8D, 0xAD, 0x76, 0x03, 0x9B, 0xC5 ],
|
||||
CodeFlag.Dwarf => [ 0x55, 0x97, 0xFE, 0xE9, 0x78, 0x64, 0xE8, 0x2F, 0xCD, 0x25, 0xD1, 0xAE, 0xDF, 0x35, 0xE6, 0xED, 0x03, 0x78, 0x54, 0x1D, 0x56, 0x22, 0x34, 0x75, 0x4B, 0x96, 0x6F, 0xBA, 0xAC, 0xEC, 0x00, 0x46 ],
|
||||
CodeFlag.Giant => [ 0x6E, 0xBB, 0x91, 0x1D, 0x67, 0xE3, 0x00, 0x07, 0xA1, 0x0F, 0x2A, 0xF0, 0x26, 0x91, 0x38, 0x63, 0xD3, 0x52, 0x82, 0xF7, 0x5D, 0x93, 0xE8, 0x83, 0xB1, 0xF6, 0xB9, 0x69, 0x78, 0x20, 0xC4, 0xCE ],
|
||||
CodeFlag.OopsHyur => [ 0x4C, 0x51, 0xE2, 0x38, 0xEF, 0xAD, 0x84, 0x0E, 0x4E, 0x11, 0x0F, 0x5E, 0xDE, 0x45, 0x41, 0x9F, 0x6A, 0xF6, 0x5F, 0x5B, 0xA8, 0x91, 0x64, 0x22, 0xEE, 0x62, 0x97, 0x3C, 0x78, 0x18, 0xCD, 0xAF ],
|
||||
CodeFlag.OopsElezen => [ 0x3D, 0x5B, 0xA9, 0x62, 0xCE, 0xBE, 0x52, 0xF5, 0x94, 0x2A, 0xF9, 0xB7, 0xCF, 0xD9, 0x24, 0x2B, 0x38, 0xC7, 0x4F, 0x28, 0x97, 0x29, 0x1D, 0x01, 0x13, 0x53, 0x44, 0x11, 0x15, 0x6F, 0x9B, 0x56 ],
|
||||
CodeFlag.OopsLalafell => [ 0x85, 0x8D, 0x5B, 0xC2, 0x66, 0x53, 0x2E, 0xB9, 0xE9, 0x85, 0xE5, 0xF8, 0xD3, 0x75, 0x18, 0x7C, 0x58, 0x55, 0xD4, 0x8C, 0x8E, 0x5F, 0x58, 0x2E, 0xF3, 0xF1, 0xAE, 0xA8, 0xA0, 0x81, 0xC6, 0x0E ],
|
||||
CodeFlag.OopsMiqote => [ 0x44, 0x73, 0x8C, 0x39, 0x5A, 0xF1, 0xDB, 0x5F, 0x62, 0xA1, 0x6E, 0x5F, 0xE6, 0x97, 0x9E, 0x90, 0xD7, 0x5C, 0x97, 0x67, 0xB6, 0xC7, 0x99, 0x61, 0x36, 0xCA, 0x34, 0x7E, 0xB9, 0xAC, 0xC3, 0x76 ],
|
||||
CodeFlag.OopsRoegadyn => [ 0xB7, 0x25, 0x73, 0xDB, 0xBE, 0xD0, 0x49, 0xFB, 0xFF, 0x9C, 0x32, 0x21, 0xB0, 0x8A, 0x2C, 0x0C, 0x77, 0x46, 0xD5, 0xCF, 0x0E, 0x63, 0x2F, 0x91, 0x85, 0x8B, 0x55, 0x5C, 0x4D, 0xD2, 0xB9, 0xB8 ],
|
||||
CodeFlag.OopsAuRa => [ 0x69, 0x93, 0xAF, 0xE4, 0xB8, 0xEC, 0x5F, 0x40, 0xEB, 0x8A, 0x6F, 0xD1, 0x9B, 0xD9, 0x56, 0x0B, 0xEA, 0x64, 0x79, 0x9B, 0x54, 0xA1, 0x41, 0xED, 0xBC, 0x3E, 0x6E, 0x5C, 0xF1, 0x23, 0x60, 0xF8 ],
|
||||
CodeFlag.OopsHrothgar => [ 0x41, 0xEC, 0x65, 0x05, 0x8D, 0x20, 0x68, 0x5A, 0xB7, 0xEB, 0x92, 0x15, 0x43, 0xCF, 0x15, 0x05, 0x27, 0x51, 0xFE, 0x20, 0xC9, 0xB6, 0x2B, 0x84, 0xD9, 0x6A, 0x49, 0x5A, 0x5B, 0x7F, 0x2E, 0xE7 ],
|
||||
CodeFlag.OopsViera => [ 0x16, 0xFF, 0x63, 0x85, 0x1C, 0xF5, 0x34, 0x33, 0x67, 0x8C, 0x46, 0x8E, 0x3E, 0xE3, 0xA6, 0x94, 0xF9, 0x74, 0x47, 0xAA, 0xC7, 0x29, 0x59, 0x1F, 0x6C, 0x6E, 0xF2, 0xF5, 0x87, 0x24, 0x9E, 0x2B ],
|
||||
CodeFlag.Artisan => [ 0xDE, 0x01, 0x32, 0x1E, 0x7F, 0x22, 0x80, 0x3D, 0x76, 0xDF, 0x74, 0x0E, 0xEC, 0x33, 0xD3, 0xF4, 0x1A, 0x98, 0x9E, 0x9D, 0x22, 0x5C, 0xAC, 0x3B, 0xFE, 0x0B, 0xC2, 0x13, 0xB9, 0x91, 0x24, 0x61 ],
|
||||
CodeFlag.SixtyThree => [ 0xA1, 0x65, 0x60, 0x99, 0xB0, 0x9F, 0xBF, 0xD7, 0x20, 0xC8, 0x29, 0xF6, 0x7B, 0x86, 0x27, 0xF5, 0xBE, 0xA9, 0x5B, 0xB0, 0x20, 0x5E, 0x57, 0x7B, 0xFF, 0xBC, 0x1E, 0x8C, 0x04, 0xF9, 0x35, 0xD3 ],
|
||||
CodeFlag.Shirts => [ 0xD1, 0x35, 0xD7, 0x18, 0xBE, 0x45, 0x42, 0xBD, 0x88, 0x77, 0x7E, 0xC4, 0x41, 0x06, 0x34, 0x4D, 0x71, 0x3A, 0xC5, 0xCC, 0xA4, 0x1B, 0x7D, 0x3F, 0x3B, 0x86, 0x07, 0xCB, 0x63, 0xD7, 0xF9, 0xDB ],
|
||||
CodeFlag.World => [ 0xFD, 0xA2, 0xD2, 0xBC, 0xD9, 0x8A, 0x7E, 0x2B, 0x52, 0xCB, 0x57, 0x6E, 0x3A, 0x2E, 0x30, 0xBA, 0x4E, 0xAE, 0x42, 0xEA, 0x5C, 0x57, 0xDF, 0x17, 0x37, 0x3C, 0xCE, 0x17, 0x42, 0x43, 0xAE, 0xD0 ],
|
||||
CodeFlag.Elephants => [ 0x9F, 0x4C, 0xCF, 0x6D, 0xC4, 0x01, 0x31, 0x46, 0x02, 0x05, 0x31, 0xED, 0xED, 0xB2, 0x66, 0x29, 0x31, 0x09, 0x1E, 0xE7, 0x47, 0xDE, 0x7B, 0x03, 0xB0, 0x3C, 0x06, 0x76, 0x26, 0x91, 0xDF, 0xB2 ],
|
||||
_ => [],
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ public class ItemManager
|
|||
|
||||
public readonly ObjectIdentification ObjectIdentification;
|
||||
public readonly ExcelSheet<Lumina.Excel.GeneratedSheets.Item> ItemSheet;
|
||||
public readonly DictStain Stains;
|
||||
public readonly DictStain Stains;
|
||||
public readonly ItemData ItemData;
|
||||
public readonly RestrictedGear RestrictedGear;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ using Glamourer.Interop;
|
|||
using Glamourer.Interop.Structs;
|
||||
using Glamourer.Services;
|
||||
using ImGuiNET;
|
||||
using OtterGui;
|
||||
using OtterGui.Classes;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.GameData.Structs;
|
||||
|
|
@ -25,18 +26,18 @@ public unsafe class FunModule : IDisposable
|
|||
AprilFirst,
|
||||
}
|
||||
|
||||
private readonly WorldSets _worldSets = new();
|
||||
private readonly ItemManager _items;
|
||||
private readonly CustomizeService _customizations;
|
||||
private readonly Configuration _config;
|
||||
private readonly CodeService _codes;
|
||||
private readonly Random _rng;
|
||||
private readonly GenericPopupWindow _popupWindow;
|
||||
private readonly StateManager _stateManager;
|
||||
private readonly DesignConverter _designConverter;
|
||||
private readonly DesignManager _designManager;
|
||||
private readonly ObjectManager _objects;
|
||||
private readonly StainId[] _stains;
|
||||
private readonly WorldSets _worldSets = new();
|
||||
private readonly ItemManager _items;
|
||||
private readonly CustomizeService _customizations;
|
||||
private readonly Configuration _config;
|
||||
private readonly CodeService _codes;
|
||||
private readonly Random _rng;
|
||||
private readonly GenericPopupWindow _popupWindow;
|
||||
private readonly StateManager _stateManager;
|
||||
private readonly DesignConverter _designConverter;
|
||||
private readonly DesignManager _designManager;
|
||||
private readonly ObjectManager _objects;
|
||||
private readonly StainId[] _stains;
|
||||
|
||||
public FestivalType CurrentFestival { get; private set; } = FestivalType.None;
|
||||
private FunEquipSet? _festivalSet;
|
||||
|
|
@ -89,54 +90,92 @@ public unsafe class FunModule : IDisposable
|
|||
public void Dispose()
|
||||
=> DayChangeTracker.DayChanged -= OnDayChange;
|
||||
|
||||
public void ApplyFun(Actor actor, ref CharacterArmor armor, EquipSlot slot)
|
||||
private bool IsInFestival
|
||||
=> _config.DisableFestivals == 0 && _festivalSet != null;
|
||||
|
||||
public void ApplyFunToSlot(Actor actor, ref CharacterArmor armor, EquipSlot slot)
|
||||
{
|
||||
if (!ValidFunTarget(actor))
|
||||
return;
|
||||
|
||||
if (_config.DisableFestivals == 0 && _festivalSet != null
|
||||
|| _codes.EnabledWorld && actor.Index != 0)
|
||||
if (IsInFestival)
|
||||
{
|
||||
armor = actor.Model.Valid ? actor.Model.GetArmor(slot) : armor;
|
||||
KeepOldArmor(actor, slot, ref armor);
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
||||
switch (_codes.Masked(CodeService.GearCodes))
|
||||
{
|
||||
ApplyEmperor(new Span<CharacterArmor>(ref armor), slot);
|
||||
ApplyClown(new Span<CharacterArmor>(ref armor));
|
||||
case CodeService.CodeFlag.Emperor:
|
||||
SetRandomItem(slot, ref armor);
|
||||
break;
|
||||
case CodeService.CodeFlag.Elephants:
|
||||
SetElephant(slot, ref armor);
|
||||
break;
|
||||
case CodeService.CodeFlag.World when actor.Index != 0:
|
||||
KeepOldArmor(actor, slot, ref armor);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (_codes.Masked(CodeService.DyeCodes))
|
||||
{
|
||||
case CodeService.CodeFlag.Clown:
|
||||
SetRandomDye(ref armor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void ApplyFun(Actor actor, Span<CharacterArmor> armor, ref CustomizeArray customize)
|
||||
public void ApplyFunOnLoad(Actor actor, Span<CharacterArmor> armor, ref CustomizeArray customize)
|
||||
{
|
||||
if (!ValidFunTarget(actor))
|
||||
return;
|
||||
|
||||
if (_config.DisableFestivals == 0 && _festivalSet != null)
|
||||
// First set the race, if any.
|
||||
SetRace(ref customize);
|
||||
// Now apply the gender.
|
||||
SetGender(ref customize);
|
||||
// Randomize customizations inside the race and gender combo.
|
||||
RandomizeCustomize(ref customize);
|
||||
// Finally, apply forced sizes.
|
||||
SetSize(actor, ref customize);
|
||||
|
||||
// Apply the festival gear with priority over all gear codes.
|
||||
if (IsInFestival)
|
||||
{
|
||||
_festivalSet.Apply(_stains, _rng, armor);
|
||||
}
|
||||
else if (_codes.EnabledWorld && actor.Index != 0)
|
||||
{
|
||||
_worldSets.Apply(actor, _rng, armor);
|
||||
}
|
||||
else
|
||||
{
|
||||
ApplyEmperor(armor);
|
||||
ApplyClown(armor);
|
||||
_festivalSet!.Apply(_stains, _rng, armor);
|
||||
return;
|
||||
}
|
||||
|
||||
ApplyOops(ref customize);
|
||||
Apply63(ref customize);
|
||||
ApplyIndividual(ref customize);
|
||||
ApplySizing(actor, ref customize);
|
||||
switch (_codes.Masked(CodeService.GearCodes))
|
||||
{
|
||||
case CodeService.CodeFlag.Emperor:
|
||||
foreach (var (slot, idx) in EquipSlotExtensions.EqdpSlots.WithIndex())
|
||||
SetRandomItem(slot, ref armor[idx]);
|
||||
break;
|
||||
case CodeService.CodeFlag.Elephants:
|
||||
SetElephant(EquipSlot.Body, ref armor[1]);
|
||||
SetElephant(EquipSlot.Head, ref armor[0]);
|
||||
break;
|
||||
case CodeService.CodeFlag.World when actor.Index != 0:
|
||||
_worldSets.Apply(actor, _rng, armor);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (_codes.Masked(CodeService.DyeCodes))
|
||||
{
|
||||
case CodeService.CodeFlag.Clown:
|
||||
foreach (ref var piece in armor)
|
||||
SetRandomDye(ref piece);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void ApplyFun(Actor actor, ref CharacterWeapon weapon, EquipSlot slot)
|
||||
public void ApplyFunToWeapon(Actor actor, ref CharacterWeapon weapon, EquipSlot slot)
|
||||
{
|
||||
if (!ValidFunTarget(actor))
|
||||
return;
|
||||
|
||||
if (_codes.EnabledWorld)
|
||||
if (_codes.Enabled(CodeService.CodeFlag.World) && actor.Index != 0)
|
||||
_worldSets.Apply(actor, _rng, ref weapon, slot);
|
||||
}
|
||||
|
||||
|
|
@ -146,55 +185,58 @@ public unsafe class FunModule : IDisposable
|
|||
&& !actor.IsTransformed
|
||||
&& actor.AsCharacter->CharacterData.ModelCharaId == 0;
|
||||
|
||||
public void ApplyClown(Span<CharacterArmor> armors)
|
||||
{
|
||||
if (!_codes.EnabledClown)
|
||||
return;
|
||||
private static void KeepOldArmor(Actor actor, EquipSlot slot, ref CharacterArmor armor)
|
||||
=> armor = actor.Model.Valid ? actor.Model.GetArmor(slot) : armor;
|
||||
|
||||
foreach (ref var armor in armors)
|
||||
{
|
||||
var stainIdx = _rng.Next(0, _stains.Length - 1);
|
||||
armor.Stain = _stains[stainIdx];
|
||||
}
|
||||
private void SetRandomDye(ref CharacterArmor armor)
|
||||
{
|
||||
var stainIdx = _rng.Next(0, _stains.Length - 1);
|
||||
armor.Stain = _stains[stainIdx];
|
||||
}
|
||||
|
||||
public void ApplyEmperor(Span<CharacterArmor> armors, EquipSlot slot = EquipSlot.Unknown)
|
||||
private void SetRandomItem(EquipSlot slot, ref CharacterArmor armor)
|
||||
{
|
||||
if (!_codes.EnabledEmperor)
|
||||
return;
|
||||
|
||||
if (armors.Length == 1)
|
||||
SetItem(slot, ref armors[0]);
|
||||
else
|
||||
for (var i = 0u; i < armors.Length; ++i)
|
||||
SetItem(i.ToEquipSlot(), ref armors[(int)i]);
|
||||
return;
|
||||
|
||||
void SetItem(EquipSlot slot2, ref CharacterArmor armor)
|
||||
{
|
||||
var list = _items.ItemData.ByType[slot2.ToEquipType()];
|
||||
var rng = _rng.Next(0, list.Count - 1);
|
||||
var item = list[rng];
|
||||
armor.Set = item.PrimaryId;
|
||||
armor.Variant = item.Variant;
|
||||
}
|
||||
var list = _items.ItemData.ByType[slot.ToEquipType()];
|
||||
var rng = _rng.Next(0, list.Count - 1);
|
||||
var item = list[rng];
|
||||
armor.Set = item.PrimaryId;
|
||||
armor.Variant = item.Variant;
|
||||
}
|
||||
|
||||
public void ApplyOops(ref CustomizeArray customize)
|
||||
private void SetElephant(EquipSlot slot, ref CharacterArmor armor)
|
||||
{
|
||||
if (_codes.EnabledOops == Race.Unknown)
|
||||
armor = slot switch
|
||||
{
|
||||
EquipSlot.Body => new CharacterArmor(6133, 1, 87),
|
||||
EquipSlot.Head => new CharacterArmor(6133, 1, 87),
|
||||
_ => armor,
|
||||
};
|
||||
}
|
||||
|
||||
private void SetRace(ref CustomizeArray customize)
|
||||
{
|
||||
var race = _codes.GetRace();
|
||||
if (race == Race.Unknown)
|
||||
return;
|
||||
|
||||
var targetClan = (SubRace)((int)_codes.EnabledOops * 2 - (int)customize.Clan % 2);
|
||||
var targetClan = (SubRace)((int)race * 2 - (int)customize.Clan % 2);
|
||||
// TODO Female Hrothgar
|
||||
if (_codes.EnabledOops is Race.Hrothgar && customize.Gender is Gender.Female)
|
||||
if (race is Race.Hrothgar && customize.Gender is Gender.Female)
|
||||
targetClan = targetClan is SubRace.Lost ? SubRace.Seawolf : SubRace.Hellsguard;
|
||||
_customizations.ChangeClan(ref customize, targetClan);
|
||||
}
|
||||
|
||||
public void ApplyIndividual(ref CustomizeArray customize)
|
||||
private void SetGender(ref CustomizeArray customize)
|
||||
{
|
||||
if (!_codes.EnabledIndividual)
|
||||
if (!_codes.Enabled(CodeService.CodeFlag.SixtyThree) || customize.Race is Race.Hrothgar) // TODO Female Hrothgar
|
||||
return;
|
||||
|
||||
_customizations.ChangeGender(ref customize, customize.Gender is Gender.Male ? Gender.Female : Gender.Male);
|
||||
}
|
||||
|
||||
private void RandomizeCustomize(ref CustomizeArray customize)
|
||||
{
|
||||
if (!_codes.Enabled(CodeService.CodeFlag.Individual))
|
||||
return;
|
||||
|
||||
var set = _customizations.Manager.GetSet(customize.Clan, customize.Gender);
|
||||
|
|
@ -208,27 +250,18 @@ public unsafe class FunModule : IDisposable
|
|||
}
|
||||
}
|
||||
|
||||
public void Apply63(ref CustomizeArray customize)
|
||||
private void SetSize(Actor actor, ref CustomizeArray customize)
|
||||
{
|
||||
if (!_codes.Enabled63 || customize.Race is Race.Hrothgar) // TODO Female Hrothgar
|
||||
return;
|
||||
|
||||
_customizations.ChangeGender(ref customize, customize.Gender is Gender.Male ? Gender.Female : Gender.Male);
|
||||
}
|
||||
|
||||
public void ApplySizing(Actor actor, ref CustomizeArray customize)
|
||||
{
|
||||
if (_codes.EnabledSizing == CodeService.Sizing.None)
|
||||
return;
|
||||
|
||||
var size = _codes.EnabledSizing switch
|
||||
var size = _codes.Masked(CodeService.SizeCodes) switch
|
||||
{
|
||||
CodeService.Sizing.Dwarf when actor.Index == 0 => 0,
|
||||
CodeService.Sizing.Dwarf when actor.Index != 0 => 100,
|
||||
CodeService.Sizing.Giant when actor.Index == 0 => 100,
|
||||
CodeService.Sizing.Giant when actor.Index != 0 => 0,
|
||||
_ => 0,
|
||||
CodeService.CodeFlag.Dwarf when actor.Index == 0 => (byte)0,
|
||||
CodeService.CodeFlag.Dwarf => (byte)100,
|
||||
CodeService.CodeFlag.Giant when actor.Index == 0 => (byte)100,
|
||||
CodeService.CodeFlag.Giant => (byte)0,
|
||||
_ => byte.MaxValue,
|
||||
};
|
||||
if (size == byte.MaxValue)
|
||||
return;
|
||||
|
||||
if (customize.Gender is Gender.Female)
|
||||
customize[CustomizeIndex.BustSize] = (CustomizeValue)size;
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ public class StateListener : IDisposable
|
|||
_creatingState.TempUnlock();
|
||||
}
|
||||
|
||||
_funModule.ApplyFun(actor, new Span<CharacterArmor>((void*)equipDataPtr, 10), ref customize);
|
||||
_funModule.ApplyFunOnLoad(actor, new Span<CharacterArmor>((void*)equipDataPtr, 10), ref customize);
|
||||
if (modelId == 0)
|
||||
ProtectRestrictedGear(equipDataPtr, customize.Race, customize.Gender);
|
||||
}
|
||||
|
|
@ -216,7 +216,7 @@ public class StateListener : IDisposable
|
|||
locked = state[slot, false] is StateChanged.Source.Ipc;
|
||||
}
|
||||
|
||||
_funModule.ApplyFun(actor, ref armor.Value, slot);
|
||||
_funModule.ApplyFunToSlot(actor, ref armor.Value, slot);
|
||||
if (!_config.UseRestrictedGearProtection || locked)
|
||||
return;
|
||||
|
||||
|
|
@ -315,7 +315,7 @@ public class StateListener : IDisposable
|
|||
_lastFistOffhand = new CharacterWeapon((PrimaryId)(weapon.Value.Skeleton.Id + 50), weapon.Value.Weapon, weapon.Value.Variant,
|
||||
weapon.Value.Stain);
|
||||
|
||||
_funModule.ApplyFun(actor, ref weapon.Value, slot);
|
||||
_funModule.ApplyFunToWeapon(actor, ref weapon.Value, slot);
|
||||
}
|
||||
|
||||
/// <summary> Update base data for a single changed equipment slot. </summary>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue