mirror of
https://github.com/kwsch/pkNX.git
synced 2026-09-11 12:05:25 -05:00
Add split file encounter dumping, weather groups
Diferent weather allows for different Mark values (ribbon), and only Symbol encounters can wander into adjacent maps Need to have separate exports with appropriate metadata add nest dumper I forgot to push before working on slot dump v2
This commit is contained in:
@@ -1,11 +1,138 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace pkNX.Structures
|
||||
{
|
||||
public static class EncounterTable8Util
|
||||
{
|
||||
public static byte[][] GetBytes(IReadOnlyDictionary<ulong, byte> zone_loc, EncounterArchive8 t)
|
||||
{
|
||||
var result = new byte[t.EncounterTables.Length][];
|
||||
for (int i = 0; i < result.Length; i++)
|
||||
{
|
||||
var zone = t.EncounterTables[i];
|
||||
result[i] = GetZoneBytes(zone, zone_loc);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static byte[] GetZoneBytes(EncounterTable8 zone, IReadOnlyDictionary<ulong, byte> zoneLoc)
|
||||
{
|
||||
byte locID = zoneLoc[zone.ZoneID];
|
||||
var list = new List<Slot8>();
|
||||
for (int i = 0; i < zone.SubTables.Length; i++)
|
||||
{
|
||||
var weather = (SWSHEncounterType)(1 << i);
|
||||
var table = zone.SubTables[i];
|
||||
var min = table.LevelMin;
|
||||
var max = table.LevelMax;
|
||||
foreach (var s in table.Slots)
|
||||
{
|
||||
var s8 = new Slot8(s.Species, s.Form, min, max) {EncounterType = weather};
|
||||
var match = list.Find(z => z.Equals(s8));
|
||||
if (match == null)
|
||||
list.Add(s8);
|
||||
else
|
||||
match.EncounterType |= weather;
|
||||
}
|
||||
}
|
||||
|
||||
return SerializeSlot8(locID, list);
|
||||
}
|
||||
|
||||
private static byte[] SerializeSlot8(byte locID, IEnumerable<Slot8> list)
|
||||
{
|
||||
using var ms = new MemoryStream();
|
||||
using var bw = new BinaryWriter(ms);
|
||||
int ctr = 0;
|
||||
bw.Write(locID);
|
||||
bw.Write((byte) 0); // count tmp
|
||||
var groups = list.GroupBy(z => (int) z.EncounterType | (z.Min << 16) | (z.Max << 24));
|
||||
foreach (var g in groups)
|
||||
{
|
||||
var slots = g.ToArray();
|
||||
var type = g.Key & 0xFFFF;
|
||||
var min = (g.Key >> 16) & 0xFF;
|
||||
var max = g.Key >> 24;
|
||||
bw.Write((ushort) type);
|
||||
bw.Write((byte) min);
|
||||
bw.Write((byte) max);
|
||||
bw.Write((byte) slots.Length);
|
||||
bw.Write((byte) 0);
|
||||
|
||||
foreach (var slot in slots)
|
||||
bw.Write((ushort)(slot.Species | (slot.Form << 11)));
|
||||
ctr += slots.Length;
|
||||
}
|
||||
|
||||
bw.BaseStream.Seek(1, SeekOrigin.Begin);
|
||||
bw.Write((byte) ctr);
|
||||
return ms.ToArray();
|
||||
}
|
||||
|
||||
[Flags]
|
||||
private enum SWSHEncounterType
|
||||
{
|
||||
None,
|
||||
Normal = 1,
|
||||
Overcast = 1 << 1,
|
||||
Raining = 1 << 2,
|
||||
Thunderstorm = 1 << 3,
|
||||
Intense_Sun = 1 << 4,
|
||||
Snowing = 1 << 5,
|
||||
Snowstorm = 1 << 6,
|
||||
Sandstorm = 1 << 7,
|
||||
Heavy_Fog = 1 << 8,
|
||||
Shaking_Trees = 1 << 9,
|
||||
Fishing = 1 << 10,
|
||||
};
|
||||
|
||||
private class Slot8 : IEquatable<Slot8>
|
||||
{
|
||||
public readonly int Species;
|
||||
public readonly int Form;
|
||||
public readonly int Min;
|
||||
public readonly int Max;
|
||||
public SWSHEncounterType EncounterType;
|
||||
|
||||
public Slot8(int s, int f, int n, int x)
|
||||
{
|
||||
Species = s;
|
||||
Form = f;
|
||||
Min = n;
|
||||
Max = x;
|
||||
}
|
||||
|
||||
public bool Equals(Slot8 other)
|
||||
{
|
||||
if (other is null) return false;
|
||||
if (ReferenceEquals(this, other)) return true;
|
||||
return Species == other.Species && Form == other.Form && Min == other.Min && Max == other.Max;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is null) return false;
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
return obj.GetType() == GetType() && Equals((Slot8) obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hashCode = Species;
|
||||
hashCode = (hashCode * 397) ^ Form;
|
||||
hashCode = (hashCode * 397) ^ Min;
|
||||
hashCode = (hashCode * 397) ^ Max;
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<string> GetLines(EncounterArchive8 t, IReadOnlyDictionary<ulong, string> zone_names, string[] subtable_names, string[] species)
|
||||
{
|
||||
for (var i = 0; i < t.EncounterTables.Length; i++)
|
||||
|
||||
@@ -297,6 +297,11 @@ public void DumpWilds()
|
||||
File.WriteAllLines(GetPath("Encounters_Symbol_Sword.txt"), EncounterTable8Util.GetLines(encount_symbol_sw, zones, subtables, species));
|
||||
File.WriteAllLines(GetPath("Encounters_Shield.txt"), EncounterTable8Util.GetLines(encount_sh, zones, subtables, species));
|
||||
File.WriteAllLines(GetPath("Encounters_Symbol_Shield.txt"), EncounterTable8Util.GetLines(encount_symbol_sh, zones, subtables, species));
|
||||
|
||||
File.WriteAllBytes(GetPath("encounter_sw_hidden.pkl"), MiniUtil.PackMini(EncounterTable8Util.GetBytes(SWSHInfo.ZoneLocations, encount_sw), "sw"));
|
||||
File.WriteAllBytes(GetPath("encounter_sh_hidden.pkl"), MiniUtil.PackMini(EncounterTable8Util.GetBytes(SWSHInfo.ZoneLocations, encount_sh), "sh"));
|
||||
File.WriteAllBytes(GetPath("encounter_sw_symbol.pkl"), MiniUtil.PackMini(EncounterTable8Util.GetBytes(SWSHInfo.ZoneLocations, encount_symbol_sw), "sw"));
|
||||
File.WriteAllBytes(GetPath("encounter_sh_symbol.pkl"), MiniUtil.PackMini(EncounterTable8Util.GetBytes(SWSHInfo.ZoneLocations, encount_symbol_sh), "sh"));
|
||||
}
|
||||
|
||||
public void DumpNestEntries()
|
||||
@@ -457,6 +462,29 @@ public void DumpDistributionNestEntries(string path)
|
||||
var dist_sh = TableUtil.GetTable(dist_encounts.Tables.Where(z => z.GameVersion == 2).SelectMany(z => z.Entries));
|
||||
File.WriteAllText(GetPath("nestDist_sw.txt"), dist_sw);
|
||||
File.WriteAllText(GetPath("nestDist_sh.txt"), dist_sh);
|
||||
|
||||
string[][] nestHex = new string[2][];
|
||||
foreach (var game in new[] { 1, 2 })
|
||||
{
|
||||
var tables = dist_encounts.Tables.Where(z => z.GameVersion == game).ToList();
|
||||
var encounters = tables.SelectMany((z, x) => z.GetSummary(speciesNames, x)).ToArray();
|
||||
|
||||
var path1 = GetPath($"nestHex{game}.txt");
|
||||
File.WriteAllLines(path1, encounters);
|
||||
nestHex[game - 1] = encounters;
|
||||
|
||||
var result = tables.Select(z => z.GetSummarySimple());
|
||||
var path2 = GetPath($"nestDistFormat_{game}.txt");
|
||||
File.WriteAllLines(path2, result);
|
||||
}
|
||||
|
||||
var common = nestHex[0].Intersect(nestHex[1]).Where(z => z.StartsWith(" ")).Distinct();
|
||||
var sword = nestHex[0].Where(z => !nestHex[1].Contains(z)).Distinct();
|
||||
var shield = nestHex[1].Where(z => !nestHex[0].Contains(z)).Distinct();
|
||||
|
||||
File.WriteAllLines(GetPath("hex_nestDistCommon.txt"), common);
|
||||
File.WriteAllLines(GetPath("hex_nestDistSword.txt"), sword);
|
||||
File.WriteAllLines(GetPath("hex_nestDistShield.txt"), shield);
|
||||
}
|
||||
|
||||
private static readonly int[] LanguageIndexes = { 0, 2, 3, 4, 5, 6, 7, 8, 9 };
|
||||
|
||||
Reference in New Issue
Block a user