Create a interface for a basic API to use the ActorRefresh and register actions to clicks on changed items (for now).

This commit is contained in:
Ottermandias 2021-07-26 15:56:09 +02:00
parent 6c26943cb7
commit 2b46397e8e
12 changed files with 225 additions and 43 deletions

View file

@ -0,0 +1,32 @@
using System;
using Dalamud.Game.ClientState.Actors.Types;
namespace Penumbra.Api
{
public interface IPenumbraApiBase
{
public int ApiVersion { get; }
public bool Valid { get; }
}
public enum MouseButton
{
None,
Left,
Right,
Middle,
}
public delegate void ChangedItemHover( object? item );
public delegate void ChangedItemClick( MouseButton button, object? item );
public interface IPenumbraApi : IPenumbraApiBase
{
public event ChangedItemHover? ChangedItemTooltip;
public event ChangedItemClick? ChangedItemClicked;
public void RedrawActor( string name, RedrawType setting );
public void RedrawActor( Actor actor, RedrawType setting );
public void RedrawAll( RedrawType setting );
}
}

View file

@ -0,0 +1,41 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net472</TargetFramework>
<LangVersion>preview</LangVersion>
<AssemblyTitle>Penumbra.Api</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>

View file

@ -0,0 +1,12 @@
namespace Penumbra.Api
{
public enum RedrawType
{
WithoutSettings,
WithSettings,
OnlyWithSettings,
Unload,
RedrawWithoutSettings,
RedrawWithSettings,
}
}

View file

@ -12,6 +12,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProject
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.Api", "Penumbra.API\Penumbra.Api.csproj", "{EE8C148E-BF59-43FB-89FC-4CADC9047FDF}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Penumbra.PlayerWatch", "Penumbra.PlayerWatch\Penumbra.PlayerWatch.csproj", "{01685BD8-8847-4B49-BF90-1683B4C76B0E}"
EndProject
Global
@ -28,6 +30,10 @@ Global
{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.Build.0 = Release|Any CPU
{EE8C148E-BF59-43FB-89FC-4CADC9047FDF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EE8C148E-BF59-43FB-89FC-4CADC9047FDF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EE8C148E-BF59-43FB-89FC-4CADC9047FDF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EE8C148E-BF59-43FB-89FC-4CADC9047FDF}.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

View file

@ -6,7 +6,7 @@ using EmbedIO.WebApi;
using Penumbra.Mods;
using Penumbra.Util;
namespace Penumbra.API
namespace Penumbra.Api
{
public class ModsController : WebApiController
{

View file

@ -0,0 +1,72 @@
using System;
using System.Linq;
using Dalamud.Game.ClientState.Actors.Types;
using ImGuiNET;
namespace Penumbra.Api
{
public class PenumbraApi : IDisposable, IPenumbraApi
{
public int ApiVersion { get; } = 1;
private bool _initialized = false;
private readonly Plugin _plugin;
public PenumbraApi( Plugin penumbra )
{
_plugin = penumbra;
//_plugin.SettingsInterface.ChangedItemClicked += TriggerChangedItemClicked;
_initialized = true;
}
public void Dispose()
{
//_plugin.SettingsInterface.ChangedItemClicked -= TriggerChangedItemClicked;
_initialized = false;
}
public event ChangedItemClick? ChangedItemClicked;
public event ChangedItemHover? ChangedItemTooltip;
internal bool HasTooltip
=> ChangedItemTooltip != null;
internal void InvokeTooltip( object? it )
=> ChangedItemTooltip?.Invoke( it );
internal void InvokeClick( MouseButton button, object? it )
=> ChangedItemClicked?.Invoke( button, it );
private void CheckInitialized()
{
if( !_initialized )
{
throw new Exception( "PluginShare is not initialized." );
}
}
public void RedrawActor( string name, RedrawType setting )
{
CheckInitialized();
_plugin.ActorRefresher.RedrawActor( name, setting );
}
public void RedrawActor( Actor? actor, RedrawType setting )
{
CheckInitialized();
_plugin.ActorRefresher.RedrawActor( actor, setting );
}
public void RedrawAll( RedrawType setting )
{
CheckInitialized();
_plugin.ActorRefresher.RedrawAll( setting );
}
public bool Valid
=> _initialized;
}
}

View file

@ -7,20 +7,11 @@ using System.Threading.Tasks;
using Dalamud.Game.ClientState;
using Dalamud.Game.ClientState.Actors.Types;
using Dalamud.Plugin;
using Penumbra.Api;
using Penumbra.Mods;
namespace Penumbra.Interop
{
public enum Redraw
{
WithoutSettings,
WithSettings,
OnlyWithSettings,
Unload,
RedrawWithoutSettings,
RedrawWithSettings,
}
public class ActorRefresher : IDisposable
{
private delegate void ManipulateDraw( IntPtr actor );
@ -43,14 +34,14 @@ namespace Penumbra.Interop
private readonly DalamudPluginInterface _pi;
private readonly ModManager _mods;
private readonly Queue< (int actorId, string name, Redraw s) > _actorIds = new();
private readonly Queue< (int actorId, string name, RedrawType s) > _actorIds = new();
private int _currentFrame = 0;
private bool _changedSettings = false;
private int _currentActorId = -1;
private string? _currentActorName = null;
private LoadingFlags _currentActorStartState = 0;
private Redraw _currentActorRedraw = Redraw.Unload;
private RedrawType _currentActorRedrawType = RedrawType.Unload;
public static IntPtr RenderPtr( Actor actor )
=> actor.Address + RenderModeOffset;
@ -165,7 +156,7 @@ namespace Penumbra.Interop
var (id, name, s) = _actorIds.Dequeue();
_currentActorName = name;
_currentActorId = id;
_currentActorRedraw = s;
_currentActorRedrawType = s;
var (actor, idx) = FindCurrentActor();
if( actor == null )
{
@ -189,30 +180,30 @@ namespace Penumbra.Interop
return;
}
switch( _currentActorRedraw )
switch( _currentActorRedrawType )
{
case Redraw.Unload:
case RedrawType.Unload:
WriteInvisible( actor, idx );
_currentFrame = 0;
break;
case Redraw.RedrawWithSettings:
case RedrawType.RedrawWithSettings:
ChangeSettings();
++_currentFrame;
break;
case Redraw.RedrawWithoutSettings:
case RedrawType.RedrawWithoutSettings:
WriteVisible( actor, idx );
_currentFrame = 0;
break;
case Redraw.WithoutSettings:
case RedrawType.WithoutSettings:
WriteInvisible( actor, idx );
++_currentFrame;
break;
case Redraw.WithSettings:
case RedrawType.WithSettings:
ChangeSettings();
WriteInvisible( actor, idx );
++_currentFrame;
break;
case Redraw.OnlyWithSettings:
case RedrawType.OnlyWithSettings:
ChangeSettings();
if( !_changedSettings )
{
@ -283,7 +274,7 @@ namespace Penumbra.Interop
}
}
private void RedrawActorIntern( int actorId, string actorName, Redraw settings )
private void RedrawActorIntern( int actorId, string actorName, RedrawType settings )
{
if( _actorIds.Contains( ( actorId, actorName, settings ) ) )
{
@ -297,7 +288,7 @@ namespace Penumbra.Interop
}
}
public void RedrawActor( Actor? actor, Redraw settings = Redraw.WithSettings )
public void RedrawActor( Actor? actor, RedrawType settings = RedrawType.WithSettings )
{
if( actor != null )
{
@ -330,10 +321,10 @@ namespace Penumbra.Interop
};
}
public void RedrawActor( string name, Redraw settings = Redraw.WithSettings )
public void RedrawActor( string name, RedrawType settings = RedrawType.WithSettings )
=> RedrawActor( GetName( name ), settings );
public void RedrawAll( Redraw settings = Redraw.WithSettings )
public void RedrawAll( RedrawType settings = RedrawType.WithSettings )
{
Clear();
foreach( var actor in _pi.ClientState.Actors )
@ -365,7 +356,7 @@ namespace Penumbra.Interop
Clear();
UnloadAll();
await Task.Delay( UnloadAllRedrawDelay );
RedrawAll( Redraw.RedrawWithSettings );
RedrawAll( RedrawType.RedrawWithSettings );
}
public async void UnloadAtOnceRedrawWithoutSettings()

View file

@ -74,6 +74,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Penumbra.API\Penumbra.Api.csproj" />
<ProjectReference Include="..\Penumbra.GameData\Penumbra.GameData.csproj" />
<ProjectReference Include="..\Penumbra.PlayerWatch\Penumbra.PlayerWatch.csproj" />
</ItemGroup>

View file

@ -2,7 +2,9 @@ using Dalamud.Game.Command;
using Dalamud.Plugin;
using EmbedIO;
using EmbedIO.WebApi;
using Penumbra.API;
using ImGuiNET;
using Lumina.Excel.GeneratedSheets;
using Penumbra.Api;
using Penumbra.Interop;
using Penumbra.Meta.Files;
using Penumbra.Mods;
@ -32,6 +34,8 @@ namespace Penumbra
public MusicManager SoundShit { get; set; } = null!;
public ActorRefresher ActorRefresher { get; set; } = null!;
public IPlayerWatcher PlayerWatcher { get; set; } = null!;
public PenumbraApi Api { get; set; } = null!;
private WebServer? _webServer;
@ -85,7 +89,28 @@ namespace Penumbra
PlayerWatcher.ActorChanged += a =>
{
PluginLog.Debug( "Triggered Redraw of {Actor}.", a.Name );
ActorRefresher.RedrawActor( a, Redraw.OnlyWithSettings );
ActorRefresher.RedrawActor( a, RedrawType.OnlyWithSettings );
};
Api = new PenumbraApi( this );
SubscribeItemLinks();
}
private void SubscribeItemLinks()
{
Api.ChangedItemTooltip += it =>
{
if( it is Item )
{
ImGui.Text( "Left Click to create an item link in chat." );
}
};
Api.ChangedItemClicked += ( button, it ) =>
{
if( button == MouseButton.Left && it is Item item )
{
ChatUtil.LinkItem( item );
}
};
}

View file

@ -7,6 +7,7 @@ using System.Reflection;
using System.Runtime.InteropServices;
using Dalamud.Game.ClientState.Actors.Types;
using ImGuiNET;
using Penumbra.Api;
using Penumbra.GameData;
using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs;
@ -155,10 +156,10 @@ namespace Penumbra.UI
return;
}
var queue = ( Queue< (int, string, Redraw) >? )_plugin.ActorRefresher.GetType()
var queue = ( Queue< (int, string, RedrawType) >? )_plugin.ActorRefresher.GetType()
.GetField( "_actorIds", BindingFlags.Instance | BindingFlags.NonPublic )
?.GetValue( _plugin.ActorRefresher )
?? new Queue< (int, string, Redraw) >();
?? new Queue< (int, string, RedrawType) >();
var currentFrame = ( int? )_plugin.ActorRefresher.GetType()
.GetField( "_currentFrame", BindingFlags.Instance | BindingFlags.NonPublic )
@ -180,7 +181,7 @@ namespace Penumbra.UI
.GetField( "_currentActorStartState", BindingFlags.Instance | BindingFlags.NonPublic )
?.GetValue( _plugin.ActorRefresher );
var currentActorRedraw = ( Redraw? )_plugin.ActorRefresher.GetType()
var currentActorRedraw = ( RedrawType? )_plugin.ActorRefresher.GetType()
.GetField( "_currentActorRedraw", BindingFlags.Instance | BindingFlags.NonPublic )
?.GetValue( _plugin.ActorRefresher );

View file

@ -4,6 +4,7 @@ using System.Linq;
using Dalamud.Interface;
using ImGuiNET;
using Lumina.Excel.GeneratedSheets;
using Penumbra.Api;
using Penumbra.GameData.Util;
using Penumbra.Meta;
using Penumbra.Mod;
@ -178,21 +179,20 @@ namespace Penumbra.UI
{
foreach( var item in Mod.Data.ChangedItems )
{
var ret = ImGui.Selectable( item.Key );
var it = item.Value as Item;
if( it == null )
var ret = ImGui.Selectable( item.Key ) ? MouseButton.Left : MouseButton.None;
ret = ImGui.IsItemClicked( ImGuiMouseButton.Right ) ? MouseButton.Right : ret;
ret = ImGui.IsItemClicked( ImGuiMouseButton.Middle ) ? MouseButton.Middle : ret;
if( ret != MouseButton.None )
{
continue;
_base._plugin.Api.InvokeClick( ret, item.Value );
}
if( ret )
if( _base._plugin.Api.HasTooltip && ImGui.IsItemHovered() )
{
ChatUtil.LinkItem( it );
}
if( ImGui.IsItemHovered() )
{
ImGui.SetTooltip( "Left click to create link in chat." );
ImGui.BeginTooltip();
_base._plugin.Api.InvokeTooltip( item.Value );
ImGui.EndTooltip();
}
}

View file

@ -4,6 +4,7 @@ using System.IO;
using System.Text.RegularExpressions;
using Dalamud.Plugin;
using ImGuiNET;
using Penumbra.Api;
using Penumbra.Interop;
using Penumbra.Mods;
using Penumbra.Util;
@ -80,7 +81,7 @@ namespace Penumbra.UI
{
_config.IsEnabled = enabled;
_configChanged = true;
_base._plugin.ActorRefresher.RedrawAll( enabled ? Redraw.WithSettings : Redraw.WithoutSettings );
_base._plugin.ActorRefresher.RedrawAll( enabled ? RedrawType.WithSettings : RedrawType.WithoutSettings );
if( _config.EnableActorWatch )
{
_base._plugin.PlayerWatcher.SetStatus( enabled );