Add some more codes.

This commit is contained in:
Ottermandias 2023-10-02 14:10:40 +02:00
parent be1adc267d
commit c98ed04bf3
8 changed files with 538 additions and 18 deletions

View file

@ -25,10 +25,11 @@ public class SettingsTab : ITab
private readonly ContextMenuService _contextMenuService; private readonly ContextMenuService _contextMenuService;
private readonly UiBuilder _uiBuilder; private readonly UiBuilder _uiBuilder;
private readonly GlamourerChangelog _changelog; private readonly GlamourerChangelog _changelog;
private readonly FunModule _funModule;
public SettingsTab(Configuration config, DesignFileSystemSelector selector, StateListener stateListener, public SettingsTab(Configuration config, DesignFileSystemSelector selector, StateListener stateListener,
CodeService codeService, PenumbraAutoRedraw autoRedraw, ContextMenuService contextMenuService, UiBuilder uiBuilder, CodeService codeService, PenumbraAutoRedraw autoRedraw, ContextMenuService contextMenuService, UiBuilder uiBuilder,
GlamourerChangelog changelog) GlamourerChangelog changelog, FunModule funModule)
{ {
_config = config; _config = config;
_selector = selector; _selector = selector;
@ -38,6 +39,7 @@ public class SettingsTab : ITab
_contextMenuService = contextMenuService; _contextMenuService = contextMenuService;
_uiBuilder = uiBuilder; _uiBuilder = uiBuilder;
_changelog = changelog; _changelog = changelog;
_funModule = funModule;
} }
public ReadOnlySpan<byte> Label public ReadOnlySpan<byte> Label
@ -203,6 +205,17 @@ public class SettingsTab : ITab
_config.Save(); _config.Save();
} }
} }
if (_codeService.EnabledCaptain)
{
if (ImGui.Button("Who am I?!?"))
_funModule.WhoAmI();
ImGui.SameLine();
if (ImGui.Button("Who is that!?!"))
_funModule.WhoIsThat();
}
} }
private void DrawCodeHints() private void DrawCodeHints()

View file

@ -21,6 +21,7 @@ public class UnlockOverview
private readonly CustomizeUnlockManager _customizeUnlocks; private readonly CustomizeUnlockManager _customizeUnlocks;
private readonly PenumbraChangedItemTooltip _tooltip; private readonly PenumbraChangedItemTooltip _tooltip;
private readonly TextureService _textures; private readonly TextureService _textures;
private readonly CodeService _codes;
private static readonly Vector4 UnavailableTint = new(0.3f, 0.3f, 0.3f, 1.0f); private static readonly Vector4 UnavailableTint = new(0.3f, 0.3f, 0.3f, 1.0f);
@ -66,7 +67,7 @@ public class UnlockOverview
} }
public UnlockOverview(ItemManager items, CustomizationService customizations, ItemUnlockManager itemUnlocks, public UnlockOverview(ItemManager items, CustomizationService customizations, ItemUnlockManager itemUnlocks,
CustomizeUnlockManager customizeUnlocks, PenumbraChangedItemTooltip tooltip, TextureService textures) CustomizeUnlockManager customizeUnlocks, PenumbraChangedItemTooltip tooltip, TextureService textures, CodeService codes)
{ {
_items = items; _items = items;
_customizations = customizations; _customizations = customizations;
@ -74,6 +75,7 @@ public class UnlockOverview
_customizeUnlocks = customizeUnlocks; _customizeUnlocks = customizeUnlocks;
_tooltip = tooltip; _tooltip = tooltip;
_textures = textures; _textures = textures;
_codes = codes;
} }
public void Draw() public void Draw()
@ -114,7 +116,7 @@ public class UnlockOverview
var unlocked = _customizeUnlocks.IsUnlocked(customize, out var time) ; var unlocked = _customizeUnlocks.IsUnlocked(customize, out var time) ;
var icon = _customizations.AwaitedService.GetIcon(customize.IconId); var icon = _customizations.AwaitedService.GetIcon(customize.IconId);
ImGui.Image(icon.ImGuiHandle, iconSize, Vector2.Zero, Vector2.One, unlocked ? Vector4.One : UnavailableTint); ImGui.Image(icon.ImGuiHandle, iconSize, Vector2.Zero, Vector2.One, unlocked || _codes.EnabledShirts ? Vector4.One : UnavailableTint);
if (ImGui.IsItemHovered()) if (ImGui.IsItemHovered())
{ {
using var tt = ImRaii.Tooltip(); using var tt = ImRaii.Tooltip();
@ -158,7 +160,7 @@ public class UnlockOverview
var (icon, size) = (iconHandle.ImGuiHandle, new Vector2(iconHandle.Width, iconHandle.Height)); var (icon, size) = (iconHandle.ImGuiHandle, new Vector2(iconHandle.Width, iconHandle.Height));
ImGui.Image(icon, iconSize, Vector2.Zero, Vector2.One, unlocked ? Vector4.One : UnavailableTint); ImGui.Image(icon, iconSize, Vector2.Zero, Vector2.One, unlocked || _codes.EnabledShirts ? Vector4.One : UnavailableTint);
if (ImGui.IsItemClicked()) if (ImGui.IsItemClicked())
{ {
// TODO link // TODO link

View file

@ -25,6 +25,10 @@ public class CodeService
public Sizing EnabledSizing { get; private set; } public Sizing EnabledSizing { get; private set; }
public Race EnabledOops { get; private set; } public Race EnabledOops { get; private set; }
public bool EnabledArtisan { 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 CodeService(Configuration config) public CodeService(Configuration config)
{ {
@ -73,6 +77,8 @@ public class CodeService
_ when CodeClown.SequenceEqual(sha) => v => EnabledClown = v, _ when CodeClown.SequenceEqual(sha) => v => EnabledClown = v,
_ when CodeEmperor.SequenceEqual(sha) => v => EnabledEmperor = v, _ when CodeEmperor.SequenceEqual(sha) => v => EnabledEmperor = v,
_ when CodeIndividual.SequenceEqual(sha) => v => EnabledIndividual = 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 CodeDwarf.SequenceEqual(sha) => v => EnabledSizing = v ? Sizing.Dwarf : Sizing.None,
_ when CodeGiant.SequenceEqual(sha) => v => EnabledSizing = v ? Sizing.Giant : 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 CodeOops1.SequenceEqual(sha) => v => EnabledOops = v ? Race.Hyur : Race.Unknown,
@ -84,6 +90,9 @@ public class CodeService
_ when CodeOops7.SequenceEqual(sha) => v => EnabledOops = v ? Race.Hrothgar : 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 CodeOops8.SequenceEqual(sha) => v => EnabledOops = v ? Race.Viera : Race.Unknown,
_ when CodeArtisan.SequenceEqual(sha) => v => EnabledArtisan = v, _ when CodeArtisan.SequenceEqual(sha) => v => EnabledArtisan = v,
_ when CodeShirts.SequenceEqual(sha) => v => EnabledShirts = v,
_ when CodeWorld.SequenceEqual(sha) => v => EnabledWorld = v,
_ => null, _ => null,
}; };
} }
@ -143,5 +152,9 @@ public class CodeService
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> 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> 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> 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 // @formatter:on
} }

View file

@ -1,4 +1,5 @@
using System; using System;
using Glamourer.Interop.Structs;
using Penumbra.GameData.Structs; using Penumbra.GameData.Structs;
namespace Glamourer.State; namespace Glamourer.State;
@ -24,6 +25,12 @@ internal class FunEquipSet
: this(new CharacterArmor(headS, headV, 0), new CharacterArmor(bodyS, bodyV, 0), new CharacterArmor(handsS, handsV, 0), : this(new CharacterArmor(headS, headV, 0), new CharacterArmor(bodyS, bodyV, 0), new CharacterArmor(handsS, handsV, 0),
new CharacterArmor(legsS, legsV, 0), new CharacterArmor(feetS, feetV, 0), stains) new CharacterArmor(legsS, legsV, 0), new CharacterArmor(feetS, feetV, 0), stains)
{ } { }
public static Group FullSetWithoutHat(ushort modelSet, byte variant, StainId[]? stains = null)
=> new(0279, 1, modelSet, variant, modelSet, variant, modelSet, variant, modelSet, variant, stains);
public static Group FullSet(ushort modelSet, byte variant, StainId[]? stains = null)
=> new(modelSet, variant, modelSet, variant, modelSet, variant, modelSet, variant, modelSet, variant, stains);
} }
private readonly Group[] _groups; private readonly Group[] _groups;

View file

@ -2,9 +2,12 @@
using System.Linq; using System.Linq;
using Dalamud.Game.ClientState.Objects.Enums; using Dalamud.Game.ClientState.Objects.Enums;
using Glamourer.Customization; using Glamourer.Customization;
using Glamourer.Designs;
using Glamourer.Gui; using Glamourer.Gui;
using Glamourer.Interop;
using Glamourer.Interop.Structs; using Glamourer.Interop.Structs;
using Glamourer.Services; using Glamourer.Services;
using ImGuiNET;
using OtterGui.Classes; using OtterGui.Classes;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs; using Penumbra.GameData.Structs;
@ -22,12 +25,17 @@ public unsafe class FunModule : IDisposable
AprilFirst, AprilFirst,
} }
private readonly WorldSets _worldSets = new();
private readonly ItemManager _items; private readonly ItemManager _items;
private readonly CustomizationService _customizations; private readonly CustomizationService _customizations;
private readonly Configuration _config; private readonly Configuration _config;
private readonly CodeService _codes; private readonly CodeService _codes;
private readonly Random _rng; private readonly Random _rng;
private readonly GenericPopupWindow _popupWindow; 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 StainId[] _stains;
public FestivalType CurrentFestival { get; private set; } = FestivalType.None; public FestivalType CurrentFestival { get; private set; } = FestivalType.None;
@ -60,13 +68,18 @@ public unsafe class FunModule : IDisposable
=> OnDayChange(DateTime.UtcNow.Day, DateTime.UtcNow.Month, DateTime.UtcNow.Year); => OnDayChange(DateTime.UtcNow.Day, DateTime.UtcNow.Month, DateTime.UtcNow.Year);
public FunModule(CodeService codes, CustomizationService customizations, ItemManager items, Configuration config, public FunModule(CodeService codes, CustomizationService customizations, ItemManager items, Configuration config,
GenericPopupWindow popupWindow) GenericPopupWindow popupWindow, StateManager stateManager, ObjectManager objects, DesignConverter designConverter,
DesignManager designManager)
{ {
_codes = codes; _codes = codes;
_customizations = customizations; _customizations = customizations;
_items = items; _items = items;
_config = config; _config = config;
_popupWindow = popupWindow; _popupWindow = popupWindow;
_stateManager = stateManager;
_objects = objects;
_designConverter = designConverter;
_designManager = designManager;
_rng = new Random(); _rng = new Random();
_stains = _items.Stains.Keys.Prepend((StainId)0).ToArray(); _stains = _items.Stains.Keys.Prepend((StainId)0).ToArray();
ResetFestival(); ResetFestival();
@ -100,6 +113,10 @@ public unsafe class FunModule : IDisposable
{ {
_festivalSet.Apply(_stains, _rng, armor); _festivalSet.Apply(_stains, _rng, armor);
} }
else if (_codes.EnabledWorld && actor.Index != 0)
{
_worldSets.Apply(actor, _rng, armor);
}
else else
{ {
ApplyEmperor(armor); ApplyEmperor(armor);
@ -107,10 +124,23 @@ public unsafe class FunModule : IDisposable
} }
ApplyOops(ref customize); ApplyOops(ref customize);
Apply63(ref customize);
ApplyIndividual(ref customize); ApplyIndividual(ref customize);
ApplySizing(actor, ref customize); ApplySizing(actor, ref customize);
} }
public void ApplyFun(Actor actor, ref CharacterWeapon weapon, EquipSlot slot)
{
if (actor.AsObject->ObjectKind is not (byte)ObjectKind.Player || !actor.IsCharacter)
return;
if (actor.AsCharacter->CharacterData.ModelCharaId != 0)
return;
if (_codes.EnabledWorld)
_worldSets.Apply(actor, _rng, ref weapon, slot);
}
public void ApplyClown(Span<CharacterArmor> armors) public void ApplyClown(Span<CharacterArmor> armors)
{ {
if (!_codes.EnabledClown) if (!_codes.EnabledClown)
@ -172,6 +202,14 @@ public unsafe class FunModule : IDisposable
} }
} }
public void Apply63(ref Customize 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 Customize customize) public void ApplySizing(Actor actor, ref Customize customize)
{ {
if (_codes.EnabledSizing == CodeService.Sizing.None) if (_codes.EnabledSizing == CodeService.Sizing.None)
@ -190,4 +228,30 @@ public unsafe class FunModule : IDisposable
customize[CustomizeIndex.BustSize] = (CustomizeValue)size; customize[CustomizeIndex.BustSize] = (CustomizeValue)size;
customize[CustomizeIndex.Height] = (CustomizeValue)size; customize[CustomizeIndex.Height] = (CustomizeValue)size;
} }
public void WhoAmI()
=> WhoIsThat(_objects.Player);
public void WhoIsThat()
=> WhoIsThat(_objects.Target);
private void WhoIsThat(Actor actor)
{
if (!actor.IsCharacter)
return;
try
{
var tmp = _designManager.CreateTemporary();
tmp.DesignData = _stateManager.FromActor(actor, true);
tmp.FixCustomizeApplication(_customizations, CustomizeFlagExtensions.AllRelevant);
var data = _designConverter.ShareBase64(tmp);
ImGui.SetClipboardText(data);
Glamourer.Chat.NotificationMessage($"Copied current actual design of {actor.Utf8Name} to clipboard.");
}
catch
{
// ignored
}
}
} }

View file

@ -270,7 +270,8 @@ public class StateListener : IDisposable
_applier.ChangeWeapon(objects, slot, currentItem, stain); _applier.ChangeWeapon(objects, slot, currentItem, stain);
break; break;
default: default:
_applier.ChangeArmor(objects, slot, current.ToArmor(), state[slot, false] is not StateChanged.Source.Ipc, state.ModelData.IsHatVisible()); _applier.ChangeArmor(objects, slot, current.ToArmor(), state[slot, false] is not StateChanged.Source.Ipc,
state.ModelData.IsHatVisible());
break; break;
} }
} }
@ -333,6 +334,8 @@ public class StateListener : IDisposable
if (slot is EquipSlot.MainHand && weapon.Value.Set.Id is > 1600 and < 1651) if (slot is EquipSlot.MainHand && weapon.Value.Set.Id is > 1600 and < 1651)
_lastFistOffhand = new CharacterWeapon((SetId)(weapon.Value.Set.Id + 50), weapon.Value.Type, weapon.Value.Variant, _lastFistOffhand = new CharacterWeapon((SetId)(weapon.Value.Set.Id + 50), weapon.Value.Type, weapon.Value.Variant,
weapon.Value.Stain); weapon.Value.Stain);
_funModule.ApplyFun(actor, ref weapon.Value, slot);
} }
/// <summary> Update base data for a single changed equipment slot. </summary> /// <summary> Update base data for a single changed equipment slot. </summary>

View file

@ -0,0 +1,418 @@
using System;
using System.Collections.Generic;
using Glamourer.Interop.Structs;
using Glamourer.Structs;
using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs;
namespace Glamourer.State;
public class WorldSets
{
// @formatter:off
private static readonly Dictionary<(Gender, Race), FunEquipSet.Group> Starter = new()
{
[(Gender.Male, Race.Hyur)] = FunEquipSet.Group.FullSetWithoutHat(0084, 2),
[(Gender.Female, Race.Hyur)] = FunEquipSet.Group.FullSetWithoutHat(0085, 2),
[(Gender.Male, Race.Elezen)] = FunEquipSet.Group.FullSetWithoutHat(0086, 2),
[(Gender.Female, Race.Elezen)] = FunEquipSet.Group.FullSetWithoutHat(0087, 2),
[(Gender.Male, Race.Miqote)] = FunEquipSet.Group.FullSetWithoutHat(0088, 2),
[(Gender.Female, Race.Miqote)] = FunEquipSet.Group.FullSetWithoutHat(0089, 2),
[(Gender.Male, Race.Roegadyn)] = FunEquipSet.Group.FullSetWithoutHat(0090, 2),
[(Gender.Female, Race.Roegadyn)] = FunEquipSet.Group.FullSetWithoutHat(0091, 2),
[(Gender.Male, Race.Lalafell)] = FunEquipSet.Group.FullSetWithoutHat(0092, 2),
[(Gender.Female, Race.Lalafell)] = FunEquipSet.Group.FullSetWithoutHat(0093, 2),
[(Gender.Male, Race.AuRa)] = FunEquipSet.Group.FullSetWithoutHat(0257, 2),
[(Gender.Female, Race.AuRa)] = FunEquipSet.Group.FullSetWithoutHat(0258, 2),
[(Gender.Male, Race.Hrothgar)] = FunEquipSet.Group.FullSetWithoutHat(0597, 1),
[(Gender.Female, Race.Hrothgar)] = FunEquipSet.Group.FullSetWithoutHat(0000, 0), // TODO Hrothgar Female
[(Gender.Male, Race.Viera)] = FunEquipSet.Group.FullSetWithoutHat(0744, 1),
[(Gender.Female, Race.Viera)] = FunEquipSet.Group.FullSetWithoutHat(0581, 1),
};
private static readonly (CharacterWeapon, CharacterWeapon)[] StarterWeapons =
{
(CharacterWeapon.Empty, CharacterWeapon.Empty), // ADV,
(CharacterWeapon.Int(0201, 43, 01), CharacterWeapon.Int(0101, 07, 2)), // GLA, Weathered Shortsword, Square Maple
(CharacterWeapon.Int(0301, 09, 01), CharacterWeapon.Int(0351, 09, 1)), // PGL, Weathered Hora
(CharacterWeapon.Int(0401, 31, 07), CharacterWeapon.Empty), // MRD, Weathered War Axe
(CharacterWeapon.Int(0501, 03, 12), CharacterWeapon.Empty), // LNC, Weathered Spear
(CharacterWeapon.Int(0601, 01, 08), CharacterWeapon.Int(0698, 01, 2)), // ARC, Weathered Shortbow
(CharacterWeapon.Int(0801, 01, 12), CharacterWeapon.Empty), // CNJ, Weathered Cane
(CharacterWeapon.Int(1001, 01, 01), CharacterWeapon.Empty), // THM, Bone Staff
(CharacterWeapon.Int(5001, 01, 01), CharacterWeapon.Int(5041, 01, 1)), // CRP, Weathered, Amateur's
(CharacterWeapon.Int(5101, 02, 01), CharacterWeapon.Int(5141, 01, 1)), // BSM, Weathered, Amateur's
(CharacterWeapon.Int(5201, 01, 05), CharacterWeapon.Int(5241, 01, 1)), // ARM, Weathered, Amateur's
(CharacterWeapon.Int(5301, 01, 01), CharacterWeapon.Int(5341, 01, 1)), // GSM, Weathered, Amateur's
(CharacterWeapon.Int(5401, 01, 06), CharacterWeapon.Int(5441, 01, 1)), // LTW, Weathered, Amateur's
(CharacterWeapon.Int(5501, 01, 14), CharacterWeapon.Int(5571, 01, 1)), // WVR, Rusty, Amateur's
(CharacterWeapon.Int(5601, 01, 04), CharacterWeapon.Int(5641, 01, 1)), // ALC, Weathered, Amateur's
(CharacterWeapon.Int(5701, 01, 07), CharacterWeapon.Int(5741, 01, 1)), // CUL, Weathered, Amateur's
(CharacterWeapon.Int(7001, 01, 05), CharacterWeapon.Int(7051, 01, 1)), // MIN, Weathered, Amateur's
(CharacterWeapon.Int(7101, 01, 05), CharacterWeapon.Int(7151, 01, 1)), // BTN, Weathered, Amateur's
(CharacterWeapon.Int(7201, 01, 06), CharacterWeapon.Int(7255, 01, 1)), // FSH, Weathered, Gig
(CharacterWeapon.Int(0201, 43, 01), CharacterWeapon.Int(0101, 07, 2)), // PLD, Weathered Shortsword, Square Maple
(CharacterWeapon.Int(0301, 09, 01), CharacterWeapon.Int(0351, 09, 1)), // MNK, Weathered Hora
(CharacterWeapon.Int(0401, 31, 07), CharacterWeapon.Empty), // WAR, Weathered War Axe
(CharacterWeapon.Int(0501, 03, 12), CharacterWeapon.Empty), // DRG, Weathered Spear
(CharacterWeapon.Int(0601, 01, 08), CharacterWeapon.Int(0698, 01, 2)), // BRD, Weathered Shortbow
(CharacterWeapon.Int(0801, 01, 12), CharacterWeapon.Empty), // WHM, Weathered Cane
(CharacterWeapon.Int(1001, 01, 01), CharacterWeapon.Empty), // BLM, Bone Staff
(CharacterWeapon.Int(1708, 01, 01), CharacterWeapon.Empty), // ACN, Weathered Grimoire
(CharacterWeapon.Int(1708, 01, 01), CharacterWeapon.Empty), // SMN, Weathered Grimoire
(CharacterWeapon.Int(1708, 01, 01), CharacterWeapon.Empty), // SCH, Weathered Grimoire
(CharacterWeapon.Int(1801, 33, 07), CharacterWeapon.Int(1851, 33, 7)), // ROG, Weathered Daggers
(CharacterWeapon.Int(1801, 33, 07), CharacterWeapon.Int(1851, 33, 7)), // NIN, Weathered Daggers
(CharacterWeapon.Int(2001, 11, 01), CharacterWeapon.Int(2099, 01, 1)), // MCH, Steel-barreled Carbine
(CharacterWeapon.Int(1501, 01, 05), CharacterWeapon.Empty), // DRK, Steel Claymore
(CharacterWeapon.Int(2101, 07, 01), CharacterWeapon.Int(2199, 01, 1)), // AST, Star Globe
(CharacterWeapon.Int(2201, 26, 01), CharacterWeapon.Int(2251, 38, 1)), // SAM, Mythrite Uchigatana
(CharacterWeapon.Int(2301, 38, 01), CharacterWeapon.Int(2351, 29, 1)), // RDM, Mythrite Rapier
(CharacterWeapon.Int(2401, 02, 01), CharacterWeapon.Empty), // BLU, Rainmaker
(CharacterWeapon.Int(2501, 14, 01), CharacterWeapon.Empty), // GNB, High Steel Gunblade
(CharacterWeapon.Int(2601, 13, 01), CharacterWeapon.Int(2651, 13, 1)), // DNC, High Steel Chakrams
(CharacterWeapon.Int(2802, 13, 01), CharacterWeapon.Empty), // RPR, Deepgold War Scythe
(CharacterWeapon.Int(2702, 08, 01), CharacterWeapon.Empty), // SGE, Stonegold Milpreves
};
private static readonly (FunEquipSet.Group, CharacterWeapon, CharacterWeapon)[] _50Artifact =
{
(FunEquipSet.Group.FullSet(000, 0), CharacterWeapon.Empty, CharacterWeapon.Empty), // ADV, Nothing
(FunEquipSet.Group.FullSet(042, 1), CharacterWeapon.Int(0201, 10, 1), CharacterWeapon.Int(0101, 11, 1)), // GLA, Gallant, Curtana, Holy Shield
(FunEquipSet.Group.FullSet(044, 1), CharacterWeapon.Int(0304, 01, 1), CharacterWeapon.Int(0354, 01, 1)), // PGL, Temple, Sphairai
(FunEquipSet.Group.FullSet(037, 1), CharacterWeapon.Int(0401, 07, 1), CharacterWeapon.Empty), // MRD, Fighter's, Bravura
(FunEquipSet.Group.FullSet(036, 1), CharacterWeapon.Int(0504, 01, 1), CharacterWeapon.Empty), // LNC, Drachen, Gae Bolg
(FunEquipSet.Group.FullSet(041, 1), CharacterWeapon.Int(0603, 01, 1), CharacterWeapon.Int(0698, 04, 1)), // ARC, Choral, Artemis
(FunEquipSet.Group.FullSet(039, 1), CharacterWeapon.Int(0801, 06, 1), CharacterWeapon.Empty), // CNJ, Healer's, Thyrus
(FunEquipSet.Group.FullSet(040, 1), CharacterWeapon.Int(1001, 02, 1), CharacterWeapon.Empty), // THM, Wizard's, Stardust Rod
(FunEquipSet.Group.FullSet(074, 1), CharacterWeapon.Int(5003, 01, 1), CharacterWeapon.Int(5041, 01, 4)), // CRP, Militia, Ullikummi
(FunEquipSet.Group.FullSet(073, 1), CharacterWeapon.Int(5101, 02, 1), CharacterWeapon.Int(5141, 01, 4)), // BSM, Militia, Vulcan
(FunEquipSet.Group.FullSet(076, 1), CharacterWeapon.Int(5201, 04, 1), CharacterWeapon.Int(5241, 01, 4)), // ARM, Militia, Kurdalegon
(FunEquipSet.Group.FullSet(078, 1), CharacterWeapon.Int(5301, 03, 1), CharacterWeapon.Int(5341, 01, 1)), // GSM, Militia, Urcaguary
(FunEquipSet.Group.FullSet(077, 1), CharacterWeapon.Int(5401, 05, 1), CharacterWeapon.Int(5441, 01, 4)), // LTW, Militia, Pinga
(FunEquipSet.Group.FullSet(075, 1), CharacterWeapon.Int(5501, 02, 1), CharacterWeapon.Int(5571, 01, 1)), // WVR, Militia, Clotho
(FunEquipSet.Group.FullSet(079, 1), CharacterWeapon.Int(5603, 01, 1), CharacterWeapon.Int(5641, 01, 4)), // ALC, Militia, Paracelsus
(FunEquipSet.Group.FullSet(080, 1), CharacterWeapon.Int(5701, 04, 1), CharacterWeapon.Int(5741, 01, 4)), // CUL, Militia, Chantico
(FunEquipSet.Group.FullSet(072, 1), CharacterWeapon.Int(7002, 01, 1), CharacterWeapon.Int(7051, 01, 4)), // MIN, Militia, Mammon
(FunEquipSet.Group.FullSet(071, 1), CharacterWeapon.Int(7101, 05, 1), CharacterWeapon.Int(7151, 01, 4)), // BTN, Militia, Rauni
(FunEquipSet.Group.FullSet(070, 1), CharacterWeapon.Int(7201, 04, 1), CharacterWeapon.Int(7255, 01, 1)), // FSH, Militia, Halcyon
(FunEquipSet.Group.FullSet(042, 1), CharacterWeapon.Int(0201, 10, 1), CharacterWeapon.Int(0101, 11, 1)), // PLD, Gallant, Curtana, Holy Shield
(FunEquipSet.Group.FullSet(044, 1), CharacterWeapon.Int(0304, 01, 1), CharacterWeapon.Int(0354, 01, 1)), // MNK, Temple, Sphairai
(FunEquipSet.Group.FullSet(037, 1), CharacterWeapon.Int(0401, 07, 1), CharacterWeapon.Empty), // WAR, Fighter's, Bravura
(FunEquipSet.Group.FullSet(036, 1), CharacterWeapon.Int(0504, 01, 1), CharacterWeapon.Empty), // DRG, Drachen, Gae Bolg
(FunEquipSet.Group.FullSet(041, 1), CharacterWeapon.Int(0603, 01, 1), CharacterWeapon.Int(0698, 04, 1)), // BRD, Choral, Artemis
(FunEquipSet.Group.FullSet(039, 1), CharacterWeapon.Int(0801, 06, 1), CharacterWeapon.Empty), // WHM, Healer's, Thyrus
(FunEquipSet.Group.FullSet(040, 1), CharacterWeapon.Int(1001, 02, 1), CharacterWeapon.Empty), // BLM, Wizard's, Stardust Rod
(FunEquipSet.Group.FullSet(132, 1), CharacterWeapon.Int(1705, 01, 1), CharacterWeapon.Empty), // ACN, Evoker's, Veil of Wiyu
(FunEquipSet.Group.FullSet(132, 1), CharacterWeapon.Int(1705, 01, 1), CharacterWeapon.Empty), // SMN, Evoker's, Veil of Wiyu
(FunEquipSet.Group.FullSet(133, 1), CharacterWeapon.Int(1715, 01, 1), CharacterWeapon.Empty), // SCH, Scholar's
(FunEquipSet.Group.FullSet(170, 1), CharacterWeapon.Int(1801, 02, 1), CharacterWeapon.Int(1851, 02, 1)), // ROG, Ninja, Yoshimitsu
(FunEquipSet.Group.FullSet(170, 1), CharacterWeapon.Int(1801, 02, 1), CharacterWeapon.Int(1851, 02, 1)), // NIN, Ninja, Yoshimitsu
(FunEquipSet.Group.FullSet(265, 1), CharacterWeapon.Int(2001, 11, 1), CharacterWeapon.Int(2099, 01, 1)), // MCH, Machinist's, Steel-barreled Carbine
(FunEquipSet.Group.FullSet(264, 1), CharacterWeapon.Int(1501, 01, 5), CharacterWeapon.Empty), // DRK, Chaos, Steel Claymore
(FunEquipSet.Group.FullSet(266, 1), CharacterWeapon.Int(2101, 07, 1), CharacterWeapon.Int(2199, 01, 1)), // AST, Welkin, Star Globe
(new FunEquipSet.Group(246, 5, 489, 1, 246, 5, 246, 5, 245, 5), CharacterWeapon.Int(2201, 26, 1), CharacterWeapon.Int(2251, 38, 1)), // SAM, Nameless, Mythrite Uchigatana
(new FunEquipSet.Group(16, 160, 16, 54, 103, 1, 16, 105, 16, 167), CharacterWeapon.Int(2301, 38, 1), CharacterWeapon.Int(2351, 29, 1)), // RDM, Red, Mythrite Rapier
(new FunEquipSet.Group(9, 255, 338, 6, 338, 6, 338, 6, 338, 6), CharacterWeapon.Int(2401, 02, 1), CharacterWeapon.Empty), // BLU, True Blue, Rainmaker
(new FunEquipSet.Group(592, 3, 380, 4, 380, 4, 380, 4, 380, 4), CharacterWeapon.Int(2501, 14, 1), CharacterWeapon.Empty), // GNB, Outsider's, High Steel Gunblade
(FunEquipSet.Group.FullSet(204, 4), CharacterWeapon.Int(2601, 13, 1), CharacterWeapon.Int(2651, 13, 1)), // DNC, Softstepper, High Steel Chakrams
(new FunEquipSet.Group(206, 7, 303, 3, 23, 109, 303, 3, 262, 7), CharacterWeapon.Int(2802, 13, 1), CharacterWeapon.Empty), // RPR, Muzhik, Deepgold War Scythe
(new FunEquipSet.Group(20, 46, 289, 6, 342, 3, 120, 9, 342, 3), CharacterWeapon.Int(2702, 08, 1), CharacterWeapon.Empty), // SGE, Bookwyrm, Stonegold Milpreves
};
private static readonly (FunEquipSet.Group, CharacterWeapon, CharacterWeapon)[] _60Artifact =
{
(FunEquipSet.Group.FullSet(000, 0), CharacterWeapon.Empty, CharacterWeapon.Empty), // ADV, Nothing
(FunEquipSet.Group.FullSet(160, 1), CharacterWeapon.Int(0201, 30, 1), CharacterWeapon.Int(0101, 29, 01)), // GLA, Creed, Hauteclaire, Prytwen
(FunEquipSet.Group.FullSet(161, 1), CharacterWeapon.Int(0313, 02, 1), CharacterWeapon.Int(0363, 02, 01)), // PGL, Tantra, Rising Suns
(FunEquipSet.Group.FullSet(162, 1), CharacterWeapon.Int(0401, 20, 1), CharacterWeapon.Empty), // MRD, Ravager, Parashu
(FunEquipSet.Group.FullSet(163, 1), CharacterWeapon.Int(0501, 18, 1), CharacterWeapon.Empty), // LNC, Dragonlancer, Brionac
(FunEquipSet.Group.FullSet(164, 1), CharacterWeapon.Int(0601, 24, 1), CharacterWeapon.Int(0698, 23, 01)), // ARC, Aoidos, Berimbau
(FunEquipSet.Group.FullSet(165, 1), CharacterWeapon.Int(0801, 18, 1), CharacterWeapon.Empty), // CNJ, Orison, Seraph Cane
(FunEquipSet.Group.FullSet(166, 1), CharacterWeapon.Int(1001, 13, 1), CharacterWeapon.Empty), // THM, Goetia, Lunaris Rod
(FunEquipSet.Group.FullSet(209, 1), CharacterWeapon.Int(5004, 01, 1), CharacterWeapon.Int(5041, 01, 01)), // CRP, Millkeep's
(FunEquipSet.Group.FullSet(210, 1), CharacterWeapon.Int(5101, 03, 1), CharacterWeapon.Int(5141, 01, 07)), // BSM, Forgekeep's
(FunEquipSet.Group.FullSet(211, 1), CharacterWeapon.Int(5201, 05, 1), CharacterWeapon.Int(5241, 01, 07)), // ARM, Hammerkeep's
(FunEquipSet.Group.FullSet(212, 1), CharacterWeapon.Int(5301, 04, 1), CharacterWeapon.Int(5341, 01, 01)), // GSM, Gemkeep's
(FunEquipSet.Group.FullSet(213, 1), CharacterWeapon.Int(5403, 01, 1), CharacterWeapon.Int(5441, 01, 06)), // LTW, Hidekeep's
(FunEquipSet.Group.FullSet(214, 1), CharacterWeapon.Int(5501, 03, 1), CharacterWeapon.Int(5571, 01, 01)), // WVR, Boltkeep's
(FunEquipSet.Group.FullSet(215, 1), CharacterWeapon.Int(5603, 02, 1), CharacterWeapon.Int(5641, 01, 07)), // ALC, Cauldronkeep's
(FunEquipSet.Group.FullSet(216, 1), CharacterWeapon.Int(5701, 07, 1), CharacterWeapon.Int(5741, 01, 07)), // CUL, Galleykeep's
(FunEquipSet.Group.FullSet(217, 1), CharacterWeapon.Int(7003, 01, 1), CharacterWeapon.Int(7051, 01, 07)), // MIN, Minekeep's
(FunEquipSet.Group.FullSet(218, 1), CharacterWeapon.Int(7101, 07, 1), CharacterWeapon.Int(7151, 01, 07)), // BTN, Fieldkeep's
(FunEquipSet.Group.FullSet(219, 1), CharacterWeapon.Int(7201, 05, 1), CharacterWeapon.Int(7255, 01, 01)), // FSH, Tacklekeep's
(FunEquipSet.Group.FullSet(160, 1), CharacterWeapon.Int(0201, 10, 1), CharacterWeapon.Int(0101, 11, 01)), // PLD, Creed
(FunEquipSet.Group.FullSet(161, 1), CharacterWeapon.Int(0304, 01, 1), CharacterWeapon.Int(0354, 01, 01)), // MNK, Tantra
(FunEquipSet.Group.FullSet(162, 1), CharacterWeapon.Int(0401, 07, 1), CharacterWeapon.Empty), // WAR, Ravager
(FunEquipSet.Group.FullSet(163, 1), CharacterWeapon.Int(0504, 01, 1), CharacterWeapon.Empty), // DRG, Dragonlancer
(FunEquipSet.Group.FullSet(164, 1), CharacterWeapon.Int(0603, 01, 1), CharacterWeapon.Int(0698, 04, 01)), // BRD, Aoidos
(FunEquipSet.Group.FullSet(165, 1), CharacterWeapon.Int(0801, 06, 1), CharacterWeapon.Empty), // WHM, Orison
(FunEquipSet.Group.FullSet(166, 1), CharacterWeapon.Int(1001, 02, 1), CharacterWeapon.Empty), // BLM, Goetia
(FunEquipSet.Group.FullSet(167, 1), CharacterWeapon.Int(1718, 01, 1), CharacterWeapon.Empty), // ACN, Caller, Almandal
(FunEquipSet.Group.FullSet(167, 1), CharacterWeapon.Int(1718, 01, 1), CharacterWeapon.Empty), // SMN, Caller, Almandal
(FunEquipSet.Group.FullSet(168, 1), CharacterWeapon.Int(1701, 14, 1), CharacterWeapon.Empty), // SCH, Savant, Elements
(FunEquipSet.Group.FullSet(169, 1), CharacterWeapon.Int(1801, 29, 1), CharacterWeapon.Int(1851, 29, 01)), // ROG, Iga, Yukimitsu
(FunEquipSet.Group.FullSet(169, 1), CharacterWeapon.Int(1801, 29, 1), CharacterWeapon.Int(1851, 29, 01)), // NIN, Iga, Yukimitsu
(FunEquipSet.Group.FullSet(265, 1), CharacterWeapon.Int(2007, 01, 1), CharacterWeapon.Int(2099, 01, 01)), // MCH, Machinist's, Ferdinant
(FunEquipSet.Group.FullSet(264, 1), CharacterWeapon.Int(1501, 37, 1), CharacterWeapon.Empty), // DRK, Chaos, Deathbringer
(FunEquipSet.Group.FullSet(266, 1), CharacterWeapon.Int(2104, 01, 1), CharacterWeapon.Int(2199, 01, 31)), // AST, Welkin, Atlas
(new FunEquipSet.Group(246, 5, 489, 1, 246, 5, 246, 5, 245, 5), CharacterWeapon.Int(2201, 26, 1), CharacterWeapon.Int(2251, 38, 01)), // SAM, Nameless, Mythrite Uchigatana
(new FunEquipSet.Group(16, 160, 16, 54, 103, 1, 16, 105, 16, 167), CharacterWeapon.Int(2301, 38, 1), CharacterWeapon.Int(2351, 29, 01)), // RDM, Red, Mythrite Rapier
(FunEquipSet.Group.FullSet(593, 1), CharacterWeapon.Int(2401, 01, 1), CharacterWeapon.Empty), // BLU, Magus, Spirit of Whalaqee
(new FunEquipSet.Group(592, 3, 380, 4, 380, 4, 380, 4, 380, 4), CharacterWeapon.Int(2501, 14, 1), CharacterWeapon.Empty), // GNB, Outsider's, High Steel Gunblade
(FunEquipSet.Group.FullSet(204, 4), CharacterWeapon.Int(2601, 13, 1), CharacterWeapon.Int(2651, 13, 01)), // DNC, Softstepper, High Steel Chakrams
(new FunEquipSet.Group(206, 7, 303, 3, 23, 109, 303, 3, 262, 7), CharacterWeapon.Int(2802, 13, 1), CharacterWeapon.Empty), // RPR, Muzhik, Deepgold War Scythe
(new FunEquipSet.Group(20, 46, 289, 6, 342, 3, 120, 9, 342, 3), CharacterWeapon.Int(2702, 08, 1), CharacterWeapon.Empty), // SGE, Bookwyrm, Stonegold Milpreves
};
private static readonly (FunEquipSet.Group, CharacterWeapon, CharacterWeapon)[] _70Artifact =
{
(FunEquipSet.Group.FullSet(000, 0), CharacterWeapon.Empty, CharacterWeapon.Empty), // ADV, Nothing
(FunEquipSet.Group.FullSet(318, 1), CharacterWeapon.Int(0201, 94, 1), CharacterWeapon.Int(0101, 65, 01)), // GLA, Chivalrous, Galatyn, Evalach
(new FunEquipSet.Group(319, 1, 319, 1, 8806, 1, 319, 1, 319, 1), CharacterWeapon.Int(1606, 01, 1), CharacterWeapon.Int(1606, 01, 01)), // PGL, Pacifist's, Sudarshana Chakra
(FunEquipSet.Group.FullSet(320, 1), CharacterWeapon.Int(0401, 63, 1), CharacterWeapon.Empty), // MRD, Brutal, Farsha
(FunEquipSet.Group.FullSet(321, 1), CharacterWeapon.Int(0501, 64, 1), CharacterWeapon.Empty), // LNC, Trueblood, Ryunohige
(FunEquipSet.Group.FullSet(322, 1), CharacterWeapon.Int(0617, 01, 1), CharacterWeapon.Int(0698, 59, 01)), // ARC, Storyteller's, Failnaught
(FunEquipSet.Group.FullSet(323, 1), CharacterWeapon.Int(0810, 01, 1), CharacterWeapon.Empty), // CNJ, Seventh Heaven, Aymur
(FunEquipSet.Group.FullSet(324, 1), CharacterWeapon.Int(1011, 01, 1), CharacterWeapon.Empty), // THM, Seventh Hell, Vanargand
(FunEquipSet.Group.FullSet(443, 1), CharacterWeapon.Int(5005, 01, 1), CharacterWeapon.Int(5041, 01, 05)), // CRP, Millking
(FunEquipSet.Group.FullSet(444, 1), CharacterWeapon.Int(5101, 04, 1), CharacterWeapon.Int(5141, 01, 06)), // BSM, Forgeking
(FunEquipSet.Group.FullSet(445, 1), CharacterWeapon.Int(5201, 06, 1), CharacterWeapon.Int(5241, 01, 06)), // ARM, Hammerking
(FunEquipSet.Group.FullSet(446, 1), CharacterWeapon.Int(5301, 05, 1), CharacterWeapon.Int(5341, 01, 01)), // GSM, Gemking
(FunEquipSet.Group.FullSet(447, 1), CharacterWeapon.Int(5401, 06, 1), CharacterWeapon.Int(5441, 01, 05)), // LTW, Hideking
(FunEquipSet.Group.FullSet(448, 1), CharacterWeapon.Int(5501, 04, 1), CharacterWeapon.Int(5571, 01, 01)), // WVR, Boltking
(FunEquipSet.Group.FullSet(449, 1), CharacterWeapon.Int(5603, 03, 1), CharacterWeapon.Int(5641, 01, 06)), // ALC, Cauldronking
(FunEquipSet.Group.FullSet(450, 1), CharacterWeapon.Int(5701, 07, 1), CharacterWeapon.Int(5741, 01, 05)), // CUL, Galleyking
(FunEquipSet.Group.FullSet(451, 1), CharacterWeapon.Int(7001, 06, 1), CharacterWeapon.Int(7051, 01, 06)), // MIN, Mineking
(FunEquipSet.Group.FullSet(452, 1), CharacterWeapon.Int(7102, 01, 1), CharacterWeapon.Int(7151, 01, 05)), // BTN, Fieldking
(FunEquipSet.Group.FullSet(453, 1), CharacterWeapon.Int(7201, 06, 1), CharacterWeapon.Int(7255, 01, 01)), // FSH, Tackleking
(FunEquipSet.Group.FullSet(318, 1), CharacterWeapon.Int(0201, 94, 1), CharacterWeapon.Int(0101, 65, 01)), // PLD, Chivalrous, Galatyn, Evalach
(new FunEquipSet.Group(319, 1, 319, 1, 8806, 1, 319, 1, 319, 1), CharacterWeapon.Int(1606, 01, 1), CharacterWeapon.Int(0363, 02, 01)), // MNK, Pacifist's, Sudarshana Chakra
(FunEquipSet.Group.FullSet(320, 1), CharacterWeapon.Int(0401, 63, 1), CharacterWeapon.Empty), // WAR, Brutal, Farsha
(FunEquipSet.Group.FullSet(321, 1), CharacterWeapon.Int(0501, 64, 1), CharacterWeapon.Empty), // DRG, Trueblood, Ryunohige
(FunEquipSet.Group.FullSet(322, 1), CharacterWeapon.Int(0617, 01, 1), CharacterWeapon.Int(0698, 59, 01)), // BRD, Storyteller's, Failnaught
(FunEquipSet.Group.FullSet(323, 1), CharacterWeapon.Int(0810, 01, 1), CharacterWeapon.Empty), // WHM, Seventh Heaven, Aymur
(FunEquipSet.Group.FullSet(324, 1), CharacterWeapon.Int(1011, 01, 1), CharacterWeapon.Empty), // BLM, Seventh Hell, Vanargand
(FunEquipSet.Group.FullSet(325, 1), CharacterWeapon.Int(1728, 01, 1), CharacterWeapon.Empty), // ACN, Channeler, Lemegeton
(FunEquipSet.Group.FullSet(325, 1), CharacterWeapon.Int(1728, 01, 1), CharacterWeapon.Empty), // SMN, Channeler, Lemegeton
(FunEquipSet.Group.FullSet(326, 1), CharacterWeapon.Int(1730, 01, 1), CharacterWeapon.Empty), // SCH, Orator, Organum
(FunEquipSet.Group.FullSet(327, 1), CharacterWeapon.Int(1801, 61, 1), CharacterWeapon.Int(1851, 61, 01)), // ROG, Kage-kakushi, Nagi
(FunEquipSet.Group.FullSet(327, 1), CharacterWeapon.Int(1801, 61, 1), CharacterWeapon.Int(1851, 61, 01)), // NIN, Kage-kakushi, Nagi
(FunEquipSet.Group.FullSet(329, 1), CharacterWeapon.Int(2001, 39, 1), CharacterWeapon.Int(2099, 01, 01)), // MCH, Gunner, Outsider
(FunEquipSet.Group.FullSet(328, 1), CharacterWeapon.Int(1501, 60, 1), CharacterWeapon.Empty), // DRK, Abyss, Caladbolg
(FunEquipSet.Group.FullSet(330, 1), CharacterWeapon.Int(2109, 01, 1), CharacterWeapon.Int(2199, 01, 82)), // AST, Constellation, Pleiades
(FunEquipSet.Group.FullSet(377, 1), CharacterWeapon.Int(2201, 12, 1), CharacterWeapon.Int(2254, 01, 01)), // SAM, Myochin, Kiku-Ichimonji
(FunEquipSet.Group.FullSet(378, 1), CharacterWeapon.Int(2301, 01, 1), CharacterWeapon.Int(2351, 01, 01)), // RDM, Duelist, Murgleis
(FunEquipSet.Group.FullSet(655, 1), CharacterWeapon.Int(2401, 01, 2), CharacterWeapon.Empty), // BLU, Mirage, Predatrice
(new FunEquipSet.Group(592, 3, 380, 4, 380, 4, 380, 4, 380, 4), CharacterWeapon.Int(2501, 14, 1), CharacterWeapon.Empty), // GNB, Outsider's, High Steel Gunblade
(FunEquipSet.Group.FullSet(204, 4), CharacterWeapon.Int(2601, 13, 1), CharacterWeapon.Int(2651, 13, 01)), // DNC, Softstepper, High Steel Chakrams
(new FunEquipSet.Group(206, 7, 303, 3, 23, 109, 303, 3, 262, 7), CharacterWeapon.Int(2802, 13, 1), CharacterWeapon.Empty), // RPR, Muzhik, Deepgold War Scythe
(new FunEquipSet.Group(20, 46, 289, 6, 342, 3, 120, 9, 342, 3), CharacterWeapon.Int(2702, 08, 1), CharacterWeapon.Empty), // SGE, Bookwyrm, Stonegold Milpreves
};
private static readonly (FunEquipSet.Group, CharacterWeapon, CharacterWeapon)[] _80Artifact =
{
(FunEquipSet.Group.FullSet(000, 0), CharacterWeapon.Empty, CharacterWeapon.Empty), // ADV, Nothing
(FunEquipSet.Group.FullSet(527, 1), CharacterWeapon.Int(0201, 116, 1), CharacterWeapon.Int(0110, 01, 001)), // GLA, Chevalier, Sequence, Srivatsa
(new FunEquipSet.Group(528, 1, 528, 1, 8812, 1, 528, 1, 528, 1), CharacterWeapon.Int(1601, 003, 1), CharacterWeapon.Int(1651, 03, 001)), // PGL, Bhikku, Godhands
(FunEquipSet.Group.FullSet(529, 1), CharacterWeapon.Int(0401, 090, 1), CharacterWeapon.Empty), // MRD, Boii, Chango
(FunEquipSet.Group.FullSet(530, 1), CharacterWeapon.Int(0501, 082, 1), CharacterWeapon.Empty), // LNC, Pteroslaver, Trishula
(FunEquipSet.Group.FullSet(531, 1), CharacterWeapon.Int(0623, 001, 1), CharacterWeapon.Int(0698, 78, 001)), // ARC, Fili, Fail-Not
(FunEquipSet.Group.FullSet(532, 1), CharacterWeapon.Int(0817, 001, 1), CharacterWeapon.Empty), // CNJ, Ebers, Tishtrya
(FunEquipSet.Group.FullSet(533, 1), CharacterWeapon.Int(1016, 001, 1), CharacterWeapon.Empty), // THM, Wicce, Khatvanga
(FunEquipSet.Group.FullSet(544, 1), CharacterWeapon.Int(5004, 003, 1), CharacterWeapon.Int(5041, 01, 010)), // CRP, Millfiend
(FunEquipSet.Group.FullSet(545, 1), CharacterWeapon.Int(5101, 005, 1), CharacterWeapon.Int(5141, 01, 005)), // BSM, Forgefiend
(FunEquipSet.Group.FullSet(546, 1), CharacterWeapon.Int(5201, 007, 1), CharacterWeapon.Int(5241, 01, 008)), // ARM, Hammerfiend
(FunEquipSet.Group.FullSet(547, 1), CharacterWeapon.Int(5301, 006, 1), CharacterWeapon.Int(5341, 01, 001)), // GSM, Gemfiend
(FunEquipSet.Group.FullSet(548, 1), CharacterWeapon.Int(5401, 007, 1), CharacterWeapon.Int(5441, 01, 007)), // LTW, Hidefiend
(FunEquipSet.Group.FullSet(549, 1), CharacterWeapon.Int(5501, 005, 1), CharacterWeapon.Int(5571, 01, 001)), // WVR, Boltfiend
(FunEquipSet.Group.FullSet(550, 1), CharacterWeapon.Int(5603, 004, 1), CharacterWeapon.Int(5641, 01, 011)), // ALC, Cauldronfiend
(FunEquipSet.Group.FullSet(551, 1), CharacterWeapon.Int(5701, 008, 1), CharacterWeapon.Int(5741, 01, 008)), // CUL, Galleyfiend
(FunEquipSet.Group.FullSet(552, 1), CharacterWeapon.Int(7002, 002, 1), CharacterWeapon.Int(7051, 01, 008)), // MIN, Minefiend
(FunEquipSet.Group.FullSet(553, 1), CharacterWeapon.Int(7101, 008, 1), CharacterWeapon.Int(7151, 01, 008)), // BTN, Fieldfiend
(FunEquipSet.Group.FullSet(554, 1), CharacterWeapon.Int(7201, 007, 1), CharacterWeapon.Int(7255, 01, 001)), // FSH, Tacklefiend
(FunEquipSet.Group.FullSet(527, 1), CharacterWeapon.Int(0201, 116, 1), CharacterWeapon.Int(0110, 01, 001)), // PLD, Chevalier, Sequence, Srivatsa
(new FunEquipSet.Group(528, 1, 528, 1, 8812, 1, 528, 1, 528, 1), CharacterWeapon.Int(1601, 003, 1), CharacterWeapon.Int(1651, 03, 001)), // MNK, Bhikku, Godhands
(FunEquipSet.Group.FullSet(529, 1), CharacterWeapon.Int(0401, 090, 1), CharacterWeapon.Empty), // WAR, Boii, Chango
(FunEquipSet.Group.FullSet(530, 1), CharacterWeapon.Int(0501, 082, 1), CharacterWeapon.Empty), // DRG, Pteroslaver, Trishula
(FunEquipSet.Group.FullSet(531, 1), CharacterWeapon.Int(0623, 001, 1), CharacterWeapon.Int(0698, 78, 001)), // BRD, Fili, Fail-Not
(FunEquipSet.Group.FullSet(532, 1), CharacterWeapon.Int(0817, 001, 1), CharacterWeapon.Empty), // WHM, Ebers, Tishtrya
(FunEquipSet.Group.FullSet(533, 1), CharacterWeapon.Int(1016, 001, 1), CharacterWeapon.Empty), // BLM, Wicce, Khatvanga
(FunEquipSet.Group.FullSet(534, 1), CharacterWeapon.Int(1708, 002, 1), CharacterWeapon.Empty), // ACN, Beckoner, Meteorologica
(FunEquipSet.Group.FullSet(534, 1), CharacterWeapon.Int(1708, 002, 1), CharacterWeapon.Empty), // SMN, Beckoner, Meteorologica
(FunEquipSet.Group.FullSet(535, 1), CharacterWeapon.Int(1736, 001, 1), CharacterWeapon.Empty), // SCH, Arbatel, Physica
(FunEquipSet.Group.FullSet(536, 1), CharacterWeapon.Int(1801, 083, 1), CharacterWeapon.Int(1851, 83, 001)), // ROG, Hattori, Heishi Shorinken
(FunEquipSet.Group.FullSet(536, 1), CharacterWeapon.Int(1801, 083, 1), CharacterWeapon.Int(1851, 83, 001)), // NIN, Hattori, Heishi Shorinken
(FunEquipSet.Group.FullSet(538, 1), CharacterWeapon.Int(2001, 060, 1), CharacterWeapon.Int(2099, 01, 001)), // MCH, Gunslinger, Fomalhaut
(FunEquipSet.Group.FullSet(537, 1), CharacterWeapon.Int(1501, 074, 1), CharacterWeapon.Empty), // DRK, Bale, Shadowbringer
(FunEquipSet.Group.FullSet(539, 1), CharacterWeapon.Int(2117, 001, 1), CharacterWeapon.Int(2199, 01, 118)), // AST, Soothsayer, Procyon
(FunEquipSet.Group.FullSet(540, 1), CharacterWeapon.Int(2201, 043, 1), CharacterWeapon.Int(2251, 61, 001)), // SAM, Kasuga, Dojikiri Yasutsuna
(FunEquipSet.Group.FullSet(541, 1), CharacterWeapon.Int(2301, 055, 1), CharacterWeapon.Int(2351, 38, 001)), // RDM, Estoqueur, Aeneas
(FunEquipSet.Group.FullSet(811, 1), CharacterWeapon.Int(2401, 005, 1), CharacterWeapon.Empty), // BLU, Phantasmal, Blue-eyes
(FunEquipSet.Group.FullSet(542, 1), CharacterWeapon.Int(2505, 001, 1), CharacterWeapon.Empty), // GNB, Bodyguard, Lion Heart
(FunEquipSet.Group.FullSet(543, 1), CharacterWeapon.Int(2601, 001, 1), CharacterWeapon.Int(2651, 01, 001)), // DNC, Dancer, Krishna
(new FunEquipSet.Group(206, 7, 303, 3, 23, 109, 303, 3, 262, 7), CharacterWeapon.Int(2802, 013, 1), CharacterWeapon.Empty), // RPR, Harvester's, Demon Slicer
(new FunEquipSet.Group(20, 46, 289, 6, 342, 3, 120, 9, 342, 3), CharacterWeapon.Int(2702, 008, 1), CharacterWeapon.Empty), // SGE, Therapeute's, Horkos
};
private static readonly (FunEquipSet.Group, CharacterWeapon, CharacterWeapon)[] _90Artifact =
{
(FunEquipSet.Group.FullSet(000, 0), CharacterWeapon.Empty, CharacterWeapon.Empty), // ADV, Nothing
(FunEquipSet.Group.FullSet(678, 1), CharacterWeapon.Int(0201, 134, 1), CharacterWeapon.Int(0101, 100, 001)), // GLA, Reverence, Lightbringer, Hero's Shield
(new FunEquipSet.Group(679, 1, 679, 1, 8816, 1, 679, 1, 679, 1), CharacterWeapon.Int(1601, 007, 1), CharacterWeapon.Int(1651, 007, 001)), // PGL, Anchorite, Burning Fists
(FunEquipSet.Group.FullSet(680, 1), CharacterWeapon.Int(0401, 111, 1), CharacterWeapon.Empty), // MRD, Pummeler, Gigantaxe
(FunEquipSet.Group.FullSet(681, 1), CharacterWeapon.Int(0501, 105, 1), CharacterWeapon.Empty), // LNC, Tiamat, Abel's Lance
(FunEquipSet.Group.FullSet(682, 1), CharacterWeapon.Int(0629, 001, 1), CharacterWeapon.Int(0698, 102, 001)), // ARC, Brioso, Perseus's Bow
(FunEquipSet.Group.FullSet(683, 1), CharacterWeapon.Int(0801, 084, 1), CharacterWeapon.Empty), // CNJ, Theophany, Xoanon
(FunEquipSet.Group.FullSet(684, 1), CharacterWeapon.Int(1025, 001, 1), CharacterWeapon.Empty), // THM, Spaekona, Asura's Rod
(FunEquipSet.Group.FullSet(697, 1), CharacterWeapon.Int(5004, 005, 1), CharacterWeapon.Int(5041, 001, 010)), // CRP, Millsoph
(FunEquipSet.Group.FullSet(698, 1), CharacterWeapon.Int(5101, 007, 1), CharacterWeapon.Int(5141, 001, 005)), // BSM, Forgesoph
(FunEquipSet.Group.FullSet(699, 1), CharacterWeapon.Int(5201, 009, 1), CharacterWeapon.Int(5241, 001, 008)), // ARM, Hammersoph
(FunEquipSet.Group.FullSet(700, 1), CharacterWeapon.Int(5301, 008, 1), CharacterWeapon.Int(5341, 001, 001)), // GSM, Gemsoph
(FunEquipSet.Group.FullSet(701, 1), CharacterWeapon.Int(5401, 009, 1), CharacterWeapon.Int(5441, 001, 007)), // LTW, Hidesoph
(FunEquipSet.Group.FullSet(702, 1), CharacterWeapon.Int(5501, 007, 1), CharacterWeapon.Int(5571, 001, 001)), // WVR, Boltsoph
(FunEquipSet.Group.FullSet(703, 1), CharacterWeapon.Int(5603, 006, 1), CharacterWeapon.Int(5641, 001, 011)), // ALC, Cauldronsoph
(FunEquipSet.Group.FullSet(704, 1), CharacterWeapon.Int(5701, 010, 1), CharacterWeapon.Int(5741, 001, 008)), // CUL, Galleysoph
(FunEquipSet.Group.FullSet(705, 1), CharacterWeapon.Int(7002, 009, 1), CharacterWeapon.Int(7051, 001, 008)), // MIN, Minesoph
(FunEquipSet.Group.FullSet(706, 1), CharacterWeapon.Int(7101, 008, 1), CharacterWeapon.Int(7151, 001, 008)), // BTN, Fieldsoph
(FunEquipSet.Group.FullSet(707, 1), CharacterWeapon.Int(7201, 009, 1), CharacterWeapon.Int(7255, 001, 001)), // FSH, Tacklesoph
(FunEquipSet.Group.FullSet(678, 1), CharacterWeapon.Int(0201, 134, 1), CharacterWeapon.Int(0101, 100, 001)), // PLD, Reverence, Lightbringer, Hero's Shield
(new FunEquipSet.Group(679, 1, 679, 1, 8816, 1, 679, 1, 679, 1), CharacterWeapon.Int(1601, 007, 1), CharacterWeapon.Int(1651, 007, 001)), // MNK, Anchorite, Burning Fists
(FunEquipSet.Group.FullSet(680, 1), CharacterWeapon.Int(0401, 111, 1), CharacterWeapon.Empty), // WAR, Pummeler, Gigantaxe
(FunEquipSet.Group.FullSet(681, 1), CharacterWeapon.Int(0501, 105, 1), CharacterWeapon.Empty), // DRG, Tiamat, Abel's Lance
(FunEquipSet.Group.FullSet(682, 1), CharacterWeapon.Int(0629, 001, 1), CharacterWeapon.Int(0698, 102, 001)), // BRD, Brioso, Perseus's Bow
(FunEquipSet.Group.FullSet(683, 1), CharacterWeapon.Int(0801, 084, 1), CharacterWeapon.Empty), // WHM, Theophany, Xoanon
(FunEquipSet.Group.FullSet(684, 1), CharacterWeapon.Int(1025, 001, 1), CharacterWeapon.Empty), // BLM, Spaekona, Asura's Rod
(FunEquipSet.Group.FullSet(685, 1), CharacterWeapon.Int(1701, 096, 1), CharacterWeapon.Empty), // ACN, Convoker, Abraxas
(FunEquipSet.Group.FullSet(685, 1), CharacterWeapon.Int(1701, 096, 1), CharacterWeapon.Empty), // SMN, Convoker, Abraxas
(FunEquipSet.Group.FullSet(686, 1), CharacterWeapon.Int(1701, 099, 1), CharacterWeapon.Empty), // SCH, Academic, Epeolatry
(FunEquipSet.Group.FullSet(687, 1), CharacterWeapon.Int(1801, 104, 1), CharacterWeapon.Int(1851, 104, 001)), // ROG, Hachiya, Mutsunokami
(FunEquipSet.Group.FullSet(687, 1), CharacterWeapon.Int(1801, 104, 1), CharacterWeapon.Int(1851, 104, 001)), // NIN, Hachiya, Mutsunokami
(FunEquipSet.Group.FullSet(689, 1), CharacterWeapon.Int(2001, 080, 1), CharacterWeapon.Int(2099, 001, 001)), // MCH, Pioneer, Ataktos
(FunEquipSet.Group.FullSet(688, 1), CharacterWeapon.Int(1501, 103, 1), CharacterWeapon.Empty), // DRK, Ignominy, Chaosbringer
(FunEquipSet.Group.FullSet(690, 1), CharacterWeapon.Int(2101, 082, 1), CharacterWeapon.Int(2199, 001, 149)), // AST, Astronomia, Diana
(FunEquipSet.Group.FullSet(691, 1), CharacterWeapon.Int(2201, 064, 1), CharacterWeapon.Int(2251, 082, 001)), // SAM, Saotome, Murasame
(FunEquipSet.Group.FullSet(692, 1), CharacterWeapon.Int(2305, 004, 1), CharacterWeapon.Int(2351, 064, 001)), // RDM, Atrophy, Wild Rose
(FunEquipSet.Group.FullSet(811, 1), CharacterWeapon.Int(2401, 005, 1), CharacterWeapon.Empty), // BLU, Phantasmal, Blue-eyes
(FunEquipSet.Group.FullSet(693, 1), CharacterWeapon.Int(2501, 044, 1), CharacterWeapon.Empty), // GNB, Allegiance, Hyperion
(FunEquipSet.Group.FullSet(694, 1), CharacterWeapon.Int(2607, 001, 1), CharacterWeapon.Int(2657, 001, 001)), // DNC, Etoile, Terpsichore
(FunEquipSet.Group.FullSet(695, 1), CharacterWeapon.Int(2801, 001, 1), CharacterWeapon.Empty), // RPR, Reaper, Death Sickle
(FunEquipSet.Group.FullSet(696, 1), CharacterWeapon.Int(2701, 006, 1), CharacterWeapon.Empty), // SGE, Didact, Hagneia
};
// @formatter:on
private (FunEquipSet.Group, CharacterWeapon, CharacterWeapon)? GetGroup(byte level, byte job, Race race, Gender gender, Random rng)
{
const int weight50 = 1200;
const int weight60 = 1500;
const int weight70 = 1700;
const int weight80 = 1800;
const int weight90 = 1900;
const int weight100 = 2000;
if (job >= StarterWeapons.Length)
return null;
var maxWeight = level switch
{
< 50 => weight50,
< 60 => weight60,
< 70 => weight70,
< 80 => weight80,
< 90 => weight90,
_ => weight100,
};
var weight = rng.Next(0, maxWeight + 1);
if (weight < weight50)
{
var (main, off) = StarterWeapons[job];
if (!Starter.TryGetValue((gender, race), out var group))
return null;
return (group, main, off);
}
var list = weight switch
{
< weight60 => _50Artifact,
< weight70 => _60Artifact,
< weight80 => _70Artifact,
< weight90 => _80Artifact,
_ => _90Artifact,
};
Glamourer.Log.Verbose($"Chose weight {weight}/{maxWeight} for World set [Character: {level} {job} {race} {gender}].");
return list[job];
}
private unsafe (byte, byte, Race, Gender) GetData(Actor actor)
{
var customize = actor.GetCustomize();
return (actor.AsCharacter->CharacterData.Level, actor.Job, customize.Race, customize.Gender);
}
public void Apply(Actor actor, Random rng, Span<CharacterArmor> armor)
{
var (level, job, race, gender) = GetData(actor);
Apply(level, job, race, gender, rng, armor);
}
public void Apply(byte level, byte job, Race race, Gender gender, Random rng, Span<CharacterArmor> armor)
{
var opt = GetGroup(level, job, race, gender, rng);
if (opt == null)
return;
armor[0] = opt.Value.Item1.Head;
armor[1] = opt.Value.Item1.Body;
armor[2] = opt.Value.Item1.Hands;
armor[3] = opt.Value.Item1.Legs;
armor[4] = opt.Value.Item1.Feet;
}
public void Apply(Actor actor, Random rng, ref CharacterArmor armor, EquipSlot slot)
{
var (level, job, race, gender) = GetData(actor);
Apply(level, job, race, gender, rng, ref armor, slot);
}
public void Apply(byte level, byte job, Race race, Gender gender, Random rng, ref CharacterArmor armor, EquipSlot slot)
{
var opt = GetGroup(level, job, race, gender, rng);
if (opt == null)
return;
armor = slot switch
{
EquipSlot.Head => opt.Value.Item1.Head,
EquipSlot.Body => opt.Value.Item1.Body,
EquipSlot.Hands => opt.Value.Item1.Hands,
EquipSlot.Legs => opt.Value.Item1.Legs,
EquipSlot.Feet => opt.Value.Item1.Feet,
_ => armor,
};
}
public void Apply(Actor actor, Random rng, ref CharacterWeapon weapon, EquipSlot slot)
{
var (level, job, race, gender) = GetData(actor);
Apply(level, job, race, gender, rng, ref weapon, slot);
}
public void Apply(byte level, byte job, Race race, Gender gender, Random rng, ref CharacterWeapon weapon, EquipSlot slot)
{
var opt = GetGroup(level, job, race, gender, rng);
if (opt == null)
return;
weapon = slot switch
{
EquipSlot.MainHand => opt.Value.Item2,
EquipSlot.BothHand => opt.Value.Item2,
EquipSlot.OffHand => opt.Value.Item3,
_ => weapon,
};
}
}

@ -1 +1 @@
Subproject commit d463e6747c10f4981077f217f86432fc9b0c7acc Subproject commit 64fe8c348dda8aed2e2e3c0dd1864501bfb4be85