Complete Rework + Update (#15)

* Remove unused dalamud packager overrides

* Use category tags, add actual description

* Use .net7

* Update DalamudPackager, update for Api8

* Remove hardcoded images, we'll use lumina to get these dynamically

* Add KamiLib

* Refactor Currency Alert

* Add LocalizationManager.cs

* remove trailing comma

* Add No Decoration flag

* More touchups and features

* Increase Version Number 0.5.0.0

* Move Chat Notifications to its own category

* Hide overlay if not logged in or there are no warnings to show

* Increase update frequency to 4x per second
This commit is contained in:
MidoriKami 2023-01-10 12:07:57 -08:00 committed by GitHub
parent 0bcc9cff01
commit e97fe36ba0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
46 changed files with 1127 additions and 464 deletions

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "KamiLib"]
path = KamiLib
url = https://github.com/MidoriKami/KamiLib

View File

@ -5,6 +5,8 @@ VisualStudioVersion = 17.0.31919.166
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CurrencyAlert", "CurrencyAlert\CurrencyAlert.csproj", "{13C812E9-0D42-4B95-8646-40EEBF30636F}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CurrencyAlert", "CurrencyAlert\CurrencyAlert.csproj", "{13C812E9-0D42-4B95-8646-40EEBF30636F}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KamiLib", "KamiLib\KamiLib.csproj", "{6EAC83CF-FCF8-42F0-B923-13658DD93725}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64 Debug|x64 = Debug|x64
@ -15,6 +17,10 @@ Global
{13C812E9-0D42-4B95-8646-40EEBF30636F}.Debug|x64.Build.0 = Debug|x64 {13C812E9-0D42-4B95-8646-40EEBF30636F}.Debug|x64.Build.0 = Debug|x64
{13C812E9-0D42-4B95-8646-40EEBF30636F}.Release|x64.ActiveCfg = Release|x64 {13C812E9-0D42-4B95-8646-40EEBF30636F}.Release|x64.ActiveCfg = Release|x64
{13C812E9-0D42-4B95-8646-40EEBF30636F}.Release|x64.Build.0 = Release|x64 {13C812E9-0D42-4B95-8646-40EEBF30636F}.Release|x64.Build.0 = Release|x64
{6EAC83CF-FCF8-42F0-B923-13658DD93725}.Debug|x64.ActiveCfg = Debug|x64
{6EAC83CF-FCF8-42F0-B923-13658DD93725}.Debug|x64.Build.0 = Debug|x64
{6EAC83CF-FCF8-42F0-B923-13658DD93725}.Release|x64.ActiveCfg = Release|x64
{6EAC83CF-FCF8-42F0-B923-13658DD93725}.Release|x64.Build.0 = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@ -0,0 +1,45 @@
using System.Collections.Generic;
using CurrencyAlert.Localization;
using KamiLib.ChatCommands;
using KamiLib.Interfaces;
namespace CurrencyAlert.Commands;
public class OverlayCommands : IPluginCommand
{
public string CommandArgument => "overlay";
public IEnumerable<ISubCommand> SubCommands { get; } = new List<ISubCommand>
{
new SubCommand
{
CommandKeyword = "show",
CommandAction = () =>
{
Service.Configuration.OverlaySettings.Show.Value = true;
Service.Configuration.Save();
},
GetHelpText = () => Strings.Commands_ShowOverlayHelp,
},
new SubCommand
{
CommandKeyword = "hide",
CommandAction = () =>
{
Service.Configuration.OverlaySettings.Show.Value = false;
Service.Configuration.Save();
},
GetHelpText = () => Strings.Commands_HideOverlayHelp,
},
new SubCommand
{
CommandKeyword = "toggle",
CommandAction = () =>
{
Service.Configuration.OverlaySettings.Show.Value = !Service.Configuration.OverlaySettings.Show.Value;
Service.Configuration.Save();
},
GetHelpText = () => Strings.Commands_ToggleOverlayHelp,
},
};
}

View File

@ -1,38 +1,57 @@
using CurrencyAlert.Helper; using Dalamud.Configuration;
using CurrencyAlert.Provider;
using Dalamud.Configuration;
using Dalamud.Plugin; using Dalamud.Plugin;
using System; using System;
using System.Collections.Generic; using CurrencyAlert.DataModels;
using CurrencyAlert.Windows;
using KamiLib.Configuration;
namespace CurrencyAlert namespace CurrencyAlert;
[Serializable]
public class Configuration : IPluginConfiguration
{ {
[Serializable] public int Version { get; set; } = 6;
public class Configuration : IPluginConfiguration
{
public int Version { get; set; } = 5;
public bool UiLocked { get; set; } = false; public OverlaySettings OverlaySettings = new();
public Dictionary<int, bool> AlertEnabled { get; } = new Dictionary<int, bool>(); public DisplaySettings DisplaySettings = new();
public Dictionary<int, int> Threshold { get; } = new Dictionary<int, int>(); public Setting<bool> ChatNotification = new(false);
public Configuration() public TrackedCurrency[] TrackedCurrencies = {
{ // Grand Company Seals
foreach (var currency in CurrencyProvider.Instance.GetAll()) new(CurrencyName.StormSeal, new Setting<int>(75_000), new Setting<bool>(true)),
{ new(CurrencyName.SerpentSeals, new Setting<int>(75_000), new Setting<bool>(true)),
this.AlertEnabled[currency.Id] = true; new(CurrencyName.FlameSeals, new Setting<int>(75_000), new Setting<bool>(true)),
this.Threshold[currency.Id] = currency.DefaultThreshold;
}
}
public void Initialize() // PvP Currencies
{ new(CurrencyName.WolfMarks, new Setting<int>(18_000), new Setting<bool>(true)),
new(CurrencyName.TrophyCrystals, new Setting<int>(18_000), new Setting<bool>(true)),
} // Hunts
new(CurrencyName.AlliedSeals, new Setting<int>(3_500), new Setting<bool>(true)),
new(CurrencyName.CenturioSeals, new Setting<int>(3_500), new Setting<bool>(true)),
new(CurrencyName.SackOfNuts, new Setting<int>(3_500), new Setting<bool>(true)),
public void Save() // FATEs
{ new(CurrencyName.BicolorGemstones, new Setting<int>(800), new Setting<bool>(true)),
PluginHelper.PluginInterface.SavePluginConfig(this);
} // Tomestones
} new(CurrencyName.Poetics, new Setting<int>(1_400), new Setting<bool>(true)),
new(CurrencyName.NonLimitedTomestone, new Setting<int>(1_700), new Setting<bool>(true)),
new(CurrencyName.LimitedTomestone, new Setting<int>(1_700), new Setting<bool>(true)),
// Crafting & Gathering
new(CurrencyName.WhiteCrafterScripts, new Setting<int>(3_500), new Setting<bool>(true)),
new(CurrencyName.WhiteGatherersScripts, new Setting<int>(3_500), new Setting<bool>(true)),
new(CurrencyName.PurpleCrafterScripts, new Setting<int>(3_500), new Setting<bool>(true)),
new(CurrencyName.PurpleGatherersScripts, new Setting<int>(3_500), new Setting<bool>(true)),
// Ishguard Restoration
new(CurrencyName.SkybuildersScripts, new Setting<int>(7_500), new Setting<bool>(true)),
};
[NonSerialized]
private DalamudPluginInterface? pluginInterface;
public void Initialize(DalamudPluginInterface inputPluginInterface) => pluginInterface = inputPluginInterface;
public void Save() => pluginInterface!.SavePluginConfig(this);
} }

