diff --git a/PKHeX.Core/Editing/Pokerus.cs b/PKHeX.Core/Editing/Pokerus.cs
index 0fff50ac3..f408a61b1 100644
--- a/PKHeX.Core/Editing/Pokerus.cs
+++ b/PKHeX.Core/Editing/Pokerus.cs
@@ -1,17 +1,92 @@
namespace PKHeX.Core;
+///
+/// Logic pertaining to Pokérus -- the virus that doubles EVs gained from battle.
+///
public static class Pokerus
{
+ ///
+ /// Gets the max duration (in days) that a strain can be infectious.
+ ///
+ /// Strain number
+ /// Initial duration (in days). When the value decrements to zero, the Pokémon is no longer infectious.
public static int GetMaxDuration(int strain) => (strain & 3) + 1;
- public static bool IsObtainable(PKM pkm) => pkm is not PA8; // don't care about PK1
+ ///
+ /// Checks if any Pokérus values are possible to have on the input entity.
+ ///
+ /// Entity to check
+ /// True if Pokérus exists in the game format, or can be transmitted to the entity via another game.
+ public static bool IsObtainable(PKM pk) => pk is not PA8; // don't care about PK1, not stored in the data.
- public static bool IsStrainValid(PKM pkm, int strain, int days) => IsObtainable(pkm) && IsStrainValid(strain, days);
+ ///
+ /// Checks if the Pokérus value for Strain is possible to have on the input entity.
+ ///
+ /// Entity to check
+ /// Strain number
+ /// Duration remaining
+ /// True if valid
+ public static bool IsStrainValid(PKM pk, int strain, int days)
+ {
+ if (!IsObtainable(pk))
+ return IsSusceptible(strain, days);
+ return IsStrainValid(strain, days);
+ }
+ ///
public static bool IsStrainValid(int strain, int days) => strain switch
{
0 when days is not 0 => false,
8 => false,
_ => true,
};
+
+ ///
+ /// Checks if the Pokérus value for Duration is possible to have on the input entity.
+ ///
+ /// Strain number
+ /// Duration remaining
+ /// Maximum value permitted
+ /// True if valid
+ public static bool IsDurationValid(int strain, int days, out int max)
+ {
+ max = GetMaxDuration(strain);
+ return (uint)days <= max;
+ }
+
+ ///
+ /// Checks if the Pokémon is immune to the Pokérus.
+ ///
+ /// Strain number
+ /// Duration remaining
+ /// True if immune (cannot be infected).
+ /// An immune Pokémon must have been infected and cured prior to being "immune".
+ public static bool IsImmune(int strain, int days) => strain != 0 && days == 0;
+
+ ///
+ /// Checks if the Pokémon is currently infected with the Pokérus.
+ ///
+ /// Strain number
+ /// Duration remaining
+ /// True if currently infected, and infectious to others.
+ public static bool IsInfectuous(int strain, int days) => strain != 0 && days != 0;
+
+ ///
+ /// Checks if the Pokémon can be infected with the Pokérus.
+ ///
+ /// Strain number
+ /// Duration remaining
+ /// True if can be infected by another infectious individual.
+ public static bool IsSusceptible(int strain, int days) => strain == 0 && days == 0;
+
+ ///
+ /// Vaccinates the Pokémon so it will never be infectious in the format it exists in.
+ ///
+ /// Entity to modify.
+ /// Overwrites all Pokérus values even if already legal.
+ public static void Vaccinate(this PKM pk)
+ {
+ pk.PKRS_Strain = IsObtainable(pk) ? 1 : 0;
+ pk.PKRS_Days = 0;
+ }
}
diff --git a/PKHeX.Core/Legality/Verifiers/MiscVerifier.cs b/PKHeX.Core/Legality/Verifiers/MiscVerifier.cs
index a1dbafbb8..8567eb801 100644
--- a/PKHeX.Core/Legality/Verifiers/MiscVerifier.cs
+++ b/PKHeX.Core/Legality/Verifiers/MiscVerifier.cs
@@ -130,9 +130,9 @@ private void VerifyMiscPokerus(LegalityAnalysis data)
if (!strainValid)
data.AddLine(GetInvalid(string.Format(LPokerusStrainUnobtainable_0, strain)));
- var expect = Pokerus.GetMaxDuration(strain);
- if (days > expect)
- data.AddLine(GetInvalid(string.Format(LPokerusDaysTooHigh_0, expect)));
+ bool daysValid = Pokerus.IsDurationValid(strain, days, out var max);
+ if (!daysValid)
+ data.AddLine(GetInvalid(string.Format(LPokerusDaysTooHigh_0, max)));
}
public void VerifyMiscG1(LegalityAnalysis data)
diff --git a/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.cs b/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.cs
index 85da376c5..cd5641bc8 100644
--- a/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.cs
+++ b/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.cs
@@ -1102,13 +1102,16 @@ private void UpdatePKRSstrain(object sender, EventArgs e)
private void UpdatePKRSdays(object sender, EventArgs e)
{
- if (CB_PKRSDays.SelectedIndex != 0)
+ var days = CB_PKRSDays.SelectedIndex;
+ if (days != 0)
return;
// If no days are selected
- if (CB_PKRSStrain.SelectedIndex == 0)
+ var strain = CB_PKRSStrain.SelectedIndex;
+ if (Pokerus.IsSusceptible(strain, days))
CHK_Cured.Checked = CHK_Infected.Checked = false; // No Strain = Never Cured / Infected, triggers Strain update
- else CHK_Cured.Checked = true; // Any Strain = Cured
+ else if (Pokerus.IsImmune(strain, days))
+ CHK_Cured.Checked = true; // Any Strain = Cured
}
private void UpdatePKRSCured(object sender, EventArgs e)
@@ -1141,7 +1144,7 @@ private void UpdatePKRSCured(object sender, EventArgs e)
}
// if not cured yet, days > 0
if (!CHK_Cured.Checked && CHK_Infected.Checked && CB_PKRSDays.SelectedIndex == 0)
- CB_PKRSDays.SelectedIndex++;
+ CB_PKRSDays.SelectedIndex = 1;
SetMarkings();
}