Some cleanup

This commit is contained in:
r00telement
2021-12-12 05:42:35 +00:00
parent f6be605a0c
commit 0406557d4d
7 changed files with 236 additions and 127 deletions

View File

@@ -14,9 +14,11 @@ namespace PlayerTags.Data
public Dictionary<string, Role> RolesByJobAbbreviation { get; }
public Dictionary<string, InheritableData> AllTagsChanges { get; }
public Dictionary<string, InheritableData> AllRoleTagsChanges { get; }
public Dictionary<Role, Dictionary<string, InheritableData>> RoleTagsChanges { get; }
public Dictionary<string, Dictionary<string, InheritableData>> JobTagsChanges { get; }
public Dictionary<string, InheritableData> AllCustomTagsChanges { get; }
public DefaultPluginData()

View File

@@ -13,50 +13,6 @@ namespace PlayerTags.Features
{
public class ChatTagTargetFeature : TagTargetFeature
{
private PluginConfiguration m_PluginConfiguration;
private PluginData m_PluginData;
public ChatTagTargetFeature(PluginConfiguration pluginConfiguration, PluginData pluginData)
: base(pluginConfiguration)
{
m_PluginConfiguration = pluginConfiguration;
m_PluginData = pluginData;
PluginServices.ChatGui.ChatMessage += Chat_ChatMessage;
}
public override void Dispose()
{
PluginServices.ChatGui.ChatMessage -= Chat_ChatMessage;
base.Dispose();
}
private void Chat_ChatMessage(XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled)
{
AddTagsToChat(sender, out _);
AddTagsToChat(message, out _);
}
protected override BitmapFontIcon? GetIcon(Tag tag)
{
if (tag.IsIconVisibleInChat.InheritedValue != null && tag.IsIconVisibleInChat.InheritedValue.Value)
{
return tag.Icon.InheritedValue;
}
return null;
}
protected override string? GetText(Tag tag)
{
if (tag.IsTextVisibleInChat.InheritedValue != null && tag.IsTextVisibleInChat.InheritedValue.Value)
{
return tag.Text.InheritedValue;
}
return null;
}
/// <summary>
/// A match found within a string.
/// </summary>
@@ -103,6 +59,50 @@ namespace PlayerTags.Features
}
}
private PluginConfiguration m_PluginConfiguration;
private PluginData m_PluginData;
public ChatTagTargetFeature(PluginConfiguration pluginConfiguration, PluginData pluginData)
: base(pluginConfiguration)
{
m_PluginConfiguration = pluginConfiguration;
m_PluginData = pluginData;
PluginServices.ChatGui.ChatMessage += Chat_ChatMessage;
}
public override void Dispose()
{
PluginServices.ChatGui.ChatMessage -= Chat_ChatMessage;
base.Dispose();
}
private void Chat_ChatMessage(XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled)
{
AddTagsToChat(sender, out _);
AddTagsToChat(message, out _);
}
protected override bool IsIconVisible(Tag tag)
{
if (tag.IsIconVisibleInChat.InheritedValue != null)
{
return tag.IsIconVisibleInChat.InheritedValue.Value;
}
return false;
}
protected override bool IsTextVisible(Tag tag)
{
if (tag.IsTextVisibleInChat.InheritedValue != null)
{
return tag.IsTextVisibleInChat.InheritedValue.Value;
}
return false;
}
/// <summary>
/// Searches the given string for game object matches.
/// </summary>
@@ -182,18 +182,12 @@ namespace PlayerTags.Features
// Add the job tag
if (m_PluginData.JobTags.TryGetValue(character.ClassJob.GameData.Abbreviation, out var jobTag))
{
bool isVisible = IsVisibleInActivity(jobTag) &&
(!(stringMatch.GameObject is PlayerCharacter playerCharacter) || IsVisibleForPlayer(jobTag, playerCharacter));
if (isVisible)
if (jobTag.TagPositionInChat.InheritedValue != null)
{
if (jobTag.TagPositionInChat.InheritedValue != null)
var payloads = GetPayloads(stringMatch.GameObject, jobTag);
if (payloads.Any())
{
var payloads = GetPayloads(jobTag);
if (payloads.Any())
{
AddPayloadChanges(jobTag.TagPositionInChat.InheritedValue.Value, payloads, stringChanges);
}
AddPayloadChanges(jobTag.TagPositionInChat.InheritedValue.Value, payloads, stringChanges);
}
}
}
@@ -216,20 +210,14 @@ namespace PlayerTags.Features
// Add the custom tag payloads
foreach (var customTag in m_PluginData.CustomTags)
{
bool isVisible = IsVisibleInActivity(customTag) &&
(!(stringMatch.GameObject is PlayerCharacter playerCharacter) || IsVisibleForPlayer(customTag, playerCharacter));
if (isVisible)
if (customTag.TagPositionInChat.InheritedValue != null)
{
if (customTag.TagPositionInChat.InheritedValue != null)
if (customTag.IncludesGameObjectNameToApplyTo(stringMatch.GetMatchText()))
{
if (customTag.IncludesGameObjectNameToApplyTo(stringMatch.GetMatchText()))
var customTagPayloads = GetPayloads(stringMatch.GameObject, customTag);
if (customTagPayloads.Any())
{
var customTagPayloads = GetPayloads(customTag);
if (customTagPayloads.Any())
{
AddPayloadChanges(customTag.TagPositionInChat.InheritedValue.Value, customTagPayloads, stringChanges);
}
AddPayloadChanges(customTag.TagPositionInChat.InheritedValue.Value, customTagPayloads, stringChanges);
}
}
}

View File

@@ -64,24 +64,24 @@ namespace PlayerTags.Features
Unhook();
}
protected override BitmapFontIcon? GetIcon(Tag tag)
protected override bool IsIconVisible(Tag tag)
{
if (tag.IsIconVisibleInNameplates.InheritedValue != null && tag.IsIconVisibleInNameplates.InheritedValue.Value)
if (tag.IsIconVisibleInNameplates.InheritedValue != null)
{
return tag.Icon.InheritedValue;
return tag.IsIconVisibleInNameplates.InheritedValue.Value;
}
return null;
return false;
}
protected override string? GetText(Tag tag)
protected override bool IsTextVisible(Tag tag)
{
if (tag.IsTextVisibleInNameplates.InheritedValue != null && tag.IsTextVisibleInNameplates.InheritedValue.Value)
if (tag.IsTextVisibleInNameplates.InheritedValue != null)
{
return tag.Text.InheritedValue;
return tag.IsTextVisibleInNameplates.InheritedValue.Value;
}
return null;
return false;
}
/// <summary>
@@ -181,18 +181,12 @@ namespace PlayerTags.Features
// Add the job tag
if (m_PluginData.JobTags.TryGetValue(character.ClassJob.GameData.Abbreviation, out var jobTag))
{
bool isVisible = IsVisibleInActivity(jobTag) &&
(!(gameObject is PlayerCharacter playerCharacter) || IsVisibleForPlayer(jobTag, playerCharacter));
if (isVisible)
if (jobTag.TagTargetInNameplates.InheritedValue != null && jobTag.TagPositionInNameplates.InheritedValue != null)
{
if (jobTag.TagTargetInNameplates.InheritedValue != null && jobTag.TagPositionInNameplates.InheritedValue != null)
var payloads = GetPayloads(gameObject, jobTag);
if (payloads.Any())
{
var payloads = GetPayloads(jobTag);
if (payloads.Any())
{
AddPayloadChanges(jobTag.TagTargetInNameplates.InheritedValue.Value, jobTag.TagPositionInNameplates.InheritedValue.Value, payloads, nameplateChanges);
}
AddPayloadChanges(jobTag.TagTargetInNameplates.InheritedValue.Value, jobTag.TagPositionInNameplates.InheritedValue.Value, payloads, nameplateChanges);
}
}
}
@@ -215,20 +209,14 @@ namespace PlayerTags.Features
// Add the custom tag payloads
foreach (var customTag in m_PluginData.CustomTags)
{
bool isVisible = IsVisibleInActivity(customTag) &&
(!(gameObject is PlayerCharacter playerCharacter) || IsVisibleForPlayer(customTag, playerCharacter));
if (isVisible)
if (customTag.TagTargetInNameplates.InheritedValue != null && customTag.TagPositionInNameplates.InheritedValue != null)
{
if (customTag.TagTargetInNameplates.InheritedValue != null && customTag.TagPositionInNameplates.InheritedValue != null)
if (customTag.IncludesGameObjectNameToApplyTo(gameObject.Name.TextValue))
{
if (customTag.IncludesGameObjectNameToApplyTo(gameObject.Name.TextValue))
var payloads = GetPayloads(gameObject, customTag);
if (payloads.Any())
{
var payloads = GetPayloads(customTag);
if (payloads.Any())
{
AddPayloadChanges(customTag.TagTargetInNameplates.InheritedValue.Value, customTag.TagPositionInNameplates.InheritedValue.Value, payloads, nameplateChanges);
}
AddPayloadChanges(customTag.TagTargetInNameplates.InheritedValue.Value, customTag.TagPositionInNameplates.InheritedValue.Value, payloads, nameplateChanges);
}
}
}

View File

@@ -1,7 +1,9 @@
using Dalamud.Game.ClientState.Objects.Enums;
using Dalamud.Game.ClientState.Objects.SubKinds;
using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Game.Text.SeStringHandling.Payloads;
using Dalamud.Logging;
using Lumina.Excel.GeneratedSheets;
using PlayerTags.Configuration;
using PlayerTags.Data;
@@ -9,6 +11,7 @@ using PlayerTags.Inheritables;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
namespace PlayerTags.Features
{
@@ -17,36 +20,24 @@ namespace PlayerTags.Features
private PluginConfiguration m_PluginConfiguration;
private ActivityContext m_ActivityContext;
private Dictionary<Tag, Payload[]> m_TagPayloads;
private TextPayload m_SpaceTextPayload;
public TagTargetFeature(PluginConfiguration pluginConfiguration)
{
m_PluginConfiguration = pluginConfiguration;
m_ActivityContext = ActivityContext.Overworld;
m_TagPayloads = new Dictionary<Tag, Payload[]>();
m_SpaceTextPayload = new TextPayload($" ");
m_PluginConfiguration.Saved += PluginConfiguration_Saved;
PluginServices.ClientState.TerritoryChanged += ClientState_TerritoryChanged;
}
public virtual void Dispose()
{
PluginServices.ClientState.TerritoryChanged -= ClientState_TerritoryChanged;
m_PluginConfiguration.Saved -= PluginConfiguration_Saved;
}
protected abstract BitmapFontIcon? GetIcon(Tag tag);
protected abstract bool IsIconVisible(Tag tag);
protected abstract string? GetText(Tag tag);
private void PluginConfiguration_Saved()
{
// Invalidate the cached payloads so they get remade
m_TagPayloads.Clear();
}
protected abstract bool IsTextVisible(Tag tag);
private void ClientState_TerritoryChanged(object? sender, ushort e)
{
@@ -68,25 +59,29 @@ namespace PlayerTags.Features
}
}
}
// Invalidate the cached payloads so they get remade
m_TagPayloads.Clear();
}
/// <summary>
/// Gets the payloads for the given tag. If the payloads don't yet exist then they will be created.
/// Gets the payloads for the given game object tag. If the payloads don't yet exist then they will be created.
/// </summary>
/// <param name="gameObject">The game object to get payloads for.</param>
/// <param name="tag">The tag config to get payloads for.</param>
/// <returns>A list of payloads for the given tag.</returns>
protected IEnumerable<Payload> GetPayloads(Tag tag)
protected IEnumerable<Payload> GetPayloads(GameObject gameObject, Tag tag)
{
if (m_TagPayloads.TryGetValue(tag, out var payloads))
// Only get payloads when in allowed activity contexts
if (!IsVisibleInActivity(tag))
{
return payloads;
return Enumerable.Empty<Payload>();
}
m_TagPayloads[tag] = CreatePayloads(tag);
return m_TagPayloads[tag];
// Only get payloads for player characters for allowed player contexts
if (gameObject is PlayerCharacter playerCharacter && !IsVisibleForPlayer(tag, playerCharacter))
{
return Enumerable.Empty<Payload>();
}
return CreatePayloads(gameObject, tag);
}
private InheritableValue<bool>? GetInheritableVisibilityForActivity(Tag tag, ActivityContext activityContext)
@@ -104,7 +99,7 @@ namespace PlayerTags.Features
return null;
}
public bool IsVisibleInActivity(Tag tag)
private bool IsVisibleInActivity(Tag tag)
{
var inheritable = GetInheritableVisibilityForActivity(tag, m_ActivityContext);
if (inheritable == null)
@@ -171,7 +166,7 @@ namespace PlayerTags.Features
return null;
}
public bool IsVisibleForPlayer(Tag tag, PlayerCharacter playerCharacter)
private bool IsVisibleForPlayer(Tag tag, PlayerCharacter playerCharacter)
{
var inheritable = GetInheritableVisibilityForPlayer(tag, GetContextForPlayer(playerCharacter));
if (inheritable == null)
@@ -187,19 +182,56 @@ namespace PlayerTags.Features
return true;
}
private Payload[] CreatePayloads(Tag tag)
private string ExpandTextParameters(GameObject gameObject, string text)
{
if (gameObject is PlayerCharacter playerCharacter)
{
var parameterIndex = text.ToLower().IndexOf("{PlayerAverageItemLevel}".ToLower());
if (parameterIndex >= 0)
{
unsafe
{
FFXIVClientStructs.FFXIV.Client.Game.Character.Character character = Marshal.PtrToStructure<FFXIVClientStructs.FFXIV.Client.Game.Character.Character>(playerCharacter.Address);
byte[] equipSlotData = new byte[40];
for (int index = 0; index < equipSlotData.Length; ++index)
{
equipSlotData[index] = character.EquipSlotData[index];
}
PluginLog.Debug(string.Join(" ", equipSlotData.Select(d => d.ToString("X2"))));
}
}
}
return text;
}
private Payload[] CreatePayloads(GameObject gameObject, Tag tag)
{
List<Payload> newPayloads = new List<Payload>();
BitmapFontIcon? icon = GetIcon(tag);
BitmapFontIcon? icon = null;
if (IsIconVisible(tag))
{
icon = tag.Icon.InheritedValue;
}
if (icon != null && icon.Value != BitmapFontIcon.None)
{
newPayloads.Add(new IconPayload(icon.Value));
}
string? text = GetText(tag);
string? text = null;
if (IsTextVisible(tag))
{
text = tag.Text.InheritedValue;
}
if (!string.IsNullOrWhiteSpace(text))
{
text = ExpandTextParameters(gameObject, text);
if (tag.IsTextItalic.InheritedValue != null && tag.IsTextItalic.InheritedValue.Value)
{
newPayloads.Add(new EmphasisItalicPayload(true));
@@ -275,7 +307,7 @@ namespace PlayerTags.Features
foreach (var indexToInsertSpaceAt in indicesToInsertSpacesAt)
{
payloads.Insert(indexToInsertSpaceAt, m_SpaceTextPayload);
payloads.Insert(indexToInsertSpaceAt, new TextPayload($" "));
}
// Decide whether to add a space to the end
@@ -284,7 +316,7 @@ namespace PlayerTags.Features
var significantPayloads = payloads.Where(payload => payload is TextPayload || payload is IconPayload);
if (significantPayloads.Last() is TextPayload)
{
payloads.Add(m_SpaceTextPayload);
payloads.Add(new TextPayload($" "));
}
}
// Decide whether to add a space to the beginning
@@ -293,7 +325,7 @@ namespace PlayerTags.Features
var significantPayloads = payloads.Where(payload => payload is TextPayload || payload is IconPayload);
if (significantPayloads.First() is TextPayload)
{
payloads.Insert(0, m_SpaceTextPayload);
payloads.Insert(0, new TextPayload($" "));
}
}
}

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Authors>r00telement</Authors>
<Version>1.1.2.0</Version>
<Version>1.1.3.0</Version>
</PropertyGroup>
<PropertyGroup>
@@ -21,7 +21,7 @@
<ItemGroup>
<PackageReference Include="DalamudPackager" Version="2.1.5" />
<PackageReference Include="XivCommon" Version="4.0.0-alpha.1" />
<PackageReference Include="XivCommon" Version="4.0.0-alpha.2" />
<Reference Include="FFXIVClientStructs">
<HintPath>$(DalamudLibPath)FFXIVClientStructs.dll</HintPath>
<Private>false</Private>

View File

@@ -357,6 +357,15 @@ namespace PlayerTags.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Whether the tag should be visible for alliance members who are not in the current party..
/// </summary>
public static string Loc_IsVisibleForAlliancePlayers_Description {
get {
return ResourceManager.GetString("Loc_IsVisibleForAlliancePlayers_Description", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Show for enemies.
/// </summary>
@@ -366,6 +375,15 @@ namespace PlayerTags.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Whether the tag should be visible for enemies in pvp..
/// </summary>
public static string Loc_IsVisibleForEnemyPlayers_Description {
get {
return ResourceManager.GetString("Loc_IsVisibleForEnemyPlayers_Description", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Show for friends.
/// </summary>
@@ -375,6 +393,15 @@ namespace PlayerTags.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Whether the tag should be visible for friends..
/// </summary>
public static string Loc_IsVisibleForFriendPlayers_Description {
get {
return ResourceManager.GetString("Loc_IsVisibleForFriendPlayers_Description", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Show for others.
/// </summary>
@@ -384,6 +411,15 @@ namespace PlayerTags.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Whether the tag should be visible for players in other circumstances for which there is no specific option..
/// </summary>
public static string Loc_IsVisibleForOtherPlayers_Description {
get {
return ResourceManager.GetString("Loc_IsVisibleForOtherPlayers_Description", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Show for party members.
/// </summary>
@@ -393,6 +429,15 @@ namespace PlayerTags.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Whether the tag should be visible for party members..
/// </summary>
public static string Loc_IsVisibleForPartyPlayers_Description {
get {
return ResourceManager.GetString("Loc_IsVisibleForPartyPlayers_Description", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Show for self.
/// </summary>
@@ -402,6 +447,15 @@ namespace PlayerTags.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Whether the tag should be visible for the local player..
/// </summary>
public static string Loc_IsVisibleForSelf_Description {
get {
return ResourceManager.GetString("Loc_IsVisibleForSelf_Description", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Show elsewhere.
/// </summary>
@@ -411,6 +465,15 @@ namespace PlayerTags.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Whether the tag should be visible in other circumstances for which there is no specific option..
/// </summary>
public static string Loc_IsVisibleInOverworld_Description {
get {
return ResourceManager.GetString("Loc_IsVisibleInOverworld_Description", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Show in pve duties.
/// </summary>
@@ -420,6 +483,15 @@ namespace PlayerTags.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Whether the tag should be visible in pvp duties..
/// </summary>
public static string Loc_IsVisibleInPveDuties_Description {
get {
return ResourceManager.GetString("Loc_IsVisibleInPveDuties_Description", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Show in pvp duties.
/// </summary>

View File

@@ -427,31 +427,58 @@
<data name="Loc_IsVisibleInPveDuties" xml:space="preserve">
<value>Show in pve duties</value>
</data>
<data name="Loc_IsVisibleInPveDuties_Description" xml:space="preserve">
<value>Whether the tag should be visible in pve duties.</value>
</data>
<data name="Loc_IsVisibleInPvpDuties" xml:space="preserve">
<value>Show in pvp duties</value>
</data>
<data name="Loc_IsVisibleInPvpDuties_Description" xml:space="preserve">
<value>Whether the tag should be visible in pvp duties.</value>
</data>
<data name="Loc_IsVisibleInOverworld" xml:space="preserve">
<value>Show elsewhere</value>
</data>
<data name="Loc_IsVisibleInOverworld_Description" xml:space="preserve">
<value>Whether the tag should be visible in other circumstances for which there is no specific option.</value>
</data>
<data name="Loc_IsVisibleForSelf" xml:space="preserve">
<value>Show for self</value>
</data>
<data name="Loc_IsVisibleForSelf_Description" xml:space="preserve">
<value>Whether the tag should be visible for the local player.</value>
</data>
<data name="Loc_IsVisibleForPartyPlayers" xml:space="preserve">
<value>Show for party members</value>
</data>
<data name="Loc_IsVisibleForPartyPlayers_Description" xml:space="preserve">
<value>Whether the tag should be visible for party members.</value>
</data>
<data name="Loc_IsVisibleForAlliancePlayers" xml:space="preserve">
<value>Show for alliance members</value>
</data>
<data name="Loc_IsVisibleForAlliancePlayers_Description" xml:space="preserve">
<value>Whether the tag should be visible for alliance members who are not in the current party.</value>
</data>
<data name="Loc_IsVisibleForFriendPlayers" xml:space="preserve">
<value>Show for friends</value>
</data>
<data name="Loc_IsVisibleForFriendPlayers_Description" xml:space="preserve">
<value>Whether the tag should be visible for friends.</value>
</data>
<data name="Loc_IsVisibleForEnemyPlayers" xml:space="preserve">
<value>Show for enemies</value>
</data>
<data name="Loc_IsVisibleForEnemyPlayers_Description" xml:space="preserve">
<value>Whether the tag should be visible for enemies in pvp.</value>
</data>
<data name="Loc_IsVisibleForOtherPlayers" xml:space="preserve">
<value>Show for others</value>
</data>
<data name="Loc_IsVisibleForOtherPlayers_Description" xml:space="preserve">
<value>Whether the tag should be visible for players in other circumstances for which there is no specific option.</value>
</data>
<data name="Loc_IsSortedByProximity" xml:space="preserve">
<value>Sort by proximity</value>