private static EncounterSlot2[] GetSlots2GrassWater(EncounterArea2 area, byte[] data, ref int ofs, SlotType t, int slotSets, int slotCount) { byte[] rates = new byte[slotSets]; for (int i = 0; i < rates.Length; i++) { rates[i] = data[ofs++]; } area.Rates = rates; var slots = EncounterSlot2.ReadSlots(data, ref ofs, slotSets * slotCount, t); if (slotSets <= 1) { return(slots); } for (int i = 0; i < slotCount; i++) { slots[i].Time = EncounterTime.Morning; } for (int r = 1; r < slotSets; r++) { for (int i = 0; i < slotCount; i++) { int index = i + (r * slotCount); slots[index].SlotNumber = i; slots[index].Time = r == 1 ? EncounterTime.Day : EncounterTime.Night; } } return(slots); }
public static IEnumerable <byte[]> Write(EncounterArea2 area) { var type = (area.Type) & (SlotType)0xF; if (type == SlotType.Grass) { var slotCount = area.Slots.Length / area.Rates.Length; for (var r = 0; r < area.Rates.Length; r++) { var rate = area.Rates[r]; using var ms = new MemoryStream(); using var bw = new BinaryWriter(ms); bw.Write((byte)area.Location); int firstSlot = r * slotCount; var first = (EncounterSlot2)area.Slots[firstSlot]; bw.Write((byte)first.Time); bw.Write((byte)area.Type); bw.Write(rate); for (int i = r * slotCount; i < (r + 1) * slotCount; i++) { var slot = (EncounterSlot2)area.Slots[i]; WriteSlot(bw, slot); } yield return(ms.ToArray()); } } else if (area.Type == SlotType.Old_Rod || area.Type == SlotType.Good_Rod || area.Type == SlotType.Super_Rod) { if (area.Slots.Length == area.Rates.Length) { yield return(WriteTable(area)); yield break; } var types = area.Slots.Cast <EncounterSlot2>().Select(z => z.Time).Distinct().ToList(); types.RemoveAll(z => z == EncounterTime.Any); foreach (var t in types) { yield return(WriteTableOfTime(area, t)); } } else { yield return(WriteTable(area)); } }
private static IEnumerable <EncounterArea2> GetAreas2(byte[] data, ref int ofs, SlotType t, int slotSets, int slotCount) { var areas = new List <EncounterArea2>(); while (data[ofs] != 0xFF) // end { var location = data[ofs++] << 8 | data[ofs++]; var area = new EncounterArea2 { Location = (short)location, Type = t }; var slots = GetSlots2GrassWater(area, data, ref ofs, t, slotSets, slotCount); area.Slots = slots; areas.Add(area); } ofs++; return(areas); }
private static byte[] WriteTable(EncounterArea2 area) { using var ms = new MemoryStream(); using var bw = new BinaryWriter(ms); bw.Write((byte)area.Location); var first = (EncounterSlot2)area.Slots[0]; bw.Write((byte)first.Time); var type = (byte)area.Type; bw.Write(type); if ((SlotType)(type & 0xF) == SlotType.Surf) { bw.Write(area.Rates[0]); } else if ((SlotType)type == SlotType.BugContest) { bw.Write(area.Rates[0]); } else { bw.Write((byte)0xFF); if (area.Rates.Length == 1) { throw new Exception(); } foreach (byte b in area.Rates) { bw.Write(b); } } foreach (var s in area.Slots.Cast <EncounterSlot2>()) { WriteSlot(bw, s); } return(ms.ToArray()); }
private static void GetSlots2Headbutt(ICollection <EncounterArea2> areas, EncounterArea2 a, byte[] data, ref int ofs, int tableCount) { // slot set ends in 0xFF var slots = new List <EncounterSlot2>(); var rates = new List <byte>(); int slot = 0; while (tableCount != 0) { byte rate = data[ofs++]; if (rate == 0xFF) // end of table { tableCount--; if (tableCount == 1) { a.Slots = slots.ToArray(); a.Rates = rates.ToArray(); a = new EncounterArea2 { Location = a.Location, Type = SlotType.Headbutt | SlotType.Special }; slots.Clear(); rates.Clear(); areas.Add(a); } continue; } int species = data[ofs++]; int level = data[ofs++]; rates.Add(rate); slots.Add(new EncounterSlot2(species, level, level, slot++)); } a.Slots = slots.ToArray(); a.Rates = rates.ToArray(); }
private static void GetSlots2Fishing(EncounterArea2 area, byte[] data, ref int ofs) { // slot set ends with final slot having 0xFF 0x** 0x** const int size = 3; int end = ofs; // scan for count while (data[end] != 0xFF) { end += size; } var count = ((end - ofs) / size) + 1; var rates = area.Rates = new byte[count]; var slots = area.Slots = new EncounterSlot2[count]; for (int i = 0; i < slots.Length; i++) { rates[i] = data[ofs++]; int species = data[ofs++]; int level = data[ofs++]; slots[i] = new EncounterSlot2(species, level, level, i); } }
private static byte[] WriteTableOfTime(EncounterArea2 area, EncounterTime t) { using var ms = new MemoryStream(); using var bw = new BinaryWriter(ms); var slots = area.Slots.Cast <EncounterSlot2>() .Where(z => z.Time == EncounterTime.Any || z.Time == t).ToArray(); bw.Write((byte)area.Location); bw.Write((byte)t); bw.Write((byte)area.Type); bw.Write((byte)0xFF); foreach (byte b in area.Rates) { bw.Write(b); } foreach (var s in slots) { WriteSlot(bw, s); } return(ms.ToArray()); }
private static List <EncounterArea2> GetAreas2Fishing(byte[] data, ref int ofs) { short a = 0; var areas = new List <EncounterArea2>(); while (ofs != 0x18C) { var aOld = new EncounterArea2 { Location = a, Type = SlotType.Old_Rod }; var aGood = new EncounterArea2 { Location = a, Type = SlotType.Good_Rod }; var aSuper = new EncounterArea2 { Location = a, Type = SlotType.Super_Rod }; GetSlots2Fishing(aOld, data, ref ofs); GetSlots2Fishing(aGood, data, ref ofs); GetSlots2Fishing(aSuper, data, ref ofs); areas.Add(aOld); areas.Add(aGood); areas.Add(aSuper); a++; } // Read TimeFishGroups var dl = new List <SlotTemplate>(); while (ofs < data.Length) { dl.Add(new SlotTemplate(data[ofs++], data[ofs++])); } // Add TimeSlots foreach (var area in areas) { var slots = area.Slots; for (int i = 0; i < slots.Length; i++) { var slot = (EncounterSlot2)slots[i]; if (slot.Species != 0) { continue; } Array.Resize(ref slots, slots.Length + 1); Array.Copy(slots, i, slots, i + 1, slots.Length - i - 1); // shift slots down slots[i + 1] = slot.Clone(); // differentiate copied slot int index = slot.LevelMin * 2; for (int j = 0; j < 2; j++) // load special slot info { var s = (EncounterSlot2)slots[i + j]; s.Species = dl[index + j].Species; s.LevelMin = s.LevelMax = dl[index + j].Level; s.Time = j == 0 ? EncounterTime.Morning | EncounterTime.Day : EncounterTime.Night; } } area.Slots = slots; } return(areas); }
public static void DumpGen2() { var g = Resources.encounter_gold; var s = Resources.encounter_silver; var c = Resources.encounter_crystal; var ga = EncounterArea2.GetArray2GrassWater(g); var sa = EncounterArea2.GetArray2GrassWater(s); var ca = EncounterArea2.GetArray2GrassWater(c); var gh = Resources.encounter_gold_h; var sh = Resources.encounter_silver_h; var ch = Resources.encounter_crystal_h; var fish = Resources.encounter_gsc_f; var gha = EncounterArea2.GetArray2Headbutt(gh); var sha = EncounterArea2.GetArray2Headbutt(sh); var cha = EncounterArea2.GetArray2Headbutt(ch); var f = EncounterArea2.GetArray2Fishing(fish); // Copy met locations from Crystal's met locations (already pre-formatted) for (int i = 0; i < ca.Length; i++) { ga[i].Location = sa[i].Location = ca[i].Location; } for (int i = 0; i < cha.Length; i++) { gha[i].Location = sha[i].Location = cha[i].Location; } // GS has different swarm ordering. Just manually apply the correct met location IDs. var gs_swarm = new short[] { 18, 25, 44, 35, 35 }; for (int i = ga.Length - gs_swarm.Length, j = 0; i < ga.Length; i++, j++) { ga[i].Location = sa[i].Location = gs_swarm[j]; } // Strip out the no-tree headbutt areas. { var gl = gha.ToList(); var sl = sha.ToList(); var cl = cha.ToList(); gl.RemoveAll(z => (z.Type & ~SlotType.Special) == SlotType.Headbutt && !Dumper2h.Trees.ContainsKey(z.Location)); sl.RemoveAll(z => (z.Type & ~SlotType.Special) == SlotType.Headbutt && !Dumper2h.Trees.ContainsKey(z.Location)); cl.RemoveAll(z => (z.Type & ~SlotType.Special) == SlotType.Headbutt && !Dumper2h.Trees.ContainsKey(z.Location)); if (gha.Length != gl.Count || sha.Length != sl.Count || cha.Length != cl.Count) { throw new Exception(); } } var gr = ga.Concat(gha).Concat(f) .Concat(new[] { EncounterBCC_GSC }) .OrderBy(z => z.Location).ThenBy(z => z.Type); var sr = sa.Concat(sha).Concat(f) .Concat(new[] { EncounterBCC_GSC }) .OrderBy(z => z.Location).ThenBy(z => z.Type); var cr = ca.Concat(cha).Concat(f) .Concat(new[] { EncounterBCC_GSC }) .OrderBy(z => z.Location).ThenBy(z => z.Type); Write(gr, "encounter_gold.pkl"); Write(sr, "encounter_silver.pkl"); Write(cr, "encounter_crystal.pkl"); }