Add gen4 headbutt slot numbers

All were zero, update dumper.
Extract some logic from other parts of the codebase
Fix wyrdeer level check if originated from GO
This commit is contained in:
Kurt 2024-01-09 19:07:32 -08:00
parent 671c3564ee
commit c66fc2f3bf
5 changed files with 37 additions and 13 deletions

View File

@ -40,19 +40,27 @@ public static bool IsAbilityPatchPossible(int format, ushort species)
{
if (format <= 7)
return false;
// Species (that can breed, from Gen6/7) that have never had a Hidden Ability distinct from their regular ability
// Gen8+ has encounters with HA, so this is no longer a concern for anything originating from Gen8+.
return species switch
{
(int)Species.Lunatone => false, // Levitate
(int)Species.Solrock => false, // Levitate
(int)Species.Rotom => false, // Levitate
(int)Species.Archen => false, // Defeatist
_ => true,
};
return IsPastGenWithUniqueHiddenAbility(species);
}
/// <summary>
/// Species (that can breed, from Gen6/7) that can visit a Gen8+ game with a unique Hidden Ability.
/// </summary>
/// <param name="species">Original encounter species</param>
/// <returns>True if ability patch can bump to Hidden Ability, false if not.</returns>
/// <remarks>
/// Gen8+ has encounters with HA, so this is no longer a concern for anything originating from Gen8+.
/// </remarks>
private static bool IsPastGenWithUniqueHiddenAbility(ushort species) => species switch
{
// Species that have never had a Hidden Ability distinct from their regular ability
(int)Species.Lunatone => false, // Levitate
(int)Species.Solrock => false, // Levitate
(int)Species.Rotom => false, // Levitate
(int)Species.Archen => false, // Defeatist
_ => true,
};
public BallInheritanceResult CanBreedWithBall(ushort species, byte form, Ball ball, PKM pk) => CanBreedWithBall(species, form, ball) ? Valid : Invalid;
private static BallType GetPermitBit(Ball ball) => ball switch

View File

@ -97,7 +97,7 @@ private CheckResult VerifyFormArgument(LegalityAnalysis data, IFormArgument f)
},
Runerigus => VerifyFormArgumentRange(enc.Species, Runerigus, arg, 49, 9999),
Alcremie => VerifyFormArgumentRange(enc.Species, Alcremie, arg, 0, (uint)AlcremieDecoration.Ribbon),
Wyrdeer when pk.CurrentLevel < 31 => GetInvalid(LEvoInvalid),
Wyrdeer when enc.Species != (int)Wyrdeer && pk.CurrentLevel < 31 => GetInvalid(LEvoInvalid),
Wyrdeer => VerifyFormArgumentRange(enc.Species, Wyrdeer, arg, 20, 9999),
Basculegion => VerifyFormArgumentRange(enc.Species, Basculegion, arg, 294, 9999),
Annihilape => VerifyFormArgumentRange(enc.Species, Annihilape, arg, 20, 9999),

View File

@ -114,11 +114,27 @@ public static TrashMatch GetTrashState(ReadOnlySpan<byte> top, ReadOnlySpan<char
return TrashMatch.TooLongToTell;
index++; // hop over the terminator
return GetTrashState(top, under, index);
}
private static TrashMatch GetTrashState(ReadOnlySpan<byte> top, ReadOnlySpan<char> under, int index)
{
// Adjust our spans to the relevant sections
under = under[index..];
var relevantSection = top[(index * 2)..];
bool check = IsEqualsEncoded(relevantSection, under);
return check ? TrashMatch.Present : TrashMatch.NotPresent;
}
private static bool IsEqualsEncoded(ReadOnlySpan<byte> relevantSection, ReadOnlySpan<char> under)
{
if (BitConverter.IsLittleEndian)
{
var u16 = MemoryMarshal.Cast<char, byte>(under);
return relevantSection.SequenceEqual(u16);
}
Span<byte> expect = stackalloc byte[relevantSection.Length];
WriteCharacters(expect, under);
return relevantSection.SequenceEqual(expect) ? TrashMatch.Present : TrashMatch.NotPresent;
return relevantSection.SequenceEqual(expect);
}
}