diff --git a/pkNX.Game/File/GameFile.cs b/pkNX.Game/File/GameFile.cs index 2138e805..dc15dd94 100644 --- a/pkNX.Game/File/GameFile.cs +++ b/pkNX.Game/File/GameFile.cs @@ -1,4 +1,4 @@ -namespace pkNX.Game; +namespace pkNX.Game; /// /// Simple descriptor related to what purpose the game data serves. @@ -197,32 +197,138 @@ public enum GameFile /// All pokedex research tasks DexResearch, - ThrowableParam, ThrowParam, - ThrowableResourceSet, - ThrowableResource, ThrowPermissionSet, + ThrowableParam, + ThrowableResource, + ThrowableResourceSet, - /// Gives bonus rolls based on met thresholds. - ShinyRolls, WormholeConfig, - CaptureConfig, - BattleLogicConfig, - PlayerConfig, - EventFarmConfig, FieldLandmarkConfig, - BattleViewConfig, - AICommonConfig, FieldSpawnerConfig, OutbreakConfig, - EvolutionConfig, BallThrowConfig, - SizeScaleConfig, - AppConfigList, HaShop, NewHugeGroup, NewHugeGroupLottery, NewHugeLottery, NewHugeTimeLimit, -} \ No newline at end of file + + AICommonConfig, + AIExcitingConfig, + AIFieldWazaConfig, + AISemiLegendConfig, + AITirednessConfig, + + AppConfigList, + AppliHudConfig, + AppliStaffrollConfig, + AppliTipsConfig, + + BattleCommonConfig, + BattleEndConfig, + BattleInConfig, + BattleLogicConfig, + BattleStartConfig, + BattleViewConfig, + BattleVsnsConfig, + + BuddyBattleConfig, + BuddyConfig, + BuddyDirectItemConfig, + BuddyGroupTalkConfig, + BuddyLandmarkConfig, + BuddyNPCReactionConfig, + BuddyPlayerModeConfig, + BuddyWarpConfig, + + CharacterBipedIkConfig, + CharacterBlinkConfig, + CharacterControllerConfig, + CharacterLookAtConfig, + + CaptureConfig, + CommonGeneralConfig, + CommonItemConfig, + + DemoConfig, + + EnvPokeVoiceConfig, + EventBalloonrunConfig, + EventBalloonthrowConfig, + EventBanditConfig, + EventCullingConfig, + EventDitherConfig, + EventFarmConfig, + EventGameOverConfig, + EventItemConfig, + EventMkrgRewardConfig, + EventQuestBoardConfig, + EventRestrictionBattle, + EventWork, + + FieldAnimationFramerateConfig, + FieldAreaSpeedConfig, + FieldCameraConfig, + FieldCaptureDirectorConfig, + FieldCharaViewerConfig, + FieldCommonConfig, + FieldDirectItemConfig, + FieldEnvConfig, + FieldItem, + FieldItemRespawn, + FieldLandmarkInciteConfig, + FieldLockonConfig, + FieldMyPokeBallHitNoneTargetConfig, + FieldObstructionWazaConfig, + FieldPokemonSlopeConfig, + FieldQuestDestinationConfig, + FieldShadowConfig, + FieldThrowConfig, + FieldThrowableAfterHitConfig, + FieldVigilanceBgmConfig, + FieldWeatheringConfig, + FieldWildPokemonConfig, + + NPCAIConfig, + NPCControllerConfig, + NPCCreaterConfig, + NPCPokemonAIConfig, + NPCPopupConfig, + NPCTalkTableConfig, + + PlayerCameraShakeConfig, + PlayerCollisionConfig, + PlayerConfig, + PlayerControllerConfig, + PlayerFaceConfig, + + PokemonConfig, + PokemonControllerConfig, + EvolutionConfig, + PokemonFriendshipConfig, + /// Gives bonus rolls based on met thresholds. + ShinyRolls, + SizeScaleConfig, + + RideBasuraoCollisionConfig, + RideBasuraoConfig, + RideChangeConfig, + RideCommonConfig, + RideNyuuraCollisionConfig, + RideNyuuraConfig, + RideNyuuraControllerConfig, + RideOdoshishiCollisionConfig, + RideOdoshishiConfig, + RideRingumaCollisionConfig, + RideRingumaConfig, + RideRingumaControllerConfig, + RideWhooguruCollisionConfig, + RideWhooguruConfig, + RideWhooguruControllerConfig, + + SoundConfig, + + WaterMotion, +} diff --git a/pkNX.Game/File/GameFileMapping.cs b/pkNX.Game/File/GameFileMapping.cs index 2a38973f..588a3d17 100644 --- a/pkNX.Game/File/GameFileMapping.cs +++ b/pkNX.Game/File/GameFileMapping.cs @@ -38,7 +38,7 @@ internal IFileContainer GetFile(GameFile file, int language) Cache.Add(file, container); return container; } - + internal void SaveAll() { foreach (var container in Cache) @@ -232,36 +232,126 @@ internal void SaveAll() new(GameFile.PokeMisc, ContainerType.SingleFile, "bin", "pokemon", "data", "poke_misc.bin"), new(GameFile.Outbreak, ContainerType.SingleFile, "bin", "field", "encount", "huge_outbreak.bin"), new(GameFile.MoveShop, ContainerType.SingleFile, "bin", "appli", "wazaremember", "bin", "wazashop_table.bin"), - - new(GameFile.ThrowableParam, ContainerType.SingleFile, "bin", "capture", "throwable_param_table.bin"), - new(GameFile.ThrowParam, ContainerType.SingleFile, "bin", "capture", "throw_param_table.bin"), - new(GameFile.ThrowableResourceSet, ContainerType.SingleFile, "bin", "capture", "throwable_resourceset_dictionary.bin"), - new(GameFile.ThrowableResource, ContainerType.SingleFile, "bin", "capture", "throwable_resource_dictionary.bin"), - new(GameFile.ThrowPermissionSet, ContainerType.SingleFile, "bin", "capture", "throw_permissionset_dictionary.bin"), new(GameFile.HaShop, ContainerType.SingleFile, "bin", "appli", "shop", "bin", "ha_shop_data.bin"), - new(GameFile.ShinyRolls, ContainerType.SingleFile, "bin", "misc", "app_config", "pokemon_rare.bin"), - new(GameFile.WormholeConfig, ContainerType.SingleFile, "bin", "misc", "app_config", "field_wormhole_config.bin"), - new(GameFile.CaptureConfig, ContainerType.SingleFile, "bin", "misc", "app_config", "common_capture_config.bin"), - new(GameFile.BattleLogicConfig, ContainerType.SingleFile, "bin", "misc", "app_config", "battle_logic_config.bin"), - new(GameFile.PlayerConfig, ContainerType.SingleFile, "bin", "misc", "app_config", "player_config.bin"), - new(GameFile.EventFarmConfig, ContainerType.SingleFile, "bin", "misc", "app_config", "event_farm_config.bin"), - new(GameFile.AppConfigList, ContainerType.SingleFile, "bin", "misc", "app_config", "app_config_list.bin"), - new(GameFile.FieldLandmarkConfig, ContainerType.SingleFile, "bin", "misc", "app_config", "field_landmark_config.bin"), - new(GameFile.BattleViewConfig, ContainerType.SingleFile, "bin", "misc", "app_config", "battle_view_config.bin"), - new(GameFile.AICommonConfig, ContainerType.SingleFile, "bin", "misc", "app_config", "ai_common_config.bin"), - new(GameFile.FieldSpawnerConfig, ContainerType.SingleFile, "bin", "misc", "app_config", "field_spawner_config.bin"), - new(GameFile.OutbreakConfig, ContainerType.SingleFile, "bin", "misc", "app_config", "field_huge_outbreak.bin"), - new(GameFile.EvolutionConfig, ContainerType.SingleFile, "bin", "misc", "app_config", "pokemon_evolution_config.bin"), - new(GameFile.BallThrowConfig, ContainerType.SingleFile, "bin", "misc", "app_config", "field_my_poke_ball_config.bin"), - new(GameFile.SizeScaleConfig, ContainerType.SingleFile, "bin", "misc", "app_config", "pokemon_size_category_adjust_scale_config.bin"), - new(GameFile.SymbolBehave, ContainerType.SingleFile, "bin", "pokemon", "data", "poke_ai.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(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(GameFile.SymbolBehave , ContainerType.SingleFile, "bin", "pokemon", "data", "poke_ai.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.FieldMyPokeBallHitNoneTargetConfig , 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(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"), // Cutscenes bin\demo // Models bin\archive\pokemon // pretty much everything is obviously named :) diff --git a/pkNX.WinForms/Main.cs b/pkNX.WinForms/Main.cs index f63b03cd..c7d9b692 100644 --- a/pkNX.WinForms/Main.cs +++ b/pkNX.WinForms/Main.cs @@ -11,6 +11,10 @@ namespace pkNX.WinForms; public partial class Main : Form { + private const int ButtonWidth = 120; + private const int ButtonHeight = 40; + private const int ButtonPadding = 3; + public static readonly string ProgramSettingsPath = Path.Combine(Application.StartupPath, "settings.json"); public ProgramSettings Settings { get; } @@ -173,19 +177,66 @@ private void OpenFolder(string path, GameVersion gameOverride) } } - private const int ButtonWidth = 120; - private const int ButtonHeight = 40; - private const int ButtonPadding = 3; + private void LoadEditorButtons(EditorCategory category = EditorCategory.None) + { + FLP_Controls.SuspendLayout(); + FLP_Controls.Controls.Clear(); + + if (category == EditorCategory.None) + { + foreach (var c in (EditorCategory[])Enum.GetValues(typeof(EditorCategory))) + { + if (c == EditorCategory.None) + continue; + + if (Editor!.CountControlsForCategory(c) == 0) + continue; + + FLP_Controls.Controls.Add(CreateCategoryButton(c)); + } + } + else + { + // Create back button + FLP_Controls.Controls.Add(CreateCategoryButton(EditorCategory.None)); + } + + AddEditorButtonsForCategory(category); + + FLP_Controls.ResumeLayout(); + } + + private void AddEditorButtonsForCategory(EditorCategory category) + { + var ctrls = Editor!.GetControls(ButtonWidth, ButtonHeight, category).OrderBy(x => x.Text); + + foreach (var ctrl in ctrls) + FLP_Controls.Controls.Add(ctrl); + } + + public Button CreateCategoryButton(EditorCategory category) + { + var b = new Button + { + Width = ButtonWidth, + Height = ButtonHeight, + Name = $"B_OpenCategory{category}", + Text = ((category == EditorCategory.None) ? "Back" : $"Show {category} Editors"), + }; + b.Click += (s, e) => + { + LoadEditorButtons(category); + }; + return b; + } private void LoadROM(EditorBase editor) { Editor = editor; - var ctrl = Editor.GetControls(ButtonWidth, ButtonHeight).OrderBy(x => x.Text); - FLP_Controls.Controls.Clear(); - foreach (var c in ctrl) - FLP_Controls.Controls.Add(c); - const int wp = ButtonWidth + (2 * ButtonPadding) + 3; + LoadEditorButtons(); + + const int wp = ButtonWidth + (2 * ButtonPadding); const int hp = ButtonHeight + (2 * ButtonPadding); const int area = wp * hp; var count = FLP_Controls.Controls.Count; @@ -194,8 +245,8 @@ private void LoadROM(EditorBase editor) var squareSide = Math.Sqrt(totalArea); var columns = (int)Math.Ceiling(squareSide / wp) + 1; var rows = (count / columns) + 2; - Width = (columns * wp) + 6; - Height = FLP_Controls.Location.Y + (rows * hp) + 6; + + ClientSize = new(columns * wp, FLP_Controls.Location.Y + (rows * hp)); CenterToScreen(); Text = $"{nameof(pkNX)} - {Editor.Game}"; diff --git a/pkNX.WinForms/MainEditor/EditorCallableAttribute.cs b/pkNX.WinForms/MainEditor/EditorCallableAttribute.cs new file mode 100644 index 00000000..f44846b8 --- /dev/null +++ b/pkNX.WinForms/MainEditor/EditorCallableAttribute.cs @@ -0,0 +1,44 @@ +using System; + +namespace pkNX.WinForms; + +public enum EditorCategory +{ + None, + Pokemon, + Battle, + Field, + Shops, + Dialog, + Graphics, + Misc, +} + + +[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] +public class EditorCallableAttribute : Attribute +{ + public EditorCategory Category { get; set; } + public string EditorName { get; set; } + + /// + /// Add this attribute to customize the button that will be displayed in the main editor + /// + /// The category of this editor. Add this to hide it under a sub editor button + /// The name that should be displayed on the editor button. Leave empty for automatic conversion from the method name. + public EditorCallableAttribute(EditorCategory category = EditorCategory.Misc, string editorName = "") + { + Category = category; + EditorName = editorName; + } + + public bool HasCustomEditorName() + { + return !string.IsNullOrWhiteSpace(EditorName); + } + + public bool HasCategory() + { + return Category != EditorCategory.None; + } +} diff --git a/pkNX.WinForms/MainEditor/EditorPLA.cs b/pkNX.WinForms/MainEditor/EditorPLA.cs index 6b4aba1d..29451b8a 100644 --- a/pkNX.WinForms/MainEditor/EditorPLA.cs +++ b/pkNX.WinForms/MainEditor/EditorPLA.cs @@ -32,79 +32,6 @@ private static void CheckOodleDllPresence() WinFormsUtil.Alert($"{file} not found in the executable folder", "Some decompression functions may cause errors."); } - public void EditCommon() - { - var text = ROM.GetFilteredFolder(GameFile.GameText, z => Path.GetExtension(z) == ".dat"); - var config = new TextConfig(ROM.Game); - var tc = new TextContainer(text, config); - using var form = new TextEditor(tc, TextEditor.TextEditorMode.Common); - form.ShowDialog(); - if (!form.Modified) - text.CancelEdits(); - } - - public void EditScript() - { - var text = ROM.GetFilteredFolder(GameFile.StoryText, z => Path.GetExtension(z) == ".dat"); - var config = new TextConfig(ROM.Game); - var tc = new TextContainer(text, config); - using var form = new TextEditor(tc, TextEditor.TextEditorMode.Script); - form.ShowDialog(); - if (!form.Modified) - text.CancelEdits(); - } - - public void EditTrainers() - { - var folder = ROM.GetFilteredFolder(GameFile.TrainerData); - var cache = new DataCache(folder) - { - Create = FlatBufferConverter.DeserializeFrom, - Write = FlatBufferConverter.SerializeFrom, - }; - var names = folder.GetPaths().Select(Path.GetFileNameWithoutExtension).OfType().ToArray(); - using var form = new GenericEditor(cache, names, "Trainers", Randomize, canSave: true); - form.ShowDialog(); - - void Randomize() - { - var settings = EditUtil.Settings.Species; - var rand = new SpeciesRandomizer(ROM.Info, Data.PersonalData); - rand.Initialize(settings, GetSpeciesBanlist()); - - for (int i = 0; i < cache.Length; i++) - { - foreach (var t in cache[i].Team) - { - t.Species = rand.GetRandomSpecies(t.Species); - t.Form = GetRandomForm(t.Species); - t.Gender = (int)FixedGender.Random; - t.Nature = NatureType8a.Random; - t.Move_01.Move = t.Move_02.Move = t.Move_03.Move = t.Move_04.Move = 0; - t.Move_01.Mastered = t.Move_02.Mastered = t.Move_03.Mastered = t.Move_04.Mastered = true; - t.Shiny = Randomization.Util.Random.Next(0, 100 + 1) < 3; - t.IsOybn = Randomization.Util.Random.Next(0, 100 + 1) < 3; - } - } - } - - if (!form.Modified) - cache.CancelEdits(); - else - cache.Save(); - } - - public void EditMoveShop() - { - var names = ROM.GetStrings(TextName.MoveNames); - var data = ROM.GetFile(GameFile.MoveShop); - var obj = FlatBufferConverter.DeserializeFrom(data[0]); - var result = PopFlat(obj.Table, "Move Shop Editor", z => names[z.Move]); - if (!result) - return; - data[0] = FlatBufferConverter.SerializeFrom(obj); - } - public void PopFlat(GameFile file, string title, Func getName, Action? rand = null, bool canSave = true) where T1 : class, IFlatBufferArchive where T2 : class { var obj = ROM.GetFile(file); @@ -125,60 +52,149 @@ public void EditMoveShop() return form.Modified; } - public void EditThrowable_Param() + public void PopFlatConfig(GameFile file, string title) { - var itemNames = ROM.GetStrings(TextName.ItemNames); - PopFlat(GameFile.ThrowableParam, "Throwable Param Editor", z => itemNames[z.ItemID]); - } - - public void EditThrow_Param() - { - PopFlat(GameFile.ThrowParam, "Throw Param Editor", z => z.Hash.ToString("X16")); - } - - public void EditThrow_ResourceSet_Dictionary() - { - PopFlat(GameFile.ThrowableResourceSet, "Throwable ResourceSet Dictionary Editor", z => z.Hash_00.ToString("X16")); - } - - public void EditThrow_Resource_Dictionary() - { - PopFlat(GameFile.ThrowableResource, "Throwable Resource Dictionary Editor", z => z.Hash_00.ToString("X16")); - } - - public void EditThrow_PermissionSet_Param() - { - PopFlat(GameFile.ThrowPermissionSet, "Throw Permission Editor", z => z.Hash_00.ToString("X16")); - } - - public void EditHa_Shop_Data() - { - var names = ROM.GetStrings(TextName.ItemNames); - var data = ROM.GetFile(GameFile.HaShop); - var obj = FlatBufferConverter.DeserializeFrom(data[0]); - var result = PopFlat(obj.Table, "ha_shop_data Editor", z => names[z.ItemID], Randomize); - if (!result) + var obj = ROM.GetFile(file); // flatbuffer + var data = obj[0]; + var root = FlatBufferConverter.DeserializeFrom(data); + var cache = new DataCache(root.Table); + var names = root.Table.Select(z => z.Name).ToArray(); + using var form = new GenericEditor(cache, names, title); + form.ShowDialog(); + if (!form.Modified) return; + obj[0] = FlatBufferConverter.SerializeFrom(root); + } - void Randomize() + public int[] GetSpeciesBanlist() + { + var pt = Data.PersonalData; + var hasForm = new HashSet(); + var banned = new HashSet(); + foreach (var pi in pt.Table.Cast()) { - foreach (var t in obj.Table) + if (pi.IsPresentInGame) { - if (Legal.Pouch_Recipe_LA.Contains((ushort)t.ItemID)) // preserve recipes - continue; - t.ItemID = Legal.Pouch_Items_LA[Randomization.Util.Random.Next(Legal.Pouch_Items_LA.Length)]; + banned.Remove(pi.ModelID); + hasForm.Add(pi.ModelID); + } + else if (!hasForm.Contains(pi.ModelID)) + { + banned.Add(pi.ModelID); } } - - data[0] = FlatBufferConverter.SerializeFrom(obj); + return banned.ToArray(); } - public void EditApp_Config_List() + public int GetRandomForm(int spec) { - PopFlat(GameFile.AppConfigList, "App Config List", z => z.OriginalPath); + var pt = Data.PersonalData; + var formRand = pt.Table.Cast() + .Where(z => z.IsPresentInGame && !(Legal.BattleExclusiveForms.Contains(z.ModelID) || Legal.BattleFusions.Contains(z.ModelID))) + .GroupBy(z => z.ModelID) + .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, + _ => Randomization.Util.Random.Next(0, count), + }; } - public void EditArea_Weather() + #region Dialog Editors + [EditorCallable(EditorCategory.Dialog)] + public void EditCommon() + { + var text = ROM.GetFilteredFolder(GameFile.GameText, z => Path.GetExtension(z) == ".dat"); + var config = new TextConfig(ROM.Game); + var tc = new TextContainer(text, config); + using var form = new TextEditor(tc, TextEditor.TextEditorMode.Common); + form.ShowDialog(); + if (!form.Modified) + text.CancelEdits(); + } + + [EditorCallable(EditorCategory.Dialog)] + public void EditScript() + { + var text = ROM.GetFilteredFolder(GameFile.StoryText, z => Path.GetExtension(z) == ".dat"); + var config = new TextConfig(ROM.Game); + var tc = new TextContainer(text, config); + using var form = new TextEditor(tc, TextEditor.TextEditorMode.Script); + form.ShowDialog(); + if (!form.Modified) + text.CancelEdits(); + } + #endregion + + #region Pokemon Editors + [EditorCallable(EditorCategory.Pokemon)] + public void EditPokemon() + { + var editor = new PokeEditor8a + { + Personal = Data.PersonalData, + PokeMisc = Data.PokeMiscData, + Evolve = Data.EvolutionData, + Learn = Data.LevelUpData, + FieldDropTables = Data.FieldDrops, + BattleDropTabels = Data.BattleDrops, + DexResearch = Data.DexResearch + }; + using var form = new PokeDataUI8a(editor, ROM, Data); + form.ShowDialog(); + if (!form.Modified) + editor.CancelEdits(); + else + editor.Save(); + } + + [EditorCallable(EditorCategory.Pokemon)] + public void EditMiscSpeciesInfo() + { + var names = ROM.GetStrings(TextName.SpeciesNames); + PopFlat(GameFile.PokeMisc, "Misc Species Info Editor", z => $"{names[z.Species]}{(z.Form == 0 ? "" : $"-{z.Form}")} ~ {z.Value}"); + } + + [EditorCallable(EditorCategory.Pokemon)] + public void EditSymbolBehave() + { + var names = ROM.GetStrings(TextName.SpeciesNames); + PopFlat(GameFile.SymbolBehave, "Symbol Behavior Editor", z => $"{names[z.Species]}{(z.Form != 0 ? $"-{z.Form}" : "")}"); + } + + [EditorCallable(EditorCategory.Pokemon)] + public void EditEvolutions() + { + var names = ROM.GetStrings(TextName.SpeciesNames); + PopFlat(GameFile.Evolutions, "Evolution Editor", + z => $"{names[z.Species]}{(z.Form != 0 ? $"-{z.Form}" : "")}"); + } + + [EditorCallable(EditorCategory.Pokemon)] + public void EditLearnsetRaw() + { + var names = ROM.GetStrings(TextName.SpeciesNames); + PopFlat(GameFile.Learnsets, "Learnset Editor (Raw)", z => $"{names[z.Species]}{(z.Form == 0 ? "" : $"-{z.Form}")}"); + } + + [EditorCallable(EditorCategory.Pokemon)] + public void EditPersonalRaw() + { + var names = ROM.GetStrings(TextName.SpeciesNames); + PopFlat(GameFile.PersonalStats, "Personal Info Editor (Raw)", z => $"{names[z.Species]}{(z.Form == 0 ? "" : $"-{z.Form}")}"); + } + #endregion + + #region Field Editors + [EditorCallable(EditorCategory.Field)] + public void EditAreaWeather() { var gfp = (GFPack)ROM.GetFile(GameFile.Resident); var data = gfp[2065]; @@ -189,7 +205,8 @@ public void EditArea_Weather() gfp[2065] = FlatBufferConverter.SerializeFrom(obj); } - public void EditStatic() + [EditorCallable(EditorCategory.Field)] + public void EditStaticEncounter() { var names = ROM.GetStrings(TextName.SpeciesNames); var obj = ROM.GetFile(GameFile.EncounterStatic); @@ -241,6 +258,204 @@ void Randomize(IEnumerable arr) } } + [EditorCallable(EditorCategory.Field)] + public void EditMapViewer() + { + var resident = (GFPack)ROM.GetFile(GameFile.Resident); + using var form = new MapViewer8a((GameManagerPLA)ROM, resident); + form.ShowDialog(); + } + + [EditorCallable(EditorCategory.Field)] + public void EditAreas() + { + using var form = new AreaEditor8a((GameManagerPLA)ROM); + form.ShowDialog(); + } + + [EditorCallable(EditorCategory.Field)] + 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.WorkValueName); + + [EditorCallable(EditorCategory.Field)] + public void EditNewOutbreakGroup() + => PopFlat(GameFile.NewHugeGroup, "New Outbreak Group Editor", z => z.Group.ToString("X16")); + + [EditorCallable(EditorCategory.Field)] + public void EditNewOutbreakGroupLottery() + => PopFlat(GameFile.NewHugeGroupLottery, "New Outbreak Group Lottery Editor", z => z.LotteryGroup.ToString("X16")); + + [EditorCallable(EditorCategory.Field)] + public void EditNewOutbreakLottery() + => PopFlat(GameFile.NewHugeLottery, "New Outbreak Lottery Editor", z => z.LotteryGroupString); + + [EditorCallable(EditorCategory.Field)] + public void EditNewOutbreakTimeLimit() + => PopFlat(GameFile.NewHugeTimeLimit, "New Outbreak Time Limit Editor", z => z.Duration.ToString()); + + [EditorCallable(EditorCategory.Field)] + public void EditFieldAttackConfig() => PopFlatConfig(GameFile.AIFieldWazaConfig, "AI Field Attack Config Editor"); + + #endregion + + #region Battle Editors + [EditorCallable(EditorCategory.Battle)] + public void EditTrainers() + { + var folder = ROM.GetFilteredFolder(GameFile.TrainerData); + var cache = new DataCache(folder) + { + Create = FlatBufferConverter.DeserializeFrom, + Write = FlatBufferConverter.SerializeFrom, + }; + var names = folder.GetPaths().Select(Path.GetFileNameWithoutExtension).ToArray(); + using var form = new GenericEditor(cache, names, "Trainers", Randomize, canSave: true); + form.ShowDialog(); + + void Randomize() + { + var settings = EditUtil.Settings.Species; + var rand = new SpeciesRandomizer(ROM.Info, Data.PersonalData); + rand.Initialize(settings, GetSpeciesBanlist()); + + for (int i = 0; i < cache.Length; i++) + { + foreach (var t in cache[i].Team) + { + t.Species = rand.GetRandomSpecies(t.Species); + t.Form = GetRandomForm(t.Species); + t.Gender = (int)FixedGender.Random; + t.Nature = NatureType8a.Random; + t.Move_01.Move = t.Move_02.Move = t.Move_03.Move = t.Move_04.Move = 0; + t.Move_01.Mastered = t.Move_02.Mastered = t.Move_03.Mastered = t.Move_04.Mastered = true; + t.Shiny = Randomization.Util.Random.Next(0, 100 + 1) < 3; + t.IsOybn = Randomization.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, + }; + using var form = new GenericEditor(cache, ROM.GetStrings(TextName.MoveNames), "Move Editor"); + form.ShowDialog(); + if (!form.Modified) + { + cache.CancelEdits(); + return; + } + + cache.Save(); + Data.MoveData.ClearAll(); // force reload if used again + } + + #endregion + + #region Shop Editors + [EditorCallable(EditorCategory.Shops)] + public void EditMoveShop() + { + var names = ROM.GetStrings(TextName.MoveNames); + var data = ROM.GetFile(GameFile.MoveShop); + var obj = FlatBufferConverter.DeserializeFrom(data[0]); + var result = PopFlat(obj.Table, "Move Shop Editor", z => names[z.Move]); + if (!result) + return; + data[0] = FlatBufferConverter.SerializeFrom(obj); + } + + [EditorCallable(EditorCategory.Shops)] + public void EditHaShopData() + { + var names = ROM.GetStrings(TextName.ItemNames); + var data = ROM.GetFile(GameFile.HaShop); + var obj = FlatBufferConverter.DeserializeFrom(data[0]); + var result = PopFlat(obj.Table, "ha_shop_data Editor", z => names[z.ItemID], Randomize); + if (!result) + return; + + void Randomize() + { + foreach (var t in obj.Table) + { + if (Legal.Pouch_Recipe_LA.Contains((ushort)t.ItemID)) // preserve recipes + continue; + t.ItemID = Legal.Pouch_Items_LA[Randomization.Util.Random.Next(Legal.Pouch_Items_LA.Length)]; + } + } + + data[0] = FlatBufferConverter.SerializeFrom(obj); + } + + #endregion + + #region Graphics Editors + [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"); + + #endregion + + #region Other Editors + [EditorCallable] + public void EditThrowParam() + { + PopFlat(GameFile.ThrowParam, "Throw Param Editor", z => z.Hash.ToString("X16")); + } + + [EditorCallable] + public void EditThrowPermissionSetParam() + { + PopFlat(GameFile.ThrowPermissionSet, "Throw Permission Editor", z => z.Hash_00.ToString("X16")); + } + + [EditorCallable] + public void EditThrowableParam() + { + var itemNames = ROM.GetStrings(TextName.ItemNames); + PopFlat(GameFile.ThrowableParam, "Throwable Param Editor", z => itemNames[z.ItemID]); + } + [EditorCallable] + public void EditThrowResourceDictionary() + { + PopFlat(GameFile.ThrowableResource, "Throwable Resource Dictionary Editor", z => z.Hash_00.ToString("X16")); + } + [EditorCallable] + public void EditThrowResourceSetDictionary() + { + PopFlat(GameFile.ThrowableResourceSet, "Throwable Resource Set Dictionary Editor", z => z.Hash_00.ToString("X16")); + } + + [EditorCallable] + public void EditAppConfigList() + { + PopFlat(GameFile.AppConfigList, "App Config List", z => z.OriginalPath); + } + + [EditorCallable] public void EditGift() { var names = ROM.GetStrings(TextName.SpeciesNames); @@ -272,98 +487,7 @@ void Randomize(IEnumerable arr) } } - 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.ModelID); - hasForm.Add(pi.ModelID); - } - else if (!hasForm.Contains(pi.ModelID)) - { - banned.Add(pi.ModelID); - } - } - return banned.ToArray(); - } - - public int GetRandomForm(int spec) - { - var pt = Data.PersonalData; - var formRand = pt.Table.Cast() - .Where(z => z.IsPresentInGame && !(Legal.BattleExclusiveForms.Contains(z.ModelID) || Legal.BattleFusions.Contains(z.ModelID))) - .GroupBy(z => z.ModelID) - .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, - _ => Randomization.Util.Random.Next(0, count), - }; - } - - public void EditPersonal_Raw() - { - var names = ROM.GetStrings(TextName.SpeciesNames); - PopFlat(GameFile.PersonalStats, "Personal Info Editor (Raw)", z => $"{names[z.Species]}{(z.Form == 0 ? "" : $"-{z.Form}")}"); - } - - public void EditLearnset_Raw() - { - var names = ROM.GetStrings(TextName.SpeciesNames); - PopFlat(GameFile.Learnsets, "Learnset Editor (Raw)", z => $"{names[z.Species]}{(z.Form == 0 ? "" : $"-{z.Form}")}"); - } - - public void EditMiscSpeciesInfo() - { - var names = ROM.GetStrings(TextName.SpeciesNames); - PopFlat(GameFile.PokeMisc, "Misc Species Info Editor", z => $"{names[z.Species]}{(z.Form == 0 ? "" : $"-{z.Form}")} ~ {z.Value}"); - } - - public void EditMap_Viewer() - { - var resident = (GFPack)ROM.GetFile(GameFile.Resident); - using var form = new MapViewer8a(ROM, resident); - form.ShowDialog(); - } - - public void EditAreas() - { - using var form = new AreaEditor8a(ROM); - form.ShowDialog(); - } - - public void EditMoves() - { - var obj = ROM[GameFile.MoveStats]; // folder - var cache = new DataCache(obj) - { - Create = FlatBufferConverter.DeserializeFrom, - Write = FlatBufferConverter.SerializeFrom, - }; - using var form = new GenericEditor(cache, ROM.GetStrings(TextName.MoveNames), "Move Editor"); - form.ShowDialog(); - if (!form.Modified) - { - cache.CancelEdits(); - return; - } - - cache.Save(); - Data.MoveData.ClearAll(); // force reload if used again - } - + [EditorCallable] public void EditItems() { var obj = ROM[GameFile.ItemStats]; // mini @@ -381,86 +505,115 @@ public void EditItems() obj[0] = Item8a.SetArray(items, data); } - public void EditPokemon() - { - var editor = new PokeEditor8a - { - Personal = Data.PersonalData, - PokeMisc = Data.PokeMiscData, - Evolve = Data.EvolutionData, - Learn = Data.LevelUpData, - FieldDropTables = Data.FieldDrops, - BattleDropTabels = Data.BattleDrops, - DexResearch = Data.DexResearch, - }; - using var form = new PokeDataUI8a(editor, ROM, Data); - form.ShowDialog(); - if (!form.Modified) - editor.CancelEdits(); - else - editor.Save(); - } + [EditorCallable] public void EditAICommonConfig() => PopFlatConfig(GameFile.AICommonConfig, "AI Common Config Editor"); + [EditorCallable] public void EditAIExcitingConfig() => PopFlatConfig(GameFile.AIExcitingConfig, "AI Exciting Config Editor"); - public void PopFlatConfig(GameFile file, string title) - { - var obj = ROM.GetFile(file); // flatbuffer - var data = obj[0]; - var root = FlatBufferConverter.DeserializeFrom(data); - var cache = new DataCache(root.Table); - var names = root.Table.Select(z => z.Name).ToArray(); - using var form = new GenericEditor(cache, names, title); - form.ShowDialog(); - if (!form.Modified) - return; - obj[0] = FlatBufferConverter.SerializeFrom(root); - } + [EditorCallable] public void EditAISemiLegendConfig() => PopFlatConfig(GameFile.AISemiLegendConfig, "AI Semi Legend Config Editor"); + [EditorCallable] public void EditAITirednessConfig() => PopFlatConfig(GameFile.AITirednessConfig, "AI Tiredness Config Editor"); + [EditorCallable] public void EditAppliHudConfig() => PopFlatConfig(GameFile.AppliHudConfig, "Appli Hud Config Editor"); + [EditorCallable] public void EditAppliStaffrollConfig() => PopFlatConfig(GameFile.AppliStaffrollConfig, "Appli Staffroll Config Editor"); + [EditorCallable] public void EditAppliTipsConfig() => PopFlatConfig(GameFile.AppliTipsConfig, "Appli Tips Config Editor"); + [EditorCallable] public void EditBattleCommonConfig() => PopFlatConfig(GameFile.BattleCommonConfig, "Battle Common Config Editor"); + [EditorCallable] public void EditBattleEndConfig() => PopFlatConfig(GameFile.BattleEndConfig, "Battle End Config Editor"); + [EditorCallable] public void EditBattleInConfig() => PopFlatConfig(GameFile.BattleInConfig, "Battle In Config Editor"); + [EditorCallable] public void EditBattleLogicConfig() => PopFlatConfig(GameFile.BattleLogicConfig, "Battle Logic Config Editor"); + [EditorCallable] public void EditBattleStartConfig() => PopFlatConfig(GameFile.BattleStartConfig, "Battle Start Config Editor"); + [EditorCallable] public void EditBattleViewConfig() => PopFlatConfig(GameFile.BattleViewConfig, "Battle View Config Editor"); + [EditorCallable] public void EditBattleVsnsConfig() => PopFlatConfig(GameFile.BattleVsnsConfig, "Battle Vsns Config Editor"); + [EditorCallable] public void EditBuddyBattleConfig() => PopFlatConfig(GameFile.BuddyBattleConfig, "Buddy Battle Config Editor"); + [EditorCallable] public void EditBuddyConfig() => PopFlatConfig(GameFile.BuddyConfig, "Buddy Config Editor"); + [EditorCallable] public void EditBuddyDirectItemConfig() => PopFlatConfig(GameFile.BuddyDirectItemConfig, "Buddy Direct Item Config Editor"); + [EditorCallable] public void EditBuddyGroupTalkConfig() => PopFlatConfig(GameFile.BuddyGroupTalkConfig, "Buddy Group Talk Config Editor"); + [EditorCallable] public void EditBuddyLandmarkConfig() => PopFlatConfig(GameFile.BuddyLandmarkConfig, "Buddy Landmark Config Editor"); + [EditorCallable] public void EditBuddyNPCReactionConfig() => PopFlatConfig(GameFile.BuddyNPCReactionConfig, "Buddy NPC Reaction Config Editor"); + [EditorCallable] public void EditBuddyPlayerModeConfig() => PopFlatConfig(GameFile.BuddyPlayerModeConfig, "Buddy Player Mode Config Editor"); + [EditorCallable] public void EditBuddyWarpConfig() => PopFlatConfig(GameFile.BuddyWarpConfig, "Buddy Warp Config Editor"); + [EditorCallable] public void EditCharacterBipedIkConfig() => PopFlatConfig(GameFile.CharacterBipedIkConfig, "Character Biped Ik Config Editor"); + [EditorCallable] public void EditCharacterBlinkConfig() => PopFlatConfig(GameFile.CharacterBlinkConfig, "Character Blink Config Editor"); + [EditorCallable] public void EditCharacterControllerConfig() => PopFlatConfig(GameFile.CharacterControllerConfig, "Character Controller Config Editor"); + [EditorCallable] public void EditCharacterLookAtConfig() => PopFlatConfig(GameFile.CharacterLookAtConfig, "Character Look At Config Editor"); + [EditorCallable] public void EditCaptureConfig() => PopFlatConfig(GameFile.CaptureConfig, "Capture Config Editor"); + [EditorCallable] public void EditCommonGeneralConfig() => PopFlatConfig(GameFile.CommonGeneralConfig, "Common General Config Editor"); + [EditorCallable] public void EditCommonItemConfig() => PopFlatConfig(GameFile.CommonItemConfig, "Common Item Config Editor"); + [EditorCallable] public void EditDemoConfig() => PopFlatConfig(GameFile.DemoConfig, "Demo Config Editor"); + [EditorCallable] public void EditEnvPokeVoiceConfig() => PopFlatConfig(GameFile.EnvPokeVoiceConfig, "Env Poke Voice Config Editor"); + [EditorCallable] public void EditEventBalloonrunConfig() => PopFlatConfig(GameFile.EventBalloonrunConfig, "Event Balloonrun Config Editor"); + [EditorCallable] public void EditEventBalloonthrowConfig() => PopFlatConfig(GameFile.EventBalloonthrowConfig, "Event Balloonthrow Config Editor"); + [EditorCallable] public void EditEventBanditConfig() => PopFlatConfig(GameFile.EventBanditConfig, "Event Bandit Config Editor"); + [EditorCallable] public void EditEventCullingConfig() => PopFlatConfig(GameFile.EventCullingConfig, "Event Culling Config Editor"); + [EditorCallable] public void EditEventDitherConfig() => PopFlatConfig(GameFile.EventDitherConfig, "Event Dither Config Editor"); + [EditorCallable] public void EditEventFarmConfig() => PopFlatConfig(GameFile.EventFarmConfig, "Farm Config Editor"); + [EditorCallable] public void EditEventGameOverConfig() => PopFlatConfig(GameFile.EventGameOverConfig, "Event Game Over Config Editor"); + [EditorCallable] public void EditEventItemConfig() => PopFlatConfig(GameFile.EventItemConfig, "Event Item Config Editor"); + [EditorCallable] public void EditEventMkrgRewardConfig() => PopFlatConfig(GameFile.EventMkrgRewardConfig, "Event Mkrg Reward Config Editor"); + [EditorCallable] public void EditEventQuestBoardConfig() => PopFlatConfig(GameFile.EventQuestBoardConfig, "Event Quest Board Config Editor"); + [EditorCallable] public void EditEventRestrictionBattle() => PopFlatConfig(GameFile.EventRestrictionBattle, "Event Restriction Battle Editor"); + [EditorCallable] public void EditEventWork() => PopFlatConfig(GameFile.EventWork, "Event Work Editor"); - public void EditShinyRate() => PopFlatConfig(GameFile.ShinyRolls, "Shiny Rate Editor"); - public void EditWormholeRate() => PopFlatConfig(GameFile.WormholeConfig, "Wormhole Config Editor"); - public void EditCapture_Config() => PopFlatConfig(GameFile.CaptureConfig, "CaptureConfig Editor"); - public void EditBattle_Logic_Config() => PopFlatConfig(GameFile.BattleLogicConfig, "Battle Logic Config Editor"); - public void EditEvent_Farm_Config() => PopFlatConfig(GameFile.EventFarmConfig, "Event Farm Config Editor"); - public void EditPlayer_Config() => PopFlatConfig(GameFile.PlayerConfig, "Player Config Editor"); - public void EditField_Landmark_Config() => PopFlatConfig(GameFile.FieldLandmarkConfig, "Field Landmark Config Editor"); - public void EditBattle_View_Config() => PopFlatConfig(GameFile.BattleViewConfig, "Battle View Config Editor"); - public void EditAICommon_Config() => PopFlatConfig(GameFile.AICommonConfig, "AI Common Config Editor"); - public void EdiField_Spawner_Config() => PopFlatConfig(GameFile.FieldSpawnerConfig, "Field Spawner Config Editor"); - public void EditOutbreak_Config() => PopFlatConfig(GameFile.OutbreakConfig, "Outbreak Config Editor"); - public void EditEvolution_Config() => PopFlatConfig(GameFile.EvolutionConfig, "Evolution Config Editor"); - public void EditBall_Throw_Config() => PopFlatConfig(GameFile.BallThrowConfig, "Ball Throw Config Editor"); - public void EditSize_Scale_Config() => PopFlatConfig(GameFile.SizeScaleConfig, "Size Scale Config Editor"); + [EditorCallable] public void EditNPCAIConfig() => PopFlatConfig(GameFile.NPCAIConfig, "NPC AI Config"); + [EditorCallable] public void EditNPCControllerConfig() => PopFlatConfig(GameFile.NPCControllerConfig, "NPC Controller Config"); + [EditorCallable] public void EditNPCCreaterConfig() => PopFlatConfig(GameFile.NPCCreaterConfig, "NPC Creater Config"); + [EditorCallable] public void EditNPCPokemonAIConfig() => PopFlatConfig(GameFile.NPCPokemonAIConfig, "NPC Pokemon AI Config"); + [EditorCallable] public void EditNPCPopupConfig() => PopFlatConfig(GameFile.NPCPopupConfig, "NPC Popup Config"); + [EditorCallable] public void EditNPCTalkTableConfig() => PopFlatConfig(GameFile.NPCTalkTableConfig, "NPC Talk Table Config"); + [EditorCallable] public void EditPlayerCameraShakeConfig() => PopFlatConfig(GameFile.PlayerCameraShakeConfig, "Player Camera Shake Config"); + [EditorCallable] public void EditPlayerCollisionConfig() => PopFlatConfig(GameFile.PlayerCollisionConfig, "Player Collision Config"); + [EditorCallable] public void EditPlayerConfig() => PopFlatConfig(GameFile.PlayerConfig, "Player Config Editor"); + [EditorCallable] public void EditPlayerControllerConfig() => PopFlatConfig(GameFile.PlayerControllerConfig, "Player Controller Config"); + [EditorCallable] public void EditPlayerFaceConfig() => PopFlatConfig(GameFile.PlayerFaceConfig, "Player Face Config"); + [EditorCallable] public void EditPokemonConfig() => PopFlatConfig(GameFile.PokemonConfig, "Pokemon Config"); + [EditorCallable] public void EditPokemonControllerConfig() => PopFlatConfig(GameFile.PokemonControllerConfig, "Pokemon Controller Config"); + [EditorCallable] public void EditPokemonFriendshipConfig() => PopFlatConfig(GameFile.PokemonFriendshipConfig, "Pokemon Friendship Config"); - public void EditEvolutions() - { - var names = ROM.GetStrings(TextName.SpeciesNames); - PopFlat(GameFile.Evolutions, "Evolution Editor", - z => $"{names[z.Species]}{(z.Form != 0 ? $"-{z.Form}" : "")}"); - } + [EditorCallable] public void EditSizeScaleConfig() => PopFlatConfig(GameFile.SizeScaleConfig, "Size Scale Config"); + [EditorCallable] public void EditRideBasuraoCollisionConfig() => PopFlatConfig(GameFile.RideBasuraoCollisionConfig, "Ride Basurao Collision Config"); + [EditorCallable] public void EditRideBasuraoConfig() => PopFlatConfig(GameFile.RideBasuraoConfig, "Ride Basurao Config"); + [EditorCallable] public void EditRideChangeConfig() => PopFlatConfig(GameFile.RideChangeConfig, "Ride Change Config"); + [EditorCallable] public void EditRideCommonConfig() => PopFlatConfig(GameFile.RideCommonConfig, "Ride Common Config"); + [EditorCallable] public void EditRideNyuuraCollisionConfig() => PopFlatConfig(GameFile.RideNyuuraCollisionConfig, "Ride Nyuura Collision Config"); + [EditorCallable] public void EditRideNyuuraConfig() => PopFlatConfig(GameFile.RideNyuuraConfig, "Ride Nyuura Config"); + [EditorCallable] public void EditRideNyuuraControllerConfig() => PopFlatConfig(GameFile.RideNyuuraControllerConfig, "Ride Nyuura Controller Config"); + [EditorCallable] public void EditRideOdoshishiCollisionConfig() => PopFlatConfig(GameFile.RideOdoshishiCollisionConfig, "Ride Odoshishi Collision Config"); + [EditorCallable] public void EditRideOdoshishiConfig() => PopFlatConfig(GameFile.RideOdoshishiConfig, "Ride Odoshishi Config"); + [EditorCallable] public void EditRideRingumaCollisionConfig() => PopFlatConfig(GameFile.RideRingumaCollisionConfig, "Ride Ringuma Collision Config"); + [EditorCallable] public void EditRideRingumaConfig() => PopFlatConfig(GameFile.RideRingumaConfig, "Ride Ringuma Config"); + [EditorCallable] public void EditRideRingumaControllerConfig() => PopFlatConfig(GameFile.RideRingumaControllerConfig, "Ride Ringuma Controller Config"); + [EditorCallable] public void EditRideWhooguruCollisionConfig() => PopFlatConfig(GameFile.RideWhooguruCollisionConfig, "Ride Whooguru Collision Config"); + [EditorCallable] public void EditRideWhooguruConfig() => PopFlatConfig(GameFile.RideWhooguruConfig, "Ride Whooguru Config"); + [EditorCallable] public void EditRideWhooguruControllerConfig() => PopFlatConfig(GameFile.RideWhooguruControllerConfig, "Ride Whooguru Controller Config"); + [EditorCallable] public void EditSoundConfig() => PopFlatConfig(GameFile.SoundConfig, "Sound Config"); - public void EditOutbreakDetail() - => PopFlat(GameFile.Outbreak, "Outbreak Proc Editor", z => z.WorkValueName); + [EditorCallable] public void EditFieldAreaSpeed() => PopFlatConfig(GameFile.FieldAreaSpeedConfig, "Field Area Speed Config"); + [EditorCallable] public void EditFieldCameraConfig() => PopFlatConfig(GameFile.FieldCameraConfig, "Field Camera Config"); + [EditorCallable] public void EditFieldCaptureDirectorConfig() => PopFlatConfig(GameFile.FieldCaptureDirectorConfig, "Field Capture Director Config"); + [EditorCallable] public void EditFieldCharaViewerConfig() => PopFlatConfig(GameFile.FieldCharaViewerConfig, "Field Chara Viewer Config"); + [EditorCallable] public void EditFieldCommonConfig() => PopFlatConfig(GameFile.FieldCommonConfig, "Field Common Config"); + [EditorCallable] public void EditFieldDirectItemConfig() => PopFlatConfig(GameFile.FieldDirectItemConfig, "Field Direct Item Config"); + [EditorCallable] public void EditFieldEnvConfig() => PopFlatConfig(GameFile.FieldEnvConfig, "Field Env Config"); + [EditorCallable] public void EditFieldItem() => PopFlatConfig(GameFile.FieldItem, "Field Item"); + [EditorCallable] public void EditFieldItemRespawn() => PopFlatConfig(GameFile.FieldItemRespawn, "Field Item Respawn"); + [EditorCallable] public void EditFieldLandmarkInciteConfig() => PopFlatConfig(GameFile.FieldLandmarkInciteConfig, "Field Landmark Incite Config"); + [EditorCallable] public void EditFieldLockonConfig() => PopFlatConfig(GameFile.FieldLockonConfig, "Field Lockon Config"); + [EditorCallable] public void EditFieldMyPokeBallHitNoneTargetConfig() => PopFlatConfig(GameFile.FieldMyPokeBallHitNoneTargetConfig, "Field My Poke Ball Hit None Target Config"); + [EditorCallable] public void EditFieldObstructionWazaConfig() => PopFlatConfig(GameFile.FieldObstructionWazaConfig, "Field Obstruction Waza Config"); + [EditorCallable] public void EditFieldPokemonSlopeConfig() => PopFlatConfig(GameFile.FieldPokemonSlopeConfig, "Field Pokemon Slope Config"); + [EditorCallable] public void EditFieldQuestDestinationConfig() => PopFlatConfig(GameFile.FieldQuestDestinationConfig, "Field Quest Destination Config"); + [EditorCallable] public void EditFieldShadowConfig() => PopFlatConfig(GameFile.FieldShadowConfig, "Field Shadow Config"); + [EditorCallable] public void EditFieldThrowConfig() => PopFlatConfig(GameFile.FieldThrowConfig, "Field Throw Config"); + [EditorCallable] public void EditFieldThrowableAfterHitConfig() => PopFlatConfig(GameFile.FieldThrowableAfterHitConfig, "Field Throwable After Hit Config"); + [EditorCallable] public void EditFieldVigilanceBgmConfig() => PopFlatConfig(GameFile.FieldVigilanceBgmConfig, "Field Vigilance Bgm Config"); + [EditorCallable] public void EditFieldWeatheringConfig() => PopFlatConfig(GameFile.FieldWeatheringConfig, "Field Weathering Config"); + [EditorCallable] public void EditFieldWildPokemonConfig() => PopFlatConfig(GameFile.FieldWildPokemonConfig, "Field Wild Pokemon Config"); - public void EditNewOutbreak_Group() - => PopFlat(GameFile.NewHugeGroup, "New Outbreak Group Editor", z => z.Group.ToString("X16")); - - public void EditNewOutbreak_GroupLottery() - => PopFlat(GameFile.NewHugeGroupLottery, "New Outbreak Group Lottery Editor", z => z.LotteryGroup.ToString("X16")); - - public void EditNewOutbreak_Lottery() - => PopFlat(GameFile.NewHugeLottery, "New Outbreak Lottery Editor", z => z.LotteryGroupString); - - public void EditNewOutbreak_TimeLimit() - => PopFlat(GameFile.NewHugeTimeLimit, "New Outbreak Time Limit Editor", z => z.Duration.ToString()); - - public void EditSymbolBehave() - { - var names = ROM.GetStrings(TextName.SpeciesNames); - PopFlat(GameFile.SymbolBehave, "Symbol Behavior Editor", z => $"{names[z.Species]}{(z.Form != 0 ? $"-{z.Form}" : "")}"); - } + [EditorCallable] public void EditFieldLandmarkConfig() => PopFlatConfig(GameFile.FieldLandmarkConfig, "Field Landmark Config Editor"); + [EditorCallable] public void EditField_Spawner_Config() => PopFlatConfig(GameFile.FieldSpawnerConfig, "Field Spawner Config Editor"); + [EditorCallable] public void EditEvolutionConfig() => PopFlatConfig(GameFile.EvolutionConfig, "Evolution Config Editor"); + [EditorCallable] public void EditBallThrowConfig() => PopFlatConfig(GameFile.BallThrowConfig, "Ball Throw Config Editor"); public void EditMasterDump() { using var md = new DumperPLA(ROM); md.ShowDialog(); } + #endregion } diff --git a/pkNX.WinForms/MainEditor/EditorProvider.cs b/pkNX.WinForms/MainEditor/EditorProvider.cs index ce12609d..6b3be9bd 100644 --- a/pkNX.WinForms/MainEditor/EditorProvider.cs +++ b/pkNX.WinForms/MainEditor/EditorProvider.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Reflection; using System.Windows.Forms; using pkNX.Game; @@ -15,25 +16,44 @@ public abstract class EditorBase public int Language { get => ROM.Language; set => ROM.Language = value; } public string? Location { get; private set; } + private const string prefix = "Edit"; + private MethodInfo[] editorMethods = Array.Empty(); + private EditorCallableAttribute[] editorAttributes = Array.Empty(); + + protected EditorBase() + { + // Collect all methods that are marked as editors + // The method name needs to start with `Edit` or an EditorCallableAttribute should be added + var editors = GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance) + .Select(x => new { Method = x, Callable = x.GetCustomAttribute() }) + .Where(x => x.Callable != null || x.Method.Name.StartsWith(prefix)); + + editorMethods = editors.Select(x => x.Method).ToArray(); + editorAttributes = editors.Select(x => x.Callable ?? new EditorCallableAttribute(EditorCategory.None)).ToArray(); + } + public void Initialize() => ROM.Initialize(); - public IEnumerable