mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-08-26 08:14:08 -05:00
Gen3: encounter legality tweaks
Gen3-5: Egg (breeding) requesting shiny now loops to match criteria. Gen3: Add evolution nickname bypass for trash byte application Gen3: Fix japanese OT prefill check from not actually working Gen3: Add missing Voltorb encounter (was superseded by Wild slot, but aggressive checks since added).
This commit is contained in:
@@ -61,6 +61,7 @@ private static EncounterArea3[] GetSwarm([ConstantExpected] string resource, [Le
|
||||
// Stationary
|
||||
new(352, 30, RSE) { Location = 034 }, // Kecleon @ Route 119
|
||||
new(352, 30, RSE) { Location = 035 }, // Kecleon @ Route 120
|
||||
new(100, 25, RSE) { Location = 062 }, // Voltorb @ New Mauville
|
||||
|
||||
// Stationary Lengendary
|
||||
new(377, 40, RSE) { Location = 082 }, // Regirock @ Desert Ruins
|
||||
|
||||
@@ -79,14 +79,14 @@ public PK3 ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria)
|
||||
// Get a random PID that matches gender/nature/ability criteria
|
||||
var pi = PersonalTable.E[Species];
|
||||
var gr = pi.Gender;
|
||||
var pid = GetRandomPID(criteria, gr);
|
||||
var pid = GetRandomPID(criteria, gr, tr.ID32);
|
||||
pk.PID = pid;
|
||||
pk.RefreshAbility((int)(pid % 2));
|
||||
|
||||
return pk;
|
||||
}
|
||||
|
||||
private uint GetRandomPID(in EncounterCriteria criteria, byte gr)
|
||||
private uint GetRandomPID(in EncounterCriteria criteria, byte gr, uint id32)
|
||||
{
|
||||
var seed = Util.Rand32();
|
||||
while (true)
|
||||
@@ -109,6 +109,10 @@ private uint GetRandomPID(in EncounterCriteria criteria, byte gr)
|
||||
if (!Daycare3.IsValidProcPID(pid, Version))
|
||||
continue; // 0-value PID is invalid
|
||||
|
||||
var shiny = ShinyUtil.GetIsShiny3(id32, pid);
|
||||
if (criteria.Shiny.IsShiny() != shiny)
|
||||
continue;
|
||||
|
||||
return pid;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ public PK4 ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria)
|
||||
// Get a random PID that matches gender/nature/ability criteria
|
||||
var pi = PersonalTable.HGSS[Species];
|
||||
var gr = pi.Gender;
|
||||
var pid = GetRandomPID(criteria, gr, out var gender);
|
||||
var pid = GetRandomPID(criteria, gr, tr.ID32, out var gender);
|
||||
pk.PID = pid;
|
||||
pk.Gender = gender;
|
||||
pk.RefreshAbility((int)(pid & 1));
|
||||
@@ -92,7 +92,7 @@ public PK4 ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria)
|
||||
return pk;
|
||||
}
|
||||
|
||||
private uint GetRandomPID(in EncounterCriteria criteria, byte gr, out byte gender)
|
||||
private uint GetRandomPID(in EncounterCriteria criteria, byte gr, uint id32, out byte gender)
|
||||
{
|
||||
var seed = Util.Rand32();
|
||||
while (true)
|
||||
@@ -115,6 +115,10 @@ private uint GetRandomPID(in EncounterCriteria criteria, byte gr, out byte gende
|
||||
// PID is rolled forward upon picking up the egg.
|
||||
// Not worth skipping 0-value PIDs. Too rare to be worth trying again, since it can be a valid PID.
|
||||
|
||||
var shiny = ShinyUtil.GetIsShiny3(id32, pid);
|
||||
if (criteria.Shiny.IsShiny() != shiny)
|
||||
continue;
|
||||
|
||||
return pid;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ public PK5 ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria)
|
||||
var pi = PersonalTable.B2W2[Species];
|
||||
var gr = pi.Gender;
|
||||
var ability = criteria.GetAbilityFromNumber(Ability);
|
||||
var pid = GetRandomPID(criteria, gr, out var gender);
|
||||
var pid = GetRandomPID(criteria, gr, tr.ID32, out var gender);
|
||||
pid = (pid & 0xFFFEFFFFu) | (uint)(ability & 1) << 16; // 0x00000000 or 0x00010000
|
||||
pk.PID = pid;
|
||||
pk.Gender = gender;
|
||||
@@ -81,7 +81,7 @@ public PK5 ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria)
|
||||
return pk;
|
||||
}
|
||||
|
||||
private static uint GetRandomPID(in EncounterCriteria criteria, byte gr, out byte gender)
|
||||
private static uint GetRandomPID(in EncounterCriteria criteria, byte gr, uint id32, out byte gender)
|
||||
{
|
||||
var seed = Util.Rand32();
|
||||
while (true)
|
||||
@@ -91,6 +91,9 @@ private static uint GetRandomPID(in EncounterCriteria criteria, byte gr, out byt
|
||||
gender = EntityGender.GetFromPIDAndRatio(pid, gr);
|
||||
if (criteria.IsSpecifiedGender() && !criteria.IsSatisfiedGender(gender))
|
||||
continue;
|
||||
var shiny = ShinyUtil.GetIsShiny3(id32, pid);
|
||||
if (criteria.Shiny.IsShiny() != shiny)
|
||||
continue;
|
||||
return pid;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,7 +139,11 @@ private static void FlagIsNicknameClean(LegalityAnalysis data, PK3 pk)
|
||||
// International games are 10 chars (full buffer) max; implicit terminator if full.
|
||||
var nick = pk.GetNicknamePrefillRegion();
|
||||
if (!TrashByteRules3.IsTerminatedFF(nick))
|
||||
data.AddLine(GetInvalid(Trainer, TrashBytesMismatchInitial));
|
||||
{
|
||||
// Trade to another language and evolve will treat it like a nickname, without actually filling with FF.
|
||||
if (!TrashByteRules3.IsTerminatedFFZero(nick) || pk.Species == data.EncounterOriginal.Species) // not evolved
|
||||
data.AddLine(GetInvalid(Trainer, TrashBytesMismatchInitial));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,9 +196,15 @@ public static bool IsTerminatedFF(ReadOnlySpan<byte> data)
|
||||
var first = TrashBytes8.GetTerminatorIndex(data);
|
||||
if (first == -1 || first >= data.Length - 1)
|
||||
return true;
|
||||
return !data[(first + 1)..].ContainsAnyExcept<byte>(0xFF);
|
||||
return !data[(first + 1)..].ContainsAnyExcept(Terminator);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the <see cref="data"/> matches the pattern of a pre-filled array with terminators of count <see cref="preFill"/>.
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="preFill"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsTerminatedFFZero(ReadOnlySpan<byte> data, int preFill = 0)
|
||||
{
|
||||
if (preFill == 0)
|
||||
@@ -211,8 +221,7 @@ public static bool IsTerminatedFFZero(ReadOnlySpan<byte> data, int preFill = 0)
|
||||
if (inner.ContainsAnyExcept(Terminator))
|
||||
return false;
|
||||
first = preFill;
|
||||
first++;
|
||||
if (first >= data.Length - 1)
|
||||
if (first >= data.Length)
|
||||
return true;
|
||||
}
|
||||
return !data[first..].ContainsAnyExcept<byte>(0);
|
||||
|
||||
Reference in New Issue
Block a user