Rework encounterslot location fetch

store ref to area instead of location, useful for fetching sibling slots
from the parent.
This commit is contained in:
Kurt 2017-11-25 18:16:50 -08:00
parent 690cbaae79
commit 2be84b6005
12 changed files with 104 additions and 90 deletions

View file

@ -79,8 +79,8 @@ namespace PKHeX.Core
/// <param name="t">Personal data for use with a given species' type</param> /// <param name="t">Personal data for use with a given species' type</param>
internal static void MarkEncountersStaticMagnetPull(ref EncounterArea[] Areas, PersonalTable t) internal static void MarkEncountersStaticMagnetPull(ref EncounterArea[] Areas, PersonalTable t)
{ {
const int steel = 8; const int steel = (int)MoveType.Steel;
const int electric = 12; const int electric = (int)MoveType.Electric;
foreach (EncounterArea Area in Areas) foreach (EncounterArea Area in Areas)
{ {
var s = new List<EncounterSlot>(); // Static var s = new List<EncounterSlot>(); // Static
@ -158,16 +158,18 @@ namespace PKHeX.Core
}).ToArray(); }).ToArray();
} }
/// <summary> internal static T[] ConcatAll<T>(params T[][] arr) => arr.SelectMany(z => z).ToArray();
/// Sets the <see cref="EncounterArea.Location"/> to the <see cref="EncounterSlot.Location"/> for identifying where the slot is encountered.
/// </summary> internal static void MarkEncounterAreaArray(params EncounterArea[][] areas)
/// <remarks>Some games / transferred <see cref="PKM"/> data do not contain original encounter location IDs; is mainly for info purposes.</remarks>
/// <param name="Areas">Ingame encounter data</param>
internal static void MarkSlotLocation(ref EncounterArea[] Areas)
{ {
foreach (EncounterArea Area in Areas) foreach (var area in areas)
foreach (EncounterSlot Slot in Area.Slots) MarkEncounterAreas(area);
Slot.Location = Area.Location; }
internal static void MarkEncounterAreas(params EncounterArea[] areas)
{
foreach (var area in areas)
foreach (var slot in area.Slots)
slot.Area = area;
} }
} }
} }

View file

@ -38,6 +38,9 @@ namespace PKHeX.Core
Array.Resize(ref table, table.Length + 1); Array.Resize(ref table, table.Length + 1);
table[table.Length - 1] = FishOldGood_RBY; table[table.Length - 1] = FishOldGood_RBY;
foreach (var arr in table)
foreach (var slot in arr.Slots)
slot.Area = arr;
return table; return table;
} }

View file

@ -20,6 +20,7 @@ namespace PKHeX.Core
SlotsGS = GetTables2(GameVersion.GS); SlotsGS = GetTables2(GameVersion.GS);
SlotsC = GetTables2(GameVersion.C); SlotsC = GetTables2(GameVersion.C);
SlotsGSC = GetTables2(GameVersion.GSC); SlotsGSC = GetTables2(GameVersion.GSC);
MarkEncounterAreaArray(SlotsGS, SlotsC, SlotsGSC, EncounterSafari_GSC, EncounterBCC_GSC);
ReduceAreasSize(ref SlotsGS); ReduceAreasSize(ref SlotsGS);
ReduceAreasSize(ref SlotsC); ReduceAreasSize(ref SlotsC);
ReduceAreasSize(ref SlotsGSC); ReduceAreasSize(ref SlotsGSC);
@ -83,7 +84,6 @@ namespace PKHeX.Core
MarkEncountersVersion(h_c, GameVersion.C); MarkEncountersVersion(h_c, GameVersion.C);
var extra = AddExtraTableSlots(c, h_c, f, bcc_c, safari_c); var extra = AddExtraTableSlots(c, h_c, f, bcc_c, safari_c);
MarkSlotLocation(ref extra);
return extra; return extra;
} }

View file

