diff --git a/Dalamud/Fools/FoolsManager.cs b/Dalamud/Fools/FoolsManager.cs index 3e74080df..8297bead3 100644 --- a/Dalamud/Fools/FoolsManager.cs +++ b/Dalamud/Fools/FoolsManager.cs @@ -77,8 +77,8 @@ internal class FoolsManager : IDisposable, IServiceType { new("Pixel Imperfect", "PixelImperfectPlugin", "Whoops... we messed up the math on that one.", "Halpo", typeof(PixelImperfectPlugin)), - new("DailyLifeDuty", "DailyLifeDutyPlugin", "Easily Track Daily and Weekly tasks... in real life", - "MidoriKami", typeof(DailyLifeDutyPlugin)), + new("DailyLifeDuty", "DailyLifeDutyPlugin", "Easily Track Daily and Weekly tasks... in real life", "MidoriKami", typeof(DailyLifeDutyPlugin)), + new("Oops, Maybe Lalafells!", "OopsMaybeLalafellsPlugin", "Turn everyone into Lalafells? Maybe. We haven't quite tested it yet.", "Chrip", typeof(OopsMaybeLalafells)) }; } diff --git a/Dalamud/Fools/Plugins/OopsMaybeLalafellsPlugin.cs b/Dalamud/Fools/Plugins/OopsMaybeLalafellsPlugin.cs new file mode 100644 index 000000000..b8f5f4f6e --- /dev/null +++ b/Dalamud/Fools/Plugins/OopsMaybeLalafellsPlugin.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; + +using Dalamud.Game; +using Dalamud.Game.ClientState.Objects; +using Dalamud.Game.ClientState.Objects.Enums; +using Dalamud.Hooking; + +using FFXIVClientStructs.FFXIV.Client.Game.Object; + +namespace Dalamud.Fools.Plugins; + +public class OopsMaybeLalafells : IFoolsPlugin +{ + // Plugin + + public OopsMaybeLalafells() + { + var scanner = Service.Get(); + var addr = scanner.ScanText(SetupCharacterSig); + SetupCharacterHook = Hook.FromAddress(addr, SetupCharacterDetour); + SetupCharacterHook.Enable(); + RedrawAll(); + } + + public void Dispose() + { + SetupCharacterHook.Disable(); + SetupCharacterHook.Dispose(); + RedrawAll(); + } + + private unsafe void RedrawAll() + { + Service.Get().RunOnFrameworkThread(() => { + var objects = Service.Get(); + foreach (var obj in objects) + { + if (obj.ObjectIndex > 241) break; + + var csObject = (GameObject*)obj.Address; + if (csObject == null) continue; + + csObject->DisableDraw(); + csObject->EnableDraw(); + } + }); + } + + // The Lalafellinator + + private readonly Random Rng = new(); + + private readonly List ReplaceIDs = new() { 84, 85, 86, 87, 88, 89, 90, 91, 257, 258, 581, 597, 744 }; + + private const string SetupCharacterSig = "E8 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? 48 8B D7 E8 ?? ?? ?? ?? 48 8B CF E8 ?? ?? ?? ?? 48 8B C7"; + + private delegate char SetupCharacterDelegate(nint a1, nint a2); + private Hook SetupCharacterHook = null!; + + private unsafe char SetupCharacterDetour(nint a1, nint a2) + { + // Roll the dice + if (Rng.Next(0, 4) == 0) + { + var customize = (byte*)a2; + customize[(int)CustomizeIndex.Race] = 3; + + var face = customize + (int)CustomizeIndex.FaceType; + *face = (byte)(1 + ((*face - 1) % 4)); + + var equipTar = (ushort)(customize[(int)CustomizeIndex.Gender] == 0 ? 92 : 93); + for (var i = 1; i < 5; i++) + { + var equip = (ushort*)(a2 + 28 + (i * 4)); + if (ReplaceIDs.Contains(*equip)) + *equip = equipTar; + } + } + + return SetupCharacterHook.Original(a1, a2); + } +} diff --git a/lib/FFXIVClientStructs b/lib/FFXIVClientStructs index 74345c974..9e97396f9 160000 --- a/lib/FFXIVClientStructs +++ b/lib/FFXIVClientStructs @@ -1 +1 @@ -Subproject commit 74345c97468f310d555929f4e40c844556bc64e7 +Subproject commit 9e97396f98c20eff17a71aacb24296efcaa04808