Set ability bit, precheck for encounter activation

This commit is contained in:
Kurt 2024-03-21 00:18:16 -05:00
parent f27326cb2e
commit 205e9b433d
6 changed files with 38 additions and 13 deletions

View file

@ -13,10 +13,17 @@ public static class GenerateMethodH
var gr = pi.Gender; var gr = pi.Gender;
var ability = criteria.GetAbilityFromNumber(AbilityPermission.Any12); var ability = criteria.GetAbilityFromNumber(AbilityPermission.Any12);
var (min, max) = SlotMethodH.GetRange(enc.Type, enc.SlotNumber); var (min, max) = SlotMethodH.GetRange(enc.Type, enc.SlotNumber);
bool checkProc = MethodH.IsEncounterCheckApplicable(enc.Type);
// Generate Method H correlated PID and IVs, no lead (keep things simple). // Generate Method H correlated PID and IVs, no lead (keep things simple).
while (true) while (true)
{ {
if (checkProc)
{
var check = new LeadSeed(seed, LeadRequired.None);
if (!MethodH.CheckEncounterActivation(enc, ref check))
continue;
}
var esv = LCRNG.Next16(ref seed) % 100; var esv = LCRNG.Next16(ref seed) % 100;
if (esv < min || esv > max) if (esv < min || esv > max)
continue; continue;
@ -116,6 +123,7 @@ public static class GenerateMethodH
pk.PID = pid; pk.PID = pid;
pk.IV32 = ((iv2 & 0x7FFF) << 15) | (iv1 & 0x7FFF); pk.IV32 = ((iv2 & 0x7FFF) << 15) | (iv1 & 0x7FFF);
pk.RefreshAbility((int)(pid & 1));
return true; return true;
} }
@ -142,6 +150,7 @@ public static class GenerateMethodH
pk.PID = pid; pk.PID = pid;
pk.IV32 = ((iv2 & 0x7FFF) << 15) | (iv1 & 0x7FFF); pk.IV32 = ((iv2 & 0x7FFF) << 15) | (iv1 & 0x7FFF);
pk.RefreshAbility((int)(pid & 1));
return true; return true;
} }
@ -221,6 +230,7 @@ public static class GenerateMethodH
var iv1 = LCRNG.Next16(ref rand); var iv1 = LCRNG.Next16(ref rand);
var iv2 = LCRNG.Next16(ref rand); var iv2 = LCRNG.Next16(ref rand);
pk.IV32 = ((iv2 & 0x7FFF) << 15) | (iv1 & 0x7FFF); pk.IV32 = ((iv2 & 0x7FFF) << 15) | (iv1 & 0x7FFF);
pk.RefreshAbility((int)(pid & 1));
} }
private static (uint iv1, uint iv2) GetCombinedIVs(EncounterCriteria criteria) private static (uint iv1, uint iv2) GetCombinedIVs(EncounterCriteria criteria)

View file

@ -202,7 +202,9 @@ public static class MethodH
return default; return default;
} }
private static bool CheckEncounterActivation<T>(T enc, ref LeadSeed result) public static bool IsEncounterCheckApplicable(SlotType3 type) => type is Rock_Smash; // Fishing can use Sticky/Suction along with Friendship boost.
public static bool CheckEncounterActivation<T>(T enc, ref LeadSeed result)
where T : IEncounterSlot3 where T : IEncounterSlot3
{ {
if (enc.Type is Rock_Smash) if (enc.Type is Rock_Smash)

View file

@ -23,10 +23,17 @@ public static class GenerateMethodJ
var ability = criteria.GetAbilityFromNumber(AbilityPermission.Any12); var ability = criteria.GetAbilityFromNumber(AbilityPermission.Any12);
var (min, max) = SlotMethodJ.GetRange(enc.Type, enc.SlotNumber); var (min, max) = SlotMethodJ.GetRange(enc.Type, enc.SlotNumber);
bool randLevel = MethodJ.IsLevelRand(enc); bool randLevel = MethodJ.IsLevelRand(enc);
bool checkProc = MethodJ.IsEncounterCheckApplicable(enc.Type);
// Generate Method J correlated PID and IVs, no lead (keep things simple). // Generate Method J correlated PID and IVs, no lead (keep things simple).
while (true) while (true)
{ {
if (checkProc)
{
var check = new LeadSeed(seed, LeadRequired.None);
if (!MethodJ.CheckEncounterActivation(enc, ref check))
continue;
}
var esv = LCRNG.Next16(ref seed) / 656; var esv = LCRNG.Next16(ref seed) / 656;
if (esv < min || esv > max) if (esv < min || esv > max)
continue; continue;
@ -55,7 +62,10 @@ public static class GenerateMethodJ
: ((lv % (enc.LevelMax - enc.LevelMin + 1)) + enc.LevelMin); : ((lv % (enc.LevelMax - enc.LevelMin + 1)) + enc.LevelMin);
pk.MetLevel = pk.CurrentLevel = (byte)lvl; pk.MetLevel = pk.CurrentLevel = (byte)lvl;
} }
SetPIDIVSequential(pk, pid, seed); pk.PID = pid;
var iv1 = LCRNG.Next16(ref seed);
var iv2 = LCRNG.Next16(ref seed);
pk.IV32 = ((iv2 & 0x7FFF) << 15) | (iv1 & 0x7FFF);
pk.Gender = gender; pk.Gender = gender;
pk.Ability = (pid & 1) == 0 ? pi.Ability1 : pi.Ability2; pk.Ability = (pid & 1) == 0 ? pi.Ability1 : pi.Ability2;
return LCRNG.Prev4(seed); return LCRNG.Prev4(seed);
@ -112,14 +122,6 @@ public static class GenerateMethodJ
public static uint GetPIDRegular(uint a, uint b) => b << 16 | a; public static uint GetPIDRegular(uint a, uint b) => b << 16 | a;
private static void SetPIDIVSequential(PK4 pk, uint pid, uint rand)
{
pk.PID = pid;
var iv1 = LCRNG.Next16(ref rand);
var iv2 = LCRNG.Next16(ref rand);
pk.IV32 = ((iv2 & 0x7FFF) << 15) | (iv1 & 0x7FFF);
}
private static (uint iv1, uint iv2) GetCombinedIVs(EncounterCriteria criteria) private static (uint iv1, uint iv2) GetCombinedIVs(EncounterCriteria criteria)
{ {
uint iv1 = (uint)criteria.IV_HP | (uint)criteria.IV_ATK << 5 | (uint)criteria.IV_DEF << 10; uint iv1 = (uint)criteria.IV_HP | (uint)criteria.IV_ATK << 5 | (uint)criteria.IV_DEF << 10;

View file

@ -24,10 +24,17 @@ public static class GenerateMethodK
var (min, max) = SlotMethodK.GetRange(enc.Type, enc.SlotNumber); var (min, max) = SlotMethodK.GetRange(enc.Type, enc.SlotNumber);
bool randLevel = MethodK.IsLevelRand(enc); bool randLevel = MethodK.IsLevelRand(enc);
var modulo = enc.Type.IsSafari() ? 10 : 100; var modulo = enc.Type.IsSafari() ? 10 : 100;
bool checkProc = MethodK.IsEncounterCheckApplicable(enc.Type);
// Generate Method K correlated PID and IVs, no lead (keep things simple). // Generate Method K correlated PID and IVs, no lead (keep things simple).
while (true) while (true)
{ {
if (checkProc)
{
var check = new LeadSeed(seed, LeadRequired.None);
if (!MethodK.CheckEncounterActivation(enc, ref check))
continue;
}
var esv = LCRNG.Next16(ref seed) % modulo; var esv = LCRNG.Next16(ref seed) % modulo;
if (esv < min || esv > max) if (esv < min || esv > max)
continue; continue;

View file

@ -93,7 +93,9 @@ public static class MethodJ
} }
} }
private static bool CheckEncounterActivation<T>(T enc, ref LeadSeed result) public static bool IsEncounterCheckApplicable(SlotType4 type) => type is HoneyTree || type.IsFishingRodType();
public static bool CheckEncounterActivation<T>(T enc, ref LeadSeed result)
where T : IEncounterSlot4 where T : IEncounterSlot4
{ {
if (enc.Type.IsFishingRodType()) if (enc.Type.IsFishingRodType())
@ -146,7 +148,7 @@ public static class MethodJ
// This occurs in Mt. Coronet B1F; if passed, check if the player is on a Feebas tile before replacing. // This occurs in Mt. Coronet B1F; if passed, check if the player is on a Feebas tile before replacing.
// 0 - Hook // 0 - Hook
// 1 - CheckTiles -- current seed // 1 - CheckTiles -- current seed
// 2- ESV // 2 - ESV
if (s4.Species is (int)Species.Feebas && !IsFeebasChance(result >> 16)) if (s4.Species is (int)Species.Feebas && !IsFeebasChance(result >> 16))
return false; return false;

View file

@ -90,7 +90,9 @@ public static class MethodK
} }
} }
private static bool CheckEncounterActivation<T>(T enc, ref LeadSeed result) public static bool IsEncounterCheckApplicable(SlotType4 type) => type is Rock_Smash or BugContest || type.IsFishingRodType();
public static bool CheckEncounterActivation<T>(T enc, ref LeadSeed result)
where T : IEncounterSlot4 where T : IEncounterSlot4
{ {
if (enc.Type.IsFishingRodType()) if (enc.Type.IsFishingRodType())