using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Windows.Forms; using FlatSharp; using FontAwesome.Sharp; using pkNX.Containers; using pkNX.Game; using pkNX.Randomization; using pkNX.Structures; using pkNX.Structures.FlatBuffers; using pkNX.Structures.FlatBuffers.Arceus; using pkNX.WinForms.Subforms; using static pkNX.Structures.Species; using EvolutionSet = pkNX.Structures.FlatBuffers.Arceus.EvolutionSet; using Learnset = pkNX.Structures.FlatBuffers.Arceus.Learnset; using TrainerData = pkNX.Structures.FlatBuffers.Arceus.TrainerData; using Util = pkNX.Randomization.Util; // ReSharper disable UnusedMember.Global namespace pkNX.WinForms.Controls; internal class EditorPLA : EditorBase { protected override GameManagerPLA ROM { get; } private GameData8a Data => ROM.Data; protected internal EditorPLA(GameManagerPLA rom) { ROM = rom; CheckOodleDllPresence(); } private static void CheckOodleDllPresence() { const string file = $"{Oodle.OodleLibraryPath}.dll"; var dir = Application.StartupPath; var path = Path.Combine(dir, file); if (!File.Exists(path)) WinFormsUtil.Alert($"{file} not found in the executable folder", "Some decompression functions may cause errors."); } public void PopFlat(GameFile file, string title, Func> sel, Func getName, Action>? rand = null, Action? addEntryCallback = null, bool canSave = true) where T1 : class, IFlatBufferSerializable where T2 : class { var obj = ROM.GetFile(file); var tableCache = new TableCache(obj, sel); DataCache loader(GenericEditor form) { if (form.Modified) tableCache.Save(); tableCache = new TableCache(obj, sel); return tableCache.Cache; } Action? cb = null; if (addEntryCallback != null) cb = () => addEntryCallback.Invoke(tableCache.Root); using var form = new GenericEditor(loader, getName, title, rand, cb, canSave); form.ShowDialog(); if (form.Modified) { tableCache.Save(); } } private static bool PopFlat(IList arr, string title, Func getName, Action>? rand = null, bool canSave = true) where T2 : class { using var form = new GenericEditor(_ => new DataCache(arr!), getName, title, rand, null, canSave); form.ShowDialog(); return form.Modified; } public void PopFlatConfig(GameFile file, string title) { PopFlat(file, title, z => z.Table, (z, _) => z.Name); } public int[] GetSpeciesBanlist() { var pt = Data.PersonalData; var hasForm = new HashSet(); var banned = new HashSet(); foreach (var pi in pt.Table.Cast()) { if (pi.IsPresentInGame) { banned.Remove(pi.DexIndexNational); hasForm.Add(pi.DexIndexNational); } else if (!hasForm.Contains(pi.DexIndexNational)) { banned.Add(pi.DexIndexNational); } } return [.. banned]; } public int GetRandomForm(int spec) { var pt = Data.PersonalData; var formRand = pt.Table.Cast() .Where(z => z.IsPresentInGame && !(Legal.BattleExclusiveForms.Contains(z.DexIndexNational) || Legal.BattleFusions.Contains(z.DexIndexNational))) .GroupBy(z => z.DexIndexNational) .ToDictionary(z => z.Key, z => z.ToList()); if (!formRand.TryGetValue((ushort)spec, out var entries)) return 0; var count = entries.Count; return (Species)spec switch { Growlithe or Arcanine or Voltorb or Electrode or Typhlosion or Qwilfish or Samurott or Lilligant or Zorua or Zoroark or Braviary or Sliggoo or Goodra or Avalugg or Decidueye => 1, Basculin => 2, Kleavor => 0, _ => Util.Random.Next(0, count), }; } [EditorCallable(EditorCategory.None, icon: IconChar.Download)] public void EditMasterDump() { using var md = new DumperPLA(ROM); md.ShowDialog(); } #region Dialog Editors [EditorCallable(EditorCategory.Dialog)] public void EditCommon() { var config = new TextConfig(ROM.Game); var form = new WPFTextEditor(WPFTextEditor.TextEditorMode.Common, config); form.ShowDialog(); } [EditorCallable(EditorCategory.Dialog)] public void EditScript() { var config = new TextConfig(ROM.Game); var form = new WPFTextEditor(WPFTextEditor.TextEditorMode.Script, config); form.ShowDialog(); } #endregion #region Pokemon Editors [EditorCallable(EditorCategory.Pokemon, icon: IconChar.Dragon)] public void EditPokemon() { var editor = new PokeEditor8a { Personal = Data.PersonalData, PokeMisc = new(ROM.GetFile(GameFile.PokeMisc), z => z.Table), SymbolBehave = new(ROM.GetFile(GameFile.SymbolBehave), z => z.Table), Evolve = Data.EvolutionData, Learn = Data.LevelUpData, FieldDropTables = Data.FieldDrops, BattleDropTabels = Data.BattleDrops, DexResearch = Data.DexResearch, PokeResourceList = new(ROM.GetFile(GameFile.PokemonResourceList), z => z.Table), PokeResourceTable = new(ROM.GetFile(GameFile.PokemonResourceTable), z => z.Table), EncounterRateTable = new(ROM.GetFile(GameFile.EncounterRateTable), z => z.Table), CaptureCollisionTable = new(ROM.GetFile(GameFile.PokeCaptureCollision), z => z.Table), }; var form = new PokemonEditor(editor, ROM, Data); form.ShowDialog(); if (!form.Modified) editor.CancelEdits(); else editor.Save(); } [EditorCallable(EditorCategory.Pokemon)] public void EditBehaviour() { var names = ROM.GetStrings(TextName.SpeciesNames); PopFlat(GameFile.SymbolBehave, "Symbol Behavior Editor", z => z.Table, (z, _) => $"{names[z.Species]}{(z.IsAlpha ? "*" : "")}{(z.Form != 0 ? $"-{z.Form}" : "")}"); } [EditorCallable(EditorCategory.Pokemon, advanced: true, editorName: "(Raw) Evolutions")] public void EditEvolutionsRaw() { var names = ROM.GetStrings(TextName.SpeciesNames); PopFlat(GameFile.Evolutions, "Evolution Editor", z => z.Table, (z, _) => $"{names[z.Species]}{(z.Form != 0 ? $"-{z.Form}" : "")}"); } [EditorCallable(EditorCategory.Pokemon, advanced: true, editorName: "(Raw) Learnset")] public void EditLearnsetRaw() { var names = ROM.GetStrings(TextName.SpeciesNames); PopFlat(GameFile.Learnsets, "Learnset Editor (Raw)", z => z.Table, (z, _) => $"{names[z.Species]}{(z.Form == 0 ? "" : $"-{z.Form}")}"); } [EditorCallable(EditorCategory.Pokemon, advanced: true, editorName: "(Raw) Personal")] public void EditPersonalRaw() { var names = ROM.GetStrings(TextName.SpeciesNames); PopFlat(GameFile.PersonalStats, "Personal Info Editor (Raw)", z => z.Table, (z, _) => $"{names[z.DexIndexNational]}{(z.Form == 0 ? "" : $"-{z.Form}")}"); } [EditorCallable(EditorCategory.Pokemon, advanced: true, editorName: "(Raw) Personal Misc")] public void EditMiscSpeciesInfoRaw() { var names = ROM.GetStrings(TextName.SpeciesNames); PopFlat(GameFile.PokeMisc, "Misc Species Info Editor", z => z.Table, (z, _) => $"{names[z.Species]}{(z.Form == 0 ? "" : $"-{z.Form}")} ~ {z.Value}"); } [EditorCallable(EditorCategory.Pokemon)] public void EditEvolutionConfig() => PopFlatConfig(GameFile.EvolutionConfig, "Evolution Config Editor"); [EditorCallable(EditorCategory.Pokemon, icon: IconChar.Gift)] public void EditGift() { var names = ROM.GetStrings(TextName.SpeciesNames); PopFlat(GameFile.EncounterTableGift, "Gift Encounter Editor", z => z.Table, (z, _) => $"{names[z.Species]}{(z.Form == 0 ? "" : $"-{z.Form}")} @ Lv. {z.Level}", Randomize); void Randomize(IEnumerable arr) { var settings = EditUtil.Settings.Species; var rand = new SpeciesRandomizer(ROM.Info, Data.PersonalData); settings.Legends = false; rand.Initialize(settings, GetSpeciesBanlist()); foreach (var t in arr) { t.Species = rand.GetRandomSpecies(t.Species); t.Form = (byte)GetRandomForm(t.Species); t.Nature = NatureType.Random; t.Gender = (int)FixedGender.Random; t.ShinyLock = ShinyType.Random; t.Ball = Util.Random.Next(27, 37); // [Strange, Origin] t.Move1 = t.Move2 = t.Move3 = t.Move4 = 0; t.Height = t.Weight = -1; } } } [EditorCallable(EditorCategory.Pokemon, advanced: true)] public void EditPokeCaptureCollision() { var names = ROM.GetStrings(TextName.SpeciesNames); PopFlat(GameFile.PokeCaptureCollision, "Pokemon Capture Collision Editor", z => z.Table, (z, _) => $"{names[z.Species]}{(z.Form == 0 ? "" : $"-{z.Form}")}"); } [EditorCallable(EditorCategory.Pokemon)] public void EditEventRestrictionBattle() => PopFlatConfig(GameFile.EventRestrictionBattle, "Event Restriction Battle Editor"); [EditorCallable(EditorCategory.Pokemon)] public void EditBuddyConfig() => PopFlatConfig(GameFile.BuddyConfig, "Buddy Config Editor"); [EditorCallable(EditorCategory.Pokemon)] public void EditBuddyDirectItemConfig() => PopFlatConfig(GameFile.BuddyDirectItemConfig, "Buddy Direct Item Config Editor"); [EditorCallable(EditorCategory.Pokemon)] public void EditBuddyGroupTalkConfig() => PopFlatConfig(GameFile.BuddyGroupTalkConfig, "Buddy Group Talk Config Editor"); [EditorCallable(EditorCategory.Pokemon)] public void EditBuddyLandmarkConfig() => PopFlatConfig(GameFile.BuddyLandmarkConfig, "Buddy Landmark Config Editor"); [EditorCallable(EditorCategory.Pokemon)] public void EditBuddyNPCReactionConfig() => PopFlatConfig(GameFile.BuddyNPCReactionConfig, "Buddy NPC Reaction Config Editor"); [EditorCallable(EditorCategory.Pokemon)] public void EditBuddyPlayerModeConfig() => PopFlatConfig(GameFile.BuddyPlayerModeConfig, "Buddy Player Mode Config Editor"); [EditorCallable(EditorCategory.Pokemon)] public void EditBuddyWarpConfig() => PopFlatConfig(GameFile.BuddyWarpConfig, "Buddy Warp Config Editor"); [EditorCallable(EditorCategory.Pokemon)] public void EditCaptureConfig() => PopFlatConfig(GameFile.CaptureConfig, "Capture Config Editor"); [EditorCallable(EditorCategory.Pokemon)] public void EditPokemonFieldConfig() => PopFlatConfig(GameFile.PokemonConfig, "Pokemon Field Config"); [EditorCallable(EditorCategory.Pokemon)] public void EditPokemonControllerConfig() => PopFlatConfig(GameFile.PokemonControllerConfig, "Pokemon Controller Config"); [EditorCallable(EditorCategory.Pokemon)] public void EditPokemonFriendshipConfig() => PopFlatConfig(GameFile.PokemonFriendshipConfig, "Pokemon Friendship Config"); [EditorCallable(EditorCategory.Pokemon)] public void EditSizeScaleConfig() => PopFlatConfig(GameFile.SizeScaleConfig, "Size Scale Config"); #endregion #region AI Editors [EditorCallable(EditorCategory.AI)] public void EditAICommonConfig() => PopFlatConfig(GameFile.AICommonConfig, "AI Common Config Editor"); [EditorCallable(EditorCategory.AI)] public void EditAIExcitingConfig() => PopFlatConfig(GameFile.AIExcitingConfig, "AI Exciting Config Editor"); [EditorCallable(EditorCategory.AI)] public void EditAISemiLegendConfig() => PopFlatConfig(GameFile.AISemiLegendConfig, "AI Semi Legend Config Editor"); [EditorCallable(EditorCategory.AI)] public void EditAITirednessConfig() => PopFlatConfig(GameFile.AITirednessConfig, "AI Tiredness Config Editor"); [EditorCallable(EditorCategory.AI)] public void EditNPC_AIConfig() => PopFlatConfig(GameFile.NPCAIConfig, "NPC AI Config"); [EditorCallable(EditorCategory.AI)] public void EditNPCPokemonAIConfig() => PopFlatConfig(GameFile.NPCPokemonAIConfig, "NPC Pokemon AI Config"); #endregion #region Field Editors [EditorCallable(EditorCategory.Field, icon: IconChar.CloudSunRain)] public void EditAreaWeather() { var gfp = (GFPack)ROM.GetFile(GameFile.Resident); var data = gfp[2065]; var obj = FlatBufferConverter.DeserializeFrom(data); var result = PopFlat(obj.Table, "Area Weather Editor", (z, _) => z.Hash.ToString("X16")); if (!result) return; gfp[2065] = obj.SerializeFrom(); } [EditorCallable(EditorCategory.Field, icon: IconChar.LocationCrosshairs)] public void EditStaticEncounter() { var names = ROM.GetStrings(TextName.SpeciesNames); PopFlat(GameFile.EncounterTableStatic, "Static Encounter Editor", z => z.Table, (z, _) => $"{z.EncounterName} ({GetDetail(z, names)})", Randomize); static string GetDetail(EventEncount z, string[] names) { if (z.Table is not { Count: not 0 } x) return "No Entries"; var s = x[0]; return $"{names[s.Species]}{(s.Form == 0 ? "" : $"-{s.Form}")} @ Lv. {s.Level}"; } void Randomize(IEnumerable arr) { var settings = EditUtil.Settings.Species; var rand = new SpeciesRandomizer(ROM.Info, Data.PersonalData); settings.Legends = false; rand.Initialize(settings, GetSpeciesBanlist()); foreach (var entry in arr) { if (entry.Table is not { Count: > 0 } x) continue; foreach (var t in x) { bool isBoss = t.Species is (int)Kleavor or (int)Lilligant or (int)Arcanine or (int)Electrode or (int)Avalugg or (int)Arceus; if (isBoss) // don't randomize boss battles continue; if (Legal.Legendary_8a.Contains(t.Species)) // don't randomize legendaries continue; t.Species = rand.GetRandomSpecies(t.Species); t.Form = (byte)GetRandomForm(t.Species); t.Nature = (NatureType)Nature.Random; t.Gender = (int)FixedGender.Random; t.ShinyLock = ShinyType.Random; t.Move1 = t.Move2 = t.Move3 = t.Move4 = 0; t.Mastered1 = t.Mastered2 = t.Mastered3 = t.Mastered4 = true; t.IVHP = t.IVATK = t.IVDEF = t.IVSPA = t.IVSPD = t.IVSPE = 31; t.GVHP = t.GVATK = t.GVDEF = t.GVSPA = t.GVSPD = t.GVSPE = 10; t.Height = t.Weight = -1; } } } } [EditorCallable(EditorCategory.Field, icon: IconChar.Xmark)] public void EditEncounterRate() { var names = ROM.GetStrings(TextName.SpeciesNames); PopFlat(GameFile.EncounterRateTable, "Encounter Rate Editor", z => z.Table, (z, _) => $"{names[z.Species]}{(z.Form == 0 ? "" : $"-{z.Form}")}"); } [EditorCallable(EditorCategory.Field, icon: IconChar.Map)] public void EditMapViewer() { var resident = (GFPack)ROM.GetFile(GameFile.Resident); using var form = new MapViewer8a(ROM, resident); form.ShowDialog(); } [EditorCallable(EditorCategory.Field, icon: IconChar.Mountain)] public void EditAreas() { using var form = new AreaEditor8a(ROM); form.ShowDialog(); } [EditorCallable(EditorCategory.Field, icon: IconChar.Star)] public void EditShinyRate() => PopFlatConfig(GameFile.ShinyRolls, "Shiny Rate Editor"); [EditorCallable(EditorCategory.Field)] public void EditWormholeRate() => PopFlatConfig(GameFile.WormholeConfig, "Wormhole Config Editor"); [EditorCallable(EditorCategory.Field)] public void EditOutbreakConfig() => PopFlatConfig(GameFile.OutbreakConfig, "Outbreak Configuration Editor"); [EditorCallable(EditorCategory.Field)] public void EditOutbreakDetail() => PopFlat(GameFile.Outbreak, "Outbreak Proc Editor", z => z.Table, (z, _) => z.WorkValueName); [EditorCallable(EditorCategory.Field)] public void EditNewOutbreakGroup() => PopFlat(GameFile.NewHugeGroup, "New Outbreak Group Editor", z => z.Table, (z, _) => z.Group.ToString("X16")); [EditorCallable(EditorCategory.Field)] public void EditNewOutbreakGroupLottery() => PopFlat(GameFile.NewHugeGroupLottery, "New Outbreak Group Lottery Editor", z => z.Table, (z, _) => z.LotteryGroup.ToString("X16")); [EditorCallable(EditorCategory.Field)] public void EditNewOutbreakLottery() => PopFlat(GameFile.NewHugeLottery, "New Outbreak Lottery Editor", z => z.Table, (z, _) => z.LotteryGroupString); [EditorCallable(EditorCategory.Field)] public void EditNewOutbreakTimeLimit() => PopFlat(GameFile.NewHugeTimeLimit, "New Outbreak Time Limit Editor", z => z.Table, (z, _) => z.Duration.ToString()); [EditorCallable(EditorCategory.Field)] public void EditFieldAttackConfig() => PopFlatConfig(GameFile.AIFieldWazaConfig, "AI Field Attack Config Editor"); [EditorCallable(EditorCategory.Field, advanced: true)] public void EditWildPokemonConfig() => PopFlatConfig(GameFile.FieldWildPokemonConfig, "Field Wild Pokemon Config"); [EditorCallable(EditorCategory.Field)] public void EditLandmarkConfig() => PopFlatConfig(GameFile.FieldLandmarkConfig, "Field Landmark Config Editor"); [EditorCallable(EditorCategory.Field)] public void EditSpawnerConfig() => PopFlatConfig(GameFile.FieldSpawnerConfig, "Field Spawner Config Editor"); [EditorCallable(EditorCategory.Field)] public void EditCameraConfig() => PopFlatConfig(GameFile.FieldCameraConfig, "Field Camera Config"); [EditorCallable(EditorCategory.Field)] public void EditCaptureDirectorConfig() => PopFlatConfig(GameFile.FieldCaptureDirectorConfig, "Field Capture Director Config"); [EditorCallable(EditorCategory.Field)] public void EditCharaViewerConfig() => PopFlatConfig(GameFile.FieldCharaViewerConfig, "Field Chara Viewer Config"); [EditorCallable(EditorCategory.Field)] public void EditCommonConfig() => PopFlatConfig(GameFile.FieldCommonConfig, "Field Common Config"); [EditorCallable(EditorCategory.Field)] public void EditDirectItemConfig() => PopFlatConfig(GameFile.FieldDirectItemConfig, "Field Direct Item Config"); [EditorCallable(EditorCategory.Field, icon: IconChar.Clock)] public void EditEnvConfig() => PopFlatConfig(GameFile.FieldEnvConfig, "Field Env Config"); [EditorCallable(EditorCategory.Field)] public void EditItemRespawn() => PopFlatConfig(GameFile.FieldItemRespawn, "Field Item Respawn"); [EditorCallable(EditorCategory.Field)] public void EditLandmarkInciteConfig() => PopFlatConfig(GameFile.FieldLandmarkInciteConfig, "Field Landmark Incite Config"); [EditorCallable(EditorCategory.Field)] public void EditPokeBallNoHitConfig() => PopFlatConfig(GameFile.FieldBallMissedConfig, "Field My Poke Ball Hit None Target Config"); [EditorCallable(EditorCategory.Field)] public void EditObstructionWazaConfig() => PopFlatConfig(GameFile.FieldObstructionWazaConfig, "Field Obstruction Waza Config"); [EditorCallable(EditorCategory.Field)] public void EditPokemonSlopeConfig() => PopFlatConfig(GameFile.FieldPokemonSlopeConfig, "Field Pokemon Slope Config"); [EditorCallable(EditorCategory.Field)] public void EditQuestDestinationConfig() => PopFlatConfig(GameFile.FieldQuestDestinationConfig, "Field Quest Destination Config"); [EditorCallable(EditorCategory.Field)] public void EditThrowConfig() => PopFlatConfig(GameFile.FieldThrowConfig, "Field Throw Config"); [EditorCallable(EditorCategory.Field)] public void EditThrowableAfterHitConfig() => PopFlatConfig(GameFile.FieldThrowableAfterHitConfig, "Field Throwable After Hit Config"); #endregion #region Battle Editors [EditorCallable(EditorCategory.Battle)] public void EditTrainers() { var folder = ROM.GetFilteredFolder(GameFile.TrainerSpecData); var names = folder.GetPaths().Select(Path.GetFileNameWithoutExtension).ToArray(); var cache = new DataCache(folder) { Create = FlatBufferConverter.DeserializeFrom, Write = FlatBufferConverter.SerializeFrom, }; using var form = new GenericEditor(_ => cache, (_, i) => names[i] ?? string.Empty, "Trainers", Randomize, canSave: true); form.ShowDialog(); void Randomize(IEnumerable arr) { var settings = EditUtil.Settings.Species; var rand = new SpeciesRandomizer(ROM.Info, Data.PersonalData); rand.Initialize(settings, GetSpeciesBanlist()); foreach (var t in arr) { foreach (var pk in t.Team) { pk.Species = rand.GetRandomSpecies(pk.Species); pk.Form = GetRandomForm(pk.Species); pk.Gender = (int)FixedGender.Random; pk.Nature = NatureType.Random; pk.Move01.Move = pk.Move02.Move = pk.Move03.Move = pk.Move04.Move = 0; pk.Move01.Mastered = pk.Move02.Mastered = pk.Move03.Mastered = pk.Move04.Mastered = true; pk.Shiny = Util.Random.Next(0, 100 + 1) < 3; pk.IsOybn = Util.Random.Next(0, 100 + 1) < 3; } } } if (!form.Modified) cache.CancelEdits(); else cache.Save(); } [EditorCallable(EditorCategory.Battle)] public void EditMoves() { var obj = ROM[GameFile.MoveStats]; // folder var cache = new DataCache(obj) { Create = FlatBufferConverter.DeserializeFrom, Write = FlatBufferConverter.SerializeFrom, }; var names = ROM.GetStrings(TextName.MoveNames); using var form = new GenericEditor(_ => cache, (_, i) => names[i], "Move Editor"); form.ShowDialog(); if (!form.Modified) { cache.CancelEdits(); return; } cache.Save(); Data.MoveData.ClearAll(); // force reload if used again } [EditorCallable(EditorCategory.Battle)] public void EditBattleCommonConfig() => PopFlatConfig(GameFile.BattleCommonConfig, "Battle Common Config Editor"); [EditorCallable(EditorCategory.Battle)] public void EditBattleEndConfig() => PopFlatConfig(GameFile.BattleEndConfig, "Battle End Config Editor"); [EditorCallable(EditorCategory.Battle)] public void EditBattleInConfig() => PopFlatConfig(GameFile.BattleInConfig, "Battle In Config Editor"); [EditorCallable(EditorCategory.Battle)] public void EditBattleLogicConfig() => PopFlatConfig(GameFile.BattleLogicConfig, "Battle Logic Config Editor"); [EditorCallable(EditorCategory.Battle)] public void EditBattleStartConfig() => PopFlatConfig(GameFile.BattleStartConfig, "Battle Start Config Editor"); [EditorCallable(EditorCategory.Battle)] public void EditBattleViewConfig() => PopFlatConfig(GameFile.BattleViewConfig, "Battle View Config Editor"); [EditorCallable(EditorCategory.Battle)] public void EditBattleVsnsConfig() => PopFlatConfig(GameFile.BattleVsnsConfig, "Battle Vsns Config Editor"); #endregion #region Shop Editors [EditorCallable(EditorCategory.Shops)] public void EditMoveShop() { var names = ROM.GetStrings(TextName.MoveNames); PopFlat(GameFile.MoveShop, "Move Shop Editor", z => z.Table, (z, _) => names[z.Move]); } [EditorCallable(EditorCategory.Shops)] public void EditHaShopData() { var names = ROM.GetStrings(TextName.ItemNames); PopFlat(GameFile.HaShop, "ha_shop_data Editor", z => z.Table, (z, _) => names[z.ItemID], Randomize); static void Randomize(IEnumerable arr) { foreach (var t in arr) { if (Legal.Pouch_Recipe_LA.Contains((ushort)t.ItemID)) // preserve recipes continue; t.ItemID = Legal.Pouch_Items_LA[Util.Random.Next(Legal.Pouch_Items_LA.Length)]; } } } #endregion #region Graphics Editors //[EditorCallable(EditorCategory.Graphics)] //public void EditPokemonModels() //{ /*var pokemonModelDir = (FolderContainer)ROM[GameFile.PokemonArchiveFolder]; pokemonModelDir.Initialize(); CB_Species.Items.AddRange(PokemonModelDir.GetFileNames().Where(x => x != "pokeconfig.gfpak").ToArray()); using var form = new ModelConverter(ROM); form.ShowDialog(); var gfp = (GFPack)ROM.GetFile(GameFile.Resident); var result = PopFlat(obj.Table, "NPC Model Set Editor", (z, _) => z.NPCModelHash.ToString()); if (!result) return; gfp[index] = FlatBufferConverter.SerializeFrom(obj);*/ /*var pokemonModelDir = (FolderContainer)ROM[GameFile.PokemonArchiveFolder]; pokemonModelDir.Initialize(); var fileNames = pokemonModelDir.GetFileNames().Where(x => x != "pokeconfig.gfpak"); var pack = new GFPack(pokemonModelDir.GetFileData(selectedFile) ?? Array.Empty()); PokemonModelArchive archive = new(pack); var cache = new DataCache(obj) { Create = PokemonModelArchive.new(GFPack), Write = FlatBufferConverter.SerializeFrom, }; var tableCache = new TableCache(obj); DataCache loader(GenericEditor form) { if (form.Modified) tableCache.Save(); tableCache = new TableCache(obj); return tableCache.Cache; } using var form = new GenericEditor(loader, (z, _) => z.NPCModelHash.ToString(), "Pokemon Model Editor"); form.ShowDialog(); if (form.Modified) { tableCache.Save(); }*/ //} [EditorCallable(EditorCategory.Graphics)] public void EditNPCModelSet() { var gfp = (GFPack)ROM.GetFile(GameFile.Resident); var index = gfp.GetIndexFull("bin/field/param/placement/common/npc_model_set.bin"); var obj = FlatBufferConverter.DeserializeFrom(gfp[index]); var result = PopFlat(obj.Table, "NPC Model Set Editor", (z, _) => z.NPCModelHash.ToString()); if (!result) return; gfp[index] = obj.SerializeFrom(); } [EditorCallable(EditorCategory.Graphics)] public void EditPokemonModelSet() { var gfp = (GFPack)ROM.GetFile(GameFile.Resident); var index = gfp.GetIndexFull("bin/field/param/placement/common/pokemon_model_set.bin"); var obj = FlatBufferConverter.DeserializeFrom(gfp[index]); var names = ROM.GetStrings(TextName.SpeciesNames); var result = PopFlat(obj.Table, "Pokemon Model Set Editor", (z, _) => $"{names[z.Species]}{(z.Form == 0 ? "" : $"-{z.Form}")} ({z.VariantDesc})"); if (!result) return; gfp[index] = obj.SerializeFrom(); } [EditorCallable(EditorCategory.Graphics)] public void EditPokeResourceTable() { var names = ROM.GetStrings(TextName.SpeciesNames); PopFlat(GameFile.PokemonResourceTable, "Pokemon Resource Table", z => z.Table, (z, _) => $"{names[z.SpeciesInfo.Species]}{(z.SpeciesInfo.Form == 0 ? "" : $"-{z.SpeciesInfo.Form}")}{(z.SpeciesInfo.Gender == 0 ? "" : $" ({z.SpeciesInfo.Gender})")}"); } [EditorCallable(EditorCategory.Graphics)] public void EditPokemonResourceList() { var names = ROM.GetStrings(TextName.SpeciesNames); PopFlat(GameFile.PokemonResourceList, "Pokemon Resource List", z => z.Table, (z, _) => $"{names[z.Species]}"); } [EditorCallable(EditorCategory.Graphics)] public void EditPokeBodyParticle() { var names = ROM.GetStrings(TextName.SpeciesNames); PopFlat(GameFile.PokeBodyParticle, "Pokemon Body Particle Editor", z => z.Table, (z, _) => $"{names[z.Species]}{(z.Form == 0 ? "" : $"-{z.Form}")}"); } [EditorCallable(EditorCategory.Graphics)] public void EditWeatheringConfig() => PopFlatConfig(GameFile.FieldWeatheringConfig, "Field Weathering Config"); [EditorCallable(EditorCategory.Graphics)] public void EditFieldBallThrowEffect() => PopFlatConfig(GameFile.FieldAreaSpeedConfig, "Field Area Speed Config"); [EditorCallable(EditorCategory.Graphics)] public void EditFieldItem() => PopFlatConfig(GameFile.FieldItem, "Field Item"); [EditorCallable(EditorCategory.Graphics)] public void EditFieldAnimationFramerate() => PopFlatConfig(GameFile.FieldAnimationFramerateConfig, "Field Anime Framerate Config"); [EditorCallable(EditorCategory.Graphics)] public void EditWaterMotion() => PopFlatConfig(GameFile.WaterMotion, "Water Motion Configuration"); [EditorCallable(EditorCategory.Graphics)] public void EditAppliHudConfig() => PopFlatConfig(GameFile.AppliHudConfig, "Appli Hud Config Editor"); [EditorCallable(EditorCategory.Graphics)] public void EditAppliTipsConfig() => PopFlatConfig(GameFile.AppliTipsConfig, "Appli Tips Config Editor"); [EditorCallable(EditorCategory.Graphics)] public void EditEventCullingConfig() => PopFlatConfig(GameFile.EventCullingConfig, "Event Culling Config Editor"); [EditorCallable(EditorCategory.Graphics)] public void EditEventDitherConfig() => PopFlatConfig(GameFile.EventDitherConfig, "Event Dither Config Editor"); [EditorCallable(EditorCategory.Graphics)] public void EditFieldShadowConfig() => PopFlatConfig(GameFile.FieldShadowConfig, "Field Shadow Config"); #endregion #region Items Editors [EditorCallable(EditorCategory.Items)] public void EditThrowParam() { PopFlat(GameFile.ThrowParam, "Throw Param Editor", z => z.Table, (z, _) => z.ThrowParamType.ToString()); } [EditorCallable(EditorCategory.Items)] public void EditThrowPermissionSetParam() { PopFlat(GameFile.ThrowPermissionSet, "Throw Permission Editor", z => z.Table, (z, _) => z.ThrowPermissionSet.ToString()); } [EditorCallable(EditorCategory.Items)] public void EditThrowableParam() { var itemNames = ROM.GetStrings(TextName.ItemNames); PopFlat(GameFile.ThrowableParam, "Throwable Param Editor", z => z.Table, (z, _) => $"{itemNames[z.ItemID]} ({z.ItemID})", null, t => t.AddEntry(0)); } [EditorCallable(EditorCategory.Items)] public void EditThrowResourceDictionary() { PopFlat(GameFile.ThrowableResource, "Throwable Resource Dictionary Editor", z => z.Table, (z, _) => z.Hash00.ToString("X16")); } [EditorCallable(EditorCategory.Items)] public void EditThrowResourceSetDictionary() { PopFlat(GameFile.ThrowableResourceSet, "Throwable Resource Set Dictionary Editor", z => z.Table, (z, _) => z.ItemType.ToString()); } [EditorCallable(EditorCategory.Items)] public void EditItems() { var obj = ROM[GameFile.ItemStats]; // mini var data = obj[0]; var items = Item8a.GetArray(data); var cache = new DataCache(items); var itemNames = ROM.GetStrings(TextName.ItemNames); using var form = new GenericEditor(_ => cache, (z, _) => $"{itemNames[z.ItemID]} ({z.ItemID})", "Item Editor"); form.ShowDialog(); if (!form.Modified) { cache.CancelEdits(); return; } obj[0] = Item8a.SetArray(items, data); } [EditorCallable(EditorCategory.Items)] public void EditCommonItemConfig() => PopFlatConfig(GameFile.CommonItemConfig, "Common Item Config Editor"); [EditorCallable(EditorCategory.Items, advanced: true)] public void EditEventItemConfig() => PopFlatConfig(GameFile.EventItemConfig, "Event Item Config Editor"); #endregion #region NPC Editors [EditorCallable(EditorCategory.NPC)] public void EditNPCControllerConfig() => PopFlatConfig(GameFile.NPCControllerConfig, "NPC Controller Config"); [EditorCallable(EditorCategory.NPC)] public void EditNPCCreaterConfig() => PopFlatConfig(GameFile.NPCCreaterConfig, "NPC Creater Config"); [EditorCallable(EditorCategory.NPC)] public void EditNPCPopupConfig() => PopFlatConfig(GameFile.NPCPopupConfig, "NPC Popup Config"); [EditorCallable(EditorCategory.NPC)] public void EditNPCTalkTableConfig() => PopFlatConfig(GameFile.NPCTalkTableConfig, "NPC Talk Table Config"); [EditorCallable(EditorCategory.NPC)] public void EditEventBanditConfig() => PopFlatConfig(GameFile.EventBanditConfig, "Event Bandit Config Editor"); #endregion #region Player Editors [EditorCallable(EditorCategory.Player)] public void EditBallThrowConfig() => PopFlatConfig(GameFile.BallThrowConfig, "Ball Throw Config Editor"); [EditorCallable(EditorCategory.Player)] public void EditFieldLockonConfig() => PopFlatConfig(GameFile.FieldLockonConfig, "Field Lockon Config"); [EditorCallable(EditorCategory.Player)] public void EditCharacterBipedIkConfig() => PopFlatConfig(GameFile.CharacterBipedIkConfig, "Character Biped Ik Config Editor"); [EditorCallable(EditorCategory.Player)] public void EditCharacterBlinkConfig() => PopFlatConfig(GameFile.CharacterBlinkConfig, "Character Blink Config Editor"); [EditorCallable(EditorCategory.Player)] public void EditCharacterControllerConfig() => PopFlatConfig(GameFile.CharacterControllerConfig, "Character Controller Config Editor"); [EditorCallable(EditorCategory.Player)] public void EditCharacterLookAtConfig() => PopFlatConfig(GameFile.CharacterLookAtConfig, "Character Look At Config Editor"); [EditorCallable(EditorCategory.Player)] public void EditPlayerCameraShakeConfig() => PopFlatConfig(GameFile.PlayerCameraShakeConfig, "Player Camera Shake Config"); [EditorCallable(EditorCategory.Player)] public void EditPlayerCollisionConfig() => PopFlatConfig(GameFile.PlayerCollisionConfig, "Player Collision Config"); [EditorCallable(EditorCategory.Player)] public void EditPlayerConfig() => PopFlatConfig(GameFile.PlayerConfig, "Player Config Editor"); [EditorCallable(EditorCategory.Player)] public void EditPlayerControllerConfig() => PopFlatConfig(GameFile.PlayerControllerConfig, "Player Controller Config"); [EditorCallable(EditorCategory.Player)] public void EditPlayerFaceConfig() => PopFlatConfig(GameFile.PlayerFaceConfig, "Player Face Config"); [EditorCallable(EditorCategory.Player)] public void EditPlayer1DressupTable() => PopFlat(GameFile.Player1DressupTable, "Player 1 DressUp Table", z => z.Table, (z, _) => z.EntryName); [EditorCallable(EditorCategory.Player)] public void EditPlayer2DressupTable() => PopFlat(GameFile.Player2DressupTable, "Player 2 DressUp Table", z => z.Table, (z, _) => z.EntryName); #endregion #region Rides Editors [EditorCallable(EditorCategory.Rides)] public void EditRideBasuraoCollisionConfig() => PopFlatConfig(GameFile.RideBasuraoCollisionConfig, "Ride Basurao Collision Config"); [EditorCallable(EditorCategory.Rides)] public void EditRideBasuraoConfig() => PopFlatConfig(GameFile.RideBasuraoConfig, "Ride Basurao Config"); [EditorCallable(EditorCategory.Rides)] public void EditRideChangeConfig() => PopFlatConfig(GameFile.RideChangeConfig, "Ride Change Config"); [EditorCallable(EditorCategory.Rides)] public void EditRideCommonConfig() => PopFlatConfig(GameFile.RideCommonConfig, "Ride Common Config"); [EditorCallable(EditorCategory.Rides)] public void EditRideNyuuraCollisionConfig() => PopFlatConfig(GameFile.RideNyuuraCollisionConfig, "Ride Nyuura Collision Config"); [EditorCallable(EditorCategory.Rides)] public void EditRideNyuuraConfig() => PopFlatConfig(GameFile.RideNyuuraConfig, "Ride Nyuura Config"); [EditorCallable(EditorCategory.Rides)] public void EditRideNyuuraControllerConfig() => PopFlatConfig(GameFile.RideNyuuraControllerConfig, "Ride Nyuura Controller Config"); [EditorCallable(EditorCategory.Rides)] public void EditRideOdoshishiCollisionConfig() => PopFlatConfig(GameFile.RideOdoshishiCollisionConfig, "Ride Odoshishi Collision Config"); [EditorCallable(EditorCategory.Rides)] public void EditRideOdoshishiConfig() => PopFlatConfig(GameFile.RideOdoshishiConfig, "Ride Odoshishi Config"); [EditorCallable(EditorCategory.Rides)] public void EditRideRingumaCollisionConfig() => PopFlatConfig(GameFile.RideRingumaCollisionConfig, "Ride Ringuma Collision Config"); [EditorCallable(EditorCategory.Rides)] public void EditRideRingumaConfig() => PopFlatConfig(GameFile.RideRingumaConfig, "Ride Ringuma Config"); [EditorCallable(EditorCategory.Rides)] public void EditRideRingumaControllerConfig() => PopFlatConfig(GameFile.RideRingumaControllerConfig, "Ride Ringuma Controller Config"); [EditorCallable(EditorCategory.Rides)] public void EditRideWhooguruCollisionConfig() => PopFlatConfig(GameFile.RideWhooguruCollisionConfig, "Ride Whooguru Collision Config"); [EditorCallable(EditorCategory.Rides)] public void EditRideWhooguruConfig() => PopFlatConfig(GameFile.RideWhooguruConfig, "Ride Whooguru Config"); [EditorCallable(EditorCategory.Rides)] public void EditRideWhooguruControllerConfig() => PopFlatConfig(GameFile.RideWhooguruControllerConfig, "Ride Whooguru Controller Config"); #endregion #region Audio Editors [EditorCallable(EditorCategory.Audio)] public void EditSoundConfig() => PopFlatConfig(GameFile.SoundConfig, "Sound Config"); [EditorCallable(EditorCategory.Audio)] public void EditFieldVigilanceBgmConfig() => PopFlatConfig(GameFile.FieldVigilanceBgmConfig, "Field Vigilance Bgm Config"); [EditorCallable(EditorCategory.Audio)] public void EditEnvPokeVoiceConfig() => PopFlatConfig(GameFile.EnvPokeVoiceConfig, "Env Poke Voice Config Editor"); #endregion #region Gameplay Editors [EditorCallable(EditorCategory.Gameplay)] public void EditPokedexRankTable() { PopFlat(GameFile.DexRank, "Pokedex Rank Table Editor", z => z.Table, (z, _) => z.Rank.ToString()); } [EditorCallable(EditorCategory.Gameplay)] public void EditEventBalloonRunConfig() => PopFlatConfig(GameFile.EventBalloonrunConfig, "Event Balloon Run Config Editor"); [EditorCallable(EditorCategory.Gameplay)] public void EditEventBalloonThrowConfig() => PopFlatConfig(GameFile.EventBalloonthrowConfig, "Event Balloon Throw Config Editor"); [EditorCallable(EditorCategory.Gameplay)] public void EditEventMkrgRewardConfig() => PopFlatConfig(GameFile.EventMkrgRewardConfig, "Event Mkrg Reward Config Editor"); [EditorCallable(EditorCategory.Gameplay)] public void EditFarmConfig() => PopFlatConfig(GameFile.EventFarmConfig, "Farm Config Editor"); [EditorCallable(EditorCategory.Gameplay)] public void EditEventGameOverConfig() => PopFlatConfig(GameFile.EventGameOverConfig, "Event Game Over Config Editor"); [EditorCallable(EditorCategory.Gameplay, advanced: true)] public void EditEventQuestBoardConfig() => PopFlatConfig(GameFile.EventQuestBoardConfig, "Event Quest Board Config Editor"); #endregion #region Physics Editors [EditorCallable(EditorCategory.Physics)] public void EditBuddyBattleConfig() => PopFlatConfig(GameFile.BuddyBattleConfig, "Buddy Battle Config Editor"); #endregion #region Misc Editors [EditorCallable()] public void ModelConverter() { using var form = new ModelConverter(ROM); form.ShowDialog(); } [EditorCallable()] public void EditPokeEatingHabits() { PopFlat(GameFile.PokeEatingHabits, "Pokemon Eating Habits Editor", z => z.Table, (z, _) => z.ID.ToString()); } [EditorCallable()] public void EditMoveObstructionLegend() { PopFlat(GameFile.MoveObstructionLegend, "PokeFieldObstructionWazaNsLegendArchive Editor", z => z.Table, (z, _) => "error"); } [EditorCallable()] public void EditMoveObstructionLegendEffect() { PopFlat(GameFile.MoveObstructionLegendEffect, "PokeFieldObstructionWazaNsLegendEffectArchive Editor", z => z.Table, (z, _) => "error"); } [EditorCallable()] public void EditMoveObstructionSE() { PopFlat(GameFile.MoveObstructionSE, "PokeFieldObstructionWazaSeArchive Editor", z => z.Table, (z, _) => "error"); } [EditorCallable()] public void EditMoveObstructionWild() { PopFlat(GameFile.MoveObstructionWild, "Poke Field Obstruction Waza Wild Editor", z => z.Table, (z, _) => z.Field00); } [EditorCallable()] public void EditMoveObstructionWildEffect() { PopFlat(GameFile.MoveObstructionWildEffect, "PokeFieldObstructionWazaWildEffectArchive Editor", z => z.Table, (z, _) => "error"); } [EditorCallable()] public void EditMoveObstructionWater() { PopFlat(GameFile.MoveObstructionWater, "PokeFieldObstructionWazaWildWaterArchive Editor", z => z.Table, (z, _) => z.Field00); } [EditorCallable()] public void EditMoveObstructionWaterEffect() { PopFlat(GameFile.MoveObstructionWaterEffect, "PokeFieldObstructionWazaWildWaterEffectArchive Editor", z => z.Table, (z, _) => "error"); } [EditorCallable(advanced: true)] public void EditAppConfigList() { PopFlat(GameFile.AppConfigList, "App Config List", z => z.Table, (z, _) => z.OriginalPath); } [EditorCallable(advanced: true)] public void EditArchiveContents() { var archiveFolder = ROM.GetFilteredFolder(GameFile.ArchiveFolder); var paths = archiveFolder.GetPaths() .Select(p => Path.GetRelativePath(ROM.PathRomFS, p).Replace('\\', '/')) .ToDictionary(p => FnvHash.HashFnv1a_64(p)); PopFlat(GameFile.archive_contents, "Archive Contents Editor", z => z.Table, (z, _) => paths.GetValueOrDefault(z.ArchivePathHash) ?? z.ArchivePathHash.ToString("X16"), addEntryCallback: x => x.AddEntry()); } //[EditorCallable(EditorCategory.Misc, true)] //public void EditPokedexFormStorage() //{ // //PopFlat(GameFile.DexFormStorage, "Pokedex Form Storage Editor", z => z.Rank.ToString()); //} [EditorCallable(advanced: true)] public void EditPokeDefaultLocator() { PopFlat(GameFile.PokeDefaultLocator, "Poke Default Locator Editor", z => z.Table, (z, _) => z.Locator); } [EditorCallable()] public void EditAppliStaffrollConfig() => PopFlatConfig(GameFile.AppliStaffrollConfig, "Appli Staffroll Config Editor"); [EditorCallable(advanced: true)] public void EditCommonGeneralConfig() => PopFlatConfig(GameFile.CommonGeneralConfig, "Common General Config Editor"); [EditorCallable(advanced: true)] public void EditDemoConfig() => PopFlatConfig(GameFile.DemoConfig, "Demo Config Editor"); [EditorCallable()] public void EditEventWork() => PopFlatConfig(GameFile.EventWork, "Event Work Editor"); #endregion }