mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-10 14:44:24 +00:00
Add HOME hoopa move share, add form specific check
Hoopa cannot know both moves due to form reversion Kyurem cannot know both moves due to form reversion Kyurem cannot know Scary Face when fused in past games Add dexnav for AtAnyTime/HOME lookback when original moveset deleted (no longer in local relearn moves) BDSP Underground encounters w/ egg moves can be shared by other means
This commit is contained in:
parent
18fd790657
commit
8c5773969a
7 changed files with 113 additions and 8 deletions
|
@ -22,8 +22,13 @@ public sealed class LearnGroup6 : ILearnGroup
|
|||
for (var i = 0; i < evos.Length; i++)
|
||||
Check(result, current, pk, evos[i], i, types, option, mode);
|
||||
|
||||
if (option is not LearnOption.Current && types.HasFlag(MoveSourceType.Encounter) && enc is EncounterEgg { Generation: Generation } egg)
|
||||
CheckEncounterMoves(result, current, egg);
|
||||
if (option.IsPast() && types.HasFlag(MoveSourceType.Encounter))
|
||||
{
|
||||
if (enc is EncounterEgg { Generation: Generation } egg)
|
||||
CheckEncounterMoves(result, current, egg);
|
||||
else if (enc is EncounterSlot6AO { CanDexNav: true } dexnav && pk.IsOriginalMovesetDeleted())
|
||||
CheckDexNavMoves(result, current, dexnav);
|
||||
}
|
||||
|
||||
return MoveResult.AllParsed(result);
|
||||
}
|
||||
|
@ -48,6 +53,22 @@ public sealed class LearnGroup6 : ILearnGroup
|
|||
}
|
||||
}
|
||||
|
||||
private static void CheckDexNavMoves(Span<MoveResult> result, ReadOnlySpan<ushort> current, EncounterSlot6AO dexnav)
|
||||
{
|
||||
// DexNav moves are only available in OR/AS
|
||||
// Can only have one DexNav move
|
||||
for (var i = 0; i < result.Length; i++)
|
||||
{
|
||||
if (result[i].Valid)
|
||||
continue;
|
||||
var move = current[i];
|
||||
if (!dexnav.CanBeDexNavMove(move))
|
||||
continue;
|
||||
result[i] = new(new(LearnMethod.Special, LearnEnvironment.ORAS), Generation);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static void Check(Span<MoveResult> result, ReadOnlySpan<ushort> current, PKM pk, EvoCriteria evo, int stage, MoveSourceType types, LearnOption option, CheckMode mode)
|
||||
{
|
||||
if (!FormChangeUtil.ShouldIterateForms(evo.Species, evo.Form, Generation, option))
|
||||
|
|
|
@ -29,7 +29,7 @@ public sealed class LearnGroup7 : ILearnGroup
|
|||
for (var i = 0; i < evos.Length; i++)
|
||||
Check(result, current, pk, evos[i], i, types, option, mode);
|
||||
|
||||
if (option is not LearnOption.Current && types.HasFlag(MoveSourceType.Encounter) && enc is EncounterEgg { Generation: Generation } egg)
|
||||
if (option.IsPast() && types.HasFlag(MoveSourceType.Encounter) && enc is EncounterEgg { Generation: Generation } egg)
|
||||
CheckEncounterMoves(result, current, egg);
|
||||
|
||||
return MoveResult.AllParsed(result);
|
||||
|
|
|
@ -46,7 +46,7 @@ public sealed class LearnGroup8 : ILearnGroup
|
|||
|
||||
CheckSharedMoves(result, current, evos[0]);
|
||||
|
||||
if (option is not LearnOption.Current && types.HasFlag(MoveSourceType.Encounter) && pk.IsOriginalMovesetDeleted() && enc is EncounterEgg { Generation: Generation } egg)
|
||||
if (option.IsPast() && types.HasFlag(MoveSourceType.Encounter) && pk.IsOriginalMovesetDeleted() && enc is EncounterEgg { Generation: Generation } egg)
|
||||
CheckEncounterMoves(result, current, egg);
|
||||
|
||||
if (MoveResult.AllParsed(result))
|
||||
|
|
|
@ -27,7 +27,7 @@ public sealed class LearnGroup9 : ILearnGroup
|
|||
|
||||
CheckSharedMoves(result, current, evos[0]);
|
||||
|
||||
if (option is not LearnOption.Current && types.HasFlag(MoveSourceType.Encounter) && pk.IsOriginalMovesetDeleted() && enc is EncounterEgg { Generation: Generation } egg)
|
||||
if (option.IsPast() && types.HasFlag(MoveSourceType.Encounter) && pk.IsOriginalMovesetDeleted() && enc is EncounterEgg { Generation: Generation } egg)
|
||||
CheckEncounterMoves(result, current, egg);
|
||||
|
||||
if (MoveResult.AllParsed(result))
|
||||
|
|
|
@ -60,6 +60,13 @@ public sealed class LearnGroupHOME : ILearnGroup
|
|||
return true;
|
||||
}
|
||||
|
||||
// HOME is silly and allows form exclusive moves to be transferred without ever knowing the move.
|
||||
if (TryAddExclusiveMoves(result, current, pk))
|
||||
{
|
||||
if (CleanPurge(result, current, pk, types, local, evos))
|
||||
return true;
|
||||
}
|
||||
|
||||
// Ignore Battle Version; can be transferred back to SW/SH and wiped after the moves have been shared from HOME
|
||||
|
||||
if (history.HasVisitedLGPE)
|
||||
|
@ -143,6 +150,7 @@ public sealed class LearnGroupHOME : ILearnGroup
|
|||
if (history.HasVisitedBDSP && pk is not PB8)
|
||||
RentLoopGetAll(LearnGroup8b.Instance, result, pk, history, enc, types, option, evos, local);
|
||||
AddOriginalMoves(result, pk, enc, types, local, evos);
|
||||
AddExclusiveMoves(result, pk);
|
||||
|
||||
// Looking backwards before HOME
|
||||
if (history.HasVisitedLGPE)
|
||||
|
@ -196,6 +204,31 @@ public sealed class LearnGroupHOME : ILearnGroup
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private static bool TryAddExclusiveMoves(Span<MoveResult> result, ReadOnlySpan<ushort> current, PKM pk)
|
||||
{
|
||||
if (pk.Species is (int)Species.Hoopa)
|
||||
{
|
||||
var move = pk.Form == 0 ? (ushort)Move.HyperspaceHole : (ushort)Move.HyperspaceFury;
|
||||
var index = current.IndexOf(move);
|
||||
if (index < 0)
|
||||
return false;
|
||||
ref var exist = ref result[index];
|
||||
if (exist.Valid)
|
||||
return false;
|
||||
exist = new MoveResult(new MoveLearnInfo(LearnMethod.Special, LearnEnvironment.HOME));
|
||||
return true;
|
||||
}
|
||||
// Kyurem as Fused cannot move into HOME and trigger move sharing.
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void AddExclusiveMoves(Span<bool> result, PKM pk)
|
||||
{
|
||||
if (pk.Species == (int)Species.Hoopa)
|
||||
result[pk.Form == 0 ? (int)Move.HyperspaceHole : (int)Move.HyperspaceFury] = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the current HOME source for the given context.
|
||||
/// </summary>
|
||||
|
|
|
@ -29,9 +29,14 @@ internal static class LearnVerifier
|
|||
private static void VerifyMoves(Span<MoveResult> result, ReadOnlySpan<ushort> current, PKM pk, IEncounterTemplate enc, EvolutionHistory history)
|
||||
{
|
||||
if (pk.IsEgg)
|
||||
{
|
||||
LearnVerifierEgg.Verify(result, current, enc, pk);
|
||||
else
|
||||
LearnVerifierHistory.Verify(result, current, enc, pk, history);
|
||||
return;
|
||||
}
|
||||
|
||||
LearnVerifierHistory.Verify(result, current, enc, pk, history);
|
||||
// Check for form exclusive interlocked moves.
|
||||
FlagFormExclusiveMoves(result, current, pk);
|
||||
}
|
||||
|
||||
private static void Finalize(Span<MoveResult> result, ReadOnlySpan<ushort> current)
|
||||
|
@ -89,4 +94,50 @@ internal static class LearnVerifier
|
|||
result[i] = EmptyInvalid;
|
||||
}
|
||||
}
|
||||
|
||||
private static void FlagFormExclusiveMoves(Span<MoveResult> result, ReadOnlySpan<ushort> current, PKM pk)
|
||||
{
|
||||
if (pk is { Species: (int)Species.Hoopa })
|
||||
FlagFormExclusiveHoopa(result, current, pk);
|
||||
else if (pk is { Species: (int)Species.Kyurem })
|
||||
FlagFormExclusiveKyurem(result, current, pk);
|
||||
}
|
||||
|
||||
private static void FlagFormExclusiveHoopa(Span<MoveResult> result, ReadOnlySpan<ushort> current, PKM pk)
|
||||
{
|
||||
if (pk.Format < 8)
|
||||
return;
|
||||
|
||||
// Hoopa in Gen8+ cannot have Hyperspace Hole if not form 0, and cannot have Hyperspace Fury if not form 1.
|
||||
var disallow = pk.Form != 0 ? (ushort)Move.HyperspaceHole : (ushort)Move.HyperspaceFury;
|
||||
var index = current.IndexOf(disallow);
|
||||
if (index >= 0)
|
||||
result[index] = MoveResult.Unobtainable(pk.Form == 0 ? (ushort)Move.HyperspaceHole : (ushort)Move.HyperspaceFury);
|
||||
}
|
||||
|
||||
private static void FlagFormExclusiveKyurem(Span<MoveResult> result, ReadOnlySpan<ushort> current, PKM pk)
|
||||
{
|
||||
// Kyurem forms replace Scary Face with their Fusion Move and vice versa.
|
||||
if (pk.Form is not 1) // not White
|
||||
{
|
||||
// Disallow Fusion Flare
|
||||
var index = current.IndexOf((ushort)Move.FusionFlare);
|
||||
if (index >= 0)
|
||||
result[index] = MoveResult.Unobtainable((ushort)Move.ScaryFace);
|
||||
}
|
||||
if (pk.Form is not 2) // not Black
|
||||
{
|
||||
// Disallow Fusion Flare
|
||||
var index = current.IndexOf((ushort)Move.FusionBolt);
|
||||
if (index >= 0)
|
||||
result[index] = MoveResult.Unobtainable((ushort)Move.ScaryFace);
|
||||
}
|
||||
if (pk.Form is not 0 && pk.Format < 8) // unfused
|
||||
{
|
||||
// Disallow Scary Face in formats < 8
|
||||
var index = current.IndexOf((ushort)Move.ScaryFace);
|
||||
if (index >= 0)
|
||||
result[index] = MoveResult.Unobtainable(pk.Form == 1 ? (ushort)Move.FusionFlare : (ushort)Move.FusionBolt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ public static class FormChangeUtil
|
|||
/// <param name="option">Conditions we're checking with</param>
|
||||
public static bool ShouldIterateForms(ushort species, byte form, int generation, LearnOption option)
|
||||
{
|
||||
if (option is not LearnOption.Current)
|
||||
if (option.IsPast())
|
||||
return FormChangeMoves.TryGetValue(species, out var func) && func((generation, form));
|
||||
return IterateAllForms(species);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue