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
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
[submodule "KamiLib"]
|
||||
path = KamiLib
|
||||
url = https://github.com/MidoriKami/KamiLib
|
@ -5,6 +5,8 @@ VisualStudioVersion = 17.0.31919.166
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CurrencyAlert", "CurrencyAlert\CurrencyAlert.csproj", "{13C812E9-0D42-4B95-8646-40EEBF30636F}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KamiLib", "KamiLib\KamiLib.csproj", "{6EAC83CF-FCF8-42F0-B923-13658DD93725}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
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}.Release|x64.ActiveCfg = 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
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
45
CurrencyAlert/Commands/OverlayCommands.cs
Normal 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,
|
||||
},
|
||||
};
|
||||
}
|
@ -1,38 +1,57 @@
|
||||
using CurrencyAlert.Helper;
|
||||
using CurrencyAlert.Provider;
|
||||
using Dalamud.Configuration;
|
||||
using Dalamud.Configuration;
|
||||
using Dalamud.Plugin;
|
||||
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 class Configuration : IPluginConfiguration
|
||||
{
|
||||
public int Version { get; set; } = 5;
|
||||
public int Version { get; set; } = 6;
|
||||
|
||||
public bool UiLocked { get; set; } = false;
|
||||
public Dictionary<int, bool> AlertEnabled { get; } = new Dictionary<int, bool>();
|
||||
public Dictionary<int, int> Threshold { get; } = new Dictionary<int, int>();
|
||||
public OverlaySettings OverlaySettings = new();
|
||||
public DisplaySettings DisplaySettings = new();
|
||||
public Setting<bool> ChatNotification = new(false);
|
||||
|
||||
public Configuration()
|
||||
{
|
||||
foreach (var currency in CurrencyProvider.Instance.GetAll())
|
||||
{
|
||||
this.AlertEnabled[currency.Id] = true;
|
||||
this.Threshold[currency.Id] = currency.DefaultThreshold;
|
||||
}
|
||||
}
|
||||
public TrackedCurrency[] TrackedCurrencies = {
|
||||
// Grand Company Seals
|
||||
new(CurrencyName.StormSeal, new Setting<int>(75_000), new Setting<bool>(true)),
|
||||
new(CurrencyName.SerpentSeals, new Setting<int>(75_000), new Setting<bool>(true)),
|
||||
new(CurrencyName.FlameSeals, new Setting<int>(75_000), new Setting<bool>(true)),
|
||||
|
||||
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()
|
||||
{
|
||||
PluginHelper.PluginInterface.SavePluginConfig(this);
|
||||
}
|
||||
}
|
||||
// FATEs
|
||||
new(CurrencyName.BicolorGemstones, new Setting<int>(800), new Setting<bool>(true)),
|
||||
|
||||
// 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);
|
||||
}
|
@ -1,34 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<Authors></Authors>
|
||||
<Company></Company>
|
||||
<Version>0.4.0.0</Version>
|
||||
<Version>0.5.0.0</Version>
|
||||
<Description>Currency Alert</Description>
|
||||
<Copyright></Copyright>
|
||||
<PackageProjectUrl>https://github.com/Lharz/xiv-currency-alert</PackageProjectUrl>
|
||||
</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>
|
||||
<TargetFramework>net6.0-windows</TargetFramework>
|
||||
<TargetFramework>net7.0-windows</TargetFramework>
|
||||
<Platforms>x64</Platforms>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>latest</LangVersion>
|
||||
@ -47,7 +26,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="DalamudPackager" Version="2.1.8" />
|
||||
<PackageReference Include="DalamudPackager" Version="2.1.10" />
|
||||
<Reference Include="FFXIVClientStructs">
|
||||
<HintPath>$(DalamudLibPath)FFXIVClientStructs.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
@ -82,4 +61,23 @@
|
||||
<Content Include="images\**" Link="images\%(RecursiveDir)\%(Filename)%(Extension)" CopyToOutputDirectory="Always" />
|
||||
</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>
|
||||
|
@ -2,15 +2,17 @@
|
||||
"Author": "Lharz",
|
||||
"Name": "CurrencyAlert",
|
||||
"Punchline": "Display alerts upon reaching configurable currencies thresholds (such as Poetics or PVP marks).",
|
||||
"Description": "/currencyalert: shows the configuration panel.",
|
||||
"Changelog": null,
|
||||
"Description": "This plugin lets you easily manage your various currencies to prevent from wasting precious resources.",
|
||||
"Tags": [
|
||||
"plugin",
|
||||
"currency",
|
||||
"tomestones",
|
||||
"utility",
|
||||
"other"
|
||||
"Currency",
|
||||
"Tomestones",
|
||||
"Utility",
|
||||
"Other"
|
||||
],
|
||||
"CategoryTags": null,
|
||||
"RepoUrl": "https://github.com/Lharz/xiv-currency-alert",
|
||||
"CategoryTags": [
|
||||
"Utility",
|
||||
"Other",
|
||||
"UI"
|
||||
],
|
||||
"RepoUrl": "https://github.com/Lharz/xiv-currency-alert"
|
||||
}
|
||||
|
84
CurrencyAlert/DataModels/CurrencyInfo.cs
Normal 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;
|
||||
}
|
||||
}
|
27
CurrencyAlert/DataModels/CurrencyName.cs
Normal 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,
|
||||
}
|
13
CurrencyAlert/DataModels/DisplaySettings.cs
Normal 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);
|
||||
}
|
30
CurrencyAlert/DataModels/TrackedCurrency.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
namespace CurrencyAlert.Enum
|
||||
{
|
||||
public enum Category
|
||||
{
|
||||
Common,
|
||||
Battle,
|
||||
Other
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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!;
|
||||
}
|
||||
}
|
41
CurrencyAlert/Localization/LocalizationManager.cs
Normal 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");
|
||||
}
|
||||
}
|
||||
}
|
269
CurrencyAlert/Localization/Strings.Designer.cs
generated
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
90
CurrencyAlert/Localization/Strings.resx
Normal 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>
|
@ -1,108 +1,36 @@
|
||||
using CurrencyAlert.Helper;
|
||||
using CurrencyAlert.Provider;
|
||||
using Dalamud.Game.Command;
|
||||
using Dalamud.Game.Gui;
|
||||
using Dalamud.IoC;
|
||||
using CurrencyAlert.Localization;
|
||||
using CurrencyAlert.System.cs;
|
||||
using CurrencyAlert.Windows;
|
||||
using Dalamud.Plugin;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game;
|
||||
using ImGuiNET;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using KamiLib;
|
||||
|
||||
namespace CurrencyAlert
|
||||
namespace CurrencyAlert;
|
||||
|
||||
public sealed class Plugin : IDalamudPlugin
|
||||
{
|
||||
public sealed class Plugin : IDalamudPlugin
|
||||
{
|
||||
public string Name => "Currency Alert";
|
||||
|
||||
private const string commandName = "/currencyalert";
|
||||
|
||||
private Configuration Configuration { get; init; }
|
||||
private PluginUI PluginUI { get; init; }
|
||||
|
||||
[PluginService] public static ChatGui Chat { get; private set; } = null!;
|
||||
|
||||
private bool LoggedIn => PluginHelper.ClientState.LocalPlayer != null && PluginHelper.ClientState.LocalContentId != 0;
|
||||
public string Name => "CurrencyAlert";
|
||||
|
||||
public Plugin(DalamudPluginInterface pluginInterface)
|
||||
{
|
||||
pluginInterface.Create<PluginHelper>();
|
||||
pluginInterface.Create<Service>();
|
||||
|
||||
try
|
||||
{
|
||||
this.Configuration = PluginHelper.PluginInterface.GetPluginConfig() as Configuration ?? new Configuration();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.Configuration = new Configuration();
|
||||
this.Configuration.Save();
|
||||
KamiCommon.Initialize(pluginInterface, Name, () => Service.Configuration.Save());
|
||||
LocalizationManager.Instance.Initialize();
|
||||
|
||||
PluginHelper.Chat.Print("Your CurrencyAlert configuration has been reset because of compatibility issues. Please check the plugin configuration window.");
|
||||
}
|
||||
Service.Configuration = Service.PluginInterface.GetPluginConfig() as Configuration ?? new Configuration();
|
||||
Service.Configuration.Initialize(Service.PluginInterface);
|
||||
|
||||
this.Configuration.Initialize();
|
||||
KamiCommon.WindowManager.AddConfigurationWindow(new ConfigurationWindow());
|
||||
KamiCommon.WindowManager.AddWindow(new OverlayWindow());
|
||||
|
||||
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;
|
||||
Service.CurrencyTracker = new CurrencyTracker();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
this.PluginUI.Dispose();
|
||||
PluginHelper.CommandManager.RemoveHandler(commandName);
|
||||
}
|
||||
KamiCommon.Dispose();
|
||||
|
||||
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;
|
||||
}
|
||||
Service.CurrencyTracker.Dispose();
|
||||
LocalizationManager.Cleanup();
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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
@ -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!;
|
||||
}
|
71
CurrencyAlert/System.cs/CurrencyTracker.cs
Normal 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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
54
CurrencyAlert/Windows/ConfigurationWindow.cs
Normal 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);
|
||||
}
|
||||
}
|
162
CurrencyAlert/Windows/OverlayWindow.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 8.5 KiB |
Before Width: | Height: | Size: 8.6 KiB |
Before Width: | Height: | Size: 8.6 KiB |
Before Width: | Height: | Size: 8.5 KiB |
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 9.7 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 8.5 KiB |
Before Width: | Height: | Size: 8.7 KiB |
Before Width: | Height: | Size: 7.7 KiB |
Before Width: | Height: | Size: 8.8 KiB |
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 12 KiB |
@ -1,12 +1,15 @@
|
||||
{
|
||||
"version": 1,
|
||||
"dependencies": {
|
||||
"net6.0-windows7.0": {
|
||||
"net7.0-windows7.0": {
|
||||
"DalamudPackager": {
|
||||
"type": "Direct",
|
||||
"requested": "[2.1.8, )",
|
||||
"resolved": "2.1.8",
|
||||
"contentHash": "YqagNXs9InxmqkXzq7kLveImxnodkBEicAhydMXVp7dFjC7xb76U6zGgAax4/BWIWfZeWzr5DJyQSev31kj81A=="
|
||||
"requested": "[2.1.10, )",
|
||||
"resolved": "2.1.10",
|
||||
"contentHash": "S6NrvvOnLgT4GDdgwuKVJjbFo+8ZEj+JsEYk9ojjOR/MMfv1dIFpT8aRJQfI24rtDcw1uF+GnSSMN4WW1yt7fw=="
|
||||
},
|
||||
"kamilib": {
|
||||
"type": "Project"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
1
KamiLib
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit f50ff8903e0adeb2dfe1d64103f54da13e055f89
|