Actor Stuff.

This commit is contained in:
Ottermandias 2022-11-04 16:09:29 +01:00
parent 1353e591b8
commit 878f69fd91
8 changed files with 513 additions and 459 deletions

View file

@ -6,8 +6,8 @@ using Penumbra.String;
namespace Penumbra.GameData.Actors;
[StructLayout( LayoutKind.Explicit )]
public readonly struct ActorIdentifier : IEquatable< ActorIdentifier >
[StructLayout(LayoutKind.Explicit)]
public readonly struct ActorIdentifier : IEquatable<ActorIdentifier>
{
public static ActorManager? Manager;
@ -26,36 +26,40 @@ public readonly struct ActorIdentifier : IEquatable< ActorIdentifier >
public ActorIdentifier CreatePermanent()
=> new(Type, Kind, Index, DataId, PlayerName.Clone());
public bool Equals( ActorIdentifier other )
public bool Equals(ActorIdentifier other)
{
if( Type != other.Type )
{
if (Type != other.Type)
return false;
}
return Type switch
{
IdentifierType.Player => HomeWorld == other.HomeWorld && PlayerName.EqualsCi( other.PlayerName ),
IdentifierType.Owned => HomeWorld == other.HomeWorld && PlayerName.EqualsCi( other.PlayerName ) && Manager.DataIdEquals( this, other ),
IdentifierType.Player => HomeWorld == other.HomeWorld && PlayerName.EqualsCi(other.PlayerName),
IdentifierType.Owned => HomeWorld == other.HomeWorld && PlayerName.EqualsCi(other.PlayerName) && Manager.DataIdEquals(this, other),
IdentifierType.Special => Special == other.Special,
IdentifierType.Npc => Index == other.Index && DataId == other.DataId && Manager.DataIdEquals( this, other ),
_ => false,
IdentifierType.Npc => Index == other.Index && DataId == other.DataId && Manager.DataIdEquals(this, other),
_ => false,
};
}
public override bool Equals( object? obj )
=> obj is ActorIdentifier other && Equals( other );
public override bool Equals(object? obj)
=> obj is ActorIdentifier other && Equals(other);
public static bool operator ==(ActorIdentifier lhs, ActorIdentifier rhs)
=> lhs.Equals(rhs);
public static bool operator !=(ActorIdentifier lhs, ActorIdentifier rhs)
=> !lhs.Equals(rhs);
public bool IsValid
=> Type != IdentifierType.Invalid;
public override string ToString()
=> Manager?.ToString( this )
=> Manager?.ToString(this)
?? Type switch
{
IdentifierType.Player => $"{PlayerName} ({HomeWorld})",
IdentifierType.Owned => $"{PlayerName}s {Kind} {DataId} ({HomeWorld})",
IdentifierType.Special => ActorManager.ToName( Special ),
IdentifierType.Special => ActorManager.ToName(Special),
IdentifierType.Npc =>
Index == ushort.MaxValue
? $"{Kind} #{DataId}"
@ -66,18 +70,18 @@ public readonly struct ActorIdentifier : IEquatable< ActorIdentifier >
public override int GetHashCode()
=> Type switch
{
IdentifierType.Player => HashCode.Combine( IdentifierType.Player, PlayerName, HomeWorld ),
IdentifierType.Owned => HashCode.Combine( IdentifierType.Owned, Kind, PlayerName, HomeWorld, DataId ),
IdentifierType.Special => HashCode.Combine( IdentifierType.Special, Special ),
IdentifierType.Npc => HashCode.Combine( IdentifierType.Npc, Kind, Index, DataId ),
IdentifierType.Player => HashCode.Combine(IdentifierType.Player, PlayerName, HomeWorld),
IdentifierType.Owned => HashCode.Combine(IdentifierType.Owned, Kind, PlayerName, HomeWorld, DataId),
IdentifierType.Special => HashCode.Combine(IdentifierType.Special, Special),
IdentifierType.Npc => HashCode.Combine(IdentifierType.Npc, Kind, Index, DataId),
_ => 0,
};
internal ActorIdentifier( IdentifierType type, ObjectKind kind, ushort index, uint data, ByteString playerName )
internal ActorIdentifier(IdentifierType type, ObjectKind kind, ushort index, uint data, ByteString playerName)
{
Type = type;
Kind = kind;
Special = ( SpecialActor )index;
Special = (SpecialActor)index;
HomeWorld = Index = index;
DataId = data;
PlayerName = playerName;
@ -86,26 +90,26 @@ public readonly struct ActorIdentifier : IEquatable< ActorIdentifier >
public JObject ToJson()
{
var ret = new JObject { { nameof( Type ), Type.ToString() } };
switch( Type )
var ret = new JObject { { nameof(Type), Type.ToString() } };
switch (Type)
{
case IdentifierType.Player:
ret.Add( nameof( PlayerName ), PlayerName.ToString() );
ret.Add( nameof( HomeWorld ), HomeWorld );
ret.Add(nameof(PlayerName), PlayerName.ToString());
ret.Add(nameof(HomeWorld), HomeWorld);
return ret;
case IdentifierType.Owned:
ret.Add( nameof( PlayerName ), PlayerName.ToString() );
ret.Add( nameof( HomeWorld ), HomeWorld );
ret.Add( nameof( Kind ), Kind.ToString() );
ret.Add( nameof( DataId ), DataId );
ret.Add(nameof(PlayerName), PlayerName.ToString());
ret.Add(nameof(HomeWorld), HomeWorld);
ret.Add(nameof(Kind), Kind.ToString());
ret.Add(nameof(DataId), DataId);
return ret;
case IdentifierType.Special:
ret.Add( nameof( Special ), Special.ToString() );
ret.Add(nameof(Special), Special.ToString());
return ret;
case IdentifierType.Npc:
ret.Add( nameof( Kind ), Kind.ToString() );
ret.Add( nameof( Index ), Index );
ret.Add( nameof( DataId ), DataId );
ret.Add(nameof(Kind), Kind.ToString());
ret.Add(nameof(Index), Index);
ret.Add(nameof(DataId), DataId);
return ret;
}
@ -115,38 +119,32 @@ public readonly struct ActorIdentifier : IEquatable< ActorIdentifier >
public static class ActorManagerExtensions
{
public static bool DataIdEquals( this ActorManager? manager, ActorIdentifier lhs, ActorIdentifier rhs )
public static bool DataIdEquals(this ActorManager? manager, ActorIdentifier lhs, ActorIdentifier rhs)
{
if( lhs.Kind != rhs.Kind )
{
if (lhs.Kind != rhs.Kind)
return false;
}
if( lhs.DataId == rhs.DataId )
{
if (lhs.DataId == rhs.DataId)
return true;
}
if( manager == null )
{
if (manager == null)
return lhs.Kind == rhs.Kind && lhs.DataId == rhs.DataId || lhs.DataId == uint.MaxValue || rhs.DataId == uint.MaxValue;
}
return lhs.Kind switch
{
ObjectKind.MountType => manager.Mounts.TryGetValue( lhs.DataId, out var lhsName )
&& manager.Mounts.TryGetValue( rhs.DataId, out var rhsName )
&& lhsName.Equals( rhsName, StringComparison.OrdinalIgnoreCase ),
ObjectKind.Companion => manager.Companions.TryGetValue( lhs.DataId, out var lhsName )
&& manager.Companions.TryGetValue( rhs.DataId, out var rhsName )
&& lhsName.Equals( rhsName, StringComparison.OrdinalIgnoreCase ),
ObjectKind.BattleNpc => manager.BNpcs.TryGetValue( lhs.DataId, out var lhsName )
&& manager.BNpcs.TryGetValue( rhs.DataId, out var rhsName )
&& lhsName.Equals( rhsName, StringComparison.OrdinalIgnoreCase ),
ObjectKind.EventNpc => manager.ENpcs.TryGetValue( lhs.DataId, out var lhsName )
&& manager.ENpcs.TryGetValue( rhs.DataId, out var rhsName )
&& lhsName.Equals( rhsName, StringComparison.OrdinalIgnoreCase ),
ObjectKind.MountType => manager.Mounts.TryGetValue(lhs.DataId, out var lhsName)
&& manager.Mounts.TryGetValue(rhs.DataId, out var rhsName)
&& lhsName.Equals(rhsName, StringComparison.OrdinalIgnoreCase),
ObjectKind.Companion => manager.Companions.TryGetValue(lhs.DataId, out var lhsName)
&& manager.Companions.TryGetValue(rhs.DataId, out var rhsName)
&& lhsName.Equals(rhsName, StringComparison.OrdinalIgnoreCase),
ObjectKind.BattleNpc => manager.BNpcs.TryGetValue(lhs.DataId, out var lhsName)
&& manager.BNpcs.TryGetValue(rhs.DataId, out var rhsName)
&& lhsName.Equals(rhsName, StringComparison.OrdinalIgnoreCase),
ObjectKind.EventNpc => manager.ENpcs.TryGetValue(lhs.DataId, out var lhsName)
&& manager.ENpcs.TryGetValue(rhs.DataId, out var rhsName)
&& lhsName.Equals(rhsName, StringComparison.OrdinalIgnoreCase),
_ => false,
};
}
}
}