mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-22 20:13:06 +00:00
Misc fixes
Ignore slot match for Swarm3 Honey Tree only yield possible slots via TID/SID Pick min level for EncounterTrade1 Set nickname for CXD Elekid trade Set held item for Pt Giratina Set egg location for Ranch gift hatched egg Set hidden ability flag for N's Darmanitan Set XY Vivillon form based on generated geolocation Force evolve Trade species if encounter requires it Correctly recognize pikachu-colored-pichu Gen4 gift PID type Set hatched manaphy egg's met location & date
This commit is contained in:
parent
b536388d0d
commit
e3f8091971
19 changed files with 78 additions and 37 deletions
|
@ -60,7 +60,7 @@ public sealed class EncounterGenerator3 : IEncounterGenerator
|
|||
foreach (var enc in iterator)
|
||||
{
|
||||
var e = enc.Encounter;
|
||||
if (e is not EncounterSlot3 s3)
|
||||
if (e is not EncounterSlot3 s3 || s3 is EncounterSlot3Swarm)
|
||||
{
|
||||
yield return e;
|
||||
continue;
|
||||
|
|
|
@ -20,9 +20,9 @@ public sealed class EncounterGenerator4 : IEncounterGenerator
|
|||
return GetEncounters(pk, chain, info);
|
||||
}
|
||||
|
||||
public IEnumerable<IEncounterable> GetPossible(PKM _, EvoCriteria[] chain, GameVersion game, EncounterTypeGroup groups)
|
||||
public IEnumerable<IEncounterable> GetPossible(PKM pk, EvoCriteria[] chain, GameVersion game, EncounterTypeGroup groups)
|
||||
{
|
||||
var iterator = new EncounterPossible4(chain, groups, game);
|
||||
var iterator = new EncounterPossible4(chain, groups, game, pk);
|
||||
foreach (var enc in iterator)
|
||||
yield return enc;
|
||||
}
|
||||
|
|
|
@ -8,9 +8,9 @@ public sealed class EncounterGenerator8b : IEncounterGenerator
|
|||
{
|
||||
public static readonly EncounterGenerator8b Instance = new();
|
||||
|
||||
public IEnumerable<IEncounterable> GetPossible(PKM _, EvoCriteria[] chain, GameVersion game, EncounterTypeGroup groups)
|
||||
public IEnumerable<IEncounterable> GetPossible(PKM pk, EvoCriteria[] chain, GameVersion game, EncounterTypeGroup groups)
|
||||
{
|
||||
var iterator = new EncounterPossible8b(chain, groups, game);
|
||||
var iterator = new EncounterPossible8b(chain, groups, game, pk);
|
||||
foreach (var enc in iterator)
|
||||
yield return enc;
|
||||
}
|
||||
|
|
|
@ -84,9 +84,9 @@ public static class EncounterMovesetGenerator
|
|||
/// </summary>
|
||||
/// <param name="pk">Rough Pokémon data which contains the requested species, gender, and form.</param>
|
||||
/// <param name="info">Trainer information of the receiver.</param>
|
||||
public static void OptimizeCriteria(PKM pk, ITrainerID16 info)
|
||||
public static void OptimizeCriteria(PKM pk, ITrainerID32 info)
|
||||
{
|
||||
pk.TID16 = info.TID16; // Necessary for Gen2 Headbutt encounters.
|
||||
pk.ID32 = info.ID32; // Necessary for Gen2 Headbutt encounters and Honey Tree encounters
|
||||
var htTrash = pk.HT_Trash;
|
||||
if (htTrash.Length != 0)
|
||||
htTrash[0] = 1; // Fake Trash to indicate trading.
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace PKHeX.Core;
|
|||
/// <summary>
|
||||
/// Iterates to find possible encounters for <see cref="GameVersion.Gen4"/> encounters.
|
||||
/// </summary>
|
||||
public record struct EncounterPossible4(EvoCriteria[] Chain, EncounterTypeGroup Flags, GameVersion Version) : IEnumerator<IEncounterable>
|
||||
public record struct EncounterPossible4(EvoCriteria[] Chain, EncounterTypeGroup Flags, GameVersion Version, PKM Entity) : IEnumerator<IEncounterable>
|
||||
{
|
||||
public IEncounterable Current { get; private set; }
|
||||
|
||||
|
@ -181,23 +181,23 @@ public record struct EncounterPossible4(EvoCriteria[] Chain, EncounterTypeGroup
|
|||
{ State = YieldState.SlotSS; goto case YieldState.SlotSS; }
|
||||
throw new ArgumentOutOfRangeException(nameof(Version));
|
||||
case YieldState.SlotHG:
|
||||
if (TryGetNext<EncounterArea4, EncounterSlot4>(Encounters4HGSS.SlotsHG))
|
||||
if (TryGetNext(Encounters4HGSS.SlotsHG))
|
||||
return true;
|
||||
goto case YieldState.SlotEnd;
|
||||
case YieldState.SlotSS:
|
||||
if (TryGetNext<EncounterArea4, EncounterSlot4>(Encounters4HGSS.SlotsSS))
|
||||
if (TryGetNext(Encounters4HGSS.SlotsSS))
|
||||
return true;
|
||||
goto case YieldState.SlotEnd;
|
||||
case YieldState.SlotD:
|
||||
if (TryGetNext<EncounterArea4, EncounterSlot4>(Encounters4DPPt.SlotsD))
|
||||
if (TryGetNext(Encounters4DPPt.SlotsD))
|
||||
return true;
|
||||
goto case YieldState.SlotEnd;
|
||||
case YieldState.SlotP:
|
||||
if (TryGetNext<EncounterArea4, EncounterSlot4>(Encounters4DPPt.SlotsP))
|
||||
if (TryGetNext(Encounters4DPPt.SlotsP))
|
||||
return true;
|
||||
goto case YieldState.SlotEnd;
|
||||
case YieldState.SlotPt:
|
||||
if (TryGetNext<EncounterArea4, EncounterSlot4>(Encounters4DPPt.SlotsPt))
|
||||
if (TryGetNext(Encounters4DPPt.SlotsPt))
|
||||
return true;
|
||||
goto case YieldState.SlotEnd;
|
||||
case YieldState.SlotEnd:
|
||||
|
@ -206,9 +206,7 @@ public record struct EncounterPossible4(EvoCriteria[] Chain, EncounterTypeGroup
|
|||
return false;
|
||||
}
|
||||
|
||||
private bool TryGetNext<TArea, TSlot>(TArea[] areas)
|
||||
where TArea : class, IEncounterArea<TSlot>
|
||||
where TSlot : class, IEncounterable, IEncounterMatch
|
||||
private bool TryGetNext(EncounterArea4[] areas)
|
||||
{
|
||||
for (; Index < areas.Length; Index++, SubIndex = 0)
|
||||
{
|
||||
|
@ -236,7 +234,7 @@ public record struct EncounterPossible4(EvoCriteria[] Chain, EncounterTypeGroup
|
|||
return false;
|
||||
}
|
||||
|
||||
private bool TryGetNextSub<T>(T[] slots) where T : class, IEncounterable, IEncounterMatch
|
||||
private bool TryGetNextSub(EncounterSlot4[] slots)
|
||||
{
|
||||
while (SubIndex < slots.Length)
|
||||
{
|
||||
|
@ -245,6 +243,8 @@ public record struct EncounterPossible4(EvoCriteria[] Chain, EncounterTypeGroup
|
|||
{
|
||||
if (enc.Species != evo.Species)
|
||||
continue;
|
||||
if (enc.IsInvalidMunchlaxTree(Entity))
|
||||
continue;
|
||||
return SetCurrent(enc);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace PKHeX.Core;
|
|||
/// <summary>
|
||||
/// Iterates to find possible encounters for <see cref="GameVersion.BDSP"/> encounters.
|
||||
/// </summary>
|
||||
public record struct EncounterPossible8b(EvoCriteria[] Chain, EncounterTypeGroup Flags, GameVersion Version) : IEnumerator<IEncounterable>
|
||||
public record struct EncounterPossible8b(EvoCriteria[] Chain, EncounterTypeGroup Flags, GameVersion Version, PKM Entity) : IEnumerator<IEncounterable>
|
||||
{
|
||||
public IEncounterable Current { get; private set; }
|
||||
|
||||
|
@ -119,11 +119,11 @@ public record struct EncounterPossible8b(EvoCriteria[] Chain, EncounterTypeGroup
|
|||
{ State = YieldState.SlotSP; goto case YieldState.SlotSP; }
|
||||
throw new ArgumentOutOfRangeException(nameof(Version));
|
||||
case YieldState.SlotBD:
|
||||
if (TryGetNext<EncounterArea8b, EncounterSlot8b>(Encounters8b.SlotsBD))
|
||||
if (TryGetNext(Encounters8b.SlotsBD))
|
||||
return true;
|
||||
goto case YieldState.SlotEnd;
|
||||
case YieldState.SlotSP:
|
||||
if (TryGetNext<EncounterArea8b, EncounterSlot8b>(Encounters8b.SlotsSP))
|
||||
if (TryGetNext(Encounters8b.SlotsSP))
|
||||
return true;
|
||||
goto case YieldState.SlotEnd;
|
||||
case YieldState.SlotEnd:
|
||||
|
@ -132,9 +132,7 @@ public record struct EncounterPossible8b(EvoCriteria[] Chain, EncounterTypeGroup
|
|||
return false;
|
||||
}
|
||||
|
||||
private bool TryGetNext<TArea, TSlot>(TArea[] areas)
|
||||
where TArea : class, IEncounterArea<TSlot>
|
||||
where TSlot : class, IEncounterable, IEncounterMatch
|
||||
private bool TryGetNext(EncounterArea8b[] areas)
|
||||
{
|
||||
for (; Index < areas.Length; Index++, SubIndex = 0)
|
||||
{
|
||||
|
@ -145,7 +143,7 @@ public record struct EncounterPossible8b(EvoCriteria[] Chain, EncounterTypeGroup
|
|||
return false;
|
||||
}
|
||||
|
||||
private bool TryGetNextSub<T>(T[] slots) where T : class, IEncounterable, IEncounterMatch
|
||||
private bool TryGetNextSub(EncounterSlot8b[] slots)
|
||||
{
|
||||
while (SubIndex < slots.Length)
|
||||
{
|
||||
|
@ -154,6 +152,8 @@ public record struct EncounterPossible8b(EvoCriteria[] Chain, EncounterTypeGroup
|
|||
{
|
||||
if (enc.Species != evo.Species)
|
||||
continue;
|
||||
if (enc.IsInvalidMunchlaxTree(Entity))
|
||||
continue;
|
||||
return SetCurrent(enc);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -112,7 +112,8 @@ public sealed record EncounterTrade1 : IEncounterable, IEncounterMatch, IFixedTr
|
|||
|
||||
public PK1 ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria)
|
||||
{
|
||||
var level = ParseSettings.AllowGen1Tradeback ? LevelMinGSC : LevelMinRBY;
|
||||
bool gsc = CanObtainMinGSC();
|
||||
var level = gsc ? LevelMinGSC : LevelMinRBY;
|
||||
int lang = (int)Language.GetSafeLanguage(Generation, (LanguageID)tr.Language, Version);
|
||||
var isJapanese = lang == (int)LanguageID.Japanese;
|
||||
var pi = EncounterUtil1.GetPersonal1(Version, Species);
|
||||
|
@ -131,6 +132,8 @@ public sealed record EncounterTrade1 : IEncounterable, IEncounterMatch, IFixedTr
|
|||
pk.OT_Trash[0] = StringConverter12.G1TradeOTCode;
|
||||
|
||||
EncounterUtil1.SetEncounterMoves(pk, Version, level);
|
||||
if (EvolveOnTrade)
|
||||
pk.Species++;
|
||||
|
||||
pk.ResetPartyStats();
|
||||
|
||||
|
@ -170,7 +173,7 @@ public sealed record EncounterTrade1 : IEncounterable, IEncounterMatch, IFixedTr
|
|||
|
||||
private bool IsMatchLevel(PKM pk, int lvl)
|
||||
{
|
||||
if (pk is not PK1)
|
||||
if (pk is not PK1 || CanObtainMinGSC())
|
||||
return lvl >= LevelMinGSC;
|
||||
return lvl >= LevelMin;
|
||||
}
|
||||
|
|
|
@ -9,9 +9,5 @@ namespace PKHeX.Core;
|
|||
internal sealed record EncounterSlot3Swarm(EncounterArea3 Parent, ushort Species, byte LevelMin, byte LevelMax, byte SlotNumber, Moveset Moves)
|
||||
: EncounterSlot3(Parent, Species, 0, LevelMin, LevelMax, SlotNumber, 0, 0, 0, 0), IMoveset
|
||||
{
|
||||
protected override void SetEncounterMoves(PKM pk)
|
||||
{
|
||||
pk.SetMoves(Moves);
|
||||
pk.SetMaximumPPCurrent(Moves);
|
||||
}
|
||||
protected override void SetEncounterMoves(PKM pk) => pk.SetMoves(Moves);
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ public sealed record EncounterTrade3XD : IEncounterable, IEncounterMatch, IEncou
|
|||
OT_Gender = 0,
|
||||
TID16 = TID16,
|
||||
SID16 = tr.SID16,
|
||||
Nickname = SpeciesName.GetSpeciesNameGeneration(Species, lang, Generation),
|
||||
Nickname = IsFixedNickname ? GetNickname(lang) : SpeciesName.GetSpeciesNameGeneration(Species, lang, Generation),
|
||||
};
|
||||
|
||||
SetPINGA(pk, criteria, pi);
|
||||
|
|
|
@ -122,12 +122,19 @@ public sealed record EncounterSlot4(EncounterArea4 Parent, ushort Species, byte
|
|||
|
||||
// A/B/C tables, only Munchlax is a 'C' encounter, and A/B are accessible from any tree.
|
||||
// C table encounters are only available from 4 trees, which are determined by TID16/SID16 of the save file.
|
||||
if (Type is SlotType.HoneyTree && Species == (int)Core.Species.Munchlax && !Parent.IsMunchlaxTree(pk))
|
||||
if (IsInvalidMunchlaxTree(pk))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool IsInvalidMunchlaxTree(PKM pk)
|
||||
{
|
||||
if (Type is not SlotType.HoneyTree)
|
||||
return false;
|
||||
return Species == (int)Core.Species.Munchlax && !Parent.IsMunchlaxTree(pk);
|
||||
}
|
||||
|
||||
public EncounterMatchRating GetMatchRating(PKM pk)
|
||||
{
|
||||
if ((pk.Ball == (int)Ball.Safari) != Locations.IsSafariZoneLocation4(Location))
|
||||
|
|
|
@ -83,6 +83,10 @@ public sealed record EncounterStatic4(GameVersion Version)
|
|||
pk.Egg_Location = EggLocation;
|
||||
pk.EggMetDate = pk.MetDate;
|
||||
}
|
||||
else if (Species == (int)Core.Species.Giratina && Form == 1)
|
||||
{
|
||||
pk.HeldItem = 0112; // Griseous Orb
|
||||
}
|
||||
|
||||
SetPINGA(pk, criteria, pi);
|
||||
if (Moves.HasMoves)
|
||||
|
|
|
@ -105,6 +105,12 @@ public sealed record EncounterTrade4RanchGift
|
|||
HT_Gender = tr.Gender,
|
||||
};
|
||||
|
||||
if (EggLocation != 0)
|
||||
{
|
||||
pk.Egg_Location = EggLocation;
|
||||
pk.EggMetDate = pk.MetDate;
|
||||
}
|
||||
|
||||
if (Moves.HasMoves)
|
||||
pk.SetMoves(Moves);
|
||||
else
|
||||
|
|
|
@ -81,6 +81,7 @@ public sealed record EncounterStatic5N(uint PID)
|
|||
AbilityPermission.OnlySecond => pi.Ability2,
|
||||
_ => pi.AbilityH,
|
||||
},
|
||||
HiddenAbility = Ability == AbilityPermission.OnlyHidden,
|
||||
};
|
||||
|
||||
EncounterUtil1.SetEncounterMoves(pk, version, LevelMin);
|
||||
|
|
|
@ -76,6 +76,9 @@ public sealed record EncounterSlot6XY(EncounterArea6XY Parent, ushort Species, b
|
|||
else
|
||||
pk.SetDefaultRegionOrigins(lang);
|
||||
|
||||
if (IsRandomUnspecificForm && Form == EncounterUtil1.FormVivillon)
|
||||
pk.Form = Vivillon3DS.GetPattern(pk.Country, pk.Region);
|
||||
|
||||
SetPINGA(pk, criteria);
|
||||
EncounterUtil1.SetEncounterMoves(pk, Version, LevelMin);
|
||||
pk.SetRandomMemory6();
|
||||
|
@ -85,8 +88,11 @@ public sealed record EncounterSlot6XY(EncounterArea6XY Parent, ushort Species, b
|
|||
|
||||
private byte GetWildForm(byte form)
|
||||
{
|
||||
if (form != EncounterUtil1.FormRandom)
|
||||
if (form < EncounterUtil1.FormDynamic)
|
||||
return form;
|
||||
if (form == EncounterUtil1.FormVivillon)
|
||||
return 0; // rectify later
|
||||
|
||||
// flagged as totally random
|
||||
return (byte)Util.Rand.Next(PersonalTable.XY[Species].FormCount);
|
||||
}
|
||||
|
|
|
@ -107,6 +107,9 @@ public sealed record EncounterTrade7 : IEncounterable, IEncounterMatch, IFixedTr
|
|||
if (pk.IsShiny)
|
||||
pk.PID ^= 0x1000_0000;
|
||||
criteria.SetRandomIVs(pk, IVs);
|
||||
if (EvolveOnTrade)
|
||||
pk.Species++;
|
||||
|
||||
pk.RefreshAbility(criteria.GetAbilityFromNumber(Ability));
|
||||
pk.ResetPartyStats();
|
||||
|
||||
|
|
|
@ -137,12 +137,19 @@ public sealed record EncounterSlot8b(EncounterArea8b Parent, ushort Species, byt
|
|||
|
||||
// A/B/C tables, only Munchlax is a 'C' encounter, and A/B are accessible from any tree.
|
||||
// C table encounters are only available from 4 trees, which are determined by TID16/SID16 of the save file.
|
||||
if (Type is SlotType.HoneyTree && Species == (int)Core.Species.Munchlax && !Parent.IsMunchlaxTree(pk))
|
||||
if (IsInvalidMunchlaxTree(pk))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool IsInvalidMunchlaxTree(PKM pk)
|
||||
{
|
||||
if (Type is not SlotType.HoneyTree)
|
||||
return false;
|
||||
return Species == (int)Core.Species.Munchlax && !Parent.IsMunchlaxTree(pk);
|
||||
}
|
||||
|
||||
public EncounterMatchRating GetMatchRating(PKM pk)
|
||||
{
|
||||
bool isHidden = pk.AbilityNumber == 4;
|
||||
|
@ -175,5 +182,4 @@ public sealed record EncounterSlot8b(EncounterArea8b Parent, ushort Species, byt
|
|||
return baseEgg.Contains(move);
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
|
|
@ -102,6 +102,8 @@ public sealed record EncounterTrade9
|
|||
|
||||
EncounterUtil1.SetEncounterMoves(pk, version, Level);
|
||||
SetPINGA(pk, criteria, pi);
|
||||
if (EvolveOnTrade)
|
||||
pk.Species++;
|
||||
|
||||
pk.ResetPartyStats();
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace PKHeX.Core;
|
|||
/// https://projectpokemon.org/home/forums/topic/5870-pok%C3%A9mon-mystery-gift-editor-v143-now-with-bw-support/
|
||||
/// See also: http://tccphreak.shiny-clique.net/debugger/pcdfiles.htm
|
||||
/// </remarks>
|
||||
public sealed class PCD : DataMysteryGift, IRibbonSetEvent3, IRibbonSetEvent4, IRestrictVersion
|
||||
public sealed class PCD : DataMysteryGift, IRibbonSetEvent3, IRibbonSetEvent4, IRestrictVersion, IRandomCorrelation
|
||||
{
|
||||
public const int Size = 0x358; // 856
|
||||
public override int Generation => 4;
|
||||
|
@ -100,6 +100,9 @@ public sealed class PCD : DataMysteryGift, IRibbonSetEvent3, IRibbonSetEvent4, I
|
|||
public override int Location { get => IsEgg ? 0 : Gift.EggLocation + 3000; set { } }
|
||||
public override int EggLocation { get => IsEgg ? Gift.EggLocation + 3000 : 0; set { } }
|
||||
|
||||
public bool IsCompatible(PIDType val, PKM pk) => Gift.IsCompatible(val, pk);
|
||||
public PIDType GetSuggestedCorrelation() => Gift.GetSuggestedCorrelation();
|
||||
|
||||
public bool GiftEquals(PGT pgt)
|
||||
{
|
||||
// Skip over the PGT's "Corresponding PCD Slot" @ 0x02
|
||||
|
|
|
@ -196,6 +196,8 @@ public sealed class PGT : DataMysteryGift, IRibbonSetEvent3, IRibbonSetEvent4, I
|
|||
pk4.Language = lang;
|
||||
pk4.Egg_Location = 1; // Ranger (will be +3000 later)
|
||||
pk4.Nickname = SpeciesName.GetSpeciesNameGeneration((int)Core.Species.Manaphy, lang, 4);
|
||||
pk4.Met_Location = pk4.Version is (int)GameVersion.HG or (int)GameVersion.SS ? Locations.HatchLocationHGSS : Locations.HatchLocationDPPt;
|
||||
pk4.MetDate = EncounterDate.GetDateNDS();
|
||||
}
|
||||
|
||||
private void SetPINGA(PK4 pk4, EncounterCriteria criteria)
|
||||
|
@ -306,6 +308,8 @@ public sealed class PGT : DataMysteryGift, IRibbonSetEvent3, IRibbonSetEvent4, I
|
|||
{
|
||||
if (IsManaphyEgg)
|
||||
return IsG4ManaphyPIDValid(val, pk);
|
||||
if (PK.PID != 1 && val == PIDType.G5MGShiny)
|
||||
return true;
|
||||
return val == PIDType.None;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue