Skip to content

Commit

Permalink
1.1.2
Browse files Browse the repository at this point in the history
  • Loading branch information
haroldiedema committed Aug 14, 2024
1 parent 56fd497 commit 3d1e0a9
Show file tree
Hide file tree
Showing 7 changed files with 473 additions and 23 deletions.
4 changes: 2 additions & 2 deletions Umbra.CounterSpyPlugin/Umbra.CounterSpyPlugin.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
<PropertyGroup>
<DalamudLibPath>$(appdata)\XIVLauncher\addon\Hooks\dev\</DalamudLibPath>
</PropertyGroup>
<!-- <PropertyGroup>-->
<PropertyGroup>
<!-- <UmbraLibPath>Z:\FFXIV-plugins\una-xiv-plugins\Umbra\out\Release\</UmbraLibPath>-->
<!-- </PropertyGroup>-->
</PropertyGroup>
<PropertyGroup>
<UmbraLibPath>$([System.IO.Directory]::GetDirectories($(appdata)\XIVLauncher\installedPlugins\Umbra\)[0])\</UmbraLibPath>
</PropertyGroup>
Expand Down
47 changes: 26 additions & 21 deletions Umbra.CounterSpyPlugin/src/CounterSpyMarker.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System.Collections.Generic;
using System.Linq;
using Dalamud.Game.ClientState.Objects.Enums;
using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.Plugin.Services;
using Umbra.Common;
using Umbra.Game;
Expand All @@ -9,10 +11,10 @@ namespace Umbra.CounterSpyPlugin;

[Service]
internal sealed class CounterSpyMarker(
IObjectTable objectTable,
IClientState clientState,
IPlayer player,
IZoneManager zoneManager
CounterSpyRepository repository,
IPlayer player,
IZoneManager zoneManager,
CounterSpyRenderer renderer

Check warning on line 17 in Umbra.CounterSpyPlugin/src/CounterSpyMarker.cs

View workflow job for this annotation

GitHub Actions / Build

Parameter 'renderer' is unread.

Check warning on line 17 in Umbra.CounterSpyPlugin/src/CounterSpyMarker.cs

View workflow job for this annotation

GitHub Actions / Build

Parameter 'renderer' is unread.
) : WorldMarkerFactory
{
public override string Id => "Umbra_CounterSpyMarker";
Expand Down Expand Up @@ -47,6 +49,12 @@ public override List<IMarkerConfigVariable> GetConfigVariables()
null,
true
),
new BooleanMarkerConfigVariable(
"ShowEffect",
"Show the eye of Sauron on the player targeting you.",
null,
true
),
new IntegerMarkerConfigVariable(
"PlayerIconId",
"Icon ID for players targeting you",
Expand All @@ -67,37 +75,34 @@ public override List<IMarkerConfigVariable> GetConfigVariables()
[OnTick]
private void OnTick()
{
if (null == clientState.LocalPlayer
|| !zoneManager.HasCurrentZone
if (!zoneManager.HasCurrentZone
|| player.IsBetweenAreas
|| player.IsInCutscene
|| player.IsDead
|| player.IsOccupied
|| !GetConfigValue<bool>("Enabled")
) {
) {
RemoveAllMarkers();
return;
}

ulong localPlayerId = clientState.LocalPlayer.GameObjectId;
uint mapId = zoneManager.CurrentZone.Id;
CounterSpyRenderer.Enabled = GetConfigValue<bool>("ShowEffect");

uint mapId = zoneManager.CurrentZone.Id;

List<string> usedIds = [];

foreach (var obj in objectTable) {
if (!obj.IsValid()
|| obj.IsDead
|| obj.GameObjectId == localPlayerId
|| obj.TargetObjectId != localPlayerId
|| obj.ObjectKind is not (ObjectKind.Player or ObjectKind.BattleNpc)
) continue;
List<IGameObject> targets = repository.GetTargets(
GetConfigValue<bool>("EnablePlayers"),
GetConfigValue<bool>("EnableNPCs")
);

switch (obj.ObjectKind) {
case ObjectKind.Player when !GetConfigValue<bool>("EnablePlayers"):
case ObjectKind.BattleNpc when !GetConfigValue<bool>("EnableNPCs"):
continue;
}
if (targets.Count == 0) {
RemoveAllMarkers();
return;
}

foreach (var obj in targets) {
var key = $"CounterSpyMarker_{mapId}_{obj.GameObjectId}";
usedIds.Add(key);

Expand Down
65 changes: 65 additions & 0 deletions Umbra.CounterSpyPlugin/src/CounterSpyRenderer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using System.Collections.Generic;
using System.Numerics;
using Dalamud.Game.ClientState.Objects.SubKinds;
using Dalamud.Game.ClientState.Objects.Types;
using FFXIVClientStructs.FFXIV.Client.Game.Object;
using Umbra.Common;
using Umbra.CounterSpyPlugin.Interop;

namespace Umbra.CounterSpyPlugin;

[Service]
internal sealed class CounterSpyRenderer(
CounterSpyRepository repository,
VfxManager vfx
)
{
public static bool Enabled { get; set; } = true;

private readonly Dictionary<ulong, nint> _vfxList = [];

[OnDraw]
private void OnDraw()
{
if (!Enabled) return;

foreach (var obj in repository.GetTargets(true, true)) {
if (obj is IPlayerCharacter p && !_vfxList.ContainsKey(obj.GameObjectId)) {
SpawnVfx(p);
}
}
}

[OnTick]
private unsafe void OnTick()
{
foreach ((ulong id, nint ptr) in _vfxList) {
var s = (VfxStruct*)ptr;
if (s == null) continue;

GameObject* obj = GameObjectManager.Instance()->Objects.GetObjectByGameObjectId(id);
if (obj == null || !Enabled) {
vfx.RemoveVfx(ptr);
_vfxList.Remove(id);
continue;
}

if (!repository.IsTargetingYou(id)) {
vfx.RemoveVfx(ptr);
_vfxList.Remove(id);
}
}
}

private void SpawnVfx(IGameObject player)
{
if (_vfxList.ContainsKey(player.GameObjectId)) return;

nint ptr = vfx.PlayVfx("vfx/common/eff/sta_death00_m1.avfx", player);
if (ptr == 0) return;

Logger.Info($"Playing VFX for {player.Name}");

_vfxList[player.GameObjectId] = ptr;
}
}
78 changes: 78 additions & 0 deletions Umbra.CounterSpyPlugin/src/CounterSpyRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Dalamud.Game.ClientState.Objects.Enums;
using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.Plugin.Services;
using Umbra.Common;
using Umbra.Game;

namespace Umbra.CounterSpyPlugin;

[Service]
internal sealed class CounterSpyRepository(
IClientState clientState,
IObjectTable objectTable,
IPlayer player
) : IDisposable
{
private readonly Dictionary<ulong, IGameObject> _objects = [];

public List<IGameObject> GetTargets(bool players, bool npcs)
{
lock (_objects) {
return _objects
.Values.Where(
obj => (players && obj.ObjectKind == ObjectKind.Player)
|| (npcs && obj.ObjectKind == ObjectKind.BattleNpc)
)
.ToList();
}
}

public bool IsTargetingYou(ulong id)
{
lock (_objects) {
return _objects.ContainsKey(id);
}
}

[OnTick]
private void OnTick()
{
if (null == clientState.LocalPlayer) return;

lock (_objects) {
if (player.IsBetweenAreas || player.IsInCutscene) {
_objects.Clear();
return;
}

ulong playerId = clientState.LocalPlayer.GameObjectId;
List<ulong> ids = [];

foreach (var obj in objectTable) {
if (obj.IsValid()
&& obj.TargetObjectId > 0
&& obj.TargetObjectId != obj.GameObjectId
&& obj.TargetObjectId == playerId
&& !obj.IsDead
) {
ids.Add(obj.GameObjectId);
_objects[obj.GameObjectId] = obj;
}
}

foreach (ulong obj in _objects.Keys.ToArray()) {
if (!ids.Contains(obj)) {
_objects.Remove(obj);
}
}
}
}

public void Dispose()
{
_objects.Clear();
}
}
Loading

0 comments on commit 3d1e0a9

Please sign in to comment.