Further refine memory 29 restrictions in SWSH

This commit is contained in:
Lusamine 2024-11-12 18:42:08 -06:00
parent cccce007b8
commit 1959eb34a5
4 changed files with 35 additions and 7 deletions

View file

@ -21,7 +21,7 @@ public abstract class MemoryContext
public abstract bool HasPokeCenter(GameVersion version, ushort location); public abstract bool HasPokeCenter(GameVersion version, ushort location);
public abstract bool IsInvalidGeneralLocationMemoryValue(byte memory, ushort variable, IEncounterTemplate enc, PKM pk); public abstract bool IsInvalidGeneralLocationMemoryValue(byte memory, ushort variable, IEncounterTemplate enc, PKM pk);
public abstract bool IsInvalidMiscMemory(byte memory, ushort variable); public abstract bool IsInvalidMiscMemory(byte memory, ushort variable, Species species, GameVersion version, int handler);
public abstract bool CanHaveIntensity(byte memory, byte intensity); public abstract bool CanHaveIntensity(byte memory, byte intensity);
public abstract bool CanHaveFeeling(byte memory, byte feeling, ushort argument); public abstract bool CanHaveFeeling(byte memory, byte feeling, ushort argument);

View file

@ -91,7 +91,7 @@ public sealed partial class MemoryContext6 : MemoryContext
return false; // todo return false; // todo
} }
public override bool IsInvalidMiscMemory(byte memory, ushort variable) public override bool IsInvalidMiscMemory(byte memory, ushort variable, Species species, GameVersion version, int handler)
{ {
return false; // todo return false; // todo
} }

View file

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using static PKHeX.Core.Species;
namespace PKHeX.Core; namespace PKHeX.Core;
@ -68,16 +69,43 @@ public sealed partial class MemoryContext8 : MemoryContext
return IsInvalidGenLoc8Other(memory, variable); return IsInvalidGenLoc8Other(memory, variable);
} }
public override bool IsInvalidMiscMemory(byte memory, ushort variable) public override bool IsInvalidMiscMemory(byte memory, ushort variable, Species species, GameVersion version, int handler)
{ {
return memory switch return memory switch
{ {
// {0} encountered {2} when it was with {1}. {4} that {3}. // {0} encountered {2} when it was with {1}. {4} that {3}.
29 when variable is not (888 or 889 or 890 or 898) => true, // Zacian, Zamazenta, Eternatus, Calyrex 29 when !IsValidMemory29((Species)variable, species, version, handler) => true,
_ => false, _ => false,
}; };
} }
private static bool IsValidMemory29(Species encountered, Species species, GameVersion version, int handler)
{
// {0} encountered {2} when it was with {1}. {4} that {3}.
// Restrictions for this memory are based on game progress and version.
// These Pokémon are allowed to meet themselves if caught to an empty party slot.
// Only these 4 species can appear in this memory.
if (encountered is not (Zacian or Zamazenta or Eternatus or Calyrex))
return false;
// If this is HT memory, it's possible to meet them in another game, so story progress doesn't matter.
if (handler == 1)
return true;
// OT Memory checks from here on.
// Zacian and Zamazenta being in an OT memory need to match the Pokemon's version.
if (version == GameVersion.SW && encountered == Zamazenta)
return false;
if (version == GameVersion.SH && encountered == Zacian)
return false;
// These legends can't meet Eternatus as OT memory since they require Eternatus to be caught.
if (species is (Zacian or Zamazenta or Glastrier or Spectrier or Calyrex))
return encountered != Eternatus;
return true;
}
private static bool CanObtainMemorySWSH(byte memory) => memory <= MAX_MEMORY_ID_SWSH && !Memory_NotSWSH.Contains(memory); private static bool CanObtainMemorySWSH(byte memory) => memory <= MAX_MEMORY_ID_SWSH && !Memory_NotSWSH.Contains(memory);
public override bool CanWinLotoID(int item) => item < byte.MaxValue && LotoPrizeSWSH.Contains((byte)item); public override bool CanWinLotoID(int item) => item < byte.MaxValue && LotoPrizeSWSH.Contains((byte)item);
@ -131,7 +159,7 @@ public sealed partial class MemoryContext8 : MemoryContext
return false; return false;
if (pk is IRibbonSetMark8 { RibbonMarkCurry: true }) if (pk is IRibbonSetMark8 { RibbonMarkCurry: true })
return false; return false;
if (pk.Species == (int)Species.Shedinja && pk is IRibbonSetAffixed { AffixedRibbon: (int)RibbonIndex.MarkCurry }) if (pk.Species == (int)Shedinja && pk is IRibbonSetAffixed { AffixedRibbon: (int)RibbonIndex.MarkCurry })
return false; return false;
return true; return true;
} }
@ -140,7 +168,7 @@ public sealed partial class MemoryContext8 : MemoryContext
{ {
if (enc is not EncounterSlot8) if (enc is not EncounterSlot8)
return false; return false;
return pk is IRibbonSetMark8 { RibbonMarkCurry: true } || pk.Species == (int)Species.Shedinja; return pk is IRibbonSetMark8 { RibbonMarkCurry: true } || pk.Species == (int)Shedinja;
} }
private static bool IsInvalidGenLoc8Other(byte memory, ushort variable) private static bool IsInvalidGenLoc8Other(byte memory, ushort variable)

View file

@ -144,7 +144,7 @@ public sealed class MemoryVerifier : Verifier
if (mem.IsInvalidGeneralLocationMemoryValue(memory.MemoryID, memory.Variable, info.EncounterMatch, pk)) if (mem.IsInvalidGeneralLocationMemoryValue(memory.MemoryID, memory.Variable, info.EncounterMatch, pk))
return GetInvalid(string.Format(LMemoryArgBadLocation, memory.Handler)); return GetInvalid(string.Format(LMemoryArgBadLocation, memory.Handler));
if (mem.IsInvalidMiscMemory(memory.MemoryID, memory.Variable)) if (mem.IsInvalidMiscMemory(memory.MemoryID, memory.Variable, (Species)pk.Species, pk.Version, handler))
return GetInvalid(string.Format(LMemoryArgBadID, memory.Handler)); return GetInvalid(string.Format(LMemoryArgBadID, memory.Handler));
switch (memory.MemoryID) switch (memory.MemoryID)