Add handling for S/V load and data ripping
Co-Authored-By: SciresM <8676005+SciresM@users.noreply.github.com> Co-Authored-By: Matt <17801814+sora10pls@users.noreply.github.com> Co-Authored-By: Lusamine <30205550+Lusamine@users.noreply.github.com>
|
|
@ -13,11 +13,11 @@ public static class Container
|
|||
public static IFileContainer GetContainer(string path, ContainerType t) => t switch
|
||||
{
|
||||
ContainerType.GARC => new GARC(path),
|
||||
ContainerType.Mini => MiniUtil.GetMini(path),
|
||||
ContainerType.BinLinker => MiniUtil.GetMini(path),
|
||||
ContainerType.SARC => new SARC(path),
|
||||
ContainerType.Folder => new FolderContainer(path),
|
||||
ContainerType.SingleFile => new SingleFileContainer(path),
|
||||
ContainerType.GFPack => new GFPack(path),
|
||||
ContainerType.GameFreakPack => new GFPack(path),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(t), t, null),
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -3,9 +3,10 @@ namespace pkNX.Containers;
|
|||
public enum ContainerType
|
||||
{
|
||||
GARC,
|
||||
Mini,
|
||||
BinLinker,
|
||||
SARC,
|
||||
Folder,
|
||||
SingleFile,
|
||||
GFPack,
|
||||
GameFreakPack,
|
||||
SingleFileInternal,
|
||||
}
|
||||
|
|
|
|||
7
pkNX.Containers/IFileInternal.cs
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
namespace pkNX.Containers;
|
||||
|
||||
public interface IFileInternal
|
||||
{
|
||||
byte[] GetPackedFile(string file);
|
||||
byte[] GetPackedFile(ulong hash);
|
||||
}
|
||||
41
pkNX.Containers/InternalFileContainer.cs
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace pkNX.Containers;
|
||||
|
||||
public class InternalFileContainer : IFileContainer
|
||||
{
|
||||
public string? FilePath { get; set; }
|
||||
public bool Modified { get; set; }
|
||||
public int Count => 1;
|
||||
|
||||
public byte[] Data = Array.Empty<byte>();
|
||||
private byte[] Backup = Array.Empty<byte>();
|
||||
public InternalFileContainer(byte[] data) => LoadData(data);
|
||||
|
||||
private void LoadData(byte[] data) => Backup = (byte[]) (Data = data).Clone();
|
||||
|
||||
public void CancelEdits()
|
||||
{
|
||||
Modified = false;
|
||||
Data = (byte[]) Backup.Clone();
|
||||
}
|
||||
|
||||
public byte[] this[int index]
|
||||
{
|
||||
get => (byte[])Data.Clone();
|
||||
set
|
||||
{
|
||||
Modified |= !Data.SequenceEqual(value);
|
||||
Data = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Task<byte[][]> GetFiles() => Task.FromResult(new[] {this[0]});
|
||||
public Task<byte[]> GetFile(int file, int subFile = 0) => Task.FromResult(this[0]);
|
||||
public Task SetFile(int file, byte[] value, int subFile = 0) => Task.FromResult(Data = value);
|
||||
public Task SaveAs(string path, ContainerHandler handler, CancellationToken token) => new(() => Dump(path, handler), token);
|
||||
public void Dump(string? path, ContainerHandler handler) => FileMitm.WriteAllBytes(path ?? FilePath!, Data);
|
||||
}
|
||||
|
|
@ -21,12 +21,10 @@ public class DatTable : Dictionary<ulong, int>
|
|||
// - u32(?) index
|
||||
// - u32(?) unk
|
||||
|
||||
public static bool IsDatTable(byte[] bytes)
|
||||
{
|
||||
// pretty weak, don't call this if you aren't sure!
|
||||
var count = BitConverter.ToUInt32(bytes, 0);
|
||||
return 4 + (count * 0x10) == bytes.Length;
|
||||
}
|
||||
// pretty weak, don't call this if you aren't sure!
|
||||
public static bool IsDatTable(ReadOnlySpan<byte> bytes) => IsDatTable(bytes, bytes.Length);
|
||||
public static bool IsDatTable(ReadOnlySpan<byte> bytes, int len) => IsDatTable(System.Buffers.Binary.BinaryPrimitives.ReadInt32LittleEndian(bytes), len);
|
||||
public static bool IsDatTable(int count, int len) => 4 + (count * 0x10) == len;
|
||||
|
||||
private readonly DatEntry[] Entries;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<Description>Packing & Unpacking</Description>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ public class DirectCache<T> : DataCache<T> where T : class
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Data 'from a flatbuffer table
|
||||
/// Data 'from a FlatBuffer table
|
||||
/// </summary>
|
||||
/// <typeparam name="TTable">The type of table</typeparam>
|
||||
/// <typeparam name="TData">The type of data inside the table</typeparam>
|
||||
|
|
|
|||
|
|
@ -75,13 +75,13 @@ public enum GameFile
|
|||
Encounters,
|
||||
|
||||
/// <summary> Trainer Data related to Trainers of a shared type. </summary>
|
||||
TrainerClass,
|
||||
TrainerSpecClass,
|
||||
|
||||
/// <summary> Trainer Data for individual Trainers that can be battled. </summary>
|
||||
TrainerData,
|
||||
TrainerSpecData,
|
||||
|
||||
/// <summary> Trainer PKM template data for regular battles. </summary>
|
||||
TrainerPoke,
|
||||
TrainerSpecPoke,
|
||||
|
||||
/// <summary> Move data that defines the properties of in-game moves. </summary>
|
||||
MoveStats,
|
||||
|
|
@ -105,7 +105,7 @@ public enum GameFile
|
|||
ItemStats,
|
||||
|
||||
/// <summary> Static (fixed position/condition) encounter table. </summary>
|
||||
EncounterStatic,
|
||||
EncounterTableStatic,
|
||||
|
||||
/// <summary> Post-game roulette trainer data with normal difficulty. </summary>
|
||||
FacilityTrainerNormal,
|
||||
|
|
@ -147,10 +147,10 @@ public enum GameFile
|
|||
MoveSprites,
|
||||
|
||||
/// <summary> Traded Pokémon swap data. </summary>
|
||||
EncounterTrade,
|
||||
EncounterTableTrade,
|
||||
|
||||
/// <summary> Gift Pokémon data. </summary>
|
||||
EncounterGift,
|
||||
EncounterTableGift,
|
||||
|
||||
/// <summary> Nest Data </summary>
|
||||
NestData,
|
||||
|
|
@ -354,4 +354,7 @@ public enum GameFile
|
|||
MoveObstructionWater,
|
||||
MoveObstructionWaterEffect,
|
||||
NushiBattleSettings,
|
||||
|
||||
DataTrpfs,
|
||||
DataTrpfd,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using static pkNX.Structures.GameVersion;
|
||||
using static pkNX.Game.GameFile;
|
||||
using static pkNX.Containers.ContainerType;
|
||||
|
||||
namespace pkNX.Game;
|
||||
|
||||
|
|
@ -21,9 +24,9 @@ public class GameFileMapping
|
|||
private readonly GameLocation ROM;
|
||||
public GameFileMapping(GameLocation rom) => FileMap = GetMapping((ROM = rom).Game);
|
||||
|
||||
internal IFileContainer GetFile(GameFile file, int language)
|
||||
internal IFileContainer GetFile(GameFile file, int language, GameManager gameManager)
|
||||
{
|
||||
if (file is GameFile.GameText or GameFile.StoryText)
|
||||
if (file is GameText or StoryText)
|
||||
file += language + 1; // shift to localized language
|
||||
|
||||
if (Cache.TryGetValue(file, out var container))
|
||||
|
|
@ -33,10 +36,18 @@ internal IFileContainer GetFile(GameFile file, int language)
|
|||
if (info == null)
|
||||
throw new ArgumentException($"Unknown {nameof(GameFile)} provided.", file.ToString());
|
||||
|
||||
var basePath = info.Parent == ContainerParent.ExeFS ? ROM.ExeFS : ROM.RomFS;
|
||||
if (basePath == null)
|
||||
throw new ArgumentException($"No {info.Parent} found for {file}.");
|
||||
container = info.Get(basePath);
|
||||
if (info.Type is SingleFileInternal && gameManager is IFileInternal irom)
|
||||
{
|
||||
var data = irom.GetPackedFile(info.RelativePath);
|
||||
container = new InternalFileContainer(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
var basePath = info.Parent == ContainerParent.ExeFS ? ROM.ExeFS : ROM.RomFS;
|
||||
if (basePath == null)
|
||||
throw new ArgumentException($"No {info.Parent} found for {file}.");
|
||||
container = info.Get(basePath);
|
||||
}
|
||||
Cache.Add(file, container);
|
||||
return container;
|
||||
}
|
||||
|
|
@ -56,13 +67,10 @@ internal void SaveAll()
|
|||
|
||||
public static IReadOnlyCollection<GameFileReference> GetMapping(GameVersion game) => game switch
|
||||
{
|
||||
GameVersion.GP => GG,
|
||||
GameVersion.GE => GG,
|
||||
GameVersion.GG => GG,
|
||||
GameVersion.SW => SWSH,
|
||||
GameVersion.SH => SWSH,
|
||||
GameVersion.SWSH => SWSH,
|
||||
GameVersion.PLA => PLA,
|
||||
GP or GE or GG => FilesGG,
|
||||
SW or SH or SWSH => FilesSWSH,
|
||||
PLA => FilesPLA,
|
||||
SL or VL or SV => FilesSV,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(game), game, null),
|
||||
};
|
||||
|
||||
|
|
@ -71,49 +79,49 @@ internal void SaveAll()
|
|||
/// <summary>
|
||||
/// Let's Go Pikachu & Let's Go Eevee
|
||||
/// </summary>
|
||||
private static readonly GameFileReference[] GG =
|
||||
private static readonly GameFileReference[] FilesGG =
|
||||
{
|
||||
new(GameFile.TrainerData, "bin", "trainer", "trainer_data"),
|
||||
new(GameFile.TrainerPoke, "bin", "trainer", "trainer_poke"),
|
||||
new(GameFile.TrainerClass, "bin", "trainer", "trainer_type"),
|
||||
new(TrainerSpecData, "bin", "trainer", "trainer_data"),
|
||||
new(TrainerSpecPoke, "bin", "trainer", "trainer_poke"),
|
||||
new(TrainerSpecClass, "bin", "trainer", "trainer_type"),
|
||||
|
||||
new(GameFile.GameText0, 0, "bin", "message", "JPN", "common"),
|
||||
new(GameFile.GameText1, 1, "bin", "message", "JPN_KANJI", "common"),
|
||||
new(GameFile.GameText2, 2, "bin", "message", "English", "common"),
|
||||
new(GameFile.GameText3, 3, "bin", "message", "French", "common"),
|
||||
new(GameFile.GameText4, 4, "bin", "message", "Italian", "common"),
|
||||
new(GameFile.GameText5, 5, "bin", "message", "German", "common"),
|
||||
new(GameText0, 0, "bin", "message", "JPN", "common"),
|
||||
new(GameText1, 1, "bin", "message", "JPN_KANJI", "common"),
|
||||
new(GameText2, 2, "bin", "message", "English", "common"),
|
||||
new(GameText3, 3, "bin", "message", "French", "common"),
|
||||
new(GameText4, 4, "bin", "message", "Italian", "common"),
|
||||
new(GameText5, 5, "bin", "message", "German", "common"),
|
||||
// 6 unused lang
|
||||
new(GameFile.GameText6, 7, "bin", "message", "Spanish", "common"),
|
||||
new(GameFile.GameText7, 8, "bin", "message", "Korean", "common"),
|
||||
new(GameFile.GameText8, 9, "bin", "message", "Simp_Chinese", "common"),
|
||||
new(GameFile.GameText9, 10, "bin", "message", "Trad_Chinese", "common"),
|
||||
new(GameText6, 7, "bin", "message", "Spanish", "common"),
|
||||
new(GameText7, 8, "bin", "message", "Korean", "common"),
|
||||
new(GameText8, 9, "bin", "message", "Simp_Chinese", "common"),
|
||||
new(GameText9, 10, "bin", "message", "Trad_Chinese", "common"),
|
||||
|
||||
new(GameFile.StoryText0, 0, "bin", "message", "JPN", "script"),
|
||||
new(GameFile.StoryText1, 1, "bin", "message", "JPN_KANJI", "script"),
|
||||
new(GameFile.StoryText2, 2, "bin", "message", "English", "script"),
|
||||
new(GameFile.StoryText3, 3, "bin", "message", "French", "script"),
|
||||
new(GameFile.StoryText4, 4, "bin", "message", "Italian", "script"),
|
||||
new(GameFile.StoryText5, 5, "bin", "message", "German", "script"),
|
||||
new(StoryText0, 0, "bin", "message", "JPN", "script"),
|
||||
new(StoryText1, 1, "bin", "message", "JPN_KANJI", "script"),
|
||||
new(StoryText2, 2, "bin", "message", "English", "script"),
|
||||
new(StoryText3, 3, "bin", "message", "French", "script"),
|
||||
new(StoryText4, 4, "bin", "message", "Italian", "script"),
|
||||
new(StoryText5, 5, "bin", "message", "German", "script"),
|
||||
// 6 unused lang
|
||||
new(GameFile.StoryText6, 7, "bin", "message", "Spanish", "script"),
|
||||
new(GameFile.StoryText7, 8, "bin", "message", "Korean", "script"),
|
||||
new(GameFile.StoryText8, 9, "bin", "message", "Simp_Chinese", "script"),
|
||||
new(GameFile.StoryText9, 10, "bin", "message", "Trad_Chinese", "script"),
|
||||
new(StoryText6, 7, "bin", "message", "Spanish", "script"),
|
||||
new(StoryText7, 8, "bin", "message", "Korean", "script"),
|
||||
new(StoryText8, 9, "bin", "message", "Simp_Chinese", "script"),
|
||||
new(StoryText9, 10, "bin", "message", "Trad_Chinese", "script"),
|
||||
|
||||
new(GameFile.ItemStats, "bin", "pokelib", "item"),
|
||||
new(GameFile.Evolutions, "bin", "pokelib", "evolution"),
|
||||
new(GameFile.PersonalStats, "bin", "pokelib", "personal"),
|
||||
new(GameFile.MegaEvolutions, "bin", "pokelib", "mega_evolution"),
|
||||
new(GameFile.MoveStats, ContainerType.Mini, "bin", "pokelib", "waza", "waza_data.bin"),
|
||||
new(GameFile.EncounterStatic, ContainerType.SingleFile, "bin", "script_event_data", "event_encount.bin"),
|
||||
new(GameFile.EncounterTrade, ContainerType.SingleFile, "bin", "script_event_data", "field_trade_data.bin"),
|
||||
new(GameFile.EncounterGift, ContainerType.SingleFile, "bin", "script_event_data", "add_poke.bin"),
|
||||
new(GameFile.Learnsets, ContainerType.GFPack, "bin", "archive", "waza_oboe.gfpak"),
|
||||
new(ItemStats, "bin", "pokelib", "item"),
|
||||
new(Evolutions, "bin", "pokelib", "evolution"),
|
||||
new(PersonalStats, "bin", "pokelib", "personal"),
|
||||
new(MegaEvolutions, "bin", "pokelib", "mega_evolution"),
|
||||
new(MoveStats, BinLinker, "bin", "pokelib", "waza", "waza_data.bin"),
|
||||
new(EncounterTableStatic, SingleFile, "bin", "script_event_data", "event_encount.bin"),
|
||||
new(EncounterTableTrade, SingleFile, "bin", "script_event_data", "field_trade_data.bin"),
|
||||
new(EncounterTableGift, SingleFile, "bin", "script_event_data", "add_poke.bin"),
|
||||
new(Learnsets, GameFreakPack, "bin", "archive", "waza_oboe.gfpak"),
|
||||
|
||||
new(GameFile.WildData1, ContainerType.SingleFile, "bin", "field", "param", "encount", "encount_data_p.bin"),
|
||||
new(GameFile.WildData2, ContainerType.SingleFile, "bin", "field", "param", "encount", "encount_data_e.bin"),
|
||||
new(GameFile.Shops, ContainerType.SingleFile, "bin", "app", "shop", "shop_data.bin"),
|
||||
new(WildData1, SingleFile, "bin", "field", "param", "encount", "encount_data_p.bin"),
|
||||
new(WildData2, SingleFile, "bin", "field", "param", "encount", "encount_data_e.bin"),
|
||||
new(Shops, SingleFile, "bin", "app", "shop", "shop_data.bin"),
|
||||
|
||||
// Cutscenes bin\demo
|
||||
// Models bin\archive\pokemon
|
||||
|
|
@ -124,60 +132,60 @@ internal void SaveAll()
|
|||
|
||||
#region Gen 8
|
||||
/// <summary>
|
||||
/// Sword
|
||||
/// Sword & Shield
|
||||
/// </summary>
|
||||
private static readonly GameFileReference[] SWSH =
|
||||
private static readonly GameFileReference[] FilesSWSH =
|
||||
{
|
||||
new(GameFile.TrainerData, "bin", "trainer", "trainer_data"),
|
||||
new(GameFile.TrainerPoke, "bin", "trainer", "trainer_poke"),
|
||||
new(GameFile.TrainerClass, "bin", "trainer", "trainer_type"),
|
||||
new(TrainerSpecData, "bin", "trainer", "trainer_data"),
|
||||
new(TrainerSpecPoke, "bin", "trainer", "trainer_poke"),
|
||||
new(TrainerSpecClass, "bin", "trainer", "trainer_type"),
|
||||
|
||||
new(GameFile.GameText0, 0, "bin", "message", "JPN", "common"),
|
||||
new(GameFile.GameText1, 1, "bin", "message", "JPN_KANJI", "common"),
|
||||
new(GameFile.GameText2, 2, "bin", "message", "English", "common"),
|
||||
new(GameFile.GameText3, 3, "bin", "message", "French", "common"),
|
||||
new(GameFile.GameText4, 4, "bin", "message", "Italian", "common"),
|
||||
new(GameFile.GameText5, 5, "bin", "message", "German", "common"),
|
||||
new(GameText0, 0, "bin", "message", "JPN", "common"),
|
||||
new(GameText1, 1, "bin", "message", "JPN_KANJI", "common"),
|
||||
new(GameText2, 2, "bin", "message", "English", "common"),
|
||||
new(GameText3, 3, "bin", "message", "French", "common"),
|
||||
new(GameText4, 4, "bin", "message", "Italian", "common"),
|
||||
new(GameText5, 5, "bin", "message", "German", "common"),
|
||||
// 6 unused lang
|
||||
new(GameFile.GameText6, 7, "bin", "message", "Spanish", "common"),
|
||||
new(GameFile.GameText7, 8, "bin", "message", "Korean", "common"),
|
||||
new(GameFile.GameText8, 9, "bin", "message", "Simp_Chinese", "common"),
|
||||
new(GameFile.GameText9, 10, "bin", "message", "Trad_Chinese", "common"),
|
||||
new(GameText6, 7, "bin", "message", "Spanish", "common"),
|
||||
new(GameText7, 8, "bin", "message", "Korean", "common"),
|
||||
new(GameText8, 9, "bin", "message", "Simp_Chinese", "common"),
|
||||
new(GameText9, 10, "bin", "message", "Trad_Chinese", "common"),
|
||||
|
||||
new(GameFile.StoryText0, 0, "bin", "message", "JPN", "script"),
|
||||
new(GameFile.StoryText1, 1, "bin", "message", "JPN_KANJI", "script"),
|
||||
new(GameFile.StoryText2, 2, "bin", "message", "English", "script"),
|
||||
new(GameFile.StoryText3, 3, "bin", "message", "French", "script"),
|
||||
new(GameFile.StoryText4, 4, "bin", "message", "Italian", "script"),
|
||||
new(GameFile.StoryText5, 5, "bin", "message", "German", "script"),
|
||||
new(StoryText0, 0, "bin", "message", "JPN", "script"),
|
||||
new(StoryText1, 1, "bin", "message", "JPN_KANJI", "script"),
|
||||
new(StoryText2, 2, "bin", "message", "English", "script"),
|
||||
new(StoryText3, 3, "bin", "message", "French", "script"),
|
||||
new(StoryText4, 4, "bin", "message", "Italian", "script"),
|
||||
new(StoryText5, 5, "bin", "message", "German", "script"),
|
||||
// 6 unused lang
|
||||
new(GameFile.StoryText6, 7, "bin", "message", "Spanish", "script"),
|
||||
new(GameFile.StoryText7, 8, "bin", "message", "Korean", "script"),
|
||||
new(GameFile.StoryText8, 9, "bin", "message", "Simp_Chinese", "script"),
|
||||
new(GameFile.StoryText9, 10, "bin", "message", "Trad_Chinese", "script"),
|
||||
new(StoryText6, 7, "bin", "message", "Spanish", "script"),
|
||||
new(StoryText7, 8, "bin", "message", "Korean", "script"),
|
||||
new(StoryText8, 9, "bin", "message", "Simp_Chinese", "script"),
|
||||
new(StoryText9, 10, "bin", "message", "Trad_Chinese", "script"),
|
||||
|
||||
new(GameFile.ItemStats, ContainerType.SingleFile, "bin", "pml", "item", "item.dat"),
|
||||
new(GameFile.Evolutions, "bin", "pml", "evolution"),
|
||||
new(ItemStats, SingleFile, "bin", "pml", "item", "item.dat"),
|
||||
new(Evolutions, "bin", "pml", "evolution"),
|
||||
new(GameFile.EggMoves, "bin", "pml", "tamagowaza"),
|
||||
new(GameFile.PersonalStats, "bin", "pml", "personal"),
|
||||
new(GameFile.MoveStats, "bin", "pml", "waza"),
|
||||
new(GameFile.EncounterStatic, ContainerType.SingleFile, "bin", "script_event_data", "event_encount_data.bin"),
|
||||
new(GameFile.EncounterTrade, ContainerType.SingleFile, "bin", "script_event_data", "field_trade.bin"),
|
||||
new(GameFile.EncounterGift, ContainerType.SingleFile, "bin", "script_event_data", "add_poke.bin"),
|
||||
new(GameFile.Learnsets, ContainerType.SingleFile, "bin", "pml", "waza_oboe", "wazaoboe_total.bin"),
|
||||
new(PersonalStats, "bin", "pml", "personal"),
|
||||
new(MoveStats, "bin", "pml", "waza"),
|
||||
new(EncounterTableStatic, SingleFile, "bin", "script_event_data", "event_encount_data.bin"),
|
||||
new(EncounterTableTrade, SingleFile, "bin", "script_event_data", "field_trade.bin"),
|
||||
new(EncounterTableGift, SingleFile, "bin", "script_event_data", "add_poke.bin"),
|
||||
new(Learnsets, SingleFile, "bin", "pml", "waza_oboe", "wazaoboe_total.bin"),
|
||||
|
||||
new(GameFile.FacilityPokeNormal, ContainerType.SingleFile, "bin", "field", "param", "battle_tower", "battle_tower_poke_table.bin"),
|
||||
new(GameFile.FacilityTrainerNormal, ContainerType.SingleFile, "bin", "field", "param", "battle_tower", "battle_tower_trainer_table.bin"),
|
||||
new(FacilityPokeNormal, SingleFile, "bin", "field", "param", "battle_tower", "battle_tower_poke_table.bin"),
|
||||
new(FacilityTrainerNormal, SingleFile, "bin", "field", "param", "battle_tower", "battle_tower_trainer_table.bin"),
|
||||
|
||||
new(GameFile.WildData, ContainerType.SingleFile, "bin", "archive", "field", "resident", "data_table.gfpak"),
|
||||
new(GameFile.NestData, ContainerType.SingleFile, "bin", "archive", "field", "resident", "data_table.gfpak"),
|
||||
new(WildData, SingleFile, "bin", "archive", "field", "resident", "data_table.gfpak"),
|
||||
new(NestData, SingleFile, "bin", "archive", "field", "resident", "data_table.gfpak"),
|
||||
|
||||
new(GameFile.DynamaxDens, ContainerType.SingleFile, "bin", "appli", "chika", "data_table", "underground_exploration_poke.bin"),
|
||||
new(DynamaxDens, SingleFile, "bin", "appli", "chika", "data_table", "underground_exploration_poke.bin"),
|
||||
|
||||
new(GameFile.Placement, ContainerType.SingleFile, "bin", "archive", "field", "resident", "placement.gfpak"),
|
||||
new(GameFile.Shops, ContainerType.SingleFile, "bin", "appli", "shop", "bin", "shop_data.bin"),
|
||||
new(GameFile.Rentals, ContainerType.SingleFile, "bin", "script_event_data", "rental.bin"),
|
||||
new(GameFile.SymbolBehave, ContainerType.SingleFile, "bin", "field", "param", "symbol_encount_mons_param", "symbol_encount_mons_param.bin"),
|
||||
new(Placement, SingleFile, "bin", "archive", "field", "resident", "placement.gfpak"),
|
||||
new(Shops, SingleFile, "bin", "appli", "shop", "bin", "shop_data.bin"),
|
||||
new(Rentals, SingleFile, "bin", "script_event_data", "rental.bin"),
|
||||
new(SymbolBehave, SingleFile, "bin", "field", "param", "symbol_encount_mons_param", "symbol_encount_mons_param.bin"),
|
||||
|
||||
// Cutscenes bin\demo
|
||||
// Models bin\archive\pokemon
|
||||
|
|
@ -185,202 +193,247 @@ internal void SaveAll()
|
|||
};
|
||||
|
||||
/// <summary>
|
||||
/// Sword
|
||||
/// Legends: Arceus
|
||||
/// </summary>
|
||||
private static readonly GameFileReference[] PLA =
|
||||
private static readonly GameFileReference[] FilesPLA =
|
||||
{
|
||||
new(GameFile.TrainerData, "bin", "trainer"),
|
||||
new(TrainerSpecData, "bin", "trainer"),
|
||||
|
||||
new(GameFile.GameText0, 0, "bin", "message", "JPN", "common"),
|
||||
new(GameFile.GameText1, 1, "bin", "message", "JPN_KANJI", "common"),
|
||||
new(GameFile.GameText2, 2, "bin", "message", "English", "common"),
|
||||
new(GameFile.GameText3, 3, "bin", "message", "French", "common"),
|
||||
new(GameFile.GameText4, 4, "bin", "message", "Italian", "common"),
|
||||
new(GameFile.GameText5, 5, "bin", "message", "German", "common"),
|
||||
new(GameText0, 0, "bin", "message", "JPN", "common"),
|
||||
new(GameText1, 1, "bin", "message", "JPN_KANJI", "common"),
|
||||
new(GameText2, 2, "bin", "message", "English", "common"),
|
||||
new(GameText3, 3, "bin", "message", "French", "common"),
|
||||
new(GameText4, 4, "bin", "message", "Italian", "common"),
|
||||
new(GameText5, 5, "bin", "message", "German", "common"),
|
||||
// 6 unused lang
|
||||
new(GameFile.GameText6, 7, "bin", "message", "Spanish", "common"),
|
||||
new(GameFile.GameText7, 8, "bin", "message", "Korean", "common"),
|
||||
new(GameFile.GameText8, 9, "bin", "message", "Simp_Chinese", "common"),
|
||||
new(GameFile.GameText9, 10, "bin", "message", "Trad_Chinese", "common"),
|
||||
new(GameText6, 7, "bin", "message", "Spanish", "common"),
|
||||
new(GameText7, 8, "bin", "message", "Korean", "common"),
|
||||
new(GameText8, 9, "bin", "message", "Simp_Chinese", "common"),
|
||||
new(GameText9, 10, "bin", "message", "Trad_Chinese", "common"),
|
||||
|
||||
new(GameFile.StoryText0, 0, "bin", "message", "JPN", "script"),
|
||||
new(GameFile.StoryText1, 1, "bin", "message", "JPN_KANJI", "script"),
|
||||
new(GameFile.StoryText2, 2, "bin", "message", "English", "script"),
|
||||
new(GameFile.StoryText3, 3, "bin", "message", "French", "script"),
|
||||
new(GameFile.StoryText4, 4, "bin", "message", "Italian", "script"),
|
||||
new(GameFile.StoryText5, 5, "bin", "message", "German", "script"),
|
||||
new(StoryText0, 0, "bin", "message", "JPN", "script"),
|
||||
new(StoryText1, 1, "bin", "message", "JPN_KANJI", "script"),
|
||||
new(StoryText2, 2, "bin", "message", "English", "script"),
|
||||
new(StoryText3, 3, "bin", "message", "French", "script"),
|
||||
new(StoryText4, 4, "bin", "message", "Italian", "script"),
|
||||
new(StoryText5, 5, "bin", "message", "German", "script"),
|
||||
// 6 unused lang
|
||||
new(GameFile.StoryText6, 7, "bin", "message", "Spanish", "script"),
|
||||
new(GameFile.StoryText7, 8, "bin", "message", "Korean", "script"),
|
||||
new(GameFile.StoryText8, 9, "bin", "message", "Simp_Chinese", "script"),
|
||||
new(GameFile.StoryText9, 10, "bin", "message", "Trad_Chinese", "script"),
|
||||
new(StoryText6, 7, "bin", "message", "Spanish", "script"),
|
||||
new(StoryText7, 8, "bin", "message", "Korean", "script"),
|
||||
new(StoryText8, 9, "bin", "message", "Simp_Chinese", "script"),
|
||||
new(StoryText9, 10, "bin", "message", "Trad_Chinese", "script"),
|
||||
|
||||
new(GameFile.DexFormStorage , ContainerType.SingleFile, "bin", "appli", "pokedex", "res_table", "pokedex_form_storage_index_table.bin"),
|
||||
new(GameFile.DexRank , ContainerType.SingleFile, "bin", "appli", "pokedex", "res_table", "pokedex_rank_table.bin"),
|
||||
new(GameFile.DexResearch , ContainerType.SingleFile, "bin", "appli", "pokedex", "res_table", "pokedex_research_task_table.bin"),
|
||||
new(GameFile.PokemonResourceList , ContainerType.SingleFile, "bin", "appli", "res_pokemon", "list", "pokemon_info_list.bin"),
|
||||
new(GameFile.MoveShop , ContainerType.SingleFile, "bin", "appli", "wazaremember", "bin", "wazashop_table.bin"),
|
||||
new(GameFile.HaShop , ContainerType.SingleFile, "bin", "appli", "shop", "bin", "ha_shop_data.bin"),
|
||||
new(DexFormStorage , SingleFile, "bin", "appli", "pokedex", "res_table", "pokedex_form_storage_index_table.bin"),
|
||||
new(DexRank , SingleFile, "bin", "appli", "pokedex", "res_table", "pokedex_rank_table.bin"),
|
||||
new(DexResearch , SingleFile, "bin", "appli", "pokedex", "res_table", "pokedex_research_task_table.bin"),
|
||||
new(PokemonResourceList , SingleFile, "bin", "appli", "res_pokemon", "list", "pokemon_info_list.bin"),
|
||||
new(MoveShop , SingleFile, "bin", "appli", "wazaremember", "bin", "wazashop_table.bin"),
|
||||
new(HaShop , SingleFile, "bin", "appli", "shop", "bin", "ha_shop_data.bin"),
|
||||
|
||||
new(GameFile.ArchiveFolder , "bin", "archive"),
|
||||
new(GameFile.Resident , ContainerType.GFPack , "bin", "archive", "field", "resident_release.gfpak"),
|
||||
new(GameFile.archive_contents , ContainerType.SingleFile, "bin", "archive", "archive_contents.bin"),
|
||||
new(ArchiveFolder , "bin", "archive"),
|
||||
new(Resident , GameFreakPack , "bin", "archive", "field", "resident_release.gfpak"),
|
||||
new(archive_contents , SingleFile, "bin", "archive", "archive_contents.bin"),
|
||||
|
||||
new(GameFile.ThrowParam , ContainerType.SingleFile, "bin", "capture", "throw_param_table.bin"),
|
||||
new(GameFile.ThrowPermissionSet , ContainerType.SingleFile, "bin", "capture", "throw_permissionset_dictionary.bin"),
|
||||
new(GameFile.ThrowableParam , ContainerType.SingleFile, "bin", "capture", "throwable_param_table.bin"),
|
||||
new(GameFile.ThrowableResource , ContainerType.SingleFile, "bin", "capture", "throwable_resource_dictionary.bin"),
|
||||
new(GameFile.ThrowableResourceSet , ContainerType.SingleFile, "bin", "capture", "throwable_resourceset_dictionary.bin"),
|
||||
new(ThrowParam , SingleFile, "bin", "capture", "throw_param_table.bin"),
|
||||
new(ThrowPermissionSet , SingleFile, "bin", "capture", "throw_permissionset_dictionary.bin"),
|
||||
new(ThrowableParam , SingleFile, "bin", "capture", "throwable_param_table.bin"),
|
||||
new(ThrowableResource , SingleFile, "bin", "capture", "throwable_resource_dictionary.bin"),
|
||||
new(ThrowableResourceSet , SingleFile, "bin", "capture", "throwable_resourceset_dictionary.bin"),
|
||||
|
||||
new(GameFile.Player1DressupTable , ContainerType.SingleFile, "bin", "chara", "table", "dressup_table_p1.bin"),
|
||||
new(GameFile.Player2DressupTable , ContainerType.SingleFile, "bin", "chara", "table", "dressup_table_p2.bin"),
|
||||
new(Player1DressupTable , SingleFile, "bin", "chara", "table", "dressup_table_p1.bin"),
|
||||
new(Player2DressupTable , SingleFile, "bin", "chara", "table", "dressup_table_p2.bin"),
|
||||
|
||||
new(GameFile.Outbreak , ContainerType.SingleFile, "bin", "field", "encount", "huge_outbreak.bin"),
|
||||
new(GameFile.NewHugeGroup , ContainerType.SingleFile, "bin", "field", "encount", "new_huge_outbreak_group.bin"),
|
||||
new(GameFile.NewHugeGroupLottery , ContainerType.SingleFile, "bin", "field", "encount", "new_huge_outbreak_group_lottery.bin"),
|
||||
new(GameFile.NewHugeLottery , ContainerType.SingleFile, "bin", "field", "encount", "new_huge_outbreak_lottery.bin"),
|
||||
new(GameFile.NewHugeTimeLimit , ContainerType.SingleFile, "bin", "field", "encount", "new_huge_outbreak_time_limit.bin"),
|
||||
new(Outbreak , SingleFile, "bin", "field", "encount", "huge_outbreak.bin"),
|
||||
new(NewHugeGroup , SingleFile, "bin", "field", "encount", "new_huge_outbreak_group.bin"),
|
||||
new(NewHugeGroupLottery , SingleFile, "bin", "field", "encount", "new_huge_outbreak_group_lottery.bin"),
|
||||
new(NewHugeLottery , SingleFile, "bin", "field", "encount", "new_huge_outbreak_lottery.bin"),
|
||||
new(NewHugeTimeLimit , SingleFile, "bin", "field", "encount", "new_huge_outbreak_time_limit.bin"),
|
||||
|
||||
new(GameFile.AICommonConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "ai_common_config.bin"),
|
||||
new(GameFile.AIExcitingConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "ai_exciting_config.bin"),
|
||||
new(GameFile.AIFieldWazaConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "ai_field_waza_config.bin"),
|
||||
new(GameFile.AISemiLegendConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "ai_semi_legend_config.bin"),
|
||||
new(GameFile.AITirednessConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "ai_tiredness_config.bin"),
|
||||
new(GameFile.AppConfigList , ContainerType.SingleFile, "bin", "misc", "app_config", "app_config_list.bin"),
|
||||
new(GameFile.AppliHudConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "appli_hud_config.bin"),
|
||||
new(GameFile.AppliStaffrollConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "appli_staffroll_config.bin"),
|
||||
new(GameFile.AppliTipsConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "appli_tips_config.bin"),
|
||||
new(GameFile.BattleCommonConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "battle_common_config.bin"),
|
||||
new(GameFile.BattleEndConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "battle_end_config.bin"),
|
||||
new(GameFile.BattleInConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "battle_in_config.bin"),
|
||||
new(GameFile.BattleLogicConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "battle_logic_config.bin"),
|
||||
new(GameFile.BattleStartConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "battle_start_config.bin"),
|
||||
new(GameFile.BattleViewConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "battle_view_config.bin"),
|
||||
new(GameFile.BattleVsnsConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "battle_vsns_config.bin"),
|
||||
new(GameFile.BuddyBattleConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "buddy_battle_config.bin"),
|
||||
new(GameFile.BuddyConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "buddy_config.bin"),
|
||||
new(GameFile.BuddyDirectItemConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "buddy_direct_item_config.bin"),
|
||||
new(GameFile.BuddyGroupTalkConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "buddy_group_talk_config.bin"),
|
||||
new(GameFile.BuddyLandmarkConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "buddy_landmark_config.bin"),
|
||||
new(GameFile.BuddyNPCReactionConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "buddy_npc_reaction_config.bin"),
|
||||
new(GameFile.BuddyPlayerModeConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "buddy_player_mode_config.bin"),
|
||||
new(GameFile.BuddyWarpConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "buddy_warp_config.bin"),
|
||||
new(GameFile.CharacterBipedIkConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "character_biped_ik_config.bin"),
|
||||
new(GameFile.CharacterBlinkConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "character_blink_config.bin"),
|
||||
new(GameFile.CharacterControllerConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "character_controller_config.bin"),
|
||||
new(GameFile.CharacterLookAtConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "character_look_at_config.bin"),
|
||||
new(GameFile.CaptureConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "common_capture_config.bin"),
|
||||
new(GameFile.CommonGeneralConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "common_general_config.bin"),
|
||||
new(GameFile.CommonItemConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "common_item_config.bin"),
|
||||
new(GameFile.DemoConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "demo_config.bin"),
|
||||
new(GameFile.EnvPokeVoiceConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "env_poke_voice_config.bin"),
|
||||
new(GameFile.EventBalloonrunConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "event_balloonrun_config.bin"),
|
||||
new(GameFile.EventBalloonthrowConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "event_balloonthrow_config.bin"),
|
||||
new(GameFile.EventBanditConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "event_bandit_config.bin"),
|
||||
new(GameFile.EventCullingConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "event_culling_config.bin"),
|
||||
new(GameFile.EventDitherConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "event_dither_config.bin"),
|
||||
new(GameFile.EventFarmConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "event_farm_config.bin"),
|
||||
new(GameFile.EventGameOverConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "event_game_over_config.bin"),
|
||||
new(GameFile.EventItemConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "event_item_config.bin"),
|
||||
new(GameFile.EventMkrgRewardConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "event_mkrg_reward_config.bin"),
|
||||
new(GameFile.EventQuestBoardConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "event_quest_board_config.bin"),
|
||||
new(GameFile.EventRestrictionBattle , ContainerType.SingleFile, "bin", "misc", "app_config", "event_restriction_battle.bin"),
|
||||
new(GameFile.EventWork , ContainerType.SingleFile, "bin", "misc", "app_config", "event_work.bin"),
|
||||
new(GameFile.FieldAnimationFramerateConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "field_anime_framerate_config.bin"),
|
||||
new(GameFile.FieldAreaSpeedConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "field_area_speed_config.bin"),
|
||||
new(GameFile.FieldCameraConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "field_camera_config.bin"),
|
||||
new(GameFile.FieldCaptureDirectorConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "field_capture_director_config.bin"),
|
||||
new(GameFile.FieldCharaViewerConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "field_chara_viewer_config.bin"),
|
||||
new(GameFile.FieldCommonConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "field_common_config.bin"),
|
||||
new(GameFile.FieldDirectItemConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "field_direct_item_config.bin"),
|
||||
new(GameFile.FieldEnvConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "field_env_config.bin"),
|
||||
new(GameFile.OutbreakConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "field_huge_outbreak.bin"),
|
||||
new(GameFile.FieldItem , ContainerType.SingleFile, "bin", "misc", "app_config", "field_item.bin"),
|
||||
new(GameFile.FieldItemRespawn , ContainerType.SingleFile, "bin", "misc", "app_config", "field_item_respawn.bin"),
|
||||
new(GameFile.FieldLandmarkConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "field_landmark_config.bin"),
|
||||
new(GameFile.FieldLandmarkInciteConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "field_landmark_incite_config.bin"),
|
||||
new(GameFile.FieldLockonConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "field_lockon_config.bin"),
|
||||
new(GameFile.BallThrowConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "field_my_poke_ball_config.bin"),
|
||||
new(GameFile.FieldBallMissedConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "field_my_poke_ball_hit_none_target_config.bin"),
|
||||
new(GameFile.FieldObstructionWazaConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "field_obstruction_waza_config.bin"),
|
||||
new(GameFile.FieldPokemonSlopeConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "field_pokemon_slope_config.bin"),
|
||||
new(GameFile.FieldQuestDestinationConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "field_quest_destination_config.bin"),
|
||||
new(GameFile.FieldShadowConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "field_shadow_config.bin"),
|
||||
new(GameFile.FieldSpawnerConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "field_spawner_config.bin"),
|
||||
new(GameFile.FieldThrowConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "field_throw_config.bin"),
|
||||
new(GameFile.FieldThrowableAfterHitConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "field_throwable_after_hit_config.bin"),
|
||||
new(GameFile.FieldVigilanceBgmConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "field_vigilance_bgm_config.bin"),
|
||||
new(GameFile.FieldWeatheringConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "field_weathering_config.bin"),
|
||||
new(GameFile.FieldWildPokemonConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "field_wild_pokemon_config.bin"),
|
||||
new(GameFile.WormholeConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "field_wormhole_config.bin"),
|
||||
new(GameFile.NPCAIConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "npc_ai_config.bin"),
|
||||
new(GameFile.NPCControllerConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "npc_controller_config.bin"),
|
||||
new(GameFile.NPCCreaterConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "npc_creater_config.bin"),
|
||||
new(GameFile.NPCPokemonAIConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "npc_pokemon_ai_config.bin"),
|
||||
new(GameFile.NPCPopupConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "npc_popup_config.bin"),
|
||||
new(GameFile.NPCTalkTableConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "npc_talk_table_config.bin"),
|
||||
new(GameFile.PlayerCameraShakeConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "player_camera_shake_config.bin"),
|
||||
new(GameFile.PlayerCollisionConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "player_collision_config.bin"),
|
||||
new(GameFile.PlayerConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "player_config.bin"),
|
||||
new(GameFile.PlayerControllerConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "player_controller_config.bin"),
|
||||
new(GameFile.PlayerFaceConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "player_face_config.bin"),
|
||||
new(GameFile.PokemonConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "pokemon_config.bin"),
|
||||
new(GameFile.PokemonControllerConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "pokemon_controller_config.bin"),
|
||||
new(GameFile.EvolutionConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "pokemon_evolution_config.bin"),
|
||||
new(GameFile.PokemonFriendshipConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "pokemon_friendship_config.bin"),
|
||||
new(GameFile.ShinyRolls , ContainerType.SingleFile, "bin", "misc", "app_config", "pokemon_rare.bin"),
|
||||
new(GameFile.SizeScaleConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "pokemon_size_category_adjust_scale_config.bin"),
|
||||
new(GameFile.RideBasuraoCollisionConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "ride_basurao_collision_config.bin"),
|
||||
new(GameFile.RideBasuraoConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "ride_basurao_config.bin"),
|
||||
new(GameFile.RideChangeConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "ride_change_config.bin"),
|
||||
new(GameFile.RideCommonConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "ride_common_config.bin"),
|
||||
new(GameFile.RideNyuuraCollisionConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "ride_nyuura_collision_config.bin"),
|
||||
new(GameFile.RideNyuuraConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "ride_nyuura_config.bin"),
|
||||
new(GameFile.RideNyuuraControllerConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "ride_nyuura_controller_config.bin"),
|
||||
new(GameFile.RideOdoshishiCollisionConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "ride_odoshishi_collision_config.bin"),
|
||||
new(GameFile.RideOdoshishiConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "ride_odoshishi_config.bin"),
|
||||
new(GameFile.RideRingumaCollisionConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "ride_ringuma_collision_config.bin"),
|
||||
new(GameFile.RideRingumaConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "ride_ringuma_config.bin"),
|
||||
new(GameFile.RideRingumaControllerConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "ride_ringuma_controller_config.bin"),
|
||||
new(GameFile.RideWhooguruCollisionConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "ride_whooguru_collision_config.bin"),
|
||||
new(GameFile.RideWhooguruConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "ride_whooguru_config.bin"),
|
||||
new(GameFile.RideWhooguruControllerConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "ride_whooguru_controller_config.bin"),
|
||||
new(GameFile.SoundConfig , ContainerType.SingleFile, "bin", "misc", "app_config", "sound_config.bin"),
|
||||
new(GameFile.WaterMotion , ContainerType.SingleFile, "bin", "misc", "app_config", "water_motion.bin"),
|
||||
new(AICommonConfig , SingleFile, "bin", "misc", "app_config", "ai_common_config.bin"),
|
||||
new(AIExcitingConfig , SingleFile, "bin", "misc", "app_config", "ai_exciting_config.bin"),
|
||||
new(AIFieldWazaConfig , SingleFile, "bin", "misc", "app_config", "ai_field_waza_config.bin"),
|
||||
new(AISemiLegendConfig , SingleFile, "bin", "misc", "app_config", "ai_semi_legend_config.bin"),
|
||||
new(AITirednessConfig , SingleFile, "bin", "misc", "app_config", "ai_tiredness_config.bin"),
|
||||
new(AppConfigList , SingleFile, "bin", "misc", "app_config", "app_config_list.bin"),
|
||||
new(AppliHudConfig , SingleFile, "bin", "misc", "app_config", "appli_hud_config.bin"),
|
||||
new(AppliStaffrollConfig , SingleFile, "bin", "misc", "app_config", "appli_staffroll_config.bin"),
|
||||
new(AppliTipsConfig , SingleFile, "bin", "misc", "app_config", "appli_tips_config.bin"),
|
||||
new(BattleCommonConfig , SingleFile, "bin", "misc", "app_config", "battle_common_config.bin"),
|
||||
new(BattleEndConfig , SingleFile, "bin", "misc", "app_config", "battle_end_config.bin"),
|
||||
new(BattleInConfig , SingleFile, "bin", "misc", "app_config", "battle_in_config.bin"),
|
||||
new(BattleLogicConfig , SingleFile, "bin", "misc", "app_config", "battle_logic_config.bin"),
|
||||
new(BattleStartConfig , SingleFile, "bin", "misc", "app_config", "battle_start_config.bin"),
|
||||
new(BattleViewConfig , SingleFile, "bin", "misc", "app_config", "battle_view_config.bin"),
|
||||
new(BattleVsnsConfig , SingleFile, "bin", "misc", "app_config", "battle_vsns_config.bin"),
|
||||
new(BuddyBattleConfig , SingleFile, "bin", "misc", "app_config", "buddy_battle_config.bin"),
|
||||
new(BuddyConfig , SingleFile, "bin", "misc", "app_config", "buddy_config.bin"),
|
||||
new(BuddyDirectItemConfig , SingleFile, "bin", "misc", "app_config", "buddy_direct_item_config.bin"),
|
||||
new(BuddyGroupTalkConfig , SingleFile, "bin", "misc", "app_config", "buddy_group_talk_config.bin"),
|
||||
new(BuddyLandmarkConfig , SingleFile, "bin", "misc", "app_config", "buddy_landmark_config.bin"),
|
||||
new(BuddyNPCReactionConfig , SingleFile, "bin", "misc", "app_config", "buddy_npc_reaction_config.bin"),
|
||||
new(BuddyPlayerModeConfig , SingleFile, "bin", "misc", "app_config", "buddy_player_mode_config.bin"),
|
||||
new(BuddyWarpConfig , SingleFile, "bin", "misc", "app_config", "buddy_warp_config.bin"),
|
||||
new(CharacterBipedIkConfig , SingleFile, "bin", "misc", "app_config", "character_biped_ik_config.bin"),
|
||||
new(CharacterBlinkConfig , SingleFile, "bin", "misc", "app_config", "character_blink_config.bin"),
|
||||
new(CharacterControllerConfig , SingleFile, "bin", "misc", "app_config", "character_controller_config.bin"),
|
||||
new(CharacterLookAtConfig , SingleFile, "bin", "misc", "app_config", "character_look_at_config.bin"),
|
||||
new(CaptureConfig , SingleFile, "bin", "misc", "app_config", "common_capture_config.bin"),
|
||||
new(CommonGeneralConfig , SingleFile, "bin", "misc", "app_config", "common_general_config.bin"),
|
||||
new(CommonItemConfig , SingleFile, "bin", "misc", "app_config", "common_item_config.bin"),
|
||||
new(DemoConfig , SingleFile, "bin", "misc", "app_config", "demo_config.bin"),
|
||||
new(EnvPokeVoiceConfig , SingleFile, "bin", "misc", "app_config", "env_poke_voice_config.bin"),
|
||||
new(EventBalloonrunConfig , SingleFile, "bin", "misc", "app_config", "event_balloonrun_config.bin"),
|
||||
new(EventBalloonthrowConfig , SingleFile, "bin", "misc", "app_config", "event_balloonthrow_config.bin"),
|
||||
new(EventBanditConfig , SingleFile, "bin", "misc", "app_config", "event_bandit_config.bin"),
|
||||
new(EventCullingConfig , SingleFile, "bin", "misc", "app_config", "event_culling_config.bin"),
|
||||
new(EventDitherConfig , SingleFile, "bin", "misc", "app_config", "event_dither_config.bin"),
|
||||
new(EventFarmConfig , SingleFile, "bin", "misc", "app_config", "event_farm_config.bin"),
|
||||
new(EventGameOverConfig , SingleFile, "bin", "misc", "app_config", "event_game_over_config.bin"),
|
||||
new(EventItemConfig , SingleFile, "bin", "misc", "app_config", "event_item_config.bin"),
|
||||
new(EventMkrgRewardConfig , SingleFile, "bin", "misc", "app_config", "event_mkrg_reward_config.bin"),
|
||||
new(EventQuestBoardConfig , SingleFile, "bin", "misc", "app_config", "event_quest_board_config.bin"),
|
||||
new(EventRestrictionBattle , SingleFile, "bin", "misc", "app_config", "event_restriction_battle.bin"),
|
||||
new(EventWork , SingleFile, "bin", "misc", "app_config", "event_work.bin"),
|
||||
new(FieldAnimationFramerateConfig , SingleFile, "bin", "misc", "app_config", "field_anime_framerate_config.bin"),
|
||||
new(FieldAreaSpeedConfig , SingleFile, "bin", "misc", "app_config", "field_area_speed_config.bin"),
|
||||
new(FieldCameraConfig , SingleFile, "bin", "misc", "app_config", "field_camera_config.bin"),
|
||||
new(FieldCaptureDirectorConfig , SingleFile, "bin", "misc", "app_config", "field_capture_director_config.bin"),
|
||||
new(FieldCharaViewerConfig , SingleFile, "bin", "misc", "app_config", "field_chara_viewer_config.bin"),
|
||||
new(FieldCommonConfig , SingleFile, "bin", "misc", "app_config", "field_common_config.bin"),
|
||||
new(FieldDirectItemConfig , SingleFile, "bin", "misc", "app_config", "field_direct_item_config.bin"),
|
||||
new(FieldEnvConfig , SingleFile, "bin", "misc", "app_config", "field_env_config.bin"),
|
||||
new(OutbreakConfig , SingleFile, "bin", "misc", "app_config", "field_huge_outbreak.bin"),
|
||||
new(FieldItem , SingleFile, "bin", "misc", "app_config", "field_item.bin"),
|
||||
new(FieldItemRespawn , SingleFile, "bin", "misc", "app_config", "field_item_respawn.bin"),
|
||||
new(FieldLandmarkConfig , SingleFile, "bin", "misc", "app_config", "field_landmark_config.bin"),
|
||||
new(FieldLandmarkInciteConfig , SingleFile, "bin", "misc", "app_config", "field_landmark_incite_config.bin"),
|
||||
new(FieldLockonConfig , SingleFile, "bin", "misc", "app_config", "field_lockon_config.bin"),
|
||||
new(BallThrowConfig , SingleFile, "bin", "misc", "app_config", "field_my_poke_ball_config.bin"),
|
||||
new(FieldBallMissedConfig , SingleFile, "bin", "misc", "app_config", "field_my_poke_ball_hit_none_target_config.bin"),
|
||||
new(FieldObstructionWazaConfig , SingleFile, "bin", "misc", "app_config", "field_obstruction_waza_config.bin"),
|
||||
new(FieldPokemonSlopeConfig , SingleFile, "bin", "misc", "app_config", "field_pokemon_slope_config.bin"),
|
||||
new(FieldQuestDestinationConfig , SingleFile, "bin", "misc", "app_config", "field_quest_destination_config.bin"),
|
||||
new(FieldShadowConfig , SingleFile, "bin", "misc", "app_config", "field_shadow_config.bin"),
|
||||
new(FieldSpawnerConfig , SingleFile, "bin", "misc", "app_config", "field_spawner_config.bin"),
|
||||
new(FieldThrowConfig , SingleFile, "bin", "misc", "app_config", "field_throw_config.bin"),
|
||||
new(FieldThrowableAfterHitConfig , SingleFile, "bin", "misc", "app_config", "field_throwable_after_hit_config.bin"),
|
||||
new(FieldVigilanceBgmConfig , SingleFile, "bin", "misc", "app_config", "field_vigilance_bgm_config.bin"),
|
||||
new(FieldWeatheringConfig , SingleFile, "bin", "misc", "app_config", "field_weathering_config.bin"),
|
||||
new(FieldWildPokemonConfig , SingleFile, "bin", "misc", "app_config", "field_wild_pokemon_config.bin"),
|
||||
new(WormholeConfig , SingleFile, "bin", "misc", "app_config", "field_wormhole_config.bin"),
|
||||
new(NPCAIConfig , SingleFile, "bin", "misc", "app_config", "npc_ai_config.bin"),
|
||||
new(NPCControllerConfig , SingleFile, "bin", "misc", "app_config", "npc_controller_config.bin"),
|
||||
new(NPCCreaterConfig , SingleFile, "bin", "misc", "app_config", "npc_creater_config.bin"),
|
||||
new(NPCPokemonAIConfig , SingleFile, "bin", "misc", "app_config", "npc_pokemon_ai_config.bin"),
|
||||
new(NPCPopupConfig , SingleFile, "bin", "misc", "app_config", "npc_popup_config.bin"),
|
||||
new(NPCTalkTableConfig , SingleFile, "bin", "misc", "app_config", "npc_talk_table_config.bin"),
|
||||
new(PlayerCameraShakeConfig , SingleFile, "bin", "misc", "app_config", "player_camera_shake_config.bin"),
|
||||
new(PlayerCollisionConfig , SingleFile, "bin", "misc", "app_config", "player_collision_config.bin"),
|
||||
new(PlayerConfig , SingleFile, "bin", "misc", "app_config", "player_config.bin"),
|
||||
new(PlayerControllerConfig , SingleFile, "bin", "misc", "app_config", "player_controller_config.bin"),
|
||||
new(PlayerFaceConfig , SingleFile, "bin", "misc", "app_config", "player_face_config.bin"),
|
||||
new(PokemonConfig , SingleFile, "bin", "misc", "app_config", "pokemon_config.bin"),
|
||||
new(PokemonControllerConfig , SingleFile, "bin", "misc", "app_config", "pokemon_controller_config.bin"),
|
||||
new(EvolutionConfig , SingleFile, "bin", "misc", "app_config", "pokemon_evolution_config.bin"),
|
||||
new(PokemonFriendshipConfig , SingleFile, "bin", "misc", "app_config", "pokemon_friendship_config.bin"),
|
||||
new(ShinyRolls , SingleFile, "bin", "misc", "app_config", "pokemon_rare.bin"),
|
||||
new(SizeScaleConfig , SingleFile, "bin", "misc", "app_config", "pokemon_size_category_adjust_scale_config.bin"),
|
||||
new(RideBasuraoCollisionConfig , SingleFile, "bin", "misc", "app_config", "ride_basurao_collision_config.bin"),
|
||||
new(RideBasuraoConfig , SingleFile, "bin", "misc", "app_config", "ride_basurao_config.bin"),
|
||||
new(RideChangeConfig , SingleFile, "bin", "misc", "app_config", "ride_change_config.bin"),
|
||||
new(RideCommonConfig , SingleFile, "bin", "misc", "app_config", "ride_common_config.bin"),
|
||||
new(RideNyuuraCollisionConfig , SingleFile, "bin", "misc", "app_config", "ride_nyuura_collision_config.bin"),
|
||||
new(RideNyuuraConfig , SingleFile, "bin", "misc", "app_config", "ride_nyuura_config.bin"),
|
||||
new(RideNyuuraControllerConfig , SingleFile, "bin", "misc", "app_config", "ride_nyuura_controller_config.bin"),
|
||||
new(RideOdoshishiCollisionConfig , SingleFile, "bin", "misc", "app_config", "ride_odoshishi_collision_config.bin"),
|
||||
new(RideOdoshishiConfig , SingleFile, "bin", "misc", "app_config", "ride_odoshishi_config.bin"),
|
||||
new(RideRingumaCollisionConfig , SingleFile, "bin", "misc", "app_config", "ride_ringuma_collision_config.bin"),
|
||||
new(RideRingumaConfig , SingleFile, "bin", "misc", "app_config", "ride_ringuma_config.bin"),
|
||||
new(RideRingumaControllerConfig , SingleFile, "bin", "misc", "app_config", "ride_ringuma_controller_config.bin"),
|
||||
new(RideWhooguruCollisionConfig , SingleFile, "bin", "misc", "app_config", "ride_whooguru_collision_config.bin"),
|
||||
new(RideWhooguruConfig , SingleFile, "bin", "misc", "app_config", "ride_whooguru_config.bin"),
|
||||
new(RideWhooguruControllerConfig , SingleFile, "bin", "misc", "app_config", "ride_whooguru_controller_config.bin"),
|
||||
new(SoundConfig , SingleFile, "bin", "misc", "app_config", "sound_config.bin"),
|
||||
new(WaterMotion , SingleFile, "bin", "misc", "app_config", "water_motion.bin"),
|
||||
|
||||
new(GameFile.MoveStats , "bin", "pml", "waza"),
|
||||
new(GameFile.ItemStats , ContainerType.SingleFile, "bin", "pml", "item", "item.dat"),
|
||||
new(GameFile.Evolutions , ContainerType.SingleFile, "bin", "pml", "evolution", "evolution_data_total.evobin"),
|
||||
new(GameFile.PersonalStats , ContainerType.SingleFile, "bin", "pml", "personal", "personal_data_total.perbin"),
|
||||
new(GameFile.Learnsets , ContainerType.SingleFile, "bin", "pml", "waza_oboe", "waza_oboe_total.wazaoboe"),
|
||||
new(MoveStats , "bin", "pml", "waza"),
|
||||
new(ItemStats , SingleFile, "bin", "pml", "item", "item.dat"),
|
||||
new(Evolutions , SingleFile, "bin", "pml", "evolution", "evolution_data_total.evobin"),
|
||||
new(PersonalStats , SingleFile, "bin", "pml", "personal", "personal_data_total.perbin"),
|
||||
new(Learnsets , SingleFile, "bin", "pml", "waza_oboe", "waza_oboe_total.wazaoboe"),
|
||||
|
||||
new(GameFile.EncounterGift , ContainerType.SingleFile, "bin", "pokemon", "data", "poke_add.bin"),
|
||||
new(GameFile.SymbolBehave , ContainerType.SingleFile, "bin", "pokemon", "data", "poke_ai.bin"),
|
||||
new(GameFile.PokeBattleSpawn , ContainerType.SingleFile, "bin", "pokemon", "data", "poke_battle_spawn.bin"),
|
||||
new(GameFile.PokeBodyParticle , ContainerType.SingleFile, "bin", "pokemon", "data", "poke_body_particle.bin"),
|
||||
new(GameFile.PokeCaptureCollision , ContainerType.SingleFile, "bin", "pokemon", "data", "poke_capture_collision.bin"),
|
||||
new(GameFile.PokeDefaultLocator , ContainerType.SingleFile, "bin", "pokemon", "data", "poke_default_locator.trloc"),
|
||||
new(GameFile.FieldDrops , ContainerType.SingleFile, "bin", "pokemon", "data", "poke_drop_item.bin"),
|
||||
new(GameFile.BattleDrops , ContainerType.SingleFile, "bin", "pokemon", "data", "poke_drop_item_battle.bin"),
|
||||
new(GameFile.PokeEatingHabits , ContainerType.SingleFile, "bin", "pokemon", "data", "poke_eating_habits.bin"),
|
||||
new(GameFile.EncounterRateTable , ContainerType.SingleFile, "bin", "pokemon", "data", "poke_encount.bin"),
|
||||
new(GameFile.EncounterStatic , ContainerType.SingleFile, "bin", "pokemon", "data", "poke_event_encount.bin"),
|
||||
new(GameFile.MoveObstructionLegend , ContainerType.SingleFile, "bin", "pokemon", "data", "poke_field_obstruction_waza_ns_legend.bin"),
|
||||
new(GameFile.MoveObstructionLegendEffect , ContainerType.SingleFile, "bin", "pokemon", "data", "poke_field_obstruction_waza_ns_legend_effect.bin"),
|
||||
new(GameFile.MoveObstructionSE , ContainerType.SingleFile, "bin", "pokemon", "data", "poke_field_obstruction_waza_se.bin"),
|
||||
new(GameFile.MoveObstructionWild , ContainerType.SingleFile, "bin", "pokemon", "data", "poke_field_obstruction_waza_wild.bin"),
|
||||
new(GameFile.MoveObstructionWildEffect , ContainerType.SingleFile, "bin", "pokemon", "data", "poke_field_obstruction_waza_wild_effect.bin"),
|
||||
new(GameFile.MoveObstructionWater , ContainerType.SingleFile, "bin", "pokemon", "data", "poke_field_obstruction_waza_wild_water.bin"),
|
||||
new(GameFile.MoveObstructionWaterEffect , ContainerType.SingleFile, "bin", "pokemon", "data", "poke_field_obstruction_waza_wild_water_effect.bin"),
|
||||
new(GameFile.PokeMisc , ContainerType.SingleFile, "bin", "pokemon", "data", "poke_misc.bin"),
|
||||
new(GameFile.NushiBattleSettings , ContainerType.SingleFile, "bin", "pokemon", "data", "poke_nushi_battle_setting.bin"),
|
||||
new(GameFile.PokemonResourceTable , ContainerType.SingleFile, "bin", "pokemon", "table", "poke_resource_table.trpmcatalog"),
|
||||
new(EncounterTableGift , SingleFile, "bin", "pokemon", "data", "poke_add.bin"),
|
||||
new(SymbolBehave , SingleFile, "bin", "pokemon", "data", "poke_ai.bin"),
|
||||
new(PokeBattleSpawn , SingleFile, "bin", "pokemon", "data", "poke_battle_spawn.bin"),
|
||||
new(PokeBodyParticle , SingleFile, "bin", "pokemon", "data", "poke_body_particle.bin"),
|
||||
new(PokeCaptureCollision , SingleFile, "bin", "pokemon", "data", "poke_capture_collision.bin"),
|
||||
new(PokeDefaultLocator , SingleFile, "bin", "pokemon", "data", "poke_default_locator.trloc"),
|
||||
new(FieldDrops , SingleFile, "bin", "pokemon", "data", "poke_drop_item.bin"),
|
||||
new(BattleDrops , SingleFile, "bin", "pokemon", "data", "poke_drop_item_battle.bin"),
|
||||
new(PokeEatingHabits , SingleFile, "bin", "pokemon", "data", "poke_eating_habits.bin"),
|
||||
new(EncounterRateTable , SingleFile, "bin", "pokemon", "data", "poke_encount.bin"),
|
||||
new(EncounterTableStatic , SingleFile, "bin", "pokemon", "data", "poke_event_encount.bin"),
|
||||
new(MoveObstructionLegend , SingleFile, "bin", "pokemon", "data", "poke_field_obstruction_waza_ns_legend.bin"),
|
||||
new(MoveObstructionLegendEffect , SingleFile, "bin", "pokemon", "data", "poke_field_obstruction_waza_ns_legend_effect.bin"),
|
||||
new(MoveObstructionSE , SingleFile, "bin", "pokemon", "data", "poke_field_obstruction_waza_se.bin"),
|
||||
new(MoveObstructionWild , SingleFile, "bin", "pokemon", "data", "poke_field_obstruction_waza_wild.bin"),
|
||||
new(MoveObstructionWildEffect , SingleFile, "bin", "pokemon", "data", "poke_field_obstruction_waza_wild_effect.bin"),
|
||||
new(MoveObstructionWater , SingleFile, "bin", "pokemon", "data", "poke_field_obstruction_waza_wild_water.bin"),
|
||||
new(MoveObstructionWaterEffect , SingleFile, "bin", "pokemon", "data", "poke_field_obstruction_waza_wild_water_effect.bin"),
|
||||
new(PokeMisc , SingleFile, "bin", "pokemon", "data", "poke_misc.bin"),
|
||||
new(NushiBattleSettings , SingleFile, "bin", "pokemon", "data", "poke_nushi_battle_setting.bin"),
|
||||
new(PokemonResourceTable , SingleFile, "bin", "pokemon", "table", "poke_resource_table.trpmcatalog"),
|
||||
|
||||
new(GameFile.EncounterTrade , ContainerType.SingleFile, "bin", "script_event_data", "field_trade.bin"), // Incorrect?
|
||||
new(EncounterTableTrade , SingleFile, "bin", "script_event_data", "field_trade.bin"), // Incorrect?
|
||||
|
||||
// Cutscenes bin\demo
|
||||
// Models bin\archive\pokemon
|
||||
// pretty much everything is obviously named :)
|
||||
};
|
||||
#endregion
|
||||
|
||||
#region Gen9
|
||||
/// <summary>
|
||||
/// Scarlet & Violet
|
||||
/// </summary>
|
||||
private static readonly GameFileReference[] FilesSV =
|
||||
{
|
||||
new(DataTrpfd, SingleFile, "arc", "data.trpfd"),
|
||||
new(DataTrpfs, SingleFile, "arc", "data.trpfs"),
|
||||
// new(TrainerSpecData, "bin", "trainer"),
|
||||
//
|
||||
// new(GameText0, 0, "bin", "message", "JPN", "common"),
|
||||
// new(GameText1, 1, "bin", "message", "JPN_KANJI", "common"),
|
||||
// new(GameText2, 2, "bin", "message", "English", "common"),
|
||||
// new(GameText3, 3, "bin", "message", "French", "common"),
|
||||
// new(GameText4, 4, "bin", "message", "Italian", "common"),
|
||||
// new(GameText5, 5, "bin", "message", "German", "common"),
|
||||
// // 6 unused lang
|
||||
// new(GameText6, 7, "bin", "message", "Spanish", "common"),
|
||||
// new(GameText7, 8, "bin", "message", "Korean", "common"),
|
||||
// new(GameText8, 9, "bin", "message", "Simp_Chinese", "common"),
|
||||
// new(GameText9, 10, "bin", "message", "Trad_Chinese", "common"),
|
||||
//
|
||||
// new(StoryText0, 0, "bin", "message", "JPN", "script"),
|
||||
// new(StoryText1, 1, "bin", "message", "JPN_KANJI", "script"),
|
||||
// new(StoryText2, 2, "bin", "message", "English", "script"),
|
||||
// new(StoryText3, 3, "bin", "message", "French", "script"),
|
||||
// new(StoryText4, 4, "bin", "message", "Italian", "script"),
|
||||
// new(StoryText5, 5, "bin", "message", "German", "script"),
|
||||
// // 6 unused lang
|
||||
// new(StoryText6, 7, "bin", "message", "Spanish", "script"),
|
||||
// new(StoryText7, 8, "bin", "message", "Korean", "script"),
|
||||
// new(StoryText8, 9, "bin", "message", "Simp_Chinese", "script"),
|
||||
// new(StoryText9, 10, "bin", "message", "Trad_Chinese", "script"),
|
||||
//
|
||||
// new(MoveStats , "bin", "pml", "waza"),
|
||||
// new(ItemStats , SingleFile, "bin", "pml", "item", "item.dat"),
|
||||
// new(Evolutions , SingleFile, "bin", "pml", "evolution", "evolution_data_total.evobin"),
|
||||
// new(PersonalStats , SingleFile, "bin", "pml", "personal", "personal_data_total.perbin"),
|
||||
// new(Learnsets , SingleFile, "bin", "pml", "waza_oboe", "waza_oboe_total.wazaoboe"),
|
||||
//
|
||||
// new(EncounterTableGift , SingleFile, "bin", "pokemon", "data", "poke_add.bin"),
|
||||
// new(EncounterTableTrade , SingleFile, "bin", "script_event_data", "field_trade.bin"), // Incorrect?
|
||||
};
|
||||
#endregion
|
||||
}
|
||||
|
|
|
|||
36
pkNX.Game/GameLoadResult.cs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
using System;
|
||||
|
||||
namespace pkNX.Game;
|
||||
|
||||
public enum GameLoadResult
|
||||
{
|
||||
Success,
|
||||
ExefsNotFound,
|
||||
DirectoryNotFound,
|
||||
RomfsNotFound,
|
||||
RomfsSelected,
|
||||
InvalidGameVersion,
|
||||
UnsupportedGame,
|
||||
|
||||
Failed = -1,
|
||||
}
|
||||
|
||||
public static class GameLoadResultExt
|
||||
{
|
||||
public static bool IsSuccess(this GameLoadResult result) => result < GameLoadResult.ExefsNotFound;
|
||||
|
||||
public static bool IsFailure(this GameLoadResult result) => !result.IsSuccess();
|
||||
|
||||
public static string GetErrorMsg(this GameLoadResult result) => result switch
|
||||
{
|
||||
GameLoadResult.Success => "Loaded successfully.",
|
||||
GameLoadResult.ExefsNotFound => "Could not detect exefs folder in the selected directory.",
|
||||
GameLoadResult.DirectoryNotFound => "The selected directory does not exist!",
|
||||
GameLoadResult.RomfsNotFound => "Could not detect romfs folder in the selected directory. Please select the folder that contains the romfs folder.",
|
||||
GameLoadResult.RomfsSelected => "You have selected the romfs folder, however pkNX needs to create a separate folder to keep a clean copy of the original romfs.",
|
||||
GameLoadResult.InvalidGameVersion => "Couldn't infer game version from romfs file count. Your game dump might have been corrupted.",
|
||||
GameLoadResult.UnsupportedGame => "This game is (currently) not supported by pkNX!",
|
||||
GameLoadResult.Failed => "Internal error occurred.",
|
||||
_ => throw new NotImplementedException(),
|
||||
};
|
||||
}
|
||||
|
|
@ -43,8 +43,8 @@ public static (GameLocation?, GameLoadResult) GetGame(string? dir, GameVersion g
|
|||
return (null, GameLoadResult.DirectoryNotFound);
|
||||
|
||||
var dirs = Directory.GetDirectories(dir);
|
||||
var romfs = Array.Find(dirs, z => Path.GetFileName(z).StartsWith("rom"));
|
||||
var exefs = Array.Find(dirs, z => Path.GetFileName(z).StartsWith("exe"));
|
||||
var romfs = Array.Find(dirs, z => Path.GetFileName(z).StartsWith("rom", StringComparison.CurrentCultureIgnoreCase));
|
||||
var exefs = Array.Find(dirs, z => Path.GetFileName(z).StartsWith("exe", StringComparison.CurrentCultureIgnoreCase));
|
||||
|
||||
if (romfs == null)
|
||||
{
|
||||
|
|
@ -87,6 +87,8 @@ private static GameVersion GetGameFromPath(string romfs, string? exefs)
|
|||
private const int FILECOUNT_LA = 18_370;
|
||||
private const int FILECOUNT_LA_101 = 18_371; // Ver. 1.0.1 (Day 1 Patch)
|
||||
private const int FILECOUNT_LA_110 = 19_095; // Ver. 1.1.0 (Daybreak)
|
||||
private const int FILECOUNT_SV = 24;
|
||||
private const int FILECOUNT_SV_101 = 25; // Ver. 1.0.1 (Day 1 Patch)
|
||||
|
||||
private static GameVersion GetGameFromCount(int fileCount, string romfs, string? exefs)
|
||||
{
|
||||
|
|
@ -141,6 +143,21 @@ private static GameVersion GetGameFromCount(int fileCount, string romfs, string?
|
|||
case FILECOUNT_LA or FILECOUNT_LA_101 or FILECOUNT_LA_110:
|
||||
return GameVersion.PLA;
|
||||
|
||||
case FILECOUNT_SV:
|
||||
case FILECOUNT_SV_101:
|
||||
{
|
||||
if (exefs == null)
|
||||
return GameVersion.SV;
|
||||
|
||||
return GetTitleID() switch
|
||||
{
|
||||
// todo sv
|
||||
"0100ABF008968000" => GameVersion.SL,
|
||||
"01008DB008C2C000" => GameVersion.VL,
|
||||
_ => GameVersion.SV, // can't figure out Title ID, default to SWSH so that wild editor prompts for version selection
|
||||
};
|
||||
}
|
||||
|
||||
default:
|
||||
return GameVersion.Invalid;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using pkNX.Containers;
|
||||
using pkNX.Structures;
|
||||
using static pkNX.Structures.GameVersion;
|
||||
|
||||
namespace pkNX.Game;
|
||||
|
||||
|
|
@ -65,7 +66,7 @@ protected GameManager(GameLocation rom, int language)
|
|||
/// </summary>
|
||||
/// <param name="file">File type to fetch</param>
|
||||
/// <returns>Container that contains the game data requested.</returns>
|
||||
public IFileContainer GetFile(GameFile file) => FileMap.GetFile(file, Language);
|
||||
public IFileContainer GetFile(GameFile file) => FileMap.GetFile(file, Language, this);
|
||||
|
||||
/// <summary>
|
||||
/// Fetches strings for the input <see cref="TextName"/>.
|
||||
|
|
@ -106,14 +107,12 @@ public FolderContainer GetFilteredFolder(GameFile type, Func<string, bool>? filt
|
|||
return c;
|
||||
}
|
||||
|
||||
public static GameManager GetManager(GameLocation loc, int language)
|
||||
public static GameManager GetManager(GameLocation loc, int language) => loc.Game switch
|
||||
{
|
||||
return loc.Game switch
|
||||
{
|
||||
GameVersion.GP or GameVersion.GE or GameVersion.GG => new GameManagerGG(loc, language),
|
||||
GameVersion.SW or GameVersion.SH or GameVersion.SWSH => new GameManagerSWSH(loc, language),
|
||||
GameVersion.PLA => new GameManagerPLA(loc, language),
|
||||
_ => throw new ArgumentException(nameof(loc.Game)),
|
||||
};
|
||||
}
|
||||
GP or GE or GG => new GameManagerGG(loc, language),
|
||||
SW or SH or SWSH => new GameManagerSWSH(loc, language),
|
||||
PLA => new GameManagerPLA(loc, language),
|
||||
SL or VL or SV => new GameManagerSV(loc, language),
|
||||
_ => throw new ArgumentException(nameof(loc.Game)),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
102
pkNX.Game/GameManagerSV.cs
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using pkNX.Containers;
|
||||
using pkNX.Structures.FlatBuffers;
|
||||
|
||||
namespace pkNX.Game;
|
||||
|
||||
public class GameManagerSV : GameManager, IFileInternal, IDisposable
|
||||
{
|
||||
private readonly TrinityFileSystemManager Manager;
|
||||
private string PathNPDM => Path.Combine(PathExeFS, "main.npdm");
|
||||
private string TitleID => BitConverter.ToUInt64(File.ReadAllBytes(PathNPDM), 0x290).ToString("X16");
|
||||
|
||||
public GameManagerSV(GameLocation rom, int language) : base(rom, language)
|
||||
{
|
||||
// TODO: Use GameFileMapping?
|
||||
|
||||
// Open the trpfs
|
||||
var pathTrpfs = Path.Combine(PathRomFS, "arc/data.trpfs");
|
||||
var pathTrpfd = Path.Combine(PathRomFS, "arc/data.trpfd");
|
||||
Manager = new TrinityFileSystemManager(pathTrpfs, pathTrpfd);
|
||||
}
|
||||
|
||||
public bool HasFile(string path) => Manager.HasFile(path);
|
||||
public bool HasFile(ulong hash) => Manager.HasFile(hash);
|
||||
public byte[] GetPackedFile(string path) => Manager.GetPackedFile(path);
|
||||
public byte[] GetPackedFile(ulong hash) => Manager.GetPackedFile(hash);
|
||||
|
||||
/// <summary>
|
||||
/// Generally useful game data that can be used by multiple editors.
|
||||
/// </summary>
|
||||
public GameData Data { get; protected set; } = null!;
|
||||
|
||||
protected override void SetMitm()
|
||||
{
|
||||
var basePath = Path.GetDirectoryName(ROM.RomFS);
|
||||
if (basePath is null)
|
||||
throw new InvalidDataException("Invalid ROMFS path.");
|
||||
var tid = ROM.ExeFS != null ? TitleID : "0100A3D008C5C000"; // no way to differentiate without exefs, so default to Scarlet
|
||||
var redirect = Path.Combine(basePath, tid);
|
||||
FileMitm.SetRedirect(basePath, redirect);
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
// initialize gametext
|
||||
//ResetText();
|
||||
|
||||
// initialize common structures
|
||||
//var personal = GetFilteredFolder(GameFile.PersonalStats, z => Path.GetFileNameWithoutExtension(z) == "personal_total");
|
||||
//var learn = this[GameFile.Learnsets][0];
|
||||
//var splitLearn = learn.Split(0x104);
|
||||
//Learn = new FakeContainer(splitLearn);
|
||||
|
||||
//var move = this[GameFile.MoveStats];
|
||||
//((FolderContainer)move).Initialize();
|
||||
Data = new GameData
|
||||
{
|
||||
//MoveData = new DataCache<IMove>(move)
|
||||
//{
|
||||
// Create = FlatBufferConverter.DeserializeFrom<Waza8>,
|
||||
// Write = z => FlatBufferConverter.SerializeFrom((Waza8)z),
|
||||
//},
|
||||
//LevelUpData = new DataCache<Learnset>(Learn)
|
||||
//{
|
||||
// Create = z => new Learnset8(z),
|
||||
// Write = z => z.Write(),
|
||||
//},
|
||||
|
||||
// folders
|
||||
//PersonalData = new PersonalTable8SWSH(personal[0]),
|
||||
//EvolutionData = new DataCache<EvolutionSet>(GetFilteredFolder(GameFile.Evolutions))
|
||||
//{
|
||||
// Create = data => new EvolutionSet8(data),
|
||||
// Write = evo => evo.Write(),
|
||||
//},
|
||||
};
|
||||
}
|
||||
|
||||
public void ResetMoves() => GetFilteredFolder(GameFile.MoveStats);
|
||||
|
||||
public void ResetText()
|
||||
{
|
||||
GetFilteredFolder(GameFile.GameText, z => Path.GetExtension(z) == ".dat");
|
||||
}
|
||||
|
||||
protected override void Terminate()
|
||||
{
|
||||
// Store Personal Data back in the file. Let the container detect if it is modified.
|
||||
//var personal = this[GameFile.PersonalStats];
|
||||
//personal[0] = Data.PersonalData.Table.SelectMany(z => ((IPersonalInfoBin)z).Write()).ToArray();
|
||||
//var learn = this[GameFile.Learnsets];
|
||||
//learn[0] = Learn.Files.SelectMany(z => z).ToArray();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Manager.Dispose();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
using System.Collections.Generic;
|
||||
using pkNX.Structures;
|
||||
using static pkNX.Game.TextName;
|
||||
using static pkNX.Structures.GameVersion;
|
||||
|
||||
namespace pkNX.Game;
|
||||
|
||||
|
|
@ -8,25 +9,19 @@ public static class TextMapping
|
|||
{
|
||||
public static IReadOnlyCollection<TextReference> GetMapping(GameVersion game) => game switch
|
||||
{
|
||||
GameVersion.XY => XY,
|
||||
GameVersion.ORASDEMO => AO,
|
||||
GameVersion.ORAS => AO,
|
||||
GameVersion.SMDEMO => SMDEMO,
|
||||
GameVersion.SN => SM,
|
||||
GameVersion.MN => SM,
|
||||
GameVersion.US => USUM,
|
||||
GameVersion.UM => USUM,
|
||||
GameVersion.GP => GG,
|
||||
GameVersion.GE => GG,
|
||||
GameVersion.GG => GG,
|
||||
GameVersion.SW => SWSH,
|
||||
GameVersion.SH => SWSH,
|
||||
GameVersion.SWSH => SWSH,
|
||||
GameVersion.PLA => PLA,
|
||||
X or Y or XY => MapXY,
|
||||
OR or AS or ORAS or ORASDEMO => MapAO,
|
||||
SMDEMO => MapSMDemo,
|
||||
SN or MN or SM => MapSM,
|
||||
US or UM or USUM => MapUSUM,
|
||||
GP or GE or GG => MapGG,
|
||||
SW or SH or SWSH => MapSWSH,
|
||||
PLA => MapPLA,
|
||||
SL or VL or SV => MapSV,
|
||||
_ => throw new System.ArgumentOutOfRangeException($"No text mapping for {game}"),
|
||||
};
|
||||
|
||||
private static readonly TextReference[] XY =
|
||||
private static readonly TextReference[] MapXY =
|
||||
{
|
||||
new(005, Forms),
|
||||
new(013, MoveNames),
|
||||
|
|
@ -46,7 +41,7 @@ public static class TextMapping
|
|||
new(141, OPowerFlavor),
|
||||
};
|
||||
|
||||
private static readonly TextReference[] AO =
|
||||
private static readonly TextReference[] MapAO =
|
||||
{
|
||||
new(005, Forms),
|
||||
new(014, MoveNames),
|
||||
|
|
@ -66,7 +61,7 @@ public static class TextMapping
|
|||
new(165, OPowerFlavor),
|
||||
};
|
||||
|
||||
private static readonly TextReference[] SMDEMO =
|
||||
private static readonly TextReference[] MapSMDemo =
|
||||
{
|
||||
new(020, ItemFlavor),
|
||||
new(021, ItemNames),
|
||||
|
|
@ -83,7 +78,7 @@ public static class TextMapping
|
|||
new(055, MoveNames),
|
||||
};
|
||||
|
||||
private static readonly TextReference[] SM =
|
||||
private static readonly TextReference[] MapSM =
|
||||
{
|
||||
new(035, ItemFlavor),
|
||||
new(036, ItemNames),
|
||||
|
|
@ -105,7 +100,7 @@ public static class TextMapping
|
|||
new(120, PokedexEntry2),
|
||||
};
|
||||
|
||||
private static readonly TextReference[] USUM =
|
||||
private static readonly TextReference[] MapUSUM =
|
||||
{
|
||||
new(039, ItemFlavor),
|
||||
new(040, ItemNames),
|
||||
|
|
@ -127,7 +122,7 @@ public static class TextMapping
|
|||
new(125, PokedexEntry2),
|
||||
};
|
||||
|
||||
private static readonly TextReference[] GG =
|
||||
private static readonly TextReference[] MapGG =
|
||||
{
|
||||
new("iteminfo.dat", ItemFlavor),
|
||||
new("itemname.dat", ItemNames),
|
||||
|
|
@ -147,7 +142,7 @@ public static class TextMapping
|
|||
new("zukan_comment_A.dat", PokedexEntry1),
|
||||
};
|
||||
|
||||
private static readonly TextReference[] SWSH =
|
||||
private static readonly TextReference[] MapSWSH =
|
||||
{
|
||||
new("iteminfo.dat", ItemFlavor),
|
||||
new("itemname.dat", ItemNames),
|
||||
|
|
@ -173,7 +168,33 @@ public static class TextMapping
|
|||
new("poke_memory_feeling.dat", MemoryFeelings),
|
||||
};
|
||||
|
||||
private static readonly TextReference[] PLA =
|
||||
private static readonly TextReference[] MapPLA =
|
||||
{
|
||||
new("iteminfo.dat", ItemFlavor),
|
||||
new("itemname.dat", ItemNames),
|
||||
new("monsname.dat", SpeciesNames),
|
||||
new("place_name_indirect.dat", metlist_00000),
|
||||
new("place_name_spe.dat", metlist_30000),
|
||||
new("place_name_out.dat", metlist_40000),
|
||||
new("place_name_per.dat", metlist_60000),
|
||||
new("seikaku.dat", Natures),
|
||||
new("tokusei.dat", AbilityNames),
|
||||
new("tokuseiinfo.dat", AbilityFlavor),
|
||||
new("trname.dat", TrainerNames),
|
||||
new("trtype.dat", TrainerClasses),
|
||||
new("trmsg.dat", TrainerText),
|
||||
new("typename.dat", TypeNames),
|
||||
new("wazainfo.dat", MoveFlavor),
|
||||
new("wazaname.dat", MoveNames),
|
||||
new("zkn_form.dat", Forms),
|
||||
new("zkn_type.dat", SpeciesClassifications),
|
||||
new("zukan_comment_A.dat", PokedexEntry1),
|
||||
new("zukan_comment_B.dat", PokedexEntry2),
|
||||
new("ribbon.dat", RibbonMark),
|
||||
new("poke_memory_feeling.dat", MemoryFeelings),
|
||||
};
|
||||
|
||||
private static readonly TextReference[] MapSV =
|
||||
{
|
||||
new("iteminfo.dat", ItemFlavor),
|
||||
new("itemname.dat", ItemNames),
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<Description>Game Data Manager</Description>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ private void Randomize(EvolutionSet evos, int species)
|
|||
if (evo.Method == 0)
|
||||
continue;
|
||||
evo.Species = (ushort)RandSpec.GetRandomSpecies(evo.Species, species);
|
||||
evo.Form = (byte)RandForm.GetRandomForme(evo.Species, false, false, true, Game.SWSH, Personal.Table);
|
||||
evo.Form = (byte)RandForm.GetRandomForm(evo.Species, false, false, Game.Generation, Personal.Table);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,70 +13,53 @@ public FormRandomizer(IPersonalTable t)
|
|||
Personal = t;
|
||||
}
|
||||
|
||||
public int GetRandomForme(int species, bool mega, bool fused, bool alola, bool galar, IPersonalInfo[]? stats = null)
|
||||
public int GetRandomForm(int species, bool mega, bool fuse, int generation, IPersonalInfo[]? stats = null)
|
||||
{
|
||||
stats ??= Personal.Table;
|
||||
if (stats[species].FormCount <= 1)
|
||||
return 0;
|
||||
bool IsGen6 = Personal.MaxSpeciesID == 721;
|
||||
|
||||
switch ((Species)species)
|
||||
if (stats.Length == 980 && species is (int)Pikachu or (int)Eevee) // ban LGPE starters, they crash trainer battles
|
||||
return 0;
|
||||
if (stats.Length == 1182 && species is (int)Rayquaza) // Rayquaza form count error in SWSH
|
||||
return 0;
|
||||
|
||||
// ban Zen Mode and Galarian Zen Mode
|
||||
if (species is (int)Darmanitan && generation >= 8)
|
||||
{
|
||||
// Rayquaza's Forme Count was unchanged in SWSH despite Megas being removed, so just in case the user allows random Megas, disallow this invalid Forme.
|
||||
case Rayquaza when Personal.Table.Length == 1192:
|
||||
return 0;
|
||||
case Unown:
|
||||
case Deerling:
|
||||
case Sawsbuck:
|
||||
return 31; // Random
|
||||
case Greninja when !mega:
|
||||
return 0;
|
||||
case Scatterbug:
|
||||
case Spewpa:
|
||||
case Vivillon:
|
||||
return 30; // save file specific
|
||||
case Zygarde when !IsGen6:
|
||||
return Util.Random.Next(4); // Complete Forme is battle only
|
||||
case Minior:
|
||||
return Util.Random.Next(7); // keep the core color a surprise
|
||||
|
||||
case Meowth when galar:
|
||||
return Util.Random.Next(3); // Kanto, Alola, Galar
|
||||
|
||||
// only allow Standard, not Zen Mode
|
||||
case Darmanitan when galar:
|
||||
{
|
||||
int form = Util.Random.Next(stats[species].FormCount);
|
||||
return form & 2;
|
||||
}
|
||||
|
||||
// some species have 1 invalid form among several other valid forms, handle them here
|
||||
case Pikachu when Personal.Table.Length == 1192:
|
||||
case Slowbro when galar:
|
||||
{
|
||||
int form = Util.Random.Next(stats[species].FormCount - 1);
|
||||
int banned = GetInvalidForm(species, galar, Personal);
|
||||
if (form == banned)
|
||||
form++;
|
||||
return form;
|
||||
}
|
||||
int form = Util.Random.Next(stats[species].FormCount);
|
||||
return form & 2;
|
||||
}
|
||||
|
||||
if (Personal.Table.Length == 980 && species is (int)Pikachu or (int)Eevee) // gg tableB -- no starters, they crash trainer battles.
|
||||
return 0;
|
||||
if (alola && Legal.EvolveToAlolanForms.Contains((ushort)species))
|
||||
return Util.Random.Next(2);
|
||||
if (galar && Legal.EvolveToGalarForms.Contains((ushort)species))
|
||||
return Util.Random.Next(2);
|
||||
if (!Legal.BattleExclusiveForms.Contains(species) || mega || (fused && Legal.BattleFusions.Contains(species)))
|
||||
return Util.Random.Next(stats[species].FormCount); // Slot-Random
|
||||
return 0;
|
||||
return (Species)species switch
|
||||
{
|
||||
Pikachu or Slowbro when generation >= 8 => GetValidForm(species, generation, Personal),
|
||||
Unown or Deerling or Sawsbuck => 31, // pure random -- todo sv see if this behavior changed
|
||||
Greninja when !mega => 0, // treat Ash-Greninja as a Mega
|
||||
Scatterbug or Spewpa or Vivillon => 30, // save file specific -- todo sv see if this behavior changed
|
||||
Zygarde when generation >= 7 => Util.Random.Next(4), // skip Complete Forme
|
||||
Minior => Util.Random.Next(7), // skip Core Forms
|
||||
|
||||
_ when !mega && Legal.BattleMegas.Contains(species) => 0,
|
||||
_ when !fuse && Legal.BattleFusions.Contains(species) => 0,
|
||||
_ when Legal.BattleForms.Contains(species) => 0,
|
||||
_ => Util.Random.Next(stats[species].FormCount),
|
||||
};
|
||||
}
|
||||
|
||||
public static int GetInvalidForm(int species, bool galar, IPersonalTable stats) => species switch
|
||||
private static int GetValidForm(int species, int generation, IPersonalTable stats)
|
||||
{
|
||||
(int)Pikachu when stats.Table.Length == 1192 => 8, // LGPE Partner Pikachu
|
||||
(int)Slowbro when galar => 1, // Mega Slowbro
|
||||
int form = Util.Random.Next(stats[species].FormCount - 1);
|
||||
int banned = GetInvalidForm(species, generation);
|
||||
if (form == banned)
|
||||
form++;
|
||||
return form;
|
||||
}
|
||||
|
||||
private static int GetInvalidForm(int species, int generation) => species switch
|
||||
{
|
||||
(int)Pikachu when generation >= 8 => 8, // LGPE Partner Pikachu
|
||||
(int)Slowbro when generation >= 8 => 1, // Mega Slowbro
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(species)),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,6 +48,16 @@ public class SpeciesSettings : RandSettings
|
|||
[Category(General), Description("Allows Generation 8 species when randomizing.")]
|
||||
public bool Gen8 { get; set; } = true;
|
||||
|
||||
/// <summary>Allows Generation 9 species when randomizing.</summary>
|
||||
[Category(General), Description("Allows Generation 9 species when randomizing.")]
|
||||
public bool Gen9 { get; set; } = true;
|
||||
|
||||
[Category(Misc), Description("Allows eligible Pokémon to already be in their Mega-Evolved forms when randomizing species.")]
|
||||
public bool AllowRandomMegaForms { get; set; }
|
||||
|
||||
[Category(Misc), Description("Allows Kyurem, Necrozma, and Calyrex to be encountered in their fused states when randomizing species.")]
|
||||
public bool AllowRandomFusions { get; set; }
|
||||
|
||||
/// <summary>Allows Legendary species when randomizing.</summary>
|
||||
[Category(Misc), Description("Allows Legendary species when randomizing.")]
|
||||
public bool Legends { get; set; }
|
||||
|
|
@ -97,6 +107,7 @@ public int[] GetSpecies(int maxSpecies, int generation)
|
|||
if (Gen6) AddGen6Species(list, maxSpecies);
|
||||
if (Gen7) AddGen7Species(list, maxSpecies);
|
||||
if (Gen8) AddGen8Species(list, maxSpecies);
|
||||
if (Gen9) AddGen9Species(list, maxSpecies);
|
||||
|
||||
if (generation == 7 && Gen1 && Events && maxSpecies <= Legal.MaxSpeciesID_7_GG)
|
||||
AddGGEvents(list);
|
||||
|
|
@ -221,6 +232,24 @@ private void AddGen8Species(List<int> list, int maxSpecies)
|
|||
}
|
||||
}
|
||||
|
||||
private void AddGen9Species(List<int> list, int maxSpecies)
|
||||
{
|
||||
if (maxSpecies <= Legal.MaxSpeciesID_8a)
|
||||
return;
|
||||
|
||||
var legendary = Enumerable.Range(994, 6);
|
||||
list.AddRange(Enumerable.Range(906, 105).Except(legendary)); // Sprigatito - Annihilape
|
||||
list.Remove(980); // AKETUBAN
|
||||
list.Remove(987); // BKETUBAN
|
||||
|
||||
if (Legends)
|
||||
{
|
||||
// list.Add(980); // AKETUBAN
|
||||
// list.Add(987); // BKETUBAN
|
||||
list.AddRange(legendary); // Ting-Lu, Chien-Pao, Wo-Chien, Chi-Yu, Koraidon, Miraidon
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddGGEvents(List<int> list)
|
||||
{
|
||||
list.AddRange(Enumerable.Range(808, Legal.MaxSpeciesID_7_GG - Legal.MaxSpeciesID_7_USUM)); // Meltan, Melmetal
|
||||
|
|
|
|||
|
|
@ -48,12 +48,6 @@ public class TrainerRandSettings
|
|||
[Category(PKM), Description("Randomizes the Species and basic stat details of all Team members.")]
|
||||
public bool RandomizeTeam { get; set; } = true;
|
||||
|
||||
[Category(PKM), Description("Allows random Mega Forms when randomizing species.")]
|
||||
public bool AllowRandomMegaForms { get; set; }
|
||||
|
||||
[Category(PKM), Description("Allows random Fused PKM when randomizing species.")]
|
||||
public bool AllowRandomFusions { get; set; }
|
||||
|
||||
[Category(PKM), Description("Allows random Held Items when randomizing species.")]
|
||||
public bool AllowRandomHeldItems { get; set; }
|
||||
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ private void RandomizeSpecFormItem(IPokeData pk, int Type)
|
|||
else // every other pkm
|
||||
{
|
||||
pk.Species = RandSpec.GetRandomSpeciesType(pk.Species, Type);
|
||||
pk.Form = RandForm.GetRandomForme(pk.Species, Settings.AllowRandomMegaForms, Settings.AllowRandomFusions, true, true, Personal.Table);
|
||||
pk.Form = RandForm.GetRandomForm(pk.Species, SpecSettings.AllowRandomMegaForms, SpecSettings.AllowRandomFusions, Info.Generation, Personal.Table);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -181,7 +181,7 @@ private void RandomizeSpecForm(TrainerPoke7b pk, int type)
|
|||
}
|
||||
|
||||
pk.Species = RandSpec.GetRandomSpeciesType(pk.Species, type);
|
||||
pk.Form = RandForm.GetRandomForme(pk.Species, Settings.AllowRandomMegaForms, Settings.AllowRandomFusions, true, false, Personal.Table);
|
||||
pk.Form = RandForm.GetRandomForm(pk.Species, SpecSettings.AllowRandomMegaForms, SpecSettings.AllowRandomFusions, Info.Generation, Personal.Table);
|
||||
}
|
||||
|
||||
private void TryForceEvolve(IPokeData pk)
|
||||
|
|
@ -253,7 +253,7 @@ private void UpdatePKMFromSettings(TrainerPoke pk)
|
|||
return;
|
||||
|
||||
c.Species = AllowedGigantamaxes[Util.Random.Next(AllowedGigantamaxes.Length)];
|
||||
c.Form = c.Species is (int)Species.Pikachu or (int)Species.Meowth ? 0 : RandForm.GetRandomForme(c.Species, false, false, false, false, Personal.Table); // Pikachu & Meowth altforms can't gmax
|
||||
c.Form = c.Species is (int)Species.Pikachu or (int)Species.Meowth ? 0 : RandForm.GetRandomForm(c.Species, false, false, Info.Generation, Personal.Table); // Pikachu & Meowth altforms can't gmax
|
||||
}
|
||||
if (Settings.MaxDynamaxLevel && c.CanDynamax)
|
||||
c.DynamaxLevel = 10;
|
||||
|
|
@ -348,6 +348,11 @@ private static int[] GetRandomMega(Dictionary<int, int[]> megas, out int species
|
|||
223, 224, // Sordward and Shielbert
|
||||
};
|
||||
|
||||
// 3 poke max
|
||||
private static readonly int[] MultiBattle_SV =
|
||||
{
|
||||
};
|
||||
|
||||
private static Dictionary<int, int> GetFixedCountIndexes(GameVersion game)
|
||||
{
|
||||
if (GameVersion.XY.Contains(game))
|
||||
|
|
@ -362,14 +367,19 @@ private static int[] GetRandomMega(Dictionary<int, int[]> megas, out int species
|
|||
return Legal.ImportantTrainers_GG.ToDictionary(z => z, index => MultiBattle_GG.Contains(index) ? 3 : 6);
|
||||
if (GameVersion.SWSH.Contains(game))
|
||||
return Legal.ImportantTrainers_SWSH.ToDictionary(z => z, index => MultiBattle_SWSH.Contains(index) ? 3 : 6);
|
||||
if (GameVersion.SV.Contains(game))
|
||||
return Legal.ImportantTrainers_SV.ToDictionary(z => z, index => MultiBattle_SV.Contains(index) ? 3 : 6);
|
||||
return new Dictionary<int, int>();
|
||||
}
|
||||
|
||||
|
||||
private static readonly int[] CrashClasses_GG = Legal.BlacklistedClasses_GG;
|
||||
private static readonly int[] CrashClasses_SWSH = Legal.BlacklistedClasses_SWSH;
|
||||
private static readonly int[] CrashClasses_SV = Legal.BlacklistedClasses_SV;
|
||||
|
||||
private static int[] GetSpecialClasses(GameVersion game)
|
||||
{
|
||||
if (GameVersion.SV.Contains(game))
|
||||
return Legal.SpecialClasses_SV;
|
||||
if (GameVersion.SWSH.Contains(game))
|
||||
return Legal.SpecialClasses_SWSH;
|
||||
if (GameVersion.GG.Contains(game))
|
||||
|
|
@ -387,6 +397,8 @@ private static int[] GetSpecialClasses(GameVersion game)
|
|||
|
||||
private static int[] GetCrashClasses(GameVersion game)
|
||||
{
|
||||
if (GameVersion.SV.Contains(game))
|
||||
return CrashClasses_SV;
|
||||
if (GameVersion.SWSH.Contains(game))
|
||||
return CrashClasses_SWSH;
|
||||
if (GameVersion.GG.Contains(game))
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<Description>Randomizer Utility</Description>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -1,63 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
using pkNX.Structures;
|
||||
using static pkNX.Structures.Species;
|
||||
|
||||
namespace pkNX.Sprites;
|
||||
|
||||
public static class FormConverter
|
||||
{
|
||||
public static bool IsTotemForm(int species, int form, int generation = 7)
|
||||
{
|
||||
if (generation != 7)
|
||||
return false;
|
||||
if (form == 0)
|
||||
return false;
|
||||
if (!Legal.Totem_USUM.Contains((ushort)species))
|
||||
return false;
|
||||
if (species == (int)Mimikyu)
|
||||
return form is 2 or 3;
|
||||
if (Legal.Totem_Alolan.Contains((ushort)species))
|
||||
return form == 2;
|
||||
return form == 1;
|
||||
}
|
||||
|
||||
public static int GetTotemBaseForm(int species, int form)
|
||||
{
|
||||
if (species == (int)Mimikyu)
|
||||
return form - 2;
|
||||
return form - 1;
|
||||
}
|
||||
|
||||
public static bool IsValidOutOfBoundsForme(int species, int form, int generation)
|
||||
{
|
||||
return (Species)species switch
|
||||
{
|
||||
Unown => form < (generation == 2 ? 26 : 28), // A-Z : A-Z?!
|
||||
Mothim => form < 3, // Wormadam base form is kept
|
||||
Scatterbug or Spewpa => form < 18,
|
||||
_ => false,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the species should have a drop-down selection visible for the form value.
|
||||
/// </summary>
|
||||
/// <param name="pi">Game specific personal info</param>
|
||||
/// <param name="species"> ID</param>
|
||||
public static bool HasFormSelection(IPersonalFormInfo pi, int species)
|
||||
{
|
||||
if (HasFormeValuesNotIndicatedByPersonal.Contains(species))
|
||||
return true;
|
||||
|
||||
int count = pi.FormCount;
|
||||
return count > 1;
|
||||
}
|
||||
|
||||
private static readonly HashSet<int> HasFormeValuesNotIndicatedByPersonal = new()
|
||||
{
|
||||
(int)Unown,
|
||||
(int)Mothim, // Burmy forme carried over, not cleared
|
||||
(int)Scatterbug,
|
||||
(int)Spewpa, // Vivillon pre-evos
|
||||
};
|
||||
}
|
||||
|
|
@ -1,260 +0,0 @@
|
|||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace pkNX.Sprites;
|
||||
|
||||
/// <summary>
|
||||
/// Image Layering/Blending Utility
|
||||
/// </summary>
|
||||
public static class ImageUtil
|
||||
{
|
||||
public static Bitmap LayerImage(Image baseLayer, Image overLayer, int x, int y, double transparency)
|
||||
{
|
||||
overLayer = ChangeOpacity(overLayer, transparency);
|
||||
return LayerImage(baseLayer, overLayer, x, y);
|
||||
}
|
||||
|
||||
public static Bitmap LayerImage(Image baseLayer, Image overLayer, int x, int y)
|
||||
{
|
||||
Bitmap img = new(baseLayer);
|
||||
using Graphics gr = Graphics.FromImage(img);
|
||||
gr.DrawImage(overLayer, x, y, overLayer.Width, overLayer.Height);
|
||||
return img;
|
||||
}
|
||||
|
||||
public static Bitmap ChangeOpacity(Image img, double trans)
|
||||
{
|
||||
if (img.PixelFormat.HasFlag(PixelFormat.Indexed))
|
||||
return (Bitmap)img;
|
||||
|
||||
var bmp = (Bitmap)img.Clone();
|
||||
GetBitmapData(bmp, out BitmapData bmpData, out IntPtr ptr, out byte[] data);
|
||||
|
||||
Marshal.Copy(ptr, data, 0, data.Length);
|
||||
SetAllTransparencyTo(data, trans);
|
||||
Marshal.Copy(data, 0, ptr, data.Length);
|
||||
bmp.UnlockBits(bmpData);
|
||||
|
||||
return bmp;
|
||||
}
|
||||
|
||||
public static Bitmap ChangeAllColorTo(Image img, Color c)
|
||||
{
|
||||
if (img.PixelFormat.HasFlag(PixelFormat.Indexed))
|
||||
return (Bitmap)img;
|
||||
|
||||
var bmp = (Bitmap)img.Clone();
|
||||
GetBitmapData(bmp, out BitmapData bmpData, out IntPtr ptr, out byte[] data);
|
||||
|
||||
Marshal.Copy(ptr, data, 0, data.Length);
|
||||
ChangeAllColorTo(data, c);
|
||||
Marshal.Copy(data, 0, ptr, data.Length);
|
||||
bmp.UnlockBits(bmpData);
|
||||
|
||||
return bmp;
|
||||
}
|
||||
|
||||
public static Bitmap ToGrayscale(Image img)
|
||||
{
|
||||
if (img.PixelFormat.HasFlag(PixelFormat.Indexed))
|
||||
return (Bitmap)img;
|
||||
|
||||
var bmp = (Bitmap)img.Clone();
|
||||
GetBitmapData(bmp, out BitmapData bmpData, out IntPtr ptr, out byte[] data);
|
||||
|
||||
Marshal.Copy(ptr, data, 0, data.Length);
|
||||
SetAllColorToGrayScale(data);
|
||||
Marshal.Copy(data, 0, ptr, data.Length);
|
||||
bmp.UnlockBits(bmpData);
|
||||
|
||||
return bmp;
|
||||
}
|
||||
|
||||
private static void GetBitmapData(Bitmap bmp, out BitmapData bmpData, out IntPtr ptr, out byte[] data)
|
||||
{
|
||||
bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
|
||||
ptr = bmpData.Scan0;
|
||||
data = new byte[bmp.Width * bmp.Height * 4];
|
||||
}
|
||||
|
||||
public static Bitmap GetBitmap(byte[] data, int width, int height, PixelFormat format = PixelFormat.Format32bppArgb)
|
||||
{
|
||||
var bmp = new Bitmap(width, height, format);
|
||||
var bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, format);
|
||||
var ptr = bmpData.Scan0;
|
||||
Marshal.Copy(data, 0, ptr, data.Length);
|
||||
bmp.UnlockBits(bmpData);
|
||||
return bmp;
|
||||
}
|
||||
|
||||
public static byte[] GetPixelData(Bitmap bitmap)
|
||||
{
|
||||
var argbData = new byte[bitmap.Width * bitmap.Height * 4];
|
||||
var bd = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, bitmap.PixelFormat);
|
||||
Marshal.Copy(bd.Scan0, argbData, 0, bitmap.Width * bitmap.Height * 4);
|
||||
bitmap.UnlockBits(bd);
|
||||
return argbData;
|
||||
}
|
||||
|
||||
public static void SetAllUsedPixelsOpaque(byte[] data)
|
||||
{
|
||||
for (int i = 0; i < data.Length; i += 4)
|
||||
{
|
||||
if (data[i + 3] != 0)
|
||||
data[i + 3] = 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
public static void RemovePixels(byte[] pixels, byte[] original)
|
||||
{
|
||||
for (int i = 0; i < original.Length; i += 4)
|
||||
{
|
||||
if (original[i + 3] == 0)
|
||||
continue;
|
||||
pixels[i + 0] = 0;
|
||||
pixels[i + 1] = 0;
|
||||
pixels[i + 2] = 0;
|
||||
pixels[i + 3] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetAllTransparencyTo(byte[] data, double trans)
|
||||
{
|
||||
for (int i = 0; i < data.Length; i += 4)
|
||||
data[i + 3] = (byte)(data[i + 3] * trans);
|
||||
}
|
||||
|
||||
public static void ChangeAllColorTo(byte[] data, Color c)
|
||||
{
|
||||
byte R = c.R;
|
||||
byte G = c.G;
|
||||
byte B = c.B;
|
||||
for (int i = 0; i < data.Length; i += 4)
|
||||
{
|
||||
if (data[i + 3] == 0)
|
||||
continue;
|
||||
data[i + 0] = B;
|
||||
data[i + 1] = G;
|
||||
data[i + 2] = R;
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetAllColorToGrayScale(byte[] data)
|
||||
{
|
||||
for (int i = 0; i < data.Length; i += 4)
|
||||
{
|
||||
if (data[i + 3] == 0)
|
||||
continue;
|
||||
byte greyS = (byte)(((0.3 * data[i + 2]) + (0.59 * data[i + 1]) + (0.11 * data[i + 0])) / 3);
|
||||
data[i + 0] = greyS;
|
||||
data[i + 1] = greyS;
|
||||
data[i + 2] = greyS;
|
||||
}
|
||||
}
|
||||
|
||||
public static void GlowEdges(byte[] data, byte blue, byte green, byte red, int width, int reach = 3, double amount = 0.0777)
|
||||
{
|
||||
PollutePixels(data, width, reach, amount);
|
||||
CleanPollutedPixels(data, blue, green, red);
|
||||
}
|
||||
|
||||
private static void PollutePixels(byte[] data, int width, int reach, double amount)
|
||||
{
|
||||
int stride = width * 4;
|
||||
int height = data.Length / stride;
|
||||
for (int i = 0; i < data.Length; i += 4)
|
||||
{
|
||||
// only pollute outwards if the current pixel isn't transparent
|
||||
if (data[i + 3] == 0)
|
||||
continue;
|
||||
|
||||
int x = (i % stride) / 4;
|
||||
int y = (i / stride);
|
||||
Pollute(x, y);
|
||||
}
|
||||
|
||||
void Pollute(int x, int y)
|
||||
{
|
||||
int left = Math.Max(0, x - reach);
|
||||
int right = Math.Min(width - 1, x + reach);
|
||||
int top = Math.Max(0, y - reach);
|
||||
int bottom = Math.Min(height - 1, y + reach);
|
||||
for (int i = left; i <= right; i++)
|
||||
{
|
||||
for (int j = top; j <= bottom; j++)
|
||||
{
|
||||
// update one of the color bits
|
||||
// it is expected that a transparent pixel RGBA value is 0.
|
||||
var c = 4 * (i + (j * width));
|
||||
data[c + 0] += (byte)(amount * (0xFF - data[c + 0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void CleanPollutedPixels(byte[] data, byte blue, byte green, byte red)
|
||||
{
|
||||
for (int i = 0; i < data.Length; i += 4)
|
||||
{
|
||||
// only clean if the current pixel isn't transparent
|
||||
if (data[i + 3] != 0)
|
||||
continue;
|
||||
|
||||
// grab the transparency from the donor byte
|
||||
var transparency = data[i + 0];
|
||||
if (transparency == 0)
|
||||
continue;
|
||||
|
||||
data[i + 0] = blue;
|
||||
data[i + 1] = green;
|
||||
data[i + 2] = red;
|
||||
data[i + 3] = transparency;
|
||||
}
|
||||
}
|
||||
|
||||
public static Color ColorBaseStat(int v)
|
||||
{
|
||||
const float maxval = 180; // shift the green cap down
|
||||
float x = 100f * v / maxval;
|
||||
if (x > 100)
|
||||
x = 100;
|
||||
double red = 255f * (x > 50 ? 1 - (2 * (x - 50) / 100.0) : 1.0);
|
||||
double green = 255f * (x > 50 ? 1.0 : 2 * x / 100.0);
|
||||
|
||||
return Blend(Color.FromArgb((int)red, (int)green, 0), Color.White, 0.4);
|
||||
}
|
||||
|
||||
public static Color Blend(Color color, Color backColor, double amount)
|
||||
{
|
||||
byte r = (byte)((color.R * amount) + (backColor.R * (1 - amount)));
|
||||
byte g = (byte)((color.G * amount) + (backColor.G * (1 - amount)));
|
||||
byte b = (byte)((color.B * amount) + (backColor.B * (1 - amount)));
|
||||
return Color.FromArgb(r, g, b);
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/a/24199315
|
||||
public static Bitmap ResizeImage(Image image, int width, int height)
|
||||
{
|
||||
var destRect = new Rectangle(0, 0, width, height);
|
||||
var destImage = new Bitmap(width, height);
|
||||
|
||||
destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
|
||||
|
||||
using var wrapMode = new ImageAttributes();
|
||||
wrapMode.SetWrapMode(WrapMode.TileFlipXY);
|
||||
|
||||
using var graphics = Graphics.FromImage(destImage);
|
||||
graphics.CompositingMode = CompositingMode.SourceCopy;
|
||||
graphics.CompositingQuality = CompositingQuality.HighQuality;
|
||||
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||
graphics.SmoothingMode = SmoothingMode.HighQuality;
|
||||
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||
|
||||
graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, wrapMode);
|
||||
|
||||
return destImage;
|
||||
}
|
||||
}
|
||||
31373
pkNX.Sprites/Properties/Resources.Designer.cs
generated
|
|
@ -1,177 +0,0 @@
|
|||
using System.Drawing;
|
||||
using pkNX.Structures;
|
||||
using pkNX.Sprites.Properties;
|
||||
|
||||
namespace pkNX.Sprites;
|
||||
|
||||
public abstract class SpriteBuilder
|
||||
{
|
||||
public static bool ShowEggSpriteAsItem { get; set; } = true;
|
||||
|
||||
public abstract int Width { get; }
|
||||
public abstract int Height { get; }
|
||||
|
||||
protected abstract int ItemShiftX { get; }
|
||||
protected abstract int ItemShiftY { get; }
|
||||
protected abstract int ItemMaxSize { get; }
|
||||
protected abstract int EggItemShiftX { get; }
|
||||
protected abstract int EggItemShiftY { get; }
|
||||
|
||||
public abstract Bitmap Hover { get; }
|
||||
public abstract Bitmap View { get; }
|
||||
public abstract Bitmap Set { get; }
|
||||
public abstract Bitmap Delete { get; }
|
||||
public abstract Bitmap Transparent { get; }
|
||||
public abstract Bitmap Drag { get; }
|
||||
public abstract Bitmap UnknownItem { get; }
|
||||
public abstract Bitmap None { get; }
|
||||
public abstract Bitmap ItemTM { get; }
|
||||
public abstract Bitmap ItemTR { get; }
|
||||
|
||||
private const double UnknownFormTransparency = 0.5;
|
||||
private const double ShinyTransparency = 0.7;
|
||||
private const double EggUnderLayerTransparency = 0.33;
|
||||
|
||||
protected abstract string GetSpriteStringSpeciesOnly(int species);
|
||||
|
||||
protected abstract string GetSpriteAll(int species, int form, int gender, bool shiny, bool gmax, int generation);
|
||||
protected abstract string GetItemResourceName(int item);
|
||||
protected abstract Bitmap Unknown { get; }
|
||||
protected abstract Bitmap GetEggSprite(int species);
|
||||
|
||||
public Image GetSprite(int species, int form, int gender, int heldItem, bool isEgg, bool isShiny, bool isGigantamax, int generation = -1)
|
||||
{
|
||||
if (species == 0)
|
||||
return None;
|
||||
|
||||
var baseImage = GetBaseImage(species, form, gender, isShiny, isGigantamax, generation);
|
||||
return GetSprite(baseImage, species, heldItem, isEgg, isShiny, isGigantamax, generation);
|
||||
}
|
||||
|
||||
public Image GetSprite(Image baseSprite, int species, int heldItem, bool isEgg, bool isShiny, bool isGigantamax, int generation = -1, bool isBoxBGRed = false)
|
||||
{
|
||||
if (isEgg)
|
||||
baseSprite = LayerOverImageEgg(baseSprite, species, heldItem != 0);
|
||||
if (heldItem > 0)
|
||||
baseSprite = LayerOverImageItem(baseSprite, heldItem, generation);
|
||||
if (isShiny)
|
||||
baseSprite = LayerOverImageShiny(baseSprite);
|
||||
return baseSprite;
|
||||
}
|
||||
|
||||
private Image GetBaseImage(int species, int form, int gender, bool shiny, bool gmax, int generation)
|
||||
{
|
||||
var img = FormConverter.IsTotemForm(species, form)
|
||||
? GetBaseImageTotem(species, form, gender, shiny, gmax, generation)
|
||||
: GetBaseImageDefault(species, form, gender, shiny, gmax, generation);
|
||||
return img ?? GetBaseImageFallback(species, form, gender, shiny, gmax, generation);
|
||||
}
|
||||
|
||||
private Image? GetBaseImageTotem(int species, int form, int gender, bool shiny, bool gmax, int generation)
|
||||
{
|
||||
var baseform = FormConverter.GetTotemBaseForm(species, form);
|
||||
var baseImage = GetBaseImageDefault(species, baseform, gender, shiny, gmax, generation);
|
||||
if (baseImage == null)
|
||||
return null;
|
||||
return ImageUtil.ToGrayscale(baseImage);
|
||||
}
|
||||
|
||||
private Image? GetBaseImageDefault(int species, int form, int gender, bool shiny, bool gmax, int generation)
|
||||
{
|
||||
var file = GetSpriteAll(species, form, gender, shiny, gmax, generation);
|
||||
return (Image?)Resources.ResourceManager.GetObject(file);
|
||||
}
|
||||
|
||||
private Image GetBaseImageFallback(int species, int form, int gender, bool shiny, bool gmax, int generation)
|
||||
{
|
||||
if (shiny) // try again without shiny
|
||||
{
|
||||
var img = GetBaseImageDefault(species, form, gender, false, gmax, generation);
|
||||
if (img != null)
|
||||
return img;
|
||||
}
|
||||
|
||||
// try again without form
|
||||
var baseImage = (Image?)Resources.ResourceManager.GetObject(GetSpriteStringSpeciesOnly(species));
|
||||
if (baseImage == null) // failed again
|
||||
return Unknown;
|
||||
return ImageUtil.LayerImage(baseImage, Unknown, 0, 0, UnknownFormTransparency);
|
||||
}
|
||||
|
||||
private Image LayerOverImageItem(Image baseImage, int item, int generation)
|
||||
{
|
||||
Image itemimg = (Image?)Resources.ResourceManager.GetObject(GetItemResourceName(item)) ?? Resources.bitem_unk;
|
||||
if (item is >= 328 and <= 419) // gen2/3/4 TM
|
||||
itemimg = ItemTM;
|
||||
else if (item is >= 1130 and <= 1229) // Gen8 TR
|
||||
itemimg = ItemTR;
|
||||
|
||||
// Redraw item in bottom right corner; since images are cropped, try to not have them at the edge
|
||||
int x = ItemShiftX + ((ItemMaxSize - itemimg.Width) / 2);
|
||||
if (x + itemimg.Width > baseImage.Width)
|
||||
x = baseImage.Width - itemimg.Width;
|
||||
int y = ItemShiftY + (ItemMaxSize - itemimg.Height);
|
||||
return ImageUtil.LayerImage(baseImage, itemimg, x, y);
|
||||
}
|
||||
|
||||
private static Image LayerOverImageShiny(Image baseImage)
|
||||
{
|
||||
// Add shiny star to top left of image.
|
||||
var rare = Resources.rare_icon;
|
||||
return ImageUtil.LayerImage(baseImage, rare, 0, 0, ShinyTransparency);
|
||||
}
|
||||
|
||||
private Image LayerOverImageEgg(Image baseImage, int species, bool hasItem)
|
||||
{
|
||||
if (ShowEggSpriteAsItem && !hasItem)
|
||||
return LayerOverImageEggAsItem(baseImage, species);
|
||||
return LayerOverImageEggTransparentSpecies(baseImage, species);
|
||||
}
|
||||
|
||||
private Image LayerOverImageEggTransparentSpecies(Image baseImage, int species)
|
||||
{
|
||||
// Partially transparent species.
|
||||
baseImage = ImageUtil.ChangeOpacity(baseImage, EggUnderLayerTransparency);
|
||||
// Add the egg layer over-top with full opacity.
|
||||
var egg = GetEggSprite(species);
|
||||
return ImageUtil.LayerImage(baseImage, egg, 0, 0);
|
||||
}
|
||||
|
||||
private Image LayerOverImageEggAsItem(Image baseImage, int species)
|
||||
{
|
||||
var egg = GetEggSprite(species);
|
||||
return ImageUtil.LayerImage(baseImage, egg, EggItemShiftX, EggItemShiftY); // similar to held item, since they can't have any
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 56 high, 68 wide sprite builder
|
||||
/// </summary>
|
||||
public class SpriteBuilder5668 : SpriteBuilder
|
||||
{
|
||||
public override int Height => 56;
|
||||
public override int Width => 68;
|
||||
|
||||
protected override int ItemShiftX => 52;
|
||||
protected override int ItemShiftY => 24;
|
||||
protected override int ItemMaxSize => 32;
|
||||
protected override int EggItemShiftX => 9;
|
||||
protected override int EggItemShiftY => 2;
|
||||
|
||||
protected override string GetSpriteStringSpeciesOnly(int species) => 'b' + $"_{species}";
|
||||
protected override string GetSpriteAll(int species, int form, int gender, bool shiny, bool gmax, int generation) => 'b' + SpriteName.GetResourceStringSprite(species, form, gender, generation, shiny, gmax);
|
||||
protected override string GetItemResourceName(int item) => 'b' + $"item_{item}";
|
||||
protected override Bitmap Unknown => Resources.b_unknown;
|
||||
protected override Bitmap GetEggSprite(int species) => species == (int)Species.Manaphy ? Resources.b_490_e : Resources.b_egg;
|
||||
|
||||
public override Bitmap Hover => Resources.slotHover68;
|
||||
public override Bitmap View => Resources.slotView68;
|
||||
public override Bitmap Set => Resources.slotSet68;
|
||||
public override Bitmap Delete => Resources.slotDel68;
|
||||
public override Bitmap Transparent => Resources.slotTrans68;
|
||||
public override Bitmap Drag => Resources.slotDrag68;
|
||||
public override Bitmap UnknownItem => Resources.bitem_unk;
|
||||
public override Bitmap None => Resources.b_0;
|
||||
public override Bitmap ItemTM => Resources.bitem_tm;
|
||||
public override Bitmap ItemTR => Resources.bitem_tr;
|
||||
}
|
||||
|
|
@ -1,110 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using pkNX.Structures;
|
||||
|
||||
namespace pkNX.Sprites;
|
||||
|
||||
public static class SpriteName
|
||||
{
|
||||
public static bool AllowShinySprite { get; set; } = true;
|
||||
public static bool AllowGigantamaxSprite { get; set; } = true;
|
||||
|
||||
private const char Separator = '_';
|
||||
private const char Cosplay = 'c';
|
||||
private const char Shiny = 's';
|
||||
private const string Gigantamax = "gmax";
|
||||
private const char GGStarter = 'p';
|
||||
|
||||
public static string GetResourceStringBall(int ball) => $"_ball{ball}";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the resource name of the Pokémon sprite.
|
||||
/// </summary>
|
||||
public static string GetResourceStringSprite(int species, int form, int gender, int generation = 8, bool shiny = false, bool gmax = false)
|
||||
{
|
||||
if (SpeciesDefaultFormSprite.Contains(species) && !gmax) // Species who show their default sprite regardless of Form
|
||||
form = 0;
|
||||
|
||||
if (gmax && species is (int)Species.Toxtricity or (int)Species.Alcremie) // same sprites for all altform gmaxes
|
||||
form = 0;
|
||||
|
||||
switch (form)
|
||||
{
|
||||
case 30 when species is >= (int)Species.Scatterbug and <= (int)Species.Vivillon: // save file specific
|
||||
form = 0;
|
||||
break;
|
||||
case 31 when species is (int)Species.Unown or (int)Species.Deerling or (int)Species.Sawsbuck: // Random
|
||||
form = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
var sb = new StringBuilder();
|
||||
sb.Append(Separator).Append(species);
|
||||
|
||||
if (form != 0)
|
||||
{
|
||||
sb.Append(Separator)
|
||||
.Append(form);
|
||||
|
||||
if (species == (int)Species.Pikachu)
|
||||
{
|
||||
if (generation == 6)
|
||||
{
|
||||
sb.Append(Cosplay);
|
||||
gender = 2; // Cosplay Pikachu gift can only be Female, but personal entries are set to be either Gender
|
||||
}
|
||||
else if (form == 8)
|
||||
{
|
||||
sb.Append(GGStarter);
|
||||
}
|
||||
}
|
||||
else if (species == (int)Species.Eevee)
|
||||
{
|
||||
if (form == 1)
|
||||
sb.Append(GGStarter);
|
||||
}
|
||||
}
|
||||
if (gender == 2 && SpeciesGenderedSprite.Contains(species) && !gmax)
|
||||
{
|
||||
sb.Append('f');
|
||||
}
|
||||
|
||||
if (gmax && AllowGigantamaxSprite)
|
||||
{
|
||||
sb.Append(Separator);
|
||||
sb.Append(Gigantamax);
|
||||
}
|
||||
if (shiny && AllowShinySprite)
|
||||
sb.Append(Shiny);
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Species that show their default Species sprite regardless of current form
|
||||
/// </summary>
|
||||
public static readonly HashSet<int> SpeciesDefaultFormSprite = new()
|
||||
{
|
||||
(int)Species.Mothim,
|
||||
(int)Species.Scatterbug,
|
||||
(int)Species.Spewpa,
|
||||
(int)Species.Rockruff,
|
||||
(int)Species.Mimikyu,
|
||||
(int)Species.Sinistea,
|
||||
(int)Species.Polteageist,
|
||||
(int)Species.Urshifu,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Species that show a Gender specific Sprite
|
||||
/// </summary>
|
||||
public static readonly HashSet<int> SpeciesGenderedSprite = new()
|
||||
{
|
||||
(int)Species.Pikachu,
|
||||
(int)Species.Hippopotas,
|
||||
(int)Species.Hippowdon,
|
||||
(int)Species.Unfezant,
|
||||
(int)Species.Frillish,
|
||||
(int)Species.Jellicent,
|
||||
(int)Species.Pyroar,
|
||||
};
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
using System.Drawing;
|
||||
using pkNX.Sprites.Properties;
|
||||
|
||||
namespace pkNX.Sprites;
|
||||
|
||||
public static class SpriteUtil
|
||||
{
|
||||
public static readonly SpriteBuilder5668 SB8 = new();
|
||||
public static SpriteBuilder Spriter { get; set; } = SB8;
|
||||
|
||||
public static Image GetBallSprite(int ball)
|
||||
{
|
||||
string resource = SpriteName.GetResourceStringBall(ball);
|
||||
return (Bitmap?)Resources.ResourceManager.GetObject(resource) ?? Resources._ball4; // Poké Ball (default)
|
||||
}
|
||||
|
||||
public static Image GetSprite(int species, int form, int gender, int item, bool isegg, bool shiny, bool gmax, int generation = -1)
|
||||
{
|
||||
return Spriter.GetSprite(species, form, gender, item, isegg, shiny, gmax, generation);
|
||||
}
|
||||
|
||||
public static void Initialize() => Spriter = SB8;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 765 B |
|
Before Width: | Height: | Size: 847 B |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 999 B |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 586 B |
|
Before Width: | Height: | Size: 779 B |
|
Before Width: | Height: | Size: 650 B |
|
Before Width: | Height: | Size: 853 B |
|
Before Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 964 B |
|
Before Width: | Height: | Size: 734 B |
|
Before Width: | Height: | Size: 820 B |
|
Before Width: | Height: | Size: 823 B |
|
Before Width: | Height: | Size: 730 B |
|
Before Width: | Height: | Size: 888 B |
|
Before Width: | Height: | Size: 874 B |
|
Before Width: | Height: | Size: 649 B |
|
Before Width: | Height: | Size: 900 B |
|
Before Width: | Height: | Size: 945 B |
|
Before Width: | Height: | Size: 894 B |
|
Before Width: | Height: | Size: 810 B |
|
Before Width: | Height: | Size: 841 B |
|
Before Width: | Height: | Size: 818 B |
|
Before Width: | Height: | Size: 844 B |
|
Before Width: | Height: | Size: 895 B |
|
Before Width: | Height: | Size: 638 B |
|
Before Width: | Height: | Size: 717 B |
|
Before Width: | Height: | Size: 911 B |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 563 B |
|
Before Width: | Height: | Size: 945 B |
|
Before Width: | Height: | Size: 612 B |
|
Before Width: | Height: | Size: 557 B |
|
Before Width: | Height: | Size: 656 B |
|
Before Width: | Height: | Size: 662 B |
|
Before Width: | Height: | Size: 600 B |
|
Before Width: | Height: | Size: 703 B |
|
Before Width: | Height: | Size: 732 B |
|
Before Width: | Height: | Size: 833 B |
|
Before Width: | Height: | Size: 864 B |
|
Before Width: | Height: | Size: 975 B |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 977 B |
|
Before Width: | Height: | Size: 430 B |
|
Before Width: | Height: | Size: 820 B |
|
Before Width: | Height: | Size: 981 B |
|
Before Width: | Height: | Size: 461 B |
|
Before Width: | Height: | Size: 619 B |
|
Before Width: | Height: | Size: 627 B |
|
Before Width: | Height: | Size: 655 B |
|
Before Width: | Height: | Size: 836 B |
|
Before Width: | Height: | Size: 964 B |
|
Before Width: | Height: | Size: 657 B |
|
Before Width: | Height: | Size: 643 B |
|
Before Width: | Height: | Size: 641 B |
|
Before Width: | Height: | Size: 655 B |
|
Before Width: | Height: | Size: 610 B |
|
Before Width: | Height: | Size: 841 B |
|
Before Width: | Height: | Size: 841 B |
|
Before Width: | Height: | Size: 841 B |
|
Before Width: | Height: | Size: 841 B |
|
Before Width: | Height: | Size: 866 B |
|
Before Width: | Height: | Size: 866 B |
|
Before Width: | Height: | Size: 866 B |
|
Before Width: | Height: | Size: 866 B |