aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Malmstone/Addons/PvPMatchAddon.cs65
-rw-r--r--Malmstone/Configuration.cs4
-rw-r--r--Malmstone/Plugin.cs10
-rw-r--r--Malmstone/Services/PVPService.cs131
-rw-r--r--Malmstone/Windows/ConfigWindow.cs30
-rw-r--r--Malmstone/Windows/MainWindow.cs74
6 files changed, 306 insertions, 8 deletions
diff --git a/Malmstone/Addons/PvPMatchAddon.cs b/Malmstone/Addons/PvPMatchAddon.cs
index 78e0e38..896001a 100644
--- a/Malmstone/Addons/PvPMatchAddon.cs
+++ b/Malmstone/Addons/PvPMatchAddon.cs
@@ -5,12 +5,16 @@ using Malmstone.Utils;
using Dalamud.Game.Text.SeStringHandling;
using System.Collections.Generic;
using Dalamud.Game.Text.SeStringHandling.Payloads;
+using FFXIVClientStructs.FFXIV.Component.GUI;
+using Dalamud.Memory;
+using static Malmstone.Services.PvPService;
namespace Malmstone.Addons
{
internal class PvPMatchAddon
{
private Plugin Plugin;
+ public bool FrontlineRecordPostSetupEnabled = false;
private enum PvPContentType
{
CrystallineConflict = 1,
@@ -49,11 +53,15 @@ namespace Malmstone.Addons
public void EnableFrontlinePostMatch()
{
Plugin.AddonLifeCycle.RegisterListener(AddonEvent.PostSetup, "FrontlineRecord", OnFrontlineRecordTrigger);
+ Plugin.PvPService.CurrentFrontlineLosingBonus = Plugin.Configuration.SavedFrontlineRewardBonus;
+ Plugin.Configuration.OutdatedFrontlineRewardBonus = true;
+ FrontlineRecordPostSetupEnabled = true;
}
public void DisableFrontlinePostMatch()
{
Plugin.AddonLifeCycle.UnregisterListener(AddonEvent.PostSetup, "FrontlineRecord", OnFrontlineRecordTrigger);
+ FrontlineRecordPostSetupEnabled = false;
}
public void EnableRivalWingsPostMatch()
@@ -64,12 +72,13 @@ namespace Malmstone.Addons
{
Plugin.AddonLifeCycle.UnregisterListener(AddonEvent.PostSetup, "ManeuversRecord", OnRivalWingsRecordTrigger);
}
-
+
// Runs on the result screen of the respective game mode
private void OnCrystallineConflictRecordTrigger(AddonEvent eventType, AddonArgs addonInfo)
{
PvPSeriesInfo? seriesInfo = Plugin.PvPService.GetPvPSeriesInfo();
+ CheckFrontlineBonus(eventType, addonInfo);
if (seriesInfo == null) return;
if (Plugin.Configuration.ShowProgressionChatPostCC)
ShowSeriesProgressionMessage(seriesInfo, PvPContentType.CrystallineConflict);
@@ -77,6 +86,8 @@ namespace Malmstone.Addons
private void OnFrontlineRecordTrigger(AddonEvent eventType, AddonArgs addonInfo)
{
+ if (Plugin.Configuration.TrackFrontlineBonus)
+ CheckFrontlineBonus(eventType, addonInfo);
PvPSeriesInfo? seriesInfo = Plugin.PvPService.GetPvPSeriesInfo();
if (seriesInfo == null) return;
if (Plugin.Configuration.ShowProgressionChatPostFL)
@@ -91,6 +102,58 @@ namespace Malmstone.Addons
ShowSeriesProgressionMessage(seriesInfo, PvPContentType.RivalWings);
}
+ private void CheckFrontlineBonus(AddonEvent eventType, AddonArgs addonInfo)
+ {
+ PVPProfileFrontlineResults CurrentFrontlineResults = Plugin.PvPService.GetPVPProfileFrontlineResults();
+ if (CurrentFrontlineResults.FirstPlace == 0 &&
+ CurrentFrontlineResults.SecondPlace == 0 &&
+ CurrentFrontlineResults.ThirdPlace == 0) return;
+ // Check placement of current Frontline match
+ FrontlinePlacement FrontlineMatchResult = FrontlinePlacement.Unknown;
+ if (CurrentFrontlineResults.FirstPlace > Plugin.PvPService.CachedFrontlineResults.FirstPlace)
+ {
+ FrontlineMatchResult = FrontlinePlacement.FirstPlace;
+ }
+ else if (CurrentFrontlineResults.SecondPlace > Plugin.PvPService.CachedFrontlineResults.SecondPlace)
+ {
+ FrontlineMatchResult = FrontlinePlacement.SecondPlace;
+ }
+ else if (CurrentFrontlineResults.ThirdPlace > Plugin.PvPService.CachedFrontlineResults.ThirdPlace)
+ {
+ FrontlineMatchResult = FrontlinePlacement.ThirdPlace;
+ }
+ Plugin.Logger.Debug("Frontline Match Result: " + FrontlineMatchResult.ToString());
+ if (FrontlineMatchResult != FrontlinePlacement.Unknown)
+ {
+ unsafe
+ {
+ var FrontlineResultUnit = (AtkUnitBase*)addonInfo.Addon;
+ if (FrontlineResultUnit == null) return;
+ var SeriesExpComponent = FrontlineResultUnit->GetComponentByNodeId(35);
+ var SeriesExpTextNode = (AtkTextNode*)SeriesExpComponent->GetTextNodeById(2);
+ byte* SeriesExpTextBytePointer = SeriesExpTextNode->GetText();
+ nint SeriesExpTextAddr = (nint)SeriesExpTextBytePointer;
+ string SeriesExpText = MemoryHelper.ReadStringNullTerminated(SeriesExpTextAddr);
+ if (int.TryParse(SeriesExpText, out int SeriesExpEarned))
+ {
+ int CurrentLossBonus = Plugin.PvPService.GenerateFrontlineBonus(FrontlineMatchResult, SeriesExpEarned);
+ Plugin.Logger.Debug("Series EXP Earned: " + SeriesExpEarned.ToString());
+ Plugin.Configuration.SavedFrontlineRewardBonus = CurrentLossBonus;
+ Plugin.Configuration.OutdatedFrontlineRewardBonus = false;
+ }
+ else
+ {
+ Plugin.Chat.PrintError("[Malmstone Calculator] Unable to get earned Series EXP: " + SeriesExpText);
+ }
+ }
+ }
+ else
+ {
+ Plugin.Chat.PrintError("[Malmstone Calculator] Unable to get current Frontline match results");
+ }
+ Plugin.PvPService.UpdateFrontlineResultCache();
+ }
+
private void ShowSeriesProgressionToast(AddonEvent eventType, AddonArgs addonInfo)
{
PvPSeriesInfo? seriesInfo = Plugin.PvPService.GetPvPSeriesInfo();
diff --git a/Malmstone/Configuration.cs b/Malmstone/Configuration.cs
index 1d0ed84..4f62a96 100644
--- a/Malmstone/Configuration.cs
+++ b/Malmstone/Configuration.cs
@@ -1,5 +1,4 @@
using Dalamud.Configuration;
-using Dalamud.Plugin;
using System;
namespace Malmstone;
@@ -18,6 +17,9 @@ public class Configuration : IPluginConfiguration
public bool ShowMainWindowOnPVPReward { get; set; } = true;
public bool SkipProgressionToastAfterGoal { get; set; } = false;
public bool SkipProgressionChatAfterGoal { get; set; } = false;
+ public bool TrackFrontlineBonus { get; set; } = true;
+ public int SavedFrontlineRewardBonus { get; set; } = -1;
+ public bool OutdatedFrontlineRewardBonus { get; set; } = false;
// the below exist just to make saving less cumbersome
public void Save()
diff --git a/Malmstone/Plugin.cs b/Malmstone/Plugin.cs
index 5ed6a65..ada8202 100644
--- a/Malmstone/Plugin.cs
+++ b/Malmstone/Plugin.cs
@@ -24,6 +24,7 @@ public sealed class Plugin : IDalamudPlugin
[PluginService] internal static IChatGui Chat { get; private set; } = null!;
[PluginService] internal static IAddonLifecycle AddonLifeCycle { get; private set; } = null!;
[PluginService] internal static IToastGui ToastGui { get; private set; } = null!;
+ [PluginService] internal static IPluginLog Logger { get; set; } = default!;
private const string CommandName = "/pmalm";
@@ -48,12 +49,14 @@ public sealed class Plugin : IDalamudPlugin
PvPAddon.EnableCrystallineConflictPostMatch();
if (Configuration.ShowProgressionChatPostRW)
PvPAddon.EnableRivalWingsPostMatch();
- if (Configuration.ShowProgressionChatPostFL)
+ if (Configuration.ShowProgressionChatPostFL || Configuration.TrackFrontlineBonus)
PvPAddon.EnableFrontlinePostMatch();
if (Configuration.ShowProgressionToastPostMatch)
PvPAddon.EnablePostMatchProgressionToast();
if (Configuration.ShowMainWindowOnPVPReward)
EnablePVPRewardWindowAddon();
+
+ PvPService.UpdateFrontlineResultCache();
if (Configuration.PostmatchProgressionToastType < 0 || Configuration.PostmatchProgressionToastType > 2)
{
@@ -84,13 +87,13 @@ public sealed class Plugin : IDalamudPlugin
PvPAddon.DisableCrystallineConflictPostMatch();
if (Configuration.ShowProgressionChatPostRW)
PvPAddon.DisableRivalWingsPostMatch();
- if (Configuration.ShowProgressionChatPostFL)
+ if (Configuration.ShowProgressionChatPostFL || Configuration.TrackFrontlineBonus)
PvPAddon.DisableFrontlinePostMatch();
if (Configuration.ShowProgressionToastPostMatch)
PvPAddon.DisablePostMatchProgressionToast();
if(Configuration.ShowMainWindowOnPVPReward)
DisablePVPRewardWindowAddon();
-
+
CommandManager.RemoveHandler(CommandName);
}
@@ -254,5 +257,6 @@ private void OnCommand(string command, string args)
AddonLifeCycle.UnregisterListener(AddonEvent.PostSetup, "PvpReward", MainWindow.OnOpenPVPRewardWindow);
AddonLifeCycle.UnregisterListener(AddonEvent.PreFinalize, "PvpReward", MainWindow.OnClosePVPRewardWindow);
}
+
}
diff --git a/Malmstone/Services/PVPService.cs b/Malmstone/Services/PVPService.cs
index cf08fea..12b4c2a 100644
--- a/Malmstone/Services/PVPService.cs
+++ b/Malmstone/Services/PVPService.cs
@@ -4,6 +4,23 @@ namespace Malmstone.Services
{
public class PvPService
{
+ public int CurrentFrontlineLosingBonus = -1;
+ public int ConsecutiveThirdPlaceFrontline = 0;
+
+ public enum FrontlinePlacement
+ {
+ FirstPlace = 1, SecondPlace = 2, ThirdPlace = 3, Unknown=4
+ }
+
+ public struct PVPProfileFrontlineResults
+ {
+ public uint FirstPlace;
+ public uint SecondPlace;
+ public uint ThirdPlace;
+ }
+
+ public PVPProfileFrontlineResults CachedFrontlineResults;
+
public PvPSeriesInfo? GetPvPSeriesInfo()
{
unsafe
@@ -21,6 +38,120 @@ namespace Malmstone.Services
return null;
}
}
+
+ public bool UpdateFrontlineResultCache()
+ {
+ unsafe
+ {
+ var pvpProfile = PvPProfile.Instance();
+ if (pvpProfile != null && pvpProfile->IsLoaded != 0)
+ {
+ CachedFrontlineResults = new PVPProfileFrontlineResults
+ {
+ FirstPlace = pvpProfile->FrontlineTotalFirstPlace,
+ SecondPlace = pvpProfile->FrontlineTotalSecondPlace,
+ ThirdPlace = pvpProfile->FrontlineTotalThirdPlace
+ };
+ return true;
+ }
+ return false;
+ }
+ }
+
+ public int GenerateFrontlineBonus(FrontlinePlacement FrontlineResult, int EarnedSeriesEXP)
+ {
+ // Calculates the current Frontline Bonus
+ // 1000 (no bonus), 1100, 1200, 1300, 1400, 1500 3rd
+ // 1250 (no bonus), 1375, 1500, 1625, 1750, 1875 2nd
+ // 1500 (no bonus), 1650, 1800, 1950, 2100, 2250 1st
+ if (FrontlineResult == FrontlinePlacement.ThirdPlace)
+ {
+ ConsecutiveThirdPlaceFrontline++;
+ switch (EarnedSeriesEXP)
+ { // Next 3rd place will get +10% value
+ case 1000:
+ CurrentFrontlineLosingBonus = 0; // Primed for buff
+ return 0;
+ case 1100:
+ CurrentFrontlineLosingBonus = 10;
+ return 10;
+ case 1200:
+ CurrentFrontlineLosingBonus = 20;
+ return 20;
+ case 1300:
+ CurrentFrontlineLosingBonus = 30;
+ return 30;
+ case 1400:
+ CurrentFrontlineLosingBonus = 40;
+ return 40;
+ case 1500:
+ CurrentFrontlineLosingBonus = 50;
+ return 50;
+ default:
+ return -1;
+ }
+ }
+ else if (FrontlineResult == FrontlinePlacement.SecondPlace)
+ {
+ switch (EarnedSeriesEXP)
+ {
+ case 1250:
+ CurrentFrontlineLosingBonus = 0;
+ return 0;
+ case 1375:
+ CurrentFrontlineLosingBonus = 10;
+ return 10;
+ case 1500:
+ CurrentFrontlineLosingBonus = 20;
+ return 20;
+ case 1625:
+ CurrentFrontlineLosingBonus = 30;
+ return 30;
+ case 2100:
+ CurrentFrontlineLosingBonus = 40;
+ return 40;
+ case 2250:
+ CurrentFrontlineLosingBonus = 50;
+ return 50;
+ default:
+ return -1;
+ }
+ }
+ else if (FrontlineResult == FrontlinePlacement.FirstPlace)
+ {
+ // Buff is reset regardless
+ ConsecutiveThirdPlaceFrontline = 0;
+ CurrentFrontlineLosingBonus = 0;
+ return 0;
+ }
+ return -1;
+ }
+
+ public PVPProfileFrontlineResults GetPVPProfileFrontlineResults()
+ {
+ unsafe
+ {
+ var pvpProfile = PvPProfile.Instance();
+ if (pvpProfile != null && pvpProfile->IsLoaded != 0)
+ {
+ return new PVPProfileFrontlineResults
+ {
+ FirstPlace = pvpProfile->FrontlineTotalFirstPlace,
+ SecondPlace = pvpProfile->FrontlineTotalSecondPlace,
+ ThirdPlace = pvpProfile->FrontlineTotalThirdPlace,
+
+ };
+ }
+ }
+ return new PVPProfileFrontlineResults
+ {
+ FirstPlace = 0,
+ SecondPlace = 0,
+ ThirdPlace = 0,
+
+ };
+ }
+
}
public class PvPSeriesInfo
diff --git a/Malmstone/Windows/ConfigWindow.cs b/Malmstone/Windows/ConfigWindow.cs
index 93af7b5..0dc4e11 100644
--- a/Malmstone/Windows/ConfigWindow.cs
+++ b/Malmstone/Windows/ConfigWindow.cs
@@ -151,9 +151,9 @@ public class ConfigWindow : Window, IDisposable
if (ImGui.Checkbox("##ShowFLMatchesRemainingPostGame", ref showFLMatchesRemainingPostGame))
{
Configuration.ShowProgressionChatPostFL = showFLMatchesRemainingPostGame;
- if (showFLMatchesRemainingPostGame)
+ if (showFLMatchesRemainingPostGame && !Plugin.PvPAddon.FrontlineRecordPostSetupEnabled)
Plugin.PvPAddon.EnableFrontlinePostMatch();
- else
+ else if (!showFLMatchesRemainingPostGame && !Configuration.TrackFrontlineBonus)
Plugin.PvPAddon.DisableFrontlinePostMatch();
Configuration.Save();
}
@@ -166,6 +166,32 @@ public class ConfigWindow : Window, IDisposable
ImGui.SameLine();
ImGui.Text("Frontlines");
+ ImGui.SameLine();
+ ImGui.Spacing();
+ ImGui.SameLine();
+
+ var trackFrontlineBonus = Configuration.TrackFrontlineBonus;
+ if (ImGui.Checkbox("##TrackFrontlineBonus", ref trackFrontlineBonus))
+ {
+ Configuration.TrackFrontlineBonus = trackFrontlineBonus;
+ if (trackFrontlineBonus && !Plugin.PvPAddon.FrontlineRecordPostSetupEnabled)
+ Plugin.PvPAddon.EnableFrontlinePostMatch();
+ else if(!trackFrontlineBonus && !Configuration.ShowProgressionChatPostFL)
+ Plugin.PvPAddon.DisableFrontlinePostMatch();
+ Configuration.Save();
+ }
+ if (ImGui.IsItemHovered())
+ {
+ ImGui.BeginTooltip();
+ ImGui.Text("(EXPERIMENTAL) Track the reward bonus you get for consecutive losses in Frontline" +
+ "\n3rd place = +10 percent bonus (max 50 percent)" +
+ "\n2nd place = Current bonus is kept" +
+ "\n1st Place = Bonus reset to 0\n");
+ ImGui.EndTooltip();
+ }
+ ImGui.SameLine();
+ ImGui.Text("Track Frontline Reward Bonus");
+
var showRWMatchesRemainingPostGame = Configuration.ShowProgressionChatPostRW;
if (ImGui.Checkbox("##ShowRWMatchesRemainingPostGame", ref showRWMatchesRemainingPostGame))
diff --git a/Malmstone/Windows/MainWindow.cs b/Malmstone/Windows/MainWindow.cs
index 0e91c4d..1617a00 100644
--- a/Malmstone/Windows/MainWindow.cs
+++ b/Malmstone/Windows/MainWindow.cs
@@ -26,7 +26,7 @@ namespace Malmstone.Windows
{
SizeConstraints = new WindowSizeConstraints
{
- MinimumSize = new Vector2(460, 510),
+ MinimumSize = new Vector2(460, 545),
MaximumSize = new Vector2(float.MaxValue, float.MaxValue)
};
@@ -101,6 +101,78 @@ namespace Malmstone.Windows
ImGui.BulletText($"Take 2nd Place: {xpResult.FrontlineDailyLose2nd} " + (xpResult.FrontlineDailyLose2nd == 1 ? "time" : "times"));
ImGui.BulletText($"Take 3rd Place: {xpResult.FrontlineDailyLose3rd} " + (xpResult.FrontlineDailyLose3rd == 1 ? "time" : "times"));
+
+ if (Plugin.Configuration.TrackFrontlineBonus)
+ {
+ if (Plugin.PvPService.CurrentFrontlineLosingBonus == -1)
+ {
+ ImGui.TextColored(new Vector4(0.0f, 1.0f, 0.0f, 1.0f), "Complete a Frontline match to view current reward bonus");
+ if (ImGui.IsItemHovered())
+ {
+ ImGui.BeginTooltip();
+ ImGui.Text("This calculates the losing streak bonus you receive after consecutive losses in Frontlines" +
+ "\nPlay a match of Frontline to confirm your existing losing bonus" +
+ "\nYou can turn off tracking entirely in the settings");
+ ImGui.EndTooltip();
+ }
+ }
+ else
+ {
+ if(Plugin.PvPService.CurrentFrontlineLosingBonus == 0)
+ {
+ if(Plugin.PvPService.ConsecutiveThirdPlaceFrontline == 1)
+ {
+ ImGui.TextColored(new Vector4(0.0f, 1.0f, 0.0f, 1.0f), "You'll receive 10%% reward bonus if you place 3rd");
+ }
+ if (ImGui.IsItemHovered())
+ {
+ ImGui.BeginTooltip();
+ ImGui.Text("You're primed for a reward bonus! You will get a 10% reward bonus if you place 3rd again" +
+ "\nCounter resets if you rank 1st");
+ ImGui.EndTooltip();
+ }
+ ImGui.Text("No Frontline Reward Bonus Currently Active");
+ }
+ else
+ {
+ if (Plugin.PvPService.CurrentFrontlineLosingBonus != 50)
+ ImGui.TextColored(new Vector4(0.0f, 1.0f, 0.0f, 1.0f), "You'll receive a " + Plugin.PvPService.CurrentFrontlineLosingBonus + "%% reward bonus placing 1st or 2nd");
+ else
+ ImGui.TextColored(new Vector4(0.0f, 1.0f, 0.0f, 1.0f), "You'll receive a " + Plugin.PvPService.CurrentFrontlineLosingBonus + "%% reward bonus placing 1st, 2nd, or 3rd");
+ if (ImGui.IsItemHovered())
+ {
+ ImGui.BeginTooltip();
+ ImGui.Text("You'll earn a percentage bonus on PvP EXP, Series EXP, and Wolf Marks " +
+ "until attaining First Place" );
+ ImGui.EndTooltip();
+ }
+ if (Plugin.PvPService.CurrentFrontlineLosingBonus != 50)
+ {
+ ImGui.TextColored(new Vector4(0.0f, 1.0f, 0.0f, 1.0f), "Your reward bonus will increase to " + (Plugin.PvPService.CurrentFrontlineLosingBonus + 10) + "%% if place 3rd");
+ if (ImGui.IsItemHovered())
+ {
+ ImGui.BeginTooltip();
+ ImGui.Text($"Finishing 3rd again will increase your bonus to {Plugin.PvPService.CurrentFrontlineLosingBonus + 10}%." +
+ "\nThis increased bonus will also apply to the match where this happens.");
+ ImGui.EndTooltip();
+ }
+ }
+ }
+ if (Plugin.Configuration.OutdatedFrontlineRewardBonus)
+ {
+ ImGui.SameLine();
+ ImGui.TextColored(new Vector4(1.0f, 0.0f, 0.0f, 1.0f),"(Outdated)");
+ if (ImGui.IsItemHovered())
+ {
+ ImGui.BeginTooltip();
+ ImGui.Text("This information may be outdated due to Frontline tracking loading and unloading!" +
+ "\nCalculations will refresh after your next match of Frontlines");
+ ImGui.EndTooltip();
+ }
+ }
+ }
+ }
+
ImGui.Spacing();
ImGui.Separator();
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage