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);
        }
예제 #2
0
        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);
        }
예제 #4
0
        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);
            }
        }
예제 #7
0
        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);
        }
예제 #9
0
        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");
        }