View File

@ -1,34 +1,13 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<Authors></Authors> <Version>0.5.0.0</Version>
<Company></Company>
<Version>0.4.0.0</Version>
<Description>Currency Alert</Description> <Description>Currency Alert</Description>
<Copyright></Copyright>
<PackageProjectUrl>https://github.com/Lharz/xiv-currency-alert</PackageProjectUrl> <PackageProjectUrl>https://github.com/Lharz/xiv-currency-alert</PackageProjectUrl>
</PropertyGroup> </PropertyGroup>
<ProjectExtensions>
<DalamudPlugin>
<ApiLevel>7</ApiLevel>
<Author>Lharz</Author>
<Name>CurrencyAlert</Name>
<Punchline>Display alerts upon reaching configurable currencies thresholds (such as Poetics or PVP marks).</Punchline>
<Description>/currencyalert: shows the configuration panel.</Description>
<Tags>
<Tag>Currency</Tag>
<Tag>Utility</Tag>
</Tags>
<Images>
<Icon>../icon.png</Icon>
</Images>
<Hidden>False</Hidden>
</DalamudPlugin>
</ProjectExtensions>
<PropertyGroup> <PropertyGroup>
<TargetFramework>net6.0-windows</TargetFramework> <TargetFramework>net7.0-windows</TargetFramework>
<Platforms>x64</Platforms> <Platforms>x64</Platforms>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<LangVersion>latest</LangVersion> <LangVersion>latest</LangVersion>
@ -47,7 +26,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="DalamudPackager" Version="2.1.8" /> <PackageReference Include="DalamudPackager" Version="2.1.10" />
<Reference Include="FFXIVClientStructs"> <Reference Include="FFXIVClientStructs">
<HintPath>$(DalamudLibPath)FFXIVClientStructs.dll</HintPath> <HintPath>$(DalamudLibPath)FFXIVClientStructs.dll</HintPath>
<Private>false</Private> <Private>false</Private>
@ -82,4 +61,23 @@
<Content Include="images\**" Link="images\%(RecursiveDir)\%(Filename)%(Extension)" CopyToOutputDirectory="Always" /> <Content Include="images\**" Link="images\%(RecursiveDir)\%(Filename)%(Extension)" CopyToOutputDirectory="Always" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\KamiLib\KamiLib.csproj" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Localization\Strings.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Strings.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Compile Update="Localization\Strings.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Strings.resx</DependentUpon>
</Compile>
</ItemGroup>
</Project> </Project>

View File

@ -2,15 +2,17 @@
"Author": "Lharz", "Author": "Lharz",
"Name": "CurrencyAlert", "Name": "CurrencyAlert",
"Punchline": "Display alerts upon reaching configurable currencies thresholds (such as Poetics or PVP marks).", "Punchline": "Display alerts upon reaching configurable currencies thresholds (such as Poetics or PVP marks).",
"Description": "/currencyalert: shows the configuration panel.", "Description": "This plugin lets you easily manage your various currencies to prevent from wasting precious resources.",
"Changelog": null,
"Tags": [ "Tags": [
"plugin", "Currency",
"currency", "Tomestones",
"tomestones", "Utility",
"utility", "Other"
"other"
], ],
"CategoryTags": null, "CategoryTags": [
"RepoUrl": "https://github.com/Lharz/xiv-currency-alert", "Utility",
"Other",
"UI"
],
"RepoUrl": "https://github.com/Lharz/xiv-currency-alert"
} }

View File

@ -0,0 +1,84 @@
using System;
using System.Linq;
using Dalamud.Utility;
using FFXIVClientStructs.FFXIV.Client.Game;
using ImGuiScene;
using KamiLib.Caching;
using Lumina.Excel.GeneratedSheets;
namespace CurrencyAlert.DataModels;
public class CurrencyInfo : IDisposable
{
public uint ItemID { get; }
public string ItemName { get; } = string.Empty;
public uint IconID { get; }
public TextureWrap? IconTexture { get; }
public CurrencyInfo(CurrencyName currency)
{
ItemID = GetItemIdForCurrency(currency);
// Gets the item from Lumina, then checks if it is null
if (LuminaCache<Item>.Instance.GetRow(ItemID) is { } currencyItem)
{
ItemName = currencyItem.Name.ToDalamudString().TextValue;
IconID = currencyItem.Icon;
if (IconCache.Instance.GetIcon(IconID) is { } iconTexture)
{
IconTexture = iconTexture;
}
}
}
public void Dispose()
{
IconTexture?.Dispose();
}
public unsafe int GetCurrentQuantity() => InventoryManager.Instance()->GetInventoryItemCount(ItemID);
private static uint GetItemIdForCurrency(CurrencyName currency)
{
return currency switch
{
CurrencyName.StormSeal => 20,
CurrencyName.SerpentSeals => 21,
CurrencyName.FlameSeals => 22,
CurrencyName.WolfMarks => 25,
CurrencyName.TrophyCrystals => 36656,
CurrencyName.AlliedSeals => 27,
CurrencyName.CenturioSeals => 10307,
CurrencyName.SackOfNuts => 26533,
CurrencyName.BicolorGemstones => 26807,
CurrencyName.Poetics => 28,
CurrencyName.NonLimitedTomestone => GetNonLimitedTomestoneId(),
CurrencyName.LimitedTomestone => GetLimitedTomestoneId(),
CurrencyName.WhiteCrafterScripts => 25199,
CurrencyName.WhiteGatherersScripts => 25200,
CurrencyName.PurpleCrafterScripts => 33913,
CurrencyName.PurpleGatherersScripts => 33914,
CurrencyName.SkybuildersScripts => 28063,
_ => throw new ArgumentOutOfRangeException(nameof(currency), currency, null)
};
}
// This will always return the ItemID of whatever tomestone is currently weekly limited
private static uint GetLimitedTomestoneId()
{
return LuminaCache<TomestonesItem>.Instance
.Where(tomestone => tomestone.Tomestones.Row is 3)
.First()
.Item.Row;
}
// This will always return the ItemID of whatever tomestone is not limited
private static uint GetNonLimitedTomestoneId()
{
return LuminaCache<TomestonesItem>.Instance
.Where(tomestone => tomestone.Tomestones.Row is 2)
.First()
.Item.Row;
}
}

View File

@ -0,0 +1,27 @@
namespace CurrencyAlert.DataModels;
public enum CurrencyName
{
StormSeal,
SerpentSeals,
FlameSeals,
WolfMarks,
TrophyCrystals,
AlliedSeals,
CenturioSeals,
SackOfNuts,
BicolorGemstones,
Poetics,
NonLimitedTomestone,
LimitedTomestone,
WhiteCrafterScripts,
WhiteGatherersScripts,
PurpleCrafterScripts,
PurpleGatherersScripts,
SkybuildersScripts,
}

View File

@ -0,0 +1,13 @@
using System.Numerics;
using KamiLib.Configuration;
using KamiLib.Drawing;
namespace CurrencyAlert.DataModels;
public class DisplaySettings
{
public Setting<bool> ShowIcon = new(true);
public Setting<bool> ShowName = new(true);
public Setting<bool> ShowWarningText = new(true);
public Setting<Vector4> TextColor = new(Colors.White);
}

View File

@ -0,0 +1,30 @@
using System.Numerics;
using ImGuiNET;
using KamiLib.Configuration;
namespace CurrencyAlert.DataModels;
public record TrackedCurrency(CurrencyName Name, Setting<int> Threshold, Setting<bool> Enabled)
{
private static DisplaySettings DisplaySettings => Service.Configuration.DisplaySettings;
public CurrencyInfo CurrencyInfo()
{
return new CurrencyInfo(Name);
}
public void DrawIcon()
{
if (CurrencyInfo().IconTexture is { } icon)
{
ImGui.Image(icon.ImGuiHandle, new Vector2(20.0f));
}
}
public void DrawName(Vector4 color)
{
ImGui.TextColored(color, CurrencyInfo().ItemName);
}
}

View File

@ -1,26 +0,0 @@
using CurrencyAlert.Enum;
using CurrencyAlert.Helper;
using ImGuiScene;
namespace CurrencyAlert.Entity
{
internal class Currency
{
public int Id { get; }
public string Name { get; }
public CurrencyType Type { get; }
public Category Category { get; }
public TextureWrap? Image { get; }
public int DefaultThreshold { get; }
public Currency(int id, string name, CurrencyType type, Category category, int defaultThreshold)
{
Id = id;
Name = name;
Type = type;
Category = category;
DefaultThreshold = defaultThreshold;
Image = ImageHelper.LoadImage(id.ToString());
}
}
}

View File

@ -1,9 +0,0 @@
namespace CurrencyAlert.Enum
{
public enum Category
{
Common,
Battle,
Other
}
}

View File

@ -1,28 +0,0 @@
namespace CurrencyAlert.Enum
{
public enum CurrencyType
{
TomestoneOfPoetics,
TomestoneOfAphorism,
TomestoneOfAstronomy,
TomestoneOfCausality,
StormSeal,
SerpentSeal,
FlameSeal,
WolfMark,
TrophyCrystal,
AlliedSeal,
CenturioSeal,
SackOfNut,
BicolorGemstone,
WhiteCraftersScrip,
PurpleCraftersScrip,
WhiteGatherersScrip,
PurpleGatherersScrip,
SkybuildersScrip
}
}

View File

@ -1,24 +0,0 @@
using ImGuiScene;
using System;
using System.IO;
namespace CurrencyAlert.Helper
{
internal class ImageHelper
{
public static TextureWrap? LoadImage(string imageName)
{
var assemblyLocation = PluginHelper.PluginInterface.AssemblyLocation.DirectoryName!;
var imagePath = Path.Combine(assemblyLocation, $@"images\{imageName}.png");
try
{
return PluginHelper.PluginInterface.UiBuilder.LoadImage(imagePath);
}
catch (SystemException e)
{
return null;
}
}
}
}

View File

@ -1,16 +0,0 @@
using Dalamud.Game.ClientState;
using Dalamud.Game.Command;
using Dalamud.Game.Gui;
using Dalamud.IoC;
using Dalamud.Plugin;
namespace CurrencyAlert.Helper
{
internal class PluginHelper
{
[PluginService] public static DalamudPluginInterface PluginInterface { get; private set; } = null!;
[PluginService] public static ClientState ClientState { get; private set; } = null!;
[PluginService] public static CommandManager CommandManager { get; private set; } = null!;
[PluginService] public static ChatGui Chat { get; private set; } = null!;
}
}

View File

@ -0,0 +1,41 @@
using System;
using System.Globalization;
using Dalamud.Logging;
namespace CurrencyAlert.Localization;
internal class LocalizationManager : IDisposable
{
private static LocalizationManager? _instance;
public static LocalizationManager Instance => _instance ??= new LocalizationManager();
public void Initialize()
{
Strings.Culture = new CultureInfo(Service.PluginInterface.UiLanguage);
Service.PluginInterface.LanguageChanged += OnLanguageChange;
}
public static void Cleanup()
{
_instance?.Dispose();
}
public void Dispose()
{
Service.PluginInterface.LanguageChanged -= OnLanguageChange;
}
private void OnLanguageChange(string languageCode)
{
try
{
PluginLog.Information($"Loading Localization for {languageCode}");
Strings.Culture = new CultureInfo(languageCode);
}
catch (Exception ex)
{
PluginLog.Error(ex, "Unable to Load Localization");
}
}
}

View File

@ -0,0 +1,269 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace CurrencyAlert.Localization {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// 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", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Strings {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Strings() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("CurrencyAlert.Localization.Strings", typeof(Strings).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to Chat Notifications.
/// </summary>
internal static string ChatNotifications {
get {
return ResourceManager.GetString("ChatNotifications", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Above threshold.
/// </summary>
internal static string ChatWarningText {
get {
return ResourceManager.GetString("ChatWarningText", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Hide Currency Alert Overlay.
/// </summary>
internal static string Commands_HideOverlayHelp {
get {
return ResourceManager.GetString("Commands_HideOverlayHelp", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Show Currency Alert Overlay.
/// </summary>
internal static string Commands_ShowOverlayHelp {
get {
return ResourceManager.GetString("Commands_ShowOverlayHelp", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Toggle Currency Alert Overlay.
/// </summary>
internal static string Commands_ToggleOverlayHelp {
get {
return ResourceManager.GetString("Commands_ToggleOverlayHelp", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Currency Configuration.
/// </summary>
internal static string CurrencyConfiguration {
get {
return ResourceManager.GetString("CurrencyConfiguration", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Currently Selected.
/// </summary>
internal static string CurrentlySelected {
get {
return ResourceManager.GetString("CurrentlySelected", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Default.
/// </summary>
internal static string Default {
get {
return ResourceManager.GetString("Default", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Display Ascending.
/// </summary>
internal static string DisplayAscending {
get {
return ResourceManager.GetString("DisplayAscending", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Display Settings.
/// </summary>
internal static string DisplaySettings {
get {
return ResourceManager.GetString("DisplaySettings", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Enabled.
/// </summary>
internal static string Enabled {
get {
return ResourceManager.GetString("Enabled", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to General Settings.
/// </summary>
internal static string GeneralSettings {
get {
return ResourceManager.GetString("GeneralSettings", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Lock Position.
/// </summary>
internal static string LockOverlay {
get {
return ResourceManager.GetString("LockOverlay", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Minimal Display.
/// </summary>
internal static string MinimalOverlay {
get {
return ResourceManager.GetString("MinimalOverlay", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Opacity.
/// </summary>
internal static string Opacity {
get {
return ResourceManager.GetString("Opacity", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Overlay Settings.
/// </summary>
internal static string OverlaySettings {
get {
return ResourceManager.GetString("OverlaySettings", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to You need to spend your.
/// </summary>
internal static string OverlayWarningText {
get {
return ResourceManager.GetString("OverlayWarningText", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Show Currency Icon.
/// </summary>
internal static string ShowCurrencyIcon {
get {
return ResourceManager.GetString("ShowCurrencyIcon", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Show Currency Name.
/// </summary>
internal static string ShowCurrencyName {
get {
return ResourceManager.GetString("ShowCurrencyName", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Show Overlay.
/// </summary>
internal static string ShowOverlay {
get {
return ResourceManager.GetString("ShowOverlay", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Show Warning Text.
/// </summary>
internal static string ShowWarningText {
get {
return ResourceManager.GetString("ShowWarningText", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Text Color.
/// </summary>
internal static string TextColor {
get {
return ResourceManager.GetString("TextColor", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Threshold.
/// </summary>
internal static string Threshold {
get {
return ResourceManager.GetString("Threshold", resourceCulture);
}
}
}
}

View File

@ -0,0 +1,90 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="GeneralSettings" xml:space="preserve">
<value>General Settings</value>
</data>
<data name="OverlaySettings" xml:space="preserve">
<value>Overlay Settings</value>
</data>
<data name="ShowOverlay" xml:space="preserve">
<value>Show Overlay</value>
</data>
<data name="LockOverlay" xml:space="preserve">
<value>Lock Position</value>
</data>
<data name="MinimalOverlay" xml:space="preserve">
<value>Minimal Display</value>
</data>
<data name="Opacity" xml:space="preserve">
<value>Opacity</value>
</data>
<data name="DisplaySettings" xml:space="preserve">
<value>Display Settings</value>
</data>
<data name="ShowCurrencyIcon" xml:space="preserve">
<value>Show Currency Icon</value>
</data>
<data name="ShowCurrencyName" xml:space="preserve">
<value>Show Currency Name</value>
</data>
<data name="ShowWarningText" xml:space="preserve">
<value>Show Warning Text</value>
</data>
<data name="CurrencyConfiguration" xml:space="preserve">
<value>Currency Configuration</value>
</data>
<data name="Enabled" xml:space="preserve">
<value>Enabled</value>
</data>
<data name="Threshold" xml:space="preserve">
<value>Threshold</value>
</data>
<data name="OverlayWarningText" xml:space="preserve">
<value>You need to spend your</value>
</data>
<data name="ChatWarningText" xml:space="preserve">
<value>Above threshold</value>
</data>
<data name="Commands_ShowOverlayHelp" xml:space="preserve">
<value>Show Currency Alert Overlay</value>
</data>
<data name="Commands_HideOverlayHelp" xml:space="preserve">
<value>Hide Currency Alert Overlay</value>
</data>
<data name="Commands_ToggleOverlayHelp" xml:space="preserve">
<value>Toggle Currency Alert Overlay</value>
</data>
<data name="CurrentlySelected" xml:space="preserve">
<value>Currently Selected</value>
</data>
<data name="ChatNotifications" xml:space="preserve">
<value>Chat Notifications</value>
</data>
<data name="DisplayAscending" xml:space="preserve">
<value>Display Ascending</value>
</data>
<data name="TextColor" xml:space="preserve">
<value>Text Color</value>
</data>
<data name="Default" xml:space="preserve">
<value>Default</value>
</data>
</root>

View File

@ -1,108 +1,36 @@
using CurrencyAlert.Helper; using CurrencyAlert.Localization;
using CurrencyAlert.Provider; using CurrencyAlert.System.cs;
using Dalamud.Game.Command; using CurrencyAlert.Windows;
using Dalamud.Game.Gui;
using Dalamud.IoC;
using Dalamud.Plugin; using Dalamud.Plugin;
using FFXIVClientStructs.FFXIV.Client.Game; using KamiLib;
using ImGuiNET;
using Newtonsoft.Json;
using System;
using System.Reflection;
namespace CurrencyAlert namespace CurrencyAlert;
public sealed class Plugin : IDalamudPlugin
{ {
public sealed class Plugin : IDalamudPlugin public string Name => "CurrencyAlert";
public Plugin(DalamudPluginInterface pluginInterface)
{ {
public string Name => "Currency Alert"; pluginInterface.Create<Service>();
private const string commandName = "/currencyalert"; KamiCommon.Initialize(pluginInterface, Name, () => Service.Configuration.Save());
LocalizationManager.Instance.Initialize();
private Configuration Configuration { get; init; } Service.Configuration = Service.PluginInterface.GetPluginConfig() as Configuration ?? new Configuration();
private PluginUI PluginUI { get; init; } Service.Configuration.Initialize(Service.PluginInterface);
[PluginService] public static ChatGui Chat { get; private set; } = null!; KamiCommon.WindowManager.AddConfigurationWindow(new ConfigurationWindow());
KamiCommon.WindowManager.AddWindow(new OverlayWindow());
private bool LoggedIn => PluginHelper.ClientState.LocalPlayer != null && PluginHelper.ClientState.LocalContentId != 0; Service.CurrencyTracker = new CurrencyTracker();
}
public Plugin(DalamudPluginInterface pluginInterface) public void Dispose()
{ {
pluginInterface.Create<PluginHelper>(); KamiCommon.Dispose();
try Service.CurrencyTracker.Dispose();
{ LocalizationManager.Cleanup();
this.Configuration = PluginHelper.PluginInterface.GetPluginConfig() as Configuration ?? new Configuration();
}
catch (Exception e)
{
this.Configuration = new Configuration();
this.Configuration.Save();
PluginHelper.Chat.Print("Your CurrencyAlert configuration has been reset because of compatibility issues. Please check the plugin configuration window.");
}
this.Configuration.Initialize();
var assemblyLocation = Assembly.GetExecutingAssembly().Location;
this.PluginUI = new PluginUI(this.Configuration);
PluginHelper.CommandManager.AddHandler(commandName, new CommandInfo(OnCommand)
{
HelpMessage = "Lets you configure alert thresholds for various currencies"
});
PluginHelper.PluginInterface.UiBuilder.Draw += DrawUI;
PluginHelper.PluginInterface.UiBuilder.OpenConfigUi += DrawConfigUI;
}
public void Dispose()
{
this.PluginUI.Dispose();
PluginHelper.CommandManager.RemoveHandler(commandName);
}
private void OnCommand(string command, string args)
{
this.DrawConfigUI();
}
private void DrawUI()
{
if (!this.LoggedIn)
return;
this.UpdateAlerts();
this.PluginUI.Draw();
}
private void UpdateAlerts()
{
// TODO: move this logic elsewhere
// TODO: do this only every X seconds
unsafe
{
InventoryManager* inventoryManager = InventoryManager.Instance();
foreach (var currency in CurrencyProvider.Instance.GetAll())
{
int quantity = inventoryManager->GetInventoryItemCount((uint)currency.Id);
if (this.Configuration.AlertEnabled[currency.Id] && quantity >= this.Configuration.Threshold[currency.Id])
{
this.PluginUI.AlertVisible[currency.Id] = true;
}
else
{
this.PluginUI.AlertVisible[currency.Id] = false;
}
}
}
}
private void DrawConfigUI()
{
this.PluginUI.SettingsVisible = true;
}
} }
} }

View File

@ -1,145 +0,0 @@
using CurrencyAlert.Provider;
using ImGuiNET;
using System;
using System.Collections.Generic;
using System.Numerics;
namespace CurrencyAlert
{
class PluginUI : IDisposable
{
private Configuration configuration;
private bool settingsVisible = false;
public bool SettingsVisible
{
get { return settingsVisible; }
set { settingsVisible = value; }
}
public Dictionary<int, bool> AlertVisible { get; set; } = new Dictionary<int, bool>();
public PluginUI(Configuration configuration)
{
this.configuration = configuration;
foreach (var currency in CurrencyProvider.Instance.GetAll())
{
this.AlertVisible[currency.Id] = false;
}
}
public void Dispose()
{
}
public void Draw()
{
DrawMainWindow();
if (this.SettingsVisible)
DrawSettingsWindow();
}
public void DrawMainWindow()
{
foreach (var currency in CurrencyProvider.Instance.GetAll())
{
if (!this.AlertVisible[currency.Id])
continue;
ImGui.SetNextWindowSize(new Vector2(375, 10), ImGuiCond.FirstUseEver);
ImGui.SetNextWindowSizeConstraints(new Vector2(375, 10), new Vector2(float.MaxValue, float.MaxValue));
var isVisible = this.AlertVisible[currency.Id];
var guiOptions = ImGuiWindowFlags.NoScrollbar |
ImGuiWindowFlags.NoScrollWithMouse |
ImGuiWindowFlags.AlwaysAutoResize |
ImGuiWindowFlags.NoTitleBar |
ImGuiWindowFlags.NoFocusOnAppearing;
if (configuration.UiLocked)
guiOptions |= ImGuiWindowFlags.NoMove;
if (ImGui.Begin("Currency Alert", ref isVisible, guiOptions))
{
ImGui.Text($"You need to spend your");
if (currency.Image != null)
{
ImGui.SameLine();
ImGui.Image(currency.Image.ImGuiHandle, new Vector2(22, 22));
}
ImGui.SameLine();
ImGui.Text($"{currency.Name}");
ImGui.End();
}
}
}
public void DrawSettingsWindow()
{
ImGui.SetNextWindowSize(new Vector2(700, 500), ImGuiCond.FirstUseEver);
if (ImGui.Begin("Currency Alert Configuration Window", ref this.settingsVisible))
{
var uiLocked = this.configuration.UiLocked;
if (ImGui.Checkbox("Lock alert window", ref uiLocked))
{
this.configuration.UiLocked = uiLocked;
this.configuration.Save();
}
if (ImGui.BeginTabBar("AlertsConfiguration_Tabs"))
{
foreach (var currency in CurrencyProvider.Instance.GetAll())
{
var name = currency.Name;
var category = currency.Category;
var alertEnabled = this.configuration.AlertEnabled[currency.Id];
if (ImGui.BeginTabItem(category.ToString()))
{
if (currency.Image != null)
{
ImGui.Image(currency.Image.ImGuiHandle, new Vector2(22, 22));
ImGui.SameLine();
}
ImGui.Text($"{currency.Name}");
if (ImGui.Checkbox($"Enabled##{name}", ref alertEnabled))
{
this.configuration.AlertEnabled[currency.Id] = alertEnabled;
this.configuration.Save();
}
ImGui.SameLine();
var thresholdValue = this.configuration.Threshold[currency.Id];
if (ImGui.InputInt($"Threshold##{name}", ref thresholdValue, 1, 1,
this.configuration.AlertEnabled[currency.Id] ? ImGuiInputTextFlags.None : ImGuiInputTextFlags.ReadOnly))
{
this.configuration.Threshold[currency.Id] = thresholdValue;
this.configuration.Save();
}
ImGui.Separator();
ImGui.EndTabItem();
}
}
ImGui.EndTabBar();
}
ImGui.End();
}
}
}
}

View File

@ -1,46 +0,0 @@
using CurrencyAlert.Entity;
using System.Collections.Generic;
namespace CurrencyAlert.Provider
{
internal sealed class CurrencyProvider
{
private static CurrencyProvider? instance = null;
public static CurrencyProvider Instance => instance ??= new CurrencyProvider();
private readonly List<Currency> currencies;
public CurrencyProvider()
{
currencies = new List<Currency>
{
new Currency(28, "Tomestones of Poetics", Enum.CurrencyType.TomestoneOfPoetics, Enum.Category.Battle, 1400),
new Currency(43, "Tomestones of Astronomy", Enum.CurrencyType.TomestoneOfAstronomy, Enum.Category.Battle, 1700),
new Currency(44, "Tomestones of Causality", Enum.CurrencyType.TomestoneOfCausality, Enum.Category.Battle, 1700),
new Currency(20, "Storm Seals", Enum.CurrencyType.StormSeal, Enum.Category.Common, 75000),
new Currency(21, "Serpent Seals", Enum.CurrencyType.SerpentSeal, Enum.Category.Common, 75000),
new Currency(22, "Flame Seals", Enum.CurrencyType.FlameSeal, Enum.Category.Common, 75000),
new Currency(25, "Wolf Marks", Enum.CurrencyType.WolfMark, Enum.Category.Battle, 18000),
new Currency(36656, "Trophy Crystals", Enum.CurrencyType.TrophyCrystal, Enum.Category.Battle, 18000),
new Currency(27, "Allied Seals", Enum.CurrencyType.AlliedSeal, Enum.Category.Battle, 3500),
new Currency(10307, "Centurio Seals", Enum.CurrencyType.CenturioSeal, Enum.Category.Battle, 3500),
new Currency(26533, "Sack of Nuts", Enum.CurrencyType.SackOfNut, Enum.Category.Battle, 3500),
new Currency(26807, "Bicolor Gemstone", Enum.CurrencyType.BicolorGemstone, Enum.Category.Battle, 800),
new Currency(25199, "White Crafters' Scrip", Enum.CurrencyType.WhiteCraftersScrip, Enum.Category.Other, 1500),
new Currency(33913, "Purple Crafters' Scrip", Enum.CurrencyType.PurpleCraftersScrip, Enum.Category.Other, 1500),
new Currency(25200, "White Gatherers' Scrip", Enum.CurrencyType.WhiteGatherersScrip, Enum.Category.Other, 1500),
new Currency(33914, "Purple Gatherers' Scrip", Enum.CurrencyType.PurpleGatherersScrip, Enum.Category.Other, 1500),
new Currency(28063, "Skybuilders' Scrip", Enum.CurrencyType.SkybuildersScrip, Enum.Category.Other, 7500),
};
}
public IEnumerable<Currency> GetAll()
{
return currencies;
}
}
}

17
CurrencyAlert/Service.cs Normal file
View File

@ -0,0 +1,17 @@
using CurrencyAlert.System.cs;
using Dalamud.Game;
using Dalamud.Game.ClientState;
using Dalamud.IoC;
using Dalamud.Plugin;
namespace CurrencyAlert;
public class Service
{
[PluginService] public static DalamudPluginInterface PluginInterface { get; private set; } = null!;
[PluginService] public static Framework Framework { get; private set; } = null!;
[PluginService] public static ClientState ClientState { get; private set; } = null!;
public static Configuration Configuration { get; set; } = null!;
public static CurrencyTracker CurrencyTracker { get; set; } = null!;
}

View File

@ -0,0 +1,71 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using CurrencyAlert.DataModels;
using CurrencyAlert.Localization;
using Dalamud.Logging;
using KamiLib.ChatCommands;
namespace CurrencyAlert.System.cs;
public class CurrencyTracker : IDisposable
{
private readonly CancellationTokenSource cancellationTokenSource = new();
private readonly Stopwatch timer = new();
public readonly List<TrackedCurrency> ActiveWarnings = new();
public CurrencyTracker()
{
UpdateCurrencies();
Service.ClientState.TerritoryChanged += OnZoneChange;
}
private void UpdateCurrencies()
{
Service.Framework.RunOnTick(UpdateCurrencies, TimeSpan.FromMilliseconds(250), 0, cancellationTokenSource.Token);
ActiveWarnings.Clear();
if (!Service.ClientState.IsLoggedIn) return;
foreach (var currency in Service.Configuration.TrackedCurrencies)
{
if (currency.Enabled)
{
if (currency.CurrencyInfo().GetCurrentQuantity() >= currency.Threshold.Value)
{
ActiveWarnings.Add(currency);
}
}
}
}
private void OnZoneChange(object? sender, ushort e)
{
if (!Service.Configuration.ChatNotification) return;
if (timer.Elapsed.Minutes >= 5 || timer.IsRunning == false)
{
timer.Restart();
foreach (var currency in ActiveWarnings)
{
Chat.Print($"{currency.CurrencyInfo().ItemName}", Strings.ChatWarningText);
}
}
else
{
var lockoutRemaining = TimeSpan.FromMinutes(5) - timer.Elapsed;
PluginLog.Debug($"Zone Change Messages Suppressed, '{lockoutRemaining}' Remaining");
}
}
public void Dispose()
{
Service.ClientState.TerritoryChanged -= OnZoneChange;
cancellationTokenSource.Cancel();
cancellationTokenSource.Dispose();
}
}

View File

@ -0,0 +1,48 @@
using CurrencyAlert.DataModels;
using CurrencyAlert.Localization;
using Dalamud.Interface;
using ImGuiNET;
using KamiLib.Drawing;
using KamiLib.Interfaces;
namespace CurrencyAlert.Windows.Components;
public class GeneralSettingsSelectable : ISelectable, IDrawable
{
private static OverlaySettings OverlaySettings => Service.Configuration.OverlaySettings;
private static DisplaySettings DisplaySettings => Service.Configuration.DisplaySettings;
public IDrawable Contents => this;
public string ID => "GeneralSettings";
public void DrawLabel()
{
ImGui.Text(Strings.GeneralSettings);
ImGuiHelpers.ScaledDummy(8.0f);
}
public void Draw()
{
InfoBox.Instance
.AddTitle(Strings.OverlaySettings, out var innerWidth)
.AddConfigCheckbox(Strings.ShowOverlay, OverlaySettings.Show)
.AddConfigCheckbox(Strings.LockOverlay, OverlaySettings.LockPosition)
.AddConfigCheckbox(Strings.MinimalOverlay, OverlaySettings.MinimalDisplay)
.AddConfigCheckbox(Strings.DisplayAscending, OverlaySettings.AscendingDescending)
.AddDragFloat(Strings.Opacity, OverlaySettings.Opacity, 0.00f, 1.0f, innerWidth / 2.0f)
.Draw();
InfoBox.Instance
.AddTitle(Strings.ChatNotifications)
.AddConfigCheckbox(Strings.ChatNotifications, Service.Configuration.ChatNotification)
.Draw();
InfoBox.Instance
.AddTitle(Strings.DisplaySettings)
.AddConfigCheckbox(Strings.ShowCurrencyIcon, DisplaySettings.ShowIcon)
.AddConfigCheckbox(Strings.ShowCurrencyName, DisplaySettings.ShowName)
.AddConfigCheckbox(Strings.ShowWarningText, DisplaySettings.ShowWarningText)
.AddConfigColor(Strings.TextColor, Strings.Default, DisplaySettings.TextColor, Colors.White)
.Draw();
}
}

View File

@ -0,0 +1,46 @@
using System.Numerics;
using CurrencyAlert.DataModels;
using CurrencyAlert.Localization;
using Dalamud.Interface;
using ImGuiNET;
using KamiLib.Drawing;
using KamiLib.Interfaces;
namespace CurrencyAlert.Windows.Components;
public class TrackedCurrencySelectable : ISelectable, IDrawable
{
public IDrawable Contents => this;
public string ID { get; }
private readonly TrackedCurrency currency;
public TrackedCurrencySelectable(TrackedCurrency trackedCurrency)
{
currency = trackedCurrency;
ID = currency.CurrencyInfo().ItemName;
}
public void DrawLabel()
{
currency.DrawIcon();
ImGui.SameLine();
currency.DrawName(Colors.White);
}
public void Draw()
{
InfoBox.Instance
.AddTitle(Strings.CurrentlySelected)
.AddIcon(currency.CurrencyInfo().IconID, ImGuiHelpers.ScaledVector2(40.0f), 1.0f)
.SameLine()
.AddString(currency.CurrencyInfo().ItemName)
.Draw();
InfoBox.Instance
.AddTitle(Strings.CurrencyConfiguration, out var innerWidth)
.AddConfigCheckbox(Strings.Enabled, currency.Enabled)
.AddInputInt(Strings.Threshold, currency.Threshold, 0, 100000, 0, 0, innerWidth / 2.0f)
.Draw();
}
}

View File

@ -0,0 +1,54 @@
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Reflection;
using CurrencyAlert.Windows.Components;
using Dalamud.Interface;
using ImGuiNET;
using KamiLib.Drawing;
using KamiLib.Interfaces;
using KamiLib.Windows;
namespace CurrencyAlert.Windows;
public class ConfigurationWindow : SelectionWindow
{
public ConfigurationWindow() : base("Currency Alert Configuration Window", 0.45f, 20.0f)
{
SizeConstraints = new WindowSizeConstraints
{
MinimumSize = new Vector2(600, 300),
MaximumSize = new Vector2(600,9999)
};
Flags |= ImGuiWindowFlags.NoScrollbar;
Flags |= ImGuiWindowFlags.NoScrollWithMouse;
}
protected override IEnumerable<ISelectable> GetSelectables()
{
return Service.Configuration.TrackedCurrencies
.Select(tracked => new TrackedCurrencySelectable(tracked) as ISelectable)
.Prepend(new GeneralSettingsSelectable());
}
protected override void DrawExtras()
{
DrawVersionNumber();
}
private static void DrawVersionNumber()
{
var assemblyInformation = Assembly.GetExecutingAssembly().FullName!.Split(',');
var versionString = assemblyInformation[1].Replace('=', ' ');
var stringSize = ImGui.CalcTextSize(versionString);
var x = ImGui.GetContentRegionAvail().X / 2 - stringSize.X / 2;
var y = ImGui.GetWindowHeight() - 20 * ImGuiHelpers.GlobalScale;
ImGui.SetCursorPos(new Vector2(x, y));
ImGui.TextColored(Colors.Grey, versionString);
}
}

View File

@ -0,0 +1,162 @@
using System.Linq;
using System.Numerics;
using CurrencyAlert.Commands;
using CurrencyAlert.DataModels;
using CurrencyAlert.Localization;
using Dalamud.Interface.Windowing;
using ImGuiNET;
using KamiLib;
using KamiLib.Configuration;
using KamiLib.GameState;
using KamiLib.Windows;
namespace CurrencyAlert.Windows;
public class OverlaySettings
{
public Setting<bool> LockPosition = new(false);
public Setting<float> Opacity = new(1.0f);
public Setting<bool> MinimalDisplay = new(false);
public Setting<bool> Show = new(true);
public Setting<bool> AscendingDescending = new(false);
}
public class OverlayWindow : Window
{
private static OverlaySettings OverlaySettings => Service.Configuration.OverlaySettings;
private static DisplaySettings DisplaySettings => Service.Configuration.DisplaySettings;
private Vector2 lastWindowSize = Vector2.Zero;
public OverlayWindow() : base("Currency Alert Overlay")
{
KamiCommon.CommandManager.AddCommand(new OverlayCommands());
Flags |= ImGuiWindowFlags.NoDecoration;
Flags |= ImGuiWindowFlags.NoBringToFrontOnFocus;
Flags |= ImGuiWindowFlags.NoFocusOnAppearing;
Flags |= ImGuiWindowFlags.NoNavFocus;
Flags |= ImGuiWindowFlags.AlwaysAutoResize;
}
public override void PreOpenCheck()
{
IsOpen = OverlaySettings.Show;
if (Condition.IsBoundByDuty()) IsOpen = false;
if (Condition.IsInCutsceneOrQuestEvent()) IsOpen = false;
if (!Service.CurrencyTracker.ActiveWarnings.Any()) IsOpen = false;
if (!Service.ClientState.IsLoggedIn) IsOpen = false;
}
public override void PreDraw()
{
var bgColor = ImGui.GetStyle().Colors[(int)ImGuiCol.WindowBg];
ImGui.PushStyleColor(ImGuiCol.WindowBg, bgColor with {W = OverlaySettings.Opacity.Value});
var borderColor = ImGui.GetStyle().Colors[(int)ImGuiCol.Border];
ImGui.PushStyleColor(ImGuiCol.Border, borderColor with {W = OverlaySettings.Opacity.Value});
if (OverlaySettings.LockPosition)
{
Flags |= DrawFlags.LockPosition;
}
else
{
Flags &= ~DrawFlags.LockPosition;
}
}
public override void Draw()
{
ResizeWindow();
if (OverlaySettings.MinimalDisplay)
{
DrawMinimalDisplay();
}
else
{
DrawNormalDisplay();
}
}
public override void PostDraw()
{
ImGui.PopStyleColor();
ImGui.PopStyleColor();
}
private void ResizeWindow()
{
if(OverlaySettings.AscendingDescending)
{
var size = ImGui.GetWindowSize();
if(lastWindowSize != Vector2.Zero)
{
var offset = lastWindowSize - size;
offset.X = 0;
if (offset != Vector2.Zero)
{
ImGui.SetWindowPos(ImGui.GetWindowPos() + offset);
}
}
lastWindowSize = size;
}
}
private static void DrawMinimalDisplay()
{
if (DisplaySettings.ShowWarningText)
{
ImGui.TextColored(DisplaySettings.TextColor.Value, Strings.OverlayWarningText);
ImGui.SameLine();
}
foreach (var currency in Service.CurrencyTracker.ActiveWarnings)
{
if (DisplaySettings.ShowIcon)
{
currency.DrawIcon();
if (DisplaySettings.ShowName)
{
ImGui.SameLine();
currency.DrawName(DisplaySettings.TextColor.Value);
ImGui.SameLine();
}
}
else if (DisplaySettings.ShowName)
{
currency.DrawName(DisplaySettings.TextColor.Value);
ImGui.SameLine();
}
}
}
private static void DrawNormalDisplay()
{
foreach (var currency in Service.CurrencyTracker.ActiveWarnings)
{
if (DisplaySettings.ShowWarningText)
{
ImGui.TextColored(DisplaySettings.TextColor.Value, Strings.OverlayWarningText);
ImGui.SameLine();
}
if (DisplaySettings.ShowIcon)
{
currency.DrawIcon();
ImGui.SameLine();
}
if (DisplaySettings.ShowName)
{
currency.DrawName(DisplaySettings.TextColor.Value);
}
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

View File

@ -1,12 +1,15 @@
{ {
"version": 1, "version": 1,
"dependencies": { "dependencies": {
"net6.0-windows7.0": { "net7.0-windows7.0": {
"DalamudPackager": { "DalamudPackager": {
"type": "Direct", "type": "Direct",
"requested": "[2.1.8, )", "requested": "[2.1.10, )",
"resolved": "2.1.8", "resolved": "2.1.10",
"contentHash": "YqagNXs9InxmqkXzq7kLveImxnodkBEicAhydMXVp7dFjC7xb76U6zGgAax4/BWIWfZeWzr5DJyQSev31kj81A==" "contentHash": "S6NrvvOnLgT4GDdgwuKVJjbFo+8ZEj+JsEYk9ojjOR/MMfv1dIFpT8aRJQfI24rtDcw1uF+GnSSMN4WW1yt7fw=="
},
"kamilib": {
"type": "Project"
} }
} }
} }

1
KamiLib Submodule

@ -0,0 +1 @@
Subproject commit f50ff8903e0adeb2dfe1d64103f54da13e055f89