mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 10:17:22 +01:00
Move PlayerWatcher to own assembly and make appropriate changes for reuse.
This commit is contained in:
parent
ea40d5bc9c
commit
d99707f77e
9 changed files with 335 additions and 133 deletions
28
Penumbra.PlayerWatch/IPlayerWatcher.cs
Normal file
28
Penumbra.PlayerWatch/IPlayerWatcher.cs
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
using System;
|
||||||
|
using Dalamud.Game.ClientState.Actors.Types;
|
||||||
|
using Penumbra.GameData.Structs;
|
||||||
|
|
||||||
|
namespace Penumbra.PlayerWatch
|
||||||
|
{
|
||||||
|
public delegate void ActorChange( Actor actor );
|
||||||
|
|
||||||
|
public interface IPlayerWatcherBase : IDisposable
|
||||||
|
{
|
||||||
|
public int Version { get; }
|
||||||
|
public bool Valid { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IPlayerWatcher : IPlayerWatcherBase
|
||||||
|
{
|
||||||
|
public event ActorChange? ActorChanged;
|
||||||
|
public bool Active { get; }
|
||||||
|
|
||||||
|
public void Enable();
|
||||||
|
public void Disable();
|
||||||
|
public void SetStatus( bool enabled );
|
||||||
|
|
||||||
|
public void AddPlayerToWatch( string name );
|
||||||
|
public void RemovePlayerFromWatch( string playerName );
|
||||||
|
public CharEquipment UpdateActorWithoutEvent( Actor actor );
|
||||||
|
}
|
||||||
|
}
|
||||||
41
Penumbra.PlayerWatch/Penumbra.PlayerWatch.csproj
Normal file
41
Penumbra.PlayerWatch/Penumbra.PlayerWatch.csproj
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net472</TargetFramework>
|
||||||
|
<LangVersion>preview</LangVersion>
|
||||||
|
<AssemblyTitle>Penumbra.PlayerWatch</AssemblyTitle>
|
||||||
|
<Company>absolute gangstas</Company>
|
||||||
|
<Product>Penumbra</Product>
|
||||||
|
<Copyright>Copyright © 2020</Copyright>
|
||||||
|
<FileVersion>1.0.0.0</FileVersion>
|
||||||
|
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||||
|
<OutputPath>bin\$(Configuration)\</OutputPath>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<MSBuildWarningsAsMessages>$(MSBuildWarningsAsMessages);MSB3277</MSBuildWarningsAsMessages>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="Dalamud">
|
||||||
|
<HintPath>$(DALAMUD_ROOT)\Dalamud.dll</HintPath>
|
||||||
|
<HintPath>..\libs\Dalamud.dll</HintPath>
|
||||||
|
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\dev\Dalamud.dll</HintPath>
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Penumbra.GameData\Penumbra.GameData.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
164
Penumbra.PlayerWatch/PlayerWatchBase.cs
Normal file
164
Penumbra.PlayerWatch/PlayerWatchBase.cs
Normal file
|
|
@ -0,0 +1,164 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Dalamud.Game.ClientState.Actors;
|
||||||
|
using Dalamud.Game.ClientState.Actors.Types;
|
||||||
|
using Dalamud.Plugin;
|
||||||
|
using Penumbra.GameData.Structs;
|
||||||
|
|
||||||
|
namespace Penumbra.PlayerWatch
|
||||||
|
{
|
||||||
|
internal class PlayerWatchBase : IDisposable
|
||||||
|
{
|
||||||
|
public const int GPosePlayerActorIdx = 201;
|
||||||
|
private const int ActorsPerFrame = 8;
|
||||||
|
|
||||||
|
private readonly DalamudPluginInterface _pi;
|
||||||
|
internal readonly HashSet< PlayerWatcher > RegisteredWatchers = new();
|
||||||
|
private readonly Dictionary< string, (CharEquipment, HashSet< PlayerWatcher >) > _equip = new();
|
||||||
|
private int _frameTicker;
|
||||||
|
private IntPtr _lastGPoseAddress = IntPtr.Zero;
|
||||||
|
|
||||||
|
internal PlayerWatchBase( DalamudPluginInterface pi )
|
||||||
|
{
|
||||||
|
_pi = pi;
|
||||||
|
EnableActorWatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void RegisterWatcher( PlayerWatcher watcher )
|
||||||
|
{
|
||||||
|
RegisteredWatchers.Add( watcher );
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void UnregisterWatcher( PlayerWatcher watcher )
|
||||||
|
{
|
||||||
|
if( RegisteredWatchers.Remove( watcher ) )
|
||||||
|
{
|
||||||
|
foreach( var items in _equip.Values )
|
||||||
|
{
|
||||||
|
items.Item2.Remove( watcher );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal CharEquipment UpdateActorWithoutEvent( Actor actor )
|
||||||
|
{
|
||||||
|
var equipment = new CharEquipment( actor );
|
||||||
|
if( _equip.ContainsKey( actor.Name ) )
|
||||||
|
{
|
||||||
|
_equip[ actor.Name ] = ( equipment, _equip[ actor.Name ].Item2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
return equipment;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void AddPlayerToWatch( string playerName, PlayerWatcher watcher )
|
||||||
|
{
|
||||||
|
if( _equip.TryGetValue( playerName, out var items ) )
|
||||||
|
{
|
||||||
|
items.Item2.Add( watcher );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_equip[ playerName ] = ( new CharEquipment(), new HashSet< PlayerWatcher > { watcher } );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemovePlayerFromWatch( string playerName, PlayerWatcher watcher )
|
||||||
|
{
|
||||||
|
if( _equip.TryGetValue( playerName, out var items ) )
|
||||||
|
{
|
||||||
|
items.Item2.Remove( watcher );
|
||||||
|
if( items.Item2.Count == 0 )
|
||||||
|
{
|
||||||
|
_equip.Remove( playerName );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void EnableActorWatch()
|
||||||
|
{
|
||||||
|
_pi.Framework.OnUpdateEvent += OnFrameworkUpdate;
|
||||||
|
_pi.ClientState.TerritoryChanged += OnTerritoryChange;
|
||||||
|
_pi.ClientState.OnLogout += OnLogout;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void DisableActorWatch()
|
||||||
|
{
|
||||||
|
_pi.Framework.OnUpdateEvent -= OnFrameworkUpdate;
|
||||||
|
_pi.ClientState.TerritoryChanged -= OnTerritoryChange;
|
||||||
|
_pi.ClientState.OnLogout -= OnLogout;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
=> DisableActorWatch();
|
||||||
|
|
||||||
|
private void OnTerritoryChange( object _1, ushort _2 )
|
||||||
|
=> Clear();
|
||||||
|
|
||||||
|
private void OnLogout( object _1, object _2 )
|
||||||
|
=> Clear();
|
||||||
|
|
||||||
|
internal void Clear()
|
||||||
|
{
|
||||||
|
foreach( var kvp in _equip )
|
||||||
|
{
|
||||||
|
kvp.Value.Item1.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
_frameTicker = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void TriggerEvents( IEnumerable< PlayerWatcher > watchers, Actor actor )
|
||||||
|
{
|
||||||
|
foreach( var watcher in watchers.Where( w => w.Active ) )
|
||||||
|
{
|
||||||
|
watcher.Trigger( actor );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnFrameworkUpdate( object framework )
|
||||||
|
{
|
||||||
|
var actors = _pi.ClientState.Actors;
|
||||||
|
var gPoseActor = actors[ GPosePlayerActorIdx ];
|
||||||
|
if( gPoseActor == null )
|
||||||
|
{
|
||||||
|
if( _lastGPoseAddress != IntPtr.Zero && actors[ 0 ] != null && _equip.TryGetValue( actors[ 0 ].Name, out var player ) )
|
||||||
|
{
|
||||||
|
TriggerEvents( player.Item2, actors[ 0 ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
_lastGPoseAddress = IntPtr.Zero;
|
||||||
|
}
|
||||||
|
else if( gPoseActor.Address != _lastGPoseAddress )
|
||||||
|
{
|
||||||
|
_lastGPoseAddress = gPoseActor.Address;
|
||||||
|
if( _equip.TryGetValue( gPoseActor.Name, out var gPose ) )
|
||||||
|
{
|
||||||
|
TriggerEvents( gPose.Item2, gPoseActor );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for( var i = 0; i < ActorsPerFrame; ++i )
|
||||||
|
{
|
||||||
|
_frameTicker = _frameTicker < actors.Length - 2
|
||||||
|
? _frameTicker + 2
|
||||||
|
: 0;
|
||||||
|
|
||||||
|
var actor = _frameTicker == 0 && gPoseActor != null ? gPoseActor : actors[ _frameTicker ];
|
||||||
|
if( actor == null
|
||||||
|
|| actor.ObjectKind != ObjectKind.Player
|
||||||
|
|| actor.Name == null
|
||||||
|
|| actor.Name.Length == 0 )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( _equip.TryGetValue( actor.Name, out var equip ) && !equip.Item1.CompareAndUpdate( actor ) )
|
||||||
|
{
|
||||||
|
TriggerEvents( equip.Item2, actor );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
88
Penumbra.PlayerWatch/PlayerWatcher.cs
Normal file
88
Penumbra.PlayerWatch/PlayerWatcher.cs
Normal file
|
|
@ -0,0 +1,88 @@
|
||||||
|
using System;
|
||||||
|
using Dalamud.Game.ClientState.Actors.Types;
|
||||||
|
using Dalamud.Plugin;
|
||||||
|
using Penumbra.GameData.Structs;
|
||||||
|
|
||||||
|
namespace Penumbra.PlayerWatch
|
||||||
|
{
|
||||||
|
public class PlayerWatcher : IDisposable, IPlayerWatcher
|
||||||
|
{
|
||||||
|
public int Version { get; } = 1;
|
||||||
|
|
||||||
|
private static PlayerWatchBase? _playerWatch;
|
||||||
|
|
||||||
|
public event ActorChange? ActorChanged;
|
||||||
|
|
||||||
|
public bool Active { get; set; } = true;
|
||||||
|
|
||||||
|
public bool Valid
|
||||||
|
=> _playerWatch != null;
|
||||||
|
|
||||||
|
internal PlayerWatcher( DalamudPluginInterface pi )
|
||||||
|
{
|
||||||
|
_playerWatch ??= new PlayerWatchBase( pi );
|
||||||
|
_playerWatch.RegisterWatcher( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Enable()
|
||||||
|
=> Active = Valid;
|
||||||
|
|
||||||
|
public void Disable()
|
||||||
|
=> Active = false;
|
||||||
|
|
||||||
|
public void SetStatus( bool enabled )
|
||||||
|
=> Active = enabled && Valid;
|
||||||
|
|
||||||
|
internal void Trigger( Actor actor )
|
||||||
|
=> ActorChanged?.Invoke( actor );
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if( _playerWatch == null )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Active = false;
|
||||||
|
ActorChanged = null;
|
||||||
|
_playerWatch.UnregisterWatcher( this );
|
||||||
|
if( _playerWatch.RegisteredWatchers.Count == 0 )
|
||||||
|
{
|
||||||
|
_playerWatch.Dispose();
|
||||||
|
_playerWatch = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CheckValidity()
|
||||||
|
{
|
||||||
|
if( !Valid )
|
||||||
|
{
|
||||||
|
throw new Exception( $"PlayerWatch was already disposed." );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddPlayerToWatch( string name )
|
||||||
|
{
|
||||||
|
CheckValidity();
|
||||||
|
_playerWatch!.AddPlayerToWatch( name, this );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemovePlayerFromWatch( string playerName )
|
||||||
|
{
|
||||||
|
CheckValidity();
|
||||||
|
_playerWatch!.RemovePlayerFromWatch( playerName, this );
|
||||||
|
}
|
||||||
|
|
||||||
|
public CharEquipment UpdateActorWithoutEvent( Actor actor )
|
||||||
|
{
|
||||||
|
CheckValidity();
|
||||||
|
return _playerWatch!.UpdateActorWithoutEvent( actor );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class PlayerWatchFactory
|
||||||
|
{
|
||||||
|
public static IPlayerWatcher Create( DalamudPluginInterface pi )
|
||||||
|
=> new PlayerWatcher( pi );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -10,7 +10,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
||||||
.editorconfig = .editorconfig
|
.editorconfig = .editorconfig
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Penumbra.GameData", "Penumbra.GameData\Penumbra.GameData.csproj", "{EE551E87-FDB3-4612-B500-DC870C07C605}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Penumbra.GameData", "Penumbra.GameData\Penumbra.GameData.csproj", "{EE551E87-FDB3-4612-B500-DC870C07C605}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Penumbra.PlayerWatch", "Penumbra.PlayerWatch\Penumbra.PlayerWatch.csproj", "{01685BD8-8847-4B49-BF90-1683B4C76B0E}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
|
@ -26,6 +28,10 @@ Global
|
||||||
{EE551E87-FDB3-4612-B500-DC870C07C605}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{EE551E87-FDB3-4612-B500-DC870C07C605}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{EE551E87-FDB3-4612-B500-DC870C07C605}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{EE551E87-FDB3-4612-B500-DC870C07C605}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{EE551E87-FDB3-4612-B500-DC870C07C605}.Release|Any CPU.Build.0 = Release|Any CPU
|
{EE551E87-FDB3-4612-B500-DC870C07C605}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{01685BD8-8847-4B49-BF90-1683B4C76B0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{01685BD8-8847-4B49-BF90-1683B4C76B0E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{01685BD8-8847-4B49-BF90-1683B4C76B0E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{01685BD8-8847-4B49-BF90-1683B4C76B0E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
|
||||||
|
|
@ -1,127 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Dalamud.Game.ClientState.Actors;
|
|
||||||
using Dalamud.Game.ClientState.Actors.Types;
|
|
||||||
using Dalamud.Plugin;
|
|
||||||
using Penumbra.GameData.Structs;
|
|
||||||
|
|
||||||
namespace Penumbra.Interop
|
|
||||||
{
|
|
||||||
public class PlayerWatcher : IDisposable
|
|
||||||
{
|
|
||||||
private const int ActorsPerFrame = 8;
|
|
||||||
|
|
||||||
private readonly DalamudPluginInterface _pi;
|
|
||||||
private readonly Dictionary< string, CharEquipment > _equip = new();
|
|
||||||
private int _frameTicker;
|
|
||||||
private IntPtr _lastGPoseAddress = IntPtr.Zero;
|
|
||||||
|
|
||||||
public PlayerWatcher( DalamudPluginInterface pi )
|
|
||||||
=> _pi = pi;
|
|
||||||
|
|
||||||
public delegate void ActorChange( Actor which );
|
|
||||||
public event ActorChange? ActorChanged;
|
|
||||||
|
|
||||||
public void AddPlayerToWatch( string playerName )
|
|
||||||
{
|
|
||||||
if( !_equip.ContainsKey( playerName ) )
|
|
||||||
{
|
|
||||||
_equip[ playerName ] = new CharEquipment();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemovePlayerFromWatch( string playerName )
|
|
||||||
{
|
|
||||||
_equip.Remove( playerName );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetActorWatch( bool on )
|
|
||||||
{
|
|
||||||
if( on )
|
|
||||||
{
|
|
||||||
EnableActorWatch();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DisableActorWatch();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void EnableActorWatch()
|
|
||||||
{
|
|
||||||
_pi.Framework.OnUpdateEvent += OnFrameworkUpdate;
|
|
||||||
_pi.ClientState.TerritoryChanged += OnTerritoryChange;
|
|
||||||
_pi.ClientState.OnLogout += OnLogout;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DisableActorWatch()
|
|
||||||
{
|
|
||||||
_pi.Framework.OnUpdateEvent -= OnFrameworkUpdate;
|
|
||||||
_pi.ClientState.TerritoryChanged -= OnTerritoryChange;
|
|
||||||
_pi.ClientState.OnLogout -= OnLogout;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
=> DisableActorWatch();
|
|
||||||
|
|
||||||
private void OnTerritoryChange( object _1, ushort _2 )
|
|
||||||
=> Clear();
|
|
||||||
|
|
||||||
private void OnLogout( object _1, object _2 )
|
|
||||||
=> Clear();
|
|
||||||
|
|
||||||
public void Clear()
|
|
||||||
{
|
|
||||||
foreach( var kvp in _equip )
|
|
||||||
{
|
|
||||||
kvp.Value.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
_frameTicker = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnFrameworkUpdate( object framework )
|
|
||||||
{
|
|
||||||
var actors = _pi.ClientState.Actors;
|
|
||||||
var gPoseActor = actors[ ActorRefresher.GPosePlayerActorIdx ];
|
|
||||||
if( gPoseActor == null )
|
|
||||||
{
|
|
||||||
if( _lastGPoseAddress != IntPtr.Zero && actors[ 0 ] != null && _equip.ContainsKey( actors[ 0 ].Name ) )
|
|
||||||
{
|
|
||||||
ActorChanged?.Invoke( actors[ 0 ] );
|
|
||||||
}
|
|
||||||
|
|
||||||
_lastGPoseAddress = IntPtr.Zero;
|
|
||||||
}
|
|
||||||
else if( gPoseActor.Address != _lastGPoseAddress )
|
|
||||||
{
|
|
||||||
_lastGPoseAddress = gPoseActor.Address;
|
|
||||||
if( _equip.ContainsKey( gPoseActor.Name ) )
|
|
||||||
{
|
|
||||||
ActorChanged?.Invoke( gPoseActor );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for( var i = 0; i < ActorsPerFrame; ++i )
|
|
||||||
{
|
|
||||||
_frameTicker = _frameTicker < actors.Length - 2
|
|
||||||
? _frameTicker + 2
|
|
||||||
: 0;
|
|
||||||
|
|
||||||
var actor = _frameTicker == 0 && gPoseActor != null ? gPoseActor : actors[ _frameTicker ];
|
|
||||||
if( actor == null
|
|
||||||
|| actor.ObjectKind != ObjectKind.Player
|
|
||||||
|| actor.Name == null
|
|
||||||
|| actor.Name.Length == 0 )
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( _equip.TryGetValue( actor.Name, out var equip ) && !equip.CompareAndUpdate( actor ) )
|
|
||||||
{
|
|
||||||
ActorChanged?.Invoke( actor );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -75,6 +75,7 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Penumbra.GameData\Penumbra.GameData.csproj" />
|
<ProjectReference Include="..\Penumbra.GameData\Penumbra.GameData.csproj" />
|
||||||
|
<ProjectReference Include="..\Penumbra.PlayerWatch\Penumbra.PlayerWatch.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ using Penumbra.API;
|
||||||
using Penumbra.Interop;
|
using Penumbra.Interop;
|
||||||
using Penumbra.Meta.Files;
|
using Penumbra.Meta.Files;
|
||||||
using Penumbra.Mods;
|
using Penumbra.Mods;
|
||||||
|
using Penumbra.PlayerWatch;
|
||||||
using Penumbra.UI;
|
using Penumbra.UI;
|
||||||
using Penumbra.Util;
|
using Penumbra.Util;
|
||||||
|
|
||||||
|
|
@ -30,7 +31,7 @@ namespace Penumbra
|
||||||
public SettingsInterface SettingsInterface { get; set; } = null!;
|
public SettingsInterface SettingsInterface { get; set; } = null!;
|
||||||
public MusicManager SoundShit { get; set; } = null!;
|
public MusicManager SoundShit { get; set; } = null!;
|
||||||
public ActorRefresher ActorRefresher { get; set; } = null!;
|
public ActorRefresher ActorRefresher { get; set; } = null!;
|
||||||
public PlayerWatcher PlayerWatcher { get; set; } = null!;
|
public IPlayerWatcher PlayerWatcher { get; set; } = null!;
|
||||||
|
|
||||||
private WebServer? _webServer;
|
private WebServer? _webServer;
|
||||||
|
|
||||||
|
|
@ -46,7 +47,7 @@ namespace Penumbra
|
||||||
SoundShit.DisableStreaming();
|
SoundShit.DisableStreaming();
|
||||||
|
|
||||||
var gameUtils = Service< GameResourceManagement >.Set( PluginInterface );
|
var gameUtils = Service< GameResourceManagement >.Set( PluginInterface );
|
||||||
PlayerWatcher = new PlayerWatcher( PluginInterface );
|
PlayerWatcher = PlayerWatchFactory.Create( PluginInterface );
|
||||||
Service< MetaDefaults >.Set( PluginInterface );
|
Service< MetaDefaults >.Set( PluginInterface );
|
||||||
var modManager = Service< ModManager >.Set( this );
|
var modManager = Service< ModManager >.Set( this );
|
||||||
|
|
||||||
|
|
@ -78,7 +79,7 @@ namespace Penumbra
|
||||||
|
|
||||||
if( Configuration.EnableActorWatch && Configuration.IsEnabled )
|
if( Configuration.EnableActorWatch && Configuration.IsEnabled )
|
||||||
{
|
{
|
||||||
PlayerWatcher.EnableActorWatch();
|
PlayerWatcher.Enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayerWatcher.ActorChanged += a =>
|
PlayerWatcher.ActorChanged += a =>
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ namespace Penumbra.UI
|
||||||
_base._plugin.ActorRefresher.RedrawAll( enabled ? Redraw.WithSettings : Redraw.WithoutSettings );
|
_base._plugin.ActorRefresher.RedrawAll( enabled ? Redraw.WithSettings : Redraw.WithoutSettings );
|
||||||
if( _config.EnableActorWatch )
|
if( _config.EnableActorWatch )
|
||||||
{
|
{
|
||||||
_base._plugin.PlayerWatcher.SetActorWatch( enabled );
|
_base._plugin.PlayerWatcher.SetStatus( enabled );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -164,7 +164,7 @@ namespace Penumbra.UI
|
||||||
{
|
{
|
||||||
_config.EnableActorWatch = enabled;
|
_config.EnableActorWatch = enabled;
|
||||||
_configChanged = true;
|
_configChanged = true;
|
||||||
_base._plugin.PlayerWatcher.SetActorWatch( enabled );
|
_base._plugin.PlayerWatcher.SetStatus( enabled );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ImGui.IsItemHovered() )
|
if( ImGui.IsItemHovered() )
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue