Quick party assign + config UI update

- Context menu options to add and remove custom tags for players
- Quick party assign config
- Update to tag config UI so it's collapsible
- Now depends on XivCommon
This commit is contained in:
r00telement
2021-12-07 22:20:15 +00:00
parent c1abfc512a
commit 5f91cd6cc2
8 changed files with 558 additions and 274 deletions

View File

@@ -21,6 +21,7 @@
<ItemGroup>
<PackageReference Include="DalamudPackager" Version="2.1.5" />
<PackageReference Include="XivCommon" Version="4.0.0-alpha.1" />
<Reference Include="FFXIVClientStructs">
<HintPath>$(DalamudLibPath)FFXIVClientStructs.dll</HintPath>
<Private>false</Private>

View File

@@ -3,6 +3,7 @@
"Name": "Player Tags",
"Description": "See tags for players in nameplates and chat, such as their role and job, or custom tags for players you know.",
"Tags": [ "Jobs", "UI" ],
"CategoryTags": [ "jobs", "UI" ],
"RepoUrl": "https://github.com/r00telement/PlayerTags",
"IconUrl": "https://github.com/r00telement/PlayerTags/raw/main/PlayerTags/Resources/Promo/Icon.png",
"ImageUrls": [

View File

@@ -4,6 +4,7 @@ using Dalamud.Game.ClientState;
using Dalamud.Game.ClientState.Objects;
using Dalamud.Game.ClientState.Objects.SubKinds;
using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.Game.ClientState.Party;
using Dalamud.Game.Command;
using Dalamud.Game.Gui;
using Dalamud.Game.Text;
@@ -12,16 +13,18 @@ using Dalamud.Game.Text.SeStringHandling.Payloads;
using Dalamud.IoC;
using Dalamud.Logging;
using Dalamud.Plugin;
using PlayerTags.Resources;
using System;
using System.Collections.Generic;
using System.Linq;
using XivCommon;
using XivCommon.Functions.ContextMenu;
namespace PlayerTags
{
public sealed class Plugin : IDalamudPlugin
{
public string Name => "Player Tags";
private const string c_CommandName = "/playertags";
[PluginService]
@@ -48,21 +51,17 @@ namespace PlayerTags
[PluginService]
private static ClientState ClientState { get; set; } = null!;
[PluginService]
private static PartyList PartyList { get; set; } = null!;
private PluginConfiguration m_PluginConfiguration;
private PluginConfigurationUI m_PluginConfigurationUI;
private RandomNameGenerator m_RandomNameGenerator = new RandomNameGenerator();
private PluginHooks? m_PluginHooks = null;
private Dictionary<Tag, Dictionary<TagTarget, Payload[]>> m_TagTargetPayloads = new Dictionary<Tag, Dictionary<TagTarget, Payload[]>>();
private TextPayload m_SpaceTextPayload = new TextPayload($" ");
private PluginData m_PluginData = new PluginData();
private bool m_OpenConfigClicked = false;
private XivCommonBase XivCommon;
public Plugin()
{
@@ -70,7 +69,7 @@ namespace PlayerTags
m_PluginConfiguration = PluginInterface.GetPluginConfig() as PluginConfiguration ?? new PluginConfiguration();
m_PluginConfiguration.Initialize(PluginInterface);
m_PluginData.Initialize(DataManager, m_PluginConfiguration);
m_PluginConfigurationUI = new PluginConfigurationUI(m_PluginConfiguration, m_PluginData);
m_PluginConfigurationUI = new PluginConfigurationUI(m_PluginConfiguration, m_PluginData, ClientState, PartyList);
ClientState.Login += ClientState_Login;
ClientState.Logout += ClientState_Logout;
@@ -87,10 +86,14 @@ namespace PlayerTags
HelpMessage = "Shows the config"
});
Hook();
XivCommon = new XivCommonBase(Hooks.ContextMenu);
XivCommon.Functions.ContextMenu.OpenContextMenu += ContextMenu_OpenContextMenu;
}
public void Dispose()
{
XivCommon.Functions.ContextMenu.OpenContextMenu -= ContextMenu_OpenContextMenu;
XivCommon.Dispose();
Unhook();
CommandManager.RemoveHandler(c_CommandName);
m_PluginConfiguration.Saved -= PluginConfiguration_Saved;
@@ -134,25 +137,78 @@ namespace PlayerTags
m_TagTargetPayloads.Clear();
}
private void ContextMenu_OpenContextMenu(ContextMenuOpenArgs args)
{
if (args.Text == null || !m_PluginConfiguration.IsCustomTagContextMenuEnabled)
{
return;
}
string gameObjectName = args.Text.TextValue;
var removedTags = m_PluginData.CustomTags.Where(tag => !tag.IncludesGameObjectNameToApplyTo(gameObjectName));
var addTagItem = new NormalContextSubMenuItem(Strings.Loc_Static_ContextMenu_AddTag, (itemArgs =>
{
foreach (var removedTag in removedTags)
{
itemArgs.Items.Add(new NormalContextMenuItem(removedTag.Text.Value, (args =>
{
removedTag.AddGameObjectNameToApplyTo(gameObjectName);
})));
}
// TODO: Temp hack because when opening somewhere other than the chat log, the last added item for some reason is added to the <Return button.
if (args.ParentAddonName != "ChatLog")
{
itemArgs.Items.Add(new NormalContextMenuItem("ReturnDummy", (args => { })));
}
}));
if (!removedTags.Any())
{
addTagItem.Enabled = false;
}
args.Items.Add(addTagItem);
var addedTags = m_PluginData.CustomTags.Where(tag => tag.IncludesGameObjectNameToApplyTo(gameObjectName));
var removeTagItem = new NormalContextSubMenuItem(Strings.Loc_Static_ContextMenu_RemoveTag, (itemArgs =>
{
foreach (var addedTag in addedTags)
{
itemArgs.Items.Add(new NormalContextMenuItem(addedTag.Text.Value, (args =>
{
addedTag.RemoveGameObjectNameToApplyTo(gameObjectName);
})));
}
// TODO: Temp hack because when opening somewhere other than the chat log, the last added item for some reason is added to the <Return button.
if (args.ParentAddonName != "ChatLog")
{
itemArgs.Items.Add(new NormalContextMenuItem("ReturnDummy", (args => { })));
}
}));
if (!addedTags.Any())
{
removeTagItem.Enabled = false;
}
args.Items.Add(removeTagItem);
}
private void UiBuilder_Draw()
{
if (m_PluginConfiguration.IsVisible)
{
// Only allow the config to be shown either when in the world, or when explicitly opened
if (ClientState.LocalPlayer != null || m_OpenConfigClicked)
{
m_PluginConfigurationUI.Draw();
}
}
else
{
m_OpenConfigClicked = false;
m_PluginConfigurationUI.Draw();
}
}
private void UiBuilder_OpenConfigUi()
{
m_OpenConfigClicked = true;
m_PluginConfiguration.IsVisible = true;
}

View File

@@ -16,6 +16,7 @@ namespace PlayerTags
public NameplateTitleVisibility NameplateTitleVisibility = NameplateTitleVisibility.WhenHasTags;
public NameplateTitlePosition NameplateTitlePosition = NameplateTitlePosition.AlwaysAboveName;
public bool IsPlayerNameRandomlyGenerated = false;
public bool IsCustomTagContextMenuEnabled = true;
[JsonProperty(TypeNameHandling = TypeNameHandling.None, ItemTypeNameHandling = TypeNameHandling.None)]
public Dictionary<string, InheritableData> AllTagsChanges = new Dictionary<string, InheritableData>();

View File

@@ -1,4 +1,9 @@
using ImGuiNET;
using Dalamud.Game.ClientState;
using Dalamud.Game.ClientState.Objects;
using Dalamud.Game.ClientState.Objects.SubKinds;
using Dalamud.Game.ClientState.Party;
using FFXIVClientStructs.FFXIV.Client.Game.Character;
using ImGuiNET;
using Lumina.Excel.GeneratedSheets;
using PlayerTags.Resources;
using System;
@@ -10,15 +15,17 @@ namespace PlayerTags
public class PluginConfigurationUI
{
private PluginConfiguration m_PluginConfiguration;
private PluginData m_PluginData;
private ClientState m_ClientState;
private PartyList m_PartyList;
private InheritableValue<ushort>? m_ColorPickerPopupDataContext;
public PluginConfigurationUI(PluginConfiguration config, PluginData pluginData)
public PluginConfigurationUI(PluginConfiguration config, PluginData pluginData, ClientState clientState, PartyList partyList)
{
m_PluginConfiguration = config;
m_PluginData = pluginData;
m_ClientState = clientState;
m_PartyList = partyList;
}
public void Draw()
@@ -34,6 +41,11 @@ namespace PlayerTags
ImGui.TextWrapped(Strings.Loc_Static_WarningMessage);
ImGui.PopStyleColor();
DrawHeading(Strings.Loc_Static_General);
ImGui.TreePush();
DrawCheckbox(nameof(m_PluginConfiguration.IsCustomTagContextMenuEnabled), true, ref m_PluginConfiguration.IsCustomTagContextMenuEnabled, () => m_PluginConfiguration.Save(m_PluginData));
ImGui.TreePop();
DrawHeading(Strings.Loc_Static_Nameplates);
ImGui.TreePush();
DrawComboBox(true, true, false, ref m_PluginConfiguration.NameplateFreeCompanyVisibility, () => m_PluginConfiguration.Save(m_PluginData));
@@ -45,32 +57,71 @@ namespace PlayerTags
ImGui.TreePush();
DrawCheckbox(nameof(m_PluginConfiguration.IsPlayerNameRandomlyGenerated), true, ref m_PluginConfiguration.IsPlayerNameRandomlyGenerated, () => m_PluginConfiguration.Save(m_PluginData));
ImGui.TreePop();
ImGui.EndTabItem();
DrawHeading(Strings.Loc_Static_Tags);
ImGui.TreePush();
Draw(m_PluginData.AllTags);
ImGui.TreePop();
ImGui.PushStyleColor(ImGuiCol.Button, new Vector4(0.1f, 0.3f, 0.1f, 1));
ImGui.PushStyleColor(ImGuiCol.ButtonHovered, new Vector4(0.2f, 0.6f, 0.2f, 1));
ImGui.PushStyleColor(ImGuiCol.ButtonActive, new Vector4(0.2f, 0.6f, 0.2f, 1));
if (ImGui.Button(Strings.Loc_Static_AddCustomTag))
DrawHeading(Strings.Loc_Static_PartyAssign);
ImGui.TreePush();
if (ImGui.BeginTable("##PartyAssignTable", 1 + m_PluginData.CustomTags.Count))
{
var newTag = new Tag(new LocalizedPluginString(nameof(PluginData.CustomTags)))
ImGui.TableHeader(Strings.Loc_Static_PlayerName);
ImGui.TableSetupColumn(Strings.Loc_Static_PlayerName);
ImGui.NextColumn();
foreach (var customTag in m_PluginData.CustomTags)
{
Text = "",
GameObjectNamesToApplyTo = ""
ImGui.TableHeader(customTag.Text.InheritedValue);
ImGui.TableSetupColumn(customTag.Text.InheritedValue);
ImGui.NextColumn();
}
ImGui.TableHeadersRow();
var drawPartyMember = (string playerName) =>
{
ImGui.TableNextRow();
ImGui.TableNextColumn();
ImGui.Text(playerName);
foreach (Tag customTag in m_PluginData.CustomTags)
{
ImGui.TableNextColumn();
bool isTagAssigned = customTag.IncludesGameObjectNameToApplyTo(playerName);
DrawCheckbox("IsEnabled", false, ref isTagAssigned, () =>
{
if (isTagAssigned)
{
customTag.AddGameObjectNameToApplyTo(playerName);
}
else
{
customTag.RemoveGameObjectNameToApplyTo(playerName);
}
m_PluginConfiguration.Save(m_PluginData);
});
}
};
m_PluginData.CustomTags.Add(newTag);
newTag.Parent = m_PluginData.AllCustomTags;
}
ImGui.PopStyleColor();
ImGui.PopStyleColor();
ImGui.PopStyleColor();
foreach (var partyMember in m_PartyList)
{
drawPartyMember(partyMember.Name.TextValue);
}
if (m_PartyList.Length == 0 && m_ClientState.LocalPlayer != null)
{
drawPartyMember(m_ClientState.LocalPlayer.Name.TextValue);
}
ImGui.EndTable();
}
ImGui.TreePop();
ImGui.End();
}
@@ -84,189 +135,209 @@ namespace PlayerTags
{
ImGui.PushID(tag.GetHashCode().ToString());
ImGui.BeginGroup();
ImGui.BeginChild(tag.GetHashCode().ToString(), new Vector2(100, 60));
var text = tag.Name.Value;
var textSize = ImGui.CalcTextSize(text);
var addButtonSize = new Vector2(23, 23);
var panelSize = ImGui.GetItemRectSize();
ImGui.SetCursorPosX(panelSize.X - textSize.X);
ImGui.Text(text);
if (ImGui.IsPopupOpen("AddPopup"))
{
ImGui.PushStyleColor(ImGuiCol.Button, new Vector4(0.2f, 0.6f, 0.2f, 1));
}
else
{
ImGui.PushStyleColor(ImGuiCol.Button, new Vector4(0.1f, 0.3f, 0.1f, 1));
}
ImGui.PushStyleColor(ImGuiCol.ButtonHovered, new Vector4(0.2f, 0.6f, 0.2f, 1));
ImGui.PushStyleColor(ImGuiCol.ButtonActive, new Vector4(0.2f, 0.6f, 0.2f, 1));
ImGui.SetCursorPosX(panelSize.X - addButtonSize.X);
var addPopupPos = ImGui.GetCursorPos();
addPopupPos.Y -= addButtonSize.Y + 2;
if (ImGui.Button("+", addButtonSize))
{
ImGui.OpenPopup("AddPopup");
}
ImGui.PopStyleColor();
ImGui.PopStyleColor();
ImGui.PopStyleColor();
bool wasPaddingConsumed = false;
ImGui.PushStyleVar(ImGuiStyleVar.WindowPadding, new Vector2(0, 5));
ImGui.SetNextWindowPos(ImGui.GetCursorScreenPos() + addPopupPos);
if (ImGui.BeginPopup("AddPopup"))
{
wasPaddingConsumed = true;
ImGui.PopStyleVar();
ImGui.PushStyleColor(ImGuiCol.FrameBg, new Vector4(0f, 0f, 0f, 0));
if (ImGui.BeginListBox("###SelectableInheritables"))
{
var selectableInheritables = tag.Inheritables.Where(inheritable => inheritable.Value.Behavior == InheritableBehavior.Inherit).ToDictionary(item => item.Key, item => item.Value);
var selectableInheritablesWithLocalizedNames = selectableInheritables
.Select(inheritable => new { Name = inheritable.Key, LocalizedName = Localizer.GetString(inheritable.Key, false) })
.OrderBy(item => item.LocalizedName);
foreach (var inheritableLocalizedName in selectableInheritablesWithLocalizedNames)
{
bool isSelected = false;
if (ImGui.Selectable(inheritableLocalizedName.LocalizedName, isSelected))
{
selectableInheritables[inheritableLocalizedName.Name].Behavior = InheritableBehavior.Enabled;
if (selectableInheritables[inheritableLocalizedName.Name] is InheritableValue<bool> inheritableBool)
{
inheritableBool.Value = true;
}
m_PluginConfiguration.Save(m_PluginData);
ImGui.CloseCurrentPopup();
}
if (isSelected)
{
ImGui.SetItemDefaultFocus();
}
if (ImGui.IsItemHovered())
{
ImGui.SetTooltip(Localizer.GetString(inheritableLocalizedName.Name, true));
}
}
ImGui.EndListBox();
}
ImGui.PopStyleColor();
ImGui.EndPopup();
}
if (!wasPaddingConsumed)
{
ImGui.PopStyleVar();
}
if (ImGui.IsItemHovered())
{
ImGui.SetTooltip(Strings.Loc_Static_AddPropertyOverride_Description);
}
ImGui.EndChild();
ImGui.EndGroup();
ImGui.SameLine();
ImGui.BeginGroup();
var selectedInheritables = tag.Inheritables.Where(inheritable => inheritable.Value.Behavior != InheritableBehavior.Inherit).ToDictionary(item => item.Key, item => item.Value);
var selectedInheritablesWithLocalizedNames = selectedInheritables
.Select(inheritable => new { Name = inheritable.Key, LocalizedName = Localizer.GetString(inheritable.Key, false) })
.OrderBy(item => item.LocalizedName);
foreach (var selectedInheritablesWithLocalizedName in selectedInheritablesWithLocalizedNames)
{
switch (selectedInheritablesWithLocalizedName.Name)
{
case nameof(tag.Icon):
ImGui.SameLine();
DrawInheritable(nameof(tag.Icon), false, true, tag.Icon);
break;
case nameof(tag.IsIconVisibleInChat):
ImGui.SameLine();
DrawInheritable(nameof(tag.IsIconVisibleInChat), tag.IsIconVisibleInChat);
break;
case nameof(tag.IsIconVisibleInNameplates):
ImGui.SameLine();
DrawInheritable(nameof(tag.IsIconVisibleInNameplates), tag.IsIconVisibleInNameplates);
break;
case nameof(tag.Text):
ImGui.SameLine();
DrawInheritable(nameof(tag.Text), tag.Text);
break;
case nameof(tag.TextColor):
ImGui.SameLine();
DrawInheritable(nameof(tag.TextColor), tag.TextColor);
break;
case nameof(tag.IsTextItalic):
ImGui.SameLine();
DrawInheritable(nameof(tag.IsTextItalic), tag.IsTextItalic);
break;
case nameof(tag.IsTextVisibleInChat):
ImGui.SameLine();
DrawInheritable(nameof(tag.IsTextVisibleInChat), tag.IsTextVisibleInChat);
break;
case nameof(tag.IsTextVisibleInNameplates):
ImGui.SameLine();
DrawInheritable(nameof(tag.IsTextVisibleInNameplates), tag.IsTextVisibleInNameplates);
break;
case nameof(tag.TagPositionInChat):
ImGui.SameLine();
DrawInheritable(nameof(tag.TagPositionInChat), true, false, tag.TagPositionInChat);
break;
case nameof(tag.TagPositionInNameplates):
ImGui.SameLine();
DrawInheritable(nameof(tag.TagPositionInNameplates), true, false, tag.TagPositionInNameplates);
break;
case nameof(tag.TagTargetInNameplates):
ImGui.SameLine();
DrawInheritable(nameof(tag.TagTargetInNameplates), true, false, tag.TagTargetInNameplates);
break;
case nameof(tag.GameObjectNamesToApplyTo):
ImGui.SameLine();
DrawInheritable(nameof(tag.GameObjectNamesToApplyTo), tag.GameObjectNamesToApplyTo);
break;
default:
break;
}
}
var collapsingHeaderName = tag.Name.Value;
if (m_PluginData.CustomTags.Contains(tag))
{
ImGui.SameLine();
ImGui.BeginGroup();
ImGui.Indent();
ImGui.Text("");
collapsingHeaderName = tag.Text.InheritedValue;
}
ImGui.PushStyleColor(ImGuiCol.Button, new Vector4(0.3f, 0.1f, 0.1f, 1));
ImGui.PushStyleColor(ImGuiCol.ButtonHovered, new Vector4(0.6f, 0.2f, 0.2f, 1));
ImGui.PushStyleColor(ImGuiCol.ButtonActive, new Vector4(0.6f, 0.2f, 0.2f, 1));
if (ImGui.Button(Strings.Loc_Static_RemoveCustomTag))
if (ImGui.CollapsingHeader($"{collapsingHeaderName}###{tag.GetHashCode()}"))
{
ImGui.TreePush();
ImGui.BeginGroup();
ImGui.BeginGroup();
var addButtonSize = new Vector2(23, 23);
if (ImGui.IsPopupOpen("AddPopup"))
{
m_PluginData.AllCustomTags.Children.Remove(tag);
m_PluginData.CustomTags.Remove(tag);
m_PluginConfiguration.Save(m_PluginData);
ImGui.PushStyleColor(ImGuiCol.Button, new Vector4(0.2f, 0.6f, 0.2f, 1));
}
else
{
ImGui.PushStyleColor(ImGuiCol.Button, new Vector4(0.1f, 0.3f, 0.1f, 1));
}
ImGui.PushStyleColor(ImGuiCol.ButtonHovered, new Vector4(0.2f, 0.6f, 0.2f, 1));
ImGui.PushStyleColor(ImGuiCol.ButtonActive, new Vector4(0.2f, 0.6f, 0.2f, 1));
ImGui.Text("");
var addPopupPos = ImGui.GetCursorPos();
addPopupPos.Y -= 4;
if (ImGui.Button("+", addButtonSize))
{
ImGui.OpenPopup("AddPopup");
}
ImGui.PopStyleColor();
ImGui.PopStyleColor();
ImGui.PopStyleColor();
ImGui.EndGroup();
}
ImGui.EndGroup();
foreach (var childTag in tag.Children.ToArray())
{
Draw(childTag);
bool wasPaddingConsumed = false;
ImGui.PushStyleVar(ImGuiStyleVar.WindowPadding, new Vector2(0, 5));
ImGui.SetNextWindowPos(ImGui.GetCursorScreenPos() + addPopupPos);
if (ImGui.BeginPopup("AddPopup"))
{
wasPaddingConsumed = true;
ImGui.PopStyleVar();
ImGui.PushStyleColor(ImGuiCol.FrameBg, new Vector4(0f, 0f, 0f, 0));
if (ImGui.BeginListBox("###SelectableInheritables"))
{
var selectableInheritables = tag.Inheritables.Where(inheritable => inheritable.Value.Behavior == InheritableBehavior.Inherit).ToDictionary(item => item.Key, item => item.Value);
var selectableInheritablesWithLocalizedNames = selectableInheritables
.Select(inheritable => new { Name = inheritable.Key, LocalizedName = Localizer.GetString(inheritable.Key, false) })
.OrderBy(item => item.LocalizedName);
foreach (var inheritableLocalizedName in selectableInheritablesWithLocalizedNames)
{
bool isSelected = false;
if (ImGui.Selectable(inheritableLocalizedName.LocalizedName, isSelected))
{
selectableInheritables[inheritableLocalizedName.Name].Behavior = InheritableBehavior.Enabled;
if (selectableInheritables[inheritableLocalizedName.Name] is InheritableValue<bool> inheritableBool)
{
inheritableBool.Value = true;
}
m_PluginConfiguration.Save(m_PluginData);
ImGui.CloseCurrentPopup();
}
if (isSelected)
{
ImGui.SetItemDefaultFocus();
}
if (ImGui.IsItemHovered())
{
ImGui.SetTooltip(Localizer.GetString(inheritableLocalizedName.Name, true));
}
}
ImGui.EndListBox();
}
ImGui.PopStyleColor();
ImGui.EndPopup();
}
if (!wasPaddingConsumed)
{
ImGui.PopStyleVar();
}
if (ImGui.IsItemHovered())
{
ImGui.SetTooltip(Strings.Loc_Static_AddPropertyOverride_Description);
}
ImGui.EndGroup();
var selectedInheritables = tag.Inheritables.Where(inheritable => inheritable.Value.Behavior != InheritableBehavior.Inherit).ToDictionary(item => item.Key, item => item.Value);
var selectedInheritablesWithLocalizedNames = selectedInheritables
.Select(inheritable => new { Name = inheritable.Key, LocalizedName = Localizer.GetString(inheritable.Key, false) })
.OrderBy(item => item.LocalizedName);
foreach (var selectedInheritablesWithLocalizedName in selectedInheritablesWithLocalizedNames)
{
ImGui.SameLine();
ImGui.BeginGroup();
ImGui.Indent();
ImGui.BeginChild(selectedInheritablesWithLocalizedName.Name, new Vector2(180, 50));
switch (selectedInheritablesWithLocalizedName.Name)
{
case nameof(tag.Icon):
DrawInheritable(nameof(tag.Icon), false, true, tag.Icon);
break;
case nameof(tag.IsIconVisibleInChat):
DrawInheritable(nameof(tag.IsIconVisibleInChat), tag.IsIconVisibleInChat);
break;
case nameof(tag.IsIconVisibleInNameplates):
DrawInheritable(nameof(tag.IsIconVisibleInNameplates), tag.IsIconVisibleInNameplates);
break;
case nameof(tag.Text):
DrawInheritable(nameof(tag.Text), tag.Text);
break;
case nameof(tag.TextColor):
DrawInheritable(nameof(tag.TextColor), tag.TextColor);
break;
case nameof(tag.IsTextItalic):
DrawInheritable(nameof(tag.IsTextItalic), tag.IsTextItalic);
break;
case nameof(tag.IsTextVisibleInChat):
DrawInheritable(nameof(tag.IsTextVisibleInChat), tag.IsTextVisibleInChat);
break;
case nameof(tag.IsTextVisibleInNameplates):
DrawInheritable(nameof(tag.IsTextVisibleInNameplates), tag.IsTextVisibleInNameplates);
break;
case nameof(tag.TagPositionInChat):
DrawInheritable(nameof(tag.TagPositionInChat), true, false, tag.TagPositionInChat);
break;
case nameof(tag.TagPositionInNameplates):
DrawInheritable(nameof(tag.TagPositionInNameplates), true, false, tag.TagPositionInNameplates);
break;
case nameof(tag.TagTargetInNameplates):
DrawInheritable(nameof(tag.TagTargetInNameplates), true, false, tag.TagTargetInNameplates);
break;
case nameof(tag.GameObjectNamesToApplyTo):
DrawInheritable(nameof(tag.GameObjectNamesToApplyTo), tag.GameObjectNamesToApplyTo);
break;
default:
break;
}
ImGui.EndChild();
ImGui.EndGroup();
}
if (m_PluginData.CustomTags.Contains(tag))
{
ImGui.SameLine();
ImGui.BeginGroup();
ImGui.Indent();
ImGui.Text("");
ImGui.PushStyleColor(ImGuiCol.Button, new Vector4(0.3f, 0.1f, 0.1f, 1));
ImGui.PushStyleColor(ImGuiCol.ButtonHovered, new Vector4(0.6f, 0.2f, 0.2f, 1));
ImGui.PushStyleColor(ImGuiCol.ButtonActive, new Vector4(0.6f, 0.2f, 0.2f, 1));
if (ImGui.Button(Strings.Loc_Static_RemoveCustomTag))
{
m_PluginData.AllCustomTags.Children.Remove(tag);
m_PluginData.CustomTags.Remove(tag);
m_PluginConfiguration.Save(m_PluginData);
}
ImGui.PopStyleColor();
ImGui.PopStyleColor();
ImGui.PopStyleColor();
ImGui.EndGroup();
}
foreach (var childTag in tag.Children.ToArray())
{
Draw(childTag);
}
if (tag == m_PluginData.AllCustomTags)
{
ImGui.PushStyleColor(ImGuiCol.Button, new Vector4(0.1f, 0.3f, 0.1f, 1));
ImGui.PushStyleColor(ImGuiCol.ButtonHovered, new Vector4(0.2f, 0.6f, 0.2f, 1));
ImGui.PushStyleColor(ImGuiCol.ButtonActive, new Vector4(0.2f, 0.6f, 0.2f, 1));
if (ImGui.Button(Strings.Loc_Static_AddCustomTag))
{
var newTag = new Tag(new LocalizedPluginString(nameof(PluginData.CustomTags)))
{
Text = "",
GameObjectNamesToApplyTo = ""
};
m_PluginData.CustomTags.Add(newTag);
newTag.Parent = m_PluginData.AllCustomTags;
}
ImGui.PopStyleColor();
ImGui.PopStyleColor();
ImGui.PopStyleColor();
}
ImGui.EndGroup();
ImGui.TreePop();
}
ImGui.PopID();
@@ -295,29 +366,16 @@ namespace PlayerTags
private void DrawInheritable(string localizedStringName, InheritableValue<bool> inheritable)
{
ImGui.BeginGroup();
ImGui.Indent();
ImGui.BeginChild(inheritable.GetHashCode().ToString(), new Vector2(180, 47));
ImGui.Text(Localizer.GetString(localizedStringName, false));
DrawCheckbox("IsEnabled", false, ref inheritable.Value, () =>
{
m_PluginConfiguration.Save(m_PluginData);
});
ImGui.SameLine();
DrawRemoveButton(inheritable);
ImGui.EndChild();
ImGui.EndGroup();
}
private void DrawInheritable<TEnum>(string localizedStringName, bool shouldLocalizeNames, bool shouldOrderNames, InheritableValue<TEnum> inheritable)
where TEnum : struct, Enum
{
ImGui.BeginGroup();
ImGui.Indent();
ImGui.BeginChild(inheritable.GetHashCode().ToString(), new Vector2(180, 47));
ImGui.Text(Localizer.GetString(localizedStringName, false));
bool isEnabled = inheritable.Behavior == InheritableBehavior.Enabled;
@@ -342,17 +400,10 @@ namespace PlayerTags
ImGui.SameLine();
DrawRemoveButton(inheritable);
ImGui.EndChild();
ImGui.EndGroup();
}
private void DrawInheritable(string localizedStringName, InheritableValue<ushort> inheritable)
{
ImGui.BeginGroup();
ImGui.Indent();
ImGui.BeginChild(inheritable.GetHashCode().ToString(), new Vector2(180, 47));
ImGui.Text(Localizer.GetString(localizedStringName, false));
bool isEnabled = inheritable.Behavior == InheritableBehavior.Enabled;
@@ -412,17 +463,10 @@ namespace PlayerTags
ImGui.SameLine();
DrawRemoveButton(inheritable);
ImGui.EndChild();
ImGui.EndGroup();
}
private void DrawInheritable(string localizedStringName, InheritableReference<string> inheritable)
{
ImGui.BeginGroup();
ImGui.Indent();
ImGui.BeginChild(inheritable.GetHashCode().ToString(), new Vector2(180, 47));
ImGui.Text(Localizer.GetString(localizedStringName, false));
bool isEnabled = inheritable.Behavior == InheritableBehavior.Enabled;
@@ -447,9 +491,6 @@ namespace PlayerTags
ImGui.SameLine();
DrawRemoveButton(inheritable);
ImGui.EndChild();
ImGui.EndGroup();
}
private void DrawHeading(string label)

View File

@@ -19,7 +19,7 @@ namespace PlayerTags.Resources {
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class Strings {
@@ -72,9 +72,9 @@ namespace PlayerTags.Resources {
/// <summary>
/// Looks up a localized string similar to All Roles.
/// </summary>
public static string Loc_AllRoleTagss {
public static string Loc_AllRoleTags {
get {
return ResourceManager.GetString("Loc_AllRoleTagss", resourceCulture);
return ResourceManager.GetString("Loc_AllRoleTags", resourceCulture);
}
}
@@ -132,6 +132,33 @@ namespace PlayerTags.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Enable context menu options for custom tags.
/// </summary>
public static string Loc_IsCustomTagContextMenuEnabled {
get {
return ResourceManager.GetString("Loc_IsCustomTagContextMenuEnabled", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to When opening the player context menu, options will be available to add and remove custom tags for the selected player..
/// </summary>
public static string Loc_IsCustomTagContextMenuEnabled_Description {
get {
return ResourceManager.GetString("Loc_IsCustomTagContextMenuEnabled_Description", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Enabled.
/// </summary>
public static string Loc_IsEnabled {
get {
return ResourceManager.GetString("Loc_IsEnabled", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Enable the value of this override..
/// </summary>
@@ -144,36 +171,36 @@ namespace PlayerTags.Resources {
/// <summary>
/// Looks up a localized string similar to Icon visible in chat.
/// </summary>
public static string Loc_IsIconVisibleInChatOption {
public static string Loc_IsIconVisibleInChat {
get {
return ResourceManager.GetString("Loc_IsIconVisibleInChatOption", resourceCulture);
return ResourceManager.GetString("Loc_IsIconVisibleInChat", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Whether the icon is visible in the tag in chat..
/// </summary>
public static string Loc_IsIconVisibleInChatOption_Description {
public static string Loc_IsIconVisibleInChat_Description {
get {
return ResourceManager.GetString("Loc_IsIconVisibleInChatOption_Description", resourceCulture);
return ResourceManager.GetString("Loc_IsIconVisibleInChat_Description", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Icon visible in nameplates.
/// </summary>
public static string Loc_IsIconVisibleInNameplateOption {
public static string Loc_IsIconVisibleInNameplates {
get {
return ResourceManager.GetString("Loc_IsIconVisibleInNameplateOption", resourceCulture);
return ResourceManager.GetString("Loc_IsIconVisibleInNameplates", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Whether the icon is visible in the tag in nameplates..
/// </summary>
public static string Loc_IsIconVisibleInNameplateOption_Description {
public static string Loc_IsIconVisibleInNameplates_Description {
get {
return ResourceManager.GetString("Loc_IsIconVisibleInNameplateOption_Description", resourceCulture);
return ResourceManager.GetString("Loc_IsIconVisibleInNameplates_Description", resourceCulture);
}
}
@@ -198,54 +225,108 @@ namespace PlayerTags.Resources {
/// <summary>
/// Looks up a localized string similar to Text italic.
/// </summary>
public static string Loc_IsTextItalicOption {
public static string Loc_IsTextItalic {
get {
return ResourceManager.GetString("Loc_IsTextItalicOption", resourceCulture);
return ResourceManager.GetString("Loc_IsTextItalic", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Whether the text in the tag is italic..
/// </summary>
public static string Loc_IsTextItalicOption_Description {
public static string Loc_IsTextItalic_Description {
get {
return ResourceManager.GetString("Loc_IsTextItalicOption_Description", resourceCulture);
return ResourceManager.GetString("Loc_IsTextItalic_Description", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Text visible in chat.
/// </summary>
public static string Loc_IsTextVisibleInChatOption {
public static string Loc_IsTextVisibleInChat {
get {
return ResourceManager.GetString("Loc_IsTextVisibleInChatOption", resourceCulture);
return ResourceManager.GetString("Loc_IsTextVisibleInChat", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Whether the text is visible in the tag in chat..
/// </summary>
public static string Loc_IsTextVisibleInChatOption_Description {
public static string Loc_IsTextVisibleInChat_Description {
get {
return ResourceManager.GetString("Loc_IsTextVisibleInChatOption_Description", resourceCulture);
return ResourceManager.GetString("Loc_IsTextVisibleInChat_Description", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Text visible in nameplates.
/// </summary>
public static string Loc_IsTextVisibleInNameplateOption {
public static string Loc_IsTextVisibleInNameplates {
get {
return ResourceManager.GetString("Loc_IsTextVisibleInNameplateOption", resourceCulture);
return ResourceManager.GetString("Loc_IsTextVisibleInNameplates", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Whether the text is visible in the tag in nameplates..
/// </summary>
public static string Loc_IsTextVisibleInNameplateOption_Description {
public static string Loc_IsTextVisibleInNameplates_Description {
get {
return ResourceManager.GetString("Loc_IsTextVisibleInNameplateOption_Description", resourceCulture);
return ResourceManager.GetString("Loc_IsTextVisibleInNameplates_Description", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Free company.
/// </summary>
public static string Loc_NameplateElement_FreeCompany {
get {
return ResourceManager.GetString("Loc_NameplateElement_FreeCompany", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The free company element on nameplates..
/// </summary>
public static string Loc_NameplateElement_FreeCompany_Description {
get {
return ResourceManager.GetString("Loc_NameplateElement_FreeCompany_Description", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Name.
/// </summary>
public static string Loc_NameplateElement_Name {
get {
return ResourceManager.GetString("Loc_NameplateElement_Name", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The name element on nameplates..
/// </summary>
public static string Loc_NameplateElement_Name_Description {
get {
return ResourceManager.GetString("Loc_NameplateElement_Name_Description", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Title.
/// </summary>
public static string Loc_NameplateElement_Title {
get {
return ResourceManager.GetString("Loc_NameplateElement_Title", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The title element on nameplates..
/// </summary>
public static string Loc_NameplateElement_Title_Description {
get {
return ResourceManager.GetString("Loc_NameplateElement_Title_Description", resourceCulture);
}
}
@@ -492,6 +573,24 @@ namespace PlayerTags.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Add tag.
/// </summary>
public static string Loc_Static_ContextMenu_AddTag {
get {
return ResourceManager.GetString("Loc_Static_ContextMenu_AddTag", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Remove tag.
/// </summary>
public static string Loc_Static_ContextMenu_RemoveTag {
get {
return ResourceManager.GetString("Loc_Static_ContextMenu_RemoveTag", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Development.
/// </summary>
@@ -501,6 +600,15 @@ namespace PlayerTags.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to General.
/// </summary>
public static string Loc_Static_General {
get {
return ResourceManager.GetString("Loc_Static_General", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Nameplates.
/// </summary>
@@ -510,6 +618,24 @@ namespace PlayerTags.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Assign custom tags to party.
/// </summary>
public static string Loc_Static_PartyAssign {
get {
return ResourceManager.GetString("Loc_Static_PartyAssign", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Player name.
/// </summary>
public static string Loc_Static_PlayerName {
get {
return ResourceManager.GetString("Loc_Static_PlayerName", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Player Tags.
/// </summary>
@@ -628,7 +754,7 @@ namespace PlayerTags.Resources {
}
/// <summary>
/// Looks up a localized string similar to Tag position in chat.
/// Looks up a localized string similar to Tag position in nameplates.
/// </summary>
public static string Loc_TagPositionInNameplates {
get {
@@ -646,7 +772,7 @@ namespace PlayerTags.Resources {
}
/// <summary>
/// Looks up a localized string similar to Tag target in chat.
/// Looks up a localized string similar to Tag target in nameplates.
/// </summary>
public static string Loc_TagTargetInNameplates {
get {
@@ -684,18 +810,18 @@ namespace PlayerTags.Resources {
/// <summary>
/// Looks up a localized string similar to Text color.
/// </summary>
public static string Loc_TextColorOption {
public static string Loc_TextColor {
get {
return ResourceManager.GetString("Loc_TextColorOption", resourceCulture);
return ResourceManager.GetString("Loc_TextColor", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The color of the text in the tag..
/// </summary>
public static string Loc_TextColorOption_Description {
public static string Loc_TextColor_Description {
get {
return ResourceManager.GetString("Loc_TextColorOption_Description", resourceCulture);
return ResourceManager.GetString("Loc_TextColor_Description", resourceCulture);
}
}
}

View File

@@ -123,9 +123,30 @@
<data name="Loc_Static_WarningMessage" xml:space="preserve">
<value>This plugin can modify nameplates. When combined with other plugins that modify nameplates, you are likely to see unexpected behavior.</value>
</data>
<data name="Loc_Static_General" xml:space="preserve">
<value>General</value>
</data>
<data name="Loc_Static_PartyAssign" xml:space="preserve">
<value>Assign custom tags to party</value>
</data>
<data name="Loc_Static_PlayerName" xml:space="preserve">
<value>Player name</value>
</data>
<data name="Loc_Static_ContextMenu_AddTag" xml:space="preserve">
<value>Add tag</value>
</data>
<data name="Loc_Static_ContextMenu_RemoveTag" xml:space="preserve">
<value>Remove tag</value>
</data>
<data name="Loc_Static_Nameplates" xml:space="preserve">
<value>Nameplates</value>
</data>
<data name="Loc_IsCustomTagContextMenuEnabled" xml:space="preserve">
<value>Enable context menu options for custom tags</value>
</data>
<data name="Loc_IsCustomTagContextMenuEnabled_Description" xml:space="preserve">
<value>When opening the player context menu, options will be available to add and remove custom tags for the selected player.</value>
</data>
<data name="Loc_NameplateFreeCompanyVisibility" xml:space="preserve">
<value>Free company visibility</value>
</data>
@@ -292,7 +313,7 @@
</data>
<data name="Loc_IsTextItalic" xml:space="preserve">
<value>Text italic</value>
</data>
</data>
<data name="Loc_IsTextItalic_Description" xml:space="preserve">
<value>Whether the text in the tag is italic.</value>
</data>

View File

@@ -80,7 +80,7 @@ namespace PlayerTags
public InheritableReference<string> GameObjectNamesToApplyTo = new InheritableReference<string>("");
private string[] CleanGameObjectNamesToApplyTo
private string[] SplitGameObjectNamesToApplyTo
{
get
{
@@ -89,7 +89,15 @@ namespace PlayerTags
return new string[] { };
}
return GameObjectNamesToApplyTo.InheritedValue.Split(';', ',').Select(gameObjectName => gameObjectName.ToLower().Trim()).ToArray();
return GameObjectNamesToApplyTo.InheritedValue.Split(';', ',');
}
}
private string[] CleanGameObjectNamesToApplyTo
{
get
{
return SplitGameObjectNamesToApplyTo.Select(gameObjectName => gameObjectName.ToLower().Trim()).ToArray();
}
}
@@ -103,6 +111,35 @@ namespace PlayerTags
return CleanGameObjectNamesToApplyTo.Contains(gameObjectName.ToLower());
}
public void AddGameObjectNameToApplyTo(string gameObjectName)
{
if (IncludesGameObjectNameToApplyTo(gameObjectName))
{
return;
}
List<string> newSplitGameObjectNamesToApplyTo = SplitGameObjectNamesToApplyTo.ToList();
newSplitGameObjectNamesToApplyTo.Add(gameObjectName);
GameObjectNamesToApplyTo = string.Join(";", newSplitGameObjectNamesToApplyTo);
}
public void RemoveGameObjectNameToApplyTo(string gameObjectName)
{
if (!IncludesGameObjectNameToApplyTo(gameObjectName))
{
return;
}
List<string> newSplitGameObjectNamesToApplyTo = SplitGameObjectNamesToApplyTo.ToList();
var index = Array.IndexOf(CleanGameObjectNamesToApplyTo, gameObjectName.ToLower());
newSplitGameObjectNamesToApplyTo.RemoveAt(index);
GameObjectNamesToApplyTo = string.Join(";", newSplitGameObjectNamesToApplyTo);
}
public Dictionary<string, InheritableData> GetChanges(Dictionary<string, InheritableData>? defaultChanges = null)
{
Dictionary<string, InheritableData> changes = new Dictionary<string, InheritableData>();