mirror of
https://github.com/xivdev/Penumbra.git
synced 2026-01-02 05:43:42 +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
|
|
@ -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>
|
||||
<ProjectReference Include="..\Penumbra.GameData\Penumbra.GameData.csproj" />
|
||||
<ProjectReference Include="..\Penumbra.PlayerWatch\Penumbra.PlayerWatch.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using Penumbra.API;
|
|||
using Penumbra.Interop;
|
||||
using Penumbra.Meta.Files;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.PlayerWatch;
|
||||
using Penumbra.UI;
|
||||
using Penumbra.Util;
|
||||
|
||||
|
|
@ -30,7 +31,7 @@ namespace Penumbra
|
|||
public SettingsInterface SettingsInterface { get; set; } = null!;
|
||||
public MusicManager SoundShit { get; set; } = null!;
|
||||
public ActorRefresher ActorRefresher { get; set; } = null!;
|
||||
public PlayerWatcher PlayerWatcher { get; set; } = null!;
|
||||
public IPlayerWatcher PlayerWatcher { get; set; } = null!;
|
||||
|
||||
private WebServer? _webServer;
|
||||
|
||||
|
|
@ -46,7 +47,7 @@ namespace Penumbra
|
|||
SoundShit.DisableStreaming();
|
||||
|
||||
var gameUtils = Service< GameResourceManagement >.Set( PluginInterface );
|
||||
PlayerWatcher = new PlayerWatcher( PluginInterface );
|
||||
PlayerWatcher = PlayerWatchFactory.Create( PluginInterface );
|
||||
Service< MetaDefaults >.Set( PluginInterface );
|
||||
var modManager = Service< ModManager >.Set( this );
|
||||
|
||||
|
|
@ -78,7 +79,7 @@ namespace Penumbra
|
|||
|
||||
if( Configuration.EnableActorWatch && Configuration.IsEnabled )
|
||||
{
|
||||
PlayerWatcher.EnableActorWatch();
|
||||
PlayerWatcher.Enable();
|
||||
}
|
||||
|
||||
PlayerWatcher.ActorChanged += a =>
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ namespace Penumbra.UI
|
|||
_base._plugin.ActorRefresher.RedrawAll( enabled ? Redraw.WithSettings : Redraw.WithoutSettings );
|
||||
if( _config.EnableActorWatch )
|
||||
{
|
||||
_base._plugin.PlayerWatcher.SetActorWatch( enabled );
|
||||
_base._plugin.PlayerWatcher.SetStatus( enabled );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -164,7 +164,7 @@ namespace Penumbra.UI
|
|||
{
|
||||
_config.EnableActorWatch = enabled;
|
||||
_configChanged = true;
|
||||
_base._plugin.PlayerWatcher.SetActorWatch( enabled );
|
||||
_base._plugin.PlayerWatcher.SetStatus( enabled );
|
||||
}
|
||||
|
||||
if( ImGui.IsItemHovered() )
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue