mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-10 14:44:24 +00:00
Permit pkrs strain 0 & 8 on Gen3+ context
Ruby & Sapphire had a bug that only looped when (rand) == 0 !!! instead of (rand & 7) == 0. End result is that the pkrs giving method yields strains 0 & 8 with 30/255 & 1/255 rarity. Gen2: z80 assembly does NOT work as intended, and has a separate bug that causes strains 9+ to never be obtainable. So close to a neat statistical separation. Revise the GUI to disable the events on field loading, and allow for selecting Strain0 w/ days !0. VC2->7 does not transfer pkrs; not that it matters since Gen3++ transfers can spread every strain. Thanks @SNBeast for clarification on Gen2's assembly logic and repro! Co-Authored-By: SNBeast <21327530+snbeast@users.noreply.github.com>
This commit is contained in:
parent
b08581aecf
commit
9a768dded3
4 changed files with 46 additions and 21 deletions
|
@ -49,16 +49,23 @@ public static class Pokerus
|
|||
{
|
||||
if (!IsObtainable(pk))
|
||||
return IsSusceptible(strain, days);
|
||||
return IsStrainValid(strain, days);
|
||||
if (pk.Format <= 2)
|
||||
return IsStrainValid2(strain);
|
||||
return IsStrainValid(strain);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IsStrainValid(PKM,int,int)"/>
|
||||
public static bool IsStrainValid(int strain, int days) => strain switch
|
||||
{
|
||||
0 when days is not 0 => false,
|
||||
8 => false,
|
||||
_ => true,
|
||||
};
|
||||
/// <remarks>
|
||||
/// Strains 9+ are not obtainable due to game programming error (jmp label too early).
|
||||
/// </remarks>
|
||||
public static bool IsStrainValid2(int strain) => strain <= 8;
|
||||
|
||||
/// <inheritdoc cref="IsStrainValid(PKM,int,int)"/>
|
||||
/// <remarks>
|
||||
/// Gen3 R/S have a 30/255 chance of giving strain 0, and a 1/255 chance of giving strain 8.
|
||||
/// Transfers will retain strain 0/8 and they're still able to infect others.
|
||||
/// </remarks>
|
||||
public static bool IsStrainValid(int strain) => strain <= 0xF;
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the Pokérus value for Duration is possible to have on the input entity.
|
||||
|
@ -88,7 +95,7 @@ public static class Pokerus
|
|||
/// <param name="strain">Strain number</param>
|
||||
/// <param name="days">Duration remaining</param>
|
||||
/// <returns>True if currently infected, and infectious to others.</returns>
|
||||
public static bool IsInfectuous(int strain, int days) => strain != 0 && days != 0;
|
||||
public static bool IsInfectious(int strain, int days) => days != 0;
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the Pokémon can be infected with the Pokérus.
|
||||
|
|
|
@ -318,7 +318,7 @@ public abstract class PKM : ISpeciesForm, ITrainerID32, IGeneration, IShiny, ILa
|
|||
}
|
||||
}
|
||||
|
||||
public bool PKRS_Infected { get => PKRS_Strain != 0; set => PKRS_Strain = value ? Math.Max(PKRS_Strain, 1) : 0; }
|
||||
public bool PKRS_Infected { get => PKRS_Days != 0; set => PKRS_Strain = value ? Math.Max(PKRS_Strain, 1) : 0; }
|
||||
|
||||
public bool PKRS_Cured
|
||||
{
|
||||
|
|
|
@ -56,9 +56,10 @@ public partial class PKMEditor
|
|||
|
||||
private void LoadPKRS(PKM pk)
|
||||
{
|
||||
Label_PKRS.Visible = CB_PKRSStrain.Visible = CHK_Infected.Checked = Label_PKRSdays.Visible = CB_PKRSDays.Visible = pk.PKRS_Infected;
|
||||
LoadClamp(CB_PKRSStrain, pk.PKRS_Strain);
|
||||
CHK_Infected.Checked = Label_PKRS.Visible = Label_PKRSdays.Visible = CB_PKRSStrain.Visible = CB_PKRSDays.Visible = pk.PKRS_Infected;
|
||||
CHK_Cured.Checked = pk.PKRS_Cured;
|
||||
ChangePKRSstrainDropDownLists(CB_PKRSStrain.SelectedIndex, pk.PKRS_Strain, 0);
|
||||
LoadClamp(CB_PKRSStrain, pk.PKRS_Strain);
|
||||
LoadClamp(CB_PKRSDays, pk.PKRS_Days); // clamp to valid day values for the current strain
|
||||
}
|
||||
|
||||
|
|
|
@ -1043,21 +1043,32 @@ public sealed partial class PKMEditor : UserControl, IMainEditor
|
|||
|
||||
private void UpdatePKRSstrain(object sender, EventArgs e)
|
||||
{
|
||||
// Change the PKRS Days to the legal bounds.
|
||||
int currentDuration = CB_PKRSDays.SelectedIndex;
|
||||
CB_PKRSDays.Items.Clear();
|
||||
if (!FieldsLoaded)
|
||||
return;
|
||||
|
||||
var strain = CB_PKRSStrain.SelectedIndex;
|
||||
int max = Pokerus.GetMaxDuration(strain);
|
||||
// Change the PKRS Days to the legal bounds.
|
||||
ChangePKRSstrainDropDownLists(-1, CB_PKRSStrain.SelectedIndex, CB_PKRSDays.SelectedIndex);
|
||||
}
|
||||
|
||||
private void ChangePKRSstrainDropDownLists(int oldStrain, int newStrain, int currentDuration)
|
||||
{
|
||||
if (oldStrain == newStrain)
|
||||
return;
|
||||
|
||||
CB_PKRSDays.Items.Clear();
|
||||
int max = Pokerus.GetMaxDuration(newStrain);
|
||||
for (int day = 0; day <= max; day++)
|
||||
CB_PKRSDays.Items.Add(day.ToString());
|
||||
|
||||
// Set the days back if they're legal
|
||||
CB_PKRSDays.SelectedIndex = strain == 0 ? 0 : Math.Min(max, currentDuration);
|
||||
CB_PKRSDays.SelectedIndex = Math.Min(max, currentDuration);
|
||||
}
|
||||
|
||||
private void UpdatePKRSdays(object sender, EventArgs e)
|
||||
{
|
||||
if (!FieldsLoaded)
|
||||
return;
|
||||
|
||||
var days = CB_PKRSDays.SelectedIndex;
|
||||
if (days != 0)
|
||||
return;
|
||||
|
@ -1072,19 +1083,22 @@ public sealed partial class PKMEditor : UserControl, IMainEditor
|
|||
|
||||
private void UpdatePKRSCured(object sender, EventArgs e)
|
||||
{
|
||||
if (!FieldsLoaded)
|
||||
return;
|
||||
|
||||
// Cured PokeRus is toggled
|
||||
if (CHK_Cured.Checked)
|
||||
{
|
||||
// If we're cured we have to have a strain infection.
|
||||
if (CB_PKRSStrain.SelectedIndex == 0)
|
||||
CB_PKRSStrain.SelectedIndex = 1;
|
||||
|
||||
// Has Had PokeRus
|
||||
Label_PKRSdays.Visible = CB_PKRSDays.Visible = false;
|
||||
CB_PKRSDays.SelectedIndex = 0;
|
||||
|
||||
Label_PKRS.Visible = CB_PKRSStrain.Visible = true;
|
||||
CHK_Infected.Checked = true;
|
||||
|
||||
// If we're cured we have to have a strain infection.
|
||||
if (CB_PKRSStrain.SelectedIndex == 0)
|
||||
CB_PKRSStrain.SelectedIndex = 1;
|
||||
}
|
||||
else if (!CHK_Infected.Checked)
|
||||
{
|
||||
|
@ -1107,6 +1121,9 @@ public sealed partial class PKMEditor : UserControl, IMainEditor
|
|||
|
||||
private void UpdatePKRSInfected(object sender, EventArgs e)
|
||||
{
|
||||
if (!FieldsLoaded)
|
||||
return;
|
||||
|
||||
if (CHK_Cured.Checked)
|
||||
{
|
||||
if (!CHK_Infected.Checked)
|
||||
|
|
Loading…
Reference in a new issue