diff --git a/Anamnesis/Actor/Refresh/AnamnesisActorRefresher.cs b/Anamnesis/Actor/Refresh/AnamnesisActorRefresher.cs index 43abcc75..67f6dbeb 100644 --- a/Anamnesis/Actor/Refresh/AnamnesisActorRefresher.cs +++ b/Anamnesis/Actor/Refresh/AnamnesisActorRefresher.cs @@ -3,9 +3,9 @@ namespace Anamnesis.Actor.Refresh; -using System.Threading.Tasks; using Anamnesis.Memory; using Anamnesis.Services; +using System.Threading.Tasks; using static Anamnesis.Memory.ActorBasicMemory; public class AnamnesisActorRefresher : IActorRefresher @@ -28,7 +28,6 @@ public bool CanRefresh(ActorMemory actor) public async Task RefreshActor(ActorMemory actor) { - await Task.Delay(16); if (SettingsService.Current.EnableNpcHack && actor.ObjectKind == ActorTypes.Player) { actor.ObjectKind = ActorTypes.BattleNpc; @@ -45,7 +44,5 @@ public async Task RefreshActor(ActorMemory actor) await Task.Delay(75); actor.RenderMode = RenderModes.Draw; } - - await Task.Delay(150); } } diff --git a/Anamnesis/Actor/Views/CustomizeEditor.xaml.cs b/Anamnesis/Actor/Views/CustomizeEditor.xaml.cs index 962c5da7..e9477363 100644 --- a/Anamnesis/Actor/Views/CustomizeEditor.xaml.cs +++ b/Anamnesis/Actor/Views/CustomizeEditor.xaml.cs @@ -31,7 +31,10 @@ public CustomizeEditor() this.ContentArea.DataContext = this; this.GenderComboBox.ItemsSource = Enum.GetValues(typeof(ActorCustomizeMemory.Genders)); - this.AgeComboBox.ItemsSource = Enum.GetValues(typeof(ActorCustomizeMemory.Ages)); + this.AgeComboBox.ItemsSource = + Enum.GetValues(typeof(ActorCustomizeMemory.Ages)) + .Cast() + .Where(age => age != ActorCustomizeMemory.Ages.None); List races = new(); foreach (Race race in GameDataService.Races) diff --git a/Anamnesis/Memory/ActorMemory.cs b/Anamnesis/Memory/ActorMemory.cs index dcd9cf5c..7e86a623 100644 --- a/Anamnesis/Memory/ActorMemory.cs +++ b/Anamnesis/Memory/ActorMemory.cs @@ -249,6 +249,10 @@ private void HandlePropertyChanged(object? sender, PropertyChangedEventArgs e) // Refresh the actor if (this.AutomaticRefreshEnabled && change.OriginBind.Flags.HasFlag(BindFlags.ActorRefresh)) { + // Don't refresh because of a refresh + if (this.IsRefreshing && (change.OriginBind.Name == nameof(this.ObjectKind) || change.OriginBind.Name == nameof(this.RenderMode))) + return; + if (change.OriginBind.Flags.HasFlag(BindFlags.WeaponRefresh)) this.IsWeaponDirty = true; diff --git a/Anamnesis/Memory/History.cs b/Anamnesis/Memory/History.cs index 867299b7..d25ec432 100644 --- a/Anamnesis/Memory/History.cs +++ b/Anamnesis/Memory/History.cs @@ -144,8 +144,28 @@ public class HistoryEntry private readonly List changes = new(); - public bool HasChanges => this.changes.Count > 0; - public int Count => this.changes.Count; + public bool HasChanges + { + get + { + lock (this.changes) + { + return this.changes.Count > 0; + } + } + } + + public int Count + { + get + { + lock (this.changes) + { + return this.changes.Count; + } + } + } + public string Name { get; set; } = string.Empty; public string ChangeList => this.GetChangeList(); @@ -153,53 +173,62 @@ public void Restore() { Log.Verbose($"Restoring change set:\n{this}"); - for (int i = this.changes.Count - 1; i >= 0; i--) + lock (this.changes) { - PropertyChange change = this.changes[i]; - if (change.OriginBind is PropertyBindInfo propertyBind) + for (int i = this.changes.Count - 1; i >= 0; i--) { - propertyBind.Property.SetValue(propertyBind.Memory, change.OldValue); + PropertyChange change = this.changes[i]; + if (change.OriginBind is PropertyBindInfo propertyBind) + { + propertyBind.Property.SetValue(propertyBind.Memory, change.OldValue); + } } } } public void Record(PropertyChange change) { - // Keep only the latest change for each bind to minimize stored changes and recovery steps - PropertyChange? existingChange = this.changes.FirstOrDefault(c => c.Path == change.Path); - if (existingChange.HasValue) + lock (this.changes) { - // Validate the existing change's OldValue - if (IsValidOldValue(existingChange.Value.OldValue)) + // Keep only the latest change for each bind to minimize stored changes and recovery steps + PropertyChange? existingChange = this.changes.FirstOrDefault(c => c.Path == change.Path); + if (existingChange.HasValue) { - // Transfer the old value of the existing change to the new change if it is valid - change.OldValue = existingChange.Value.OldValue; + // Validate the existing change's OldValue + if (IsValidOldValue(existingChange.Value.OldValue)) + { + // Transfer the old value of the existing change to the new change if it is valid + change.OldValue = existingChange.Value.OldValue; + } + + // Remove the existing change + this.changes.Remove(existingChange.Value); } - // Remove the existing change - this.changes.Remove(existingChange.Value); - } - - // Add the latest change into the history entry's changes list - this.changes.Add(change); + // Add the latest change into the history entry's changes list + this.changes.Add(change); - // Sanity check history depth - if (this.changes.Count > MaxChanges) - { - Log.Warning($"Change depth exceded max: {MaxChanges}. Flushing"); - this.changes.Clear(); + // Sanity check history depth + if (this.changes.Count > MaxChanges) + { + Log.Warning($"Change depth exceded max: {MaxChanges}. Flushing"); + this.changes.Clear(); + } } } public string GetName() { HashSet names = new(); - foreach (PropertyChange change in this.changes) + lock (this.changes) { - if (change.Name == null) - continue; + foreach (PropertyChange change in this.changes) + { + if (change.Name == null) + continue; - names.Add(change.Name); + names.Add(change.Name); + } } StringBuilder builder = new(); @@ -220,18 +249,21 @@ public string GetChangeList() // Flatten the changes to repeated changes to the same value dont show up Dictionary flattenedChanges = new(); - foreach (PropertyChange change in this.changes) + lock (this.changes) { - if (!flattenedChanges.ContainsKey(change.OriginBind)) + foreach (PropertyChange change in this.changes) { - flattenedChanges.Add(change.OriginBind, new(change)); - } - else - { - PropertyChange existingChange = flattenedChanges[change.OriginBind]; - - existingChange.NewValue = change.NewValue; - flattenedChanges[change.OriginBind] = existingChange; + if (!flattenedChanges.ContainsKey(change.OriginBind)) + { + flattenedChanges.Add(change.OriginBind, new(change)); + } + else + { + PropertyChange existingChange = flattenedChanges[change.OriginBind]; + + existingChange.NewValue = change.NewValue; + flattenedChanges[change.OriginBind] = existingChange; + } } }