refactor: use Dalamud API for targeting

This commit is contained in:
Anna 2020-08-04 21:03:26 -04:00
parent 504a1a0fac
commit 4d57e3c150
3 changed files with 43 additions and 36 deletions

View File

@ -71,6 +71,7 @@
<DesignTime>True</DesignTime> <DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon> <DependentUpon>Resources.resx</DependentUpon>
</Compile> </Compile>
<Compile Include="Util.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="Properties\Resources.resx"> <EmbeddedResource Include="Properties\Resources.resx">

View File

@ -21,7 +21,7 @@ namespace PeepingTom {
private readonly DalamudPluginInterface pi; private readonly DalamudPluginInterface pi;
private readonly List<Targeter> previousTargeters = new List<Targeter>(); private readonly List<Targeter> previousTargeters = new List<Targeter>();
private IntPtr? previousFocus = null; private Optional<Actor> previousFocus = new Optional<Actor>();
private long soundLastPlayed = 0; private long soundLastPlayed = 0;
private int lastTargetAmount = 0; private int lastTargetAmount = 0;
@ -323,7 +323,7 @@ namespace PeepingTom {
// .Skip(1) // .Skip(1)
// .Select(actor => actor as PlayerCharacter) // .Select(actor => actor as PlayerCharacter)
// .Take(2)) { // .Take(2)) {
// this.AddEntry(p); // this.AddEntry(new Targeter(p), p, ref anyHovered);
//} //}
foreach (PlayerCharacter targeter in targeting) { foreach (PlayerCharacter targeter in targeting) {
if (this.config.KeepHistory) { if (this.config.KeepHistory) {
@ -333,7 +333,7 @@ namespace PeepingTom {
} }
this.previousTargeters.Insert(0, new Targeter(targeter)); this.previousTargeters.Insert(0, new Targeter(targeter));
} }
this.AddEntry(new Targeter(targeter), targeter.Address, ref anyHovered); this.AddEntry(new Targeter(targeter), targeter, ref anyHovered);
} }
if (this.config.KeepHistory) { if (this.config.KeepHistory) {
// only keep the configured number of previous targeters (ignoring ones that are currently targeting) // only keep the configured number of previous targeters (ignoring ones that are currently targeting)
@ -352,38 +352,38 @@ namespace PeepingTom {
} }
ImGui.ListBoxFooter(); ImGui.ListBoxFooter();
} }
if (this.config.FocusTargetOnHover && !anyHovered && this.previousFocus != null) { if (this.config.FocusTargetOnHover && !anyHovered && this.previousFocus.Get(out Actor previousFocus)) {
// old focus target still here if (previousFocus == null) {
if (this.pi.ClientState.Actors.Any(actor => actor.Address == this.previousFocus)) { this.pi.ClientState.Targets.SetFocusTarget(null);
this.FocusTarget((IntPtr)this.previousFocus);
} else { } else {
this.FocusTarget(IntPtr.Zero); Actor actor = this.pi.ClientState.Actors.FirstOrDefault(a => a.ActorId == previousFocus.ActorId);
// either target the actor if still present or target nothing
this.pi.ClientState.Targets.SetFocusTarget(actor);
} }
this.previousFocus = null; this.previousFocus = new Optional<Actor>();
} }
ImGui.Text("Click to link or right click to target."); ImGui.Text("Click to link or right click to target.");
ImGui.End(); ImGui.End();
} }
} }
private void AddEntry(Targeter targeter, IntPtr? address, ref bool anyHovered, ImGuiSelectableFlags flags = ImGuiSelectableFlags.None) { private void AddEntry(Targeter targeter, Actor actor, ref bool anyHovered, ImGuiSelectableFlags flags = ImGuiSelectableFlags.None) {
ImGui.Selectable(targeter.Name, false, flags); ImGui.Selectable(targeter.Name, false, flags);
bool hover = ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled); bool hover = ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled);
anyHovered |= hover; anyHovered |= hover;
bool left = hover && ImGui.IsMouseClicked(0); bool left = hover && ImGui.IsMouseClicked(0);
bool right = hover && ImGui.IsMouseClicked(1); bool right = hover && ImGui.IsMouseClicked(1);
if (address == null) { if (actor == null) {
address = this.pi.ClientState.Actors actor = this.pi.ClientState.Actors
.Where(actor => actor.ActorId == targeter.ActorId) .Where(a => a.ActorId == targeter.ActorId)
.FirstOrDefault() .FirstOrDefault();
?.Address;
} }
if (this.config.FocusTargetOnHover && hover && address != null) { if (this.config.FocusTargetOnHover && hover && actor != null) {
if (this.previousFocus == null) { if (!this.previousFocus.Present) {
this.previousFocus = this.GetRawFocusTarget(); this.previousFocus = new Optional<Actor>(this.pi.ClientState.Targets.FocusTarget);
} }
this.FocusTarget(address.Value); this.pi.ClientState.Targets.SetFocusTarget(actor);
} }
if (left) { if (left) {
@ -392,8 +392,8 @@ namespace PeepingTom {
this.pi.Framework.Gui.Chat.PrintChat(new XivChatEntry { this.pi.Framework.Gui.Chat.PrintChat(new XivChatEntry {
MessageBytes = new SeString(payloads).Encode() MessageBytes = new SeString(payloads).Encode()
}); });
} else if (right && address != null) { } else if (right && actor != null) {
this.Target(address.Value); this.pi.ClientState.Targets.SetCurrentTarget(actor);
} }
} }
@ -444,21 +444,6 @@ namespace PeepingTom {
.FirstOrDefault(); .FirstOrDefault();
} }
private void Target(IntPtr actor) {
IntPtr targetPtr = this.pi.TargetModuleScanner.ResolveRelativeAddress(this.pi.TargetModuleScanner.Module.BaseAddress, 0x1c64150);
Marshal.WriteIntPtr(targetPtr, actor);
}
private void FocusTarget(IntPtr ptr) {
IntPtr targetPtr = this.pi.TargetModuleScanner.ResolveRelativeAddress(this.pi.TargetModuleScanner.Module.BaseAddress, 0x1c641c8);
Marshal.WriteIntPtr(targetPtr, ptr);
}
private IntPtr GetRawFocusTarget() {
IntPtr targetPtr = this.pi.TargetModuleScanner.ResolveRelativeAddress(this.pi.TargetModuleScanner.Module.BaseAddress, 0x1c641c8);
return Marshal.ReadIntPtr(targetPtr);
}
private bool CanPlaySound() { private bool CanPlaySound() {
if (this.soundLastPlayed == 0) { if (this.soundLastPlayed == 0) {
return true; return true;

21
Peeping Tom/Util.cs Normal file
View File

@ -0,0 +1,21 @@
namespace PeepingTom {
[System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1716:Identifiers should not match keywords")]
public class Optional<T> {
public bool Present { get; private set; }
private readonly T value;
public Optional(T value) {
this.value = value;
this.Present = true;
}
public Optional() {
this.Present = false;
}
public bool Get(out T value) {
value = this.value;
return this.Present;
}
}
}