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(); }