mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2025-12-12 18:27:24 +01:00
Add some codes.
This commit is contained in:
parent
5460ffd0a0
commit
3a63a1b22d
3 changed files with 165 additions and 23 deletions
|
|
@ -78,8 +78,8 @@ public class NpcCustomizeSet : IAsyncDataContainer, IReadOnlyList<NpcData>
|
|||
};
|
||||
|
||||
// Event NPCs have a reference to NpcEquip but also contain the appearance in their own row.
|
||||
// Prefer the NpcEquip reference if it is set, otherwise use the own.
|
||||
if (row.NpcEquip.Row != 0 && row.NpcEquip.Value is { } equip)
|
||||
// Prefer the NpcEquip reference if it is set and the own does not appear to be set, otherwise use the own.
|
||||
if (row.NpcEquip.Row != 0 && row.NpcEquip.Value is { } equip && row is { ModelBody: 0, ModelLegs: 0 })
|
||||
ApplyNpcEquip(ref ret, equip);
|
||||
else
|
||||
ApplyNpcEquip(ref ret, row);
|
||||
|
|
|
|||
|
|
@ -30,13 +30,19 @@ public class CodeService
|
|||
Elephants = 0x020000,
|
||||
Crown = 0x040000,
|
||||
Dolphins = 0x080000,
|
||||
Face = 0x100000,
|
||||
Manderville = 0x200000,
|
||||
Smiles = 0x400000,
|
||||
}
|
||||
|
||||
public static readonly CodeFlag AllHintCodes =
|
||||
Enum.GetValues<CodeFlag>().Where(f => GetData(f).Display).Aggregate((CodeFlag)0, (f1, f2) => f1 | f2);
|
||||
|
||||
public const CodeFlag DyeCodes = CodeFlag.Clown | CodeFlag.World | CodeFlag.Elephants | CodeFlag.Dolphins;
|
||||
public const CodeFlag GearCodes = CodeFlag.Emperor | CodeFlag.World | CodeFlag.Elephants | CodeFlag.Dolphins;
|
||||
public const CodeFlag DyeCodes =
|
||||
CodeFlag.Clown | CodeFlag.World | CodeFlag.Elephants | CodeFlag.Dolphins;
|
||||
|
||||
public const CodeFlag GearCodes =
|
||||
CodeFlag.Emperor | CodeFlag.World | CodeFlag.Elephants | CodeFlag.Dolphins;
|
||||
|
||||
public const CodeFlag RaceCodes = CodeFlag.OopsHyur
|
||||
| CodeFlag.OopsElezen
|
||||
|
|
@ -46,6 +52,8 @@ public class CodeService
|
|||
| CodeFlag.OopsAuRa
|
||||
| CodeFlag.OopsHrothgar;
|
||||
|
||||
public const CodeFlag FullCodes = CodeFlag.Face | CodeFlag.Manderville | CodeFlag.Smiles;
|
||||
|
||||
public const CodeFlag SizeCodes = CodeFlag.Dwarf | CodeFlag.Giant;
|
||||
|
||||
private CodeFlag _enabled;
|
||||
|
|
@ -161,26 +169,29 @@ public class CodeService
|
|||
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.Clown => (FullCodes | DyeCodes) & ~CodeFlag.Clown,
|
||||
CodeFlag.Emperor => (FullCodes | GearCodes) & ~CodeFlag.Emperor,
|
||||
CodeFlag.Individual => FullCodes,
|
||||
CodeFlag.Dwarf => (FullCodes | SizeCodes) & ~CodeFlag.Dwarf,
|
||||
CodeFlag.Giant => (FullCodes | SizeCodes) & ~CodeFlag.Giant,
|
||||
CodeFlag.OopsHyur => (FullCodes | RaceCodes) & ~CodeFlag.OopsHyur,
|
||||
CodeFlag.OopsElezen => (FullCodes | RaceCodes) & ~CodeFlag.OopsElezen,
|
||||
CodeFlag.OopsLalafell => (FullCodes | RaceCodes) & ~CodeFlag.OopsLalafell,
|
||||
CodeFlag.OopsMiqote => (FullCodes | RaceCodes) & ~CodeFlag.OopsMiqote,
|
||||
CodeFlag.OopsRoegadyn => (FullCodes | RaceCodes) & ~CodeFlag.OopsRoegadyn,
|
||||
CodeFlag.OopsAuRa => (FullCodes | RaceCodes) & ~CodeFlag.OopsAuRa,
|
||||
CodeFlag.OopsHrothgar => (FullCodes | RaceCodes) & ~CodeFlag.OopsHrothgar,
|
||||
CodeFlag.OopsViera => (FullCodes | RaceCodes) & ~CodeFlag.OopsViera,
|
||||
CodeFlag.Artisan => 0,
|
||||
CodeFlag.SixtyThree => 0,
|
||||
CodeFlag.SixtyThree => FullCodes,
|
||||
CodeFlag.Shirts => 0,
|
||||
CodeFlag.World => (DyeCodes | GearCodes) & ~CodeFlag.World,
|
||||
CodeFlag.Elephants => (DyeCodes | GearCodes) & ~CodeFlag.Elephants,
|
||||
CodeFlag.Crown => 0,
|
||||
CodeFlag.Dolphins => (DyeCodes | GearCodes) & ~CodeFlag.Dolphins,
|
||||
CodeFlag.World => (FullCodes | DyeCodes | GearCodes) & ~CodeFlag.World,
|
||||
CodeFlag.Elephants => (FullCodes | DyeCodes | GearCodes) & ~CodeFlag.Elephants,
|
||||
CodeFlag.Crown => FullCodes,
|
||||
CodeFlag.Dolphins => (FullCodes | DyeCodes | GearCodes) & ~CodeFlag.Dolphins,
|
||||
CodeFlag.Face => (FullCodes | RaceCodes | SizeCodes | GearCodes | DyeCodes | CodeFlag.Crown | CodeFlag.SixtyThree) & ~CodeFlag.Face,
|
||||
CodeFlag.Manderville => (FullCodes | RaceCodes | SizeCodes | GearCodes | DyeCodes | CodeFlag.Crown | CodeFlag.SixtyThree) & ~CodeFlag.Manderville,
|
||||
CodeFlag.Smiles => (FullCodes | RaceCodes | SizeCodes | GearCodes | DyeCodes | CodeFlag.Crown | CodeFlag.SixtyThree) & ~CodeFlag.Smiles,
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
|
|
@ -207,6 +218,9 @@ public class CodeService
|
|||
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 ],
|
||||
CodeFlag.Crown => [ 0x43, 0x8E, 0x34, 0x56, 0x24, 0xC9, 0xC6, 0xDE, 0x2A, 0x68, 0x3A, 0x5D, 0xF5, 0x8E, 0xCB, 0xEF, 0x0D, 0x4D, 0x5B, 0xDC, 0x23, 0xF9, 0xF9, 0xBD, 0xD9, 0x60, 0xAD, 0x53, 0xC5, 0xA0, 0x33, 0xC4 ],
|
||||
CodeFlag.Dolphins => [ 0x64, 0xC6, 0x2E, 0x7C, 0x22, 0x3A, 0x42, 0xF5, 0xC3, 0x93, 0x4F, 0x70, 0x1F, 0xFD, 0xFA, 0x3C, 0x98, 0xD2, 0x7C, 0xD8, 0x88, 0xA7, 0x3D, 0x1D, 0x0D, 0xD6, 0x70, 0x15, 0x28, 0x2E, 0x79, 0xE7 ],
|
||||
CodeFlag.Face => [ 0xCA, 0x97, 0x81, 0x12, 0xCA, 0x1B, 0xBD, 0xCA, 0xFA, 0xC2, 0x31, 0xB3, 0x9A, 0x23, 0xDC, 0x4D, 0xA7, 0x86, 0xEF, 0xF8, 0x14, 0x7C, 0x4E, 0x72, 0xB9, 0x80, 0x77, 0x85, 0xAF, 0xEE, 0x48, 0xBB ],
|
||||
CodeFlag.Manderville => [ 0x3E, 0x23, 0xE8, 0x16, 0x00, 0x39, 0x59, 0x4A, 0x33, 0x89, 0x4F, 0x65, 0x64, 0xE1, 0xB1, 0x34, 0x8B, 0xBD, 0x7A, 0x00, 0x88, 0xD4, 0x2C, 0x4A, 0xCB, 0x73, 0xEE, 0xAE, 0xD5, 0x9C, 0x00, 0x9D ],
|
||||
CodeFlag.Smiles => [ 0x2E, 0x7D, 0x2C, 0x03, 0xA9, 0x50, 0x7A, 0xE2, 0x65, 0xEC, 0xF5, 0xB5, 0x35, 0x68, 0x85, 0xA5, 0x33, 0x93, 0xA2, 0x02, 0x9D, 0x24, 0x13, 0x94, 0x99, 0x72, 0x65, 0xA1, 0xA2, 0x5A, 0xEF, 0xC6 ],
|
||||
_ => [],
|
||||
};
|
||||
|
||||
|
|
@ -233,6 +247,9 @@ public class CodeService
|
|||
CodeFlag.Crown => (true, 1, ".", "A famous Shakespearean line.", "Sets every player with a mentor symbol enabled to the clown's hat."),
|
||||
CodeFlag.Dolphins => (true, 5, ",", "The farewell of the second smartest species on Earth.", "Sets every player to a Namazu hat with different costume bodies."),
|
||||
CodeFlag.Artisan => (false, 3, ",,!", string.Empty, "Enable a debugging mode for the UI. Not really useful."),
|
||||
CodeFlag.Face => (false, 3, ",,!", string.Empty, "Enable a debugging mode for the UI. Not really useful."),
|
||||
CodeFlag.Manderville => (false, 3, ",,!", string.Empty, "Enable a debugging mode for the UI. Not really useful."),
|
||||
CodeFlag.Smiles => (false, 3, ",,!", string.Empty, "Enable a debugging mode for the UI. Not really useful."),
|
||||
_ => (false, 0, string.Empty, string.Empty, string.Empty),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using Dalamud.Interface.ImGuiNotification;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
||||
using Glamourer.Designs;
|
||||
using Glamourer.GameData;
|
||||
using Glamourer.Gui;
|
||||
using Glamourer.Services;
|
||||
using ImGuiNET;
|
||||
|
|
@ -35,6 +36,7 @@ public unsafe class FunModule : IDisposable
|
|||
private readonly DesignConverter _designConverter;
|
||||
private readonly DesignManager _designManager;
|
||||
private readonly ObjectManager _objects;
|
||||
private readonly NpcCustomizeSet _npcs;
|
||||
private readonly StainId[] _stains;
|
||||
|
||||
public FestivalType CurrentFestival { get; private set; } = FestivalType.None;
|
||||
|
|
@ -68,7 +70,7 @@ public unsafe class FunModule : IDisposable
|
|||
|
||||
public FunModule(CodeService codes, CustomizeService customizations, ItemManager items, Configuration config,
|
||||
GenericPopupWindow popupWindow, StateManager stateManager, ObjectManager objects, DesignConverter designConverter,
|
||||
DesignManager designManager)
|
||||
DesignManager designManager, NpcCustomizeSet npcs)
|
||||
{
|
||||
_codes = codes;
|
||||
_customizations = customizations;
|
||||
|
|
@ -79,6 +81,7 @@ public unsafe class FunModule : IDisposable
|
|||
_objects = objects;
|
||||
_designConverter = designConverter;
|
||||
_designManager = designManager;
|
||||
_npcs = npcs;
|
||||
_rng = new Random();
|
||||
_stains = _items.Stains.Keys.Prepend((StainId)0).ToArray();
|
||||
ResetFestival();
|
||||
|
|
@ -102,6 +105,15 @@ public unsafe class FunModule : IDisposable
|
|||
return;
|
||||
}
|
||||
|
||||
switch (_codes.Masked(CodeService.FullCodes))
|
||||
{
|
||||
case CodeService.CodeFlag.Face:
|
||||
case CodeService.CodeFlag.Manderville:
|
||||
case CodeService.CodeFlag.Smiles:
|
||||
KeepOldArmor(actor, slot, ref armor);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_codes.Enabled(CodeService.CodeFlag.Crown)
|
||||
&& actor.OnlineStatus is OnlineStatus.PvEMentor or OnlineStatus.PvPMentor or OnlineStatus.TradeMentor
|
||||
&& slot.IsEquipment())
|
||||
|
|
@ -130,11 +142,124 @@ public unsafe class FunModule : IDisposable
|
|||
}
|
||||
}
|
||||
|
||||
private sealed class PrioritizedList<T> : List<(T Item, int Priority)>
|
||||
{
|
||||
private int _cumulative;
|
||||
|
||||
public PrioritizedList(params (T Item, int Priority)[] list)
|
||||
{
|
||||
if (list.Length == 0)
|
||||
return;
|
||||
|
||||
AddRange(list.Where(p => p.Priority > 0).OrderByDescending(p => p.Priority).Select(p => (p.Item, _cumulative += p.Priority)));
|
||||
}
|
||||
|
||||
public T GetRandom(Random rng)
|
||||
{
|
||||
var val = rng.Next(0, _cumulative);
|
||||
foreach (var (item, priority) in this)
|
||||
{
|
||||
if (val < priority)
|
||||
return item;
|
||||
}
|
||||
|
||||
// Should never happen.
|
||||
return this[^1].Item1;
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly PrioritizedList<NpcId> MandervilleMale = new
|
||||
(
|
||||
(1008264, 30), // Hildi
|
||||
(1008731, 10), // Hildi, slightly damaged
|
||||
(1011668, 3), // Zombi
|
||||
(1016617, 5), // Hildi, heavily damaged
|
||||
(1042518, 1), // Hildi of Light
|
||||
(1006339, 2), // Godbert, naked
|
||||
(1008734, 10), // Godbert, shorts
|
||||
(1015921, 5), // Godbert, ripped
|
||||
(1041606, 5), // Godbert, only shorts
|
||||
(1041605, 5), // Godbert, summer
|
||||
(1024501, 30), // Godbert, fully clothed
|
||||
(1045184, 3), // Godbrand
|
||||
(1044749, 1) // Brandihild
|
||||
);
|
||||
|
||||
private static readonly PrioritizedList<NpcId> MandervilleFemale = new
|
||||
(
|
||||
(1025669, 5), // Hildi, Geisha
|
||||
(1025670, 2), // Hildi, makeup, black
|
||||
(1042477, 2), // Hildi, makeup, white
|
||||
(1016798, 20), // Julyan, Winter
|
||||
(1011707, 30), // Julyan
|
||||
(1005714, 20), // Nashu
|
||||
(1025668, 5), // Nashu, Kimono
|
||||
(1025674, 5), // Nashu, fancy
|
||||
(1042486, 30), // Nashu, inspector
|
||||
(1017263, 3), // Gigi
|
||||
(1017263, 1) // Gigi, buff
|
||||
);
|
||||
|
||||
private static readonly PrioritizedList<NpcId> Smile = new
|
||||
(
|
||||
(1046504, 75), // Normal
|
||||
(1046501, 20), // Hat
|
||||
(1050613, 4), // Armor
|
||||
(1047625, 1) // Elephant
|
||||
);
|
||||
|
||||
private static readonly PrioritizedList<NpcId> FaceMale = new
|
||||
(
|
||||
(1016136, 35), // Gerolt
|
||||
(1032667, 2), // Gerolt, Suit
|
||||
(1030519, 35), // Grenoldt
|
||||
(1030519, 20), // Grenoldt, Short
|
||||
(1046262, 2), // Grenoldt, Suit
|
||||
(1048084, 15) // Genolt
|
||||
);
|
||||
|
||||
private static readonly PrioritizedList<NpcId> FaceFemale = new
|
||||
(
|
||||
(1013713, 10), // Rowena, Togi
|
||||
(1018496, 30), // Rowena, Poncho
|
||||
(1032668, 2), // Rowena, Gown
|
||||
(1042857, 10), // Rowena, Hannish
|
||||
(1046255, 10), // Mowen, Miner
|
||||
(1046263, 2), // Mowen, Gown
|
||||
(1027544, 30), // Mowen, Bustle
|
||||
(1049088, 15) // Rhodina
|
||||
);
|
||||
|
||||
private bool ApplyFullCode(Actor actor, Span<CharacterArmor> armor, ref CustomizeArray customize)
|
||||
{
|
||||
var id = _codes.Masked(CodeService.FullCodes) switch
|
||||
{
|
||||
CodeService.CodeFlag.Face when customize.Gender is Gender.Female && actor.Index != 0 => FaceFemale.GetRandom(_rng),
|
||||
CodeService.CodeFlag.Face when actor.Index != 0 => FaceFemale.GetRandom(_rng),
|
||||
CodeService.CodeFlag.Smiles => Smile.GetRandom(_rng),
|
||||
CodeService.CodeFlag.Manderville when customize.Gender is Gender.Female => MandervilleFemale.GetRandom(_rng),
|
||||
CodeService.CodeFlag.Manderville => MandervilleMale.GetRandom(_rng),
|
||||
_ => (NpcId)0,
|
||||
};
|
||||
|
||||
if (id.Id == 0 || !_npcs.FindFirst(n => n.Id == id, out var npc))
|
||||
return false;
|
||||
|
||||
customize = npc.Customize;
|
||||
var idx = 0;
|
||||
foreach (ref var a in armor)
|
||||
a = npc.Equip[idx++];
|
||||
return true;
|
||||
}
|
||||
|
||||
public void ApplyFunOnLoad(Actor actor, Span<CharacterArmor> armor, ref CustomizeArray customize)
|
||||
{
|
||||
if (!ValidFunTarget(actor))
|
||||
return;
|
||||
|
||||
if (ApplyFullCode(actor, armor, ref customize))
|
||||
return;
|
||||
|
||||
// First set the race, if any.
|
||||
SetRace(ref customize);
|
||||
// Now apply the gender.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue