Reset cached mission attributes when changing characters; improve detection of who is part of the mission
This commit is contained in:
parent
821311e4cc
commit
75084ef5eb
@ -1,8 +1,40 @@
|
||||
using System;
|
||||
|
||||
namespace Squadronista.Solver;
|
||||
|
||||
internal class Attributes
|
||||
internal class Attributes : IEquatable<Attributes>
|
||||
{
|
||||
public required int PhysicalAbility { get; init; }
|
||||
public required int MentalAbility { get; init; }
|
||||
public required int TacticalAbility { get; init; }
|
||||
|
||||
public bool Equals(Attributes? other)
|
||||
{
|
||||
if (ReferenceEquals(null, other)) return false;
|
||||
if (ReferenceEquals(this, other)) return true;
|
||||
return PhysicalAbility == other.PhysicalAbility && MentalAbility == other.MentalAbility && TacticalAbility == other.TacticalAbility;
|
||||
}
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj)) return false;
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
if (obj.GetType() != this.GetType()) return false;
|
||||
return Equals((Attributes)obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(PhysicalAbility, MentalAbility, TacticalAbility);
|
||||
}
|
||||
|
||||
public static bool operator ==(Attributes? left, Attributes? right)
|
||||
{
|
||||
return Equals(left, right);
|
||||
}
|
||||
|
||||
public static bool operator !=(Attributes? left, Attributes? right)
|
||||
{
|
||||
return !Equals(left, right);
|
||||
}
|
||||
}
|
||||
|
11
Squadronista/Solver/SquadronMemberUiFlags.cs
Normal file
11
Squadronista/Solver/SquadronMemberUiFlags.cs
Normal file
@ -0,0 +1,11 @@
|
||||
using System;
|
||||
|
||||
namespace Squadronista.Solver;
|
||||
|
||||
[Flags]
|
||||
public enum SquadronMemberUiFlags : int
|
||||
{
|
||||
Unknown1 = 1,
|
||||
IsPartOfMission = 2,
|
||||
NewChemistryAvailable = 8192,
|
||||
}
|
@ -40,9 +40,9 @@ internal sealed class SquadronSolver
|
||||
|
||||
public IEnumerable<CalculationResult> SolveFor(SquadronMission mission, int requiredMatchingStats)
|
||||
{
|
||||
int minPhysical = mission.CurrentAttributes.PhysicalAbility;
|
||||
int minMental = mission.CurrentAttributes.MentalAbility;
|
||||
int minTactical = mission.CurrentAttributes.TacticalAbility;
|
||||
int minPhysical = mission.CurrentAttributes!.PhysicalAbility;
|
||||
int minMental = mission.CurrentAttributes!.MentalAbility;
|
||||
int minTactical = mission.CurrentAttributes!.TacticalAbility;
|
||||
|
||||
bool foundWithoutTraining = false;
|
||||
List<CalculationResult> intermediates = CalculateForAllMemberCombinations(mission.Level, _state.Bonus);
|
||||
|
@ -1,4 +1,5 @@
|
||||
using Squadronista.Solver;
|
||||
using System.Collections.Generic;
|
||||
using Squadronista.Solver;
|
||||
|
||||
namespace Squadronista;
|
||||
|
||||
@ -9,5 +10,6 @@ internal sealed class SquadronMission
|
||||
public required byte Level { get; init; }
|
||||
public required bool IsFlaggedMission { get; init; }
|
||||
|
||||
public required IReadOnlyList<Attributes> PossibleAttributes { get; init; }
|
||||
public Attributes? CurrentAttributes { get; set; }
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0-windows</TargetFramework>
|
||||
<Version>0.3</Version>
|
||||
<Version>0.4</Version>
|
||||
<LangVersion>11.0</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
|
@ -55,6 +55,15 @@ public class SquadronistaPlugin : IDalamudPlugin
|
||||
|
||||
// 13 and 14 seems to be a duplicate
|
||||
IsFlaggedMission = x.RowId is 7 or 14 or 15 or 34,
|
||||
PossibleAttributes = Enumerable.Range(0, x.RequiredPhysical.Length)
|
||||
.Select(i => new Attributes
|
||||
{
|
||||
PhysicalAbility = x.RequiredPhysical[i],
|
||||
MentalAbility = x.RequiredMental[i],
|
||||
TacticalAbility = x.RequiredTactical[i],
|
||||
})
|
||||
.ToList()
|
||||
.AsReadOnly(),
|
||||
})
|
||||
.ToList()
|
||||
.AsReadOnly();
|
||||
@ -73,7 +82,7 @@ public class SquadronistaPlugin : IDalamudPlugin
|
||||
.AsReadOnly();
|
||||
|
||||
_pluginInterface.UiBuilder.Draw += _windowSystem.Draw;
|
||||
_clientState.Logout += Logout;
|
||||
_clientState.Logout += ResetCharacterSpecificData;
|
||||
_addonLifecycle.RegisterListener(AddonEvent.PostSetup, "GcArmyMemberList", UpdateSquadronState);
|
||||
_addonLifecycle.RegisterListener(AddonEvent.PostRefresh, "GcArmyExpedition", UpdateExpeditionState);
|
||||
_addonLifecycle.RegisterListener(AddonEvent.PostSetup, "GcArmyExpedition", UpdateExpeditionState);
|
||||
@ -94,7 +103,7 @@ public class SquadronistaPlugin : IDalamudPlugin
|
||||
if (addon->AtkValuesCount != 133)
|
||||
{
|
||||
_pluginLog.Error("Unexpected AddonGcArmyMemberList atkvalues count");
|
||||
SquadronState = null;
|
||||
ResetCharacterSpecificData();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -104,7 +113,7 @@ public class SquadronistaPlugin : IDalamudPlugin
|
||||
// can't do any missions like this...
|
||||
if (memberCount < 4)
|
||||
{
|
||||
SquadronState = null;
|
||||
ResetCharacterSpecificData();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -157,7 +166,7 @@ public class SquadronistaPlugin : IDalamudPlugin
|
||||
{
|
||||
AvailableMissions.Clear();
|
||||
if (type == AddonEvent.PostSetup)
|
||||
SquadronState = null;
|
||||
ResetCharacterSpecificData();
|
||||
|
||||
AddonGcArmyExpedition* addonExpedition = (AddonGcArmyExpedition*)args.Addon;
|
||||
if (addonExpedition->AtkUnitBase.AtkValuesCount != 216)
|
||||
@ -182,9 +191,11 @@ public class SquadronistaPlugin : IDalamudPlugin
|
||||
return null;
|
||||
}
|
||||
|
||||
private void Logout()
|
||||
private void ResetCharacterSpecificData()
|
||||
{
|
||||
SquadronState = null;
|
||||
foreach (var mission in _allMissions)
|
||||
mission.CurrentAttributes = null;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
@ -193,7 +204,7 @@ public class SquadronistaPlugin : IDalamudPlugin
|
||||
_addonLifecycle.UnregisterListener(AddonEvent.PostSetup, "GcArmyExpedition", UpdateExpeditionState);
|
||||
_addonLifecycle.UnregisterListener(AddonEvent.PostRefresh, "GcArmyExpedition", UpdateExpeditionState);
|
||||
_addonLifecycle.UnregisterListener(AddonEvent.PostSetup, "GcArmyMemberList", UpdateSquadronState);
|
||||
_clientState.Logout -= Logout;
|
||||
_clientState.Logout -= ResetCharacterSpecificData;
|
||||
_pluginInterface.UiBuilder.Draw -= _windowSystem.Draw;
|
||||
}
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ internal sealed class MainWindow : Window, IDisposable
|
||||
{
|
||||
var atkValues = addonMemberList->AtkValues;
|
||||
activeMembers = Enumerable.Range(0, (int)atkValues[4].UInt)
|
||||
.Where(i => atkValues[5 + i * 15].UInt == 3)
|
||||
.Where(i => ((SquadronMemberUiFlags)atkValues[5 + i * 15].Int).HasFlag(SquadronMemberUiFlags.IsPartOfMission))
|
||||
.Select(i => atkValues[6 + i * 15].ReadAtkString())
|
||||
.Where(x => !string.IsNullOrEmpty(x))
|
||||
.Cast<string>()
|
||||
@ -170,21 +170,21 @@ internal sealed class MainWindow : Window, IDisposable
|
||||
ImGui.Text("Final Stats:");
|
||||
ImGui.SameLine(0);
|
||||
ImGui.TextColored(
|
||||
result.PhysicalAbility >= selectedMission.CurrentAttributes.PhysicalAbility
|
||||
result.PhysicalAbility >= selectedMission.CurrentAttributes!.PhysicalAbility
|
||||
? ImGuiColors.HealerGreen
|
||||
: ImGuiColors.DalamudYellow, $"{result.PhysicalAbility}");
|
||||
ImGui.SameLine(0);
|
||||
ImGui.Text("/");
|
||||
ImGui.SameLine(0);
|
||||
ImGui.TextColored(
|
||||
result.MentalAbility >= selectedMission.CurrentAttributes.MentalAbility
|
||||
result.MentalAbility >= selectedMission.CurrentAttributes!.MentalAbility
|
||||
? ImGuiColors.HealerGreen
|
||||
: ImGuiColors.DalamudYellow, $"{result.MentalAbility}");
|
||||
ImGui.SameLine(0);
|
||||
ImGui.Text("/");
|
||||
ImGui.SameLine(0);
|
||||
ImGui.TextColored(
|
||||
result.TacticalAbility >= selectedMission.CurrentAttributes.TacticalAbility
|
||||
result.TacticalAbility >= selectedMission.CurrentAttributes!.TacticalAbility
|
||||
? ImGuiColors.HealerGreen
|
||||
: ImGuiColors.DalamudYellow, $"{result.TacticalAbility}");
|
||||
|
||||
@ -193,7 +193,7 @@ internal sealed class MainWindow : Window, IDisposable
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.TextColored(ImGuiColors.DalamudRed, $"No combination of members/trainings can achieve\n{(selectedMission.IsFlaggedMission ? "all" : "2 out of 3")} attributes for {selectedMission.CurrentAttributes.PhysicalAbility} / {selectedMission.CurrentAttributes.MentalAbility} / {selectedMission.CurrentAttributes.TacticalAbility}.");
|
||||
ImGui.TextColored(ImGuiColors.DalamudRed, $"No combination of members/trainings can achieve\n{(selectedMission.IsFlaggedMission ? "all" : "2 out of 3")} attributes for {selectedMission.CurrentAttributes!.PhysicalAbility} / {selectedMission.CurrentAttributes!.MentalAbility} / {selectedMission.CurrentAttributes!.TacticalAbility}.");
|
||||
ImGui.Text("Level the squadron further and check again.");
|
||||
}
|
||||
}
|
||||
@ -315,12 +315,16 @@ internal sealed class MainWindow : Window, IDisposable
|
||||
int mental = int.Parse(mentalText->NodeText.ToString());
|
||||
int tactical = int.Parse(tacticalText->NodeText.ToString());
|
||||
|
||||
selectedMission.CurrentAttributes = new Attributes
|
||||
var newAttributes = new Attributes
|
||||
{
|
||||
PhysicalAbility = physical,
|
||||
MentalAbility = mental,
|
||||
TacticalAbility = tactical,
|
||||
};
|
||||
if (selectedMission.PossibleAttributes.Contains(newAttributes))
|
||||
selectedMission.CurrentAttributes = newAttributes;
|
||||
else
|
||||
_pluginLog.Warning($"Wrong attributes for {selectedMission.Name}: {physical} / {mental} / {tactical}");
|
||||
}
|
||||
|
||||
private static unsafe T* GetNodeById<T>(AtkUldManager uldManager, uint nodeId, NodeType? type = null)
|
||||
|
Loading…
Reference in New Issue
Block a user