@ -33,6 +33,8 @@ namespace PKHeX.Core
var FR_Slots = get("fr", "fr"); var FR_Slots = get("fr", "fr");
var LG_Slots = get("lg", "lg"); var LG_Slots = get("lg", "lg");
MarkEncounterAreaArray(SlotsRSEAlt, SlotsFRLGAlt);
ReduceAreasSize(ref R_Slots); ReduceAreasSize(ref R_Slots);
ReduceAreasSize(ref S_Slots); ReduceAreasSize(ref S_Slots);
ReduceAreasSize(ref E_Slots); ReduceAreasSize(ref E_Slots);
@ -56,12 +58,6 @@ namespace PKHeX.Core
SlotsE = AddExtraTableSlots(E_Slots, SlotsRSEAlt); SlotsE = AddExtraTableSlots(E_Slots, SlotsRSEAlt);
SlotsFR = AddExtraTableSlots(FR_Slots, SlotsFRLGAlt); SlotsFR = AddExtraTableSlots(FR_Slots, SlotsFRLGAlt);
SlotsLG = AddExtraTableSlots(LG_Slots, SlotsFRLGAlt); SlotsLG = AddExtraTableSlots(LG_Slots, SlotsFRLGAlt);
MarkSlotLocation(ref SlotsR);
MarkSlotLocation(ref SlotsS);
MarkSlotLocation(ref SlotsE);
MarkSlotLocation(ref SlotsFR);
MarkSlotLocation(ref SlotsLG);
} }
private static void MarkG3Slots_FRLG(ref EncounterArea[] Areas) private static void MarkG3Slots_FRLG(ref EncounterArea[] Areas)

View file

@ -67,6 +67,10 @@ namespace PKHeX.Core
MarkG4SlotsGreatMarsh(ref P_Slots, 52); MarkG4SlotsGreatMarsh(ref P_Slots, 52);
MarkG4SlotsGreatMarsh(ref Pt_Slots, 52); MarkG4SlotsGreatMarsh(ref Pt_Slots, 52);
MarkEncounterAreaArray(D_HoneyTrees_Slots, P_HoneyTrees_Slots, Pt_HoneyTrees_Slots,
DP_GreatMarshAlt, Pt_GreatMarshAlt, DPPt_Unown, DP_Trophy, DP_Feebas, Pt_Trophy, Pt_Feebas,
HG_Headbutt_Slots, SS_Headbutt_Slots, SlotsHGSSAlt);
SlotsD = AddExtraTableSlots(D_Slots, D_HoneyTrees_Slots, DP_GreatMarshAlt, DPPt_Unown, DP_Trophy, DP_Feebas); SlotsD = AddExtraTableSlots(D_Slots, D_HoneyTrees_Slots, DP_GreatMarshAlt, DPPt_Unown, DP_Trophy, DP_Feebas);
SlotsP = AddExtraTableSlots(P_Slots, P_HoneyTrees_Slots, DP_GreatMarshAlt, DPPt_Unown, DP_Trophy, DP_Feebas); SlotsP = AddExtraTableSlots(P_Slots, P_HoneyTrees_Slots, DP_GreatMarshAlt, DPPt_Unown, DP_Trophy, DP_Feebas);
SlotsPt = AddExtraTableSlots(Pt_Slots, Pt_HoneyTrees_Slots, Pt_GreatMarshAlt, DPPt_Unown, Pt_Trophy, Pt_Feebas); SlotsPt = AddExtraTableSlots(Pt_Slots, Pt_HoneyTrees_Slots, Pt_GreatMarshAlt, DPPt_Unown, Pt_Trophy, Pt_Feebas);
@ -78,12 +82,6 @@ namespace PKHeX.Core
MarkDPPtEncounterTypeSlots(ref SlotsPt); MarkDPPtEncounterTypeSlots(ref SlotsPt);
MarkHGSSEncounterTypeSlots(ref SlotsHG); MarkHGSSEncounterTypeSlots(ref SlotsHG);
MarkHGSSEncounterTypeSlots(ref SlotsSS); MarkHGSSEncounterTypeSlots(ref SlotsSS);
MarkSlotLocation(ref SlotsD);
MarkSlotLocation(ref SlotsP);
MarkSlotLocation(ref SlotsPt);
MarkSlotLocation(ref SlotsHG);
MarkSlotLocation(ref SlotsSS);
} }
private static EncounterArea[] GetFeebasArea(EncounterArea template) private static EncounterArea[] GetFeebasArea(EncounterArea template)
@ -180,12 +178,8 @@ namespace PKHeX.Core
private static void MarkG4AltFormSlots(ref EncounterArea[] Areas, int Species, int form, int[] Locations) private static void MarkG4AltFormSlots(ref EncounterArea[] Areas, int Species, int form, int[] Locations)
{ {
foreach (EncounterArea Area in Areas.Where(a => Locations.Contains(a.Location))) foreach (EncounterArea Area in Areas.Where(a => Locations.Contains(a.Location)))
{ foreach (EncounterSlot Slot in Area.Slots.Where(s => s.Species == Species))
foreach (EncounterSlot Slot in Area.Slots.Where(s => s.Species == Species)) Slot.Form = form;
{
Slot.Form = form;
}
}
} }
private static EncounterType GetEncounterTypeBySlotDPPt(SlotType Type, EncounterType GrassType) private static EncounterType GetEncounterTypeBySlotDPPt(SlotType Type, EncounterType GrassType)
{ {
@ -1380,7 +1374,6 @@ namespace PKHeX.Core
new EncounterSlot { Species = 418, LevelMin = 44, LevelMax = 45, Type = SlotType.Grass_Safari }, // Buizel new EncounterSlot { Species = 418, LevelMin = 44, LevelMax = 45, Type = SlotType.Grass_Safari }, // Buizel
}; };
private static EncounterSlot[] ConcatAll(params EncounterSlot[][] arr) => arr.SelectMany(z => z).ToArray();
private static readonly EncounterArea SlotsHGSS_SafariZone = new EncounterArea private static readonly EncounterArea SlotsHGSS_SafariZone = new EncounterArea
{ {
// Source http://bulbapedia.bulbagarden.net/wiki/Johto_Safari_Zone#Pok.C3.A9mon // Source http://bulbapedia.bulbagarden.net/wiki/Johto_Safari_Zone#Pok.C3.A9mon

View file

@ -37,6 +37,7 @@ namespace PKHeX.Core
MarkB2W2SwarmSlots(SlotsW2_Swarm); MarkB2W2SwarmSlots(SlotsW2_Swarm);
MarkG5HiddenGrottoSlots(SlotsB2_HiddenGrotto); MarkG5HiddenGrottoSlots(SlotsB2_HiddenGrotto);
MarkG5HiddenGrottoSlots(SlotsW2_HiddenGrotto); MarkG5HiddenGrottoSlots(SlotsW2_HiddenGrotto);
MarkEncounterAreaArray(SlotsB_Swarm, SlotsW_Swarm, SlotsB2_Swarm, SlotsW2_Swarm, SlotsB2_HiddenGrotto, SlotsW2_HiddenGrotto);
SlotsB = AddExtraTableSlots(BSlots, SlotsB_Swarm); SlotsB = AddExtraTableSlots(BSlots, SlotsB_Swarm);
SlotsW = AddExtraTableSlots(WSlots, SlotsW_Swarm, WhiteForestSlot); SlotsW = AddExtraTableSlots(WSlots, SlotsW_Swarm, WhiteForestSlot);

View file

@ -21,6 +21,7 @@ namespace PKHeX.Core
var YSlots = GetEncounterTables(GameVersion.Y); var YSlots = GetEncounterTables(GameVersion.Y);
MarkG6XYSlots(ref XSlots); MarkG6XYSlots(ref XSlots);
MarkG6XYSlots(ref YSlots); MarkG6XYSlots(ref YSlots);
MarkEncounterAreaArray(SlotsXYAlt);
SlotsX = AddExtraTableSlots(XSlots, SlotsXYAlt); SlotsX = AddExtraTableSlots(XSlots, SlotsXYAlt);
SlotsY = AddExtraTableSlots(YSlots, SlotsXYAlt); SlotsY = AddExtraTableSlots(YSlots, SlotsXYAlt);

View file

@ -39,6 +39,7 @@ namespace PKHeX.Core
MarkG7SMSlots(ref SOS_UM); MarkG7SMSlots(ref SOS_UM);
SlotsUS = AddExtraTableSlots(REG_US, SOS_US, Encounter_Pelago_UU, Encounter_Pelago_US); SlotsUS = AddExtraTableSlots(REG_US, SOS_US, Encounter_Pelago_UU, Encounter_Pelago_US);
SlotsUM = AddExtraTableSlots(REG_UM, SOS_UM, Encounter_Pelago_UU, Encounter_Pelago_UM); SlotsUM = AddExtraTableSlots(REG_UM, SOS_UM, Encounter_Pelago_UU, Encounter_Pelago_UM);
MarkEncounterAreaArray(SOS_SN, SOS_MN, SOS_US, SOS_UM, Encounter_Pelago_SN, Encounter_Pelago_MN, Encounter_Pelago_US, Encounter_Pelago_UM);
} }
private static void MarkG7REGSlots(ref EncounterArea[] Areas) private static void MarkG7REGSlots(ref EncounterArea[] Areas)
{ {

View file

@ -39,20 +39,23 @@ namespace PKHeX.Core
LevelMax = data[5 + i * 4], LevelMax = data[5 + i * 4],
}; };
} }
foreach (var slot in Slots)
slot.Area = this;
} }
public EncounterArea Clone(int location) public EncounterArea Clone(int location)
{ {
EncounterArea Areas = new EncounterArea EncounterArea Area = new EncounterArea
{ {
Location = location, Location = location,
Slots = new EncounterSlot[Slots.Length] Slots = new EncounterSlot[Slots.Length]
}; };
for (int i = 0; i < Slots.Length; i++) for (int i = 0; i < Slots.Length; i++)
{ {
Areas.Slots[i] = Slots[i].Clone(); Area.Slots[i] = Slots[i].Clone();
Area.Slots[i].Area = Area;
} }
return Areas; return Area;
} }
public EncounterArea[] Clone(int[] locations) public EncounterArea[] Clone(int[] locations)
@ -162,11 +165,16 @@ namespace PKHeX.Core
var areas = new List<EncounterArea>(); var areas = new List<EncounterArea>();
while (data[ofs] != 0xFF) // end while (data[ofs] != 0xFF) // end
{ {
areas.Add(new EncounterArea var location = data[ofs++] << 8 | data[ofs++];
var slots = GetSlots2_GW(data, ref ofs, t, slotSets, slotCount);
var area = new EncounterArea
{ {
Location = data[ofs++] << 8 | data[ofs++], Location = location,
Slots = GetSlots2_GW(data, ref ofs, t, slotSets, slotCount), Slots = slots,
}); };
foreach (var slot in slots)
slot.Area = area;
areas.Add(area);
} }
ofs++; ofs++;
return areas; return areas;
@ -450,12 +458,6 @@ namespace PKHeX.Core
private static EncounterArea GetArea3(byte[] data) private static EncounterArea GetArea3(byte[] data)
{ {
EncounterArea Area3 = new EncounterArea();
if (data.Length < 6)
{ Area3.Location = 0; Area3.Slots = new EncounterSlot[0]; return Area3; }
Area3.Location = data[0];
var HaveGrassSlots = data[1] == 1; var HaveGrassSlots = data[1] == 1;
var HaveSurfSlots = data[2] == 1; var HaveSurfSlots = data[2] == 1;
var HaveRockSmashSlots = data[3] == 1; var HaveRockSmashSlots = data[3] == 1;
@ -471,18 +473,21 @@ namespace PKHeX.Core
slots.AddRange(GetSlots3(data, ref offset, 5, SlotType.Rock_Smash)); slots.AddRange(GetSlots3(data, ref offset, 5, SlotType.Rock_Smash));
if (HaveFishingSlots) if (HaveFishingSlots)
slots.AddRange(GetSlots3_F(data, ref offset, 10)); slots.AddRange(GetSlots3_F(data, ref offset, 10));
Area3.Slots = slots.ToArray();
EncounterArea Area3 = new EncounterArea
{
Location = data[0],
Slots = slots.ToArray()
};
foreach (var slot in Area3.Slots)
slot.Area = Area3;
return Area3; return Area3;
} }
private static EncounterArea GetArea4DPPt(byte[] data) private static EncounterArea GetArea4DPPt(byte[] data)
{ {
EncounterArea Area4 = new EncounterArea();
if (data.Length != 0x1AA) // 426 Bytes
{ Area4.Location = 0; Area4.Slots = new EncounterSlot[0]; return Area4; }
var Slots = new List<EncounterSlot>(); var Slots = new List<EncounterSlot>();
Area4.Location = BitConverter.ToUInt16(data, 0x00);
var GrassRatio = BitConverter.ToInt32(data, 0x02); var GrassRatio = BitConverter.ToInt32(data, 0x02);
if (GrassRatio > 0) if (GrassRatio > 0)
@ -524,18 +529,20 @@ namespace PKHeX.Core
if (SuperRodRatio > 0) if (SuperRodRatio > 0)
Slots.AddRange(GetSlots4DPPt_WFR(data, 0x182, 5, SlotType.Super_Rod)); Slots.AddRange(GetSlots4DPPt_WFR(data, 0x182, 5, SlotType.Super_Rod));
Area4.Slots = Slots.ToArray(); EncounterArea Area4 = new EncounterArea
{
Location = BitConverter.ToUInt16(data, 0x00),
Slots = Slots.ToArray()
};
foreach (var slot in Area4.Slots)
slot.Area = Area4;
return Area4; return Area4;
} }
private static EncounterArea GetArea4HGSS(byte[] data) private static EncounterArea GetArea4HGSS(byte[] data)
{ {
EncounterArea Area4 = new EncounterArea();
if (data.Length != 0xC6)
{ Area4.Location = 0; Area4.Slots = new EncounterSlot[0]; return Area4; }
var Slots = new List<EncounterSlot>(); var Slots = new List<EncounterSlot>();
Area4.Location = BitConverter.ToUInt16(data, 0x00);
var GrassRatio = data[0x02]; var GrassRatio = data[0x02];
var SurfRatio = data[0x03]; var SurfRatio = data[0x03];
@ -577,7 +584,13 @@ namespace PKHeX.Core
if (data[0xC2] == 120) // Location = 182, 127, 130, 132, 167, 188, 210 if (data[0xC2] == 120) // Location = 182, 127, 130, 132, 167, 188, 210
Slots.AddRange(SlotsHGSS_Staryu); Slots.AddRange(SlotsHGSS_Staryu);
Area4.Slots = Slots.ToArray(); EncounterArea Area4 = new EncounterArea
{
Location = BitConverter.ToUInt16(data, 0x00),
Slots = Slots.ToArray()
};
foreach (var slot in Area4.Slots)
slot.Area = Area4;
return Area4; return Area4;
} }
private static readonly EncounterSlot[] SlotsHGSS_Staryu = private static readonly EncounterSlot[] SlotsHGSS_Staryu =
@ -611,11 +624,14 @@ namespace PKHeX.Core
}); });
} }
return new EncounterArea var Area = new EncounterArea
{ {
Location = BitConverter.ToUInt16(data, 0), Location = BitConverter.ToUInt16(data, 0),
Slots = Slots.ToArray() Slots = Slots.ToArray()
}; };
foreach (var slot in Area.Slots)
slot.Area = Area;
return Area;
} }
/// <summary> /// <summary>
@ -849,7 +865,7 @@ namespace PKHeX.Core
/// <returns>Array of encounter areas.</returns> /// <returns>Array of encounter areas.</returns>
public static EncounterArea[] GetArray4DPPt(byte[][] entries) public static EncounterArea[] GetArray4DPPt(byte[][] entries)
{ {
return entries?.Select(GetArea4DPPt).Where(Area => Area.Slots.Any()).ToArray(); return entries?.Select(GetArea4DPPt).Where(Area => Area.Slots.Length != 0).ToArray();
} }
/// <summary> /// <summary>
@ -859,7 +875,7 @@ namespace PKHeX.Core
/// <returns>Array of encounter areas.</returns> /// <returns>Array of encounter areas.</returns>
public static EncounterArea[] GetArray4HGSS(byte[][] entries) public static EncounterArea[] GetArray4HGSS(byte[][] entries)
{ {
return entries?.Select(GetArea4HGSS).Where(Area => Area.Slots.Any()).ToArray(); return entries?.Select(GetArea4HGSS).Where(Area => Area.Slots.Length != 0).ToArray();
} }
/// <summary> /// <summary>
@ -869,7 +885,7 @@ namespace PKHeX.Core
/// <returns>Array of encounter areas.</returns> /// <returns>Array of encounter areas.</returns>
public static EncounterArea[] GetArray4HGSS_Headbutt(byte[][] entries) public static EncounterArea[] GetArray4HGSS_Headbutt(byte[][] entries)
{ {
return entries?.Select(GetArea4HGSS_Headbutt).Where(Area => Area.Slots.Any()).ToArray(); return entries?.Select(GetArea4HGSS_Headbutt).Where(Area => Area.Slots.Length != 0).ToArray();
} }
/// <summary> /// <summary>

View file

@ -19,7 +19,6 @@
/// </summary> /// </summary>
public class EncounterSlot : IEncounterable, IGeneration public class EncounterSlot : IEncounterable, IGeneration
{ {
public int Location { get; set; } = -1;
public int Species { get; set; } public int Species { get; set; }
public int Form { get; set; } public int Form { get; set; }
public int LevelMin { get; set; } public int LevelMin { get; set; }
@ -32,18 +31,9 @@
internal EncounterSlotPermissions _perm; internal EncounterSlotPermissions _perm;
public EncounterSlotPermissions Permissions => _perm ?? (_perm = new EncounterSlotPermissions()); public EncounterSlotPermissions Permissions => _perm ?? (_perm = new EncounterSlotPermissions());
public virtual EncounterSlot Clone() internal EncounterArea Area { get; set; }
{ public int Location => Area.Location;
return new EncounterSlot public EncounterSlot Clone() => (EncounterSlot)MemberwiseClone();
{
Species = Species,
LevelMax = LevelMax,
LevelMin = LevelMin,
Type = Type,
SlotNumber = SlotNumber,
_perm = _perm
};
}
public string Name public string Name
{ {
@ -69,20 +59,5 @@
public int Rate; public int Rate;
internal EncounterTime Time = EncounterTime.Any; internal EncounterTime Time = EncounterTime.Any;
public GameVersion Version = GameVersion.Any; public GameVersion Version = GameVersion.Any;
public override EncounterSlot Clone()
{
return new EncounterSlot1
{
Species = Species,
LevelMax = LevelMax,
LevelMin = LevelMin,
Type = Type,
SlotNumber = SlotNumber,
_perm = _perm,
Rate = Rate,
Time = Time,
Generation = Generation,
};
}
} }
} }

View file

@ -0,0 +1,25 @@
namespace PKHeX.Core
{
public enum MoveType
{
Any = -1,
Normal,
Fighting,
Flying,
Poison,
Ground,
Rock,
Bug,
Ghost,
Steel,
Fire,
Water,
Grass,
Electric,
Psychic,
Ice,
Dragon,
Dark,
Fairy,
}
}

View file

@ -100,7 +100,8 @@ namespace PKHeX.WinForms
BAKprompt = false; BAKprompt = false;
CB_MainLanguage.Items.AddRange(main_langlist); CB_MainLanguage.Items.AddRange(main_langlist);
C_SAV.HaX = PKME_Tabs.HaX = HaX = args.Any(x => string.Equals(x.Trim('-'), nameof(HaX), StringComparison.CurrentCultureIgnoreCase)); C_SAV.HaX = PKME_Tabs.HaX = HaX = args.Any(x => string.Equals(x.Trim('-'), nameof(HaX), StringComparison.CurrentCultureIgnoreCase))
|| Path.GetFileNameWithoutExtension(Process.GetCurrentProcess().MainModule.FileName).EndsWith(nameof(HaX));
PB_Legal.Visible = !HaX; PB_Legal.Visible = !HaX;
int languageID = 1; // English int languageID = 1; // English