Add shiny rate bonus editor

Untested, but should allow for changing the various bonuses (besides swarm's +25).
This commit is contained in:
Kurt 2022-02-05 09:24:44 -08:00
parent 0bc60747d3
commit 3baa9161b2
7 changed files with 146 additions and 3 deletions

View File

@ -190,5 +190,8 @@ public enum GameFile
/// <summary> "PokeMisc" Details about a given Species-Form not stored in <see cref="PersonalStats"/> </summary>
PokeMisc,
/// <summary> Gives bonus rolls based on met thresholds. </summary>
ShinyRolls,
}
}

View File

@ -460,6 +460,7 @@ public static IReadOnlyCollection<GameFileReference> GetMapping(GameVersion game
new(GameFile.PokeMisc, ContainerType.SingleFile, "bin", "pokemon", "data", "poke_misc.bin"),
new(GameFile.Outbreak, ContainerType.SingleFile, "bin", "field", "encount", "huge_outbreak.bin"),
new(GameFile.MoveShop, ContainerType.SingleFile, "bin", "appli", "wazaremember", "bin", "wazashop_table.bin"),
new(GameFile.ShinyRolls, ContainerType.SingleFile, "bin", "misc", "app_config", "pokemon_rare.bin"),
// Cutscenes bin\demo
// Models bin\archive\pokemon

View File

@ -16,6 +16,7 @@ public sealed class AreaInstance8a
public readonly LandmarkItem8a[] LandMarks;
public readonly PlacementUnnnEntry[] Unown;
public readonly PlacementMkrgEntry[] Mikaruge;
public readonly PlacementSearchItem[] SearchItem;
public readonly EncounterDataArchive8a Encounters;
@ -36,6 +37,7 @@ private AreaInstance8a(GFPack resident, string areaName, AreaInstance8a? parentA
var l_markf = resident.GetDataFullPath($"bin/field/param/placement/{areaName}/landmark_item/landmark_item.bin");
var unnf = resident.GetDataFullPath($"bin/field/param/placement/{areaName}/unnn/unnn.bin");
var mkrgf = resident.GetDataFullPath($"bin/field/param/placement/{areaName}/mkrg/mkrg.bin");
var psif = resident.GetDataFullPath($"bin/field/param/placement/{areaName}/search_item/search_item.bin");
Locations = FlatBufferConverter.DeserializeFrom<PlacementLocationArchive8a>(locationf).Table;
Spawners = FlatBufferConverter.DeserializeFrom<PlacementSpawnerArchive8a>(spawnerf).Table;
@ -44,6 +46,7 @@ private AreaInstance8a(GFPack resident, string areaName, AreaInstance8a? parentA
LandMarks = FlatBufferConverter.DeserializeFrom<LandmarkItemTable8a>(l_markf).Table;
Unown = FlatBufferConverter.DeserializeFrom<PlacementUnnnTable>(unnf).Table;
Mikaruge = FlatBufferConverter.DeserializeFrom<PlacementMkrgTable>(mkrgf).Table;
SearchItem = FlatBufferConverter.DeserializeFrom<PlacementSearchItemTable>(psif).Table;
AreaName = areaName;

View File

@ -0,0 +1,77 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using FlatSharp.Attributes;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers;
[FlatBufferTable, TypeConverter(typeof(ExpandableObjectConverter))]
public class PlacementSearchItemTable : IFlatBufferArchive<PlacementSearchItem>
{
public byte[] Write() => FlatBufferConverter.SerializeFrom(this);
[FlatBufferItem(0)] public PlacementSearchItem[] Table { get; set; } = Array.Empty<PlacementSearchItem>();
}
[FlatBufferTable, TypeConverter(typeof(ExpandableObjectConverter))]
public class PlacementSearchItem
{
[FlatBufferItem(0)] public string Identifier { get; set; } = string.Empty;
[FlatBufferItem(1)] public ulong Hash_01 { get; set; }
[FlatBufferItem(2)] public PlacementParameters8a[] Field_02 { get; set; } = Array.Empty<PlacementParameters8a>();
[FlatBufferItem(03)] public string Field_03 { get; set; } = string.Empty;
[FlatBufferItem(04)] public string Field_04 { get; set; } = string.Empty;
[FlatBufferItem(05)] public int Rate { get; set; }
[FlatBufferItem(06)] public bool Field_06 { get; set; } // bool
[FlatBufferItem(07)] public bool Field_07 { get; set; } // bool
[FlatBufferItem(08)] public PlacementV3f8a Field_08 { get; set; } = new();
[FlatBufferItem(09)] public byte Field_09 { get; set; } // bool
[FlatBufferItem(10)] public PlacementV3f8a Field_10 { get; set; } = new();
[FlatBufferItem(11)] public bool Field_11 { get; set; } // bool
[FlatBufferItem(12)] public PlacementV3f8a Field_12 { get; set; } = new();
[FlatBufferItem(13)] public bool Field_13 { get; set; } // bool
[FlatBufferItem(14)] public PlacementV3f8a Field_14 { get; set; } = new();
[FlatBufferItem(15)] public bool Field_15 { get; set; } // bool
[FlatBufferItem(16)] public PlacementV3f8a Field_16 { get; set; } = new();
[FlatBufferItem(17)] public bool Field_17 { get; set; } // bool
[FlatBufferItem(18)] public PlacementV3f8a Field_18 { get; set; } = new();
[FlatBufferItem(19)] public bool Field_19 { get; set; } // bool
[FlatBufferItem(20)] public PlacementV3f8a Field_20 { get; set; } = new();
[FlatBufferItem(21)] public bool Field_21 { get; set; } // bool
[FlatBufferItem(22)] public PlacementV3f8a Field_22 { get; set; } = new();
[FlatBufferItem(23)] public bool Field_23 { get; set; } // bool
[FlatBufferItem(24)] public PlacementV3f8a Field_24 { get; set; } = new();
[FlatBufferItem(25)] public bool Field_25 { get; set; } // bool
[FlatBufferItem(26)] public PlacementV3f8a Field_26 { get; set; } = new();
public PlacementParameters8a Parameters
{
get { if (Field_02.Length != 1) throw new ArgumentException($"Invalid {nameof(Field_02)}"); return Field_02[0]; }
set { if (Field_02.Length != 1) throw new ArgumentException($"Invalid {nameof(Field_02)}"); Field_02[0] = value; }
}
public override string ToString() => $"SearchItem(\"{Identifier}\", 0x{Hash_01:X16}, {Parameters}, {Rate}, {Field_03}, {Field_04})";
public IEnumerable<PlacementLocation8a> GetContainingLocations(IReadOnlyList<PlacementLocation8a> locations)
{
var result = new List<PlacementLocation8a>();
foreach (var loc in locations)
{
if (!loc.IsNamedPlace)
continue;
if (loc.Contains(Parameters.Coordinates))
result.Add(loc);
}
if (result.Count == 0)
result.Add(locations.First(l => l.IsNamedPlace)); // base area name
return result;
}
}

View File

@ -26,7 +26,12 @@ public class PokemonRare8aEntry
[FlatBufferItem(01)] public ulong Hash { get; set; }
[FlatBufferItem(02)] public byte UnusedValue { get; set; } // none have this
[FlatBufferItem(03)] public string Option { get; set; } = string.Empty;
[FlatBufferItem(04)] public string Value { get; set; } = string.Empty;
[FlatBufferItem(05)] public string[] Field_05 { get; set; } = Array.Empty<string>();
[FlatBufferItem(04)] public string Field_04 { get; set; } = string.Empty;
[FlatBufferItem(05)] public string[] Parameters { get; set; } = Array.Empty<string>();
[FlatBufferItem(06)] public FlatDummyEntry[] UnusedArray { get; set; } = Array.Empty<FlatDummyEntry>(); // none have this
public string ConfiguredValue
{
get => Parameters[0];
set => Parameters[0] = value;
}
}

View File

@ -460,6 +460,8 @@ public void DumpWilds()
var allLandItems = new List<LandmarkItemSpawn8a>();
var allLandMarks = new List<LandmarkItem8a>();
var allUnown = new List<PlacementUnnnEntry>();
var allMkrg = new List<PlacementMkrgEntry>();
var allSearchItem = new List<PlacementSearchItem>();
foreach (var areaNameList in PLAInfo.AreaNames)
{
var instance = AreaInstance8a.Create(resident, areaNameList);
@ -490,6 +492,8 @@ public void DumpWilds()
allLandItems.AddRange(instance.LandItems);
allLandMarks.AddRange(instance.LandMarks);
allUnown.AddRange(instance.Unown);
allMkrg.AddRange(instance.Mikaruge);
allSearchItem.AddRange(instance.SearchItem);
foreach (var subArea in instance.SubAreas)
{
@ -499,6 +503,9 @@ public void DumpWilds()
allLocations.AddRange(subArea.Locations);
allLandItems.AddRange(subArea.LandItems);
allLandMarks.AddRange(subArea.LandMarks);
allUnown.AddRange(subArea.Unown);
allMkrg.AddRange(subArea.Mikaruge);
allSearchItem.AddRange(subArea.SearchItem);
}
}
@ -518,6 +525,8 @@ public void DumpWilds()
File.WriteAllText(GetPath(wild, "allLandMarks.csv"), TableUtil.GetTable(allLandMarks));
File.WriteAllText(GetPath(wild, "allLandMarkSpawns.csv"), TableUtil.GetTable(allLandMarks));
File.WriteAllText(GetPath(wild, "allUnown.csv"), TableUtil.GetTable(allUnown));
File.WriteAllText(GetPath(wild, "allMkrg.csv"), TableUtil.GetTable(allMkrg));
File.WriteAllText(GetPath(wild, "allSearchItem.csv"), TableUtil.GetTable(allSearchItem));
}
public void DumpResident()
@ -610,6 +619,14 @@ public void DumpPlacement()
mkrg_all.Add(string.Empty);
File.WriteAllLines(GetPath(placement, $"Mikaruge_{areaName}.txt"), mkrg_lines);
}
if (subArea.SearchItem.Length != 0)
{
var mkrg_lines = GetSearchItemLines(areaName, map, subArea.SearchItem, subArea.Locations);
mkrg_all.AddRange(mkrg_lines);
mkrg_all.Add(string.Empty);
File.WriteAllLines(GetPath(placement, $"SearchItem_{areaName}.txt"), mkrg_lines);
}
// Debug for Visualization
if (new[] { "ha_area01", "ha_area02", "ha_area03", "ha_area04", "ha_area05" }.Contains(areaName))
@ -684,6 +701,20 @@ public void DumpPlacement()
return result;
}
private static IReadOnlyList<string> GetSearchItemLines(string areaName,
IReadOnlyDictionary<string, (string Name, int Index)> map,
IEnumerable<PlacementSearchItem> mkrgs,
IReadOnlyList<PlacementLocation8a> locations)
{
var result = new List<string> { $"Area: {areaName}" };
foreach (var psi in mkrgs)
{
var contained = GetNearbyLocationNames(psi, locations, map);
result.Add($"\t{psi} // Containing Locations: {contained}");
}
return result;
}
private static string GetNearbyLocationNames(PlacementSpawner8a spawner,
IReadOnlyList<PlacementLocation8a> locations,
IReadOnlyDictionary<string, (string Name, int Index)> map)
@ -694,6 +725,16 @@ public void DumpPlacement()
return string.Join(", ", localized);
}
private static string GetNearbyLocationNames(PlacementSearchItem mkrg,
IReadOnlyList<PlacementLocation8a> locations,
IReadOnlyDictionary<string, (string Name, int Index)> map)
{
var containedBy = mkrg.GetContainingLocations(locations);
var placeNames = containedBy.Select(z => z.PlaceName).Distinct();
var localized = placeNames.Select(pn => map[pn].Name);
return string.Join(", ", localized);
}
private static string GetNearbyLocationNames(PlacementMkrgEntry mkrg,
IReadOnlyList<PlacementLocation8a> locations,
IReadOnlyDictionary<string, (string Name, int Index)> map)

View File

@ -1,6 +1,5 @@
using System.IO;
using System.Linq;
using System.Windows.Forms;
using pkNX.Containers;
using pkNX.Game;
using pkNX.Structures;
@ -107,6 +106,20 @@ public void EditItems()
obj[0] = Item8a.SetArray(items, data);
}
public void EditShinyRate()
{
var obj = ROM.GetFile(GameFile.ShinyRolls); // flatbuffer
var data = obj[0];
var root = FlatBufferConverter.DeserializeFrom<PokemonRare8aTable>(data);
var cache = new DataCache<PokemonRare8aEntry>(root.Table);
var names = root.Table.Select(z => z.Name).ToArray();
using var form = new GenericEditor<PokemonRare8aEntry>(cache, names, "Shiny Rate Editor");
form.ShowDialog();
if (!form.Modified)
return;
obj[0] = FlatBufferConverter.SerializeFrom(root);
}
public void EditSymbolBehave()
{
var obj = ROM.GetFile(GameFile.SymbolBehave);