mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-05-23 09:56:07 -05:00
SlotNumber/MagnetStatic int->byte
more size reductions
This commit is contained in:
parent
ba9d3c95af
commit
462ef70ffb
|
|
@ -29,26 +29,22 @@ private EncounterArea1(ReadOnlySpan<byte> data, GameVersion game) : base(game)
|
|||
Type = (SlotType)data[2];
|
||||
Rate = data[3];
|
||||
|
||||
int count = (data.Length - 4) / 4;
|
||||
var next = data[4..];
|
||||
int count = next.Length / 4;
|
||||
var slots = new EncounterSlot1[count];
|
||||
for (int i = 0; i < slots.Length; i++)
|
||||
{
|
||||
int offset = 4 + (4 * i);
|
||||
var entry = data.Slice(offset, 4);
|
||||
slots[i] = ReadSlot(entry);
|
||||
const int size = 4;
|
||||
var entry = data.Slice(i * size, size);
|
||||
int max = entry[3];
|
||||
int min = entry[2];
|
||||
byte slotNum = entry[1];
|
||||
int species = entry[0];
|
||||
slots[i] = new EncounterSlot1(this, species, min, max, slotNum);
|
||||
}
|
||||
Slots = slots;
|
||||
}
|
||||
|
||||
private EncounterSlot1 ReadSlot(ReadOnlySpan<byte> entry)
|
||||
{
|
||||
int species = entry[0];
|
||||
int slotNum = entry[1];
|
||||
int min = entry[2];
|
||||
int max = entry[3];
|
||||
return new EncounterSlot1(this, species, min, max, slotNum);
|
||||
}
|
||||
|
||||
public override IEnumerable<EncounterSlot> GetMatchingSlots(PKM pkm, IReadOnlyList<EvoCriteria> chain)
|
||||
{
|
||||
int rate = pkm is PK1 pk1 ? pk1.Catch_Rate : -1;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ public sealed record EncounterArea2 : EncounterArea
|
|||
private static readonly byte[] RatesSurf = { 60, 30, 10 };
|
||||
|
||||
internal readonly EncounterTime Time;
|
||||
public readonly int Rate;
|
||||
public readonly byte Rate;
|
||||
public readonly IReadOnlyList<byte> Rates;
|
||||
public readonly EncounterSlot2[] Slots;
|
||||
|
||||
|
|
@ -33,61 +33,49 @@ private EncounterArea2(ReadOnlySpan<byte> data, GameVersion game) : base(game)
|
|||
Location = data[0];
|
||||
Time = (EncounterTime)data[1];
|
||||
var type = (Type = (SlotType)data[2]) & (SlotType)0xF;
|
||||
var rate = data[3];
|
||||
Rate = data[3];
|
||||
|
||||
var next = data[4..];
|
||||
if (type is > SlotType.Surf and not SlotType.BugContest) // Not Grass/Surf
|
||||
{
|
||||
const int size = 5;
|
||||
int count = (data.Length - 4) / size;
|
||||
|
||||
var rates = new byte[count];
|
||||
for (int i = 0; i < rates.Length; i++)
|
||||
rates[i] = data[4 + i];
|
||||
|
||||
Rates = rates;
|
||||
Slots = ReadSlots(data, count, 4 + count);
|
||||
int count = next.Length / size;
|
||||
Rates = next[..count].ToArray();
|
||||
Slots = ReadSlots(next[count..], count);
|
||||
}
|
||||
else
|
||||
{
|
||||
Rate = rate;
|
||||
|
||||
const int size = 4;
|
||||
int count = (data.Length - 4) / size;
|
||||
int count = next.Length / size;
|
||||
Rates = type switch
|
||||
{
|
||||
SlotType.BugContest => BCC_SlotRates,
|
||||
SlotType.Grass => RatesGrass,
|
||||
_ => RatesSurf,
|
||||
};
|
||||
Slots = ReadSlots(data, count, 4);
|
||||
Slots = ReadSlots(next, count);
|
||||
}
|
||||
}
|
||||
|
||||
private EncounterSlot2[] ReadSlots(ReadOnlySpan<byte> data, int count, int start)
|
||||
private EncounterSlot2[] ReadSlots(ReadOnlySpan<byte> data, int count)
|
||||
{
|
||||
const int size = 4;
|
||||
var slots = new EncounterSlot2[count];
|
||||
for (int i = 0; i < slots.Length; i++)
|
||||
{
|
||||
int offset = start + (4 * i);
|
||||
var entry = data.Slice(offset, 4);
|
||||
slots[i] = ReadSlot(entry);
|
||||
var entry = data.Slice(i * size, size);
|
||||
int max = entry[3];
|
||||
int min = entry[2];
|
||||
byte slotNum = entry[1];
|
||||
int species = entry[0];
|
||||
slots[i] = new EncounterSlot2(this, species, min, max, slotNum);
|
||||
}
|
||||
|
||||
return slots;
|
||||
}
|
||||
|
||||
private EncounterSlot2 ReadSlot(ReadOnlySpan<byte> entry)
|
||||
{
|
||||
int species = entry[0];
|
||||
int slotNum = entry[1];
|
||||
int min = entry[2];
|
||||
int max = entry[3];
|
||||
return new EncounterSlot2(this, species, min, max, slotNum);
|
||||
}
|
||||
|
||||
public override IEnumerable<EncounterSlot> GetMatchingSlots(PKM pkm, IReadOnlyList<EvoCriteria> chain)
|
||||
{
|
||||
if (pkm is not ICaughtData2 pk2 || pk2.CaughtData == 0)
|
||||
if (pkm is not ICaughtData2 {CaughtData: not 0} pk2)
|
||||
return GetSlotsFuzzy(chain);
|
||||
|
||||
if (pk2.Met_Location != Location)
|
||||
|
|
|
|||
|
|
@ -68,14 +68,14 @@ private EncounterSlot3 ReadRegularSlot(ReadOnlySpan<byte> entry)
|
|||
{
|
||||
int species = ReadUInt16LittleEndian(entry);
|
||||
int form = entry[2];
|
||||
int slotNum = entry[3];
|
||||
byte slotNum = entry[3];
|
||||
int min = entry[4];
|
||||
int max = entry[5];
|
||||
|
||||
int mpi = entry[6];
|
||||
int mpc = entry[7];
|
||||
int sti = entry[8];
|
||||
int stc = entry[9];
|
||||
byte mpi = entry[6];
|
||||
byte mpc = entry[7];
|
||||
byte sti = entry[8];
|
||||
byte stc = entry[9];
|
||||
return new EncounterSlot3(this, species, form, min, max, slotNum, mpi, mpc, sti, stc);
|
||||
}
|
||||
|
||||
|
|
@ -98,7 +98,7 @@ private EncounterSlot3Swarm ReadSwarmSlot(ReadOnlySpan<byte> entry)
|
|||
{
|
||||
int species = ReadUInt16LittleEndian(entry);
|
||||
// form always 0
|
||||
int slotNum = entry[3];
|
||||
byte slotNum = entry[3];
|
||||
int min = entry[4];
|
||||
int max = entry[5];
|
||||
|
||||
|
|
|
|||
|
|
@ -54,13 +54,13 @@ private EncounterSlot4 ReadRegularSlot(ReadOnlySpan<byte> entry)
|
|||
{
|
||||
int species = ReadUInt16LittleEndian(entry);
|
||||
int form = entry[2];
|
||||
int slotNum = entry[3];
|
||||
byte slotNum = entry[3];
|
||||
int min = entry[4];
|
||||
int max = entry[5];
|
||||
int mpi = entry[6];
|
||||
int mpc = entry[7];
|
||||
int sti = entry[8];
|
||||
int stc = entry[9];
|
||||
byte mpi = entry[6];
|
||||
byte mpc = entry[7];
|
||||
byte sti = entry[8];
|
||||
byte stc = entry[9];
|
||||
return new EncounterSlot4(this, species, form, min, max, slotNum, mpi, mpc, sti, stc);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,10 +7,10 @@
|
|||
public sealed record EncounterSlot1 : EncounterSlot, INumberedSlot
|
||||
{
|
||||
public override int Generation => 1;
|
||||
public int SlotNumber { get; }
|
||||
public byte SlotNumber { get; }
|
||||
public override Ball FixedBall => Ball.Poke;
|
||||
|
||||
public EncounterSlot1(EncounterArea1 area, int species, int min, int max, int slot) : base(area, species, 0, min, max)
|
||||
public EncounterSlot1(EncounterArea1 area, int species, int min, int max, byte slot) : base(area, species, 0, min, max)
|
||||
{
|
||||
SlotNumber = slot;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,10 +12,10 @@ namespace PKHeX.Core
|
|||
public sealed record EncounterSlot2 : EncounterSlot, INumberedSlot
|
||||
{
|
||||
public override int Generation => 2;
|
||||
public int SlotNumber { get; }
|
||||
public byte SlotNumber { get; }
|
||||
public override Ball FixedBall => Ball.Poke;
|
||||
|
||||
public EncounterSlot2(EncounterArea2 area, int species, int min, int max, int slot) : base(area, species, species == 201 ? FormRandom : 0, min, max)
|
||||
public EncounterSlot2(EncounterArea2 area, int species, int min, int max, byte slot) : base(area, species, species == 201 ? FormRandom : 0, min, max)
|
||||
{
|
||||
SlotNumber = slot;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,16 +8,16 @@ public record EncounterSlot3 : EncounterSlot, IMagnetStatic, INumberedSlot, ISlo
|
|||
{
|
||||
public sealed override int Generation => 3;
|
||||
|
||||
public int StaticIndex { get; }
|
||||
public int MagnetPullIndex { get; }
|
||||
public int StaticCount { get; }
|
||||
public int MagnetPullCount { get; }
|
||||
public byte StaticIndex { get; }
|
||||
public byte MagnetPullIndex { get; }
|
||||
public byte StaticCount { get; }
|
||||
public byte MagnetPullCount { get; }
|
||||
public SlotType Type => Area.Type;
|
||||
|
||||
public int SlotNumber { get; }
|
||||
public byte SlotNumber { get; }
|
||||
public override Ball FixedBall => Locations.IsSafariZoneLocation3(Location) ? Ball.Safari : Ball.None;
|
||||
|
||||
public EncounterSlot3(EncounterArea3 area, int species, int form, int min, int max, int slot, int mpi, int mpc, int sti, int stc) : base(area, species, form, min, max)
|
||||
public EncounterSlot3(EncounterArea3 area, int species, int form, int min, int max, byte slot, byte mpi, byte mpc, byte sti, byte stc) : base(area, species, form, min, max)
|
||||
{
|
||||
SlotNumber = slot;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ public sealed record EncounterSlot3PokeSpot : EncounterSlot, INumberedSlot
|
|||
{
|
||||
public override int Generation => 3;
|
||||
|
||||
public int SlotNumber { get; }
|
||||
public byte SlotNumber { get; }
|
||||
|
||||
public EncounterSlot3PokeSpot(EncounterArea3XD area, int species, int min, int max, int slot) : base(area, species, 0, min, max)
|
||||
public EncounterSlot3PokeSpot(EncounterArea3XD area, int species, int min, int max, byte slot) : base(area, species, 0, min, max)
|
||||
{
|
||||
SlotNumber = slot;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ internal sealed record EncounterSlot3Swarm : EncounterSlot3, IMoveset
|
|||
{
|
||||
public IReadOnlyList<int> Moves { get; }
|
||||
|
||||
public EncounterSlot3Swarm(EncounterArea3 area, int species, int min, int max, int slot,
|
||||
public EncounterSlot3Swarm(EncounterArea3 area, int species, int min, int max, byte slot,
|
||||
IReadOnlyList<int> moves) : base(area, species, 0, min, max, slot, 0, 0, 0, 0) => Moves = moves;
|
||||
|
||||
protected override void SetEncounterMoves(PKM pk, GameVersion version, int level)
|
||||
|
|
|
|||
|
|
@ -9,17 +9,17 @@ public sealed record EncounterSlot4 : EncounterSlot, IMagnetStatic, INumberedSlo
|
|||
public override int Generation => 4;
|
||||
public GroundTilePermission GroundTile => ((EncounterArea4)Area).GroundTile;
|
||||
|
||||
public int StaticIndex { get; }
|
||||
public int MagnetPullIndex { get; }
|
||||
public int StaticCount { get; }
|
||||
public int MagnetPullCount { get; }
|
||||
public byte StaticIndex { get; }
|
||||
public byte MagnetPullIndex { get; }
|
||||
public byte StaticCount { get; }
|
||||
public byte MagnetPullCount { get; }
|
||||
public SlotType Type => Area.Type;
|
||||
|
||||
public int SlotNumber { get; }
|
||||
public byte SlotNumber { get; }
|
||||
public override Ball FixedBall => GetRequiredBallValue();
|
||||
public bool CanUseRadar => !GameVersion.HGSS.Contains(Version) && GroundTile.HasFlag(GroundTilePermission.Grass);
|
||||
|
||||
public EncounterSlot4(EncounterArea4 area, int species, int form, int min, int max, int slot, int mpi, int mpc, int sti, int stc) : base(area, species, form, min, max)
|
||||
public EncounterSlot4(EncounterArea4 area, int species, int form, int min, int max, byte slot, byte mpi, byte mpc, byte sti, byte stc) : base(area, species, form, min, max)
|
||||
{
|
||||
SlotNumber = slot;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,29 +1,32 @@
|
|||
namespace PKHeX.Core
|
||||
namespace PKHeX.Core;
|
||||
|
||||
/// <summary>
|
||||
/// Contains information about the RNG restrictions for the slot, and any mutated RNG values.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// When encountering a Wild Pokémon with a lead that has an ability of <see cref="Ability.Static"/> or <see cref="Ability.MagnetPull"/>,
|
||||
/// the game picks encounters from the <seealso cref="EncounterArea"/> that match the type.
|
||||
/// The values in this interface change the <seealso cref="INumberedSlot"/> to allow different values for slot yielding.
|
||||
/// </remarks>
|
||||
public interface IMagnetStatic
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains information about the RNG restrictions for the slot, and any mutated RNG values.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// When encountering a Wild Pokémon with a lead that has an ability of <see cref="Ability.Static"/> or <see cref="Ability.MagnetPull"/>,
|
||||
/// the game picks encounters from the <seealso cref="EncounterArea"/> that match the type.
|
||||
/// The values in this interface change the <seealso cref="INumberedSlot"/> to allow different values for slot yielding.
|
||||
/// </remarks>
|
||||
public interface IMagnetStatic
|
||||
{
|
||||
/// <summary> <see cref="INumberedSlot.SlotNumber"/> if the lead is <see cref="Ability.Static"/> </summary>
|
||||
int StaticIndex { get; }
|
||||
/// <summary> <see cref="INumberedSlot.SlotNumber"/> if the lead is <see cref="Ability.MagnetPull"/> </summary>
|
||||
int MagnetPullIndex { get; }
|
||||
/// <summary> <see cref="INumberedSlot.SlotNumber"/> if the lead is <see cref="Ability.Static"/> </summary>
|
||||
byte StaticIndex { get; }
|
||||
/// <summary> <see cref="INumberedSlot.SlotNumber"/> if the lead is <see cref="Ability.MagnetPull"/> </summary>
|
||||
byte MagnetPullIndex { get; }
|
||||
|
||||
/// <summary> Count of slots in the parent area that can be yielded by <see cref="Ability.Static"/> </summary>
|
||||
int StaticCount { get; }
|
||||
/// <summary> Count of slots in the parent area that can be yielded by <see cref="Ability.MagnetPull"/> </summary>
|
||||
int MagnetPullCount { get; }
|
||||
}
|
||||
|
||||
public static class MagnetStaticExtensions
|
||||
{
|
||||
public static bool IsMatchStatic(this IMagnetStatic slot, int index, int count) => index == slot.StaticIndex && count == slot.StaticCount;
|
||||
public static bool IsMatchMagnet(this IMagnetStatic slot, int index, int count) => index == slot.MagnetPullIndex && count == slot.MagnetPullCount;
|
||||
}
|
||||
/// <summary> Count of slots in the parent area that can be yielded by <see cref="Ability.Static"/> </summary>
|
||||
byte StaticCount { get; }
|
||||
/// <summary> Count of slots in the parent area that can be yielded by <see cref="Ability.MagnetPull"/> </summary>
|
||||
byte MagnetPullCount { get; }
|
||||
}
|
||||
|
||||
public static class MagnetStaticExtensions
|
||||
{
|
||||
private const byte NotMagnetStaticSlot = byte.MaxValue;
|
||||
public static bool IsStaticSlot(this IMagnetStatic slot) => slot.StaticCount != 0 && slot.StaticIndex != NotMagnetStaticSlot;
|
||||
public static bool IsMagnetSlot(this IMagnetStatic slot) => slot.MagnetPullCount != 0 && slot.MagnetPullIndex != NotMagnetStaticSlot;
|
||||
|
||||
public static bool IsMatchStatic(this IMagnetStatic slot, int index, int count) => index == slot.StaticIndex && count == slot.StaticCount;
|
||||
public static bool IsMatchMagnet(this IMagnetStatic slot, int index, int count) => index == slot.MagnetPullIndex && count == slot.MagnetPullCount;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,15 @@
|
|||
namespace PKHeX.Core
|
||||
namespace PKHeX.Core;
|
||||
|
||||
/// <summary>
|
||||
/// <seealso cref="EncounterSlot"/> that contains information about what Index it is within the <seealso cref="EncounterArea"/>'s type-group of slots.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Useful for checking legality (if the RNG can yield this slot).
|
||||
/// </remarks>
|
||||
public interface INumberedSlot
|
||||
{
|
||||
/// <summary>
|
||||
/// <seealso cref="EncounterSlot"/> that contains information about what Index it is within the <seealso cref="EncounterArea"/>'s type-group of slots.
|
||||
/// Number Index of the <seealso cref="EncounterSlot"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Useful for checking legality (if the RNG can yield this slot).
|
||||
/// </remarks>
|
||||
public interface INumberedSlot
|
||||
{
|
||||
/// <summary>
|
||||
/// Number Index of the <seealso cref="EncounterSlot"/>.
|
||||
/// </summary>
|
||||
int SlotNumber { get; }
|
||||
}
|
||||
byte SlotNumber { get; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ namespace PKHeX.Core
|
|||
/// Generation 2 Time of Encounter enum
|
||||
/// </summary>
|
||||
[Flags]
|
||||
internal enum EncounterTime
|
||||
internal enum EncounterTime : byte
|
||||
{
|
||||
Any = 0,
|
||||
Morning = 1 << 1,
|
||||
|
|
@ -29,4 +29,4 @@ internal static int RandomValidTime(this EncounterTime t1)
|
|||
return val;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -168,13 +168,13 @@ public static int GetLevel(EncounterSlot slot, LeadRequired lead, uint lvlrand)
|
|||
/// <returns>Slot number from the slot data if the slot is selected on this frame, else an invalid slot value.</returns>
|
||||
internal static int GetSlotStaticMagnet<T>(T slot, uint esv) where T : EncounterSlot, IMagnetStatic, INumberedSlot
|
||||
{
|
||||
if (slot.StaticCount > 0 && slot.StaticIndex >= 0)
|
||||
if (slot.IsStaticSlot())
|
||||
{
|
||||
var index = esv % slot.StaticCount;
|
||||
if (index == slot.StaticIndex)
|
||||
return slot.SlotNumber;
|
||||
}
|
||||
if (slot.MagnetPullCount > 0 && slot.MagnetPullIndex >= 0)
|
||||
if (slot.IsMagnetSlot())
|
||||
{
|
||||
var index = esv % slot.MagnetPullCount;
|
||||
if (index == slot.MagnetPullIndex)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user