diff --git a/Penumbra.GameData/Actors/ActorManager.Data.cs b/Penumbra.GameData/Actors/ActorManager.Data.cs index fb161304..0bcaa792 100644 --- a/Penumbra.GameData/Actors/ActorManager.Data.cs +++ b/Penumbra.GameData/Actors/ActorManager.Data.cs @@ -165,14 +165,15 @@ public sealed partial class ActorManager : IDisposable public readonly ActorManagerData Data; - public ActorManager(DalamudPluginInterface pluginInterface, ObjectTable objects, ClientState state, DataManager gameData, GameGui gameGui, + public ActorManager(DalamudPluginInterface pluginInterface, ObjectTable objects, ClientState state, Dalamud.Game.Framework framework, DataManager gameData, GameGui gameGui, Func toParentIdx) - : this(pluginInterface, objects, state, gameData, gameGui, gameData.Language, toParentIdx) + : this(pluginInterface, objects, state, framework, gameData, gameGui, gameData.Language, toParentIdx) { } - public ActorManager(DalamudPluginInterface pluginInterface, ObjectTable objects, ClientState state, DataManager gameData, GameGui gameGui, + public ActorManager(DalamudPluginInterface pluginInterface, ObjectTable objects, ClientState state, Dalamud.Game.Framework framework, DataManager gameData, GameGui gameGui, ClientLanguage language, Func toParentIdx) { + _framework = framework; _objects = objects; _gameGui = gameGui; _clientState = state; @@ -340,9 +341,10 @@ public sealed partial class ActorManager : IDisposable ~ActorManager() => Dispose(); - private readonly ObjectTable _objects; - private readonly ClientState _clientState; - private readonly GameGui _gameGui; + private readonly Dalamud.Game.Framework _framework; + private readonly ObjectTable _objects; + private readonly ClientState _clientState; + private readonly GameGui _gameGui; private readonly Func _toParentIdx; diff --git a/Penumbra.GameData/Actors/ActorManager.Identifiers.cs b/Penumbra.GameData/Actors/ActorManager.Identifiers.cs index d5e0c30e..500bbc98 100644 --- a/Penumbra.GameData/Actors/ActorManager.Identifiers.cs +++ b/Penumbra.GameData/Actors/ActorManager.Identifiers.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using Dalamud.Game.ClientState.Objects.Enums; using Dalamud.Game.ClientState.Objects.Types; +using Dalamud.Logging; using Newtonsoft.Json.Linq; using Penumbra.String; using Character = FFXIVClientStructs.FFXIV.Client.Game.Character.Character; @@ -313,8 +314,8 @@ public partial class ActorManager static ByteString Get(byte* ptr) => ptr == null ? ByteString.Empty : new ByteString(ptr); - var actualName = Get(actor->GetName()); var retainerName = Get(actor->Name); + var actualName = _framework.IsInFrameworkUpdateThread ? Get(actor->GetName()) : ByteString.Empty; if (!actualName.Equals(retainerName)) { var ident = check @@ -338,7 +339,7 @@ public partial class ActorManager if (owner == null) return ActorIdentifier.Invalid; - var dataId = GetCompanionId(actor, (Character*) owner); + var dataId = GetCompanionId(actor, (Character*)owner); var name = new ByteString(owner->Name); var homeWorld = ((Character*)owner)->HomeWorld; return check @@ -553,10 +554,10 @@ public partial class ActorManager { return index switch { - ushort.MaxValue => true, - < 200 => index % 2 == 0, + ushort.MaxValue => true, + < 200 => index % 2 == 0, > (ushort)ScreenActor.Card8 => index < 426, - _ => false, + _ => false, }; } diff --git a/Penumbra.String b/Penumbra.String index 4f7a112e..5ae32fd5 160000 --- a/Penumbra.String +++ b/Penumbra.String @@ -1 +1 @@ -Subproject commit 4f7a112ea9c9b377c265746dc572fa26e371de69 +Subproject commit 5ae32fd5f19fcc641d5f2d777de2276186900c0b diff --git a/Penumbra/Api/TempModManager.cs b/Penumbra/Api/TempModManager.cs index 511cb861..08393ebd 100644 --- a/Penumbra/Api/TempModManager.cs +++ b/Penumbra/Api/TempModManager.cs @@ -1,3 +1,4 @@ +using System; using Penumbra.Collections; using Penumbra.Meta.Manipulations; using Penumbra.Mods; @@ -20,6 +21,7 @@ public enum RedirectResult public class TempModManager { + public int GlobalChangeCounter { get; private set; } = 0; private readonly Dictionary< ModCollection, List< Mod.TemporaryMod > > _mods = new(); private readonly List< Mod.TemporaryMod > _modsForAllCollections = new(); private readonly Dictionary< string, ModCollection > _customCollections = new(); @@ -158,7 +160,9 @@ public class TempModManager return string.Empty; } - var collection = ModCollection.CreateNewTemporary( name ); + if( GlobalChangeCounter == int.MaxValue ) + GlobalChangeCounter = 0; + var collection = ModCollection.CreateNewTemporary( name, GlobalChangeCounter++ ); if( _customCollections.TryAdd( collection.Name.ToLowerInvariant(), collection ) ) { return collection.Name; @@ -175,6 +179,7 @@ public class TempModManager return false; } + GlobalChangeCounter += Math.Max(collection.ChangeCounter + 1 - GlobalChangeCounter, 0); _mods.Remove( collection ); collection.ClearCache(); for( var i = 0; i < Collections.Count; ++i ) diff --git a/Penumbra/Collections/ModCollection.cs b/Penumbra/Collections/ModCollection.cs index 2b7a8605..f5ce009d 100644 --- a/Penumbra/Collections/ModCollection.cs +++ b/Penumbra/Collections/ModCollection.cs @@ -85,12 +85,13 @@ public partial class ModCollection => new(name, CurrentVersion, new Dictionary< string, ModSettings.SavedSettings >()); // Create a new temporary collection that does not save and has a negative index. - public static ModCollection CreateNewTemporary( string name ) + public static ModCollection CreateNewTemporary( string name, int changeCounter ) { var collection = new ModCollection( name, Empty ); collection.ModSettingChanged -= collection.SaveOnChange; collection.InheritanceChanged -= collection.SaveOnChange; collection.Index = ~Penumbra.TempMods.Collections.Count; + collection.ChangeCounter = changeCounter; collection.CreateCache(); return collection; } diff --git a/Penumbra/Interop/Loader/ResourceLoader.Debug.cs b/Penumbra/Interop/Loader/ResourceLoader.Debug.cs index ad1d69d7..438e6fa5 100644 --- a/Penumbra/Interop/Loader/ResourceLoader.Debug.cs +++ b/Penumbra/Interop/Loader/ResourceLoader.Debug.cs @@ -257,7 +257,7 @@ public unsafe partial class ResourceLoader { var pathString = manipulatedPath != null ? $"custom file {manipulatedPath} instead of {path}" : path.ToString(); Penumbra.Log.Information( - $"[ResourceLoader] [{handle->FileType}] Loaded {pathString} to 0x{( ulong )handle:X} using collection {data.ModCollection.AnonymizedName} for {data.AssociatedName()}. (Refcount {handle->RefCount}) " ); + $"[ResourceLoader] [{handle->FileType}] Loaded {pathString} to 0x{( ulong )handle:X} using collection {data.ModCollection.AnonymizedName} for {data.AssociatedName()} (Refcount {handle->RefCount}) " ); } private static void LogLoadedFile( Structs.ResourceHandle* resource, ByteString path, bool success, bool custom ) diff --git a/Penumbra/Interop/ObjectReloader.cs b/Penumbra/Interop/ObjectReloader.cs index 3f7adaf1..5f466b95 100644 --- a/Penumbra/Interop/ObjectReloader.cs +++ b/Penumbra/Interop/ObjectReloader.cs @@ -8,6 +8,7 @@ using Dalamud.Game.ClientState.Objects.Types; using Penumbra.Api; using Penumbra.Api.Enums; using Penumbra.GameData; +using Penumbra.GameData.Actors; using Penumbra.Interop.Structs; namespace Penumbra.Interop; @@ -99,7 +100,7 @@ public unsafe partial class ObjectReloader } tableIndex = ObjectTableIndex( actor ); - return tableIndex is >= 240 and < 245; + return tableIndex is >= (int) ScreenActor.CharacterScreen and <= ( int) ScreenActor.Card8; } } diff --git a/Penumbra/Penumbra.cs b/Penumbra/Penumbra.cs index 739975e5..92ac8385 100644 --- a/Penumbra/Penumbra.cs +++ b/Penumbra/Penumbra.cs @@ -99,14 +99,14 @@ public class Penumbra : IDalamudPlugin GamePathParser = GameData.GameData.GetGamePathParser(); StainManager = new StainManager( Dalamud.PluginInterface, Dalamud.GameData ); ItemData = new ItemData( Dalamud.PluginInterface, Dalamud.GameData, Dalamud.GameData.Language ); - Actors = new ActorManager( Dalamud.PluginInterface, Dalamud.Objects, Dalamud.ClientState, Dalamud.GameData, Dalamud.GameGui, ResolveCutscene ); + Actors = new ActorManager( Dalamud.PluginInterface, Dalamud.Objects, Dalamud.ClientState, Dalamud.Framework, Dalamud.GameData, Dalamud.GameGui, ResolveCutscene ); Framework = new FrameworkManager(Dalamud.Framework, Log); CharacterUtility = new CharacterUtility(); Backup.CreateBackup( pluginInterface.ConfigDirectory, PenumbraBackupFiles() ); Config = Configuration.Load(); - + TempMods = new TempModManager(); MetaFileManager = new MetaFileManager(); ResourceLoader = new ResourceLoader( this ); diff --git a/Penumbra/UI/ConfigWindow.DebugTab.cs b/Penumbra/UI/ConfigWindow.DebugTab.cs index 52a1f636..10eded81 100644 --- a/Penumbra/UI/ConfigWindow.DebugTab.cs +++ b/Penumbra/UI/ConfigWindow.DebugTab.cs @@ -20,6 +20,7 @@ using Penumbra.Interop.Structs; using Penumbra.String; using Penumbra.Util; using static OtterGui.Raii.ImRaii; +using CharacterBase = FFXIVClientStructs.FFXIV.Client.Graphics.Scene.CharacterBase; using CharacterUtility = Penumbra.Interop.CharacterUtility; using ObjectKind = Dalamud.Game.ClientState.Objects.Enums.ObjectKind; @@ -550,6 +551,19 @@ public partial class ConfigWindow return; } + using( var t1 = ImRaii.Table( "##table", 2, ImGuiTableFlags.SizingFixedFit ) ) + { + if( t1 ) + { + ImGuiUtil.DrawTableColumn( "Flags" ); + ImGuiUtil.DrawTableColumn( $"{model->UnkFlags_01:X2}" ); + ImGuiUtil.DrawTableColumn( "Has Model In Slot Loaded" ); + ImGuiUtil.DrawTableColumn( $"{model->HasModelInSlotLoaded:X8}" ); + ImGuiUtil.DrawTableColumn( "Has Model Files In Slot Loaded" ); + ImGuiUtil.DrawTableColumn( $"{model->HasModelFilesInSlotLoaded:X8}" ); + } + } + using var table = ImRaii.Table( $"##{name}DrawTable", 5, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit ); if( !table ) {