mirror of
https://github.com/xivdev/Penumbra.git
synced 2026-01-03 14:23:43 +01:00
Fix some bugs and start work on new collections tab.
This commit is contained in:
parent
e9fc57022e
commit
fba5bc6820
26 changed files with 1346 additions and 717 deletions
|
|
@ -13,24 +13,35 @@ using Penumbra.Util;
|
|||
|
||||
namespace Penumbra.Collections.Manager;
|
||||
|
||||
public class ActiveCollectionData
|
||||
{
|
||||
public ModCollection Current { get; internal set; } = ModCollection.Empty;
|
||||
public ModCollection Default { get; internal set; } = ModCollection.Empty;
|
||||
public ModCollection Interface { get; internal set; } = ModCollection.Empty;
|
||||
|
||||
public readonly ModCollection?[] SpecialCollections = new ModCollection?[Enum.GetValues<Api.Enums.ApiCollectionType>().Length - 3];
|
||||
}
|
||||
|
||||
public class ActiveCollections : ISavable, IDisposable
|
||||
{
|
||||
public const int Version = 1;
|
||||
|
||||
private readonly CollectionStorage _storage;
|
||||
private readonly CommunicatorService _communicator;
|
||||
private readonly SaveService _saveService;
|
||||
private readonly CollectionStorage _storage;
|
||||
private readonly CommunicatorService _communicator;
|
||||
private readonly SaveService _saveService;
|
||||
private readonly ActiveCollectionData _data;
|
||||
|
||||
public ActiveCollections(Configuration config, CollectionStorage storage, ActorService actors, CommunicatorService communicator, SaveService saveService)
|
||||
public ActiveCollections(Configuration config, CollectionStorage storage, ActorService actors, CommunicatorService communicator, SaveService saveService, ActiveCollectionData data)
|
||||
{
|
||||
_storage = storage;
|
||||
_communicator = communicator;
|
||||
_saveService = saveService;
|
||||
_data = data;
|
||||
Current = storage.DefaultNamed;
|
||||
Default = storage.DefaultNamed;
|
||||
Interface = storage.DefaultNamed;
|
||||
Individuals = new IndividualCollections(actors.AwaitedService, config);
|
||||
_communicator.CollectionChange.Subscribe(OnCollectionChange);
|
||||
_communicator.CollectionChange.Subscribe(OnCollectionChange, -100);
|
||||
LoadCollections();
|
||||
UpdateCurrentCollectionInUse();
|
||||
}
|
||||
|
|
@ -39,16 +50,28 @@ public class ActiveCollections : ISavable, IDisposable
|
|||
=> _communicator.CollectionChange.Unsubscribe(OnCollectionChange);
|
||||
|
||||
/// <summary> The collection currently selected for changing settings. </summary>
|
||||
public ModCollection Current { get; private set; }
|
||||
public ModCollection Current
|
||||
{
|
||||
get => _data.Current;
|
||||
private set => _data.Current = value;
|
||||
}
|
||||
|
||||
/// <summary> Whether the currently selected collection is used either directly via assignment or via inheritance. </summary>
|
||||
public bool CurrentCollectionInUse { get; private set; }
|
||||
|
||||
/// <summary> The collection used for general file redirections and all characters not specifically named. </summary>
|
||||
public ModCollection Default { get; private set; }
|
||||
public ModCollection Default
|
||||
{
|
||||
get => _data.Default;
|
||||
private set => _data.Default = value;
|
||||
}
|
||||
|
||||
/// <summary> The collection used for all files categorized as UI files. </summary>
|
||||
public ModCollection Interface { get; private set; }
|
||||
public ModCollection Interface
|
||||
{
|
||||
get => _data.Interface;
|
||||
private set => _data.Interface = value;
|
||||
}
|
||||
|
||||
/// <summary> The list of individual assignments. </summary>
|
||||
public readonly IndividualCollections Individuals;
|
||||
|
|
@ -58,16 +81,17 @@ public class ActiveCollections : ISavable, IDisposable
|
|||
=> Individuals.TryGetCollection(identifier, out var c) ? c : Default;
|
||||
|
||||
/// <summary> The list of group assignments. </summary>
|
||||
private readonly ModCollection?[] _specialCollections = new ModCollection?[Enum.GetValues<Api.Enums.ApiCollectionType>().Length - 3];
|
||||
private ModCollection?[] SpecialCollections
|
||||
=> _data.SpecialCollections;
|
||||
|
||||
/// <summary> Return all actually assigned group assignments. </summary>
|
||||
public IEnumerable<KeyValuePair<CollectionType, ModCollection>> SpecialAssignments
|
||||
{
|
||||
get
|
||||
{
|
||||
for (var i = 0; i < _specialCollections.Length; ++i)
|
||||
for (var i = 0; i < SpecialCollections.Length; ++i)
|
||||
{
|
||||
var collection = _specialCollections[i];
|
||||
var collection = SpecialCollections[i];
|
||||
if (collection != null)
|
||||
yield return new KeyValuePair<CollectionType, ModCollection>((CollectionType)i, collection);
|
||||
}
|
||||
|
|
@ -82,7 +106,7 @@ public class ActiveCollections : ISavable, IDisposable
|
|||
public ModCollection? ByType(CollectionType type, ActorIdentifier identifier)
|
||||
{
|
||||
if (type.IsSpecial())
|
||||
return _specialCollections[(int)type];
|
||||
return SpecialCollections[(int)type];
|
||||
|
||||
return type switch
|
||||
{
|
||||
|
|
@ -94,13 +118,13 @@ public class ActiveCollections : ISavable, IDisposable
|
|||
};
|
||||
}
|
||||
|
||||
/// <summary> Create a special collection if it does not exist and set it to Empty. </summary>
|
||||
/// <summary> Create a special collection if it does not exist and set it to the current default. </summary>
|
||||
public bool CreateSpecialCollection(CollectionType collectionType)
|
||||
{
|
||||
if (!collectionType.IsSpecial() || _specialCollections[(int)collectionType] != null)
|
||||
if (!collectionType.IsSpecial() || SpecialCollections[(int)collectionType] != null)
|
||||
return false;
|
||||
|
||||
_specialCollections[(int)collectionType] = Default;
|
||||
SpecialCollections[(int)collectionType] = Default;
|
||||
_communicator.CollectionChange.Invoke(collectionType, null, Default, string.Empty);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -111,11 +135,11 @@ public class ActiveCollections : ISavable, IDisposable
|
|||
if (!collectionType.IsSpecial())
|
||||
return;
|
||||
|
||||
var old = _specialCollections[(int)collectionType];
|
||||
var old = SpecialCollections[(int)collectionType];
|
||||
if (old == null)
|
||||
return;
|
||||
|
||||
_specialCollections[(int)collectionType] = null;
|
||||
SpecialCollections[(int)collectionType] = null;
|
||||
_communicator.CollectionChange.Invoke(collectionType, old, null, string.Empty);
|
||||
}
|
||||
|
||||
|
|
@ -144,7 +168,38 @@ public class ActiveCollections : ISavable, IDisposable
|
|||
_saveService.QueueSave(this);
|
||||
}
|
||||
|
||||
/// <summary> Set a active collection, can be used to set Default, Current, Interface, Special, or Individual collections. </summary>
|
||||
/// <summary> Set and create an active collection, can be used to set Default, Current, Interface, Special, or Individual collections. </summary>
|
||||
public void SetCollection(ModCollection? collection, CollectionType collectionType, ActorIdentifier[] identifiers)
|
||||
{
|
||||
if (collectionType is CollectionType.Individual && identifiers.Length > 0 && identifiers[0].IsValid)
|
||||
{
|
||||
var idx = Individuals.Index(identifiers[0]);
|
||||
if (idx >= 0)
|
||||
{
|
||||
if (collection == null)
|
||||
RemoveIndividualCollection(idx);
|
||||
else
|
||||
SetCollection(collection, collectionType, idx);
|
||||
}
|
||||
else if (collection != null)
|
||||
{
|
||||
CreateIndividualCollection(identifiers);
|
||||
SetCollection(collection, CollectionType.Individual, Individuals.Count - 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (collection == null)
|
||||
RemoveSpecialCollection(collectionType);
|
||||
else
|
||||
{
|
||||
CreateSpecialCollection(collectionType);
|
||||
SetCollection(collection, collectionType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Set an active collection, can be used to set Default, Current, Interface, Special, or Individual collections. </summary>
|
||||
public void SetCollection(ModCollection collection, CollectionType collectionType, int individualIndex = -1)
|
||||
{
|
||||
var oldCollection = collectionType switch
|
||||
|
|
@ -154,7 +209,7 @@ public class ActiveCollections : ISavable, IDisposable
|
|||
CollectionType.Current => Current,
|
||||
CollectionType.Individual when individualIndex >= 0 && individualIndex < Individuals.Count => Individuals[individualIndex].Collection,
|
||||
CollectionType.Individual => null,
|
||||
_ when collectionType.IsSpecial() => _specialCollections[(int)collectionType] ?? Default,
|
||||
_ when collectionType.IsSpecial() => SpecialCollections[(int)collectionType] ?? Default,
|
||||
_ => null,
|
||||
};
|
||||
|
||||
|
|
@ -178,7 +233,7 @@ public class ActiveCollections : ISavable, IDisposable
|
|||
|
||||
break;
|
||||
default:
|
||||
_specialCollections[(int)collectionType] = collection;
|
||||
SpecialCollections[(int)collectionType] = collection;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -205,7 +260,7 @@ public class ActiveCollections : ISavable, IDisposable
|
|||
{ nameof(Interface), Interface.Name },
|
||||
{ nameof(Current), Current.Name },
|
||||
};
|
||||
foreach (var (type, collection) in _specialCollections.WithIndex().Where(p => p.Value != null)
|
||||
foreach (var (type, collection) in SpecialCollections.WithIndex().Where(p => p.Value != null)
|
||||
.Select(p => ((CollectionType)p.Index, p.Value!)))
|
||||
jObj.Add(type.ToString(), collection.Name);
|
||||
|
||||
|
|
@ -215,7 +270,7 @@ public class ActiveCollections : ISavable, IDisposable
|
|||
}
|
||||
|
||||
private void UpdateCurrentCollectionInUse()
|
||||
=> CurrentCollectionInUse = _specialCollections
|
||||
=> CurrentCollectionInUse = SpecialCollections
|
||||
.OfType<ModCollection>()
|
||||
.Prepend(Interface)
|
||||
.Prepend(Default)
|
||||
|
|
@ -240,9 +295,9 @@ public class ActiveCollections : ISavable, IDisposable
|
|||
if (oldCollection == Current)
|
||||
SetCollection(Default.Index > ModCollection.Empty.Index ? Default : _storage.DefaultNamed, CollectionType.Current);
|
||||
|
||||
for (var i = 0; i < _specialCollections.Length; ++i)
|
||||
for (var i = 0; i < SpecialCollections.Length; ++i)
|
||||
{
|
||||
if (oldCollection == _specialCollections[i])
|
||||
if (oldCollection == SpecialCollections[i])
|
||||
SetCollection(ModCollection.Empty, (CollectionType)i);
|
||||
}
|
||||
|
||||
|
|
@ -329,7 +384,7 @@ public class ActiveCollections : ISavable, IDisposable
|
|||
}
|
||||
else
|
||||
{
|
||||
_specialCollections[(int)type] = typeCollection;
|
||||
SpecialCollections[(int)type] = typeCollection;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -398,24 +453,6 @@ public class ActiveCollections : ISavable, IDisposable
|
|||
: string.Empty;
|
||||
}
|
||||
|
||||
break;
|
||||
// The group of all Characters is redundant if they are all equal to Default or unassigned.
|
||||
case CollectionType.MalePlayerCharacter:
|
||||
case CollectionType.MaleNonPlayerCharacter:
|
||||
case CollectionType.FemalePlayerCharacter:
|
||||
case CollectionType.FemaleNonPlayerCharacter:
|
||||
var first = ByType(CollectionType.MalePlayerCharacter) ?? Default;
|
||||
var second = ByType(CollectionType.MaleNonPlayerCharacter) ?? Default;
|
||||
var third = ByType(CollectionType.FemalePlayerCharacter) ?? Default;
|
||||
var fourth = ByType(CollectionType.FemaleNonPlayerCharacter) ?? Default;
|
||||
if (first.Index == second.Index
|
||||
&& first.Index == third.Index
|
||||
&& first.Index == fourth.Index
|
||||
&& first.Index == Default.Index)
|
||||
return
|
||||
"Assignment is currently redundant due to the group [Male, Female, Player, NPC] Characters being unassigned or identical to each other and Default.\n"
|
||||
+ "You can keep just the Default Assignment.";
|
||||
|
||||
break;
|
||||
// Children and Elderly are redundant if they are identical to both Male NPCs and Female NPCs, or if they are unassigned to Default.
|
||||
case CollectionType.NonPlayerChild:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue