Allow some nidoran/volbeat to mismatch correlation

https://github.com/kwsch/PKHeX/issues/4356#issuecomment-2333031493
fix flow so it is called in format3+
Closes #4356 ty @abcboy101

add another check for EC=0 eggs from Gen4 -- game uses the PID value as the "is egg available" flag, so can't obtain a 0-pid egg from gen4!

remove python paths from gitignore, so I can call one of the test folders `Eggs`
This commit is contained in:
Kurt 2024-09-05 23:55:46 -05:00
parent 95ffbca973
commit 617914b257
5 changed files with 40 additions and 37 deletions

32
.gitignore vendored
View file

@ -227,38 +227,6 @@ $RECYCLE.BIN/
pingme.txt pingme.txt
#############
## Python
#############
*.py[cod]
__pycache__/
# Packages
*.egg
*.egg-info
dist/
build/
eggs/
parts/
var/
sdist/
develop-eggs/
.installed.cfg
# Installer logs
pip-log.txt
# Unit test / coverage reports
.coverage
.tox
# Translations
*.mo
# Mr Developer
.mr.developer.cfg
################# #################
## MonoDevelop ## MonoDevelop
################# #################

View file

@ -1,3 +1,4 @@
using System;
using static PKHeX.Core.LegalityCheckStrings; using static PKHeX.Core.LegalityCheckStrings;
namespace PKHeX.Core; namespace PKHeX.Core;
@ -25,10 +26,34 @@ public sealed class PIDVerifier : Verifier
data.AddLine(Get(LPIDZero, Severity.Fishy)); data.AddLine(Get(LPIDZero, Severity.Fishy));
if (!pk.Nature.IsFixed()) // out of range if (!pk.Nature.IsFixed()) // out of range
data.AddLine(GetInvalid(LPIDNatureMismatch)); data.AddLine(GetInvalid(LPIDNatureMismatch));
if (data.Info.EncounterMatch is EncounterEgg egg)
VerifyEggPID(data, pk, egg);
VerifyShiny(data); VerifyShiny(data);
} }
private static void VerifyEggPID(LegalityAnalysis data, PKM pk, EncounterEgg egg)
{
if (egg.Generation is 4 && pk.EncryptionConstant == 0)
{
// Gen4 Eggs are "egg available" based on the stored PID value in the save file.
// If this value is 0 or is generated as 0 (possible), the game will see "false" and no egg is available.
// Only a non-zero value is possible to obtain.
data.AddLine(GetInvalid(LPIDEncryptZero, CheckIdentifier.EC));
return;
}
if (egg.Generation is 3 or 4 && Breeding.IsGenderSpeciesDetermination(egg.Species))
{
var gender = pk.Gender;
if (!Breeding.IsValidSpeciesBit34(pk.EncryptionConstant, gender)) // 50/50 chance!
{
if (gender == 1 || IsEggBitRequiredMale34(data.Info.Moves))
data.AddLine(GetInvalid(LPIDGenderMismatch, CheckIdentifier.EC));
}
}
}
private void VerifyShiny(LegalityAnalysis data) private void VerifyShiny(LegalityAnalysis data)
{ {
var pk = data.Entity; var pk = data.Entity;
@ -126,11 +151,6 @@ public sealed class PIDVerifier : Verifier
// Gen3-5 => Gen6 have PID==EC with an edge case exception. // Gen3-5 => Gen6 have PID==EC with an edge case exception.
if (Info.Generation is 3 or 4 or 5) if (Info.Generation is 3 or 4 or 5)
{ {
if (Info.Generation is 3 or 4 && Info.EncounterMatch is EncounterEgg egg && Breeding.IsGenderSpeciesDetermination(egg.Species))
{
if (!Breeding.IsValidSpeciesBit34(pk.EncryptionConstant, pk.Gender))
data.AddLine(GetInvalid(LPIDGenderMismatch, CheckIdentifier.EC));
}
VerifyTransferEC(data); VerifyTransferEC(data);
return; return;
} }
@ -214,4 +234,19 @@ public sealed class PIDVerifier : Verifier
expect = (xorPID ? (ec ^ 0x80000000) : ec); expect = (xorPID ? (ec ^ 0x80000000) : ec);
return xorPID; return xorPID;
} }
private static bool IsEggBitRequiredMale34(ReadOnlySpan<MoveResult> moves)
{
// If female, it must match the correlation.
// If Ditto was used with a Male Nidoran / Volbeat, it'll always be that gender.
// If Ditto was not used and a Male was obtained, it must match the correlation.
// This not-Ditto scenario is detectable if the entity has any Inherited level up moves.
foreach (var move in moves)
{
// Egg Moves (passed via Male) are allowed. Check only for inherited level up moves.
if (move.Info.Method is LearnMethod.InheritLevelUp)
return true;
}
return false;
}
} }