From 58da1023c14c881ceea2b5a8779463ab054616bc Mon Sep 17 00:00:00 2001 From: chardub Date: Sat, 19 Apr 2025 15:43:57 -0400 Subject: [PATCH] Remove Scripts folder to convert to submodule --- Data/Scripts/001_Settings.rb | 640 --- .../001_Debugging/001_PBDebug.rb | 40 - .../001_Debugging/002_DebugConsole.rb | 54 - .../001_Technical/001_Debugging/003_Errors.rb | 93 - .../001_Debugging/004_Validation.rb | 31 - .../001_Debugging/005_Deprecation.rb | 53 - .../001_Technical/001_MKXP_Compatibility.rb | 39 - .../001_Technical/002_Files/001_FileTests.rb | 492 --- .../001_Technical/002_Files/002_FileMixins.rb | 150 - .../002_Files/003_HTTP_Utilities.rb | 150 - .../001_Technical/002_RubyUtilities.rb | 142 - .../001_Technical/003_Intl_Messages.rb | 789 ---- Data/Scripts/001_Technical/004_Input.rb | 33 - .../001_Technical/005_PluginManager.rb | 712 ---- Data/Scripts/001_Technical/006_RPG_Sprite.rb | 534 --- Data/Scripts/002_BattleSettings.rb | 78 - Data/Scripts/002_Save data/001_SaveData.rb | 96 - .../002_Save data/002_SaveData_Value.rb | 269 -- .../002_Save data/003_SaveData_Conversion.rb | 221 - .../002_Save data/004_Game_SaveValues.rb | 135 - .../002_Save data/005_Game_SaveConversions.rb | 242 -- .../003_Game processing/001_StartGame.rb | 259 -- .../003_Game processing/002_Scene_Map.rb | 292 -- .../003_Game processing/003_Interpreter.rb | 457 -- .../004_Interpreter_Commands.rb | 1027 ----- .../003_Game processing/005_Event_Handlers.rb | 275 -- .../006_Event_OverworldEvents.rb | 172 - .../004_Game classes/001_Game_Screen.rb | 154 - .../001_Game_Temp.rb | 68 - .../002_Game_Switches.rb | 31 - .../003_Game_Variables.rb | 30 - .../004_Game_SelfSwitches.rb | 29 - .../004_Game classes/002_Game_System.rb | 286 -- .../004_Game classes/003_Game_Picture.rb | 156 - Data/Scripts/004_Game classes/004_Game_Map.rb | 547 --- .../005_Game_Map_Autoscroll.rb | 194 - .../004_Game classes/006_Game_MapFactory.rb | 526 --- .../004_Game classes/007_Game_Character.rb | 1176 ------ .../004_Game classes/008_Game_Event.rb | 279 -- .../004_Game classes/009_Game_Player.rb | 447 -- .../010_Game_Player_Visuals.rb | 126 - .../004_Game classes/011_Game_CommonEvent.rb | 82 - .../012_Game_DependentEvents.rb | 588 --- .../005_Map renderer/001_Tilemap_XP.rb | 921 ---- .../Scripts/005_Sprites/001_Sprite_Picture.rb | 58 - Data/Scripts/005_Sprites/002_Sprite_Timer.rb | 45 - .../005_Sprites/003_Sprite_Character.rb | 264 -- .../005_Sprites/004_Sprite_Reflection.rb | 87 - .../005_Sprites/005_Sprite_SurfBase.rb | 150 - .../005_Sprites/006_Spriteset_Global.rb | 30 - Data/Scripts/005_Sprites/007_Spriteset_Map.rb | 168 - .../005_Sprites/008_Sprite_AnimationSprite.rb | 84 - .../005_Sprites/009_Sprite_DynamicShadows.rb | 253 -- .../Scripts/005_Sprites/010_ParticleEngine.rb | 586 --- Data/Scripts/005_Sprites/011_PictureEx.rb | 519 --- Data/Scripts/005_Sprites/012_Interpolators.rb | 172 - .../005_Sprites/013_ScreenPosHelper.rb | 43 - .../005_Sprites/013_Sprite_Player_Offsets.rb | 35 - .../005_Sprites/013_Sprite_Wearable.rb | 170 - Data/Scripts/005_Sprites/014_Sprite_Hair.rb | 85 - Data/Scripts/005_Sprites/014_Sprite_Hat.rb | 8 - Data/Scripts/005_Sprites/016_Sprite_Player.rb | 116 - .../006_Map renderer/001_TilemapRenderer.rb | 670 --- .../006_Map renderer/002_TilesetWrapper.rb | 97 - .../006_Map renderer/003_AutotileExpander.rb | 75 - .../006_Map renderer/004_TileDrawingHelper.rb | 246 -- .../007_Objects and windows/001_RPG_Cache.rb | 167 - .../002_MessageConfig.rb | 818 ---- .../007_Objects and windows/003_Window.rb | 604 --- .../004_SpriteWindow.rb | 936 ----- .../005_SpriteWindow_text.rb | 1401 ------- .../006_SpriteWindow_pictures.rb | 123 - .../007_SpriteWrapper.rb | 496 --- .../008_AnimatedBitmap.rb | 360 -- .../007_Objects and windows/009_Planes.rb | 230 - .../007_Objects and windows/010_DrawText.rb | 1277 ------ .../007_Objects and windows/011_Messages.rb | 1057 ----- .../007_Objects and windows/012_TextEntry.rb | 564 --- Data/Scripts/008_Audio/001_Audio.rb | 171 - Data/Scripts/008_Audio/002_Audio_Play.rb | 293 -- Data/Scripts/009_Scenes/001_Transitions.rb | 1627 ------- Data/Scripts/009_Scenes/002_EventScene.rb | 198 - Data/Scripts/010_Data/001_GameData.rb | 273 -- .../001_Hardcoded data/001_GrowthRate.rb | 190 - .../001_Hardcoded data/002_GenderRatio.rb | 77 - .../001_Hardcoded data/003_EggGroup.rb | 102 - .../001_Hardcoded data/004_BodyShape.rb | 117 - .../001_Hardcoded data/005_BodyColor.rb | 90 - .../001_Hardcoded data/006_Habitat.rb | 76 - .../001_Hardcoded data/007_Evolution.rb | 599 --- .../010_Data/001_Hardcoded data/008_Stat.rb | 131 - .../010_Data/001_Hardcoded data/009_Nature.rb | 200 - .../010_Data/001_Hardcoded data/010_Status.rb | 79 - .../001_Hardcoded data/011_TerrainTag.rb | 289 -- .../001_Hardcoded data/012_Weather.rb | 173 - .../001_Hardcoded data/013_EncounterType.rb | 219 - .../001_Hardcoded data/014_Environment.rb | 131 - .../001_Hardcoded data/015_BattleWeather.rb | 81 - .../001_Hardcoded data/016_BattleTerrain.rb | 58 - .../010_Data/001_Hardcoded data/017_Target.rb | 194 - .../010_Data/002_PBS data/001_MiscPBSData.rb | 107 - .../002_PBS data/002_PhoneDatabase.rb | 31 - .../Scripts/010_Data/002_PBS data/003_Type.rb | 132 - .../010_Data/002_PBS data/004_Ability.rb | 31 - .../Scripts/010_Data/002_PBS data/005_Move.rb | 85 - .../Scripts/010_Data/002_PBS data/006_Item.rb | 324 -- .../010_Data/002_PBS data/007_BerryPlant.rb | 36 - .../010_Data/002_PBS data/008_Species.rb | 444 -- .../002_PBS data/009_Species_Files.rb | 388 -- .../010_Data/002_PBS data/010_Ribbon.rb | 31 - .../010_Data/002_PBS data/011_Encounter.rb | 78 - .../002_PBS data/011_EncounterModern.rb | 77 - .../002_PBS data/011_Encounter_random.rb | 77 - .../010_Data/002_PBS data/012_TrainerType.rb | 157 - .../010_Data/002_PBS data/013_Trainer.rb | 387 -- .../002_PBS data/013_TrainerExpert.rb | 14 - .../002_PBS data/013_TrainerModern.rb | 369 -- .../010_Data/002_PBS data/014_Metadata.rb | 147 - .../010_Data/002_PBS data/015_MapMetadata.rb | 129 - .../001_Battler/001_PokeBattle_Battler.rb | 801 ---- .../001_Battler/002_Battler_Initialize.rb | 330 -- .../001_Battler/003_Battler_ChangeSelf.rb | 312 -- .../001_Battler/004_Battler_Statuses.rb | 576 --- .../001_Battler/005_Battler_StatStages.rb | 308 -- .../001_Battler/006_Battler_AbilityAndItem.rb | 303 -- .../001_Battler/007_Battler_UseMove.rb | 809 ---- .../008_Battler_UseMove_Targeting.rb | 193 - .../009_Battler_UseMove_SuccessChecks.rb | 541 --- .../010_Battler_UseMove_TriggerEffects.rb | 194 - Data/Scripts/011_Battle/001_PBEffects.rb | 182 - Data/Scripts/011_Battle/002_BattleHandlers.rb | 601 --- .../002_Move/001_PokeBattle_Move.rb | 141 - .../011_Battle/002_Move/002_Move_Usage.rb | 350 -- .../002_Move/003_Move_Usage_Calculations.rb | 492 --- .../002_Move/004_Move_Effects_Generic.rb | 716 ---- .../002_Move/005_Move_Effects_000-07F.rb | 2572 ------------ .../002_Move/006_Move_Effects_080-0FF.rb | 3723 ----------------- .../002_Move/007_Move_Effects_100-17F.rb | 2493 ----------- .../003_Battle/001_PokeBattle_BattleCommon.rb | 264 -- .../003_Battle/002_PokeBattle_Battle.rb | 799 ---- .../003_Battle/003_Battle_StartAndEnd.rb | 581 --- .../004_Battle_ExpAndMoveLearning.rb | 302 -- .../005_Battle_Action_AttacksPriority.rb | 248 -- .../003_Battle/006_Battle_Action_Switching.rb | 415 -- .../003_Battle/007_Battle_Action_UseItem.rb | 148 - .../003_Battle/008_Battle_Action_Running.rb | 156 - .../003_Battle/009_Battle_Action_Other.rb | 188 - .../003_Battle/010_Battle_Phase_Command.rb | 253 -- .../003_Battle/011_Battle_Phase_Attack.rb | 190 - .../003_Battle/012_Battle_Phase_EndOfRound.rb | 666 --- .../003_BattleHandlers_Abilities.rb | 2426 ----------- .../011_Battle/004_AI/001_PokeBattle_AI.rb | 69 - Data/Scripts/011_Battle/004_AI/002_AI_Item.rb | 171 - .../011_Battle/004_AI/003_AI_Switch.rb | 178 - Data/Scripts/011_Battle/004_AI/004_AI_Move.rb | 291 -- .../004_AI/005_AI_Move_EffectScores.rb | 3053 -------------- .../004_AI/006_AI_Move_Utilities.rb | 669 --- .../011_Battle/004_BattleHandlers_Items.rb | 1590 ------- .../005_BallHandlers_PokeBallEffects.rb | 251 -- .../001_PokeBattle_Animation.rb | 278 -- .../002_PokeBattle_SceneAnimations.rb | 876 ---- .../003_PokeBattle_SceneConstants.rb | 67 - .../004_PokeBattle_SceneElements.rb | 743 ---- .../005_PokeBattle_SceneMenus.rb | 552 --- .../005_Battle scene/006_PokeBattle_Scene.rb | 351 -- .../005_Battle scene/007_Scene_Initialize.rb | 240 -- .../005_Battle scene/008_Scene_Commands.rb | 475 --- .../005_Battle scene/009_Scene_Animations.rb | 575 --- .../001_PokeBattle_AnimationPlayer.rb | 876 ---- .../002_PokeBattle_SafariZone.rb | 511 --- .../003_PokeBattle_BugContest.rb | 87 - .../004_PokeBattle_BattlePalace.rb | 250 -- .../005_PokeBattle_BattleArena.rb | 349 -- .../006_PokeBattle_BattleRecord.rb | 307 -- .../007_PokeBattle_DebugScene.rb | 84 - .../008_PokeBattle_BattlePeer.rb | 78 - .../009_PokeBattle_Clauses.rb | 242 -- .../011_Battle/006_PokeBattle_ActiveField.rb | 90 - .../011_Battle/007_PokeBattle_DamageState.rb | 50 - .../001_Overworld_Weather.rb | 518 --- .../002_Overworld_Overlays.rb | 291 -- .../003_Overworld_MapTransitionAnims.rb | 151 - Data/Scripts/012_Overworld/001_Overworld.rb | 961 ----- .../001_Overworld_BattleStarting.rb | 860 ---- .../002_Overworld_BattleIntroAnim.rb | 352 -- .../003_Overworld_WildEncounters.rb | 465 -- .../004_Overworld_EncounterModifiers.rb | 50 - .../005_Overworld_RoamingPokemon.rb | 257 -- .../012_Overworld/002_Overworld_Metadata.rb | 291 -- .../012_Overworld/003_Overworld_Time.rb | 340 -- .../012_Overworld/004_Overworld_FieldMoves.rb | 1185 ------ .../012_Overworld/005_Overworld_Fishing.rb | 174 - .../006_Overworld_BerryPlants.rb | 542 --- .../012_Overworld/007_Overworld_DayCare.rb | 403 -- .../008_Overworld_RandomDungeons.rb | 669 --- Data/Scripts/013_Items/001_Item_Utilities.rb | 794 ---- Data/Scripts/013_Items/002_Item_Effects.rb | 1098 ----- .../013_Items/003_Item_BattleEffects.rb | 695 --- Data/Scripts/013_Items/004_1_PokeradarUI.rb | 138 - Data/Scripts/013_Items/004_Item_Phone.rb | 303 -- Data/Scripts/013_Items/005_Item_PokeRadar.rb | 345 -- Data/Scripts/013_Items/006_Item_Mail.rb | 134 - Data/Scripts/013_Items/007_Item_Sprites.rb | 163 - Data/Scripts/013_Items/008_PokemonBag.rb | 400 -- .../001_Pokemon-related/001_FormHandlers.rb | 609 --- .../002_ShadowPokemon_Other.rb | 529 --- .../003_Pokemon_Sprites.rb | 424 -- .../001_Pokemon-related/004_PokemonStorage.rb | 406 -- Data/Scripts/014_Pokemon/001_Pokemon.rb | 1617 ------- .../014_Pokemon/002_Pokemon_MegaEvolution.rb | 80 - .../014_Pokemon/003_Pokemon_ShadowPokemon.rb | 160 - Data/Scripts/014_Pokemon/004_Pokemon_Move.rb | 78 - Data/Scripts/014_Pokemon/005_Pokemon_Owner.rb | 78 - .../014_Pokemon/006_Pokemon_Deprecated.rb | 207 - .../015_Trainers and player/001_Trainer.rb | 242 -- .../002_Trainer_LoadAndNew.rb | 145 - .../003_Trainer_Sprites.rb | 84 - .../015_Trainers and player/004_Player.rb | 391 -- .../005_Player_Pokedex.rb | 487 --- .../006_Player_Deprecated.rb | 194 - .../001_UI_SplashesAndTitleScreen.rb | 122 - .../001_Non-interactive UI/002_UI_Controls.rb | 80 - .../003_UI_EggHatching.rb | 248 -- .../004_UI_Evolution.rb | 666 --- .../001_Non-interactive UI/005_UI_Trading.rb | 252 -- .../006_UI_HallOfFame.rb | 673 --- .../001_Non-interactive UI/007_UI_Credits.rb | 374 -- Data/Scripts/016_UI/001_UI_PauseMenu.rb | 289 -- Data/Scripts/016_UI/002_UI_Pokedex_Menu.rb | 127 - Data/Scripts/016_UI/003_UI_Pokedex_Main.rb | 1233 ------ Data/Scripts/016_UI/004_UI_Pokedex_Entry.rb | 825 ---- Data/Scripts/016_UI/005_UI_Party.rb | 1552 ------- Data/Scripts/016_UI/006_UI_Summary.rb | 1537 ------- Data/Scripts/016_UI/007_UI_Bag.rb | 716 ---- Data/Scripts/016_UI/008_UI_Pokegear.rb | 157 - Data/Scripts/016_UI/009_UI_RegionMap.rb | 376 -- Data/Scripts/016_UI/010_UI_Phone.rb | 149 - Data/Scripts/016_UI/011_UI_Jukebox.rb | 136 - Data/Scripts/016_UI/012_UI_TrainerCard.rb | 161 - Data/Scripts/016_UI/013_UI_Load.rb | 374 -- Data/Scripts/016_UI/014_UI_Save.rb | 129 - Data/Scripts/016_UI/015_UI_Options.rb | 531 --- Data/Scripts/016_UI/016_UI_ReadyMenu.rb | 327 -- Data/Scripts/016_UI/017_UI_PokemonStorage.rb | 2436 ----------- Data/Scripts/016_UI/018_UI_ItemStorage.rb | 368 -- Data/Scripts/016_UI/019_UI_PC.rb | 275 -- Data/Scripts/016_UI/020_UI_PokeMart.rb | 794 ---- Data/Scripts/016_UI/021_UI_MoveRelearner.rb | 217 - Data/Scripts/016_UI/022_UI_PurifyChamber.rb | 1361 ------ Data/Scripts/016_UI/023_UI_MysteryGift.rb | 421 -- Data/Scripts/016_UI/024_UI_TextEntry.rb | 804 ---- .../017_Minigames/001_Minigame_Duel.rb | 391 -- .../017_Minigames/002_Minigame_TripleTriad.rb | 1302 ------ .../017_Minigames/003_Minigame_SlotMachine.rb | 404 -- .../017_Minigames/004_Minigame_VoltorbFlip.rb | 626 --- .../017_Minigames/005_Minigame_Lottery.rb | 54 - .../017_Minigames/006_Minigame_Mining.rb | 622 --- .../017_Minigames/007_Minigame_TilePuzzles.rb | 582 --- .../001_Challenge_BattleChallenge.rb | 428 -- .../001_Battle Frontier/002_Challenge_Data.rb | 316 -- .../003_Challenge_ChooseFoes.rb | 188 - .../004_Challenge_Battles.rb | 146 - .../001_Battle Frontier/005_UI_BattleSwap.rb | 230 - .../001_SafariZone.rb | 145 - .../001_Challenge_ChallengeRules.rb | 382 -- .../002_Challenge_Rulesets.rb | 329 -- .../003_Challenge_EntryRestrictions.rb | 398 -- .../004_Challenge_LevelAdjustment.rb | 227 - .../005_Challenge_BattleRules.rb | 97 - .../002_BugContest.rb | 398 -- .../001_ChallengeGenerator_Data.rb | 344 -- .../002_ChallengeGenerator_Pokemon.rb | 366 -- .../003_ChallengeGenerator_Trainers.rb | 215 - .../004_ChallengeGenerator_BattleSim.rb | 433 -- Data/Scripts/019_Utilities/001_Utilities.rb | 604 --- .../019_Utilities/002_Utilities_Pokemon.rb | 279 -- .../003_Utilities_BattleAudio.rb | 146 - .../001_Editor screens/001_EditorScreens.rb | 320 -- .../002_EditorScreens_TerrainTags.rb | 234 -- .../003_EditorScreens_MapConnections.rb | 590 --- .../004_EditorScreens_SpritePositioning.rb | 421 -- .../Scripts/020_Debug/001_Editor_Utilities.rb | 417 -- .../001_AnimEditor_SceneElements.rb | 1026 ----- .../002_AnimEditor_ControlsButtons.rb | 910 ---- .../003_AnimEditor_Interpolation.rb | 440 -- .../004_AnimEditor_ExportImport.rb | 144 - .../005_AnimEditor_Functions.rb | 1199 ------ .../Scripts/020_Debug/002_Editor_DataTypes.rb | 1535 ------- .../003_Debug menus/001_Debug_Menus.rb | 185 - .../003_Debug menus/002_Debug_MenuCommands.rb | 1053 ----- .../003_Debug_MenuExtraCode.rb | 904 ---- .../004_Debug_MenuSpriteRenamer.rb | 311 -- .../005_Debug_PokemonCommands.rb | 1278 ------ Data/Scripts/020_Debug/003_Editor_Listers.rb | 609 --- Data/Scripts/021_Compiler/001_Compiler.rb | 852 ---- .../021_Compiler/002_Compiler_CompilePBS.rb | 1611 ------- .../021_Compiler/003_Compiler_WritePBS.rb | 805 ---- .../004_Compiler_MapsAndEvents.rb | 1433 ------- Data/Scripts/025-Randomizer/Random Pokemon.rb | 198 - .../025-Randomizer/RandomizerSettings.rb | 535 --- .../Scripts/025-Randomizer/RandomizerUtils.rb | 126 - .../025-Randomizer/randomizer - encounters.rb | 223 - .../randomizer gym leader edit.rb | 773 ---- Data/Scripts/025-Randomizer/randomizer.rb | 366 -- .../Scripts/048_Fusion/DoublePreviewScreen.rb | 219 - Data/Scripts/048_Fusion/FusedSpecies.rb | 403 -- Data/Scripts/048_Fusion/FusionAnim.rb | 38 - Data/Scripts/048_Fusion/FusionMenu.rb | 115 - Data/Scripts/048_Fusion/FusionMovesMenu.rb | 240 -- .../Scripts/048_Fusion/FusionPreviewScreen.rb | 39 - Data/Scripts/048_Fusion/PokemonFusion.rb | 1140 ----- Data/Scripts/048_Fusion/SplitNames.rb | 1165 ------ .../Sprites/001_PifSpriteBitmapCache.rb | 52 - .../Sprites/002_PIFSpriteExtracter.rb | 98 - .../048_Fusion/Sprites/AutogenExtracter.rb | 160 - .../048_Fusion/Sprites/BaseSpriteExtracter.rb | 61 - .../048_Fusion/Sprites/BattleSpriteLoader.rb | 277 -- .../Sprites/CustomSpriteExtracter.rb | 106 - Data/Scripts/048_Fusion/Sprites/PIFSprite.rb | 114 - .../Sprites/SpritesSubstitutions.rb | 89 - Data/Scripts/049_Compatibility/Constants.rb | 336 -- .../049_Compatibility/DeprecatedClasses.rb | 2 - Data/Scripts/049_Compatibility/EggGroups.rb | 0 .../049_Compatibility/MarinUtilities.rb | 1291 ------ Data/Scripts/049_Compatibility/PBItems.rb | 662 --- Data/Scripts/049_Compatibility/PBMoves.rb | 684 --- Data/Scripts/049_Compatibility/PBSpecies.rb | 30 - Data/Scripts/049_Compatibility/PBTrainers.rb | 120 - .../049_Compatibility/UtilityMethods.rb | 187 - Data/Scripts/049_Compatibility/pb_types.rb | 7 - .../001_OutfitsMain/LayeredClothes.rb | 409 -- .../001_OutfitsMain/OutfitSelector.rb | 174 - .../001_OutfitsMain/OutfitsGlobal.rb | 75 - .../001_OutfitsMain/OutfitsSearch.rb | 221 - Data/Scripts/050_Outfits/ItemSets.rb | 185 - Data/Scripts/050_Outfits/OutfitIds.rb | 148 - .../050_Outfits/UI/CharacterSelectMenu.rb | 181 - .../UI/CharacterSelectMenuPresenter.rb | 275 -- .../050_Outfits/UI/LayeredClothes_Menus.rb | 265 -- .../UI/PokemonHatScreenPresenter.rb | 103 - .../050_Outfits/UI/PokemonHatScreenView.rb | 139 - .../050_Outfits/UI/TrainerClothesPreview.rb | 72 - .../UI/clothesShop/0_OutfitsMartAdapter.rb | 159 - .../UI/clothesShop/ClothesMartAdapter.rb | 116 - .../050_Outfits/UI/clothesShop/ClothesShop.rb | 146 - .../UI/clothesShop/ClothesShopPresenter.rb | 163 - .../ClothesShopPresenter_HatsMenu.rb | 154 - .../UI/clothesShop/ClothesShopView.rb | 205 - .../UI/clothesShop/HairMartAdapter.rb | 209 - .../UI/clothesShop/HairShopPresenter.rb | 68 - .../050_Outfits/UI/clothesShop/HatShopView.rb | 110 - .../UI/clothesShop/HatsMartAdapter.rb | 230 - .../UI/hairMenu/HairStyleSelectionMenuView.rb | 160 - .../HairstyleSelectionMenuPresenter.rb | 187 - .../050_Outfits/utils/OutfitFilenameUtils.rb | 126 - .../050_Outfits/utils/OutfitsGameplayUtils.rb | 412 -- .../050_Outfits/wrappers/001_Outfit.rb | 19 - Data/Scripts/050_Outfits/wrappers/Clothes.rb | 11 - .../Scripts/050_Outfits/wrappers/Hairstyle.rb | 12 - Data/Scripts/050_Outfits/wrappers/Hat.rb | 11 - Data/Scripts/051_Wrappers/quest_reward.rb | 15 - Data/Scripts/051_Wrappers/type_expert.rb | 158 - Data/Scripts/052_AddOns/AttributeReader.rb | 0 Data/Scripts/052_AddOns/Autosave.rb | 133 - Data/Scripts/052_AddOns/BattleLounge.rb | 232 - Data/Scripts/052_AddOns/BetterRegionMap.rb | 972 ----- Data/Scripts/052_AddOns/CustomTrainers.rb | 232 - Data/Scripts/052_AddOns/DevUtils.rb | 191 - Data/Scripts/052_AddOns/DisplayText.rb | 51 - Data/Scripts/052_AddOns/DoubleAbilities.rb | 259 -- .../DoubleAbilitiesHandlersOverrides.rb | 389 -- Data/Scripts/052_AddOns/DoubleAbilities_UI.rb | 130 - Data/Scripts/052_AddOns/EggMoveTutor.rb | 32 - .../Scripts/052_AddOns/ExperimentalOptions.rb | 72 - Data/Scripts/052_AddOns/ExportScripts.rb | 38 - Data/Scripts/052_AddOns/Footprints.rb | 225 - Data/Scripts/052_AddOns/FusionMoveTutor.rb | 205 - Data/Scripts/052_AddOns/FusionSprites.rb | 403 -- Data/Scripts/052_AddOns/FusionUtils.rb | 410 -- Data/Scripts/052_AddOns/GameOptions.rb | 250 -- Data/Scripts/052_AddOns/GameplayUtils.rb | 1806 -------- Data/Scripts/052_AddOns/Gen 2.rb | 302 -- Data/Scripts/052_AddOns/GeneralUtils.rb | 525 --- Data/Scripts/052_AddOns/GuessPokemonQuiz.rb | 309 -- Data/Scripts/052_AddOns/HiddenAbilityMaps.rb | 47 - Data/Scripts/052_AddOns/HttpCalls.rb | 442 -- Data/Scripts/052_AddOns/IntroScreen.rb | 495 --- Data/Scripts/052_AddOns/MapExporter.rb | 189 - Data/Scripts/052_AddOns/Movie.rb | 79 - Data/Scripts/052_AddOns/MultiSaves.rb | 935 ----- Data/Scripts/052_AddOns/New Balls.rb | 128 - Data/Scripts/052_AddOns/New HMs.rb | 141 - Data/Scripts/052_AddOns/New Items effects.rb | 2057 --------- Data/Scripts/052_AddOns/NonMoneyShop.rb | 53 - Data/Scripts/052_AddOns/OnlineWondertrade.rb | 91 - Data/Scripts/052_AddOns/Overrides.rb | 3 - Data/Scripts/052_AddOns/OverworldShadows.rb | 302 -- Data/Scripts/052_AddOns/Pathfinding.rb | 89 - Data/Scripts/052_AddOns/PokedexUtils.rb | 89 - Data/Scripts/052_AddOns/PokemonSelection.rb | 137 - Data/Scripts/052_AddOns/PoliceQuest.rb | 8 - Data/Scripts/052_AddOns/QuestIcons.rb | 174 - Data/Scripts/052_AddOns/QuestLogScript.rb | 1109 ----- Data/Scripts/052_AddOns/RandomAddOns.rb | 19 - Data/Scripts/052_AddOns/ShinyColorOffsets.rb | 422 -- Data/Scripts/052_AddOns/Silhouette.rb | 147 - Data/Scripts/052_AddOns/SpeechBubbles.rb | 217 - Data/Scripts/052_AddOns/Spped Up.rb | 71 - Data/Scripts/052_AddOns/SpriteCreditsUtils.rb | 498 --- Data/Scripts/052_AddOns/TRQuests.rb | 380 -- Data/Scripts/052_AddOns/TeamFlags.rb | 18 - Data/Scripts/052_AddOns/TempEvents.rb | 34 - .../052_AddOns/TrainerCardBackgrounds.rb | 196 - .../052_AddOns/TrainerGeneratorUtils.rb | 36 - Data/Scripts/052_AddOns/Trainers Rebattle.rb | 295 -- Data/Scripts/052_AddOns/TripleFusion.rb | 90 - .../052_AddOns/UI_Pokedex_SpritesPage.rb | 373 -- Data/Scripts/052_AddOns/UnrealTime.rb | 293 -- Data/Scripts/052_AddOns/WaterEffect.rb | 23 - Data/Scripts/052_AddOns/WonderTrade_names.rb | 1070 ----- Data/Scripts/052_AddOns/Wondertrade.rb | 208 - Data/Scripts/052_AddOns/dynamic_waterfall.rb | 225 - Data/Scripts/052_AddOns/k_scriptsUtils.rb | 1167 ------ Data/Scripts/052_AddOns/mapExporter2.rb | 533 --- Data/Scripts/052_AddOns/mapExporter2_ui.rb | 74 - Data/Scripts/052_AddOns/platform.rb | 251 -- Data/Scripts/052_Tests/FusionUtilsTests.rb | 20 - Data/Scripts/999_Main/999_Main.rb | 192 - Data/Scripts/DownloadedSettings.rb | 51 - 429 files changed, 165507 deletions(-) delete mode 100644 Data/Scripts/001_Settings.rb delete mode 100644 Data/Scripts/001_Technical/001_Debugging/001_PBDebug.rb delete mode 100644 Data/Scripts/001_Technical/001_Debugging/002_DebugConsole.rb delete mode 100644 Data/Scripts/001_Technical/001_Debugging/003_Errors.rb delete mode 100644 Data/Scripts/001_Technical/001_Debugging/004_Validation.rb delete mode 100644 Data/Scripts/001_Technical/001_Debugging/005_Deprecation.rb delete mode 100644 Data/Scripts/001_Technical/001_MKXP_Compatibility.rb delete mode 100644 Data/Scripts/001_Technical/002_Files/001_FileTests.rb delete mode 100644 Data/Scripts/001_Technical/002_Files/002_FileMixins.rb delete mode 100644 Data/Scripts/001_Technical/002_Files/003_HTTP_Utilities.rb delete mode 100644 Data/Scripts/001_Technical/002_RubyUtilities.rb delete mode 100644 Data/Scripts/001_Technical/003_Intl_Messages.rb delete mode 100644 Data/Scripts/001_Technical/004_Input.rb delete mode 100644 Data/Scripts/001_Technical/005_PluginManager.rb delete mode 100644 Data/Scripts/001_Technical/006_RPG_Sprite.rb delete mode 100644 Data/Scripts/002_BattleSettings.rb delete mode 100644 Data/Scripts/002_Save data/001_SaveData.rb delete mode 100644 Data/Scripts/002_Save data/002_SaveData_Value.rb delete mode 100644 Data/Scripts/002_Save data/003_SaveData_Conversion.rb delete mode 100644 Data/Scripts/002_Save data/004_Game_SaveValues.rb delete mode 100644 Data/Scripts/002_Save data/005_Game_SaveConversions.rb delete mode 100644 Data/Scripts/003_Game processing/001_StartGame.rb delete mode 100644 Data/Scripts/003_Game processing/002_Scene_Map.rb delete mode 100644 Data/Scripts/003_Game processing/003_Interpreter.rb delete mode 100644 Data/Scripts/003_Game processing/004_Interpreter_Commands.rb delete mode 100644 Data/Scripts/003_Game processing/005_Event_Handlers.rb delete mode 100644 Data/Scripts/003_Game processing/006_Event_OverworldEvents.rb delete mode 100644 Data/Scripts/004_Game classes/001_Game_Screen.rb delete mode 100644 Data/Scripts/004_Game classes/001_Switches and Variables/001_Game_Temp.rb delete mode 100644 Data/Scripts/004_Game classes/001_Switches and Variables/002_Game_Switches.rb delete mode 100644 Data/Scripts/004_Game classes/001_Switches and Variables/003_Game_Variables.rb delete mode 100644 Data/Scripts/004_Game classes/001_Switches and Variables/004_Game_SelfSwitches.rb delete mode 100644 Data/Scripts/004_Game classes/002_Game_System.rb delete mode 100644 Data/Scripts/004_Game classes/003_Game_Picture.rb delete mode 100644 Data/Scripts/004_Game classes/004_Game_Map.rb delete mode 100644 Data/Scripts/004_Game classes/005_Game_Map_Autoscroll.rb delete mode 100644 Data/Scripts/004_Game classes/006_Game_MapFactory.rb delete mode 100644 Data/Scripts/004_Game classes/007_Game_Character.rb delete mode 100644 Data/Scripts/004_Game classes/008_Game_Event.rb delete mode 100644 Data/Scripts/004_Game classes/009_Game_Player.rb delete mode 100644 Data/Scripts/004_Game classes/010_Game_Player_Visuals.rb delete mode 100644 Data/Scripts/004_Game classes/011_Game_CommonEvent.rb delete mode 100644 Data/Scripts/004_Game classes/012_Game_DependentEvents.rb delete mode 100644 Data/Scripts/005_Map renderer/001_Tilemap_XP.rb delete mode 100644 Data/Scripts/005_Sprites/001_Sprite_Picture.rb delete mode 100644 Data/Scripts/005_Sprites/002_Sprite_Timer.rb delete mode 100644 Data/Scripts/005_Sprites/003_Sprite_Character.rb delete mode 100644 Data/Scripts/005_Sprites/004_Sprite_Reflection.rb delete mode 100644 Data/Scripts/005_Sprites/005_Sprite_SurfBase.rb delete mode 100644 Data/Scripts/005_Sprites/006_Spriteset_Global.rb delete mode 100644 Data/Scripts/005_Sprites/007_Spriteset_Map.rb delete mode 100644 Data/Scripts/005_Sprites/008_Sprite_AnimationSprite.rb delete mode 100644 Data/Scripts/005_Sprites/009_Sprite_DynamicShadows.rb delete mode 100644 Data/Scripts/005_Sprites/010_ParticleEngine.rb delete mode 100644 Data/Scripts/005_Sprites/011_PictureEx.rb delete mode 100644 Data/Scripts/005_Sprites/012_Interpolators.rb delete mode 100644 Data/Scripts/005_Sprites/013_ScreenPosHelper.rb delete mode 100644 Data/Scripts/005_Sprites/013_Sprite_Player_Offsets.rb delete mode 100644 Data/Scripts/005_Sprites/013_Sprite_Wearable.rb delete mode 100644 Data/Scripts/005_Sprites/014_Sprite_Hair.rb delete mode 100644 Data/Scripts/005_Sprites/014_Sprite_Hat.rb delete mode 100644 Data/Scripts/005_Sprites/016_Sprite_Player.rb delete mode 100644 Data/Scripts/006_Map renderer/001_TilemapRenderer.rb delete mode 100644 Data/Scripts/006_Map renderer/002_TilesetWrapper.rb delete mode 100644 Data/Scripts/006_Map renderer/003_AutotileExpander.rb delete mode 100644 Data/Scripts/006_Map renderer/004_TileDrawingHelper.rb delete mode 100644 Data/Scripts/007_Objects and windows/001_RPG_Cache.rb delete mode 100644 Data/Scripts/007_Objects and windows/002_MessageConfig.rb delete mode 100644 Data/Scripts/007_Objects and windows/003_Window.rb delete mode 100644 Data/Scripts/007_Objects and windows/004_SpriteWindow.rb delete mode 100644 Data/Scripts/007_Objects and windows/005_SpriteWindow_text.rb delete mode 100644 Data/Scripts/007_Objects and windows/006_SpriteWindow_pictures.rb delete mode 100644 Data/Scripts/007_Objects and windows/007_SpriteWrapper.rb delete mode 100644 Data/Scripts/007_Objects and windows/008_AnimatedBitmap.rb delete mode 100644 Data/Scripts/007_Objects and windows/009_Planes.rb delete mode 100644 Data/Scripts/007_Objects and windows/010_DrawText.rb delete mode 100644 Data/Scripts/007_Objects and windows/011_Messages.rb delete mode 100644 Data/Scripts/007_Objects and windows/012_TextEntry.rb delete mode 100644 Data/Scripts/008_Audio/001_Audio.rb delete mode 100644 Data/Scripts/008_Audio/002_Audio_Play.rb delete mode 100644 Data/Scripts/009_Scenes/001_Transitions.rb delete mode 100644 Data/Scripts/009_Scenes/002_EventScene.rb delete mode 100644 Data/Scripts/010_Data/001_GameData.rb delete mode 100644 Data/Scripts/010_Data/001_Hardcoded data/001_GrowthRate.rb delete mode 100644 Data/Scripts/010_Data/001_Hardcoded data/002_GenderRatio.rb delete mode 100644 Data/Scripts/010_Data/001_Hardcoded data/003_EggGroup.rb delete mode 100644 Data/Scripts/010_Data/001_Hardcoded data/004_BodyShape.rb delete mode 100644 Data/Scripts/010_Data/001_Hardcoded data/005_BodyColor.rb delete mode 100644 Data/Scripts/010_Data/001_Hardcoded data/006_Habitat.rb delete mode 100644 Data/Scripts/010_Data/001_Hardcoded data/007_Evolution.rb delete mode 100644 Data/Scripts/010_Data/001_Hardcoded data/008_Stat.rb delete mode 100644 Data/Scripts/010_Data/001_Hardcoded data/009_Nature.rb delete mode 100644 Data/Scripts/010_Data/001_Hardcoded data/010_Status.rb delete mode 100644 Data/Scripts/010_Data/001_Hardcoded data/011_TerrainTag.rb delete mode 100644 Data/Scripts/010_Data/001_Hardcoded data/012_Weather.rb delete mode 100644 Data/Scripts/010_Data/001_Hardcoded data/013_EncounterType.rb delete mode 100644 Data/Scripts/010_Data/001_Hardcoded data/014_Environment.rb delete mode 100644 Data/Scripts/010_Data/001_Hardcoded data/015_BattleWeather.rb delete mode 100644 Data/Scripts/010_Data/001_Hardcoded data/016_BattleTerrain.rb delete mode 100644 Data/Scripts/010_Data/001_Hardcoded data/017_Target.rb delete mode 100644 Data/Scripts/010_Data/002_PBS data/001_MiscPBSData.rb delete mode 100644 Data/Scripts/010_Data/002_PBS data/002_PhoneDatabase.rb delete mode 100644 Data/Scripts/010_Data/002_PBS data/003_Type.rb delete mode 100644 Data/Scripts/010_Data/002_PBS data/004_Ability.rb delete mode 100644 Data/Scripts/010_Data/002_PBS data/005_Move.rb delete mode 100644 Data/Scripts/010_Data/002_PBS data/006_Item.rb delete mode 100644 Data/Scripts/010_Data/002_PBS data/007_BerryPlant.rb delete mode 100644 Data/Scripts/010_Data/002_PBS data/008_Species.rb delete mode 100644 Data/Scripts/010_Data/002_PBS data/009_Species_Files.rb delete mode 100644 Data/Scripts/010_Data/002_PBS data/010_Ribbon.rb delete mode 100644 Data/Scripts/010_Data/002_PBS data/011_Encounter.rb delete mode 100644 Data/Scripts/010_Data/002_PBS data/011_EncounterModern.rb delete mode 100644 Data/Scripts/010_Data/002_PBS data/011_Encounter_random.rb delete mode 100644 Data/Scripts/010_Data/002_PBS data/012_TrainerType.rb delete mode 100644 Data/Scripts/010_Data/002_PBS data/013_Trainer.rb delete mode 100644 Data/Scripts/010_Data/002_PBS data/013_TrainerExpert.rb delete mode 100644 Data/Scripts/010_Data/002_PBS data/013_TrainerModern.rb delete mode 100644 Data/Scripts/010_Data/002_PBS data/014_Metadata.rb delete mode 100644 Data/Scripts/010_Data/002_PBS data/015_MapMetadata.rb delete mode 100644 Data/Scripts/011_Battle/001_Battler/001_PokeBattle_Battler.rb delete mode 100644 Data/Scripts/011_Battle/001_Battler/002_Battler_Initialize.rb delete mode 100644 Data/Scripts/011_Battle/001_Battler/003_Battler_ChangeSelf.rb delete mode 100644 Data/Scripts/011_Battle/001_Battler/004_Battler_Statuses.rb delete mode 100644 Data/Scripts/011_Battle/001_Battler/005_Battler_StatStages.rb delete mode 100644 Data/Scripts/011_Battle/001_Battler/006_Battler_AbilityAndItem.rb delete mode 100644 Data/Scripts/011_Battle/001_Battler/007_Battler_UseMove.rb delete mode 100644 Data/Scripts/011_Battle/001_Battler/008_Battler_UseMove_Targeting.rb delete mode 100644 Data/Scripts/011_Battle/001_Battler/009_Battler_UseMove_SuccessChecks.rb delete mode 100644 Data/Scripts/011_Battle/001_Battler/010_Battler_UseMove_TriggerEffects.rb delete mode 100644 Data/Scripts/011_Battle/001_PBEffects.rb delete mode 100644 Data/Scripts/011_Battle/002_BattleHandlers.rb delete mode 100644 Data/Scripts/011_Battle/002_Move/001_PokeBattle_Move.rb delete mode 100644 Data/Scripts/011_Battle/002_Move/002_Move_Usage.rb delete mode 100644 Data/Scripts/011_Battle/002_Move/003_Move_Usage_Calculations.rb delete mode 100644 Data/Scripts/011_Battle/002_Move/004_Move_Effects_Generic.rb delete mode 100644 Data/Scripts/011_Battle/002_Move/005_Move_Effects_000-07F.rb delete mode 100644 Data/Scripts/011_Battle/002_Move/006_Move_Effects_080-0FF.rb delete mode 100644 Data/Scripts/011_Battle/002_Move/007_Move_Effects_100-17F.rb delete mode 100644 Data/Scripts/011_Battle/003_Battle/001_PokeBattle_BattleCommon.rb delete mode 100644 Data/Scripts/011_Battle/003_Battle/002_PokeBattle_Battle.rb delete mode 100644 Data/Scripts/011_Battle/003_Battle/003_Battle_StartAndEnd.rb delete mode 100644 Data/Scripts/011_Battle/003_Battle/004_Battle_ExpAndMoveLearning.rb delete mode 100644 Data/Scripts/011_Battle/003_Battle/005_Battle_Action_AttacksPriority.rb delete mode 100644 Data/Scripts/011_Battle/003_Battle/006_Battle_Action_Switching.rb delete mode 100644 Data/Scripts/011_Battle/003_Battle/007_Battle_Action_UseItem.rb delete mode 100644 Data/Scripts/011_Battle/003_Battle/008_Battle_Action_Running.rb delete mode 100644 Data/Scripts/011_Battle/003_Battle/009_Battle_Action_Other.rb delete mode 100644 Data/Scripts/011_Battle/003_Battle/010_Battle_Phase_Command.rb delete mode 100644 Data/Scripts/011_Battle/003_Battle/011_Battle_Phase_Attack.rb delete mode 100644 Data/Scripts/011_Battle/003_Battle/012_Battle_Phase_EndOfRound.rb delete mode 100644 Data/Scripts/011_Battle/003_BattleHandlers_Abilities.rb delete mode 100644 Data/Scripts/011_Battle/004_AI/001_PokeBattle_AI.rb delete mode 100644 Data/Scripts/011_Battle/004_AI/002_AI_Item.rb delete mode 100644 Data/Scripts/011_Battle/004_AI/003_AI_Switch.rb delete mode 100644 Data/Scripts/011_Battle/004_AI/004_AI_Move.rb delete mode 100644 Data/Scripts/011_Battle/004_AI/005_AI_Move_EffectScores.rb delete mode 100644 Data/Scripts/011_Battle/004_AI/006_AI_Move_Utilities.rb delete mode 100644 Data/Scripts/011_Battle/004_BattleHandlers_Items.rb delete mode 100644 Data/Scripts/011_Battle/005_BallHandlers_PokeBallEffects.rb delete mode 100644 Data/Scripts/011_Battle/005_Battle scene/001_PokeBattle_Animation.rb delete mode 100644 Data/Scripts/011_Battle/005_Battle scene/002_PokeBattle_SceneAnimations.rb delete mode 100644 Data/Scripts/011_Battle/005_Battle scene/003_PokeBattle_SceneConstants.rb delete mode 100644 Data/Scripts/011_Battle/005_Battle scene/004_PokeBattle_SceneElements.rb delete mode 100644 Data/Scripts/011_Battle/005_Battle scene/005_PokeBattle_SceneMenus.rb delete mode 100644 Data/Scripts/011_Battle/005_Battle scene/006_PokeBattle_Scene.rb delete mode 100644 Data/Scripts/011_Battle/005_Battle scene/007_Scene_Initialize.rb delete mode 100644 Data/Scripts/011_Battle/005_Battle scene/008_Scene_Commands.rb delete mode 100644 Data/Scripts/011_Battle/005_Battle scene/009_Scene_Animations.rb delete mode 100644 Data/Scripts/011_Battle/006_Other battle types/001_PokeBattle_AnimationPlayer.rb delete mode 100644 Data/Scripts/011_Battle/006_Other battle types/002_PokeBattle_SafariZone.rb delete mode 100644 Data/Scripts/011_Battle/006_Other battle types/003_PokeBattle_BugContest.rb delete mode 100644 Data/Scripts/011_Battle/006_Other battle types/004_PokeBattle_BattlePalace.rb delete mode 100644 Data/Scripts/011_Battle/006_Other battle types/005_PokeBattle_BattleArena.rb delete mode 100644 Data/Scripts/011_Battle/006_Other battle types/006_PokeBattle_BattleRecord.rb delete mode 100644 Data/Scripts/011_Battle/006_Other battle types/007_PokeBattle_DebugScene.rb delete mode 100644 Data/Scripts/011_Battle/006_Other battle types/008_PokeBattle_BattlePeer.rb delete mode 100644 Data/Scripts/011_Battle/006_Other battle types/009_PokeBattle_Clauses.rb delete mode 100644 Data/Scripts/011_Battle/006_PokeBattle_ActiveField.rb delete mode 100644 Data/Scripts/011_Battle/007_PokeBattle_DamageState.rb delete mode 100644 Data/Scripts/012_Overworld/001_Overworld visuals/001_Overworld_Weather.rb delete mode 100644 Data/Scripts/012_Overworld/001_Overworld visuals/002_Overworld_Overlays.rb delete mode 100644 Data/Scripts/012_Overworld/001_Overworld visuals/003_Overworld_MapTransitionAnims.rb delete mode 100644 Data/Scripts/012_Overworld/001_Overworld.rb delete mode 100644 Data/Scripts/012_Overworld/002_Battle triggering/001_Overworld_BattleStarting.rb delete mode 100644 Data/Scripts/012_Overworld/002_Battle triggering/002_Overworld_BattleIntroAnim.rb delete mode 100644 Data/Scripts/012_Overworld/002_Battle triggering/003_Overworld_WildEncounters.rb delete mode 100644 Data/Scripts/012_Overworld/002_Battle triggering/004_Overworld_EncounterModifiers.rb delete mode 100644 Data/Scripts/012_Overworld/002_Battle triggering/005_Overworld_RoamingPokemon.rb delete mode 100644 Data/Scripts/012_Overworld/002_Overworld_Metadata.rb delete mode 100644 Data/Scripts/012_Overworld/003_Overworld_Time.rb delete mode 100644 Data/Scripts/012_Overworld/004_Overworld_FieldMoves.rb delete mode 100644 Data/Scripts/012_Overworld/005_Overworld_Fishing.rb delete mode 100644 Data/Scripts/012_Overworld/006_Overworld_BerryPlants.rb delete mode 100644 Data/Scripts/012_Overworld/007_Overworld_DayCare.rb delete mode 100644 Data/Scripts/012_Overworld/008_Overworld_RandomDungeons.rb delete mode 100644 Data/Scripts/013_Items/001_Item_Utilities.rb delete mode 100644 Data/Scripts/013_Items/002_Item_Effects.rb delete mode 100644 Data/Scripts/013_Items/003_Item_BattleEffects.rb delete mode 100644 Data/Scripts/013_Items/004_1_PokeradarUI.rb delete mode 100644 Data/Scripts/013_Items/004_Item_Phone.rb delete mode 100644 Data/Scripts/013_Items/005_Item_PokeRadar.rb delete mode 100644 Data/Scripts/013_Items/006_Item_Mail.rb delete mode 100644 Data/Scripts/013_Items/007_Item_Sprites.rb delete mode 100644 Data/Scripts/013_Items/008_PokemonBag.rb delete mode 100644 Data/Scripts/014_Pokemon/001_Pokemon-related/001_FormHandlers.rb delete mode 100644 Data/Scripts/014_Pokemon/001_Pokemon-related/002_ShadowPokemon_Other.rb delete mode 100644 Data/Scripts/014_Pokemon/001_Pokemon-related/003_Pokemon_Sprites.rb delete mode 100644 Data/Scripts/014_Pokemon/001_Pokemon-related/004_PokemonStorage.rb delete mode 100644 Data/Scripts/014_Pokemon/001_Pokemon.rb delete mode 100644 Data/Scripts/014_Pokemon/002_Pokemon_MegaEvolution.rb delete mode 100644 Data/Scripts/014_Pokemon/003_Pokemon_ShadowPokemon.rb delete mode 100644 Data/Scripts/014_Pokemon/004_Pokemon_Move.rb delete mode 100644 Data/Scripts/014_Pokemon/005_Pokemon_Owner.rb delete mode 100644 Data/Scripts/014_Pokemon/006_Pokemon_Deprecated.rb delete mode 100644 Data/Scripts/015_Trainers and player/001_Trainer.rb delete mode 100644 Data/Scripts/015_Trainers and player/002_Trainer_LoadAndNew.rb delete mode 100644 Data/Scripts/015_Trainers and player/003_Trainer_Sprites.rb delete mode 100644 Data/Scripts/015_Trainers and player/004_Player.rb delete mode 100644 Data/Scripts/015_Trainers and player/005_Player_Pokedex.rb delete mode 100644 Data/Scripts/015_Trainers and player/006_Player_Deprecated.rb delete mode 100644 Data/Scripts/016_UI/001_Non-interactive UI/001_UI_SplashesAndTitleScreen.rb delete mode 100644 Data/Scripts/016_UI/001_Non-interactive UI/002_UI_Controls.rb delete mode 100644 Data/Scripts/016_UI/001_Non-interactive UI/003_UI_EggHatching.rb delete mode 100644 Data/Scripts/016_UI/001_Non-interactive UI/004_UI_Evolution.rb delete mode 100644 Data/Scripts/016_UI/001_Non-interactive UI/005_UI_Trading.rb delete mode 100644 Data/Scripts/016_UI/001_Non-interactive UI/006_UI_HallOfFame.rb delete mode 100644 Data/Scripts/016_UI/001_Non-interactive UI/007_UI_Credits.rb delete mode 100644 Data/Scripts/016_UI/001_UI_PauseMenu.rb delete mode 100644 Data/Scripts/016_UI/002_UI_Pokedex_Menu.rb delete mode 100644 Data/Scripts/016_UI/003_UI_Pokedex_Main.rb delete mode 100644 Data/Scripts/016_UI/004_UI_Pokedex_Entry.rb delete mode 100644 Data/Scripts/016_UI/005_UI_Party.rb delete mode 100644 Data/Scripts/016_UI/006_UI_Summary.rb delete mode 100644 Data/Scripts/016_UI/007_UI_Bag.rb delete mode 100644 Data/Scripts/016_UI/008_UI_Pokegear.rb delete mode 100644 Data/Scripts/016_UI/009_UI_RegionMap.rb delete mode 100644 Data/Scripts/016_UI/010_UI_Phone.rb delete mode 100644 Data/Scripts/016_UI/011_UI_Jukebox.rb delete mode 100644 Data/Scripts/016_UI/012_UI_TrainerCard.rb delete mode 100644 Data/Scripts/016_UI/013_UI_Load.rb delete mode 100644 Data/Scripts/016_UI/014_UI_Save.rb delete mode 100644 Data/Scripts/016_UI/015_UI_Options.rb delete mode 100644 Data/Scripts/016_UI/016_UI_ReadyMenu.rb delete mode 100644 Data/Scripts/016_UI/017_UI_PokemonStorage.rb delete mode 100644 Data/Scripts/016_UI/018_UI_ItemStorage.rb delete mode 100644 Data/Scripts/016_UI/019_UI_PC.rb delete mode 100644 Data/Scripts/016_UI/020_UI_PokeMart.rb delete mode 100644 Data/Scripts/016_UI/021_UI_MoveRelearner.rb delete mode 100644 Data/Scripts/016_UI/022_UI_PurifyChamber.rb delete mode 100644 Data/Scripts/016_UI/023_UI_MysteryGift.rb delete mode 100644 Data/Scripts/016_UI/024_UI_TextEntry.rb delete mode 100644 Data/Scripts/017_Minigames/001_Minigame_Duel.rb delete mode 100644 Data/Scripts/017_Minigames/002_Minigame_TripleTriad.rb delete mode 100644 Data/Scripts/017_Minigames/003_Minigame_SlotMachine.rb delete mode 100644 Data/Scripts/017_Minigames/004_Minigame_VoltorbFlip.rb delete mode 100644 Data/Scripts/017_Minigames/005_Minigame_Lottery.rb delete mode 100644 Data/Scripts/017_Minigames/006_Minigame_Mining.rb delete mode 100644 Data/Scripts/017_Minigames/007_Minigame_TilePuzzles.rb delete mode 100644 Data/Scripts/018_Alternate battle modes/001_Battle Frontier/001_Challenge_BattleChallenge.rb delete mode 100644 Data/Scripts/018_Alternate battle modes/001_Battle Frontier/002_Challenge_Data.rb delete mode 100644 Data/Scripts/018_Alternate battle modes/001_Battle Frontier/003_Challenge_ChooseFoes.rb delete mode 100644 Data/Scripts/018_Alternate battle modes/001_Battle Frontier/004_Challenge_Battles.rb delete mode 100644 Data/Scripts/018_Alternate battle modes/001_Battle Frontier/005_UI_BattleSwap.rb delete mode 100644 Data/Scripts/018_Alternate battle modes/001_SafariZone.rb delete mode 100644 Data/Scripts/018_Alternate battle modes/002_Battle Frontier rules/001_Challenge_ChallengeRules.rb delete mode 100644 Data/Scripts/018_Alternate battle modes/002_Battle Frontier rules/002_Challenge_Rulesets.rb delete mode 100644 Data/Scripts/018_Alternate battle modes/002_Battle Frontier rules/003_Challenge_EntryRestrictions.rb delete mode 100644 Data/Scripts/018_Alternate battle modes/002_Battle Frontier rules/004_Challenge_LevelAdjustment.rb delete mode 100644 Data/Scripts/018_Alternate battle modes/002_Battle Frontier rules/005_Challenge_BattleRules.rb delete mode 100644 Data/Scripts/018_Alternate battle modes/002_BugContest.rb delete mode 100644 Data/Scripts/018_Alternate battle modes/003_Battle Frontier generator/001_ChallengeGenerator_Data.rb delete mode 100644 Data/Scripts/018_Alternate battle modes/003_Battle Frontier generator/002_ChallengeGenerator_Pokemon.rb delete mode 100644 Data/Scripts/018_Alternate battle modes/003_Battle Frontier generator/003_ChallengeGenerator_Trainers.rb delete mode 100644 Data/Scripts/018_Alternate battle modes/003_Battle Frontier generator/004_ChallengeGenerator_BattleSim.rb delete mode 100644 Data/Scripts/019_Utilities/001_Utilities.rb delete mode 100644 Data/Scripts/019_Utilities/002_Utilities_Pokemon.rb delete mode 100644 Data/Scripts/019_Utilities/003_Utilities_BattleAudio.rb delete mode 100644 Data/Scripts/020_Debug/001_Editor screens/001_EditorScreens.rb delete mode 100644 Data/Scripts/020_Debug/001_Editor screens/002_EditorScreens_TerrainTags.rb delete mode 100644 Data/Scripts/020_Debug/001_Editor screens/003_EditorScreens_MapConnections.rb delete mode 100644 Data/Scripts/020_Debug/001_Editor screens/004_EditorScreens_SpritePositioning.rb delete mode 100644 Data/Scripts/020_Debug/001_Editor_Utilities.rb delete mode 100644 Data/Scripts/020_Debug/002_Animation editor/001_AnimEditor_SceneElements.rb delete mode 100644 Data/Scripts/020_Debug/002_Animation editor/002_AnimEditor_ControlsButtons.rb delete mode 100644 Data/Scripts/020_Debug/002_Animation editor/003_AnimEditor_Interpolation.rb delete mode 100644 Data/Scripts/020_Debug/002_Animation editor/004_AnimEditor_ExportImport.rb delete mode 100644 Data/Scripts/020_Debug/002_Animation editor/005_AnimEditor_Functions.rb delete mode 100644 Data/Scripts/020_Debug/002_Editor_DataTypes.rb delete mode 100644 Data/Scripts/020_Debug/003_Debug menus/001_Debug_Menus.rb delete mode 100644 Data/Scripts/020_Debug/003_Debug menus/002_Debug_MenuCommands.rb delete mode 100644 Data/Scripts/020_Debug/003_Debug menus/003_Debug_MenuExtraCode.rb delete mode 100644 Data/Scripts/020_Debug/003_Debug menus/004_Debug_MenuSpriteRenamer.rb delete mode 100644 Data/Scripts/020_Debug/003_Debug menus/005_Debug_PokemonCommands.rb delete mode 100644 Data/Scripts/020_Debug/003_Editor_Listers.rb delete mode 100644 Data/Scripts/021_Compiler/001_Compiler.rb delete mode 100644 Data/Scripts/021_Compiler/002_Compiler_CompilePBS.rb delete mode 100644 Data/Scripts/021_Compiler/003_Compiler_WritePBS.rb delete mode 100644 Data/Scripts/021_Compiler/004_Compiler_MapsAndEvents.rb delete mode 100644 Data/Scripts/025-Randomizer/Random Pokemon.rb delete mode 100644 Data/Scripts/025-Randomizer/RandomizerSettings.rb delete mode 100644 Data/Scripts/025-Randomizer/RandomizerUtils.rb delete mode 100644 Data/Scripts/025-Randomizer/randomizer - encounters.rb delete mode 100644 Data/Scripts/025-Randomizer/randomizer gym leader edit.rb delete mode 100644 Data/Scripts/025-Randomizer/randomizer.rb delete mode 100644 Data/Scripts/048_Fusion/DoublePreviewScreen.rb delete mode 100644 Data/Scripts/048_Fusion/FusedSpecies.rb delete mode 100644 Data/Scripts/048_Fusion/FusionAnim.rb delete mode 100644 Data/Scripts/048_Fusion/FusionMenu.rb delete mode 100644 Data/Scripts/048_Fusion/FusionMovesMenu.rb delete mode 100644 Data/Scripts/048_Fusion/FusionPreviewScreen.rb delete mode 100644 Data/Scripts/048_Fusion/PokemonFusion.rb delete mode 100644 Data/Scripts/048_Fusion/SplitNames.rb delete mode 100644 Data/Scripts/048_Fusion/Sprites/001_PifSpriteBitmapCache.rb delete mode 100644 Data/Scripts/048_Fusion/Sprites/002_PIFSpriteExtracter.rb delete mode 100644 Data/Scripts/048_Fusion/Sprites/AutogenExtracter.rb delete mode 100644 Data/Scripts/048_Fusion/Sprites/BaseSpriteExtracter.rb delete mode 100644 Data/Scripts/048_Fusion/Sprites/BattleSpriteLoader.rb delete mode 100644 Data/Scripts/048_Fusion/Sprites/CustomSpriteExtracter.rb delete mode 100644 Data/Scripts/048_Fusion/Sprites/PIFSprite.rb delete mode 100644 Data/Scripts/048_Fusion/Sprites/SpritesSubstitutions.rb delete mode 100644 Data/Scripts/049_Compatibility/Constants.rb delete mode 100644 Data/Scripts/049_Compatibility/DeprecatedClasses.rb delete mode 100644 Data/Scripts/049_Compatibility/EggGroups.rb delete mode 100644 Data/Scripts/049_Compatibility/MarinUtilities.rb delete mode 100644 Data/Scripts/049_Compatibility/PBItems.rb delete mode 100644 Data/Scripts/049_Compatibility/PBMoves.rb delete mode 100644 Data/Scripts/049_Compatibility/PBSpecies.rb delete mode 100644 Data/Scripts/049_Compatibility/PBTrainers.rb delete mode 100644 Data/Scripts/049_Compatibility/UtilityMethods.rb delete mode 100644 Data/Scripts/049_Compatibility/pb_types.rb delete mode 100644 Data/Scripts/050_Outfits/001_OutfitsMain/LayeredClothes.rb delete mode 100644 Data/Scripts/050_Outfits/001_OutfitsMain/OutfitSelector.rb delete mode 100644 Data/Scripts/050_Outfits/001_OutfitsMain/OutfitsGlobal.rb delete mode 100644 Data/Scripts/050_Outfits/001_OutfitsMain/OutfitsSearch.rb delete mode 100644 Data/Scripts/050_Outfits/ItemSets.rb delete mode 100644 Data/Scripts/050_Outfits/OutfitIds.rb delete mode 100644 Data/Scripts/050_Outfits/UI/CharacterSelectMenu.rb delete mode 100644 Data/Scripts/050_Outfits/UI/CharacterSelectMenuPresenter.rb delete mode 100644 Data/Scripts/050_Outfits/UI/LayeredClothes_Menus.rb delete mode 100644 Data/Scripts/050_Outfits/UI/PokemonHatScreenPresenter.rb delete mode 100644 Data/Scripts/050_Outfits/UI/PokemonHatScreenView.rb delete mode 100644 Data/Scripts/050_Outfits/UI/TrainerClothesPreview.rb delete mode 100644 Data/Scripts/050_Outfits/UI/clothesShop/0_OutfitsMartAdapter.rb delete mode 100644 Data/Scripts/050_Outfits/UI/clothesShop/ClothesMartAdapter.rb delete mode 100644 Data/Scripts/050_Outfits/UI/clothesShop/ClothesShop.rb delete mode 100644 Data/Scripts/050_Outfits/UI/clothesShop/ClothesShopPresenter.rb delete mode 100644 Data/Scripts/050_Outfits/UI/clothesShop/ClothesShopPresenter_HatsMenu.rb delete mode 100644 Data/Scripts/050_Outfits/UI/clothesShop/ClothesShopView.rb delete mode 100644 Data/Scripts/050_Outfits/UI/clothesShop/HairMartAdapter.rb delete mode 100644 Data/Scripts/050_Outfits/UI/clothesShop/HairShopPresenter.rb delete mode 100644 Data/Scripts/050_Outfits/UI/clothesShop/HatShopView.rb delete mode 100644 Data/Scripts/050_Outfits/UI/clothesShop/HatsMartAdapter.rb delete mode 100644 Data/Scripts/050_Outfits/UI/hairMenu/HairStyleSelectionMenuView.rb delete mode 100644 Data/Scripts/050_Outfits/UI/hairMenu/HairstyleSelectionMenuPresenter.rb delete mode 100644 Data/Scripts/050_Outfits/utils/OutfitFilenameUtils.rb delete mode 100644 Data/Scripts/050_Outfits/utils/OutfitsGameplayUtils.rb delete mode 100644 Data/Scripts/050_Outfits/wrappers/001_Outfit.rb delete mode 100644 Data/Scripts/050_Outfits/wrappers/Clothes.rb delete mode 100644 Data/Scripts/050_Outfits/wrappers/Hairstyle.rb delete mode 100644 Data/Scripts/050_Outfits/wrappers/Hat.rb delete mode 100644 Data/Scripts/051_Wrappers/quest_reward.rb delete mode 100644 Data/Scripts/051_Wrappers/type_expert.rb delete mode 100644 Data/Scripts/052_AddOns/AttributeReader.rb delete mode 100644 Data/Scripts/052_AddOns/Autosave.rb delete mode 100644 Data/Scripts/052_AddOns/BattleLounge.rb delete mode 100644 Data/Scripts/052_AddOns/BetterRegionMap.rb delete mode 100644 Data/Scripts/052_AddOns/CustomTrainers.rb delete mode 100644 Data/Scripts/052_AddOns/DevUtils.rb delete mode 100644 Data/Scripts/052_AddOns/DisplayText.rb delete mode 100644 Data/Scripts/052_AddOns/DoubleAbilities.rb delete mode 100644 Data/Scripts/052_AddOns/DoubleAbilitiesHandlersOverrides.rb delete mode 100644 Data/Scripts/052_AddOns/DoubleAbilities_UI.rb delete mode 100644 Data/Scripts/052_AddOns/EggMoveTutor.rb delete mode 100644 Data/Scripts/052_AddOns/ExperimentalOptions.rb delete mode 100644 Data/Scripts/052_AddOns/ExportScripts.rb delete mode 100644 Data/Scripts/052_AddOns/Footprints.rb delete mode 100644 Data/Scripts/052_AddOns/FusionMoveTutor.rb delete mode 100644 Data/Scripts/052_AddOns/FusionSprites.rb delete mode 100644 Data/Scripts/052_AddOns/FusionUtils.rb delete mode 100644 Data/Scripts/052_AddOns/GameOptions.rb delete mode 100644 Data/Scripts/052_AddOns/GameplayUtils.rb delete mode 100644 Data/Scripts/052_AddOns/Gen 2.rb delete mode 100644 Data/Scripts/052_AddOns/GeneralUtils.rb delete mode 100644 Data/Scripts/052_AddOns/GuessPokemonQuiz.rb delete mode 100644 Data/Scripts/052_AddOns/HiddenAbilityMaps.rb delete mode 100644 Data/Scripts/052_AddOns/HttpCalls.rb delete mode 100644 Data/Scripts/052_AddOns/IntroScreen.rb delete mode 100644 Data/Scripts/052_AddOns/MapExporter.rb delete mode 100644 Data/Scripts/052_AddOns/Movie.rb delete mode 100644 Data/Scripts/052_AddOns/MultiSaves.rb delete mode 100644 Data/Scripts/052_AddOns/New Balls.rb delete mode 100644 Data/Scripts/052_AddOns/New HMs.rb delete mode 100644 Data/Scripts/052_AddOns/New Items effects.rb delete mode 100644 Data/Scripts/052_AddOns/NonMoneyShop.rb delete mode 100644 Data/Scripts/052_AddOns/OnlineWondertrade.rb delete mode 100644 Data/Scripts/052_AddOns/Overrides.rb delete mode 100644 Data/Scripts/052_AddOns/OverworldShadows.rb delete mode 100644 Data/Scripts/052_AddOns/Pathfinding.rb delete mode 100644 Data/Scripts/052_AddOns/PokedexUtils.rb delete mode 100644 Data/Scripts/052_AddOns/PokemonSelection.rb delete mode 100644 Data/Scripts/052_AddOns/PoliceQuest.rb delete mode 100644 Data/Scripts/052_AddOns/QuestIcons.rb delete mode 100644 Data/Scripts/052_AddOns/QuestLogScript.rb delete mode 100644 Data/Scripts/052_AddOns/RandomAddOns.rb delete mode 100644 Data/Scripts/052_AddOns/ShinyColorOffsets.rb delete mode 100644 Data/Scripts/052_AddOns/Silhouette.rb delete mode 100644 Data/Scripts/052_AddOns/SpeechBubbles.rb delete mode 100644 Data/Scripts/052_AddOns/Spped Up.rb delete mode 100644 Data/Scripts/052_AddOns/SpriteCreditsUtils.rb delete mode 100644 Data/Scripts/052_AddOns/TRQuests.rb delete mode 100644 Data/Scripts/052_AddOns/TeamFlags.rb delete mode 100644 Data/Scripts/052_AddOns/TempEvents.rb delete mode 100644 Data/Scripts/052_AddOns/TrainerCardBackgrounds.rb delete mode 100644 Data/Scripts/052_AddOns/TrainerGeneratorUtils.rb delete mode 100644 Data/Scripts/052_AddOns/Trainers Rebattle.rb delete mode 100644 Data/Scripts/052_AddOns/TripleFusion.rb delete mode 100644 Data/Scripts/052_AddOns/UI_Pokedex_SpritesPage.rb delete mode 100644 Data/Scripts/052_AddOns/UnrealTime.rb delete mode 100644 Data/Scripts/052_AddOns/WaterEffect.rb delete mode 100644 Data/Scripts/052_AddOns/WonderTrade_names.rb delete mode 100644 Data/Scripts/052_AddOns/Wondertrade.rb delete mode 100644 Data/Scripts/052_AddOns/dynamic_waterfall.rb delete mode 100644 Data/Scripts/052_AddOns/k_scriptsUtils.rb delete mode 100644 Data/Scripts/052_AddOns/mapExporter2.rb delete mode 100644 Data/Scripts/052_AddOns/mapExporter2_ui.rb delete mode 100644 Data/Scripts/052_AddOns/platform.rb delete mode 100644 Data/Scripts/052_Tests/FusionUtilsTests.rb delete mode 100644 Data/Scripts/999_Main/999_Main.rb delete mode 100644 Data/Scripts/DownloadedSettings.rb diff --git a/Data/Scripts/001_Settings.rb b/Data/Scripts/001_Settings.rb deleted file mode 100644 index f0fd87f8f..000000000 --- a/Data/Scripts/001_Settings.rb +++ /dev/null @@ -1,640 +0,0 @@ -#==============================================================================# -# Pokémon Essentials # -# Version 19.1.dev # -# https://github.com/Maruno17/pokemon-essentials # -#==============================================================================# -module Settings - # The version of your game. It has to adhere to the MAJOR.MINOR.PATCH format. - GAME_VERSION = '6.5.1' - GAME_VERSION_NUMBER = "6.5.1" - LATEST_GAME_RELEASE = "6.5" - - POKERADAR_LIGHT_ANIMATION_RED_ID = 17 - POKERADAR_LIGHT_ANIMATION_GREEN_ID = 18 - POKERADAR_HIDDEN_ABILITY_POKE_CHANCE = 32 - POKERADAR_BATTERY_STEPS = 0 - - LEADER_VICTORY_MUSIC="Battle victory leader" - TRAINER_VICTORY_MUSIC="trainer-victory" - WILD_VICTORY_MUSIC="wild-victory" - #getRandomCustomFusionForIntro - FUSION_ICON_SPRITE_OFFSET = 10 - - #Infinite fusion settings - NB_POKEMON = 501 - CUSTOM_BASE_SPRITES_FOLDER = "Graphics/CustomBattlers/local_sprites/BaseSprites/" - CUSTOM_BATTLERS_FOLDER = "Graphics/CustomBattlers/" - CUSTOM_SPRITES_TO_IMPORT_FOLDER = "Graphics/CustomBattlers/Sprites to import/" - CUSTOM_BATTLERS_FOLDER_INDEXED = "Graphics/CustomBattlers/local_sprites/indexed/" - CUSTOM_BASE_SPRITE_FOLDER = "Graphics/CustomBattlers/local_sprites/BaseSprites/" - BATTLERS_FOLDER = "Graphics/Battlers/Autogens/" - DOWNLOADED_SPRITES_FOLDER = "Graphics/temp/" - DEFAULT_SPRITE_PATH = "Graphics/Battlers/Special/000.png" - CREDITS_FILE_PATH = "Data/sprites/Sprite Credits.csv" - VERSION_FILE_PATH = "Data/VERSION" - CUSTOM_SPRITES_FILE_PATH = "Data/sprites/CUSTOM_SPRITES" - BASE_SPRITES_FILE_PATH = "Data/sprites/BASE_SPRITES" - CUSTOM_DEX_ENTRIES_PATH = "Data/pokedex/dex.json" - AI_DEX_ENTRIES_PATH = "Data/pokedex/generated_entries.json" - POKEDEX_ENTRIES_PATH = "Data/pokedex/all_entries.json" - - UPDATED_SPRITESHEETS_CACHE = "Data/sprites/updated_spritesheets_cache" - - BACK_ITEM_ICON_PATH = "Graphics/Items/back.png" - - PLAYER_GRAPHICS_FOLDER = "Graphics/Characters/player/" - PLAYER_HAT_FOLDER = 'hat' - PLAYER_HAIR_FOLDER = 'hair' - PLAYER_CLOTHES_FOLDER = 'clothes' - PLAYER_BALL_FOLDER = 'balls' - PLAYER_TEMP_OUTFIT_FALLBACK = 'temp' - - - HATS_DATA_PATH = "Data/outfits/hats_data.json" - HAIRSTYLE_DATA_PATH = "Data/outfits/hairstyles_data.json" - CLOTHES_DATA_PATH = "Data/outfits/clothes_data.json" - - PLAYER_SURFBASE_FOLDER = 'surf_base/' - OW_SHINE_ANIMATION_ID=25 - - HTTP_CONFIGS_FILE_URL = "https://raw.githubusercontent.com/infinitefusion/pif-downloadables/refs/heads/master/Settings.rb" - HTTP_CONFIGS_FILE_PATH = "Data/Scripts/DownloadedSettings.rb" - - SPRITES_FILE_URL = "https://raw.githubusercontent.com/infinitefusion/infinitefusion-e18/main/Data/sprites/CUSTOM_SPRITES" - BASE_SPRITES_FILE_URL = "https://raw.githubusercontent.com/infinitefusion/infinitefusion-e18/main/Data/sprites/BASE_SPRITES" - - CREDITS_FILE_URL = "https://infinitefusion.net/Sprite Credits.csv" - CUSTOM_DEX_FILE_URL = "https://raw.githubusercontent.com/infinitefusion/pif-downloadables/refs/heads/master/dex.json" - - STARTUP_MESSAGES = "" - - LEVEL_CAPS=[12,22,26,35,38,45,51,54,62,62,63,64,64,65,67,68] - - CUSTOM_ENTRIES_NAME_PLACEHOLDER = "POKENAME" - - DEFAULT_SPEED_UP_SPEED=2 - FRONTSPRITE_POSITION_OFFSET = 20 - FRONTSPRITE_SCALE = 0.6666666666666666 - BACKRPSPRITE_SCALE = 1 - EGGSPRITE_SCALE = 1 - BACKSPRITE_POSITION_OFFSET = 20 - FRONTSPRITE_POSITION = 200 - SHINY_HUE_OFFSET = 75 - NO_LEVEL_MODE_LEVEL_INCR = 5.8 - NO_LEVEL_MODE_LEVEL_BASE = 6 - - SAVEFILE_NB_BACKUPS=10 - - DISCORD_URL = "https://discord.com/invite/infinitefusion" - WIKI_URL = "https://infinitefusion.fandom.com/" - - AI_ENTRIES_URL = "https://ai-entries.pkmninfinitefusion.workers.dev/" - AI_ENTRIES_RATE_MAX_NB_REQUESTS = 10 #Nb. requests allowed in each time window - AI_ENTRIES_RATE_TIME_WINDOW = 120 # In seconds - AI_ENTRIES_RATE_LOG_FILE = 'Data/pokedex/dex_rate_limit.log' # Path to the log file - - CUSTOMSPRITES_RATE_MAX_NB_REQUESTS = 15 #Nb. requests allowed in each time window - CUSTOMSPRITES_ENTRIES_RATE_TIME_WINDOW = 120 # In seconds - CUSTOMSPRITES_RATE_LOG_FILE = 'Data/sprites/sprites_rate_limit.log' # Path to the log file - MAX_NB_SPRITES_TO_DOWNLOAD_AT_ONCE=5 - - CUSTOM_SPRITES_REPO_URL = "https://bitbucket.org/infinitefusionsprites/customsprites/raw/main/CustomBattlers/" - CUSTOM_SPRITES_NEW_URL = "https://infinitefusion.net/CustomBattlers/" - - BASE_POKEMON_ALT_SPRITES_REPO_URL = "https://bitbucket.org/infinitefusionsprites/customsprites/raw/main/Other/BaseSprites/" - BASE_POKEMON_ALT_SPRITES_NEW_URL = "https://infinitefusion.net/Other/BaseSprites/" - - BASE_POKEMON_SPRITESHEET_URL = "https://infinitefusion.net/spritesheets/spritesheets_base/" - CUSTOM_FUSIONS_SPRITESHEET_URL = "https://infinitefusion.net/spritesheets/spritesheets_custom/" - - BASE_POKEMON_SPRITESHEET_TRUE_SIZE_URL = "" - CUSTOM_FUSIONS_SPRITESHEET_TRUE_SIZE_URL = "" - - RIVAL_STARTER_PLACEHOLDER_SPECIES = :MEW #(MEW) - VAR_1_PLACEHOLDER_SPECIES = :DIALGA - VAR_2_PLACEHOLDER_SPECIES = :PALKIA - VAR_3_PLACEHOLDER_SPECIES = :GIRATINA - - RIVAL_STARTER_PLACEHOLDER_VARIABLE = 250 - - OVERRIDE_BATTLE_LEVEL_SWITCH = 785 - OVERRIDE_BATTLE_LEVEL_VALUE_VAR = 240 - HARD_MODE_LEVEL_MODIFIER = 1.1 - - ZAPMOLCUNO_NB = 999999#176821 - MAPS_WITHOUT_SURF_MUSIC = [762] - - WONDERTRADE_BASE_URL = "http://localhost:8080" - WONDERTRADE_PUBLIC_KEY = "http://localhost:8080" - - MAX_NB_OUTFITS=99 - - OUTFIT_PREVIEW_PICTURE_ID=20 - - DEFAULT_TRAINER_CARD_BG="BLUE" - - # The generation that the battle system follows. Used throughout the battle - # scripts, and also by some other settings which are used in and out of battle - # (you can of course change those settings to suit your game). - # Note that this isn't perfect. Essentials doesn't accurately replicate every - # single generation's mechanics. It's considered to be good enough. Only - # generations 5 and later are reasonably supported. - MECHANICS_GENERATION = 5 - - #============================================================================= - - # The default screen width (at a scale of 1.0). - SCREEN_WIDTH = 512 - # The default screen height (at a scale of 1.0). - SCREEN_HEIGHT = 384 - # The default screen scale factor. Possible values are 0.5, 1.0, 1.5 and 2.0. - SCREEN_SCALE = 1.0 - - FADEOUT_SPEED = 0.2 - - #============================================================================= - - # The maximum level Pokémon can reach. - MAXIMUM_LEVEL = 100 - # The level of newly hatched Pokémon. - EGG_LEVEL = 1 - # Number of badges in the game - NB_BADGES = 16 - # The odds of a newly generated Pokémon being shiny (out of 65536). - SHINY_POKEMON_CHANCE = 16#(MECHANICS_GENERATION >= 6) ? 16 : 8 - - # The odds of a wild Pokémon/bred egg having Pokérus (out of 65536). - POKERUS_CHANCE = 3 - # Whether a bred baby Pokémon can inherit any TM/HM moves from its father. It - # can never inherit TM/HM moves from its mother. - BREEDING_CAN_INHERIT_MACHINE_MOVES = (MECHANICS_GENERATION <= 5) - # Whether a bred baby Pokémon can inherit egg moves from its mother. It can - # always inherit egg moves from its father. - BREEDING_CAN_INHERIT_EGG_MOVES_FROM_MOTHER = (MECHANICS_GENERATION >= 6) - - KANTO_STARTERS = [:BULBASAUR, :CHARMANDER, :SQUIRTLE] - JOHTO_STARTERS = [:CHIKORITA, :CYNDAQUIL, :TOTODILE] - HOENN_STARTERS = [:TREECKO, :TORCHIC, :MUDKIP] - SINNOH_STARTERS = [:TURTWIG, :CHIMCHAR, :PIPLUP] - KALOS_STARTERS = [:CHESPIN, :FENNEKIN, :FROAKIE] - - - #============================================================================= - - # The amount of money the player starts the game with. - INITIAL_MONEY = 3000 - # The maximum amount of money the player can have. - MAX_MONEY = 999_999 - # The maximum number of Game Corner coins the player can have. - MAX_COINS = 99_999 - # The maximum number of Battle Points the player can have. - MAX_BATTLE_POINTS = 9_999 - # The maximum amount of soot the player can have. - MAX_SOOT = 9_999 - # The maximum length, in characters, that the player's name can be. - MAX_PLAYER_NAME_SIZE = 10 - # The maximum number of Pokémon that can be in the party. - MAX_PARTY_SIZE = 6 - - #============================================================================= - - # A set of arrays each containing a trainer type followed by a Global Variable - # number. If the variable isn't set to 0, then all trainers with the - # associated trainer type will be named as whatever is in that variable. - RIVAL_NAMES = [ - [:RIVAL1, 12], - [:RIVAL2, 12], - [:CHAMPION, 12] - ] - - #============================================================================= - - # Whether outdoor maps should be shaded according to the time of day. - TIME_SHADING = true - - #============================================================================= - - # Whether poisoned Pokémon will lose HP while walking around in the field. - POISON_IN_FIELD = true #(MECHANICS_GENERATION <= 4) - # Whether poisoned Pokémon will faint while walking around in the field - # (true), or survive the poisoning with 1 HP (false). - POISON_FAINT_IN_FIELD = (MECHANICS_GENERATION >= 3) - # Whether planted berries grow according to Gen 4 mechanics (true) or Gen 3 - # mechanics (false). - NEW_BERRY_PLANTS = (MECHANICS_GENERATION >= 4) - # Whether fishing automatically hooks the Pokémon (true), or whether there is - # a reaction test first (false). - FISHING_AUTO_HOOK = false - # The ID of the common event that runs when the player starts fishing (runs - # instead of showing the casting animation). - FISHING_BEGIN_COMMON_EVENT = -1 - # The ID of the common event that runs when the player stops fishing (runs - # instead of showing the reeling in animation). - FISHING_END_COMMON_EVENT = -1 - - #============================================================================= - - # The number of steps allowed before a Safari Zone game is over (0=infinite). - SAFARI_STEPS = 600 - # The number of seconds a Bug Catching Contest lasts for (0=infinite). - BUG_CONTEST_TIME = 20 * 60 # 20 minutes - - #============================================================================= - - # Pairs of map IDs, where the location signpost isn't shown when moving from - # one of the maps in a pair to the other (and vice versa). Useful for single - # long routes/towns that are spread over multiple maps. - # e.g. [4,5,16,17,42,43] will be map pairs 4,5 and 16,17 and 42,43. - # Moving between two maps that have the exact same name won't show the - # location signpost anyway, so you don't need to list those maps here. - NO_SIGNPOSTS = [] - - #============================================================================= - - # Whether you need at least a certain number of badges to use some hidden - # moves in the field (true), or whether you need one specific badge to use - # them (false). The amounts/specific badges are defined below. - FIELD_MOVES_COUNT_BADGES = true - # Depending on FIELD_MOVES_COUNT_BADGES, either the number of badges required - # to use each hidden move in the field, or the specific badge number required - # to use each move. Remember that badge 0 is the first badge, badge 1 is the - # second badge, etc. - # e.g. To require the second badge, put false and 1. - # To require at least 2 badges, put true and 2. - BADGE_FOR_CUT = 1 - BADGE_FOR_FLASH = 1 - BADGE_FOR_ROCKSMASH = 0 - BADGE_FOR_SURF = 6 - BADGE_FOR_FLY = 3 - BADGE_FOR_STRENGTH = 5 - BADGE_FOR_DIVE = 9 - BADGE_FOR_WATERFALL = 9 - BADGE_FOR_TELEPORT = 3 - BADGE_FOR_BOUNCE = 8 - BADGE_FOR_ROCKCLIMB = 16 - #============================================================================= - - # If a move taught by a TM/HM/TR replaces another move, this setting is - # whether the machine's move retains the replaced move's PP (true), or whether - # the machine's move has full PP (false). - TAUGHT_MACHINES_KEEP_OLD_PP = (MECHANICS_GENERATION == 5) - # Whether the Black/White Flutes will raise/lower the levels of wild Pokémon - # respectively (true), or will lower/raise the wild encounter rate - # respectively (false). - FLUTES_CHANGE_WILD_ENCOUNTER_LEVELS = (MECHANICS_GENERATION >= 6) - # Whether Repel uses the level of the first Pokémon in the party regardless of - # its HP (true), or it uses the level of the first unfainted Pokémon (false). - REPEL_COUNTS_FAINTED_POKEMON = (MECHANICS_GENERATION >= 6) - # Whether Rage Candy Bar acts as a Full Heal (true) or a Potion (false). - RAGE_CANDY_BAR_CURES_STATUS_PROBLEMS = (MECHANICS_GENERATION >= 7) - - #============================================================================= - - # The name of the person who created the Pokémon storage system. - def self.storage_creator_name - return _INTL("Bill") - end - - # The number of boxes in Pokémon storage. - NUM_STORAGE_BOXES = 40 - - #============================================================================= - - # The names of each pocket of the Bag. Ignore the first entry (""). - def self.bag_pocket_names - return ["", - _INTL("Items"), - _INTL("Medicine"), - _INTL("Poké Balls"), - _INTL("TMs & HMs"), - _INTL("Berries"), - _INTL("Mail"), - _INTL("Battle Items"), - _INTL("Key Items") - ] - end - - # The maximum number of slots per pocket (-1 means infinite number). Ignore - # the first number (0). - BAG_MAX_POCKET_SIZE = [0, -1, -1, -1, -1, -1, -1, -1, -1] - # The maximum number of items each slot in the Bag can hold. - BAG_MAX_PER_SLOT = 999 - # Whether each pocket in turn auto-sorts itself by item ID number. Ignore the - # first entry (the 0). - BAG_POCKET_AUTO_SORT = [0, false, false, false, true, true, false, false, false] - - #============================================================================= - - # Whether the Pokédex list shown is the one for the player's current region - # (true), or whether a menu pops up for the player to manually choose which - # Dex list to view if more than one is available (false). - USE_CURRENT_REGION_DEX = false - # The names of the Pokédex lists, in the order they are defined in the PBS - # file "regionaldexes.txt". The last name is for the National Dex and is added - # onto the end of this array (remember that you don't need to use it). This - # array's order is also the order of $Trainer.pokedex.unlocked_dexes, which - # records which Dexes have been unlocked (the first is unlocked by default). - # If an entry is just a name, then the region map shown in the Area page while - # viewing that Dex list will be the region map of the region the player is - # currently in. The National Dex entry should always behave like this. - # If an entry is of the form [name, number], then the number is a region - # number. That region's map will appear in the Area page while viewing that - # Dex list, no matter which region the player is currently in. - def self.pokedex_names - return [ - # [_INTL("Kanto Pokédex"), 0] - ] - end - - # Whether all forms of a given species will be immediately available to view - # in the Pokédex so long as that species has been seen at all (true), or - # whether each form needs to be seen specifically before that form appears in - # the Pokédex (false). - DEX_SHOWS_ALL_FORMS = false - # An array of numbers, where each number is that of a Dex list (in the same - # order as above, except the National Dex is -1). All Dex lists included here - # will begin their numbering at 0 rather than 1 (e.g. Victini in Unova's Dex). - DEXES_WITH_OFFSETS = [] - - - #============================================================================= - - # A set of arrays, each containing details of a graphic to be shown on the - # region map if appropriate. The values for each array are as follows: - # * Region number. - # * Game Switch; the graphic is shown if this is ON (non-wall maps only). - # * X coordinate of the graphic on the map, in squares. - # * Y coordinate of the graphic on the map, in squares. - # * Name of the graphic, found in the Graphics/Pictures folder. - # * The graphic will always (true) or never (false) be shown on a wall map. - REGION_MAP_EXTRAS = [ - #[0, 51, 16, 15, "mapHiddenBerth", false], - #[0, 52, 20, 14, "mapHiddenFaraday", false] - ] - - TRIPLE_TYPES = [:QMARKS,:ICEFIREELECTRIC,:FIREWATERELECTRIC,:WATERGROUNDFLYING,:GHOSTSTEELWATER, - :FIREWATERGRASS,:GRASSSTEEL,:BUGSTEELPSYCHIC,:ICEROCKSTEEL] - - #============================================================================= - - # A list of maps used by roaming Pokémon. Each map has an array of other maps - # it can lead to. - ROAMING_AREAS = { - 262 => [261,311], - 311 => [262,312], - 312 => [311], - 261 => [262,288,267], - 288 => [261,267,285], - 267 => [261,288,300,254], - 284 => [288,266,285], - 300 => [267,254], - 254 => [300,265], - 266 => [284,265], - 265 => [266,254], - 285 => [284,288]} - - SEVII_ROAMING = { - 528 => [526], #Treasure beach - 526 => [528,559], #Knot Island - 559 => [526,561,564], #Kindle Road - 561 => [559], #Mt. Ember - 564 => [559,562,563,594], #brine road - 562 => [564], #boon island - 563 => [564,600] , #kin island - 594 => [564,566,603], #water labyrinth - 600 => [563,619], #bond bridge - 619 => [600] , #Berry forest - 566 => [594,603], #Resort gorgeous - 603 => [566,594], #Chrono Island - } - # A set of arrays, each containing the details of a roaming Pokémon. The - # information within each array is as follows: - # * Species. - # * Level. - # * Game Switch; the Pokémon roams while this is ON. - # * Encounter type (0=any, 1=grass/walking in cave, 2=surfing, 3=fishing, - # 4=surfing/fishing). See the bottom of PField_RoamingPokemon for lists. - # * Name of BGM to play for that encounter (optional). - # * Roaming areas specifically for this Pokémon (optional). - ROAMING_SPECIES = [ - [:ENTEI, 50, 350, 1, "Legendary Birds",ROAMING_AREAS,:Sunny], - [:B245H243, 50, 341, 1, "Legendary Birds",ROAMING_AREAS,:Storm], - [:B379H378, 50, 602, 0, "Legendary Birds",SEVII_ROAMING,:StrongWinds], - [:B378H379, 50, 602, 0, "Legendary Birds",SEVII_ROAMING,:StrongWinds], - [:FEEBAS, 15, 4, 3, "Pokemon HeartGold and SoulSilver - Wild Pokemon Battle (Kanto)",SEVII_ROAMING,:Rain] - ] - - PINKAN_ISLAND_MAPS=[51,46,428,531] - - #============================================================================= - - # A set of arrays, each containing the details of a wild encounter that can - # only occur via using the Poké Radar. The information within each array is as - # follows: - # * Map ID on which this encounter can occur. - # * Probability that this encounter will occur (as a percentage). - # * Species. - # * Minimum possible level. - # * Maximum possible level (optional). - POKE_RADAR_ENCOUNTERS = [ - [78, 50, :FLETCHLING,2,5], #Rt. 1 - [86, 50, :FLETCHLING,2,5], #Rt. 2 - [90, 50, :FLETCHLING,2,5], #Rt. 2 - [491, 50, :SHROOMISH,2,5], #Viridian Forest - [490, 50, :BUDEW,4,9], #Rt. 3 - [106, 50, :NINCADA,8,10], #Rt. 4 - [12, 50, :TOGEPI,10,10], #Rt. 5 - [16, 50, :SLAKOTH,12,15], #Rt. 6 - [413, 50, :DRIFLOON,17,20], #Rt. 7 - [409, 50, :SHINX,17,18], #Rt. 8 - [495, 50, :ARON,12,15], #Rt. 9 - [351, 50, :ARON,12,15], #Rt. 9 - [154, 50, :KLINK,14,17], #Rt. 10 - [155, 50, :NINCADA,12,15], #Rt. 11 - [159, 50, :COTTONEE,22,25], #Rt. 12 - [437, 50, :COTTONEE,22,25], #Rt. 13 - [437, 50, :JOLTIK,22,25], #Rt. 13 - [440, 50, :JOLTIK,22,25], #Rt. 14 - [444, 50, :SOLOSIS,22,25], #Rt. 15 - [438, 50, :NATU,22,25], #Rt. 16 - [146, 50, :KLEFKI,22,25], #Rt. 17 - [517, 50, :FERROSEED,22,25], #Rt. 18 - [445, 50, :BAGON,20,20], #Safari zone 1 - [484, 50, :AXEW,20,20], #Safari zone 2 - [485, 50, :DEINO,20,20], #Safari zone 3 - [486, 50, :LARVITAR,20,20], #Safari zone 4 - [487, 50, :JANGMOO,20,20], #Safari zone 5 - [59, 50, :DUNSPARCE,25,30], #Rt. 21 - [171, 50, :BIDOOF,2,5], #Rt. 22 - [143, 50, :RIOLU,25,25], #Rt. 23 - [8, 50, :BUNEARY,12,13], #Rt. 24 - [145, 50, :ABSOL,30,35], #Rt. 26 - [147, 50, :ABSOL,30,35], #Rt. 27 - [311, 50, :BIDOOF,5,5], #Rt. 29 - [284, 50, :LUXIO,40,45], #Rt. 33 - [288, 50, :VIGOROTH,40,45], #Rt. 32 - [342, 50, :GOLETT,40,45], #Ruins of Alph - [261, 50, :BELLOSSOM,45,50], #Rt. 31 - [262, 50, :BIBAREL,45,50], #Rt. 30 - [265, 50, :KIRLIA,25,30], #Rt. 34 - [254, 50, :SMEARGLE,25,30], #Rt. 35 - [267, 50, :SUDOWOODO,25,30], #Rt. 36 - [500, 50, :FOMANTIS,30,30], #National Park - [266, 50, :BRELOOM,30,30], #Ilex Forest - [670, 50, :WEAVILE,50,50], #Ice mountains - [528, 50, :PYUKUMUKU,20,20], #Treasure Beach - [690, 50, :OCTILLERY,32,45], #Deep Ocean - [561, 50, :FLETCHINDER,32,45], #Mt. Ember - [562, 50, :NINJASK,45,50], #Boon Island - [603, 50, :KECLEON,45,50], #Chrono Island - [654, 50, :WHIMSICOTT,32,45], #Brine Road - [559, 50, :SCRAGGY,32,45] #Kindle Road - ] - - #============================================================================= - - # The Game Switch that is set to ON when the player blacks out. - STARTING_OVER_SWITCH = 1 - # The Game Switch that is set to ON when the player has seen Pokérus in the - # Poké Center (and doesn't need to be told about it again). - SEEN_POKERUS_SWITCH = 2 - # The Game Switch which, while ON, makes all wild Pokémon created be shiny. - SHINY_WILD_POKEMON_SWITCH = 31 - # The Game Switch which, while ON, makes all Pokémon created considered to be - # met via a fateful encounter. - FATEFUL_ENCOUNTER_SWITCH = 32 - - #============================================================================= - - # ID of the animation played when the player steps on grass (grass rustling). - GRASS_ANIMATION_ID = 1 - # ID of the animation played when the player lands on the ground after hopping - # over a ledge (shows a dust impact). - DUST_ANIMATION_ID = 2 - # ID of the animation played when a trainer notices the player (an exclamation - # bubble). - EXCLAMATION_ANIMATION_ID = 3 - # ID of the animation played when a patch of grass rustles due to using the - # Poké Radar. - RUSTLE_NORMAL_ANIMATION_ID = 1 - # ID of the animation played when a patch of grass rustles vigorously due to - # using the Poké Radar. (Rarer species) - RUSTLE_VIGOROUS_ANIMATION_ID = 5 - # ID of the animation played when a patch of grass rustles and shines due to - # using the Poké Radar. (Shiny encounter) - RUSTLE_SHINY_ANIMATION_ID = 6 - # ID of the animation played when a berry tree grows a stage while the player - # is on the map (for new plant growth mechanics only). - PLANT_SPARKLE_ANIMATION_ID = 7 - SLEEP_ANIMATION_ID = 26 - - CUT_TREE_ANIMATION_ID = 19 - ROCK_SMASH_ANIMATION_ID = 20 - - #============================================================================= - - # An array of available languages in the game, and their corresponding message - # file in the Data folder. Edit only if you have 2 or more languages to choose - # from. - LANGUAGES = [ - # ["English", "english.dat"], - # ["Deutsch", "deutsch.dat"] - ] - - - #Technical - SPRITE_CACHE_MAX_NB=100 - NEWEST_SPRITEPACK_MONTH = 12 - NEWEST_SPRITEPACK_YEAR = 2020 - #============================================================================= - - # Available speech frames. These are graphic files in "Graphics/Windowskins/". - SPEECH_WINDOWSKINS = [ - "speech hgss 1", - "speech hgss 2", - "speech hgss 3", - "speech hgss 4", - "speech hgss 5", - "speech hgss 6", - "speech hgss 7", - "speech hgss 8", - "speech hgss 9", - "speech hgss 10", - "speech hgss 11", - "speech hgss 12", - "speech hgss 13", - "speech hgss 14", - "speech hgss 15", - "speech hgss 16", - "speech hgss 17", - "speech hgss 18", - "speech hgss 19", - "speech hgss 20", - "speech pl 18" - ] - - # Available menu frames. These are graphic files in "Graphics/Windowskins/". - MENU_WINDOWSKINS = [ - "default_transparent", - "default_opaque", - "choice 2", - "choice 3", - "choice 4", - "choice 5", - "choice 6", - "choice 7", - "choice 8", - "choice 9", - "choice 10", - "choice 11", - "choice 12", - "choice 13", - "choice 14", - "choice 15", - "choice 16", - "choice 17", - "choice 18", - "choice 19", - "choice 20", - "choice 21", - "choice 22", - "choice 23", - "choice 24", - "choice 25", - "choice 26", - "choice 27", - "choice 28" - ] - - - RANDOMIZED_GYM_TYPE_TM= - { - :NORMAL => [:TM32,:TM49,:TM42,:TM98], #DOUBLETEAM ECHOEDVOICE FACADE BATONPASS - :FIGHTING => [:TM83,:TM115,:TM52,:TM112], #WORKUP POWERUPPUNCH FOCUSBLAST FOCUSPUNCH - :FLYING => [:TM62,:TM58,:TM108,:TM100], #ACROBATICS SKYDROP SKYATTACK DEFOG - :POISON => [:TM84,:TM06,:TM36,:TM34], #POISONJAB TOXIC SLUDGEBOMB SLUDGEWAVE - :GROUND => [:TM28,:TM78,:TM26,:TM119], #DIG BULLDOZE EARTHQUAKE STOMPINGTANTRUM - :ROCK => [:TM39,:TM80,:TM71,:TM69], #ROCKTOMB ROCKTHROW STONEDGE ROCKPOLISH - :BUG => [:TM76,:TM89,:TM113,:TM99], #STRUGGLEBUG UTURN INFESTATION QUIVERDANCE - :GHOST => [:TM85,:TM65,:TM30,:TM97], #DREAMEATER SHADOWCLAW SHADOWBALL NASTYPLOT - :STEEL => [:TM74,:TM118,:TM117,:TM75], # GYROBALL STEELWING SMARTSTRIKE SWORDDANCE - :FIRE => [:TM11,:TM43,:TM38,:TM61], #SUNNYDAY FLAMECHARGE FIREBLAST WILLOWISP - :WATER => [:TM55,:TM105,:TM121,:TM18], #WATERPULSE AQUAJET SCALD RAINDANCE - :GRASS => [:TM22,:TM53,:TM86,:TM102], # SOLARBEAM ENERGYBALL GRASSKNOT SPORE - :ELECTRIC => [:TM73,:TM116,:TM93,:TM72], #THUNDERWAVE SHOCKWAVE WILDCHARGE VOLTSWITCH - :PSYCHIC => [:TM77,:TM03,:TM29,:TM04], #PSYCHUP PSYSHOCK PSYCHIC CALMMIND - :ICE => [:TM110,:TM13,:TM14,:TM07], #AURORAVEIL ICEBEAM BLIZZARD HAIL - :DRAGON => [:TM95,:TM02,:TM82,:TM101], #SNARL DRAGONCLAW DRAGONTAIL DRAGONDANCE - :DARK => [:TM95,:TM46,:TM120,:TM97], #SNARL THIEF THROATCHOP NASTYPLOT - :FAIRY => [:TM45,:TM111,:TM96,:TM104] #ATTRACT DAZZLINGGLEAM MOONBLAST RECOVER - } - - EXCLUDE_FROM_RANDOM_SHOPS=[:RARECANDY] - -end - -# DO NOT EDIT THESE! -module Essentials - VERSION = "19.1.dev" - ERROR_TEXT = "" -end diff --git a/Data/Scripts/001_Technical/001_Debugging/001_PBDebug.rb b/Data/Scripts/001_Technical/001_Debugging/001_PBDebug.rb deleted file mode 100644 index dc7e7e91d..000000000 --- a/Data/Scripts/001_Technical/001_Debugging/001_PBDebug.rb +++ /dev/null @@ -1,40 +0,0 @@ -module PBDebug - @@log = [] - - def self.logonerr - begin - yield - rescue - PBDebug.log("") - PBDebug.log("**Exception: #{$!.message}") - PBDebug.log("#{$!.backtrace.inspect}") - PBDebug.log("") -# if $INTERNAL - pbPrintException($!) -# end - PBDebug.flush - end - end - - def self.flush - if $DEBUG && $INTERNAL && @@log.length>0 - File.open("Data/debuglog.txt", "a+b") { |f| f.write("#{@@log}") } - end - @@log.clear - end - - def self.log(msg) - if $DEBUG && $INTERNAL - @@log.push("#{msg}\r\n") -# if @@log.length>1024 - PBDebug.flush -# end - end - end - - def self.dump(msg) - if $DEBUG && $INTERNAL - File.open("Data/dumplog.txt", "a+b") { |f| f.write("#{msg}\r\n") } - end - end -end diff --git a/Data/Scripts/001_Technical/001_Debugging/002_DebugConsole.rb b/Data/Scripts/001_Technical/001_Debugging/002_DebugConsole.rb deleted file mode 100644 index 6eb42fccd..000000000 --- a/Data/Scripts/001_Technical/001_Debugging/002_DebugConsole.rb +++ /dev/null @@ -1,54 +0,0 @@ -# To use the console, use the executable explicitly built -# with the console enabled on Windows. On Linux and macOS, -# just launch the executable directly from a terminal. -module Console - def self.setup_console - return unless $DEBUG - echoln "--------------------------------" - echoln "#{System.game_title} Output Window" - echoln "--------------------------------" - echoln "If you are seeing this window, you are running" - echoln "#{System.game_title} in Debug Mode. This means" - echoln "that you're either playing a Debug Version, or" - echoln "you are playing from within RPG Maker XP." - echoln "" - echoln "Closing this window will close the game. If" - echoln "you want to get rid of this window, run the" - echoln "program from the Shell, or download a Release" - echoln "version." - echoln "" - echoln "--------------------------------" - echoln "Debug Output:" - echoln "--------------------------------" - echoln "" - end - - def self.readInput - return gets.strip - end - - def self.readInput2 - return self.readInput - end - - def self.get_input - echo self.readInput2 - end -end - -module Kernel - def echo(string) - return unless $DEBUG - printf(string.is_a?(String) ? string : string.inspect) - end - - def echoln(string) - caller_info = caller(1..1).first - file, line, method = caller_info.split(":") - echo "#{file}, #{line}:\t" - echo(string) - echo("\r\n") - end -end - -Console.setup_console diff --git a/Data/Scripts/001_Technical/001_Debugging/003_Errors.rb b/Data/Scripts/001_Technical/001_Debugging/003_Errors.rb deleted file mode 100644 index d744b325b..000000000 --- a/Data/Scripts/001_Technical/001_Debugging/003_Errors.rb +++ /dev/null @@ -1,93 +0,0 @@ -#=============================================================================== -# Exceptions and critical code -#=============================================================================== -class Reset < Exception -end - -def pbGetExceptionMessage(e,_script="") - emessage = e.message.dup - emessage.force_encoding(Encoding::UTF_8) - if e.is_a?(Hangup) - emessage = "The script is taking too long. The game will restart." - elsif e.is_a?(Errno::ENOENT) - filename = emessage.sub("No such file or directory - ", "") - emessage = "File #{filename} not found." - end - emessage.gsub!(/Section(\d+)/) { $RGSS_SCRIPTS[$1.to_i][1] } rescue nil - return emessage -end - -def pbPrintException(e) - emessage = "" - if $EVENTHANGUPMSG && $EVENTHANGUPMSG!="" - emessage = $EVENTHANGUPMSG # Message with map/event ID generated elsewhere - $EVENTHANGUPMSG = nil - else - emessage = pbGetExceptionMessage(e) - end - # begin message formatting - message = "[Infinite Fusion version #{Settings::GAME_VERSION_NUMBER}]\r\n" - if $game_switches - message += "Randomized trainers, " if $game_switches[SWITCH_RANDOM_TRAINERS] - message += "Randomized gym trainers, " if $game_switches[SWITCH_RANDOMIZE_GYMS_SEPARATELY] - message += "Randomized wild Pokemon (global), " if $game_switches[SWITCH_WILD_RANDOM_GLOBAL] - message += "Randomized wild Pokemon (area), " if $game_switches[RandomizerWildPokemonOptionsScene::RANDOM_WILD_AREA] - message += "All fused, " if $game_switches[SWITCH_RANDOM_TRAINERS] - message += "Randomized trainers, " if $game_switches[RandomizerWildPokemonOptionsScene::REGULAR_TO_FUSIONS] - end - message += "#{Essentials::ERROR_TEXT}\r\n" # For third party scripts to add to - message += "Exception: #{e.class}\r\n" - message += "Message: #{emessage}\r\n" - # show last 10/25 lines of backtrace - message += "\r\nBacktrace:\r\n" - btrace = "" - if e.backtrace - maxlength = ($INTERNAL) ? 25 : 10 - e.backtrace[0, maxlength].each { |i| btrace += "#{i}\r\n" } - end - btrace.gsub!(/Section(\d+)/) { $RGSS_SCRIPTS[$1.to_i][1] } rescue nil - message += btrace - # output to log - errorlog = "errorlog.txt" - errorlog = RTP.getSaveFileName("errorlog.txt") if (Object.const_defined?(:RTP) rescue false) - File.open(errorlog, "ab") do |f| - f.write("\r\n=================\r\n\r\n[#{Time.now}]\r\n") - f.write(message) - end - # format/censor the error log directory - errorlogline = errorlog.gsub("/", "\\") - errorlogline.sub!(Dir.pwd + "\\", "") - errorlogline.sub!(pbGetUserName, "USERNAME") - errorlogline = "\r\n" + errorlogline if errorlogline.length > 20 - # output message - print("#{message}\r\nThis exception was logged in #{errorlogline}.\r\nHold Ctrl when closing this message to copy it to the clipboard.") - # Give a ~500ms coyote time to start holding Control - t = System.delta - until (System.delta - t) >= 500000 - Input.update - if Input.press?(Input::CTRL) - Input.clipboard = message - break - end - end -end - -def pbCriticalCode - ret = 0 - begin - yield - ret = 1 - rescue Exception - e = $! - if e.is_a?(Reset) || e.is_a?(SystemExit) - raise - else - pbPrintException(e) - if e.is_a?(Hangup) - ret = 2 - raise Reset.new - end - end - end - return ret -end diff --git a/Data/Scripts/001_Technical/001_Debugging/004_Validation.rb b/Data/Scripts/001_Technical/001_Debugging/004_Validation.rb deleted file mode 100644 index e3c23ccca..000000000 --- a/Data/Scripts/001_Technical/001_Debugging/004_Validation.rb +++ /dev/null @@ -1,31 +0,0 @@ -# The Kernel module is extended to include the validate method. -module Kernel - private - - # Used to check whether method arguments are of a given class or respond to a method. - # @param value_pairs [Hash{Object => Class, Array, Symbol}] value pairs to validate - # @example Validate a class or method - # validate foo => Integer, baz => :to_s # raises an error if foo is not an Integer or if baz doesn't implement #to_s - # @example Validate a class from an array - # validate foo => [Sprite, Bitmap, Viewport] # raises an error if foo isn't a Sprite, Bitmap or Viewport - # @raise [ArgumentError] if validation fails - def validate(value_pairs) - unless value_pairs.is_a?(Hash) - raise ArgumentError, "Non-hash argument #{value_pairs.inspect} passed into validate." - end - errors = value_pairs.map do |value, condition| - if condition.is_a?(Array) - unless condition.any? { |klass| value.is_a?(klass) } - next "Expected #{value.inspect} to be one of #{condition.inspect}, but got #{value.class.name}." - end - elsif condition.is_a?(Symbol) - next "Expected #{value.inspect} to respond to #{condition}." unless value.respond_to?(condition) - elsif !value.is_a?(condition) - next "Expected #{value.inspect} to be a #{condition.name}, but got #{value.class.name}." - end - end - errors.compact! - return if errors.empty? - raise ArgumentError, "Invalid argument passed to method.\r\n" + errors.join("\r\n") - end -end diff --git a/Data/Scripts/001_Technical/001_Debugging/005_Deprecation.rb b/Data/Scripts/001_Technical/001_Debugging/005_Deprecation.rb deleted file mode 100644 index 64660171a..000000000 --- a/Data/Scripts/001_Technical/001_Debugging/005_Deprecation.rb +++ /dev/null @@ -1,53 +0,0 @@ -# The Deprecation module is used to warn game & plugin creators of deprecated -# methods. -module Deprecation - module_function - - # Sends a warning of a deprecated method into the debug console. - # @param method_name [String] name of the deprecated method - # @param removal_version [String] version the method is removed in - # @param alternative [String] preferred alternative method - def warn_method(method_name, removal_version = nil, alternative = nil) - text = _INTL('WARN: usage of deprecated method "{1}" or its alias.', method_name) - unless removal_version.nil? - text += _INTL("\nThe method is slated to be"\ - " removed in Essentials {1}.", removal_version) - end - unless alternative.nil? - text += _INTL("\nUse \"{1}\" instead.", alternative) - end - echoln text - end -end - -# The Module class is extended to allow easy deprecation of instance and class methods. -class Module - private - - # Creates a deprecated alias for a method. - # Using it sends a warning to the debug console. - # @param name [Symbol] name of the new alias - # @param aliased_method [Symbol] name of the aliased method - # @param removal_in [String] version the alias is removed in - # @param class_method [Boolean] whether the method is a class method - def deprecated_method_alias(name, aliased_method, removal_in: nil, class_method: false) - validate name => Symbol, aliased_method => Symbol, removal_in => [NilClass, String], - class_method => [TrueClass, FalseClass] - - target = class_method ? self.class : self - class_name = self.name - - unless target.method_defined?(aliased_method) - raise ArgumentError, "#{class_name} does not have method #{aliased_method} defined" - end - - delimiter = class_method ? '.' : '#' - - target.define_method(name) do |*args, **kvargs| - alias_name = format('%s%s%s', class_name, delimiter, name) - aliased_method_name = format('%s%s%s', class_name, delimiter, aliased_method) - Deprecation.warn_method(alias_name, removal_in, aliased_method_name) - method(aliased_method).call(*args, **kvargs) - end - end -end diff --git a/Data/Scripts/001_Technical/001_MKXP_Compatibility.rb b/Data/Scripts/001_Technical/001_MKXP_Compatibility.rb deleted file mode 100644 index 639b37890..000000000 --- a/Data/Scripts/001_Technical/001_MKXP_Compatibility.rb +++ /dev/null @@ -1,39 +0,0 @@ -# Using mkxp-z v2.2.0 - https://gitlab.com/mkxp-z/mkxp-z/-/releases/v2.2.0 -$VERBOSE = nil -Font.default_shadow = false if Font.respond_to?(:default_shadow) -Graphics.frame_rate = 40 - -def pbSetWindowText(string) - System.set_window_title(string || System.game_title) -end - -class Bitmap - attr_accessor :storedPath - - alias mkxp_draw_text draw_text unless method_defined?(:mkxp_draw_text) - - def draw_text(x, y, width, height, text, align = 0) - height = text_size(text).height - mkxp_draw_text(x, y, width, height, text, align) - end -end - -module Graphics - def self.delta_s - return self.delta.to_f / 1_000_000 - end -end - -def pbSetResizeFactor(factor) - if !$ResizeInitialized - Graphics.resize_screen(Settings::SCREEN_WIDTH, Settings::SCREEN_HEIGHT) - $ResizeInitialized = true - end - if factor < 0 || factor == 4 - Graphics.fullscreen = true if !Graphics.fullscreen - else - Graphics.fullscreen = false if Graphics.fullscreen - Graphics.scale = (factor + 1) * 0.5 - Graphics.center - end -end diff --git a/Data/Scripts/001_Technical/002_Files/001_FileTests.rb b/Data/Scripts/001_Technical/002_Files/001_FileTests.rb deleted file mode 100644 index 56def11ef..000000000 --- a/Data/Scripts/001_Technical/002_Files/001_FileTests.rb +++ /dev/null @@ -1,492 +0,0 @@ -#=============================================================================== -# Reads files of certain format from a directory -#=============================================================================== -class Dir - #----------------------------------------------------------------------------- - # Reads all files in a directory - #----------------------------------------------------------------------------- - def self.get(dir, filters = "*", full = true) - files = [] - filters = [filters] if !filters.is_a?(Array) - self.chdir(dir) do - for filter in filters - self.glob(filter){ |f| files.push(full ? (dir + "/" + f) : f) } - end - end - return files.sort - end - #----------------------------------------------------------------------------- - # Generates entire file/folder tree from a certain directory - #----------------------------------------------------------------------------- - def self.all(dir, filters = "*", full = true) - # sets variables for starting - files = [] - subfolders = [] - for file in self.get(dir, filters, full) - # engages in recursion to read the entire file tree - if self.safe?(file) # Is a directory - subfolders += self.all(file, filters, full) - else # Is a file - files += [file] - end - end - # returns all found files - return files + subfolders - end - #----------------------------------------------------------------------------- - # Checks for existing directory, gets around accents - #----------------------------------------------------------------------------- - def self.safe?(dir) - return false if !FileTest.directory?(dir) - ret = false - self.chdir(dir) { ret = true } rescue nil - return ret - end - #----------------------------------------------------------------------------- -end - - - -#=============================================================================== -# extensions for file class -#=============================================================================== -class File - #----------------------------------------------------------------------------- - # Checks for existing file, gets around accents - #----------------------------------------------------------------------------- - def self.safe?(file) - ret = false - self.open(file, 'rb') { ret = true } rescue nil - return ret - end - #----------------------------------------------------------------------------- -end - - - -#=============================================================================== -# Checking for files and directories -#=============================================================================== -# Works around a problem with FileTest.directory if directory contains accent marks -def safeIsDirectory?(f) - ret = false - Dir.chdir(f) { ret = true } rescue nil - return ret -end - -# Works around a problem with FileTest.exist if path contains accent marks -def safeExists?(f) - return FileTest.exist?(f) if f[/\A[\x20-\x7E]*\z/] - ret = false - begin - File.open(f,"rb") { ret = true } - rescue Errno::ENOENT, Errno::EINVAL, Errno::EACCES - ret = false - end - return ret -end - -# Similar to "Dir.glob", but designed to work around a problem with accessing -# files if a path contains accent marks. -# "dir" is the directory path, "wildcard" is the filename pattern to match. -def safeGlob(dir,wildcard) - ret = [] - afterChdir = false - begin - Dir.chdir(dir) { - afterChdir = true - Dir.glob(wildcard) { |f| ret.push(dir+"/"+f) } - } - rescue Errno::ENOENT - raise if afterChdir - end - if block_given? - ret.each { |f| yield(f) } - end - return (block_given?) ? nil : ret -end - -def pbResolveAudioSE(file) - return nil if !file - if RTP.exists?("Audio/SE/"+file,["",".wav",".mp3",".ogg"]) - return RTP.getPath("Audio/SE/"+file,["",".wav",".mp3",".ogg"]) - end - return nil -end - -# Finds the real path for an image file. This includes paths in encrypted -# archives. Returns nil if the path can't be found. -def pbResolveBitmap(x) - return nil if !x - noext = x.gsub(/\.(bmp|png|gif|jpg|jpeg)$/,"") - filename = nil -# RTP.eachPathFor(x) { |path| -# filename = pbTryString(path) if !filename -# filename = pbTryString(path+".gif") if !filename -# } - RTP.eachPathFor(noext) { |path| - filename = pbTryString(path+".png") if !filename - filename = pbTryString(path+".gif") if !filename -# filename = pbTryString(path+".jpg") if !filename -# filename = pbTryString(path+".jpeg") if !filename -# filename = pbTryString(path+".bmp") if !filename - } - return filename -end - -# Finds the real path for an image file. This includes paths in encrypted -# archives. Returns _x_ if the path can't be found. -def pbBitmapName(x) - ret = pbResolveBitmap(x) - return (ret) ? ret : x -end - -def strsplit(str, re) - ret = [] - tstr = str - while re =~ tstr - ret[ret.length] = $~.pre_match - tstr = $~.post_match - end - ret[ret.length] = tstr if ret.length - return ret -end - -def canonicalize(c) - csplit = strsplit(c, /[\/\\]/) - pos = -1 - ret = [] - retstr = "" - for x in csplit - if x == ".." - if pos >= 0 - ret.delete_at(pos) - pos -= 1 - end - elsif x != "." - ret.push(x) - pos += 1 - end - end - for i in 0...ret.length - retstr += "/" if i > 0 - retstr += ret[i] - end - return retstr -end - - - -module RTP - @rtpPaths = nil - - def self.exists?(filename,extensions=[]) - return false if nil_or_empty?(filename) - eachPathFor(filename) { |path| - return true if safeExists?(path) - for ext in extensions - return true if safeExists?(path+ext) - end - } - return false - end - - def self.getImagePath(filename) - return self.getPath(filename,["",".png",".gif"]) # ".jpg", ".jpeg", ".bmp" - end - - def self.getAudioPath(filename) - return self.getPath(filename,["",".mp3",".wav",".wma",".mid",".ogg",".midi"]) - end - - def self.getPath(filename,extensions=[]) - return filename if nil_or_empty?(filename) - eachPathFor(filename) { |path| - return path if safeExists?(path) - for ext in extensions - file = path+ext - return file if safeExists?(file) - end - } - return filename - end - - # Gets the absolute RGSS paths for the given file name - def self.eachPathFor(filename) - return if !filename - if filename[/^[A-Za-z]\:[\/\\]/] || filename[/^[\/\\]/] - # filename is already absolute - yield filename - else - # relative path - RTP.eachPath { |path| - if path=="./" - yield filename - else - yield path+filename - end - } - end - end - - # Gets all RGSS search paths. - # This function basically does nothing now, because - # the passage of time and introduction of MKXP make - # it useless, but leaving it for compatibility - # reasons - def self.eachPath - # XXX: Use "." instead of Dir.pwd because of problems retrieving files if - # the current directory contains an accent mark - yield ".".gsub(/[\/\\]/,"/").gsub(/[\/\\]$/,"")+"/" - end - - private - - def self.getSaveFileName(fileName) - File.join(getSaveFolder, fileName) - end - - def self.getSaveFolder - # MKXP makes sure that this folder has been created - # once it starts. The location differs depending on - # the operating system: - # Windows: %APPDATA% - # Linux: $HOME/.local/share - # macOS (unsandboxed): $HOME/Library/Application Support - System.data_directory - end -end - - - -module FileTest - Image_ext = ['.png', '.gif'] # '.jpg', '.jpeg', '.bmp', - Audio_ext = ['.mp3', '.mid', '.midi', '.ogg', '.wav', '.wma'] - - def self.audio_exist?(filename) - return RTP.exists?(filename,Audio_ext) - end - - def self.image_exist?(filename) - return RTP.exists?(filename,Image_ext) - end -end - - - -# Used to determine whether a data file exists (rather than a graphics or -# audio file). Doesn't check RTP, but does check encrypted archives. - -# Note: pbGetFileChar checks anything added in MKXP's RTP setting, -# and matching mount points added through System.mount -def pbRgssExists?(filename) - if safeExists?("./Game.rgssad") - return pbGetFileChar(filename)!=nil - else - filename = canonicalize(filename) - return safeExists?(filename) - end -end - -# Opens an IO, even if the file is in an encrypted archive. -# Doesn't check RTP for the file. - -# Note: load_data checks anything added in MKXP's RTP setting, -# and matching mount points added through System.mount -def pbRgssOpen(file,mode=nil) - #File.open("debug.txt","ab") { |fw| fw.write([file,mode,Time.now.to_f].inspect+"\r\n") } - if !safeExists?("./Game.rgssad") - if block_given? - File.open(file,mode) { |f| yield f } - return nil - else - return File.open(file,mode) - end - end - file = canonicalize(file) - Marshal.neverload = true - str = load_data(file, true) - if block_given? - StringInput.open(str) { |f| yield f } - return nil - else - return StringInput.open(str) - end -end - -# Gets at least the first byte of a file. Doesn't check RTP, but does check -# encrypted archives. -def pbGetFileChar(file) - canon_file = canonicalize(file) - if !safeExists?("./Game.rgssad") - return nil if !safeExists?(canon_file) - return nil if file.last == '/' # Is a directory - begin - File.open(canon_file, "rb") { |f| return f.read(1) } # read one byte - rescue Errno::ENOENT, Errno::EINVAL, Errno::EACCES, Errno::EISDIR - return nil - end - end - str = nil - begin - str = load_data(canon_file, true) - rescue Errno::ENOENT, Errno::EINVAL, Errno::EACCES, Errno::EISDIR, RGSSError, MKXPError - str = nil - end - return str -end - -def pbTryString(x) - ret = pbGetFileChar(x) - return (ret!=nil && ret!="") ? x : nil -end - -# Gets the contents of a file. Doesn't check RTP, but does check -# encrypted archives. - -# Note: load_data will check anything added in MKXP's RTP setting, -# and matching mount points added through System.mount -def pbGetFileString(file) - file = canonicalize(file) - if !safeExists?("./Game.rgssad") - return nil if !safeExists?(file) - begin - File.open(file,"rb") { |f| return f.read } # read all data - rescue Errno::ENOENT, Errno::EINVAL, Errno::EACCES - return nil - end - end - str = nil - begin - str = load_data(file, true) - rescue Errno::ENOENT, Errno::EINVAL, Errno::EACCES, RGSSError, MKXPError - str = nil - end - return str -end - - - -#=============================================================================== -# -#=============================================================================== -class StringInput - include Enumerable - - class << self - def new( str ) - if block_given? - begin - f = super - yield f - ensure - f.close if f - end - else - super - end - end - alias open new - end - - def initialize( str ) - @string = str - @pos = 0 - @closed = false - @lineno = 0 - end - - attr_reader :lineno,:string - - def inspect - return "#<#{self.class}:#{@closed ? 'closed' : 'open'},src=#{@string[0,30].inspect}>" - end - - def close - raise IOError, 'closed stream' if @closed - @pos = nil - @closed = true - end - - def closed?; @closed; end - - def pos - raise IOError, 'closed stream' if @closed - [@pos, @string.size].min - end - - alias tell pos - - def rewind; seek(0); end - - def pos=(value); seek(value); end - - def seek(offset, whence=IO::SEEK_SET) - raise IOError, 'closed stream' if @closed - case whence - when IO::SEEK_SET then @pos = offset - when IO::SEEK_CUR then @pos += offset - when IO::SEEK_END then @pos = @string.size - offset - else - raise ArgumentError, "unknown seek flag: #{whence}" - end - @pos = 0 if @pos < 0 - @pos = [@pos, @string.size + 1].min - offset - end - - def eof? - raise IOError, 'closed stream' if @closed - @pos > @string.size - end - - def each( &block ) - raise IOError, 'closed stream' if @closed - begin - @string.each(&block) - ensure - @pos = 0 - end - end - - def gets - raise IOError, 'closed stream' if @closed - if idx = @string.index(?\n, @pos) - idx += 1 # "\n".size - line = @string[ @pos ... idx ] - @pos = idx - @pos += 1 if @pos == @string.size - else - line = @string[ @pos .. -1 ] - @pos = @string.size + 1 - end - @lineno += 1 - line - end - - def getc - raise IOError, 'closed stream' if @closed - ch = @string[@pos] - @pos += 1 - @pos += 1 if @pos == @string.size - ch - end - - def read( len = nil ) - raise IOError, 'closed stream' if @closed - if !len - return nil if eof? - rest = @string[@pos ... @string.size] - @pos = @string.size + 1 - return rest - end - str = @string[@pos, len] - @pos += len - @pos += 1 if @pos == @string.size - str - end - - def read_all; read(); end - - alias sysread read -end diff --git a/Data/Scripts/001_Technical/002_Files/002_FileMixins.rb b/Data/Scripts/001_Technical/002_Files/002_FileMixins.rb deleted file mode 100644 index 187049ec6..000000000 --- a/Data/Scripts/001_Technical/002_Files/002_FileMixins.rb +++ /dev/null @@ -1,150 +0,0 @@ -module FileInputMixin - def fgetb - ret = 0 - each_byte do |i| - ret = i || 0 - break - end - return ret - end - - def fgetw - x = 0 - ret = 0 - each_byte do |i| - break if !i - ret |= (i << x) - x += 8 - break if x == 16 - end - return ret - end - - def fgetdw - x = 0 - ret = 0 - each_byte do |i| - break if !i - ret |= (i << x) - x += 8 - break if x == 32 - end - return ret - end - - def fgetsb - ret = fgetb - ret -= 256 if (ret & 0x80) != 0 - return ret - end - - def xfgetb(offset) - self.pos = offset - return fgetb - end - - def xfgetw(offset) - self.pos = offset - return fgetw - end - - def xfgetdw(offset) - self.pos = offset - return fgetdw - end - - def getOffset(index) - self.binmode - self.pos = 0 - offset = fgetdw >> 3 - return 0 if index >= offset - self.pos = index * 8 - return fgetdw - end - - def getLength(index) - self.binmode - self.pos = 0 - offset = fgetdw >> 3 - return 0 if index >= offset - self.pos = index * 8 + 4 - return fgetdw - end - - def readName(index) - self.binmode - self.pos = 0 - offset = fgetdw >> 3 - return "" if index >= offset - self.pos = index << 3 - offset = fgetdw - length = fgetdw - return "" if length == 0 - self.pos = offset - return read(length) - end -end - -module FileOutputMixin - def fputb(b) - b &= 0xFF - write(b.chr) - end - - def fputw(w) - 2.times do - b = w & 0xFF - write(b.chr) - w >>= 8 - end - end - - def fputdw(w) - 4.times do - b = w & 0xFF - write(b.chr) - w >>= 8 - end - end -end - -class File < IO -=begin - unless defined?(debugopen) - class << self - alias debugopen open - end - end - - def open(f, m = "r") - debugopen("debug.txt", "ab") { |file| file.write([f, m, Time.now.to_f].inspect + "\r\n") } - if block_given? - debugopen(f, m) { |file| yield file } - else - return debugopen(f, m) - end - end -=end - include FileInputMixin - include FileOutputMixin -end - -class StringInput - include FileInputMixin - - def pos=(value) - seek(value) - end - - def each_byte - while !eof? - yield getc - end - end - - def binmode; end -end - -class StringOutput - include FileOutputMixin -end diff --git a/Data/Scripts/001_Technical/002_Files/003_HTTP_Utilities.rb b/Data/Scripts/001_Technical/002_Files/003_HTTP_Utilities.rb deleted file mode 100644 index b918e0592..000000000 --- a/Data/Scripts/001_Technical/002_Files/003_HTTP_Utilities.rb +++ /dev/null @@ -1,150 +0,0 @@ -############################# -# -# HTTP utility functions -# -############################# -# - -def pbPostData(url, postdata, filename=nil, depth=0) - if url[/^http:\/\/([^\/]+)(.*)$/] - host = $1 - path = $2 - path = "/" if path.length==0 - userAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.14) Gecko/2009082707 Firefox/3.0.14" - body = postdata.map { |key, value| - keyString = key.to_s - valueString = value.to_s - keyString.gsub!(/[^a-zA-Z0-9_\.\-]/n) { |s| sprintf('%%%02x', s[0]) } - valueString.gsub!(/[^a-zA-Z0-9_\.\-]/n) { |s| sprintf('%%%02x', s[0]) } - next "#{keyString}=#{valueString}" - }.join('&') - ret = HTTPLite.post_body( - url, - body, - "application/x-www-form-urlencoded", - { - "Host" => host, # might not be necessary - "Proxy-Connection" => "Close", - "Content-Length" => body.bytesize.to_s, - "Pragma" => "no-cache", - "User-Agent" => userAgent - } - ) rescue "" - return ret if !ret.is_a?(Hash) - return "" if ret[:status] != 200 - return ret[:body] if !filename - File.open(filename, "wb"){|f|f.write(ret[:body])} - return "" - end - return "" -end - -def pbDownloadData(url, filename = nil, authorization = nil, depth = 0, &block) - return nil if !downloadAllowed?() - echoln "downloading data from #{url}" - headers = { - "Proxy-Connection" => "Close", - "Pragma" => "no-cache", - "User-Agent" => "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.14) Gecko/2009082707 Firefox/3.0.14" - } - headers["authorization"] = authorization if authorization - ret = HTTPLite.get(url, headers) rescue "" - return ret if !ret.is_a?(Hash) - return "" if ret[:status] != 200 - return ret[:body] if !filename - File.open(filename, "wb") { |f| f.write(ret[:body]) } - return "" -end - -def pbDownloadToString(url) - begin - data = pbDownloadData(url) - return data if data - return "" - rescue - return "" - end -end - -def pbDownloadToFile(url, file) - begin - pbDownloadData(url,file) - rescue - end -end - -def pbPostToString(url, postdata) - begin - data = pbPostData(url, postdata) - return data - rescue - return "" - end -end - -def pbPostToFile(url, postdata, file) - begin - pbPostData(url, postdata,file) - rescue - end -end - -def serialize_value(value) - if value.is_a?(Hash) - serialize_json(value) - elsif value.is_a?(String) - escaped_value = value.gsub(/\\/, '\\\\\\').gsub(/"/, '\\"').gsub(/\n/, '\\n').gsub(/\r/, '\\r') - "\"#{escaped_value}\"" - else - value.to_s - end -end - - -def serialize_json(data) - #echoln data - # Manually serialize the JSON data into a string - parts = ["{"] - data.each_with_index do |(key, value), index| - parts << "\"#{key}\":#{serialize_value(value)}" - parts << "," unless index == data.size - 1 - end - parts << "}" - return parts.join -end - - -def downloadAllowed?() - return $PokemonSystem.download_sprites==0 -end - -def clean_json_string(str) - #echoln str - #return str if $PokemonSystem.on_mobile - # Remove non-UTF-8 characters and unexpected control characters - #cleaned_str = str.encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '') - cleaned_str = str - # Remove literal \n, \r, \t, etc. - cleaned_str = cleaned_str.gsub(/\\n|\\r|\\t/, '') - - # Remove actual newlines and carriage returns - cleaned_str = cleaned_str.gsub(/[\n\r]/, '') - - # Remove leading and trailing quotes - cleaned_str = cleaned_str.gsub(/\A"|"\Z/, '') - - # Replace Unicode escape sequences with corresponding characters - cleaned_str = cleaned_str.gsub(/\\u([\da-fA-F]{4})/) { |match| - [$1.to_i(16)].pack("U") - } - return cleaned_str -end - - - - - - - - - diff --git a/Data/Scripts/001_Technical/002_RubyUtilities.rb b/Data/Scripts/001_Technical/002_RubyUtilities.rb deleted file mode 100644 index c71bb3e06..000000000 --- a/Data/Scripts/001_Technical/002_RubyUtilities.rb +++ /dev/null @@ -1,142 +0,0 @@ -#=============================================================================== -# class Object -#=============================================================================== -class Object - alias full_inspect inspect unless method_defined?(:full_inspect) - - def inspect - return "#<#{self.class}>" - end -end - -#=============================================================================== -# class Class -#=============================================================================== -class Class - def to_sym - return self.to_s.to_sym - end -end - -#=============================================================================== -# class String -#=============================================================================== -class String - def starts_with_vowel? - return ['a', 'e', 'i', 'o', 'u'].include?(self[0, 1].downcase) - end - - def first(n = 1) - return self[0...n] - end - - def last(n = 1) - return self[-n..-1] || self - end - - def blank? - blank = true - s = self.scan(/./) - for l in s - blank = false if l != "" - end - return blank - end - - def cut(bitmap, width) - string = self - width -= bitmap.text_size("...").width - string_width = 0 - text = [] - for char in string.scan(/./) - wdh = bitmap.text_size(char).width - next if (wdh + string_width) > width - string_width += wdh - text.push(char) - end - text.push("...") if text.length < string.length - new_string = "" - for char in text - new_string += char - end - return new_string - end -end - -#=============================================================================== -# class Numeric -#=============================================================================== -class Numeric - # Turns a number into a string formatted like 12,345,678. - def to_s_formatted - return self.to_s.reverse.gsub(/(\d{3})(?=\d)/, '\1,').reverse - end - - def to_word - ret = [_INTL("zero"), _INTL("one"), _INTL("two"), _INTL("three"), - _INTL("four"), _INTL("five"), _INTL("six"), _INTL("seven"), - _INTL("eight"), _INTL("nine"), _INTL("ten"), _INTL("eleven"), - _INTL("twelve"), _INTL("thirteen"), _INTL("fourteen"), _INTL("fifteen"), - _INTL("sixteen"), _INTL("seventeen"), _INTL("eighteen"), _INTL("nineteen"), - _INTL("twenty")] - return ret[self] if self.is_a?(Integer) && self >= 0 && self <= ret.length - return self.to_s - end -end - -#=============================================================================== -# class Array -#=============================================================================== -class Array - def ^(other) # xor of two arrays - return (self|other) - (self&other) - end - - def swap(val1, val2) - index1 = self.index(val1) - index2 = self.index(val2) - self[index1] = val2 - self[index2] = val1 - end -end - -#=============================================================================== -# module Enumerable -#=============================================================================== -module Enumerable - def transform - ret = [] - self.each { |item| ret.push(yield(item)) } - return ret - end -end - -#=============================================================================== -# Kernel methods -#=============================================================================== -def rand(*args) - Kernel.rand(*args) -end - -class << Kernel - alias oldRand rand unless method_defined?(:oldRand) - def rand(a = nil, b = nil) - if a.is_a?(Range) - lo = a.min - hi = a.max - return lo + oldRand(hi - lo + 1) - elsif a.is_a?(Numeric) - if b.is_a?(Numeric) - return a + oldRand(b - a + 1) - else - return oldRand(a) - end - elsif a.nil? - return (b) ? oldRand(b) : oldRand(2) - end - end -end - -def nil_or_empty?(string) - return string.nil? || !string.is_a?(String) || string.size == 0 -end diff --git a/Data/Scripts/001_Technical/003_Intl_Messages.rb b/Data/Scripts/001_Technical/003_Intl_Messages.rb deleted file mode 100644 index 7f8b21799..000000000 --- a/Data/Scripts/001_Technical/003_Intl_Messages.rb +++ /dev/null @@ -1,789 +0,0 @@ -def pbAddScriptTexts(items,script) - script.scan(/(?:_I)\s*\(\s*\"((?:[^\\\"]*\\\"?)*[^\"]*)\"/) { |s| - string=s[0] - string.gsub!(/\\\"/,"\"") - string.gsub!(/\\\\/,"\\") - items.push(string) - } -end - -def pbAddRgssScriptTexts(items,script) - script.scan(/(?:_INTL|_ISPRINTF)\s*\(\s*\"((?:[^\\\"]*\\\"?)*[^\"]*)\"/) { |s| - string=s[0] - string.gsub!(/\\r/,"\r") - string.gsub!(/\\n/,"\n") - string.gsub!(/\\1/,"\1") - string.gsub!(/\\\"/,"\"") - string.gsub!(/\\\\/,"\\") - items.push(string) - } -end - -def pbSetTextMessages - Graphics.update - begin - t = Time.now.to_i - texts=[] - for script in $RGSS_SCRIPTS - if Time.now.to_i - t >= 5 - t = Time.now.to_i - Graphics.update - end - scr=Zlib::Inflate.inflate(script[2]) - pbAddRgssScriptTexts(texts,scr) - end - if safeExists?("Data/PluginScripts.rxdata") - plugin_scripts = load_data("Data/PluginScripts.rxdata") - for plugin in plugin_scripts - for script in plugin[2] - if Time.now.to_i - t >= 5 - t = Time.now.to_i - Graphics.update - end - scr = Zlib::Inflate.inflate(script[1]).force_encoding(Encoding::UTF_8) - pbAddRgssScriptTexts(texts,scr) - end - end - end - # Must add messages because this code is used by both game system and Editor - MessageTypes.addMessagesAsHash(MessageTypes::ScriptTexts,texts) - commonevents = load_data("Data/CommonEvents.rxdata") - items=[] - choices=[] - for event in commonevents.compact - if Time.now.to_i - t >= 5 - t = Time.now.to_i - Graphics.update - end - begin - neednewline=false - lastitem="" - for j in 0...event.list.size - list = event.list[j] - if neednewline && list.code!=401 - if lastitem!="" - lastitem.gsub!(/([^\.\!\?])\s\s+/) { |m| $1+" " } - items.push(lastitem) - lastitem="" - end - neednewline=false - end - if list.code == 101 - lastitem+="#{list.parameters[0]}" - neednewline=true - elsif list.code == 102 - for k in 0...list.parameters[0].length - choices.push(list.parameters[0][k]) - end - neednewline=false - elsif list.code == 401 - lastitem+=" " if lastitem!="" - lastitem+="#{list.parameters[0]}" - neednewline=true - elsif list.code == 355 || list.code == 655 - pbAddScriptTexts(items,list.parameters[0]) - elsif list.code == 111 && list.parameters[0]==12 - pbAddScriptTexts(items,list.parameters[1]) - elsif list.code == 209 - route=list.parameters[1] - for k in 0...route.list.size - if route.list[k].code == 45 - pbAddScriptTexts(items,route.list[k].parameters[0]) - end - end - end - end - if neednewline - if lastitem!="" - items.push(lastitem) - lastitem="" - end - end - end - end - if Time.now.to_i - t >= 5 - t = Time.now.to_i - Graphics.update - end - items|=[] - choices|=[] - items.concat(choices) - MessageTypes.setMapMessagesAsHash(0,items) - mapinfos = pbLoadMapInfos - mapnames=[] - for id in mapinfos.keys - mapnames[id]=mapinfos[id].name - end - MessageTypes.setMessages(MessageTypes::MapNames,mapnames) - for id in mapinfos.keys - if Time.now.to_i - t >= 5 - t = Time.now.to_i - Graphics.update - end - filename=sprintf("Data/Map%03d.rxdata",id) - next if !pbRgssExists?(filename) - map = load_data(filename) - items=[] - choices=[] - for event in map.events.values - if Time.now.to_i - t >= 5 - t = Time.now.to_i - Graphics.update - end - begin - for i in 0...event.pages.size - neednewline=false - lastitem="" - for j in 0...event.pages[i].list.size - list = event.pages[i].list[j] - if neednewline && list.code!=401 - if lastitem!="" - lastitem.gsub!(/([^\.\!\?])\s\s+/) { |m| $1+" " } - items.push(lastitem) - lastitem="" - end - neednewline=false - end - if list.code == 101 - lastitem+="#{list.parameters[0]}" - neednewline=true - elsif list.code == 102 - for k in 0...list.parameters[0].length - choices.push(list.parameters[0][k]) - end - neednewline=false - elsif list.code == 401 - lastitem+=" " if lastitem!="" - lastitem+="#{list.parameters[0]}" - neednewline=true - elsif list.code == 355 || list.code==655 - pbAddScriptTexts(items,list.parameters[0]) - elsif list.code == 111 && list.parameters[0]==12 - pbAddScriptTexts(items,list.parameters[1]) - elsif list.code==209 - route=list.parameters[1] - for k in 0...route.list.size - if route.list[k].code==45 - pbAddScriptTexts(items,route.list[k].parameters[0]) - end - end - end - end - if neednewline - if lastitem!="" - items.push(lastitem) - lastitem="" - end - end - end - end - end - if Time.now.to_i - t >= 5 - t = Time.now.to_i - Graphics.update - end - items|=[] - choices|=[] - items.concat(choices) - MessageTypes.setMapMessagesAsHash(id,items) - if Time.now.to_i - t >= 5 - t = Time.now.to_i - Graphics.update - end - end - rescue Hangup - end - Graphics.update -end - -def pbEachIntlSection(file) - lineno=1 - re=/^\s*\[\s*([^\]]+)\s*\]\s*$/ - havesection=false - sectionname=nil - lastsection=[] - file.each_line { |line| - if lineno==1 && line[0].ord==0xEF && line[1].ord==0xBB && line[2].ord==0xBF - line=line[3,line.length-3] - end - if !line[/^\#/] && !line[/^\s*$/] - if line[re] - if havesection - yield lastsection,sectionname - end - lastsection.clear - sectionname=$~[1] - havesection=true - else - if sectionname==nil - raise _INTL("Expected a section at the beginning of the file (line {1})",lineno) - end - lastsection.push(line.gsub(/\s+$/,"")) - end - end - lineno+=1 - if lineno%500==0 - Graphics.update - end - } - if havesection - yield lastsection,sectionname - end -end - -def pbGetText(infile) - begin - file=File.open(infile,"rb") - rescue - raise _INTL("Can't find {1}",infile) - end - intldat=[] - begin - pbEachIntlSection(file) { |section,name| - next if section.length==0 - if !name[/^([Mm][Aa][Pp])?(\d+)$/] - raise _INTL("Invalid section name {1}",name) - end - ismap=$~[1] && $~[1]!="" - id=$~[2].to_i - itemlength=0 - if section[0][/^\d+$/] - intlhash=[] - itemlength=3 - if ismap - raise _INTL("Section {1} can't be an ordered list (section was recognized as an ordered list because its first line is a number)",name) - end - if section.length%3!=0 - raise _INTL("Section {1}'s line count is not divisible by 3 (section was recognized as an ordered list because its first line is a number)",name) - end - else - intlhash=OrderedHash.new - itemlength=2 - if section.length%2!=0 - raise _INTL("Section {1} has an odd number of entries (section was recognized as a hash because its first line is not a number)",name) - end - end - i=0 - loop do break unless i0 - str+=@keys[i].inspect+"=>"+self[@keys[i]].inspect - end - str+="}" - return str - end - - alias :to_s :inspect - - def []=(key,value) - oldvalue=self[key] - if !oldvalue && value - @keys.push(key) - elsif !value - @keys|=[] - @keys-=[key] - end - return super(key,value) - end - - def self._load(string) - ret=self.new - keysvalues=Marshal.load(string) - keys=keysvalues[0] - values=keysvalues[1] - for i in 0...keys.length - ret[keys[i]]=values[i] - end - return ret - end - - def _dump(_depth=100) - values=[] - for key in @keys - values.push(self[key]) - end - return Marshal.dump([@keys,values]) - end -end - - - -class Messages - def initialize(filename=nil,delayLoad=false) - @messages=nil - @filename=filename - if @filename && !delayLoad - loadMessageFile(@filename) - end - end - - def delayedLoad - if @filename && !@messages - loadMessageFile(@filename) - @filename=nil - end - end - - def self.stringToKey(str) - if str && str[/[\r\n\t\1]|^\s+|\s+$|\s{2,}/] - key=str.clone - key.gsub!(/^\s+/,"") - key.gsub!(/\s+$/,"") - key.gsub!(/\s{2,}/," ") - return key - end - return str - end - - def self.normalizeValue(value) - if value[/[\r\n\t\x01]|^[\[\]]/] - ret=value.clone - ret.gsub!(/\r/,"<>") - ret.gsub!(/\n/,"<>") - ret.gsub!(/\t/,"<>") - ret.gsub!(/\[/,"<<[>>") - ret.gsub!(/\]/,"<<]>>") - ret.gsub!(/\x01/,"<<1>>") - return ret - end - return value - end - - def self.denormalizeValue(value) - if value[/<<[rnt1\[\]]>>/] - ret=value.clone - ret.gsub!(/<<1>>/,"\1") - ret.gsub!(/<>/,"\r") - ret.gsub!(/<>/,"\n") - ret.gsub!(/<<\[>>/,"[") - ret.gsub!(/<<\]>>/,"]") - ret.gsub!(/<>/,"\t") - return ret - end - return value - end - - def self.writeObject(f,msgs,secname,origMessages=nil) - return if !msgs - if msgs.is_a?(Array) - f.write("[#{secname}]\r\n") - for j in 0...msgs.length - next if nil_or_empty?(msgs[j]) - value=Messages.normalizeValue(msgs[j]) - origValue="" - if origMessages - origValue=Messages.normalizeValue(origMessages.get(secname,j)) - else - origValue=Messages.normalizeValue(MessageTypes.get(secname,j)) - end - f.write("#{j}\r\n") - f.write(origValue+"\r\n") - f.write(value+"\r\n") - end - elsif msgs.is_a?(OrderedHash) - f.write("[#{secname}]\r\n") - keys=msgs.keys - for key in keys - next if nil_or_empty?(msgs[key]) - value=Messages.normalizeValue(msgs[key]) - valkey=Messages.normalizeValue(key) - # key is already serialized - f.write(valkey+"\r\n") - f.write(value+"\r\n") - end - end - end - - def messages - return @messages || [] - end - - def extract(outfile) -# return if !@messages - origMessages=Messages.new("Data/messages.dat") - File.open(outfile,"wb") { |f| - f.write(0xef.chr) - f.write(0xbb.chr) - f.write(0xbf.chr) - f.write("# To localize this text for a particular language, please\r\n") - f.write("# translate every second line of this file.\r\n") - if origMessages.messages[0] - for i in 0...origMessages.messages[0].length - msgs=origMessages.messages[0][i] - Messages.writeObject(f,msgs,"Map#{i}",origMessages) - end - end - for i in 1...origMessages.messages.length - msgs=origMessages.messages[i] - Messages.writeObject(f,msgs,i,origMessages) - end - } - end - - def setMessages(type,array) - @messages=[] if !@messages - arr=[] - for i in 0...array.length - arr[i]=(array[i]) ? array[i] : "" - end - @messages[type]=arr - end - - def addMessages(type,array) - @messages=[] if !@messages - arr=(@messages[type]) ? @messages[type] : [] - for i in 0...array.length - arr[i]=(array[i]) ? array[i] : (arr[i]) ? arr[i] : "" - end - @messages[type]=arr - end - - def self.createHash(_type,array) - arr=OrderedHash.new - for i in 0...array.length - if array[i] - key=Messages.stringToKey(array[i]) - arr[key]=array[i] - end - end - return arr - end - - def self.addToHash(_type,array,hash) - hash=OrderedHash.new if !hash - for i in 0...array.length - if array[i] - key=Messages.stringToKey(array[i]) - hash[key]=array[i] - end - end - return hash - end - - def setMapMessagesAsHash(type,array) - @messages=[] if !@messages - @messages[0]=[] if !@messages[0] - @messages[0][type]=Messages.createHash(type,array) - end - - def addMapMessagesAsHash(type,array) - @messages=[] if !@messages - @messages[0]=[] if !@messages[0] - @messages[0][type]=Messages.addToHash(type,array,@messages[0][type]) - end - - def setMessagesAsHash(type,array) - @messages=[] if !@messages - @messages[type]=Messages.createHash(type,array) - end - - def addMessagesAsHash(type,array) - @messages=[] if !@messages - @messages[type]=Messages.addToHash(type,array,@messages[type]) - end - - def saveMessages(filename=nil) - filename="Data/messages.dat" if !filename - File.open(filename,"wb") { |f| Marshal.dump(@messages,f) } - end - - def loadMessageFile(filename) - begin - pbRgssOpen(filename,"rb") { |f| @messages=Marshal.load(f) } - if !@messages.is_a?(Array) - @messages=nil - raise "Corrupted data" - end - return @messages - rescue - @messages=nil - return nil - end - end - - def set(type,id,value) - delayedLoad - return if !@messages - return if !@messages[type] - @messages[type][id]=value - end - - def getCount(type) - delayedLoad - return 0 if !@messages - return 0 if !@messages[type] - return @messages[type].length - end - - def get(type,id) - delayedLoad - return "" if !@messages - return "" if !@messages[type] - return "" if !@messages[type][id] - return @messages[type][id] - end - - def getFromHash(type,key) - delayedLoad - return key if !@messages || !@messages[type] || !key - id=Messages.stringToKey(key) - return key if !@messages[type][id] - return @messages[type][id] - end - - def getFromMapHash(type,key) - delayedLoad - return key if !@messages - return key if !@messages[0] - return key if !@messages[0][type] && !@messages[0][0] - id=Messages.stringToKey(key) - if @messages[0][type] && @messages[0][type][id] - return @messages[0][type][id] - elsif @messages[0][0] && @messages[0][0][id] - return @messages[0][0][id] - end - return key - end -end - - - -module MessageTypes - # Value 0 is used for common event and map event text - Species = 1 - Kinds = 2 - Entries = 3 - FormNames = 4 - Moves = 5 - MoveDescriptions = 6 - Items = 7 - ItemPlurals = 8 - ItemDescriptions = 9 - Abilities = 10 - AbilityDescs = 11 - Types = 12 - TrainerTypes = 13 - TrainerNames = 14 - BeginSpeech = 15 - EndSpeechWin = 16 - EndSpeechLose = 17 - RegionNames = 18 - PlaceNames = 19 - PlaceDescriptions = 20 - MapNames = 21 - PhoneMessages = 22 - TrainerLoseText = 23 - ScriptTexts = 24 - RibbonNames = 25 - RibbonDescriptions = 26 - @@messages = Messages.new - @@messagesFallback = Messages.new("Data/messages.dat",true) - - def self.stringToKey(str) - return Messages.stringToKey(str) - end - - def self.normalizeValue(value) - return Messages.normalizeValue(value) - end - - def self.denormalizeValue(value) - Messages.denormalizeValue(value) - end - - def self.writeObject(f,msgs,secname) - Messages.denormalizeValue(str) - end - - def self.extract(outfile) - @@messages.extract(outfile) - end - - def self.setMessages(type,array) - @@messages.setMessages(type,array) - end - - def self.addMessages(type,array) - @@messages.addMessages(type,array) - end - - def self.createHash(type,array) - Messages.createHash(type,array) - end - - def self.addMapMessagesAsHash(type,array) - @@messages.addMapMessagesAsHash(type,array) - end - - def self.setMapMessagesAsHash(type,array) - @@messages.setMapMessagesAsHash(type,array) - end - - def self.addMessagesAsHash(type,array) - @@messages.addMessagesAsHash(type,array) - end - - def self.setMessagesAsHash(type,array) - @@messages.setMessagesAsHash(type,array) - end - - def self.saveMessages(filename=nil) - @@messages.saveMessages(filename) - end - - def self.loadMessageFile(filename) - @@messages.loadMessageFile(filename) - end - - def self.get(type,id) - ret=@@messages.get(type,id) - if ret=="" - ret=@@messagesFallback.get(type,id) - end - return ret - end - - def self.getCount(type) - c1=@@messages.getCount(type) - c2=@@messagesFallback.getCount(type) - return c1>c2 ? c1 : c2 - end - - def self.getOriginal(type,id) - return @@messagesFallback.get(type,id) - end - - def self.getFromHash(type,key) - @@messages.getFromHash(type,key) - end - - def self.getFromMapHash(type,key) - @@messages.getFromMapHash(type,key) - end -end - - - -def pbLoadMessages(file) - return MessageTypes.loadMessageFile(file) -end - -def pbGetMessageCount(type) - return MessageTypes.getCount(type) -end - -def pbGetMessage(type,id) - return MessageTypes.get(type,id) -end - -def pbGetMessageFromHash(type,id) - return MessageTypes.getFromHash(type,id) -end - -# Replaces first argument with a localized version and formats the other -# parameters by replacing {1}, {2}, etc. with those placeholders. -def _INTL(*arg) - begin - string=MessageTypes.getFromHash(MessageTypes::ScriptTexts,arg[0]) - rescue - string=arg[0] - end - string=string.clone - for i in 1...arg.length - string.gsub!(/\{#{i}\}/,"#{arg[i]}") - end - return string -end - -# Replaces first argument with a localized version and formats the other -# parameters by replacing {1}, {2}, etc. with those placeholders. -# This version acts more like sprintf, supports e.g. {1:d} or {2:s} -def _ISPRINTF(*arg) - begin - string=MessageTypes.getFromHash(MessageTypes::ScriptTexts,arg[0]) - rescue - string=arg[0] - end - string=string.clone - for i in 1...arg.length - string.gsub!(/\{#{i}\:([^\}]+?)\}/) { |m| - next sprintf("%"+$1,arg[i]) - } - end - return string -end - -def _I(str) - return _MAPINTL($game_map.map_id,str) -end - -def _MAPINTL(mapid,*arg) - string=MessageTypes.getFromMapHash(mapid,arg[0]) - string=string.clone - for i in 1...arg.length - string.gsub!(/\{#{i}\}/,"#{arg[i]}") - end - return string -end - -def _MAPISPRINTF(mapid,*arg) - string=MessageTypes.getFromMapHash(mapid,arg[0]) - string=string.clone - for i in 1...arg.length - string.gsub!(/\{#{i}\:([^\}]+?)\}/) { |m| - next sprintf("%"+$1,arg[i]) - } - end - return string -end diff --git a/Data/Scripts/001_Technical/004_Input.rb b/Data/Scripts/001_Technical/004_Input.rb deleted file mode 100644 index 952965d7b..000000000 --- a/Data/Scripts/001_Technical/004_Input.rb +++ /dev/null @@ -1,33 +0,0 @@ -module Input - USE = C - BACK = B - ACTION = A - JUMPUP = X - JUMPDOWN = Y - SPECIAL = Z - AUX1 = L - AUX2 = R - - unless defined?(update_KGC_ScreenCapture) - class << Input - alias update_KGC_ScreenCapture update - end - end - - def self.update - update_KGC_ScreenCapture - if trigger?(Input::F8) - pbScreenCapture - end - end -end - -module Mouse - module_function - - # Returns the position of the mouse relative to the game window. - def getMousePos(catch_anywhere = false) - return nil unless Input.mouse_in_window || catch_anywhere - return Input.mouse_x, Input.mouse_y - end -end diff --git a/Data/Scripts/001_Technical/005_PluginManager.rb b/Data/Scripts/001_Technical/005_PluginManager.rb deleted file mode 100644 index befca88ce..000000000 --- a/Data/Scripts/001_Technical/005_PluginManager.rb +++ /dev/null @@ -1,712 +0,0 @@ -#==============================================================================# -# Plugin Manager # -# by Marin # -# support for external plugin scripts by Luka S.J. # -# tweaked by Maruno # -#------------------------------------------------------------------------------# -# Provides a simple interface that allows plugins to require dependencies # -# at specific versions, and to specify incompatibilities between plugins. # -# # -# Supports external scripts that are in .rb files in folders within the # -# Plugins folder. # -#------------------------------------------------------------------------------# -# Usage: # -# # -# A Pokémon Essentials plugin should register itself using the PluginManager. # -# The simplest way to do so, for a plugin without dependencies, is as follows: # -# # -# PluginManager.register({ # -# :name => "Basic Plugin", # -# :version => "1.0", # -# :link => "https://reliccastle.com/link-to-the-plugin/", # -# :credits => "Marin" # -# }) # -# # -# The link portion here is optional, but recommended. This will be shown in # -# the error message if the PluginManager detects that this plugin needs to be # -# updated. # -# # -# A plugin's version should be in the format X.Y.Z, but the number of digits # -# you use does not matter. You can also use Xa, Xb, Xc, Ya, etc. # -# What matters is that you use it consistently, so that it can be compared. # -# # -# IF there are multiple people to credit, their names should be in an array. # -# If there is only one credit, it does not need an array: # -# # -# :credits => "Marin" # -# :credits => ["Marin", "Maruno"], # -# # -# # -# # -# Dependency: # -# # -# A plugin can require another plugin to be installed in order to work. For # -# example, the "Simple Extension" plugin depends on the above "Basic Plugin" # -# like so: # -# # -# PluginManager.register({ # -# :name => "Simple Extension", # -# :version => "1.0", # -# :link => "https://reliccastle.com/link-to-the-plugin/", # -# :credits => ["Marin", "Maruno"], # -# :dependencies => ["Basic Plugin"] # -# }) # -# # -# If there are multiple dependencies, they should be listed in an array. If # -# there is only one dependency, it does not need an array: # -# # -# :dependencies => "Basic Plugin" # -# # -# To require a minimum version of a dependency plugin, you should turn the # -# dependency's name into an array which contains the name and the version # -# (both as strings). For example, to require "Basic Plugin" version 1.2 or # -# higher, you would write: # -# # -# :dependencies => [ # -# ["Basic Plugin", "1.2"] # -# ] # -# # -# To require a specific version (no higher and no lower) of a dependency # -# plugin, you should add the :exact flag as the first thing in the array for # -# that dependency: # -# # -# :dependencies => [ # -# [:exact, "Basic Plugin", "1.2"] # -# ] # -# # -# If your plugin can work without another plugin, but it is incompatible with # -# an old version of that other plugin, you should list it as an optional # -# dependency. If that other plugin is present in a game, then this optional # -# dependency will check whether it meets the minimum version required for your # -# plugin. Write it in the same way as any other dependency as described above, # -# but use the :optional flag instead. # -# # -# :dependencies => [ # -# [:optional, "QoL Improvements", "1.1"] # -# ] # -# # -# The :optional_exact flag is a combination of :optional and :exact. # -# # -# # -# # -# Incompatibility: # -# # -# If your plugin is known to be incompatible with another plugin, you should # -# list that other plugin as such. Only one of the two plugins needs to list # -# that it is incompatible with the other. # -# # -# PluginManager.register({ # -# :name => "QoL Improvements", # -# :version => "1.0", # -# :link => "https://reliccastle.com/link-to-the-plugin/", # -# :credits => "Marin", # -# :incompatibilities => [ # -# "Simple Extension" # -# ] # -# }) # -# # -#------------------------------------------------------------------------------# -# Plugin folder: # -# # -# The Plugin folder is treated like the PBS folder, but for script files for # -# plugins. Each plugin has its own folder within the Plugin folder. Each # -# plugin must have a meta.txt file in its folder, which contains information # -# about that plugin. Folders without this meta.txt file are ignored. # -# # -# Scripts must be in .rb files. You should not put any other files into a # -# plugin's folder except for script files and meta.txt. # -# # -# When the game is compiled, scripts in these folders are read and converted # -# into a usable format, and saved in the file Data/PluginScripts.rxdata. # -# Script files are loaded in order of their name and subfolder, so it is wise # -# to name script files "001_first script.rb", "002_second script.rb", etc. to # -# ensure they are loaded in the correct order. # -# # -# When the game is compressed for distribution, the Plugin folder and all its # -# contents should be deleted (like the PBS folder), because its contents will # -# be unused (they will have been compiled into the PluginScripts.rxdata file). # -# # -# The contents of meta.txt are as follows: # -# # -# Name = Simple Extension # -# Version = 1.0 # -# Requires = Basic Plugin # -# Requires = Useful Utilities,1.1 # -# Conflicts = Complex Extension # -# Conflicts = Extended Windows # -# Link = https://reliccastle.com/link-to-the-plugin/ # -# Credits = Luka S.J.,Maruno,Marin # -# # -# These lines are related to what is described above. You can have multiple # -# "Requires" and "Conflicts" lines, each listing a single other plugin that is # -# either a dependency or a conflict respectively. # -# # -# Examples of the "Requires" line: # -# # -# Requires = Basic Plugin # -# Requires = Basic Plugin,1.1 # -# Requires = Basic Plugin,1.1,exact # -# Requires = Basic Plugin,1.1,optional # -# Exact = Basic Plugin,1.1 # -# Optional = Basic Plugin,1.1 # -# # -# The "Exact" and "Optional" lines are equivalent to the "Requires" lines # -# that contain those keywords. # -# # -# There is also a "Scripts" line, which lists one or more script files that # -# should be loaded first. You can have multiple "Scripts" lines. However, you # -# can achieve the same effect by simply naming your script files in # -# alphanumeric order to make them load in a particular order, so the "Scripts" # -# line should not be necessary. # -# # -#------------------------------------------------------------------------------# -# Please give credit when using this. # -#==============================================================================# - -module PluginManager - # Holds all registered plugin data. - @@Plugins = {} - #----------------------------------------------------------------------------- - # Registers a plugin and tests its dependencies and incompatibilities. - #----------------------------------------------------------------------------- - def self.register(options) - name = nil - version = nil - link = nil - dependencies = nil - incompats = nil - credits = [] - order = [:name, :version, :link, :dependencies, :incompatibilities, :credits] - # Ensure it first reads the plugin's name, which is used in error reporting, - # by sorting the keys - keys = options.keys.sort do |a, b| - idx_a = order.index(a) - idx_a = order.size if idx_a == -1 - idx_b = order.index(b) - idx_b = order.size if idx_b == -1 - next idx_a <=> idx_b - end - for key in keys - value = options[key] - case key - when :name # Plugin name - if nil_or_empty?(value) - self.error("Plugin name must be a non-empty string.") - end - if !@@Plugins[value].nil? - self.error("A plugin called '#{value}' already exists.") - end - name = value - when :version # Plugin version - if nil_or_empty?(value) - self.error("Plugin version must be a string.") - end - version = value - when :link # Plugin website - if nil_or_empty?(value) - self.error("Plugin link must be a non-empty string.") - end - link = value - when :dependencies # Plugin dependencies - dependencies = value - dependencies = [dependencies] if !dependencies.is_a?(Array) || !dependencies[0].is_a?(Array) - for dep in value - if dep.is_a?(String) # "plugin name" - if !self.installed?(dep) - self.error("Plugin '#{name}' requires plugin '#{dep}' to be installed above it.") - end - elsif dep.is_a?(Array) - case dep.size - when 1 # ["plugin name"] - if dep[0].is_a?(String) - dep_name = dep[0] - if !self.installed?(dep_name) - self.error("Plugin '#{name}' requires plugin '#{dep_name}' to be installed above it.") - end - else - self.error("Expected the plugin name as a string, but got #{dep[0].inspect}.") - end - when 2 # ["plugin name", "version"] - if dep[0].is_a?(Symbol) - self.error("A plugin version comparator symbol was given but no version was given.") - elsif dep[0].is_a?(String) && dep[1].is_a?(String) - dep_name = dep[0] - dep_version = dep[1] - next if self.installed?(dep_name, dep_version) - if self.installed?(dep_name) # Have plugin but lower version - msg = "Plugin '#{name}' requires plugin '#{dep_name}' version #{dep_version} or higher, " + - "but the installed version is #{self.version(dep_name)}." - if dep_link = self.link(dep_name) - msg += "\r\nCheck #{dep_link} for an update to plugin '#{dep_name}'." - end - self.error(msg) - else # Don't have plugin - self.error("Plugin '#{name}' requires plugin '#{dep_name}' version #{dep_version} " + - "or higher to be installed above it.") - end - end - when 3 # [:optional/:exact/:optional_exact, "plugin name", "version"] - if !dep[0].is_a?(Symbol) - self.error("Expected first dependency argument to be a symbol, but got #{dep[0].inspect}.") - end - if !dep[1].is_a?(String) - self.error("Expected second dependency argument to be a plugin name, but got #{dep[1].inspect}.") - end - if !dep[2].is_a?(String) - self.error("Expected third dependency argument to be the plugin version, but got #{dep[2].inspect}.") - end - dep_arg = dep[0] - dep_name = dep[1] - dep_version = dep[2] - optional = false - exact = false - case dep_arg - when :optional - optional = true - when :exact - exact = true - when :optional_exact - optional = true - exact = true - else - self.error("Expected first dependency argument to be one of " + - ":optional, :exact or :optional_exact, but got #{dep_arg.inspect}.") - end - if optional - if self.installed?(dep_name) && # Have plugin but lower version - !self.installed?(dep_name, dep_version, exact) - msg = "Plugin '#{name}' requires plugin '#{dep_name}', if installed, to be version #{dep_version}" - msg << " or higher" if !exact - msg << ", but the installed version was #{self.version(dep_name)}." - if dep_link = self.link(dep_name) - msg << "\r\nCheck #{dep_link} for an update to plugin '#{dep_name}'." - end - self.error(msg) - end - elsif !self.installed?(dep_name, dep_version, exact) - if self.installed?(dep_name) # Have plugin but lower version - msg = "Plugin '#{name}' requires plugin '#{dep_name}' to be version #{dep_version}" - msg << " or later" if !exact - msg << ", but the installed version was #{self.version(dep_name)}." - if dep_link = self.link(dep_name) - msg << "\r\nCheck #{dep_link} for an update to plugin '#{dep_name}'." - end - self.error(msg) - else # Don't have plugin - msg = "Plugin '#{name}' requires plugin '#{dep_name}' version #{dep_version} " - msg << "or later" if !exact - msg << "to be installed above it." - self.error(msg) - end - end - end - end - end - when :incompatibilities # Plugin incompatibilities - incompats = value - incompats = [incompats] if !incompats.is_a?(Array) - for incompat in incompats - if self.installed?(incompat) - self.error("Plugin '#{name}' is incompatible with '#{incompat}'. " + - "They cannot both be used at the same time.") - end - end - when :credits # Plugin credits - value = [value] if value.is_a?(String) - if value.is_a?(Array) - for entry in value - if !entry.is_a?(String) - self.error("Plugin '#{name}'s credits array contains a non-string value.") - else - credits << entry - end - end - else - self.error("Plugin '#{name}'s credits field must contain a string, or a string array.") - end - else - self.error("Invalid plugin registry key '#{key}'.") - end - end - for plugin in @@Plugins.values - if plugin[:incompatibilities] && plugin[:incompatibilities].include?(name) - self.error("Plugin '#{plugin[:name]}' is incompatible with '#{name}'. " + - "They cannot both be used at the same time.") - end - end - # Add plugin to class variable - @@Plugins[name] = { - :name => name, - :version => version, - :link => link, - :dependencies => dependencies, - :incompatibilities => incompats, - :credits => credits - } - end - #----------------------------------------------------------------------------- - # Throws a pure error message without stack trace or any other useless info. - #----------------------------------------------------------------------------- - def self.error(msg) - Graphics.update - t = Thread.new do - echoln "Plugin Error:\r\n#{msg}" - p "Plugin Error: #{msg}" - Thread.exit - end - while t.status - Graphics.update - end - Kernel.exit! true - end - #----------------------------------------------------------------------------- - # Returns true if the specified plugin is installed. - # If the version is specified, this version is taken into account. - # If mustequal is true, the version must be a match with the specified version. - #----------------------------------------------------------------------------- - def self.installed?(plugin_name, plugin_version = nil, mustequal = false) - plugin = @@Plugins[plugin_name] - return false if plugin.nil? - return true if plugin_version.nil? - comparison = compare_versions(plugin[:version], plugin_version) - return true if !mustequal && comparison >= 0 - return true if mustequal && comparison == 0 - end - #----------------------------------------------------------------------------- - # Returns the string names of all installed plugins. - #----------------------------------------------------------------------------- - def self.plugins - return @@Plugins.keys - end - #----------------------------------------------------------------------------- - # Returns the installed version of the specified plugin. - #----------------------------------------------------------------------------- - def self.version(plugin_name) - return if !installed?(plugin_name) - return @@Plugins[plugin_name][:version] - end - #----------------------------------------------------------------------------- - # Returns the link of the specified plugin. - #----------------------------------------------------------------------------- - def self.link(plugin_name) - return if !installed?(plugin_name) - return @@Plugins[plugin_name][:link] - end - #----------------------------------------------------------------------------- - # Returns the credits of the specified plugin. - #----------------------------------------------------------------------------- - def self.credits(plugin_name) - return if !installed?(plugin_name) - return @@Plugins[plugin_name][:credits] - end - #----------------------------------------------------------------------------- - # Compares two versions given in string form. v1 should be the plugin version - # you actually have, and v2 should be the minimum/desired plugin version. - # Return values: - # 1 if v1 is higher than v2 - # 0 if v1 is equal to v2 - # -1 if v1 is lower than v2 - #----------------------------------------------------------------------------- - def self.compare_versions(v1, v2) - d1 = v1.split("") - d1.insert(0, "0") if d1[0] == "." # Turn ".123" into "0.123" - while d1[-1] == "."; d1 = d1[0..-2]; end # Turn "123." into "123" - d2 = v2.split("") - d2.insert(0, "0") if d2[0] == "." # Turn ".123" into "0.123" - while d2[-1] == "."; d2 = d2[0..-2]; end # Turn "123." into "123" - for i in 0...[d1.size, d2.size].max # Compare each digit in turn - c1 = d1[i] - c2 = d2[i] - if c1 - return 1 if !c2 - return 1 if c1.to_i(16) > c2.to_i(16) - return -1 if c1.to_i(16) < c2.to_i(16) - else - return -1 if c2 - end - end - return 0 - end - #----------------------------------------------------------------------------- - # formats the error message - #----------------------------------------------------------------------------- - def self.pluginErrorMsg(name, script) - # begin message formatting - message = "[Infinite Fusion version #{Settings::GAME_VERSION_NUMBER}]\r\n" - message += "#{Essentials::ERROR_TEXT}\r\n" # For third party scripts to add to - message += "Error in Plugin [#{name}]:\r\n" - message += "#{$!.class} occurred.\r\n" - # go through message content - for line in $!.message.split("\r\n") - next if nil_or_empty?(line) - n = line[/\d+/] - err = line.split(":")[-1].strip - lms = line.split(":")[0].strip - err.gsub!(n, "") if n - err = err.capitalize if err.is_a?(String) && !err.empty? - linum = n ? "Line #{n}: " : "" - message += "#{linum}#{err}: #{lms}\r\n" - end - # show last 10 lines of backtrace - message += "\r\nBacktrace:\r\n" - $!.backtrace[0, 10].each { |i| message += "#{i}\r\n" } - # output to log - errorlog = "errorlog.txt" - errorlog = RTP.getSaveFileName("errorlog.txt") if (Object.const_defined?(:RTP) rescue false) - File.open(errorlog, "ab") do |f| - f.write("\r\n=================\r\n\r\n[#{Time.now}]\r\n") - f.write(message) - end - # format/censor the error log directory - errorlogline = errorlog.gsub("/", "\\") - errorlogline.sub!(Dir.pwd + "\\", "") - errorlogline.sub!(pbGetUserName, "USERNAME") - errorlogline = "\r\n" + errorlogline if errorlogline.length > 20 - # output message - print("#{message}\r\nThis exception was logged in #{errorlogline}.\r\nHold Ctrl when closing this message to copy it to the clipboard.") - # Give a ~500ms coyote time to start holding Control - t = System.delta - until (System.delta - t) >= 500000 - Input.update - if Input.press?(Input::CTRL) - Input.clipboard = message - break - end - end - end - #----------------------------------------------------------------------------- - # Used to read the metadata file - #----------------------------------------------------------------------------- - def self.readMeta(dir, file) - filename = "#{dir}/#{file}" - meta = {} - # read file - Compiler.pbCompilerEachPreppedLine(filename) { |line, line_no| - # split line up into property name and values - if !line[/^\s*(\w+)\s*=\s*(.*)$/] - raise _INTL("Bad line syntax (expected syntax like XXX=YYY)\r\n{1}", FileLineData.linereport) - end - property = $~[1].upcase - data = $~[2].split(',') - data.each_with_index { |value, i| data[i] = value.strip } - # begin formatting data hash - case property - when 'REQUIRES' - meta[:dependencies] = [] if !meta[:dependencies] - if data.length < 2 # No version given, just push name of plugin dependency - meta[:dependencies].push(data[0]) - next - elsif data.length == 2 # Push name and version of plugin dependency - meta[:dependencies].push([data[0], data[1]]) - else # Push dependency type, name and version of plugin dependency - meta[:dependencies].push([data[2].downcase.to_sym, data[0], data[1]]) - end - when 'EXACT' - next if data.length < 2 # Exact dependencies must have a version given; ignore if not - meta[:dependencies] = [] if !meta[:dependencies] - meta[:dependencies].push([:exact, data[0], data[1]]) - when 'OPTIONAL' - next if data.length < 2 # Optional dependencies must have a version given; ignore if not - meta[:dependencies] = [] if !meta[:dependencies] - meta[:dependencies].push([:optional, data[0], data[1]]) - when 'CONFLICTS' - meta[:incompatibilities] = [] if !meta[:incompatibilities] - data.each { |value| meta[:incompatibilities].push(value) if value && !value.empty? } - when 'SCRIPTS' - meta[:scripts] = [] if !meta[:scripts] - data.each { |scr| meta[:scripts].push(scr) } - when 'CREDITS' - meta[:credits] = data - when 'LINK', 'WEBSITE' - meta[:link] = data[0] - else - meta[property.downcase.to_sym] = data[0] - end - } - # generate a list of all script files to be loaded, in the order they are to - # be loaded (files listed in the meta file are loaded first) - meta[:scripts] = [] if !meta[:scripts] - # get all script files from plugin Dir - for fl in Dir.all(dir) - next if !fl.include?(".rb") - meta[:scripts].push(fl.gsub("#{dir}/", "")) - end - # ensure no duplicate script files are queued - meta[:scripts].uniq! - # return meta hash - return meta - end - #----------------------------------------------------------------------------- - # Get a list of all the plugin directories to inspect - #----------------------------------------------------------------------------- - def self.listAll - return [] - return [] if !$DEBUG || safeExists?("Game.rgssad") - # get a list of all directories in the `Plugins/` folder - dirs = [] - Dir.get("Plugins").each { |d| dirs.push(d) if Dir.safe?(d) } - # return all plugins - return dirs - end - #----------------------------------------------------------------------------- - # Catch any potential loop with dependencies and raise an error - #----------------------------------------------------------------------------- - def self.validateDependencies(name, meta, og = nil) - # exit if no registered dependency - return nil if !meta[name] || !meta[name][:dependencies] - og = [name] if !og - # go through all dependencies - for dname in meta[name][:dependencies] - # clean the name to a simple string - dname = dname[0] if dname.is_a?(Array) && dname.length == 2 - dname = dname[1] if dname.is_a?(Array) && dname.length == 3 - # catch looping dependency issue - self.error("Plugin '#{og[0]}' has looping dependencies which cannot be resolved automatically.") if !og.nil? && og.include?(dname) - new_og = og.clone - new_og.push(dname) - self.validateDependencies(dname, meta, new_og) - end - return name - end - #----------------------------------------------------------------------------- - # Sort load order based on dependencies (this ends up in reverse order) - #----------------------------------------------------------------------------- - def self.sortLoadOrder(order, plugins) - # go through the load order - for o in order - next if !plugins[o] || !plugins[o][:dependencies] - # go through all dependencies - for dname in plugins[o][:dependencies] - # clean the name to a simple string - dname = dname[0] if dname.is_a?(Array) && dname.length == 2 - dname = dname[1] if dname.is_a?(Array) && dname.length == 3 - # catch missing dependency - self.error("Plugin '#{o}' requires plugin '#{dname}' to work properly.") if !order.include?(dname) - # skip if already sorted - next if order.index(dname) > order.index(o) - # catch looping dependency issue - order.swap(o, dname) - order = self.sortLoadOrder(order, plugins) - end - end - return order - end - #----------------------------------------------------------------------------- - # Get the order in which to load plugins - #----------------------------------------------------------------------------- - def self.getPluginOrder - plugins = {} - order = [] - # Find all plugin folders that have a meta.txt and add them to the list of - # plugins. - for dir in self.listAll - # skip if there is no meta file - next if !safeExists?(dir + "/meta.txt") - ndx = order.length - meta = self.readMeta(dir, "meta.txt") - meta[:dir] = dir - # raise error if no name defined for plugin - self.error("No 'Name' metadata defined for plugin located at '#{dir}'.") if !meta[:name] - # raise error if no script defined for plugin - self.error("No 'Scripts' metadata defined for plugin located at '#{dir}'.") if !meta[:scripts] - plugins[meta[:name]] = meta - # raise error if a plugin with the same name already exists - self.error("A plugin called '#{meta[:name]}' already exists in the load order.") if order.include?(meta[:name]) - order.insert(ndx, meta[:name]) - end - # validate all dependencies - order.each { |o| self.validateDependencies(o, plugins) } - # sort the load order - return self.sortLoadOrder(order, plugins).reverse, plugins - end - #----------------------------------------------------------------------------- - # Check if plugins need compiling - #----------------------------------------------------------------------------- - def self.needCompiling?(order, plugins) - # fixed actions - return false if !$DEBUG || safeExists?("Game.rgssad") - return true if !safeExists?("Data/PluginScripts.rxdata") - Input.update - return true if Input.press?(Input::CTRL) - # analyze whether or not to push recompile - mtime = File.mtime("Data/PluginScripts.rxdata") - for o in order - # go through all the registered plugin scripts - scr = plugins[o][:scripts] - dir = plugins[o][:dir] - for sc in scr - return true if File.mtime("#{dir}/#{sc}") > mtime - end - return true if File.mtime("#{dir}/meta.txt") > mtime - end - return false - end - #----------------------------------------------------------------------------- - # Check if plugins need compiling - #----------------------------------------------------------------------------- - def self.compilePlugins(order, plugins) - echo 'Compiling plugin scripts...' - scripts = [] - # go through the entire order one by one - for o in order - # save name, metadata and scripts array - meta = plugins[o].clone - meta.delete(:scripts) - meta.delete(:dir) - dat = [o, meta, []] - # iterate through each file to deflate - for file in plugins[o][:scripts] - File.open("#{plugins[o][:dir]}/#{file}", 'rb') do |f| - dat[2].push([file, Zlib::Deflate.deflate(f.read)]) - end - end - # push to the main scripts array - scripts.push(dat) - end - # save to main `PluginScripts.rxdata` file - File.open("Data/PluginScripts.rxdata", 'wb') { |f| Marshal.dump(scripts, f) } - # collect garbage - GC.start - echoln ' done.' - echoln '' - end - #----------------------------------------------------------------------------- - # Check if plugins need compiling - #----------------------------------------------------------------------------- - def self.runPlugins - # get the order of plugins to interpret - order, plugins = self.getPluginOrder - # compile if necessary - self.compilePlugins(order, plugins) if self.needCompiling?(order, plugins) - # load plugins - scripts = load_data("Data/PluginScripts.rxdata") - echoed_plugins = [] - for plugin in scripts - # get the required data - name, meta, script = plugin - # register plugin - self.register(meta) - # go through each script and interpret - for scr in script - # turn code into plaintext - code = Zlib::Inflate.inflate(scr[1]).force_encoding(Encoding::UTF_8) - # get rid of tabs - code.gsub!("\t", " ") - # construct filename - sname = scr[0].gsub("\\","/").split("/")[-1] - fname = "[#{name}] #{sname}" - # try to run the code - begin - eval(code, TOPLEVEL_BINDING, fname) - echoln "Loaded plugin: #{name}" if !echoed_plugins.include?(name) - echoed_plugins.push(name) - rescue Exception # format error message to display - self.pluginErrorMsg(name, sname) - Kernel.exit! true - end - end - end - echoln '' if !echoed_plugins.empty? - end - #----------------------------------------------------------------------------- -end diff --git a/Data/Scripts/001_Technical/006_RPG_Sprite.rb b/Data/Scripts/001_Technical/006_RPG_Sprite.rb deleted file mode 100644 index 7f5e36a3e..000000000 --- a/Data/Scripts/001_Technical/006_RPG_Sprite.rb +++ /dev/null @@ -1,534 +0,0 @@ -class SpriteAnimation - @@_animations = [] - @@_reference_count = {} - - def initialize(sprite) - @sprite = sprite - end - - %w[ - x y ox oy viewport flash src_rect opacity tone - ].each_with_index do |s, _i| - eval <<-__END__ - - def #{s}(*arg) - @sprite.#{s}(*arg) - end - - __END__ - end - - def self.clear - @@_animations.clear - end - - def dispose - dispose_animation - dispose_loop_animation - end - - def animation(animation, hit, height = 3) - dispose_animation - @_animation = animation - return if @_animation == nil - @_animation_hit = hit - @_animation_height = height - @_animation_duration = @_animation.frame_max - fr = 20 - if @_animation.name[/\[\s*(\d+?)\s*\]\s*$/] - fr = $~[1].to_i - end - @_animation_frame_skip = Graphics.frame_rate / fr - animation_name = @_animation.animation_name - animation_hue = @_animation.animation_hue - bitmap = pbGetAnimation(animation_name, animation_hue) - if @@_reference_count.include?(bitmap) - @@_reference_count[bitmap] += 1 - else - @@_reference_count[bitmap] = 1 - end - @_animation_sprites = [] - if @_animation.position != 3 || !@@_animations.include?(animation) - 16.times do - sprite = ::Sprite.new(self.viewport) - sprite.bitmap = bitmap - sprite.visible = false - @_animation_sprites.push(sprite) - end - unless @@_animations.include?(animation) - @@_animations.push(animation) - end - end - update_animation - end - - def loop_animation(animation) - return if animation == @_loop_animation - dispose_loop_animation - @_loop_animation = animation - return if @_loop_animation == nil - @_loop_animation_index = 0 - fr = 20 - if @_animation.name[/\[\s*(\d+?)\s*\]\s*$/] - fr = $~[1].to_i - end - @_loop_animation_frame_skip = Graphics.frame_rate / fr - animation_name = @_loop_animation.animation_name - animation_hue = @_loop_animation.animation_hue - bitmap = pbGetAnimation(animation_name, animation_hue) - if @@_reference_count.include?(bitmap) - @@_reference_count[bitmap] += 1 - else - @@_reference_count[bitmap] = 1 - end - @_loop_animation_sprites = [] - 16.times do - sprite = ::Sprite.new(self.viewport) - sprite.bitmap = bitmap - sprite.visible = false - @_loop_animation_sprites.push(sprite) - end - update_loop_animation - end - - def dispose_animation - return if @_animation_sprites == nil - sprite = @_animation_sprites[0] - if sprite != nil - @@_reference_count[sprite.bitmap] -= 1 - if @@_reference_count[sprite.bitmap] == 0 - sprite.bitmap.dispose - end - end - for sprite in @_animation_sprites - sprite.dispose - end - @_animation_sprites = nil - @_animation = nil - end - - def dispose_loop_animation - return if @_loop_animation_sprites == nil - sprite = @_loop_animation_sprites[0] - if sprite != nil - @@_reference_count[sprite.bitmap] -= 1 - if @@_reference_count[sprite.bitmap] == 0 - sprite.bitmap.dispose - end - end - for sprite in @_loop_animation_sprites - sprite.dispose - end - @_loop_animation_sprites = nil - @_loop_animation = nil - end - - def active? - return @_loop_animation_sprites != nil || @_animation_sprites != nil - end - - def effect? - return @_animation_duration > 0 - end - - def update - if @_animation != nil - quick_update = true - if Graphics.frame_count % @_animation_frame_skip == 0 - @_animation_duration -= 1 - quick_update = false - end - update_animation(quick_update) - end - if @_loop_animation != nil - quick_update = (Graphics.frame_count % @_loop_animation_frame_skip != 0) - update_loop_animation(quick_update) - if !quick_update - @_loop_animation_index += 1 - @_loop_animation_index %= @_loop_animation.frame_max - end - end - end - - def update_animation(quick_update = false) - if @_animation_duration <= 0 - dispose_animation - return - end - frame_index = @_animation.frame_max - @_animation_duration - cell_data = @_animation.frames[frame_index].cell_data - position = @_animation.position - animation_set_sprites(@_animation_sprites, cell_data, position, quick_update) - return if quick_update - for timing in @_animation.timings - next if timing.frame != frame_index - animation_process_timing(timing, @_animation_hit) - end - end - - def update_loop_animation(quick_update = false) - frame_index = @_loop_animation_index - cell_data = @_loop_animation.frames[frame_index].cell_data - position = @_loop_animation.position - animation_set_sprites(@_loop_animation_sprites, cell_data, position, quick_update) - return if quick_update - for timing in @_loop_animation.timings - next if timing.frame != frame_index - animation_process_timing(timing, true) - end - end - - def animation_set_sprites(sprites, cell_data, position, quick_update = false) - sprite_x = 320 - sprite_y = 240 - if position == 3 - if self.viewport != nil - sprite_x = self.viewport.rect.width / 2 - sprite_y = self.viewport.rect.height - 160 - end - else - sprite_x = self.x - self.ox + self.src_rect.width / 2 - sprite_y = self.y - self.oy - sprite_y += self.src_rect.height / 2 if position == 1 - sprite_y += self.src_rect.height if position == 2 - end - for i in 0..15 - sprite = sprites[i] - pattern = cell_data[i, 0] - if sprite == nil || pattern == nil || pattern == -1 - sprite.visible = false if sprite != nil - next - end - sprite.x = sprite_x + cell_data[i, 1] - sprite.y = sprite_y + cell_data[i, 2] - next if quick_update - sprite.visible = true - sprite.src_rect.set(pattern % 5 * 192, pattern / 5 * 192, 192, 192) - case @_animation_height - when 0 then sprite.z = 1 - when 1 then sprite.z = sprite.y+32+15 - when 2 then sprite.z = sprite.y+32+32+17 - else sprite.z = 2000 - end - sprite.ox = 96 - sprite.oy = 96 - sprite.zoom_x = cell_data[i, 3] / 100.0 - sprite.zoom_y = cell_data[i, 3] / 100.0 - sprite.angle = cell_data[i, 4] - sprite.mirror = (cell_data[i, 5] == 1) - sprite.tone = self.tone - sprite.opacity = cell_data[i, 6] * self.opacity / 255.0 - sprite.blend_type = cell_data[i, 7] - end - end - - def animation_process_timing(timing, hit) - if timing.condition == 0 || - (timing.condition == 1 && hit == true) || - (timing.condition == 2 && hit == false) - if timing.se.name != "" - se = timing.se - pbSEPlay(se) - end - case timing.flash_scope - when 1 - self.flash(timing.flash_color, timing.flash_duration * 2) - when 2 - if self.viewport != nil - self.viewport.flash(timing.flash_color, timing.flash_duration * 2) - end - when 3 - self.flash(nil, timing.flash_duration * 2) - end - end - end - - def x=(x) - sx = x - self.x - return if sx == 0 - if @_animation_sprites != nil - for i in 0..15 - @_animation_sprites[i].x += sx - end - end - if @_loop_animation_sprites != nil - for i in 0..15 - @_loop_animation_sprites[i].x += sx - end - end - end - - def y=(y) - sy = y - self.y - return if sy == 0 - if @_animation_sprites != nil - for i in 0..15 - @_animation_sprites[i].y += sy - end - end - if @_loop_animation_sprites != nil - for i in 0..15 - @_loop_animation_sprites[i].y += sy - end - end - end -end - - - -module RPG - class Sprite < ::Sprite - def initialize(viewport = nil) - super(viewport) - @_whiten_duration = 0 - @_appear_duration = 0 - @_escape_duration = 0 - @_collapse_duration = 0 - @_damage_duration = 0 - @_animation_duration = 0 - @_blink = false - @animations = [] - @loopAnimations = [] - end - - def dispose - dispose_damage - dispose_animation - dispose_loop_animation - super - end - - def whiten - self.blend_type = 0 - self.color.set(255, 255, 255, 128) - self.opacity = 255 - @_whiten_duration = 16 - @_appear_duration = 0 - @_escape_duration = 0 - @_collapse_duration = 0 - end - - def appear - self.blend_type = 0 - self.color.set(0, 0, 0, 0) - self.opacity = 0 - @_appear_duration = 16 - @_whiten_duration = 0 - @_escape_duration = 0 - @_collapse_duration = 0 - end - - def escape - self.blend_type = 0 - self.color.set(0, 0, 0, 0) - self.opacity = 255 - @_escape_duration = 32 - @_whiten_duration = 0 - @_appear_duration = 0 - @_collapse_duration = 0 - end - - def collapse - self.blend_type = 1 - self.color.set(255, 64, 64, 255) - self.opacity = 255 - @_collapse_duration = 48 - @_whiten_duration = 0 - @_appear_duration = 0 - @_escape_duration = 0 - end - - def damage(value, critical) - dispose_damage - damage_string = (value.is_a?(Numeric)) ? value.abs.to_s : value.to_s - bitmap = Bitmap.new(160, 48) - bitmap.font.name = "Arial Black" - bitmap.font.size = 32 - bitmap.font.color.set(0, 0, 0) - bitmap.draw_text(-1, 12-1, 160, 36, damage_string, 1) - bitmap.draw_text(+1, 12-1, 160, 36, damage_string, 1) - bitmap.draw_text(-1, 12+1, 160, 36, damage_string, 1) - bitmap.draw_text(+1, 12+1, 160, 36, damage_string, 1) - if value.is_a?(Numeric) && value < 0 - bitmap.font.color.set(176, 255, 144) - else - bitmap.font.color.set(255, 255, 255) - end - bitmap.draw_text(0, 12, 160, 36, damage_string, 1) - if critical - bitmap.font.size = 20 - bitmap.font.color.set(0, 0, 0) - bitmap.draw_text(-1, -1, 160, 20, "CRITICAL", 1) - bitmap.draw_text(+1, -1, 160, 20, "CRITICAL", 1) - bitmap.draw_text(-1, +1, 160, 20, "CRITICAL", 1) - bitmap.draw_text(+1, +1, 160, 20, "CRITICAL", 1) - bitmap.font.color.set(255, 255, 255) - bitmap.draw_text(0, 0, 160, 20, "CRITICAL", 1) - end - @_damage_sprite = ::Sprite.new(self.viewport) - @_damage_sprite.bitmap = bitmap - @_damage_sprite.ox = 80 - @_damage_sprite.oy = 20 - @_damage_sprite.x = self.x - @_damage_sprite.y = self.y - self.oy / 2 - @_damage_sprite.z = 3000 - @_damage_duration = 40 - end - - def pushAnimation(array, anim) - for i in 0...array.length - next if array[i] && array[i].active? - array[i] = anim - return - end - array.push(anim) - end - - def animation(animation, hit, height = 3) - anim = SpriteAnimation.new(self) - anim.animation(animation,hit,height) - pushAnimation(@animations,anim) - end - - def loop_animation(animation) - anim = SpriteAnimation.new(self) - anim.loop_animation(animation) - pushAnimation(@loopAnimations,anim) - end - - def dispose_damage - return if @_damage_sprite == nil - @_damage_sprite.bitmap.dispose - @_damage_sprite.dispose - @_damage_sprite = nil - @_damage_duration = 0 - end - - def dispose_animation - for a in @animations - a.dispose_animation if a - end - @animations.clear - end - - def dispose_loop_animation - for a in @loopAnimations - a.dispose_loop_animation if a - end - @loopAnimations.clear - end - - def blink_on - return if @_blink - @_blink = true - @_blink_count = 0 - end - - def blink_off - return unless @_blink - @_blink = false - self.color.set(0, 0, 0, 0) - end - - def blink? - return @_blink - end - - def effect? - return true if @_whiten_duration > 0 - return true if @_appear_duration > 0 - return true if @_escape_duration > 0 - return true if @_collapse_duration > 0 - return true if @_damage_duration > 0 - for a in @animations - return true if a.effect? - end - return false - end - - def update - super - if @_whiten_duration > 0 - @_whiten_duration -= 1 - self.color.alpha = 128 - (16 - @_whiten_duration) * 10 - end - if @_appear_duration > 0 - @_appear_duration -= 1 - self.opacity = (16 - @_appear_duration) * 16 - end - if @_escape_duration > 0 - @_escape_duration -= 1 - self.opacity = 256 - (32 - @_escape_duration) * 10 - end - if @_collapse_duration > 0 - @_collapse_duration -= 1 - self.opacity = 256 - (48 - @_collapse_duration) * 6 - end - if @_damage_duration > 0 - @_damage_duration -= 1 - case @_damage_duration - when 38..39 - @_damage_sprite.y -= 4 - when 36..37 - @_damage_sprite.y -= 2 - when 34..35 - @_damage_sprite.y += 2 - when 28..33 - @_damage_sprite.y += 4 - end - @_damage_sprite.opacity = 256 - (12 - @_damage_duration) * 32 - if @_damage_duration == 0 - dispose_damage - end - end - for a in @animations - a.update - end - for a in @loopAnimations - a.update - end - if @_blink - @_blink_count = (@_blink_count + 1) % 32 - if @_blink_count < 16 - alpha = (16 - @_blink_count) * 6 - else - alpha = (@_blink_count - 16) * 6 - end - self.color.set(255, 255, 255, alpha) - end - SpriteAnimation.clear - end - - def update_animation - for a in @animations - a.update_animation if a && a.active? - end - end - - def update_loop_animation - for a in @loopAnimations - a.update_loop_animation if a && a.active? - end - end - - def x=(x) - for a in @animations - a.x = x if a - end - for a in @loopAnimations - a.x = x if a - end - super - end - - def y=(y) - for a in @animations - a.y = y if a - end - for a in @loopAnimations - a.y = y if a - end - super - end - end -end diff --git a/Data/Scripts/002_BattleSettings.rb b/Data/Scripts/002_BattleSettings.rb deleted file mode 100644 index a50ce0886..000000000 --- a/Data/Scripts/002_BattleSettings.rb +++ /dev/null @@ -1,78 +0,0 @@ -module Settings - # Whether a move's physical/special category depends on the move itself as in - # newer Gens (true), or on its type as in older Gens (false). - MOVE_CATEGORY_PER_MOVE = (MECHANICS_GENERATION >= 4) - # Whether turn order is recalculated after a Pokémon Mega Evolves. - RECALCULATE_TURN_ORDER_AFTER_MEGA_EVOLUTION = (MECHANICS_GENERATION >= 7) - # Whether turn order is recalculated after a Pokémon's Speed stat changes. - RECALCULATE_TURN_ORDER_AFTER_SPEED_CHANGES = (MECHANICS_GENERATION >= 8) - # Whether critical hits do 1.5x damage and have 4 stages (true), or they do 2x - # damage and have 5 stages as in Gen 5 (false). Also determines whether - # critical hit rate can be copied by Transform/Psych Up. - NEW_CRITICAL_HIT_RATE_MECHANICS = (MECHANICS_GENERATION >= 5) - # Whether several effects apply relating to a Pokémon's type: - # * Electric-type immunity to paralysis - # * Ghost-type immunity to being trapped - # * Grass-type immunity to powder moves and Effect Spore - # * Poison-type Pokémon can't miss when using Toxic - MORE_TYPE_EFFECTS = (MECHANICS_GENERATION >= 5) - # Whether weather caused by an ability lasts 5 rounds (true) or forever (false). - FIXED_DURATION_WEATHER_FROM_ABILITY = (MECHANICS_GENERATION >= 6) - - #============================================================================= - - # Whether X items (X Attack, etc.) raise their stat by 2 stages (true) or 1 - # (false). - X_STAT_ITEMS_RAISE_BY_TWO_STAGES = (MECHANICS_GENERATION >= 7) - # Whether some Poké Balls have catch rate multipliers from Gen 7 (true) or - # from earlier generations (false). - NEW_POKE_BALL_CATCH_RATES = (MECHANICS_GENERATION >= 7) - # Whether Soul Dew powers up Psychic and Dragon-type moves by 20% (true) or - # raises the holder's Special Attack and Special Defense by 50% (false). - SOUL_DEW_POWERS_UP_TYPES = (MECHANICS_GENERATION >= 7) - - #============================================================================= - - # The minimum number of badges required to boost each stat of a player's - # Pokémon by 1.1x, in battle only. - NUM_BADGES_BOOST_ATTACK = (MECHANICS_GENERATION >= 4) ? 999 : 1 - NUM_BADGES_BOOST_DEFENSE = (MECHANICS_GENERATION >= 4) ? 999 : 5 - NUM_BADGES_BOOST_SPATK = (MECHANICS_GENERATION >= 4) ? 999 : 7 - NUM_BADGES_BOOST_SPDEF = (MECHANICS_GENERATION >= 4) ? 999 : 7 - NUM_BADGES_BOOST_SPEED = (MECHANICS_GENERATION >= 4) ? 999 : 3 - - #============================================================================= - - # An array of items which act as Mega Rings for the player (NPCs don't need a - # Mega Ring item, just a Mega Stone held by their Pokémon). - MEGA_RINGS = [:MEGARING, :MEGABRACELET, :MEGACUFF, :MEGACHARM] - # The Game Switch which, while ON, prevents all Pokémon in battle from Mega - # Evolving even if they otherwise could. - NO_MEGA_EVOLUTION = 34 - - #============================================================================= - - # Whether the Exp gained from beating a Pokémon should be scaled depending on - # the gainer's level. - SCALED_EXP_FORMULA = (MECHANICS_GENERATION == 5 || MECHANICS_GENERATION >= 7) - # Whether the Exp gained from beating a Pokémon should be divided equally - # between each participant (true), or whether each participant should gain - # that much Exp (false). This also applies to Exp gained via the Exp Share - # (held item version) being distributed to all Exp Share holders. - SPLIT_EXP_BETWEEN_GAINERS = (MECHANICS_GENERATION <= 5) - # Whether the critical capture mechanic applies. Note that its calculation is - # based on a total of 600+ species (i.e. that many species need to be caught - # to provide the greatest critical capture chance of 2.5x), and there may be - # fewer species in your game. - ENABLE_CRITICAL_CAPTURES = false#(MECHANICS_GENERATION >= 5) - # Whether Pokémon gain Exp for capturing a Pokémon. - GAIN_EXP_FOR_CAPTURE = (MECHANICS_GENERATION >= 5) - # The Game Switch which, whie ON, prevents the player from losing money if - # they lose a battle (they can still gain money from trainers for winning). - NO_MONEY_LOSS = 33 - # Whether party Pokémon check whether they can evolve after all battles - # regardless of the outcome (true), or only after battles the player won (false). - CHECK_EVOLUTION_AFTER_ALL_BATTLES = (MECHANICS_GENERATION >= 6) - # Whether fainted Pokémon can try to evolve after a battle. - CHECK_EVOLUTION_FOR_FAINTED_POKEMON = true -end diff --git a/Data/Scripts/002_Save data/001_SaveData.rb b/Data/Scripts/002_Save data/001_SaveData.rb deleted file mode 100644 index 6dfcb4390..000000000 --- a/Data/Scripts/002_Save data/001_SaveData.rb +++ /dev/null @@ -1,96 +0,0 @@ -# The SaveData module is used to manipulate save data. It contains the {Value}s -# that make up the save data and {Conversion}s for resolving incompatibilities -# between Essentials and game versions. -# @see SaveData.register -# @see SaveData.register_conversion -module SaveData - # Contains the file path of the save file. - FILE_PATH = if File.directory?(System.data_directory) - System.data_directory + '/Game.rxdata' - else - './Game.rxdata' - end - - # @return [Boolean] whether the save file exists - def self.exists? - return File.file?(FILE_PATH) - end - - # Fetches the save data from the given file. - # Returns an Array in the case of a pre-v19 save file. - # @param file_path [String] path of the file to load from - # @return [Hash, Array] loaded save data - # @raise [IOError, SystemCallError] if file opening fails - def self.get_data_from_file(file_path) validate file_path => String - save_data = nil - File.open(file_path) do |file| - data = Marshal.load(file) - if data.is_a?(Hash) - save_data = data - next - end - save_data = [data] - save_data << Marshal.load(file) until file.eof? - end - return save_data - end - - # Fetches save data from the given file. If it needed converting, resaves it. - # @param file_path [String] path of the file to read from - # @return [Hash] save data in Hash format - # @raise (see .get_data_from_file) - def self.read_from_file(file_path) - validate file_path => String - save_data = get_data_from_file(file_path) - save_data = to_hash_format(save_data) if save_data.is_a?(Array) - if !save_data.empty? && run_conversions(save_data) - File.open(file_path, 'wb') { |file| Marshal.dump(save_data, file) } - end - return save_data - end - - # Compiles the save data and saves a marshaled version of it into - # the given file. - # @param file_path [String] path of the file to save into - # @raise [InvalidValueError] if an invalid value is being saved - def self.save_to_file(file_path) - validate file_path => String - save_data = self.compile_save_hash - File.open(file_path, 'wb') { |file| Marshal.dump(save_data, file) } - end - - # Deletes the save file (and a possible .bak backup file if one exists) - # @raise [Error::ENOENT] - def self.delete_file - File.delete(FILE_PATH) - File.delete(FILE_PATH + '.bak') if File.file?(FILE_PATH + '.bak') - end - - # Converts the pre-v19 format data to the new format. - # @param old_format [Array] pre-v19 format save data - # @return [Hash] save data in new format - def self.to_hash_format(old_format) - validate old_format => Array - hash = {} - @values.each do |value| - data = value.get_from_old_format(old_format) - hash[value.id] = data unless data.nil? - end - return hash - end - - # Moves a save file from the old Saved Games folder to the new - # location specified by {FILE_PATH}. Does nothing if a save file - # already exists in {FILE_PATH}. - def self.move_old_windows_save - return if File.file?(FILE_PATH) - game_title = System.game_title.gsub(/[^\w ]/, '_') - home = ENV['HOME'] || ENV['HOMEPATH'] - return if home.nil? - old_location = File.join(home, 'Saved Games', game_title) - return unless File.directory?(old_location) - old_file = File.join(old_location, 'Game.rxdata') - return unless File.file?(old_file) - File.move(old_file, FILE_PATH) - end -end diff --git a/Data/Scripts/002_Save data/002_SaveData_Value.rb b/Data/Scripts/002_Save data/002_SaveData_Value.rb deleted file mode 100644 index 7e5bdf9da..000000000 --- a/Data/Scripts/002_Save data/002_SaveData_Value.rb +++ /dev/null @@ -1,269 +0,0 @@ -module SaveData - # Contains Value objects for each save element. - # Populated during runtime by SaveData.register calls. - # @type [Array] - @values = [] - - # An error raised if an invalid save value is being saved or loaded. - class InvalidValueError < RuntimeError; end - - #============================================================================= - # Represents a single value in save data. - # New values are added using {SaveData.register}. - class Value - # @return [Symbol] the value id - attr_reader :id - - # @param id [Symbol] value id - def initialize(id, &block) - validate id => Symbol, block => Proc - @id = id - @loaded = false - @load_in_bootup = false - instance_eval(&block) - raise "No save_value defined for save value #{id.inspect}" if @save_proc.nil? - raise "No load_value defined for save value #{id.inspect}" if @load_proc.nil? - end - - # @param value [Object] value to check - # @return [Boolean] whether the given value is valid - def valid?(value) - return true if @ensured_class.nil? - return value.is_a?(Object.const_get(@ensured_class)) - end - - # Calls the value's load proc with the given argument passed into it. - # @param value [Object] load proc argument - # @raise [InvalidValueError] if an invalid value is being loaded - def load(value) - validate_value(value) - @load_proc.call(value) - @loaded = true - end - - # Calls the value's save proc and returns its value. - # @return [Object] save proc value - # @raise [InvalidValueError] if an invalid value is being saved - def save - value = @save_proc.call - validate_value(value) - return value - end - - # @return [Boolean] whether the value has a new game value proc defined - def has_new_game_proc? - return @new_game_value_proc.is_a?(Proc) - end - - # Calls the save value's load proc with the value fetched - # from the defined new game value proc. - # @raise (see #load) - def load_new_game_value - unless self.has_new_game_proc? - raise "Save value #{@id.inspect} has no new_game_value defined" - end - self.load(@new_game_value_proc.call) - end - - # @return [Boolean] whether the value should be loaded during bootup - def load_in_bootup? - return @load_in_bootup - end - - # @return [Boolean] whether the value has been loaded - def loaded? - return @loaded - end - - # Marks value as unloaded. - def mark_as_unloaded - @loaded = false - end - - # Uses the {#from_old_format} proc to select the correct data from - # +old_format+ and return it. - # Returns nil if the proc is undefined. - # @param old_format [Array] old format to load value from - # @return [Object] data from the old format - def get_from_old_format(old_format) - return nil if @old_format_get_proc.nil? - return @old_format_get_proc.call(old_format) - end - - private - - # Raises an {InvalidValueError} if the given value is invalid. - # @param value [Object] value to check - # @raise [InvalidValueError] if the value is invalid - def validate_value(value) - return if self.valid?(value) - raise InvalidValueError, "Save value #{@id.inspect} is not a #{@ensured_class} (#{value.class.name} given)" - end - - # @!group Configuration - - # If present, ensures that the value is of the given class. - # @param class_name [Symbol] class to enforce - # @see SaveData.register - def ensure_class(class_name) - validate class_name => Symbol - @ensured_class = class_name - end - - # Defines how the loaded value is placed into a global variable. - # Requires a block with the loaded value as its parameter. - # @see SaveData.register - def load_value(&block) - raise ArgumentError, 'No block given to load_value' unless block_given? - @load_proc = block - end - - # Defines what is saved into save data. Requires a block. - # @see SaveData.register - def save_value(&block) - raise ArgumentError, 'No block given to save_value' unless block_given? - @save_proc = block - end - - # If present, defines what the value is set to at the start of a new game. - # @see SaveData.register - def new_game_value(&block) - raise ArgumentError, 'No block given to new_game_value' unless block_given? - @new_game_value_proc = block - end - - # If present, sets the value to be loaded during bootup. - # @see SaveData.register - def load_in_bootup - @load_in_bootup = true - end - - # If present, defines how the value should be fetched from the pre-v19 - # save format. Requires a block with the old format array as its parameter. - # @see SaveData.register - def from_old_format(&block) - raise ArgumentError, 'No block given to from_old_format' unless block_given? - @old_format_get_proc = block - end - - # @!endgroup - end - - #============================================================================= - # Registers a {Value} to be saved into save data. - # Takes a block which defines the value's saving ({Value#save_value}) - # and loading ({Value#load_value}) procedures. - # - # It is also possible to provide a proc for fetching the value - # from the pre-v19 format ({Value#from_old_format}), define - # a value to be set upon starting a new game with {Value#new_game_value} - # and ensure that the saved and loaded value is of the correct - # class with {Value#ensure_class}. - # - # Values can be registered to be loaded on bootup with - # {Value#load_in_bootup}. If a new_game_value proc is defined, it - # will be called when the game is launched for the first time, - # or if the save data does not contain the value in question. - # - # @example Registering a new value - # SaveData.register(:foo) do - # ensure_class :Foo - # save_value { $foo } - # load_value { |value| $foo = value } - # new_game_value { Foo.new } - # from_old_format { |old_format| old_format[16] if old_format[16].is_a?(Foo) } - # end - # @example Registering a value to be loaded on bootup - # SaveData.register(:bar) do - # load_in_bootup - # save_value { $bar } - # load_value { |value| $bar = value } - # new_game_value { Bar.new } - # end - # @param id [Symbol] value id - # @yieldself [Value] - def self.register(id, &block) - validate id => Symbol - unless block_given? - raise ArgumentError, 'No block given to SaveData.register' - end - @values << Value.new(id, &block) - end - - # @param save_data [Hash] save data to validate - # @return [Boolean] whether the given save data is valid - def self.valid?(save_data) - validate save_data => Hash - return @values.all? { |value| value.valid?(save_data[value.id]) } - end - - # Loads values from the given save data. - # An optional condition can be passed. - # @param save_data [Hash] save data to load from - # @param condition_block [Proc] optional condition - # @api private - def self.load_values(save_data, &condition_block) - @values.each do |value| - next if block_given? && !condition_block.call(value) - if save_data.has_key?(value.id) - value.load(save_data[value.id]) - elsif value.has_new_game_proc? - value.load_new_game_value - end - end - end - - # Loads the values from the given save data by - # calling each {Value} object's {Value#load_value} proc. - # Values that are already loaded are skipped. - # If a value does not exist in the save data and has - # a {Value#new_game_value} proc defined, that value - # is loaded instead. - # @param save_data [Hash] save data to load - # @raise [InvalidValueError] if an invalid value is being loaded - def self.load_all_values(save_data) - validate save_data => Hash - load_values(save_data) { |value| !value.loaded? } - end - - # Marks all values that aren't loaded on bootup as unloaded. - def self.mark_values_as_unloaded - @values.each do |value| - value.mark_as_unloaded unless value.load_in_bootup? - end - end - - # Loads each value from the given save data that has - # been set to be loaded during bootup. Done when a save file exists. - # @param save_data [Hash] save data to load - # @raise [InvalidValueError] if an invalid value is being loaded - def self.load_bootup_values(save_data) - validate save_data => Hash - load_values(save_data) { |value| !value.loaded? && value.load_in_bootup? } - end - - # Goes through each value with {Value#load_in_bootup} enabled and loads their - # new game value, if one is defined. Done when no save file exists. - def self.initialize_bootup_values - @values.each do |value| - next unless value.load_in_bootup? - value.load_new_game_value if value.has_new_game_proc? && !value.loaded? - end - end - - # Loads each {Value}'s new game value, if one is defined. Done when starting a - # new game. - def self.load_new_game_values - @values.each do |value| - value.load_new_game_value if value.has_new_game_proc? && !value.loaded? - end - end - - # @return [Hash{Symbol => Object}] a hash representation of the save data - # @raise [InvalidValueError] if an invalid value is being saved - def self.compile_save_hash - save_data = {} - @values.each { |value| save_data[value.id] = value.save } - return save_data - end -end diff --git a/Data/Scripts/002_Save data/003_SaveData_Conversion.rb b/Data/Scripts/002_Save data/003_SaveData_Conversion.rb deleted file mode 100644 index f48bc35ea..000000000 --- a/Data/Scripts/002_Save data/003_SaveData_Conversion.rb +++ /dev/null @@ -1,221 +0,0 @@ -module SaveData - # Contains Conversion objects for each defined conversion: - # { - # :essentials => { - # '19' => [, ...], - # '19.1' => [, ...], - # ... - # }, - # :game => { - # '1.1.0' => [, ...], - # '1.2.0' => [, ...], - # ... - # } - # } - # Populated during runtime by SaveData.register_conversion calls. - @conversions = { - essentials: {}, - game: {} - } - - #============================================================================= - # Represents a conversion made to save data. - # New conversions are added using {SaveData.register_conversion}. - class Conversion - # @return [Symbol] conversion ID - attr_reader :id - # @return [String] conversion title - attr_reader :title - # @return [Symbol] trigger type of the conversion (+:essentials+ or +:game+) - attr_reader :trigger_type - # @return [String] trigger version of the conversion - attr_reader :version - - # @param id [String] conversion ID - def initialize(id, &block) - @id = id - @value_procs = {} - @all_proc = nil - @title = "Running conversion #{@id}" - @trigger_type = nil - @version = nil - instance_eval(&block) - if @trigger_type.nil? || @version.nil? - raise "Conversion #{@id} is missing a condition" - end - end - - # Returns whether the conversion should be run with the given version. - # @param version [String] version to check - # @return [Boolean] whether the conversion should be run - def should_run?(version) - return PluginManager.compare_versions(version, @version) < 0 - end - - # Runs the conversion on the given save data. - # @param save_data [Hash] - def run(save_data) - @value_procs.each do |value_id, proc| - unless save_data.has_key?(value_id) - raise "Save data does not have value #{value_id.inspect}" - end - proc.call(save_data[value_id]) - end - @all_proc.call(save_data) if @all_proc.is_a?(Proc) - end - - # Runs the conversion on the given object. - # @param object - # @param key [Symbol] - def run_single(object, key) - @value_procs[key].call(object) if @value_procs[key].is_a?(Proc) - end - - private - - # @!group Configuration - - # Sets the conversion's title. - # @param new_title [String] conversion title - # @note Since conversions are run before loading the player's chosen language, - # conversion titles can not be localized. - # @see SaveData.register_conversion - def display_title(new_title) - validate new_title => String - @title = new_title - end - - # Sets the conversion to trigger for save files created below - # the given Essentials version. - # @param version [Numeric, String] - # @see SaveData.register_conversion - def essentials_version(version) - validate version => [Numeric, String] - raise "Multiple conditions in conversion #{@id}" unless @version.nil? - @trigger_type = :essentials - @version = version.to_s - end - - # Sets the conversion to trigger for save files created below - # the given game version. - # @param version [Numeric, String] - # @see SaveData.register_conversion - def game_version(version) - validate version => [Numeric, String] - raise "Multiple conditions in conversion #{@id}" unless @version.nil? - @trigger_type = :game - @version = version.to_s - end - - # Defines a conversion to the given save value. - # @param value_id [Symbol] save value ID - # @see SaveData.register_conversion - def to_value(value_id, &block) - validate value_id => Symbol - raise ArgumentError, 'No block given to to_value' unless block_given? - if @value_procs[value_id].is_a?(Proc) - raise "Multiple to_value definitions in conversion #{@id} for #{value_id}" - end - @value_procs[value_id] = block - end - - # Defines a conversion to the entire save data. - # @see SaveData.register_conversion - def to_all(&block) - raise ArgumentError, 'No block given to to_all' unless block_given? - if @all_proc.is_a?(Proc) - raise "Multiple to_all definitions in conversion #{@id}" - end - @all_proc = block - end - - # @!endgroup - end - - #============================================================================= - # Registers a {Conversion} to occur for save data that meets the given criteria. - # Two types of criteria can be defined: {Conversion#essentials_version} and - # {Conversion#game_version}. The conversion is automatically run on save data - # that contains an older version number. - # - # A single value can be modified with {Conversion#to_value}. The entire save data - # is accessed with {Conversion#to_all}, and a conversion title can be specified - # with {Conversion#display_title}. - # @example Registering a new conversion - # SaveData.register_conversion(:my_conversion) do - # game_version '1.1.0' - # display_title 'Converting some stuff' - # to_value :player do |player| - # # code that modifies the :player value - # end - # to_all do |save_data| - # save_data[:new_value] = Foo.new - # end - # end - # @yield self [Conversion] - def self.register_conversion(id, &block) - validate id => Symbol - unless block_given? - raise ArgumentError, 'No block given to SaveData.register_conversion' - end - conversion = Conversion.new(id, &block) - @conversions[conversion.trigger_type][conversion.version] ||= [] - @conversions[conversion.trigger_type][conversion.version] << conversion - end - - # @param save_data [Hash] save data to get conversions for - # @return [Array] all conversions that should be run on the data - def self.get_conversions(save_data) - conversions_to_run = [] - versions = { - essentials: save_data[:essentials_version] || '18.1', - game: save_data[:game_version] || '0.0.0' - } - [:essentials, :game].each do |trigger_type| - # Ensure the versions are sorted from lowest to highest - sorted_versions = @conversions[trigger_type].keys.sort do |v1, v2| - PluginManager.compare_versions(v1, v2) - end - sorted_versions.each do |version| - @conversions[trigger_type][version].each do |conversion| - next unless conversion.should_run?(versions[trigger_type]) - conversions_to_run << conversion - end - end - end - return conversions_to_run - end - - # Runs all possible conversions on the given save data. - # Saves a backup before running conversions. - # @param save_data [Hash] save data to run conversions on - # @return [Boolean] whether conversions were run - def self.run_conversions(save_data) - validate save_data => Hash - conversions_to_run = self.get_conversions(save_data) - return false if conversions_to_run.none? - File.open(SaveData::FILE_PATH + '.bak', 'wb') { |f| Marshal.dump(save_data, f) } - echoln "Running #{conversions_to_run.length} conversions..." - conversions_to_run.each do |conversion| - echo "#{conversion.title}..." - conversion.run(save_data) - echoln ' done.' - end - echoln '' if conversions_to_run.length > 0 - save_data[:essentials_version] = Essentials::VERSION - save_data[:game_version] = Settings::GAME_VERSION - return true - end - - # Runs all possible conversions on the given object. - # @param object [Hash] object to run conversions on - # @param key [Hash] object's key in save data - # @param save_data [Hash] save data to run conversions on - def self.run_single_conversions(object, key, save_data) - validate key => Symbol - conversions_to_run = self.get_conversions(save_data) - conversions_to_run.each do |conversion| - conversion.run_single(object, key) - end - end -end diff --git a/Data/Scripts/002_Save data/004_Game_SaveValues.rb b/Data/Scripts/002_Save data/004_Game_SaveValues.rb deleted file mode 100644 index 18d3ab07b..000000000 --- a/Data/Scripts/002_Save data/004_Game_SaveValues.rb +++ /dev/null @@ -1,135 +0,0 @@ -# Contains the save values defined in Essentials by default. - -SaveData.register(:player) do - ensure_class :Player - save_value { $Trainer } - load_value { |value| $Trainer = value } - new_game_value { - trainer_type = nil # Get the first defined trainer type as a placeholder - GameData::TrainerType.each { |t| trainer_type = t.id; break } - Player.new("Unnamed", trainer_type) - } - from_old_format { |old_format| old_format[0] } -end - -SaveData.register(:frame_count) do - ensure_class :Integer - save_value { Graphics.frame_count } - load_value { |value| Graphics.frame_count = value } - new_game_value { 0 } - from_old_format { |old_format| old_format[1] } -end - -SaveData.register(:game_system) do - load_in_bootup - ensure_class :Game_System - save_value { $game_system } - load_value { |value| $game_system = value } - new_game_value { Game_System.new } - from_old_format { |old_format| old_format[2] } -end - -SaveData.register(:pokemon_system) do - load_in_bootup - ensure_class :PokemonSystem - save_value { $PokemonSystem } - load_value { |value| $PokemonSystem = value } - new_game_value { PokemonSystem.new } - from_old_format { |old_format| old_format[3] } -end - -SaveData.register(:switches) do - ensure_class :Game_Switches - save_value { $game_switches } - load_value { |value| $game_switches = value } - new_game_value { Game_Switches.new } - from_old_format { |old_format| old_format[5] } -end - -SaveData.register(:variables) do - ensure_class :Game_Variables - save_value { $game_variables } - load_value { |value| $game_variables = value } - new_game_value { Game_Variables.new } - from_old_format { |old_format| old_format[6] } -end - -SaveData.register(:self_switches) do - ensure_class :Game_SelfSwitches - save_value { $game_self_switches } - load_value { |value| $game_self_switches = value } - new_game_value { Game_SelfSwitches.new } - from_old_format { |old_format| old_format[7] } -end - -SaveData.register(:game_screen) do - ensure_class :Game_Screen - save_value { $game_screen } - load_value { |value| $game_screen = value } - new_game_value { Game_Screen.new } - from_old_format { |old_format| old_format[8] } -end - -SaveData.register(:map_factory) do - ensure_class :PokemonMapFactory - save_value { $MapFactory } - load_value { |value| $MapFactory = value } - from_old_format { |old_format| old_format[9] } -end - -SaveData.register(:game_player) do - ensure_class :Game_Player - save_value { $game_player } - load_value { |value| $game_player = value } - new_game_value { Game_Player.new } - from_old_format { |old_format| old_format[10] } -end - -SaveData.register(:global_metadata) do - ensure_class :PokemonGlobalMetadata - save_value { $PokemonGlobal } - load_value { |value| $PokemonGlobal = value } - new_game_value { PokemonGlobalMetadata.new } - from_old_format { |old_format| old_format[11] } -end - -SaveData.register(:map_metadata) do - ensure_class :PokemonMapMetadata - save_value { $PokemonMap } - load_value { |value| $PokemonMap = value } - new_game_value { PokemonMapMetadata.new } - from_old_format { |old_format| old_format[12] } -end - -SaveData.register(:bag) do - ensure_class :PokemonBag - save_value { $PokemonBag } - load_value { |value| $PokemonBag = value } - new_game_value { PokemonBag.new } - from_old_format { |old_format| old_format[13] } -end - -SaveData.register(:storage_system) do - ensure_class :PokemonStorage - save_value { $PokemonStorage } - load_value { |value| $PokemonStorage = value } - new_game_value { PokemonStorage.new } - from_old_format { |old_format| old_format[14] } -end - -SaveData.register(:essentials_version) do - load_in_bootup - ensure_class :String - save_value { Essentials::VERSION } - load_value { |value| $SaveVersion = value } - new_game_value { Essentials::VERSION } - from_old_format { |old_format| old_format[15] } -end - -SaveData.register(:game_version) do - load_in_bootup - ensure_class :String - save_value { Settings::GAME_VERSION } - load_value { |value| $game_version = value } - new_game_value { Settings::GAME_VERSION } -end diff --git a/Data/Scripts/002_Save data/005_Game_SaveConversions.rb b/Data/Scripts/002_Save data/005_Game_SaveConversions.rb deleted file mode 100644 index 554864de6..000000000 --- a/Data/Scripts/002_Save data/005_Game_SaveConversions.rb +++ /dev/null @@ -1,242 +0,0 @@ -# Contains conversions defined in Essentials by default. - -SaveData.register_conversion(:v19_define_versions) do - essentials_version 19 - display_title 'Adding game version and Essentials version to save data' - to_all do |save_data| - unless save_data.has_key?(:essentials_version) - save_data[:essentials_version] = Essentials::VERSION - end - unless save_data.has_key?(:game_version) - save_data[:game_version] = Settings::GAME_VERSION - end - end -end - -SaveData.register_conversion(:v19_convert_PokemonSystem) do - essentials_version 19 - display_title 'Updating PokemonSystem class' - to_all do |save_data| - new_system = PokemonSystem.new - new_system.textspeed = save_data[:pokemon_system].textspeed || new_system.textspeed - new_system.battlescene = save_data[:pokemon_system].battlescene || new_system.battlescene - new_system.battlestyle = save_data[:pokemon_system].battlestyle || new_system.battlestyle - new_system.frame = save_data[:pokemon_system].frame || new_system.frame - new_system.textskin = save_data[:pokemon_system].textskin || new_system.textskin - new_system.screensize = save_data[:pokemon_system].screensize || new_system.screensize - new_system.language = save_data[:pokemon_system].language || new_system.language - new_system.runstyle = save_data[:pokemon_system].runstyle || new_system.runstyle - new_system.bgmvolume = save_data[:pokemon_system].bgmvolume || new_system.bgmvolume - new_system.sevolume = save_data[:pokemon_system].sevolume || new_system.sevolume - new_system.textinput = save_data[:pokemon_system].textinput || new_system.textinput - save_data[:pokemon_system] = new_system - end -end - -SaveData.register_conversion(:v19_convert_player) do - essentials_version 19 - display_title 'Converting player trainer class' - to_all do |save_data| - next if save_data[:player].is_a?(Player) - # Conversion of the party is handled in PokeBattle_Trainer.convert - save_data[:player] = PokeBattle_Trainer.convert(save_data[:player]) - end -end - -SaveData.register_conversion(:v19_move_global_data_to_player) do - essentials_version 19 - display_title 'Moving some global metadata data to player' - to_all do |save_data| - global = save_data[:global_metadata] - player = save_data[:player] - player.character_ID = global.playerID - global.playerID = nil - global.pokedexUnlocked.each_with_index do |value, i| - if value - player.pokedex.unlock(i) - else - player.pokedex.lock(i) - end - end - player.coins = global.coins - global.coins = nil - player.soot = global.sootsack - global.sootsack = nil - player.has_running_shoes = global.runningShoes - global.runningShoes = nil - player.seen_storage_creator = global.seenStorageCreator - global.seenStorageCreator = nil - player.has_snag_machine = global.snagMachine - global.snagMachine = nil - player.seen_purify_chamber = global.seenPurifyChamber - global.seenPurifyChamber = nil - end -end - -SaveData.register_conversion(:v19_convert_global_metadata) do - essentials_version 19 - display_title 'Adding encounter version variable to global metadata' - to_value :global_metadata do |global| - global.bridge ||= 0 - global.encounter_version ||= 0 - if global.pcItemStorage - global.pcItemStorage.items.each_with_index do |slot, i| - item_data = GameData::Item.try_get(slot[0]) - if item_data - slot[0] = item_data.id - else - global.pcItemStorage.items[i] = nil - end - end - global.pcItemStorage.items.compact! - end - if global.mailbox - global.mailbox.each_with_index do |mail, i| - global.mailbox[i] = PokemonMail.convert(mail) if mail - end - end - global.phoneNumbers.each do |contact| - contact[1] = GameData::TrainerType.get(contact[1]).id if contact && contact.length == 8 - end - if global.partner - global.partner[0] = GameData::TrainerType.get(global.partner[0]).id - global.partner[3].each_with_index do |pkmn, i| - global.partner[3][i] = PokeBattle_Pokemon.convert(pkmn) if pkmn - end - end - if global.daycare - global.daycare.each do |slot| - slot[0] = PokeBattle_Pokemon.convert(slot[0]) if slot && slot[0] - end - end - if global.roamPokemon - global.roamPokemon.each_with_index do |pkmn, i| - global.roamPokemon[i] = PokeBattle_Pokemon.convert(pkmn) if pkmn && pkmn != true - end - end - global.purifyChamber.sets.each do |set| - set.shadow = PokeBattle_Pokemon.convert(set.shadow) if set.shadow - set.list.each_with_index do |pkmn, i| - set.list[i] = PokeBattle_Pokemon.convert(pkmn) if pkmn - end - end - if global.hallOfFame - global.hallOfFame.each do |team| - next if !team - team.each_with_index do |pkmn, i| - team[i] = PokeBattle_Pokemon.convert(pkmn) if pkmn - end - end - end - if global.triads - global.triads.items.each do |card| - card[0] = GameData::Species.get(card[0]).id if card && card[0] && card[0] != 0 - end - end - end -end - -SaveData.register_conversion(:v19_1_fix_phone_contacts) do - essentials_version 19.1 - display_title 'Fixing phone contacts data' - to_value :global_metadata do |global| - global.phoneNumbers.each do |contact| - contact[1] = GameData::TrainerType.get(contact[1]).id if contact && contact.length == 8 - end - end -end - -SaveData.register_conversion(:v19_convert_bag) do - essentials_version 19 - display_title 'Converting item IDs in Bag' - to_value :bag do |bag| - bag.instance_eval do - for pocket in self.pockets - pocket.each_with_index do |item, i| - next if !item || !item[0] || item[0] == 0 - item_data = GameData::Item.try_get(item[0]) - if item_data - item[0] = item_data.id - else - pocket[i] = nil - end - end - pocket.compact! - end - self.registeredIndex # Just to ensure this data exists - self.registeredItems.each_with_index do |item, i| - next if !item - if item == 0 - self.registeredItems[i] = nil - else - item_data = GameData::Item.try_get(item) - if item_data - self.registeredItems[i] = item_data.id - else - self.registeredItems[i] = nil - end - end - end - self.registeredItems.compact! - end # bag.instance_eval - end # to_value -end - -SaveData.register_conversion(:v19_convert_game_variables) do - essentials_version 19 - display_title 'Converting classes of things in Game Variables' - to_all do |save_data| - variables = save_data[:variables] - for i in 0..5000 - value = variables[i] - next if value.nil? - if value.is_a?(Array) - value.each_with_index do |value2, j| - if value2.is_a?(PokeBattle_Pokemon) - value[j] = PokeBattle_Pokemon.convert(value2) - end - end - elsif value.is_a?(PokeBattle_Pokemon) - variables[i] = PokeBattle_Pokemon.convert(value) - elsif value.is_a?(PokemonBag) - SaveData.run_single_conversions(value, :bag, save_data) - end - end - end -end - -SaveData.register_conversion(:v19_convert_storage) do - essentials_version 19 - display_title 'Converting classes of Pokémon in storage' - to_value :storage_system do |storage| - storage.instance_eval do - for box in 0...self.maxBoxes - for i in 0...self.maxPokemon(box) - self[box, i] = PokeBattle_Pokemon.convert(self[box, i]) if self[box, i] - end - end - self.unlockedWallpapers # Just to ensure this data exists - end # storage.instance_eval - end # to_value -end - -SaveData.register_conversion(:v19_convert_game_player) do - essentials_version 19 - display_title 'Converting game player character' - to_value :game_player do |game_player| - game_player.width = 1 - game_player.height = 1 - game_player.sprite_size = [Game_Map::TILE_WIDTH, Game_Map::TILE_HEIGHT] - game_player.pattern_surf ||= 0 - game_player.lock_pattern ||= false - game_player.move_speed = game_player.move_speed - end -end - -SaveData.register_conversion(:v19_convert_game_screen) do - essentials_version 19 - display_title 'Converting game screen' - to_value :game_screen do |game_screen| - game_screen.weather(game_screen.weather_type, game_screen.weather_max, 0) - end -end diff --git a/Data/Scripts/003_Game processing/001_StartGame.rb b/Data/Scripts/003_Game processing/001_StartGame.rb deleted file mode 100644 index 4eab8ac50..000000000 --- a/Data/Scripts/003_Game processing/001_StartGame.rb +++ /dev/null @@ -1,259 +0,0 @@ -# The Game module contains methods for saving and loading the game. -module Game - # Initializes various global variables and loads the game data. - - - def self.initialize - $PokemonTemp = PokemonTemp.new - $game_temp = Game_Temp.new - $game_system = Game_System.new - $data_animations = load_data('Data/Animations.rxdata') - $data_tilesets = load_data('Data/Tilesets.rxdata') - $data_common_events = load_data('Data/CommonEvents.rxdata') - $data_system = load_data('Data/System.rxdata') - pbLoadBattleAnimations - load_sprites_list_caches() - $updated_spritesheets = load_updated_spritesheets() - GameData.load_all - map_file = format('Data/Map%03d.rxdata', $data_system.start_map_id) - if $data_system.start_map_id == 0 || !pbRgssExists?(map_file) - raise _INTL('No starting position was set in the map editor.') - end - end - - def self.load_updated_spritesheets - updated_spritesheets_file = Settings::UPDATED_SPRITESHEETS_CACHE - updated_spritesheets = [] - if File.exist?(updated_spritesheets_file) - File.open(updated_spritesheets_file, "r") do |file| - file.each_line { |line| updated_spritesheets << line.chomp } - end - end - return updated_spritesheets - end - - def self.load_sprites_list_caches() - self.load_custom_sprites_list_cache() if File.exists?(Settings::CUSTOM_SPRITES_FILE_PATH) - self.load_base_sprites_list_cache() if File.exists?(Settings::BASE_SPRITES_FILE_PATH) - end - - def self.load_custom_sprites_list_cache() - return if !$game_temp.custom_sprites_list.keys.empty? #only load once at loadup - echoln "loading custom sprites cache" - sprite_index = {} - File.foreach(Settings::CUSTOM_SPRITES_FILE_PATH) do |line| - filename = line.strip - next unless filename =~ /^(\d+)\.(\d+)([a-zA-Z]*)\.png$/ # Regex: Captures the numbers and any trailing letters - - # Match groups - head_number = $1.to_i # Head (e.g., "1" in "1.2.png") - body_number = $2.to_i # Body (e.g., "2" in "1.2.png") - letters = $3 # Letters after the second number (e.g., "a", "b", etc.) - - key = "B#{body_number}H#{head_number}".to_sym - sprite_index[key] ||= [] - if letters.empty? - sprite_index[key] << "" - else - sprite_index[key] << letters - end - end - $game_temp.custom_sprites_list = sprite_index - echoln "custom sprites loaded" - end - - # - # {1 => ["","a","b"] - #etc. - # - def self.load_base_sprites_list_cache() - return if !$game_temp.base_sprites_list.keys.empty? #only load once at loadup - echoln "loading base sprites cache" - sprite_index = {} - File.foreach(Settings::BASE_SPRITES_FILE_PATH) do |line| - filename = line.strip - next unless filename =~ /^(\d+)([a-zA-Z]*)\.png$/ # Regex: Captures the numbers and any trailing letters - - # Match groups - dex_number = $1.to_i # Head (e.g., "1" in "1.2.png") - letters = $2 # Letters after the second number (e.g., "a", "b", etc.) - - key = dex_number - sprite_index[key] ||= [] - if letters.empty? - sprite_index[key] << "" - else - sprite_index[key] << letters - end - end - $game_temp.base_sprites_list = sprite_index - echoln "custom sprites loaded" - end - - # - # {:B10H10 => ["","a","b"] - #etc. - # - def self.set_up_system - SaveData.move_old_windows_save if System.platform[/Windows/] - save_data = (SaveData.exists?) ? SaveData.read_from_file(SaveData::FILE_PATH) : {} - if save_data.empty? - SaveData.initialize_bootup_values - else - SaveData.load_bootup_values(save_data) - end - # Set resize factor - pbSetResizeFactor([$PokemonSystem.screensize, 4].min) - # Set language (and choose language if there is no save file) - if Settings::LANGUAGES.length >= 2 - $PokemonSystem.language = pbChooseLanguage if save_data.empty? - pbLoadMessages('Data/' + Settings::LANGUAGES[$PokemonSystem.language][1]) - end - end - - #For new game plus - resets everything in boxes/party to level 5 and 1st stage - def self.ngp_clean_pc_data(old_storage, old_party) - new_storage = old_storage - for pokemon in old_party - new_storage.pbStoreCaught(pokemon) - end - - for box in new_storage.boxes - for pokemon in box.pokemon - if pokemon != nil - if !pokemon.egg? - pokemon.exp_when_fused_head=nil - pokemon.exp_when_fused_body=nil - pokemon.exp_gained_since_fused=nil - pokemon.level = 5 - - echoln pokemon.owner.id - pokemon.owner.id = $Trainer.id - pokemon.ot=$Trainer.name - pokemon.obtain_method = 0 - pokemon.species = GameData::Species.get(pokemon.species).get_baby_species(false) - $Trainer.pokedex.set_seen(pokemon.species) - $Trainer.pokedex.set_owned(pokemon.species) - pokemon.reset_moves - pokemon.calc_stats - - end - end - end - end - return new_storage - end - - #For new game plus - removes key items - def self.ngp_clean_item_data(old_bag) - new_storage = old_bag - new_storage.clear - - for pocket in old_bag.pockets - for bagElement in pocket - item_id = bagElement[0] - item_qt = bagElement[1] - item = GameData::Item.get(item_id) - if !item.is_key_item? && !item.is_HM? - new_storage.pbStoreItem(item, 1) - end - end - end - return new_storage - end - - # Called when starting a new game. Initializes global variables - # and transfers the player into the map scene. - def self.start_new(ngp_bag = nil, ngp_storage = nil, ngp_trainer = nil) - - if $game_map && $game_map.events - $game_map.events.each_value { |event| event.clear_starting } - end - $game_temp.common_event_id = 0 if $game_temp - $PokemonTemp.begunNewGame = true - $scene = Scene_Map.new - SaveData.load_new_game_values - $MapFactory = PokemonMapFactory.new($data_system.start_map_id) - $game_player.moveto($data_system.start_x, $data_system.start_y) - $game_player.refresh - $PokemonEncounters = PokemonEncounters.new - $PokemonEncounters.setup($game_map.map_id) - $game_map.autoplay - $game_map.update - # - # if ngp_bag != nil - # $PokemonBag = ngp_clean_item_data(ngp_bag) - # end - if ngp_storage != nil - $PokemonStorage = ngp_clean_pc_data(ngp_storage, ngp_trainer.party) - end - onStartingNewGame() - end - - # Loads the game from the given save data and starts the map scene. - # @param save_data [Hash] hash containing the save data - # @raise [SaveData::InvalidValueError] if an invalid value is being loaded - def self.load(save_data) - validate save_data => Hash - SaveData.load_all_values(save_data) - self.load_map - pbAutoplayOnSave - $game_map.update - $PokemonMap.updateMap - $scene = Scene_Map.new - onLoadExistingGame() - end - - # Loads and validates the map. Called when loading a saved game. - def self.load_map - $game_map = $MapFactory.map - magic_number_matches = ($game_system.magic_number == $data_system.magic_number) - if !magic_number_matches || $PokemonGlobal.safesave - if pbMapInterpreterRunning? - pbMapInterpreter.setup(nil, 0) - end - begin - $MapFactory.setup($game_map.map_id) - rescue Errno::ENOENT - if $DEBUG - pbMessage(_INTL('Map {1} was not found.', $game_map.map_id)) - map = pbWarpToMapList - exit unless map - $MapFactory.setup(map[0]) - $game_player.moveto(map[1], map[2]) - else - raise _INTL('The map was not found. The game cannot continue.') - end - end - $game_player.center($game_player.x, $game_player.y) - else - $MapFactory.setMapChanged($game_map.map_id) - end - if $game_map.events.nil? - raise _INTL('The map is corrupt. The game cannot continue.') - end - $PokemonEncounters = PokemonEncounters.new - $PokemonEncounters.setup($game_map.map_id) - pbUpdateVehicle - end - - # Saves the game. Returns whether the operation was successful. - # @param save_file [String] the save file path - # @param safe [Boolean] whether $PokemonGlobal.safesave should be set to true - # @return [Boolean] whether the operation was successful - # @raise [SaveData::InvalidValueError] if an invalid value is being saved - def self.save(save_file = SaveData::FILE_PATH, safe: false) - validate save_file => String, safe => [TrueClass, FalseClass] - $PokemonGlobal.safesave = safe - $game_system.save_count += 1 - $game_system.magic_number = $data_system.magic_number - begin - SaveData.save_to_file(save_file) - Graphics.frame_reset - rescue IOError, SystemCallError - $game_system.save_count -= 1 - return false - end - return true - end -end diff --git a/Data/Scripts/003_Game processing/002_Scene_Map.rb b/Data/Scripts/003_Game processing/002_Scene_Map.rb deleted file mode 100644 index 63bec0c5f..000000000 --- a/Data/Scripts/003_Game processing/002_Scene_Map.rb +++ /dev/null @@ -1,292 +0,0 @@ -#=============================================================================== -# ** Modified Scene_Map class for Pokémon. -#------------------------------------------------------------------------------- -# -#=============================================================================== -class Scene_Map - attr_reader :spritesetGlobal - attr_reader :map_renderer - attr_accessor :spritesets - - def spriteset - for i in @spritesets.values - return i if i.map == $game_map - end - return @spritesets.values[0] - end - - def createSpritesets - @map_renderer = TilemapRenderer.new(Spriteset_Map.viewport) if !@map_renderer || @map_renderer.disposed? - @spritesetGlobal = Spriteset_Global.new if !@spritesetGlobal - @spritesets = {} - for map in $MapFactory.maps - @spritesets[map.map_id] = Spriteset_Map.new(map) - end - $MapFactory.setSceneStarted(self) - updateSpritesets(true) - end - - def createSingleSpriteset(map) - temp = $scene.spriteset.getAnimations - @spritesets[map] = Spriteset_Map.new($MapFactory.maps[map]) - $scene.spriteset.restoreAnimations(temp) - $MapFactory.setSceneStarted(self) - updateSpritesets(true) - end - - def disposeSpritesets - return if !@spritesets - for i in @spritesets.keys - next if !@spritesets[i] - @spritesets[i].dispose - @spritesets[i] = nil - end - @spritesets.clear - @spritesets = {} - end - - def dispose - disposeSpritesets - @map_renderer.dispose - @map_renderer = nil - @spritesetGlobal.dispose - @spritesetGlobal = nil - end - - def autofade(mapid) - playingBGM = $game_system.playing_bgm - playingBGS = $game_system.playing_bgs - return if playingBGM && playingBGM.name == "ultra_metropolis" && darknessEffectOnMap(mapid) - return if !playingBGM && !playingBGS - map = load_data(sprintf("Data/Map%03d.rxdata", mapid)) - if playingBGM && map.autoplay_bgm - if (PBDayNight.isNight? rescue false) - pbBGMFade(0.8) if playingBGM.name != map.bgm.name && playingBGM.name != map.bgm.name + "_n" - else - pbBGMFade(0.8) if playingBGM.name != map.bgm.name - end - end - if playingBGS && map.autoplay_bgs - pbBGMFade(0.8) if playingBGS.name != map.bgs.name - end - Graphics.frame_reset - end - - #todo - def cacheNeedsClearing - return RPG::Cache.size >= 100 - end - - def reset_switches_for_map_transfer - $game_switches[SWITCH_ILEX_FOREST_SPOOKED_POKEMON] = false - end - - def clear_quest_icons() - for sprite in $scene.spriteset.character_sprites - if sprite.is_a?(Sprite_Character) && sprite.questIcon - sprite.removeQuestIcon - end - end - end - - def transfer_player(cancelVehicles = true) - reset_switches_for_map_transfer() - $game_temp.player_transferring = false - pbCancelVehicles($game_temp.player_new_map_id) if cancelVehicles - autofade($game_temp.player_new_map_id) - pbBridgeOff - @spritesetGlobal.playersprite.clearShadows - clear_quest_icons() - if $game_map.map_id != $game_temp.player_new_map_id - $MapFactory.setup($game_temp.player_new_map_id) - end - $game_player.moveto($game_temp.player_new_x, $game_temp.player_new_y) - case $game_temp.player_new_direction - when 2 then - $game_player.turn_down - when 4 then - $game_player.turn_left - when 6 then - $game_player.turn_right - when 8 then - $game_player.turn_up - end - - $game_player.straighten - $game_map.update - disposeSpritesets - if RPG::Cache.need_clearing - RPG::Cache.clear - end - createSpritesets - if $game_temp.transition_processing - $game_temp.transition_processing = false - Graphics.transition(20) - end - $game_map.autoplay - Graphics.frame_reset - Input.update - end - - def call_menu - $game_temp.menu_calling = false - $game_temp.in_menu = true - $game_player.straighten - $game_map.update - sscene = PokemonPauseMenu_Scene.new - sscreen = PokemonPauseMenu.new(sscene) - sscreen.pbStartPokemonMenu - $game_temp.in_menu = false - end - - def call_debug - $game_temp.debug_calling = false - pbPlayDecisionSE - $game_player.straighten - pbFadeOutIn { pbDebugMenu } - end - - def miniupdate - $PokemonTemp.miniupdate = true - loop do - $game_player.update - updateMaps - $game_system.update - $game_screen.update - break unless $game_temp.player_transferring - transfer_player - break if $game_temp.transition_processing - end - updateSpritesets - $PokemonTemp.miniupdate = false - end - - def updateMaps - for map in $MapFactory.maps - map.update - end - $MapFactory.updateMaps(self) - end - - def updateSpritesets(refresh = false) - @spritesets = {} if !@spritesets - keys = @spritesets.keys.clone - for i in keys - if !$MapFactory.hasMap?(i) - @spritesets[i].dispose if @spritesets[i] - @spritesets[i] = nil - @spritesets.delete(i) - else - @spritesets[i].update - end - end - @spritesetGlobal.update - for map in $MapFactory.maps - @spritesets[map.map_id] = Spriteset_Map.new(map) if !@spritesets[map.map_id] - end - pbDayNightTint(@map_renderer) - @map_renderer.refresh if refresh - @map_renderer.update - Events.onMapUpdate.trigger(self) - end - - def update - loop do - pbMapInterpreter.update - $game_player.update - updateMaps - $game_system.update - $game_screen.update - break unless $game_temp.player_transferring - transfer_player - break if $game_temp.transition_processing - end - updateSpritesets - if $game_temp.to_title - $game_temp.to_title = false - SaveData.mark_values_as_unloaded - $scene = pbCallTitle - return - end - if $game_temp.transition_processing - $game_temp.transition_processing = false - if $game_temp.transition_name == "" - Graphics.transition(20) - else - Graphics.transition(40, "Graphics/Transitions/" + $game_temp.transition_name) - end - end - return if $game_temp.message_window_showing - if !pbMapInterpreterRunning? - if Input.trigger?(Input::USE) - $PokemonTemp.hiddenMoveEventCalling = true - elsif Input.trigger?(Input::BACK) - unless $game_system.menu_disabled || $game_player.moving? - $game_temp.menu_calling = true - $game_temp.menu_beep = true - dayOfWeek = getDayOfTheWeek().to_s - $scene.spriteset.addUserSprite(LocationWindow.new($game_map.name+ "\n"+ pbGetTimeNow.strftime("%I:%M %p") + "\n" + dayOfWeek)) - end - elsif Input.trigger?(Input::SPECIAL) - unless $game_system.menu_disabled || $game_player.moving? - $PokemonTemp.keyItemCalling = true - end - elsif Input.press?(Input::F9) - $game_temp.debug_calling = true if $DEBUG - end - end - unless $game_player.moving? - if $game_temp.menu_calling - call_menu - elsif $game_temp.debug_calling - call_debug - elsif $PokemonTemp.keyItemCalling - $PokemonTemp.keyItemCalling = false - $game_player.straighten - pbUseKeyItem - elsif $PokemonTemp.hiddenMoveEventCalling - $PokemonTemp.hiddenMoveEventCalling = false - $game_player.straighten - Events.onAction.trigger(self) - end - end - end - - def reset_player_sprite - @spritesetGlobal.playersprite.updateBitmap - end - - def reset_map(fadeout = false,reset_music=true) - $MapFactory.setup($game_map.map_id) - $game_player.moveto($game_player.x, $game_player.y) - $game_player.straighten - $game_map.update - disposeSpritesets - GC.start - createSpritesets - if fadeout - $game_temp.transition_processing = false - Graphics.transition(20) - end - $game_map.autoplay if reset_music - Graphics.frame_reset - Input.update - end - - def main - createSpritesets - Graphics.transition(20) - loop do - Graphics.update - Input.update - update - break if $scene != self - end - Graphics.freeze - dispose - if $game_temp.to_title - Graphics.transition(20) - Graphics.freeze - end - end -end diff --git a/Data/Scripts/003_Game processing/003_Interpreter.rb b/Data/Scripts/003_Game processing/003_Interpreter.rb deleted file mode 100644 index 89d007cf8..000000000 --- a/Data/Scripts/003_Game processing/003_Interpreter.rb +++ /dev/null @@ -1,457 +0,0 @@ -#=============================================================================== -# ** Interpreter -#------------------------------------------------------------------------------- -# This interpreter runs event commands. This class is used within the -# Game_System class and the Game_Event class. -#=============================================================================== -class Interpreter - #----------------------------------------------------------------------------- - # * Object Initialization - # depth : nest depth - # main : main flag - #----------------------------------------------------------------------------- - def initialize(depth = 0, main = false) - @depth = depth - @main = main - if depth > 100 - print("Common event call has exceeded maximum limit.") - exit - end - clear - end - - def inspect - str = super.chop - str << format(' @event_id: %d>', @event_id) - return str - end - - def clear - @map_id = 0 # map ID when starting up - @event_id = 0 # event ID - @message_waiting = false # waiting for message to end - @move_route_waiting = false # waiting for move completion - @wait_count = 0 # wait count - @child_interpreter = nil # child interpreter - @branch = {} # branch data - @buttonInput = false - end - #----------------------------------------------------------------------------- - # * Event Setup - # list : list of event commands - # event_id : event ID - #----------------------------------------------------------------------------- - def setup(list, event_id, map_id = nil) - clear - @map_id = map_id || $game_map.map_id - @event_id = event_id - @list = list - @index = 0 - @branch.clear - end - - def setup_starting_event - $game_map.refresh if $game_map.need_refresh - # Set up common event if one wants to start - if $game_temp.common_event_id > 0 - setup($data_common_events[$game_temp.common_event_id].list, 0) - $game_temp.common_event_id = 0 - return - end - # Check all map events for one that wants to start, and set it up - for event in $game_map.events.values - next if !event.starting - if event.trigger < 3 # Isn't autorun or parallel processing - event.lock - event.clear_starting - end - setup(event.list, event.id, event.map.map_id) - return - end - # Check all common events for one that is autorun, and set it up - for common_event in $data_common_events.compact - next if common_event.trigger != 1 || !$game_switches[common_event.switch_id] - setup(common_event.list, 0) - return - end - end - - def running? - return @list != nil - end - #----------------------------------------------------------------------------- - # * Frame Update - #----------------------------------------------------------------------------- - def update - @loop_count = 0 - loop do - @loop_count += 1 - if @loop_count > 100 # Call Graphics.update for freeze prevention - Graphics.update - @loop_count = 0 - end - # If this interpreter's map isn't the current map or connected to it, - # forget this interpreter's event ID - if $game_map.map_id != @map_id && !$MapFactory.areConnected?($game_map.map_id, @map_id) - @event_id = 0 - end - # Update child interpreter if one exists - if @child_interpreter - @child_interpreter.update - @child_interpreter = nil if !@child_interpreter.running? - return if @child_interpreter - end - # Do nothing if a message is being shown - return if @message_waiting - # Do nothing if any event or the player is in the middle of a move route - if @move_route_waiting - return if $game_player.move_route_forcing - for event in $game_map.events.values - return if event.move_route_forcing - end - @move_route_waiting = false - end - # Do nothing while waiting - if @wait_count > 0 - @wait_count -= 1 - return - end - # Do nothing if the pause menu is going to open - return if $game_temp.menu_calling - # If there are no commands in the list, try to find something that wants to run - if @list.nil? - setup_starting_event if @main - return if @list.nil? # Couldn't find anything that wants to run - end - # Execute the next command - return if execute_command == false - # Move to the next @index - @index += 1 - end - end - #----------------------------------------------------------------------------- - # * Execute script - #----------------------------------------------------------------------------- - def execute_script(script) - begin - result = eval(script) - return result - rescue Exception - e = $! - raise if e.is_a?(SystemExit) || "#{e.class}" == "Reset" - event = get_self - s = "Backtrace:\r\n" - message = pbGetExceptionMessage(e) - if e.is_a?(SyntaxError) - script.each_line { |line| - line.gsub!(/\s+$/, "") - if line[/^\s*\(/] - message += "\r\n***Line '#{line}' shouldn't begin with '('. Try\r\n" - message += "putting the '(' at the end of the previous line instead,\r\n" - message += "or using 'extendtext.exe'." - end - if line[/\:\:\s*$/] - message += "\r\n***Line '#{line}' can't end with '::'. Try putting\r\n" - message += "the next word on the same line, e.g. 'PBSpecies:" + ":MEW'" - end - } - else - for bt in e.backtrace[0, 10] - s += bt + "\r\n" - end - s.gsub!(/Section(\d+)/) { $RGSS_SCRIPTS[$1.to_i][1] } - end - message = "Exception: #{e.class}\r\nMessage: " + message + "\r\n" - message += "\r\n***Full script:\r\n#{script}\r\n" - if event && $game_map - map_name = ($game_map.name rescue nil) || "???" - err = "Script error in event #{event.id} (coords #{event.x},#{event.y}), map #{$game_map.map_id} (#{map_name}):\r\n" - err += "#{message}\r\n#{s}" - if e.is_a?(Hangup) - $EVENTHANGUPMSG = err - raise - end - elsif $game_map - map_name = ($game_map.name rescue nil) || "???" - err = "Script error in map #{$game_map.map_id} (#{map_name}):\r\n" - err += "#{message}\r\n#{s}" - if e.is_a?(Hangup) - $EVENTHANGUPMSG = err - raise - end - else - err = "Script error in interpreter:\r\n#{message}\r\n#{s}" - if e.is_a?(Hangup) - $EVENTHANGUPMSG = err - raise - end - end - raise err - end - end - #----------------------------------------------------------------------------- - # * Get Character - # parameter : parameter - #----------------------------------------------------------------------------- - def get_character(parameter = 0) - case parameter - when -1 # player - return $game_player - when 0 # this event - events = $game_map.events - return (events) ? events[@event_id] : nil - else # specific event - events = $game_map.events - return (events) ? events[parameter] : nil - end - end - - def get_player - return get_character(-1) - end - - def get_self - return get_character(0) - end - - def get_event(parameter) - return get_character(parameter) - end - #----------------------------------------------------------------------------- - # * Freezes all events on the map (for use at the beginning of common events) - #----------------------------------------------------------------------------- - def pbGlobalLock - $game_map.events.values.each { |event| event.minilock } - end - #----------------------------------------------------------------------------- - # * Unfreezes all events on the map (for use at the end of common events) - #----------------------------------------------------------------------------- - def pbGlobalUnlock - $game_map.events.values.each { |event| event.unlock } - end - #----------------------------------------------------------------------------- - # * Gets the next index in the interpreter, ignoring certain commands between messages - #----------------------------------------------------------------------------- - def pbNextIndex(index) - return -1 if !@list || @list.length == 0 - i = index + 1 - loop do - return i if i >= @list.length - 1 - case @list[i].code - when 118, 108, 408 # Label, Comment - i += 1 - when 413 # Repeat Above - i = pbRepeatAbove(i) - when 113 # Break Loop - i = pbBreakLoop(i) - when 119 # Jump to Label - newI = pbJumpToLabel(i, @list[i].parameters[0]) - i = (newI > i) ? newI : i + 1 - else - return i - end - end - end - - def pbRepeatAbove(index) - index = @list[index].indent - loop do - index -= 1 - return index + 1 if @list[index].indent == indent - end - end - - def pbBreakLoop(index) - indent = @list[index].indent - temp_index = index - loop do - temp_index += 1 - return index + 1 if temp_index >= @list.size - 1 - return temp_index + 1 if @list[temp_index].code == 413 && - @list[temp_index].indent < indent - end - end - - def pbJumpToLabel(index, label_name) - temp_index = 0 - loop do - return index + 1 if temp_index >= @list.size - 1 - return temp_index + 1 if @list[temp_index].code == 118 && - @list[temp_index].parameters[0] == label_name - temp_index += 1 - end - end - #----------------------------------------------------------------------------- - # * Various methods to be used in a script event command. - #----------------------------------------------------------------------------- - # Helper function that shows a picture in a script. - def pbShowPicture(number, name, origin, x, y, zoomX = 100, zoomY = 100, opacity = 255, blendType = 0) - number = number + ($game_temp.in_battle ? 50 : 0) - $game_screen.pictures[number].show(name, origin, x, y, zoomX, zoomY, opacity, blendType) - end - - # Erases an event and adds it to the list of erased events so that - # it can stay erased when the game is saved then loaded again. - def pbEraseThisEvent - if $game_map.events[@event_id] - if $game_map.events[@event_id].name[/cuttree/i] - pbSmashThisEvent() - end - $game_map.events[@event_id].erase - $PokemonMap.addErasedEvent(@event_id) if $PokemonMap - end - @index += 1 - return true - end - - # Runs a common event. - def pbCommonEvent(id) - common_event = $data_common_events[id] - return if !common_event - if $game_temp.in_battle - $game_system.battle_interpreter.setup(common_event.list, 0) - else - interp = Interpreter.new - interp.setup(common_event.list, 0) - loop do - Graphics.update - Input.update - interp.update - pbUpdateSceneMap - break if !interp.running? - end - end - end - - # Sets another event's self switch (eg. pbSetSelfSwitch(20, "A", true) ). - def pbSetSelfSwitch(eventid, switch_name, value, mapid = -1) - mapid = @map_id if mapid < 0 - old_value = $game_self_switches[[mapid, eventid, switch_name]] - $game_self_switches[[mapid, eventid, switch_name]] = value - if value != old_value && $MapFactory.hasMap?(mapid) - $MapFactory.getMap(mapid, false).need_refresh = true - end - end - - def tsOff?(c) - return get_self.tsOff?(c) - end - alias isTempSwitchOff? tsOff? - - def tsOn?(c) - return get_self.tsOn?(c) - end - alias isTempSwitchOn? tsOn? - - def setTempSwitchOn(c) - get_self.setTempSwitchOn(c) - end - - def setTempSwitchOff(c) - get_self.setTempSwitchOff(c) - end - - def getVariable(*arg) - if arg.length == 0 - return nil if !$PokemonGlobal.eventvars - return $PokemonGlobal.eventvars[[@map_id, @event_id]] - else - return $game_variables[arg[0]] - end - end - - def setVariable(*arg) - if arg.length == 1 - $PokemonGlobal.eventvars = {} if !$PokemonGlobal.eventvars - $PokemonGlobal.eventvars[[@map_id, @event_id]] = arg[0] - else - $game_variables[arg[0]] = arg[1] - $game_map.need_refresh = true - end - end - - def pbGetPokemon(id) - return $Trainer.party[pbGet(id)] - end - - def pbSetEventTime(*arg) - $PokemonGlobal.eventvars = {} if !$PokemonGlobal.eventvars - time = pbGetTimeNow - time = time.to_i - pbSetSelfSwitch(@event_id, "A", true) - $PokemonGlobal.eventvars[[@map_id, @event_id]] = time - for otherevt in arg - pbSetSelfSwitch(otherevt, "A", true) - $PokemonGlobal.eventvars[[@map_id, otherevt]] = time - end - end - - # Used in boulder events. Allows an event to be pushed. - def pbPushThisEvent - event = get_self - old_x = event.x - old_y = event.y - # Apply strict version of passable, which treats tiles that are passable - # only from certain directions as fully impassible - # ^why?? - no - return if !event.can_move_in_direction?($game_player.direction, false) - case $game_player.direction - when 2 then event.move_down - when 4 then event.move_left - when 6 then event.move_right - when 8 then event.move_up - end - - if old_x != event.x || old_y != event.y - $game_player.lock - loop do - Graphics.update - Input.update - pbUpdateSceneMap - break if !event.moving? - end - $game_player.unlock - end - end - - def pbPushThisBoulder - pbPushThisEvent if $PokemonMap.strengthUsed - return true - end - - def pbSmashThisEvent - event = get_self - pbSmashEvent(event) if event - @index += 1 - return true - end - - def pbTrainerIntro(symbol) - return true if $DEBUG && !GameData::TrainerType.exists?(symbol) - tr_type = GameData::TrainerType.get(symbol).id - pbGlobalLock - pbPlayTrainerIntroME(tr_type) - return true - end - - def pbTrainerEnd - pbGlobalUnlock - event = get_self - event.erase_route if event - end - - def setPrice(item, buy_price = -1, sell_price = -1) - item = GameData::Item.get(item).id - $game_temp.mart_prices[item] = [-1, -1] if !$game_temp.mart_prices[item] - $game_temp.mart_prices[item][0] = buy_price if buy_price > 0 - if sell_price >= 0 # 0=can't sell - $game_temp.mart_prices[item][1] = sell_price * 2 - else - $game_temp.mart_prices[item][1] = buy_price if buy_price > 0 - end - end - - def setSellPrice(item, sell_price) - setPrice(item, -1, sell_price) - end -end diff --git a/Data/Scripts/003_Game processing/004_Interpreter_Commands.rb b/Data/Scripts/003_Game processing/004_Interpreter_Commands.rb deleted file mode 100644 index 710fbc8c6..000000000 --- a/Data/Scripts/003_Game processing/004_Interpreter_Commands.rb +++ /dev/null @@ -1,1027 +0,0 @@ -#=============================================================================== -# ** Interpreter -#------------------------------------------------------------------------------- -# This interpreter runs event commands. This class is used within the -# Game_System class and the Game_Event class. -#=============================================================================== -class Interpreter - #----------------------------------------------------------------------------- - # * Event Command Execution - #----------------------------------------------------------------------------- - def execute_command - # Reached end of list of commands - if @index >= @list.size - 1 - command_end - return true - end - # Make current command's parameters available for reference via @parameters - @parameters = @list[@index].parameters - # Branch by command code - case @list[@index].code - when 101 then return command_101 # Show Text - when 102 then return command_102 # Show Choices - when 402 then return command_402 # When [**] - when 403 then return command_403 # When Cancel - when 103 then return command_103 # Input Number - when 104 then return command_104 # Change Text Options - when 105 then return command_105 # Button Input Processing - when 106 then return command_106 # Wait - when 111 then return command_111 # Conditional Branch - when 411 then return command_411 # Else - when 112 then return command_112 # Loop - when 413 then return command_413 # Repeat Above - when 113 then return command_113 # Break Loop - when 115 then return command_115 # Exit Event Processing - when 116 then return command_116 # Erase Event - when 117 then return command_117 # Call Common Event - when 118 then return command_118 # Label - when 119 then return command_119 # Jump to Label - when 121 then return command_121 # Control Switches - when 122 then return command_122 # Control Variables - when 123 then return command_123 # Control Self Switch - when 124 then return command_124 # Control Timer - when 125 then return command_125 # Change Gold - when 126 then return command_126 # Change Items - when 127 then return command_127 # Change Weapons - when 128 then return command_128 # Change Armor - when 129 then return command_129 # Change Party Member - when 131 then return command_131 # Change Windowskin - when 132 then return command_132 # Change Battle BGM - when 133 then return command_133 # Change Battle End ME - when 134 then return command_134 # Change Save Access - when 135 then return command_135 # Change Menu Access - when 136 then return command_136 # Change Encounter - when 201 then return command_201 # Transfer Player - when 202 then return command_202 # Set Event Location - when 203 then return command_203 # Scroll Map - when 204 then return command_204 # Change Map Settings - when 205 then return command_205 # Change Fog Color Tone - when 206 then return command_206 # Change Fog Opacity - when 207 then return command_207 # Show Animation - when 208 then return command_208 # Change Transparent Flag - when 209 then return command_209 # Set Move Route - when 210 then return command_210 # Wait for Move's Completion - when 221 then return command_221 # Prepare for Transition - when 222 then return command_222 # Execute Transition - when 223 then return command_223 # Change Screen Color Tone - when 224 then return command_224 # Screen Flash - when 225 then return command_225 # Screen Shake - when 231 then return command_231 # Show Picture - when 232 then return command_232 # Move Picture - when 233 then return command_233 # Rotate Picture - when 234 then return command_234 # Change Picture Color Tone - when 235 then return command_235 # Erase Picture - when 236 then return command_236 # Set Weather Effects - when 241 then return command_241 # Play BGM - when 242 then return command_242 # Fade Out BGM - when 245 then return command_245 # Play BGS - when 246 then return command_246 # Fade Out BGS - when 247 then return command_247 # Memorize BGM/BGS - when 248 then return command_248 # Restore BGM/BGS - when 249 then return command_249 # Play ME - when 250 then return command_250 # Play SE - when 251 then return command_251 # Stop SE - when 301 then return command_301 # Battle Processing - when 601 then return command_601 # If Win - when 602 then return command_602 # If Escape - when 603 then return command_603 # If Lose - when 302 then return command_302 # Shop Processing - when 303 then return command_303 # Name Input Processing - when 311 then return command_311 # Change HP - when 312 then return command_312 # Change SP - when 313 then return command_313 # Change State - when 314 then return command_314 # Recover All - when 315 then return command_315 # Change EXP - when 316 then return command_316 # Change Level - when 317 then return command_317 # Change Parameters - when 318 then return command_318 # Change Skills - when 319 then return command_319 # Change Equipment - when 320 then return command_320 # Change Actor Name - when 321 then return command_321 # Change Actor Class - when 322 then return command_322 # Change Actor Graphic - when 331 then return command_331 # Change Enemy HP - when 332 then return command_332 # Change Enemy SP - when 333 then return command_333 # Change Enemy State - when 334 then return command_334 # Enemy Recover All - when 335 then return command_335 # Enemy Appearance - when 336 then return command_336 # Enemy Transform - when 337 then return command_337 # Show Battle Animation - when 338 then return command_338 # Deal Damage - when 339 then return command_339 # Force Action - when 340 then return command_340 # Abort Battle - when 351 then return command_351 # Call Menu Screen - when 352 then return command_352 # Call Save Screen - when 353 then return command_353 # Game Over - when 354 then return command_354 # Return to Title Screen - when 355 then return command_355 # Script - else return true # Other - end - end - - def command_dummy - return true - end - #----------------------------------------------------------------------------- - # * End Event - #----------------------------------------------------------------------------- - def command_end - @list = nil - # If main map event and event ID are valid, unlock event - if @main && @event_id > 0 && $game_map.events[@event_id] - $game_map.events[@event_id].unlock - end - end - #----------------------------------------------------------------------------- - # * Command Skip - #----------------------------------------------------------------------------- - def command_skip - indent = @list[@index].indent - loop do - return true if @list[@index + 1].indent == indent - @index += 1 - end - end - #----------------------------------------------------------------------------- - # * Command If - #----------------------------------------------------------------------------- - def command_if(value) - if @branch[@list[@index].indent] == value - @branch.delete(@list[@index].indent) - return true - end - return command_skip - end - #----------------------------------------------------------------------------- - # * Show Text - #----------------------------------------------------------------------------- - def command_101 - return false if $game_temp.message_window_showing - message = @list[@index].parameters[0] - message_end = "" - commands = nil - number_input_variable = nil - number_input_max_digits = nil - # Check the next command(s) for things to add on to this text - loop do - next_index = pbNextIndex(@index) - case @list[next_index].code - when 401 # Continuation of 101 Show Text - text = @list[next_index].parameters[0] - message += " " if text != "" && message[message.length - 1, 1] != " " - message += text - @index = next_index - next - when 101 # Show Text - message_end = "\1" - when 102 # Show Choices - commands = @list[next_index].parameters - @index = next_index - when 103 # Input Number - number_input_variable = @list[next_index].parameters[0] - number_input_max_digits = @list[next_index].parameters[1] - @index = next_index - end - break - end - # Translate the text - message = _MAPINTL($game_map.map_id, message) - # Display the text, with commands/number choosing if appropriate - @message_waiting = true # Lets parallel process events work while a message is displayed - if commands - cmd_texts = [] - for cmd in commands[0] - cmd_texts.push(_MAPINTL($game_map.map_id, cmd)) - end - command = pbMessage(message + message_end, cmd_texts, commands[1]) - @branch[@list[@index].indent] = command - elsif number_input_variable - params = ChooseNumberParams.new - params.setMaxDigits(number_input_max_digits) - params.setDefaultValue($game_variables[number_input_variable]) - $game_variables[number_input_variable] = pbMessageChooseNumber(message + message_end, params) - $game_map.need_refresh = true if $game_map - else - pbMessage(message + message_end) - end - @message_waiting = false - return true - end - #----------------------------------------------------------------------------- - # * Show Choices - #----------------------------------------------------------------------------- - def command_102 - @message_waiting = true - command = pbShowCommands(nil, @list[@index].parameters[0], @list[@index].parameters[1]) - @message_waiting = false - @branch[@list[@index].indent] = command - Input.update # Must call Input.update again to avoid extra triggers - return true - end - #----------------------------------------------------------------------------- - # * When [**] - #----------------------------------------------------------------------------- - def command_402 - if @branch[@list[@index].indent] == @parameters[0] - @branch.delete(@list[@index].indent) - return true - end - return command_skip - end - #----------------------------------------------------------------------------- - # * When Cancel - #----------------------------------------------------------------------------- - def command_403 - if @branch[@list[@index].indent] == 4 - @branch.delete(@list[@index].indent) - return true - end - return command_skip - end - #----------------------------------------------------------------------------- - # * Input Number - #----------------------------------------------------------------------------- - def command_103 - @message_waiting = true - variable_number = @list[@index].parameters[0] - params = ChooseNumberParams.new - params.setMaxDigits(@list[@index].parameters[1]) - params.setDefaultValue($game_variables[variable_number]) - $game_variables[variable_number] = pbChooseNumber(nil, params) - $game_map.need_refresh = true if $game_map - @message_waiting = false - return true - end - #----------------------------------------------------------------------------- - # * Change Text Options - #----------------------------------------------------------------------------- - def command_104 - return false if $game_temp.message_window_showing - $game_system.message_position = @parameters[0] - $game_system.message_frame = @parameters[1] - return true - end - #----------------------------------------------------------------------------- - # * Button Input Processing - #----------------------------------------------------------------------------- - def pbButtonInputProcessing(variable_number = 0, timeout_frames = 0) - ret = 0 - timer = timeout_frames * Graphics.frame_rate / 20 - loop do - Graphics.update - Input.update - pbUpdateSceneMap - # Check for input and break if there is one - for i in 1..18 - ret = i if Input.trigger?(i) - end - break if ret != 0 - # Count down the timer and break if it runs out - if timeout_frames > 0 - timer -= 1 - break if timer <= 0 - end - end - Input.update - if variable_number && variable_number > 0 - $game_variables[variable_number] = ret - $game_map.need_refresh = true if $game_map - end - return ret - end - - def command_105 - return false if @buttonInput - @buttonInput = true - pbButtonInputProcessing(@list[@index].parameters[0]) - @buttonInput = false - @index += 1 - return true - end - #----------------------------------------------------------------------------- - # * Wait - #----------------------------------------------------------------------------- - def command_106 - @wait_count = @parameters[0] * Graphics.frame_rate / 20 - return true - end - #----------------------------------------------------------------------------- - # * Conditional Branch - #----------------------------------------------------------------------------- - def command_111 - result = false - case @parameters[0] - when 0 # switch - switch_name = $data_system.switches[@parameters[1]] - if switch_name && switch_name[/^s\:/] - result = (eval($~.post_match) == (@parameters[2] == 0)) - else - result = ($game_switches[@parameters[1]] == (@parameters[2] == 0)) - end - when 1 # variable - value1 = $game_variables[@parameters[1]] - value2 = (@parameters[2] == 0) ? @parameters[3] : $game_variables[@parameters[3]] - case @parameters[4] - when 0 then result = (value1 == value2) - when 1 then result = (value1 >= value2) - when 2 then result = (value1 <= value2) - when 3 then result = (value1 > value2) - when 4 then result = (value1 < value2) - when 5 then result = (value1 != value2) - end - when 2 # self switch - if @event_id > 0 - key = [$game_map.map_id, @event_id, @parameters[1]] - result = ($game_self_switches[key] == (@parameters[2] == 0)) - end - when 3 # timer - if $game_system.timer_working - sec = $game_system.timer / Graphics.frame_rate - result = (@parameters[2] == 0) ? (sec >= @parameters[1]) : (sec <= @parameters[1]) - end -# when 4, 5 # actor, enemy - when 6 # character - character = get_character(@parameters[1]) - result = (character.direction == @parameters[2]) if character - when 7 # gold - gold = $Trainer.money - result = (@parameters[2] == 0) ? (gold >= @parameters[1]) : (gold <= @parameters[1]) -# when 8, 9, 10 # item, weapon, armor - when 11 # button - result = Input.press?(@parameters[1]) - when 12 # script - result = execute_script(@parameters[1]) - end - # Store result in hash - @branch[@list[@index].indent] = result - if @branch[@list[@index].indent] - @branch.delete(@list[@index].indent) - return true - end - return command_skip - end - #----------------------------------------------------------------------------- - # * Else - #----------------------------------------------------------------------------- - def command_411 - if @branch[@list[@index].indent] == false # Could be nil, so intentionally checks for false - @branch.delete(@list[@index].indent) - return true - end - return command_skip - end - #----------------------------------------------------------------------------- - # * Loop - #----------------------------------------------------------------------------- - def command_112 - return true - end - #----------------------------------------------------------------------------- - # * Repeat Above - #----------------------------------------------------------------------------- - def command_413 - indent = @list[@index].indent - loop do - @index -= 1 - return true if @list[@index].indent == indent - end - end - #----------------------------------------------------------------------------- - # * Break Loop - #----------------------------------------------------------------------------- - def command_113 - indent = @list[@index].indent - temp_index = @index - loop do - temp_index += 1 - return true if temp_index >= @list.size - 1 # Reached end of commands - # Skip ahead to after the [Repeat Above] end of the current loop - if @list[temp_index].code == 413 && @list[temp_index].indent < indent - @index = temp_index - return true - end - end - end - #----------------------------------------------------------------------------- - # * Exit Event Processing - #----------------------------------------------------------------------------- - def command_115 - command_end - return true - end - #----------------------------------------------------------------------------- - # * Erase Event - #----------------------------------------------------------------------------- - def command_116 - if @event_id > 0 - $game_map.events[@event_id].erase if $game_map.events[@event_id] - $PokemonMap.addErasedEvent(@event_id) if $PokemonMap - end - @index += 1 - return false - end - #----------------------------------------------------------------------------- - # * Call Common Event - #----------------------------------------------------------------------------- - def command_117 - common_event = $data_common_events[@parameters[0]] - if common_event - @child_interpreter = Interpreter.new(@depth + 1) - @child_interpreter.setup(common_event.list, @event_id) - end - return true - end - #----------------------------------------------------------------------------- - # * Label - #----------------------------------------------------------------------------- - def command_118 - return true - end - #----------------------------------------------------------------------------- - # * Jump to Label - #----------------------------------------------------------------------------- - def command_119 - label_name = @parameters[0] - temp_index = 0 - loop do - return true if temp_index >= @list.size - 1 # Reached end of commands - # Check whether this command is a label with the desired name - if @list[temp_index].code == 118 && - @list[temp_index].parameters[0] == label_name - @index = temp_index - return true - end - # Command isn't the desired label, increment temp_index and keep looking - temp_index += 1 - end - end - #----------------------------------------------------------------------------- - # * Control Switches - #----------------------------------------------------------------------------- - def command_121 - should_refresh = false - for i in @parameters[0]..@parameters[1] - next if $game_switches[i] == (@parameters[2] == 0) - $game_switches[i] = (@parameters[2] == 0) - should_refresh = true - end - # Refresh map - $game_map.need_refresh = true if should_refresh - return true - end - #----------------------------------------------------------------------------- - # * Control Variables - #----------------------------------------------------------------------------- - def command_122 - value = 0 - case @parameters[3] - when 0 # invariable (fixed value) - value = @parameters[4] - when 1 # variable - value = $game_variables[@parameters[4]] - when 2 # random number - value = @parameters[4] + rand(@parameters[5] - @parameters[4] + 1) -# when 3, 4, 5 # item, actor, enemy - when 6 # character - character = get_character(@parameters[4]) - if character - case @parameters[5] - when 0 then value = character.x # x-coordinate - when 1 then value = character.y # y-coordinate - when 2 then value = character.direction # direction - when 3 then value = character.screen_x # screen x-coordinate - when 4 then value = character.screen_y # screen y-coordinate - when 5 then value = character.terrain_tag.id_number # terrain tag - end - end - when 7 # other - case @parameters[4] - when 0 then value = $game_map.map_id # map ID - when 1 then value = $Trainer.pokemon_party.length # party members - when 2 then value = $Trainer.money # gold -# when 3 # steps - when 4 then value = Graphics.frame_count / Graphics.frame_rate # play time - when 5 then value = $game_system.timer / Graphics.frame_rate # timer - when 6 then value = $game_system.save_count # save count - end - end - # Apply value and operation to all specified game variables - for i in @parameters[0]..@parameters[1] - case @parameters[2] - when 0 # set - next if $game_variables[i] == value - $game_variables[i] = value - when 1 # add - next if $game_variables[i] >= 99999999 - $game_variables[i] += value - when 2 # subtract - next if $game_variables[i] <= -99999999 - $game_variables[i] -= value - when 3 # multiply - next if value == 1 - $game_variables[i] *= value - when 4 # divide - next if value == 1 || value == 0 - $game_variables[i] /= value - when 5 # remainder - next if value == 1 || value == 0 - $game_variables[i] %= value - end - $game_variables[i] = 99999999 if $game_variables[i] > 99999999 - $game_variables[i] = -99999999 if $game_variables[i] < -99999999 - $game_map.need_refresh = true - end - return true - end - #----------------------------------------------------------------------------- - # * Control Self Switch - #----------------------------------------------------------------------------- - def command_123 - if @event_id > 0 - new_value = (@parameters[1] == 0) - key = [$game_map.map_id, @event_id, @parameters[0]] - if $game_self_switches[key] != new_value - $game_self_switches[key] = new_value - $game_map.need_refresh = true - end - end - return true - end - #----------------------------------------------------------------------------- - # * Control Timer - #----------------------------------------------------------------------------- - def command_124 - $game_system.timer_working = (@parameters[0] == 0) - $game_system.timer = @parameters[1] * Graphics.frame_rate if @parameters[0] == 0 - return true - end - #----------------------------------------------------------------------------- - # * Change Gold - #----------------------------------------------------------------------------- - def command_125 - value = (@parameters[1] == 0) ? @parameters[2] : $game_variables[@parameters[2]] - value = -value if @parameters[0] == 1 # Decrease - $Trainer.money += value - return true - end - - def command_126; command_dummy; end # Change Items - def command_127; command_dummy; end # Change Weapons - def command_128; command_dummy; end # Change Armor - def command_129; command_dummy; end # Change Party Member - #----------------------------------------------------------------------------- - # * Change Windowskin - #----------------------------------------------------------------------------- - def command_131 - for i in 0...Settings::SPEECH_WINDOWSKINS.length - next if Settings::SPEECH_WINDOWSKINS[i] != @parameters[0] - $PokemonSystem.textskin = i - MessageConfig.pbSetSpeechFrame("Graphics/Windowskins/" + Settings::SPEECH_WINDOWSKINS[i]) - return true - end - return true - end - #----------------------------------------------------------------------------- - # * Change Battle BGM - #----------------------------------------------------------------------------- - def command_132 - ($PokemonGlobal.nextBattleBGM = @parameters[0]) ? @parameters[0].clone : nil - return true - end - #----------------------------------------------------------------------------- - # * Change Battle End ME - #----------------------------------------------------------------------------- - def command_133 - ($PokemonGlobal.nextBattleME = @parameters[0]) ? @parameters[0].clone : nil - return true - end - #----------------------------------------------------------------------------- - # * Change Save Access - #----------------------------------------------------------------------------- - def command_134 - $game_system.save_disabled = (@parameters[0] == 0) - return true - end - #----------------------------------------------------------------------------- - # * Change Menu Access - #----------------------------------------------------------------------------- - def command_135 - $game_system.menu_disabled = (@parameters[0] == 0) - return true - end - #----------------------------------------------------------------------------- - # * Change Encounter - #----------------------------------------------------------------------------- - def command_136 - $game_system.encounter_disabled = (@parameters[0] == 0) - $game_player.make_encounter_count - return true - end - #----------------------------------------------------------------------------- - # * Transfer Player - #----------------------------------------------------------------------------- - def command_201 - return true if $game_temp.in_battle - return false if $game_temp.player_transferring || - $game_temp.message_window_showing || - $game_temp.transition_processing - # Set up the transfer and the player's new coordinates - $game_temp.player_transferring = true - if @parameters[0] == 0 # Direct appointment - $game_temp.player_new_map_id = @parameters[1] - $game_temp.player_new_x = @parameters[2] - $game_temp.player_new_y = @parameters[3] - $game_temp.player_new_direction = @parameters[4] - else # Appoint with variables - $game_temp.player_new_map_id = $game_variables[@parameters[1]] - $game_temp.player_new_x = $game_variables[@parameters[2]] - $game_temp.player_new_y = $game_variables[@parameters[3]] - $game_temp.player_new_direction = @parameters[4] - end - @index += 1 - # If transition happens with a fade, do the fade - if @parameters[5] == 0 - Graphics.freeze - $game_temp.transition_processing = true - $game_temp.transition_name = "" - end - return false - end - #----------------------------------------------------------------------------- - # * Set Event Location - #----------------------------------------------------------------------------- - def command_202 - return true if $game_temp.in_battle - character = get_character(@parameters[0]) - return true if character.nil? - # Move the character - if @parameters[1] == 0 # Direct appointment - character.moveto(@parameters[2], @parameters[3]) - elsif @parameters[1] == 1 # Appoint with variables - character.moveto($game_variables[@parameters[2]], $game_variables[@parameters[3]]) - else # Exchange with another event - character2 = get_character(@parameters[2]) - if character2 - old_x = character.x - old_y = character.y - character.moveto(character2.x, character2.y) - character2.moveto(old_x, old_y) - end - end - # Set character's direction - case @parameters[4] - when 2 then character.turn_down - when 4 then character.turn_left - when 6 then character.turn_right - when 8 then character.turn_up - end - return true - end - #----------------------------------------------------------------------------- - # * Scroll Map - #----------------------------------------------------------------------------- - def command_203 - return true if $game_temp.in_battle - return false if $game_map.scrolling? - $game_map.start_scroll(@parameters[0], @parameters[1], @parameters[2]) - return true - end - #----------------------------------------------------------------------------- - # * Change Map Settings - #----------------------------------------------------------------------------- - def command_204 - case @parameters[0] - when 0 # panorama - $game_map.panorama_name = @parameters[1] - $game_map.panorama_hue = @parameters[2] - when 1 # fog - $game_map.fog_name = @parameters[1] - $game_map.fog_hue = @parameters[2] - $game_map.fog_opacity = @parameters[3] - $game_map.fog_blend_type = @parameters[4] - $game_map.fog_zoom = @parameters[5] - $game_map.fog_sx = @parameters[6] - $game_map.fog_sy = @parameters[7] - when 2 # battleback - $game_map.battleback_name = @parameters[1] - $game_temp.battleback_name = @parameters[1] - end - return true - end - #----------------------------------------------------------------------------- - # * Change Fog Color Tone - #----------------------------------------------------------------------------- - def command_205 - $game_map.start_fog_tone_change(@parameters[0], @parameters[1] * Graphics.frame_rate / 20) - return true - end - #----------------------------------------------------------------------------- - # * Change Fog Opacity - #----------------------------------------------------------------------------- - def command_206 - $game_map.start_fog_opacity_change(@parameters[0], @parameters[1] * Graphics.frame_rate / 20) - return true - end - #----------------------------------------------------------------------------- - # * Show Animation - #----------------------------------------------------------------------------- - def command_207 - character = get_character(@parameters[0]) - return true if character.nil? - character.animation_id = @parameters[1] - return true - end - #----------------------------------------------------------------------------- - # * Change Transparent Flag - #----------------------------------------------------------------------------- - def command_208 - $game_player.transparent = (@parameters[0] == 0) - return true - end - #----------------------------------------------------------------------------- - # * Set Move Route - #----------------------------------------------------------------------------- - def command_209 - character = get_character(@parameters[0]) - return true if character.nil? - character.force_move_route(@parameters[1]) - return true - end - #----------------------------------------------------------------------------- - # * Wait for Move's Completion - #----------------------------------------------------------------------------- - def command_210 - @move_route_waiting = true if !$game_temp.in_battle - return true - end - #----------------------------------------------------------------------------- - # * Prepare for Transition - #----------------------------------------------------------------------------- - def command_221 - return false if $game_temp.message_window_showing - Graphics.freeze - return true - end - #----------------------------------------------------------------------------- - # * Execute Transition - #----------------------------------------------------------------------------- - def command_222 - return false if $game_temp.transition_processing - $game_temp.transition_processing = true - $game_temp.transition_name = @parameters[0] - @index += 1 - return false - end - #----------------------------------------------------------------------------- - # * Change Screen Color Tone - #----------------------------------------------------------------------------- - def command_223 - $game_screen.start_tone_change(@parameters[0], @parameters[1] * Graphics.frame_rate / 20) - return true - end - #----------------------------------------------------------------------------- - # * Screen Flash - #----------------------------------------------------------------------------- - def command_224 - $game_screen.start_flash(@parameters[0], @parameters[1] * Graphics.frame_rate / 20) - return true - end - #----------------------------------------------------------------------------- - # * Screen Shake - #----------------------------------------------------------------------------- - def command_225 - $game_screen.start_shake(@parameters[0], @parameters[1], @parameters[2] * Graphics.frame_rate / 20) - return true - end - #----------------------------------------------------------------------------- - # * Show Picture - #----------------------------------------------------------------------------- - def command_231 - number = @parameters[0] + ($game_temp.in_battle ? 50 : 0) - if @parameters[3] == 0 # Direct appointment - x = @parameters[4] - y = @parameters[5] - else # Appoint with variables - x = $game_variables[@parameters[4]] - y = $game_variables[@parameters[5]] - end - $game_screen.pictures[number].show(@parameters[1], @parameters[2], - x, y, @parameters[6], @parameters[7], @parameters[8], @parameters[9]) - return true - end - #----------------------------------------------------------------------------- - # * Move Picture - #----------------------------------------------------------------------------- - def command_232 - number = @parameters[0] + ($game_temp.in_battle ? 50 : 0) - if @parameters[3] == 0 # Direct appointment - x = @parameters[4] - y = @parameters[5] - else # Appoint with variables - x = $game_variables[@parameters[4]] - y = $game_variables[@parameters[5]] - end - $game_screen.pictures[number].move(@parameters[1] * Graphics.frame_rate / 20, - @parameters[2], x, y, @parameters[6], @parameters[7], @parameters[8], @parameters[9]) - return true - end - #----------------------------------------------------------------------------- - # * Rotate Picture - #----------------------------------------------------------------------------- - def command_233 - number = @parameters[0] + ($game_temp.in_battle ? 50 : 0) - $game_screen.pictures[number].rotate(@parameters[1]) - return true - end - #----------------------------------------------------------------------------- - # * Change Picture Color Tone - #----------------------------------------------------------------------------- - def command_234 - number = @parameters[0] + ($game_temp.in_battle ? 50 : 0) - $game_screen.pictures[number].start_tone_change(@parameters[1], - @parameters[2] * Graphics.frame_rate / 20) - return true - end - #----------------------------------------------------------------------------- - # * Erase Picture - #----------------------------------------------------------------------------- - def command_235 - number = @parameters[0] + ($game_temp.in_battle ? 50 : 0) - $game_screen.pictures[number].erase - return true - end - #----------------------------------------------------------------------------- - # * Set Weather Effects - #----------------------------------------------------------------------------- - def command_236 - $game_screen.weather(@parameters[0], @parameters[1], @parameters[2]) - return true - end - #----------------------------------------------------------------------------- - # * Play BGM - #----------------------------------------------------------------------------- - def command_241 - pbBGMPlay(@parameters[0]) - return true - end - #----------------------------------------------------------------------------- - # * Fade Out BGM - #----------------------------------------------------------------------------- - def command_242 - pbBGMFade(@parameters[0]) - return true - end - #----------------------------------------------------------------------------- - # * Play BGS - #----------------------------------------------------------------------------- - def command_245 - pbBGSPlay(@parameters[0]) - return true - end - #----------------------------------------------------------------------------- - # * Fade Out BGS - #----------------------------------------------------------------------------- - def command_246 - pbBGSFade(@parameters[0]) - return true - end - #----------------------------------------------------------------------------- - # * Memorize BGM/BGS - #----------------------------------------------------------------------------- - def command_247 - $game_system.bgm_memorize - $game_system.bgs_memorize - return true - end - #----------------------------------------------------------------------------- - # * Restore BGM/BGS - #----------------------------------------------------------------------------- - def command_248 - $game_system.bgm_restore - $game_system.bgs_restore - return true - end - #----------------------------------------------------------------------------- - # * Play ME - #----------------------------------------------------------------------------- - def command_249 - pbMEPlay(@parameters[0]) - return true - end - #----------------------------------------------------------------------------- - # * Play SE - #----------------------------------------------------------------------------- - def command_250 - pbSEPlay(@parameters[0]) - return true - end - #----------------------------------------------------------------------------- - # * Stop SE - #----------------------------------------------------------------------------- - def command_251 - pbSEStop - return true - end - - def command_301; command_dummy; end # Battle Processing - def command_601; command_if(0); end # If Win - def command_602; command_if(1); end # If Escape - def command_603; command_if(2); end # If Lose - def command_302; command_dummy; end # Shop Processing - #----------------------------------------------------------------------------- - # * Name Input Processing - #----------------------------------------------------------------------------- - def command_303 - if $Trainer - $Trainer.name = pbEnterPlayerName(_INTL("Your name?"), 1, @parameters[1], $Trainer.name) - return true - end - if $game_actors && $data_actors && $data_actors[@parameters[0]] != nil - $game_temp.battle_abort = true - pbFadeOutIn { - sscene = PokemonEntryScene.new - sscreen = PokemonEntry.new(sscene) - $game_actors[@parameters[0]].name = sscreen.pbStartScreen( - _INTL("Enter {1}'s name.", $game_actors[@parameters[0]].name), - 1, @parameters[1], $game_actors[@parameters[0]].name) - } - end - return true - end - - def command_311; command_dummy; end # Change HP - def command_312; command_dummy; end # Change SP - def command_313; command_dummy; end # Change State - #----------------------------------------------------------------------------- - # * Recover All - #----------------------------------------------------------------------------- - def command_314 - $Trainer.heal_party if @parameters[0] == 0 - return true - end - - def command_315; command_dummy; end # Change EXP - def command_316; command_dummy; end # Change Level - def command_317; command_dummy; end # Change Parameters - def command_318; command_dummy; end # Change Skills - def command_319; command_dummy; end # Change Equipment - def command_320; command_dummy; end # Change Actor Name - def command_321; command_dummy; end # Change Actor Class - def command_322; command_dummy; end # Change Actor Graphic - def command_331; command_dummy; end # Change Enemy HP - def command_332; command_dummy; end # Change Enemy SP - def command_333; command_dummy; end # Change Enemy State - def command_334; command_dummy; end # Enemy Recover All - def command_335; command_dummy; end # Enemy Appearance - def command_336; command_dummy; end # Enemy Transform - def command_337; command_dummy; end # Show Battle Animation - def command_338; command_dummy; end # Deal Damage - def command_339; command_dummy; end # Force Action - def command_340; command_dummy; end # Abort Battle - #----------------------------------------------------------------------------- - # * Call Menu Screen - #----------------------------------------------------------------------------- - def command_351 - $game_temp.menu_calling = true - @index += 1 - return false - end - #----------------------------------------------------------------------------- - # * Call Save Screen - #----------------------------------------------------------------------------- - def command_352 - scene = PokemonSave_Scene.new - screen = PokemonSaveScreen.new(scene) - screen.pbSaveScreen - return true - end - #----------------------------------------------------------------------------- - # * Game Over - #----------------------------------------------------------------------------- - def command_353 - pbBGMFade(1.0) - pbBGSFade(1.0) - pbFadeOutIn { pbStartOver(true) } - end - #----------------------------------------------------------------------------- - # * Return to Title Screen - #----------------------------------------------------------------------------- - def command_354 - $game_temp.to_title = true - return false - end - #----------------------------------------------------------------------------- - # * Script - #----------------------------------------------------------------------------- - def command_355 - script = @list[@index].parameters[0] + "\n" - # Look for more script commands or a continuation of one, and add them to script - loop do - break if ![355, 655].include?(@list[@index + 1].code) - script += @list[@index+1].parameters[0] + "\n" - @index += 1 - end - # Run the script - execute_script(script) - return true - end -end diff --git a/Data/Scripts/003_Game processing/005_Event_Handlers.rb b/Data/Scripts/003_Game processing/005_Event_Handlers.rb deleted file mode 100644 index 58129853f..000000000 --- a/Data/Scripts/003_Game processing/005_Event_Handlers.rb +++ /dev/null @@ -1,275 +0,0 @@ -#=============================================================================== -# Defines an event that procedures can subscribe to. -#=============================================================================== -class Event - def initialize - @callbacks = [] - end - - # Sets an event handler for this event and removes all other event handlers. - def set(method) - @callbacks.clear - @callbacks.push(method) - end - - # Removes an event handler procedure from the event. - def -(method) - for i in 0...@callbacks.length - next if @callbacks[i]!=method - @callbacks.delete_at(i) - break - end - return self - end - - # Adds an event handler procedure from the event. - def +(method) - for i in 0...@callbacks.length - return self if @callbacks[i]==method - end - @callbacks.push(method) - return self - end - - # Clears the event of event handlers. - def clear - @callbacks.clear - end - - # Triggers the event and calls all its event handlers. Normally called only - # by the code where the event occurred. - # The first argument is the sender of the event, the second argument contains - # the event's parameters. If three or more arguments are given, this method - # supports the following callbacks: - # proc { |sender,params| } where params is an array of the other parameters, and - # proc { |sender,arg0,arg1,...| } - def trigger(*arg) - arglist = arg[1,arg.length] - for callback in @callbacks - if callback.arity>2 && arg.length==callback.arity - # Retrofitted for callbacks that take three or more arguments - callback.call(*arg) - else - callback.call(arg[0],arglist) - end - end - end - - # Triggers the event and calls all its event handlers. Normally called only - # by the code where the event occurred. The first argument is the sender of - # the event, the other arguments are the event's parameters. - def trigger2(*arg) - for callback in @callbacks - callback.call(*arg) - end - end -end - -#=============================================================================== -# -#=============================================================================== -class HandlerHash - def initialize(mod) - @mod = mod - @hash = {} - @addIfs = [] - @symbolCache = {} - end - - def fromSymbol(sym) - return sym unless sym.is_a?(Symbol) || sym.is_a?(String) - mod = Object.const_get(@mod) rescue nil - return nil if !mod - return mod.const_get(sym.to_sym) rescue nil - end - - def toSymbol(sym) - return sym.to_sym if sym.is_a?(Symbol) || sym.is_a?(String) - ret = @symbolCache[sym] - return ret if ret - mod = Object.const_get(@mod) rescue nil - return nil if !mod - for key in mod.constants - next if mod.const_get(key)!=sym - ret = key.to_sym - @symbolCache[sym] = ret - break - end - return ret - end - - def addIf(conditionProc,handler=nil,&handlerBlock) - if ![Proc,Hash].include?(handler.class) && !block_given? - raise ArgumentError, "addIf call for #{self.class.name} has no valid handler (#{handler.inspect} was given)" - end - @addIfs.push([conditionProc,handler || handlerBlock]) - end - - def add(sym,handler=nil,&handlerBlock) # 'sym' can be an ID or symbol - if ![Proc,Hash].include?(handler.class) && !block_given? - raise ArgumentError, "#{self.class.name} for #{sym.inspect} has no valid handler (#{handler.inspect} was given)" - end - id = fromSymbol(sym) - @hash[id] = handler || handlerBlock if id - symbol = toSymbol(sym) - @hash[symbol] = handler || handlerBlock if symbol - end - - def copy(src,*dests) - handler = self[src] - if handler - for dest in dests - self.add(dest,handler) - end - end - end - - def [](sym) # 'sym' can be an ID or symbol - id = fromSymbol(sym) - ret = nil - ret = @hash[id] if id && @hash[id] # Real ID from the item - symbol = toSymbol(sym) - ret = @hash[symbol] if symbol && @hash[symbol] # Symbol or string - unless ret - for addif in @addIfs - return addif[1] if addif[0].call(id) - end - end - return ret - end - - def trigger(sym,*args) - handler = self[sym] - return (handler) ? handler.call(fromSymbol(sym),*args) : nil - end - - def clear - @hash.clear - end -end - -#=============================================================================== -# A stripped-down version of class HandlerHash which only deals with symbols and -# doesn't care about whether those symbols actually relate to a defined thing. -#=============================================================================== -class HandlerHash2 - def initialize - @hash = {} - @add_ifs = [] - end - - def [](sym) - sym = sym.id if !sym.is_a?(Symbol) && sym.respond_to?("id") - return @hash[sym] if sym && @hash[sym] - for add_if in @add_ifs - return add_if[1] if add_if[0].call(sym) - end - return nil - end - - def addIf(conditionProc, handler = nil, &handlerBlock) - if ![Proc, Hash].include?(handler.class) && !block_given? - raise ArgumentError, "addIf call for #{self.class.name} has no valid handler (#{handler.inspect} was given)" - end - @add_ifs.push([conditionProc, handler || handlerBlock]) - end - - def add(sym, handler = nil, &handlerBlock) - if ![Proc, Hash].include?(handler.class) && !block_given? - raise ArgumentError, "#{self.class.name} for #{sym.inspect} has no valid handler (#{handler.inspect} was given)" - end - @hash[sym] = handler || handlerBlock if sym - end - - def copy(src, *dests) - handler = self[src] - return if !handler - for dest in dests - self.add(dest, handler) - end - end - - def clear - @hash.clear - end - - def trigger(sym, *args) - sym = sym.id if !sym.is_a?(Symbol) && sym.respond_to?("id") - handler = self[sym] - return (handler) ? handler.call(sym, *args) : nil - end -end - -#=============================================================================== -# An even more stripped down version of class HandlerHash which just takes -# hashes with keys, no matter what the keys are. -#=============================================================================== -class HandlerHashBasic - def initialize - @ordered_keys = [] - @hash = {} - @addIfs = [] - end - - def [](entry) - ret = nil - ret = @hash[entry] if entry && @hash[entry] - unless ret - for addif in @addIfs - return addif[1] if addif[0].call(entry) - end - end - return ret - end - - def each - @ordered_keys.each { |key| yield key, @hash[key] } - end - - def add(entry, handler = nil, &handlerBlock) - if ![Proc,Hash].include?(handler.class) && !block_given? - raise ArgumentError, "#{self.class.name} for #{entry.inspect} has no valid handler (#{handler.inspect} was given)" - end - return if !entry || entry.empty? - @ordered_keys.push(entry) if !@ordered_keys.include?(entry) - @hash[entry] = handler || handlerBlock - end - - def addIf(conditionProc, handler = nil, &handlerBlock) - if ![Proc, Hash].include?(handler.class) && !block_given? - raise ArgumentError, "addIf call for #{self.class.name} has no valid handler (#{handler.inspect} was given)" - end - @addIfs.push([conditionProc, handler || handlerBlock]) - end - - def copy(src, *dests) - handler = self[src] - return if !handler - dests.each { |dest| self.add(dest, handler) } - end - - def clear - @hash.clear - @ordered_keys.clear - end - - def trigger(entry, *args) - handler = self[entry] - return (handler) ? handler.call(*args) : nil - end -end - -#=============================================================================== -# -#=============================================================================== -class SpeciesHandlerHash < HandlerHash2 -end - -class AbilityHandlerHash < HandlerHash2 -end - -class ItemHandlerHash < HandlerHash2 -end - -class MoveHandlerHash < HandlerHash2 -end diff --git a/Data/Scripts/003_Game processing/006_Event_OverworldEvents.rb b/Data/Scripts/003_Game processing/006_Event_OverworldEvents.rb deleted file mode 100644 index b83ea0d6f..000000000 --- a/Data/Scripts/003_Game processing/006_Event_OverworldEvents.rb +++ /dev/null @@ -1,172 +0,0 @@ -#=============================================================================== -# This module stores events that can happen during the game. A procedure can -# subscribe to an event by adding itself to the event. It will then be called -# whenever the event occurs. -#=============================================================================== -module Events - @@OnMapCreate = Event.new - @@OnMapUpdate = Event.new - @@OnMapChange = Event.new - @@OnMapChanging = Event.new - @@OnMapSceneChange = Event.new - @@OnSpritesetCreate = Event.new - @@OnAction = Event.new - @@OnStepTaken = Event.new - @@OnLeaveTile = Event.new - @@OnStepTakenFieldMovement = Event.new - @@OnStepTakenTransferPossible = Event.new - @@OnStartBattle = Event.new - @@OnEndBattle = Event.new - @@OnWildPokemonCreate = Event.new - @@OnWildBattleOverride = Event.new - @@OnWildBattleEnd = Event.new - @@OnTrainerPartyLoad = Event.new - @@OnChangeDirection = Event.new - - # Fires whenever a map is created. Event handler receives two parameters: the - # map (RPG::Map) and the tileset (RPG::Tileset) - def self.onMapCreate; @@OnMapCreate; end - def self.onMapCreate=(v); @@OnMapCreate = v; end - - # Fires each frame during a map update. - def self.onMapUpdate; @@OnMapUpdate; end - def self.onMapUpdate=(v); @@OnMapUpdate = v; end - - # Fires whenever one map is about to change to a different one. Event handler - # receives the new map ID and the Game_Map object representing the new map. - # When the event handler is called, $game_map still refers to the old map. - def self.onMapChanging; @@OnMapChanging; end - def self.onMapChanging=(v); @@OnMapChanging = v; end - - # Fires whenever the player moves to a new map. Event handler receives the old - # map ID or 0 if none. Also fires when the first map of the game is loaded - def self.onMapChange; @@OnMapChange; end - def self.onMapChange=(v); @@OnMapChange = v; end - - # Fires whenever the map scene is regenerated and soon after the player moves - # to a new map. - # Parameters: - # e[0] - Scene_Map object. - # e[1] - Whether the player just moved to a new map (either true or false). If - # false, some other code had called $scene.createSpritesets to - # regenerate the map scene without transferring the player elsewhere - def self.onMapSceneChange; @@OnMapSceneChange; end - def self.onMapSceneChange=(v); @@OnMapSceneChange = v; end - - # Fires whenever a spriteset is created. - # Parameters: - # e[0] - Spriteset being created. e[0].map is the map associated with the - # spriteset (not necessarily the current map). - # e[1] - Viewport used for tilemap and characters - def self.onSpritesetCreate; @@OnSpritesetCreate; end - def self.onSpritesetCreate=(v); @@OnSpritesetCreate = v; end - - # Triggers when the player presses the Action button on the map. - def self.onAction; @@OnAction; end - def self.onAction=(v); @@OnAction = v; end - - # Fires whenever the player takes a step. - def self.onStepTaken; @@OnStepTaken; end - def self.onStepTaken=(v); @@OnStepTaken = v; end - - # Fires whenever the player or another event leaves a tile. - # Parameters: - # e[0] - Event that just left the tile. - # e[1] - Map ID where the tile is located (not necessarily - # the current map). Use "$MapFactory.getMap(e[1])" to - # get the Game_Map object corresponding to that map. - # e[2] - X-coordinate of the tile - # e[3] - Y-coordinate of the tile - def self.onLeaveTile; @@OnLeaveTile; end - def self.onLeaveTile=(v); @@OnLeaveTile = v; end - - # Fires whenever the player or another event enters a tile. - # Parameters: - # e[0] - Event that just entered a tile. - def self.onStepTakenFieldMovement; @@OnStepTakenFieldMovement; end - def self.onStepTakenFieldMovement=(v); @@OnStepTakenFieldMovement = v; end - - # Fires whenever the player takes a step. The event handler may possibly move - # the player elsewhere. - # Parameters: - # e[0] - Array that contains a single boolean value. If an event handler moves - # the player to a new map, it should set this value to true. Other - # event handlers should check this parameter's value. - def self.onStepTakenTransferPossible; @@OnStepTakenTransferPossible; end - def self.onStepTakenTransferPossible=(v); @@OnStepTakenTransferPossible = v; end - - def self.onStartBattle; @@OnStartBattle; end - def self.onStartBattle=(v); @@OnStartBattle = v; end - - def self.onEndBattle; @@OnEndBattle; end - def self.onEndBattle=(v); @@OnEndBattle = v; end - - # Triggers whenever a wild Pokémon is created - # Parameters: - # e[0] - Pokémon being created - def self.onWildPokemonCreate; @@OnWildPokemonCreate; end - def self.onWildPokemonCreate=(v); @@OnWildPokemonCreate = v; end - - # Triggers at the start of a wild battle. Event handlers can provide their - # own wild battle routines to override the default behavior. - def self.onWildBattleOverride; @@OnWildBattleOverride; end - def self.onWildBattleOverride=(v); @@OnWildBattleOverride = v; end - - # Triggers whenever a wild Pokémon battle ends - # Parameters: - # e[0] - Pokémon species - # e[1] - Pokémon level - # e[2] - Battle result (1-win, 2-loss, 3-escaped, 4-caught, 5-draw) - def self.onWildBattleEnd; @@OnWildBattleEnd; end - def self.onWildBattleEnd=(v); @@OnWildBattleEnd = v; end - - # Triggers whenever an NPC trainer's Pokémon party is loaded - # Parameters: - # e[0] - Trainer - # e[1] - Items possessed by the trainer - # e[2] - Party - def self.onTrainerPartyLoad; @@OnTrainerPartyLoad; end - def self.onTrainerPartyLoad=(v); @@OnTrainerPartyLoad = v; end - - # Fires whenever the player changes direction. - def self.onChangeDirection; @@OnChangeDirection; end - def self.onChangeDirection=(v); @@OnChangeDirection = v; end -end - -#=============================================================================== -# -#=============================================================================== -def pbOnSpritesetCreate(spriteset,viewport) - Events.onSpritesetCreate.trigger(nil,spriteset,viewport) -end - -#=============================================================================== -# This module stores encounter-modifying events that can happen during the game. -# A procedure can subscribe to an event by adding itself to the event. It will -# then be called whenever the event occurs. -#=============================================================================== -module EncounterModifier - @@procs = [] - @@procsEnd = [] - - def self.register(p) - @@procs.push(p) - end - - def self.registerEncounterEnd(p) - @@procsEnd.push(p) - end - - def self.trigger(encounter) - for prc in @@procs - encounter = prc.call(encounter) - end - return encounter - end - - def self.triggerEncounterEnd() - for prc in @@procsEnd - prc.call() - end - end -end diff --git a/Data/Scripts/004_Game classes/001_Game_Screen.rb b/Data/Scripts/004_Game classes/001_Game_Screen.rb deleted file mode 100644 index 417cc2fdb..000000000 --- a/Data/Scripts/004_Game classes/001_Game_Screen.rb +++ /dev/null @@ -1,154 +0,0 @@ -#=============================================================================== -# ** Game_Screen -#------------------------------------------------------------------------------- -# This class handles screen maintenance data, such as change in color tone, -# flashing, etc. Refer to "$game_screen" for the instance of this class. -#=============================================================================== - -class Game_Screen - #----------------------------------------------------------------------------- - # * Public Instance Variables - #----------------------------------------------------------------------------- - attr_reader :brightness # brightness - attr_reader :tone # color tone - attr_reader :flash_color # flash color - attr_reader :shake # shake positioning - attr_reader :pictures # pictures - attr_reader :weather_type # weather type - attr_reader :weather_max # max number of weather sprites - attr_accessor :weather_duration # ticks in which the weather should fade in - #----------------------------------------------------------------------------- - # * Object Initialization - #----------------------------------------------------------------------------- - def initialize - @brightness = 255 - @fadeout_duration = 0 - @fadein_duration = 0 - @tone = Tone.new(0, 0, 0, 0) - @tone_target = Tone.new(0, 0, 0, 0) - @tone_duration = 0 - @flash_color = Color.new(0, 0, 0, 0) - @flash_duration = 0 - @shake_power = 0 - @shake_speed = 0 - @shake_duration = 0 - @shake_direction = 1 - @shake = 0 - @pictures = [nil] - for i in 1..100 - @pictures.push(Game_Picture.new(i)) - end - @weather_type = 0 - @weather_max = 0.0 - @weather_duration = 0 - end - #----------------------------------------------------------------------------- - # * Start Changing Color Tone - # tone : color tone - # duration : time - #----------------------------------------------------------------------------- - def start_tone_change(tone, duration) - @tone_target = tone.clone - @tone_duration = duration - if @tone_duration == 0 - @tone = @tone_target.clone - end - end - #----------------------------------------------------------------------------- - # * Start Flashing - # color : color - # duration : time - #----------------------------------------------------------------------------- - def start_flash(color, duration) - @flash_color = color.clone - @flash_duration = duration - end - #----------------------------------------------------------------------------- - # * Start Shaking - # power : strength - # speed : speed - # duration : time - #----------------------------------------------------------------------------- - def start_shake(power, speed, duration) - @shake_power = power - @shake_speed = speed - @shake_duration = duration - end - #----------------------------------------------------------------------------- - # * Set Weather - # type : type - # power : strength - # duration : time - #----------------------------------------------------------------------------- - def weather(type, power, duration) - @weather_type = GameData::Weather.get(type).id - @weather_max = (power + 1) * RPG::Weather::MAX_SPRITES / 10 - @weather_duration = duration # In 1/20ths of a seconds - end - #----------------------------------------------------------------------------- - # * Frame Update - #----------------------------------------------------------------------------- - def update - if @fadeout_duration && @fadeout_duration>=1 - d = @fadeout_duration - @brightness = (@brightness*(d-1))/d - @fadeout_duration -= 1 - end - if @fadein_duration && @fadein_duration>=1 - d = @fadein_duration - @brightness = (@brightness*(d-1)+255)/d - @fadein_duration -= 1 - end - if @tone_duration>=1 - d = @tone_duration - @tone.red = (@tone.red*(d-1)+@tone_target.red)/d - @tone.green = (@tone.green*(d-1)+@tone_target.green)/d - @tone.blue = (@tone.blue*(d-1)+@tone_target.blue)/d - @tone.gray = (@tone.gray*(d-1)+@tone_target.gray)/d - @tone_duration -= 1 - end - if @flash_duration>=1 - d = @flash_duration - @flash_color.alpha = @flash_color.alpha*(d-1)/d - @flash_duration -= 1 - end - if @shake_duration>=1 || @shake!=0 - delta = (@shake_power*@shake_speed*@shake_direction)/10.0 - if @shake_duration<=1 && @shake*(@shake+delta)<0 - @shake = 0 - else - @shake += delta - end - @shake_direction = -1 if @shake>@shake_power*2 - @shake_direction = 1 if @shake<-@shake_power*2 - @shake_duration -= 1 if @shake_duration>=1 - end - if $game_temp.in_battle - for i in 51..100 - @pictures[i].update - end - else - for i in 1..50 - @pictures[i].update - end - end - end -end - -#=============================================================================== -# -#=============================================================================== -def pbToneChangeAll(tone,duration) - $game_screen.start_tone_change(tone,duration*Graphics.frame_rate/20) - for picture in $game_screen.pictures - picture.start_tone_change(tone,duration*Graphics.frame_rate/20) if picture - end -end - -def pbShake(power,speed,frames) - $game_screen.start_shake(power,speed,frames*Graphics.frame_rate/20) -end - -def pbFlash(color,frames) - $game_screen.start_flash(color,frames*Graphics.frame_rate/20) -end diff --git a/Data/Scripts/004_Game classes/001_Switches and Variables/001_Game_Temp.rb b/Data/Scripts/004_Game classes/001_Switches and Variables/001_Game_Temp.rb deleted file mode 100644 index ac969e184..000000000 --- a/Data/Scripts/004_Game classes/001_Switches and Variables/001_Game_Temp.rb +++ /dev/null @@ -1,68 +0,0 @@ -#=============================================================================== -# ** Game_Temp -#------------------------------------------------------------------------------- -# This class handles temporary data that is not included with save data. -# Refer to "$game_temp" for the instance of this class. -#=============================================================================== -class Game_Temp - attr_accessor :message_window_showing # message window showing - attr_accessor :common_event_id # common event ID - attr_accessor :in_battle # in-battle flag - attr_accessor :battle_abort # battle flag: interrupt - attr_accessor :battleback_name # battleback file name - attr_accessor :in_menu # menu is open - attr_accessor :menu_beep # menu: play sound effect flag - attr_accessor :menu_calling # menu calling flag - attr_accessor :debug_calling # debug calling flag - attr_accessor :player_transferring # player place movement flag - attr_accessor :player_new_map_id # player destination: map ID - attr_accessor :player_new_x # player destination: x-coordinate - attr_accessor :player_new_y # player destination: y-coordinate - attr_accessor :player_new_direction # player destination: direction - attr_accessor :transition_processing # transition processing flag - attr_accessor :transition_name # transition file name - attr_accessor :to_title # return to title screen flag - attr_accessor :fadestate # for sprite hashes - attr_accessor :background_bitmap - attr_accessor :mart_prices - attr_accessor :unimportedSprites - attr_accessor :nb_imported_sprites - attr_accessor :loading_screen - attr_accessor :custom_sprites_list - attr_accessor :base_sprites_list - - #----------------------------------------------------------------------------- - # * Object Initialization - #----------------------------------------------------------------------------- - def initialize - @message_window_showing = false - @common_event_id = 0 - @in_battle = false - @battle_abort = false - @battleback_name = '' - @in_menu = false - @menu_beep = false - @menu_calling = false - @debug_calling = false - @player_transferring = false - @player_new_map_id = 0 - @player_new_x = 0 - @player_new_y = 0 - @player_new_direction = 0 - @transition_processing = false - @transition_name = "" - @to_title = false - @fadestate = 0 - @background_bitmap = nil - @message_window_showing = false - @transition_processing = false - @mart_prices = {} - @custom_sprites_list ={} - @base_sprites_list ={} - - end - - def clear_mart_prices - @mart_prices = {} - end -end diff --git a/Data/Scripts/004_Game classes/001_Switches and Variables/002_Game_Switches.rb b/Data/Scripts/004_Game classes/001_Switches and Variables/002_Game_Switches.rb deleted file mode 100644 index 28c87cf4f..000000000 --- a/Data/Scripts/004_Game classes/001_Switches and Variables/002_Game_Switches.rb +++ /dev/null @@ -1,31 +0,0 @@ -#=============================================================================== -# ** Game_Switches -#------------------------------------------------------------------------------- -# This class handles switches. It's a wrapper for the built-in class "Array." -# Refer to "$game_switches" for the instance of this class. -#=============================================================================== -class Game_Switches - #----------------------------------------------------------------------------- - # * Object Initialization - #----------------------------------------------------------------------------- - def initialize - echoln caller - @data = [] - end - #----------------------------------------------------------------------------- - # * Get Switch - # switch_id : switch ID - #----------------------------------------------------------------------------- - def [](switch_id) - return @data[switch_id] if switch_id <= 5000 && @data[switch_id] != nil - return false - end - #----------------------------------------------------------------------------- - # * Set Switch - # switch_id : switch ID - # value : ON (true) / OFF (false) - #----------------------------------------------------------------------------- - def []=(switch_id, value) - @data[switch_id] = value if switch_id <= 5000 - end -end diff --git a/Data/Scripts/004_Game classes/001_Switches and Variables/003_Game_Variables.rb b/Data/Scripts/004_Game classes/001_Switches and Variables/003_Game_Variables.rb deleted file mode 100644 index 70d16f90e..000000000 --- a/Data/Scripts/004_Game classes/001_Switches and Variables/003_Game_Variables.rb +++ /dev/null @@ -1,30 +0,0 @@ -#=============================================================================== -# ** Game_Variables -#------------------------------------------------------------------------------- -# This class handles variables. It's a wrapper for the built-in class "Array." -# Refer to "$game_variables" for the instance of this class. -#=============================================================================== -class Game_Variables - #----------------------------------------------------------------------------- - # * Object Initialization - #----------------------------------------------------------------------------- - def initialize - @data = [] - end - #----------------------------------------------------------------------------- - # * Get Variable - # variable_id : variable ID - #----------------------------------------------------------------------------- - def [](variable_id) - return @data[variable_id] if variable_id <= 5000 && !@data[variable_id].nil? - return 0 - end - #----------------------------------------------------------------------------- - # * Set Variable - # variable_id : variable ID - # value : the variable's value - #----------------------------------------------------------------------------- - def []=(variable_id, value) - @data[variable_id] = value if variable_id <= 5000 - end -end diff --git a/Data/Scripts/004_Game classes/001_Switches and Variables/004_Game_SelfSwitches.rb b/Data/Scripts/004_Game classes/001_Switches and Variables/004_Game_SelfSwitches.rb deleted file mode 100644 index 528e4b1c0..000000000 --- a/Data/Scripts/004_Game classes/001_Switches and Variables/004_Game_SelfSwitches.rb +++ /dev/null @@ -1,29 +0,0 @@ -#=============================================================================== -# ** Game_SelfSwitches -#------------------------------------------------------------------------------- -# This class handles self switches. It's a wrapper for the built-in class -# "Hash." Refer to "$game_self_switches" for the instance of this class. -#=============================================================================== -class Game_SelfSwitches - #----------------------------------------------------------------------------- - # * Object Initialization - #----------------------------------------------------------------------------- - def initialize - @data = {} - end - #----------------------------------------------------------------------------- - # * Get Self Switch - # key : key - #----------------------------------------------------------------------------- - def [](key) - return (@data[key]==true) ? true : false - end - #----------------------------------------------------------------------------- - # * Set Self Switch - # key : key - # value : ON (true) / OFF (false) - #----------------------------------------------------------------------------- - def []=(key, value) - @data[key] = value - end -end diff --git a/Data/Scripts/004_Game classes/002_Game_System.rb b/Data/Scripts/004_Game classes/002_Game_System.rb deleted file mode 100644 index 7db54145f..000000000 --- a/Data/Scripts/004_Game classes/002_Game_System.rb +++ /dev/null @@ -1,286 +0,0 @@ -#============================================================================== -# ** Game_System -#------------------------------------------------------------------------------ -# This class handles data surrounding the system. Backround music, etc. -# is managed here as well. Refer to "$game_system" for the instance of -# this class. -#============================================================================== -class Game_System - attr_reader :map_interpreter # map event interpreter - attr_reader :battle_interpreter # battle event interpreter - attr_accessor :timer # timer - attr_accessor :timer_working # timer working flag - attr_accessor :save_disabled # save forbidden - attr_accessor :menu_disabled # menu forbidden - attr_accessor :encounter_disabled # encounter forbidden - attr_accessor :message_position # text option: positioning - attr_accessor :message_frame # text option: window frame - attr_accessor :save_count # save count - attr_accessor :magic_number # magic number - attr_accessor :autoscroll_x_speed - attr_accessor :autoscroll_y_speed - attr_accessor :bgm_position - - def initialize - @map_interpreter = Interpreter.new(0, true) - @battle_interpreter = Interpreter.new(0, false) - @timer = 0 - @timer_working = false - @save_disabled = false - @menu_disabled = false - @encounter_disabled = false - @message_position = 2 - @message_frame = 0 - @save_count = 0 - @magic_number = 0 - @autoscroll_x_speed = 0 - @autoscroll_y_speed = 0 - @bgm_position = 0 - @bgs_position = 0 - end - -################################################################################ - - def bgm_play(bgm) - old_pos = @bgm_position - @bgm_position = 0 - bgm_play_internal(bgm,0) - @bgm_position = old_pos - end - - def bgm_play_internal2(name,volume,pitch,position) # :nodoc: - vol = volume - vol *= $PokemonSystem.bgmvolume/100.0 - vol = vol.to_i - begin - Audio.bgm_play(name,vol,pitch,position) - rescue ArgumentError - Audio.bgm_play(name,vol,pitch) - end - end - - def bgm_play_internal(bgm,position) # :nodoc: - @bgm_position = position if !@bgm_paused - @playing_bgm = (bgm==nil) ? nil : bgm.clone - if bgm!=nil && bgm.name!="" - if FileTest.audio_exist?("Audio/BGM/"+bgm.name) - bgm_play_internal2("Audio/BGM/"+bgm.name, - bgm.volume,bgm.pitch,@bgm_position) if !@defaultBGM - end - else - @bgm_position = position if !@bgm_paused - @playing_bgm = nil - Audio.bgm_stop if !@defaultBGM - end - if @defaultBGM - bgm_play_internal2("Audio/BGM/"+@defaultBGM.name, - @defaultBGM.volume,@defaultBGM.pitch,@bgm_position) - end - Graphics.frame_reset - end - - def bgm_pause(fadetime=0.0) # :nodoc: - pos = Audio.bgm_pos rescue 0 - self.bgm_fade(fadetime) if fadetime>0.0 - @bgm_position = pos - @bgm_paused = true - end - - def bgm_unpause # :nodoc: - @bgm_position = 0 - @bgm_paused = false - end - - def bgm_resume(bgm) # :nodoc: - if @bgm_paused - self.bgm_play_internal(bgm,@bgm_position) - @bgm_position = 0 - @bgm_paused = false - end - end - - def bgm_stop # :nodoc: - @bgm_position = 0 if !@bgm_paused - @playing_bgm = nil - Audio.bgm_stop if !@defaultBGM - end - - def bgm_fade(time) # :nodoc: - @bgm_position = 0 if !@bgm_paused - @playing_bgm = nil - Audio.bgm_fade((time*1000).floor) if !@defaultBGM - end - - def playing_bgm - return @playing_bgm - end - - # Saves the currently playing background music for later playback. - def bgm_memorize - @memorized_bgm = @playing_bgm - end - - # Plays the currently memorized background music - def bgm_restore - bgm_play(@memorized_bgm) - end - - # Returns an RPG::AudioFile object for the currently playing background music - def getPlayingBGM - return (@playing_bgm) ? @playing_bgm.clone : nil - end - - def setDefaultBGM(bgm,volume=80,pitch=100) - bgm = RPG::AudioFile.new(bgm,volume,pitch) if bgm.is_a?(String) - if bgm!=nil && bgm.name!="" - @defaultBGM = nil - self.bgm_play(bgm) - @defaultBGM = bgm.clone - else - @defaultBGM = nil - self.bgm_play(@playing_bgm) - end - end - -################################################################################ - - def me_play(me) - me = RPG::AudioFile.new(me) if me.is_a?(String) - if me!=nil && me.name!="" - if FileTest.audio_exist?("Audio/ME/"+me.name) - vol = me.volume - vol *= $PokemonSystem.bgmvolume/100.0 - vol = vol.to_i - Audio.me_play("Audio/ME/"+me.name,vol,me.pitch) - end - else - Audio.me_stop - end - Graphics.frame_reset - end - -################################################################################ - - def bgs_play(bgs) - @playing_bgs = (bgs==nil) ? nil : bgs.clone - if bgs!=nil && bgs.name!="" - if FileTest.audio_exist?("Audio/BGS/"+bgs.name) - vol = bgs.volume - vol *= $PokemonSystem.sevolume/100.0 - vol = vol.to_i - Audio.bgs_play("Audio/BGS/"+bgs.name,vol,bgs.pitch) - end - else - @bgs_position = 0 - @playing_bgs = nil - Audio.bgs_stop - end - Graphics.frame_reset - end - - def bgs_pause(fadetime=0.0) # :nodoc: - if fadetime>0.0 - self.bgs_fade(fadetime) - else - self.bgs_stop - end - @bgs_paused = true - end - - def bgs_unpause # :nodoc: - @bgs_paused = false - end - - def bgs_resume(bgs) # :nodoc: - if @bgs_paused - self.bgs_play(bgs) - @bgs_paused = false - end - end - - def bgs_stop - @bgs_position = 0 - @playing_bgs = nil - Audio.bgs_stop - end - - def bgs_fade(time) - @bgs_position = 0 - @playing_bgs = nil - Audio.bgs_fade((time*1000).floor) - end - - def playing_bgs - return @playing_bgs - end - - def bgs_memorize - @memorized_bgs = @playing_bgs - end - - def bgs_restore - bgs_play(@memorized_bgs) - end - - def getPlayingBGS - return (@playing_bgs) ? @playing_bgs.clone : nil - end - -################################################################################ - - def se_play(se) - se = RPG::AudioFile.new(se) if se.is_a?(String) - if se!=nil && se.name!="" && FileTest.audio_exist?("Audio/SE/"+se.name) - vol = se.volume - vol *= $PokemonSystem.sevolume/100.0 - vol = vol.to_i - Audio.se_play("Audio/SE/"+se.name,vol,se.pitch) - end - end - - def se_stop - Audio.se_stop - end - -################################################################################ - - def battle_bgm - return (@battle_bgm) ? @battle_bgm : $data_system.battle_bgm - end - - def battle_bgm=(battle_bgm) - @battle_bgm = battle_bgm - end - - def battle_end_me - return (@battle_end_me) ? @battle_end_me : $data_system.battle_end_me - end - - def battle_end_me=(battle_end_me) - @battle_end_me = battle_end_me - end - -################################################################################ - - def windowskin_name - if @windowskin_name==nil - return $data_system.windowskin_name - else - return @windowskin_name - end - end - - def windowskin_name=(windowskin_name) - @windowskin_name = windowskin_name - end - - def update - @timer -= 1 if @timer_working && @timer>0 - if Input.trigger?(Input::SPECIAL) && pbCurrentEventCommentInput(1,"Cut Scene") - event = @map_interpreter.get_character(0) - @map_interpreter.pbSetSelfSwitch(event.id,"A",true) - @map_interpreter.command_end - event.start - end - end -end diff --git a/Data/Scripts/004_Game classes/003_Game_Picture.rb b/Data/Scripts/004_Game classes/003_Game_Picture.rb deleted file mode 100644 index 5d5be5b44..000000000 --- a/Data/Scripts/004_Game classes/003_Game_Picture.rb +++ /dev/null @@ -1,156 +0,0 @@ -#=============================================================================== -# ** Game_Picture -#------------------------------------------------------------------------------- -# This class handles the picture. It's used within the Game_Screen class -# ($game_screen). -#=============================================================================== - -class Game_Picture - #----------------------------------------------------------------------------- - # * Public Instance Variables - #----------------------------------------------------------------------------- - attr_reader :number # picture number - attr_accessor :name # file name - attr_reader :origin # starting point - attr_reader :x # x-coordinate - attr_reader :y # y-coordinate - attr_accessor :zoom_x # x directional zoom rate - attr_accessor :zoom_y # y directional zoom rate - attr_accessor :opacity # opacity level - attr_reader :blend_type # blend method - attr_reader :tone # color tone - attr_reader :angle # rotation angle - #----------------------------------------------------------------------------- - # * Object Initialization - # number : picture number - #----------------------------------------------------------------------------- - def initialize(number) - @number = number - @name = "" - @origin = 0 - @x = 0.0 - @y = 0.0 - @zoom_x = 100.0 - @zoom_y = 100.0 - @opacity = 255.0 - @blend_type = 1 - @duration = 0 - @target_x = @x - @target_y = @y - @target_zoom_x = @zoom_x - @target_zoom_y = @zoom_y - @target_opacity = @opacity - @tone = Tone.new(0, 0, 0, 0) - @tone_target = Tone.new(0, 0, 0, 0) - @tone_duration = 0 - @angle = 0 - @rotate_speed = 0 - end - #----------------------------------------------------------------------------- - # * Show Picture - # name : file name - # origin : starting point - # x : x-coordinate - # y : y-coordinate - # zoom_x : x directional zoom rate - # zoom_y : y directional zoom rate - # opacity : opacity level - # blend_type : blend method - #----------------------------------------------------------------------------- - def show(name, origin, x, y, zoom_x=100, zoom_y=100, opacity=255, blend_type=0) - @name = name - @origin = origin - @x = x.to_f - @y = y.to_f - @zoom_x = zoom_x.to_f - @zoom_y = zoom_y.to_f - @opacity = opacity.to_f - @blend_type = blend_type ? blend_type : 0 - @duration = 0 - @target_x = @x - @target_y = @y - @target_zoom_x = @zoom_x - @target_zoom_y = @zoom_y - @target_opacity = @opacity - @tone = Tone.new(0, 0, 0, 0) - @tone_target = Tone.new(0, 0, 0, 0) - @tone_duration = 0 - @angle = 0 - @rotate_speed = 0 - end - #----------------------------------------------------------------------------- - # * Move Picture - # duration : time - # origin : starting point - # x : x-coordinate - # y : y-coordinate - # zoom_x : x directional zoom rate - # zoom_y : y directional zoom rate - # opacity : opacity level - # blend_type : blend method - #----------------------------------------------------------------------------- - def move(duration, origin, x, y, zoom_x, zoom_y, opacity, blend_type) - @duration = duration - @origin = origin - @target_x = x.to_f - @target_y = y.to_f - @target_zoom_x = zoom_x.to_f - @target_zoom_y = zoom_y.to_f - @target_opacity = opacity.to_f - @blend_type = blend_type ? blend_type : 0 - end - #----------------------------------------------------------------------------- - # * Change Rotation Speed - # speed : rotation speed - #----------------------------------------------------------------------------- - def rotate(speed) - @rotate_speed = speed - end - #----------------------------------------------------------------------------- - # * Start Change of Color Tone - # tone : color tone - # duration : time - #----------------------------------------------------------------------------- - def start_tone_change(tone, duration) - @tone_target = tone.clone - @tone_duration = duration - if @tone_duration == 0 - @tone = @tone_target.clone - end - end - #----------------------------------------------------------------------------- - # * Erase Picture - #----------------------------------------------------------------------------- - def erase - @name = "" - end - #----------------------------------------------------------------------------- - # * Frame Update - #----------------------------------------------------------------------------- - def update - if @duration >= 1 - d = @duration - @x = (@x * (d - 1) + @target_x) / d - @y = (@y * (d - 1) + @target_y) / d - @zoom_x = (@zoom_x * (d - 1) + @target_zoom_x) / d - @zoom_y = (@zoom_y * (d - 1) + @target_zoom_y) / d - @opacity = (@opacity * (d - 1) + @target_opacity) / d - @duration -= 1 - end - if @tone_duration >= 1 - d = @tone_duration - @tone.red = (@tone.red * (d - 1) + @tone_target.red) / d - @tone.green = (@tone.green * (d - 1) + @tone_target.green) / d - @tone.blue = (@tone.blue * (d - 1) + @tone_target.blue) / d - @tone.gray = (@tone.gray * (d - 1) + @tone_target.gray) / d - @tone_duration -= 1 - end - if @rotate_speed != 0 - @angle += @rotate_speed / 2.0 - while @angle < 0 - @angle += 360 - end - @angle %= 360 - end - end -end diff --git a/Data/Scripts/004_Game classes/004_Game_Map.rb b/Data/Scripts/004_Game classes/004_Game_Map.rb deleted file mode 100644 index cdcbb68a4..000000000 --- a/Data/Scripts/004_Game classes/004_Game_Map.rb +++ /dev/null @@ -1,547 +0,0 @@ -#============================================================================== -# ** Game_Map -#------------------------------------------------------------------------------ -# This class handles the map. It includes scrolling and passable determining -# functions. Refer to "$game_map" for the instance of this class. -#============================================================================== -class Game_Map - attr_accessor :map_id - attr_accessor :tileset_name # tileset file name - attr_accessor :autotile_names # autotile file name - attr_reader :passages # passage table - attr_reader :priorities # priority table - attr_reader :terrain_tags # terrain tag table - attr_reader :events # events - attr_accessor :panorama_name # panorama file name - attr_accessor :panorama_hue # panorama hue - attr_accessor :fog_name # fog file name - attr_accessor :fog_hue # fog hue - attr_accessor :fog_opacity # fog opacity level - attr_accessor :fog_blend_type # fog blending method - attr_accessor :fog_zoom # fog zoom rate - - attr_accessor :fog_sx # fog sx - attr_accessor :fog_sy # fog sy - attr_accessor :fog_ox # fog x-coordinate starting point - attr_accessor :fog_oy # fog y-coordinate starting point - - attr_accessor :fog2_ox # fog x-coordinate starting point - attr_accessor :fog2_oy # fog y-coordinate starting point - attr_accessor :fog2_sx # fog sx - attr_accessor :fog2_sy # fog sy - attr_accessor :fog2_opacity # fog sy - - attr_reader :fog_tone # fog color tone - attr_accessor :battleback_name # battleback file name - attr_reader :display_x # display x-coordinate * 128 - attr_reader :display_y # display y-coordinate * 128 - attr_accessor :need_refresh # refresh request flag - attr_accessor :scroll_direction - - TILE_WIDTH = 32 - TILE_HEIGHT = 32 - X_SUBPIXELS = 4 - Y_SUBPIXELS = 4 - REAL_RES_X = TILE_WIDTH * X_SUBPIXELS - REAL_RES_Y = TILE_HEIGHT * Y_SUBPIXELS - - def initialize - @map_id = 0 - @display_x = 0 - @display_y = 0 - end - - def setup(map_id) - @map_id = map_id - @map = load_data(sprintf("Data/Map%03d.rxdata", map_id)) - tileset = $data_tilesets[@map.tileset_id] - updateTileset - @fog_ox = 0 - @fog_oy = 0 - - @fog2_ox = 0 - @fog2_oy = 0 - @fog2_sx = 0 - @fog2_sy = 0 - @fog2_opacity = 0 - - @fog_tone = Tone.new(0, 0, 0, 0) - @fog_tone_target = Tone.new(0, 0, 0, 0) - @fog_tone_duration = 0 - @fog_opacity_duration = 0 - @fog_opacity_target = 0 - self.display_x = 0 - self.display_y = 0 - @need_refresh = false - Events.onMapCreate.trigger(self, map_id, @map, tileset) - @events = {} - for i in @map.events.keys - @events[i] = Game_Event.new(@map_id, @map.events[i], self) - end - @common_events = {} - for i in 1...$data_common_events.size - @common_events[i] = Game_CommonEvent.new(i) - end - @scroll_direction = 2 - @scroll_rest = 0 - @scroll_speed = 4 - end - - def updateTileset - tileset = $data_tilesets[@map.tileset_id] - @tileset_name = tileset.tileset_name - @autotile_names = tileset.autotile_names - @panorama_name = tileset.panorama_name - @panorama_hue = tileset.panorama_hue - @fog_name = tileset.fog_name - @fog_hue = tileset.fog_hue - @fog_opacity = tileset.fog_opacity - @fog_blend_type = tileset.fog_blend_type - @fog_zoom = tileset.fog_zoom - @fog_sx = tileset.fog_sx - @fog_sy = tileset.fog_sy - @battleback_name = tileset.battleback_name - @passages = tileset.passages - @priorities = tileset.priorities - @terrain_tags = tileset.terrain_tags - end - - def width - return @map.width; - end - - def height - return @map.height; - end - - def encounter_list - return @map.encounter_list; - end - - def encounter_step - return @map.encounter_step; - end - - def data - return @map.data; - end - - def tileset_id; - return @map.tileset_id; - end - - def name - ret = pbGetMessage(MessageTypes::MapNames, @map_id) - ret.gsub!(/\\PN/, $Trainer.name) if $Trainer - return ret - end - - #----------------------------------------------------------------------------- - # * Autoplays background music - # Plays music called "[normal BGM]_n" if it's night time and it exists - #----------------------------------------------------------------------------- - def autoplayAsCue - if @map.autoplay_bgm - if PBDayNight.isNight? && FileTest.audio_exist?("Audio/BGM/" + @map.bgm.name + "_n") - pbCueBGM(@map.bgm.name + "_n", 1.0, @map.bgm.volume, @map.bgm.pitch) - else - pbCueBGM(@map.bgm, 1.0) - end - end - if @map.autoplay_bgs - pbBGSPlay(@map.bgs) - end - end - - def setFog2(filename,sx=0,sy=0,opacity=32) - @fog2_sx=sx - @fog2_sy=-sy - @fog2_opacity = opacity - $scene.spriteset.setFog2(filename) - end - - def eraseFog2() - @fog2_sx=0 - @fog2_sy=-0 - @fog2_opacity = 0 - $scene.spriteset.disposeFog2() - end - - - #----------------------------------------------------------------------------- - # * Plays background music - # Plays music called "[normal BGM]_n" if it's night time and it exists - #----------------------------------------------------------------------------- - def autoplay - if @map.autoplay_bgm - if PBDayNight.isNight? && FileTest.audio_exist?("Audio/BGM/" + @map.bgm.name + "_n") - pbBGMPlay(@map.bgm.name + "_n", @map.bgm.volume, @map.bgm.pitch) - else - pbBGMPlay(@map.bgm) - end - end - if @map.autoplay_bgs - pbBGSPlay(@map.bgs) - end - end - - def valid?(x, y) - return x >= 0 && x < width && y >= 0 && y < height - end - - def validLax?(x, y) - return x >= -10 && x <= width + 10 && y >= -10 && y <= height + 10 - end - - def passable?(x, y, d, self_event = nil) - return false if !valid?(x, y) - bit = (1 << (d / 2 - 1)) & 0x0f - for event in events.values - next if event.tile_id <= 0 - next if event == self_event - next if !event.at_coordinate?(x, y) - next if event.through - next if GameData::TerrainTag.try_get(@terrain_tags[event.tile_id]).ignore_passability - passage = @passages[event.tile_id] - return false if passage & bit != 0 - return false if passage & 0x0f == 0x0f - return true if @priorities[event.tile_id] == 0 - end - return playerPassable?(x, y, d, self_event) if self_event == $game_player - # All other events - newx = x - newy = y - case d - when 1 - newx -= 1 - newy += 1 - when 2 - newy += 1 - when 3 - newx += 1 - newy += 1 - when 4 - newx -= 1 - when 6 - newx += 1 - when 7 - newx -= 1 - newy -= 1 - when 8 - newy -= 1 - when 9 - newx += 1 - newy -= 1 - end - return false if !valid?(newx, newy) - for i in [2, 1, 0] - tile_id = data[x, y, i] - terrain = GameData::TerrainTag.try_get(@terrain_tags[tile_id]) - # If already on water, only allow movement to another water tile - if self_event != nil && terrain.can_surf_freely - for j in [2, 1, 0] - facing_tile_id = data[newx, newy, j] - return false if facing_tile_id == nil - facing_terrain = GameData::TerrainTag.try_get(@terrain_tags[facing_tile_id]) - if facing_terrain.id != :None && !facing_terrain.ignore_passability - return facing_terrain.can_surf_freely - end - end - return false - # Can't walk onto ice - # removed for mahogany gym. idk if this will cause problems, hopefully not - # elsif terrain.ice - # return false - elsif self_event != nil && self_event.x == x && self_event.y == y - # Can't walk onto ledges - for j in [2, 1, 0] - facing_tile_id = data[newx, newy, j] - return false if facing_tile_id == nil - facing_terrain = GameData::TerrainTag.try_get(@terrain_tags[facing_tile_id]) - return false if facing_terrain.ledge - break if facing_terrain.id != :None && !facing_terrain.ignore_passability - end - end - # Regular passability checks - if !terrain || !terrain.ignore_passability - passage = @passages[tile_id] - return false if passage & bit != 0 || passage & 0x0f == 0x0f - return true if @priorities[tile_id] == 0 - end - end - return true - end - - def playerPassable?(x, y, d, self_event = nil) - bit = (1 << (d / 2 - 1)) & 0x0f - for i in [2, 1, 0] - tile_id = data[x, y, i] - terrain = GameData::TerrainTag.try_get(@terrain_tags[tile_id]) - passage = @passages[tile_id] - if terrain - # Ignore bridge tiles if not on a bridge - next if terrain.bridge && $PokemonGlobal.bridge == 0 - # Make water tiles passable if player is surfing - return true if $PokemonGlobal.surfing && terrain.can_surf && !terrain.waterfall - # Prevent cycling in really tall grass/on ice - return false if $PokemonGlobal.bicycle && terrain.must_walk - # Depend on passability of bridge tile if on bridge - if terrain.bridge && $PokemonGlobal.bridge > 0 - return (passage & bit == 0 && passage & 0x0f != 0x0f) - end - end - # Regular passability checks - if !terrain || !terrain.ignore_passability - return false if passage & bit != 0 || passage & 0x0f == 0x0f - return true if @priorities[tile_id] == 0 - end - end - return true - end - - # Returns whether the position x,y is fully passable (there is no blocking - # event there, and the tile is fully passable in all directions) - def passableStrict?(x, y, d, self_event = nil) - return false if !valid?(x, y) - for event in events.values - next if event == self_event || event.tile_id < 0 || event.through - next if !event.at_coordinate?(x, y) - next if GameData::TerrainTag.try_get(@terrain_tags[event.tile_id]).ignore_passability - return false if @passages[event.tile_id] & 0x0f != 0 - return true if @priorities[event.tile_id] == 0 - end - for i in [2, 1, 0] - tile_id = data[x, y, i] - next if GameData::TerrainTag.try_get(@terrain_tags[tile_id]).ignore_passability - return false if @passages[tile_id] & 0x0f != 0 - return true if @priorities[tile_id] == 0 - end - return true - end - - def bush?(x, y) - for i in [2, 1, 0] - tile_id = data[x, y, i] - return false if GameData::TerrainTag.try_get(@terrain_tags[tile_id]).bridge && - $PokemonGlobal.bridge > 0 - return true if @passages[tile_id] & 0x40 == 0x40 - end - return false - end - - def deepBush?(x, y) - for i in [2, 1, 0] - tile_id = data[x, y, i] - terrain = GameData::TerrainTag.try_get(@terrain_tags[tile_id]) - return false if terrain.bridge && $PokemonGlobal.bridge > 0 - return true if terrain.deep_bush && @passages[tile_id] & 0x40 == 0x40 - end - return false - end - - def counter?(x, y) - for i in [2, 1, 0] - tile_id = data[x, y, i] - passage = @passages[tile_id] - return true if passage & 0x80 == 0x80 - end - return false - end - - def terrain_tag(x, y, countBridge = false) - if valid?(x, y) - for i in [2, 1, 0] - tile_id = data[x, y, i] - terrain = GameData::TerrainTag.try_get(@terrain_tags[tile_id]) - next if terrain.id == :None || terrain.ignore_passability - next if !countBridge && terrain.bridge && $PokemonGlobal.bridge == 0 - return terrain - end - end - return GameData::TerrainTag.get(:None) - end - - # Unused. - def check_event(x, y) - for event in self.events.values - return event.id if event.at_coordinate?(x, y) - end - end - - def event_at_position(x, y) - for event in self.events.values - return true if event.at_coordinate?(x, y) - end - return false - end - - def get_event_at_position(x, y, excluding_IDs = []) - for event in self.events.values - next if excluding_IDs.include?(event.id) - return event if event.at_coordinate?(x, y) - end - return nil - end - - def display_x=(value) - return if @display_x == value - @display_x = value - if GameData::MapMetadata.exists?(self.map_id) && GameData::MapMetadata.get(self.map_id).snap_edges - max_x = (self.width - Graphics.width * 1.0 / TILE_WIDTH) * REAL_RES_X - @display_x = [0, [@display_x, max_x].min].max - end - $MapFactory.setMapsInRange if $MapFactory - end - - def display_y=(value) - return if @display_y == value - @display_y = value - if GameData::MapMetadata.exists?(self.map_id) && GameData::MapMetadata.get(self.map_id).snap_edges - max_y = (self.height - Graphics.height * 1.0 / TILE_HEIGHT) * REAL_RES_Y - @display_y = [0, [@display_y, max_y].min].max - end - $MapFactory.setMapsInRange if $MapFactory - end - - def scroll_up(distance) - self.display_y -= distance - end - - def scroll_down(distance) - self.display_y += distance - end - - def scroll_left(distance) - self.display_x -= distance - end - - def scroll_right(distance) - self.display_x += distance - end - - def start_scroll(direction, distance, speed) - @scroll_direction = direction - if direction == 2 || direction == 8 # down or up - @scroll_rest = distance * REAL_RES_Y - else - @scroll_rest = distance * REAL_RES_X - end - @scroll_speed = speed - end - - def scrolling? - return @scroll_rest > 0 - end - - def start_fog_tone_change(tone, duration) - @fog_tone_target = tone.clone - @fog_tone_duration = duration - if @fog_tone_duration == 0 - @fog_tone = @fog_tone_target.clone - end - end - - def start_fog_opacity_change(opacity, duration) - @fog_opacity_target = opacity * 1.0 - @fog_opacity_duration = duration - if @fog_opacity_duration == 0 - @fog_opacity = @fog_opacity_target - end - end - - def refresh - for event in @events.values - event.refresh - end - for common_event in @common_events.values - common_event.refresh - end - @need_refresh = false - end - - def update - # refresh maps if necessary - if $MapFactory - for i in $MapFactory.maps - i.refresh if i.need_refresh - end - $MapFactory.setCurrentMap - end - # If scrolling - if @scroll_rest > 0 - distance = (1 << @scroll_speed) * 40.0 / Graphics.frame_rate - distance = @scroll_rest if distance > @scroll_rest - case @scroll_direction - when 2 then - scroll_down(distance) - when 4 then - scroll_left(distance) - when 6 then - scroll_right(distance) - when 8 then - scroll_up(distance) - end - @scroll_rest -= distance - end - # Only update events that are on-screen - for event in @events.values - event.update - end - # Update common events - for common_event in @common_events.values - common_event.update - end - # Update fog - @fog_ox -= @fog_sx / 8.0 - @fog_oy -= @fog_sy / 8.0 - - @fog2_ox -= @fog2_sx / 8.0 if @fog2_ox - @fog2_oy -= @fog2_sy / 8.0 if @fog2_oy - - if @fog_tone_duration >= 1 - d = @fog_tone_duration - target = @fog_tone_target - @fog_tone.red = (@fog_tone.red * (d - 1) + target.red) / d - @fog_tone.green = (@fog_tone.green * (d - 1) + target.green) / d - @fog_tone.blue = (@fog_tone.blue * (d - 1) + target.blue) / d - @fog_tone.gray = (@fog_tone.gray * (d - 1) + target.gray) / d - @fog_tone_duration -= 1 - end - if @fog_opacity_duration >= 1 - d = @fog_opacity_duration - @fog_opacity = (@fog_opacity * (d - 1) + @fog_opacity_target) / d - @fog_opacity_duration -= 1 - end - end -end - -#=============================================================================== -# -#=============================================================================== -def pbScrollMap(direction, distance, speed) - if speed == 0 - case direction - when 2 then - $game_map.scroll_down(distance * Game_Map::REAL_RES_Y) - when 4 then - $game_map.scroll_left(distance * Game_Map::REAL_RES_X) - when 6 then - $game_map.scroll_right(distance * Game_Map::REAL_RES_X) - when 8 then - $game_map.scroll_up(distance * Game_Map::REAL_RES_Y) - end - else - $game_map.start_scroll(direction, distance, speed) - oldx = $game_map.display_x - oldy = $game_map.display_y - loop do - Graphics.update - Input.update - break if !$game_map.scrolling? - pbUpdateSceneMap - break if $game_map.display_x == oldx && $game_map.display_y == oldy - oldx = $game_map.display_x - oldy = $game_map.display_y - end - end -end diff --git a/Data/Scripts/004_Game classes/005_Game_Map_Autoscroll.rb b/Data/Scripts/004_Game classes/005_Game_Map_Autoscroll.rb deleted file mode 100644 index 3af3ea189..000000000 --- a/Data/Scripts/004_Game classes/005_Game_Map_Autoscroll.rb +++ /dev/null @@ -1,194 +0,0 @@ -#=============================================================================== -# ** Map Autoscroll -#------------------------------------------------------------------------------- -# Wachunga -# Version 1.02 -# 2005-12-18 -#=============================================================================== -=begin - - This script supplements the built-in "Scroll Map" event command with the - aim of simplifying cutscenes (and map scrolling in general). Whereas the - normal event command requires a direction and number of tiles to scroll, - Map Autoscroll scrolls the map to center on the tile whose x and y - coordinates are given. - - FEATURES - - automatic map scrolling to given x,y coordinate (or player) - - destination is fixed, so it's possible to scroll to same place even if - origin is variable (e.g. moving NPC) - - variable speed (just like "Scroll Map" event command) - - diagonal scrolling supported - - SETUP - Instead of a "Scroll Map" event command, use the "Call Script" command - and enter on the following on the first line: - - autoscroll(x,y) - - (replacing "x" and "y" with the x and y coordinates of the tile to scroll to) - - To specify a scroll speed other than the default (4), use: - - autoscroll(x,y,speed) - - (now also replacing "speed" with the scroll speed from 1-6) - - Diagonal scrolling happens automatically when the destination is diagonal - relative to the starting point (i.e., not directly up, down, left or right). - - To scroll to the player, instead use the following: - - autoscroll_player(speed) - - Note: because of how the interpreter and the "Call Script" event command - are setup, the call to autoscroll(...) can only be on the first line of - the "Call Script" event command (and not flowing down to subsequent lines). - - For example, the following call may not work as expected: - - autoscroll($game_variables[1], - $game_variables[2]) - - (since the long argument names require dropping down to a second line) - A work-around is to setup new variables with shorter names in a preceding - (separate) "Call Script" event command: - - @x = $game_variables[1] - @y = $game_variables[2] - - and then use those as arguments: - - autoscroll(@x,@y) - - The renaming must be in a separate "Call Script" because otherwise - the call to autoscroll(...) isn't on the first line. - - Originally requested by militantmilo80: - http://www.rmxp.net/forums/index.php?showtopic=29519 - -=end - -class Interpreter - SCROLL_SPEED_DEFAULT = 4 - #----------------------------------------------------------------------------- - # * Map Autoscroll to Coordinates - # x : x coordinate to scroll to and center on - # y : y coordinate to scroll to and center on - # speed : (optional) scroll speed (from 1-6, default being 4) - #----------------------------------------------------------------------------- - def autoscroll(x,y,speed=SCROLL_SPEED_DEFAULT) - if $game_map.scrolling? - return false - elsif !$game_map.valid?(x,y) - print 'Map Autoscroll: given x,y is invalid' - return command_skip - elsif !(1..6).include?(speed) - print 'Map Autoscroll: invalid speed (1-6 only)' - return command_skip - end - center_x = (Graphics.width/2 - Game_Map::TILE_WIDTH/2) * 4 # X coordinate in the center of the screen - center_y = (Graphics.height/2 - Game_Map::TILE_HEIGHT/2) * 4 # Y coordinate in the center of the screen - max_x = ($game_map.width - Graphics.width*1.0/Game_Map::TILE_WIDTH) * 4 * Game_Map::TILE_WIDTH - max_y = ($game_map.height - Graphics.height*1.0/Game_Map::TILE_HEIGHT) * 4 * Game_Map::TILE_HEIGHT - count_x = ($game_map.display_x - [0,[x*Game_Map::REAL_RES_X-center_x,max_x].min].max)/Game_Map::REAL_RES_X - count_y = ($game_map.display_y - [0,[y*Game_Map::REAL_RES_Y-center_y,max_y].min].max)/Game_Map::REAL_RES_Y - if !@diag - @diag = true - dir = nil - if count_x > 0 - if count_y > 0 - dir = 7 - elsif count_y < 0 - dir = 1 - end - elsif count_x < 0 - if count_y > 0 - dir = 9 - elsif count_y < 0 - dir = 3 - end - end - count = [count_x.abs,count_y.abs].min - else - @diag = false - dir = nil - if count_x != 0 && count_y != 0 - return false - elsif count_x > 0 - dir = 4 - elsif count_x < 0 - dir = 6 - elsif count_y > 0 - dir = 8 - elsif count_y < 0 - dir = 2 - end - count = count_x != 0 ? count_x.abs : count_y.abs - end - $game_map.start_scroll(dir, count, speed) if dir != nil - if @diag - return false - else - return true - end - end - - #----------------------------------------------------------------------------- - # * Map Autoscroll (to Player) - # speed : (optional) scroll speed (from 1-6, default being 4) - #----------------------------------------------------------------------------- - def autoscroll_player(speed=SCROLL_SPEED_DEFAULT) - autoscroll($game_player.x,$game_player.y,speed) - end -end - - - -class Game_Map - def scroll_downright(distance) - @display_x = [@display_x + distance, - (self.width - Graphics.width*1.0/TILE_WIDTH) * REAL_RES_X].min - @display_y = [@display_y + distance, - (self.height - Graphics.height*1.0/TILE_HEIGHT) * REAL_RES_Y].min - end - - def scroll_downleft(distance) - @display_x = [@display_x - distance, 0].max - @display_y = [@display_y + distance, - (self.height - Graphics.height*1.0/TILE_HEIGHT) * REAL_RES_Y].min - end - - def scroll_upright(distance) - @display_x = [@display_x + distance, - (self.width - Graphics.width*1.0/TILE_WIDTH) * REAL_RES_X].min - @display_y = [@display_y - distance, 0].max - end - - def scroll_upleft(distance) - @display_x = [@display_x - distance, 0].max - @display_y = [@display_y - distance, 0].max - end - - def update_scrolling - # If scrolling - if @scroll_rest > 0 - # Change from scroll speed to distance in map coordinates - distance = (1<<@scroll_speed)*40/Graphics.frame_rate - distance = @scroll_rest if distance>@scroll_rest - # Execute scrolling - case @scroll_direction - when 1 then scroll_downleft(distance) - when 2 then scroll_down(distance) - when 3 then scroll_downright(distance) - when 4 then scroll_left(distance) - when 6 then scroll_right(distance) - when 7 then scroll_upleft(distance) - when 8 then scroll_up(distance) - when 9 then scroll_upright(distance) - end - # Subtract distance scrolled - @scroll_rest -= distance - end - end -end diff --git a/Data/Scripts/004_Game classes/006_Game_MapFactory.rb b/Data/Scripts/004_Game classes/006_Game_MapFactory.rb deleted file mode 100644 index b0ba2b677..000000000 --- a/Data/Scripts/004_Game classes/006_Game_MapFactory.rb +++ /dev/null @@ -1,526 +0,0 @@ -#=============================================================================== -# Map Factory (allows multiple maps to be loaded at once and connected) -#=============================================================================== -class PokemonMapFactory - attr_reader :maps - - def initialize(id) - @maps = [] - @fixup = false - @mapChanged = false # transient instance variable - setup(id) - end - - # Clears all maps and sets up the current map with id. This function also sets - # the positions of neighboring maps and notifies the game system of a map - # change. - def setup(id) - @maps.clear - @maps[0] = Game_Map.new - @mapIndex = 0 - oldID = ($game_map) ? $game_map.map_id : 0 - setMapChanging(id,@maps[0]) if oldID!=0 && oldID!=@maps[0].map_id - $game_map = @maps[0] - @maps[0].setup(id) - setMapsInRange - setMapChanged(oldID) - end - - def map - @mapIndex = 0 if !@mapIndex || @mapIndex<0 - return @maps[@mapIndex] if @maps[@mapIndex] - raise "No maps in save file... (mapIndex=#{@mapIndex})" if @maps.length==0 - if @maps[0] - echoln("Using next map, may be incorrect (mapIndex=#{@mapIndex}, length=#{@maps.length})") - return @maps[0] - end - raise "No maps in save file... (all maps empty; mapIndex=#{@mapIndex})" - end - - def hasMap?(id) - for map in @maps - return true if map.map_id==id - end - return false - end - - def getMapIndex(id) - for i in 0...@maps.length - return i if @maps[i].map_id==id - end - return -1 - end - - def getMap(id,add=true) - for map in @maps - return map if map.map_id==id - end - map = Game_Map.new - map.setup(id) - @maps.push(map) if add - return map - end - - def getMapNoAdd(id) - return getMap(id,false) - end - - def getNewMap(playerX,playerY) - id = $game_map.map_id - conns = MapFactoryHelper.getMapConnections - if conns[id] - for conn in conns[id] - mapidB = nil - newx = 0 - newy = 0 - if conn[0] == id - mapidB = conn[3] - mapB = MapFactoryHelper.getMapDims(conn[3]) - newx = conn[4] - conn[1] + playerX - newy = conn[5] - conn[2] + playerY - else - mapidB = conn[0] - mapB = MapFactoryHelper.getMapDims(conn[0]) - newx = conn[1] - conn[4] + playerX - newy = conn[2] - conn[5] + playerY - end - if newx >= 0 && newx < mapB[0] && newy >= 0 && newy < mapB[1] - return [getMap(mapidB), newx, newy] - end - end - end - return nil - end - - # Detects whether the player has moved onto a connected map, and if so, causes - # their transfer to that map. - def setCurrentMap - return if $game_player.moving? - return if $game_map.valid?($game_player.x,$game_player.y) - newmap = getNewMap($game_player.x,$game_player.y) - return if !newmap - oldmap=$game_map.map_id - if oldmap!=0 && oldmap!=newmap[0].map_id - setMapChanging(newmap[0].map_id,newmap[0]) - end - $game_map = newmap[0] - @mapIndex = getMapIndex($game_map.map_id) - $game_player.moveto(newmap[1],newmap[2]) - $game_map.update - pbAutoplayOnTransition - $game_map.refresh - setMapChanged(oldmap) - $game_screen.weather_duration = 20 - end - - def setMapsInRange - return if @fixup - @fixup = true - id = $game_map.map_id - conns = MapFactoryHelper.getMapConnections - if conns[id] - for conn in conns[id] - if conn[0] == id - mapA = getMap(conn[0]) - newdispx = (conn[4] - conn[1]) * Game_Map::REAL_RES_X + mapA.display_x - newdispy = (conn[5] - conn[2]) * Game_Map::REAL_RES_Y + mapA.display_y - if hasMap?(conn[3]) || MapFactoryHelper.mapInRangeById?(conn[3], newdispx, newdispy) - mapB = getMap(conn[3]) - mapB.display_x = newdispx if mapB.display_x != newdispx - mapB.display_y = newdispy if mapB.display_y != newdispy - end - else - mapA = getMap(conn[3]) - newdispx = (conn[1] - conn[4]) * Game_Map::REAL_RES_X + mapA.display_x - newdispy = (conn[2] - conn[5]) * Game_Map::REAL_RES_Y + mapA.display_y - if hasMap?(conn[0]) || MapFactoryHelper.mapInRangeById?(conn[0], newdispx, newdispy) - mapB = getMap(conn[0]) - mapB.display_x = newdispx if mapB.display_x != newdispx - mapB.display_y = newdispy if mapB.display_y != newdispy - end - end - end - end - @fixup = false - end - - def setMapChanging(newID,newMap) - Events.onMapChanging.trigger(self,newID,newMap) - end - - def setMapChanged(prevMap) - Events.onMapChange.trigger(self,prevMap) - @mapChanged = true - end - - def setSceneStarted(scene) - Events.onMapSceneChange.trigger(self,scene,@mapChanged) - @mapChanged = false - end - - # Similar to Game_Player#passable?, but supports map connections - def isPassableFromEdge?(x, y) - return true if $game_map.valid?(x, y) - newmap = getNewMap(x, y) - return false if !newmap - return isPassable?(newmap[0].map_id, newmap[1], newmap[2]) - end - - def isPassable?(mapID, x, y, thisEvent = nil) - thisEvent = $game_player if !thisEvent - map = getMapNoAdd(mapID) - return false if !map - return false if !map.valid?(x, y) - return true if thisEvent.through - # Check passability of tile - if thisEvent.is_a?(Game_Player) - return false unless ($DEBUG && Input.press?(Input::CTRL)) || - map.passable?(x, y, 0, thisEvent) - else - return false unless map.passable?(x, y, 0, thisEvent) - end - # Check passability of event(s) in that spot - for event in map.events.values - next if event == thisEvent || !event.at_coordinate?(x, y) - return false if !event.through && event.character_name != "" - end - # Check passability of player - if !thisEvent.is_a?(Game_Player) - if $game_map.map_id == mapID && $game_player.x == x && $game_player.y == y - return false if !$game_player.through && $game_player.character_name != "" - end - end - return true - end - - # Only used by dependent events - def isPassableStrict?(mapID,x,y,thisEvent=nil) - thisEvent = $game_player if !thisEvent - map = getMapNoAdd(mapID) - return false if !map - return false if !map.valid?(x,y) - return true if thisEvent.through - if thisEvent==$game_player - if !($DEBUG && Input.press?(Input::CTRL)) - return false if !map.passableStrict?(x,y,0,thisEvent) - end - else - return false if !map.passableStrict?(x,y,0,thisEvent) - end - for event in map.events.values - next if event == thisEvent || !event.at_coordinate?(x, y) - return false if !event.through && event.character_name!="" - end - return true - end - - def getTerrainTag(mapid,x,y,countBridge=false) - map = getMapNoAdd(mapid) - return map.terrain_tag(x,y,countBridge) - end - - # NOTE: Assumes the event is 1x1 tile in size. Only returns one terrain tag. - def getFacingTerrainTag(dir=nil,event=nil) - tile = getFacingTile(dir,event) - return GameData::TerrainTag.get(:None) if !tile - return getTerrainTag(tile[0],tile[1],tile[2]) - end - - def getTerrainTagFromCoords(mapid,x,y,countBridge=false) - tile = getRealTilePos(mapid,x,y) - return GameData::TerrainTag.get(:None) if !tile - return getTerrainTag(tile[0],tile[1],tile[2]) - end - - def areConnected?(mapID1, mapID2) - return true if mapID1 == mapID2 - conns = MapFactoryHelper.getMapConnections - if conns[mapID1] - for conn in conns[mapID1] - return true if conn[0] == mapID2 || conn[3] == mapID2 - end - end - return false - end - - def getRelativePos(thisMapID, thisX, thisY, otherMapID, otherX, otherY) - if thisMapID == otherMapID # Both events share the same map - return [otherX - thisX, otherY - thisY] - end - conns = MapFactoryHelper.getMapConnections - if conns[thisMapID] - for conn in conns[thisMapID] - if conn[0] == otherMapID - posX = thisX + conn[1] - conn[4] + otherX - posY = thisY + conn[2] - conn[5] + otherY - return [posX, posY] - elsif conn[3] == otherMapID - posX = thisX + conn[4] - conn[1] + otherX - posY = thisY + conn[5] - conn[2] + otherY - return [posX, posY] - end - end - end - return [0, 0] - end - - # Gets the distance from this event to another event. Example: If this event's - # coordinates are (2,5) and the other event's coordinates are (5,1), returns - # the array (3,-4), because (5-2=3) and (1-5=-4). - def getThisAndOtherEventRelativePos(thisEvent,otherEvent) - return [0,0] if !thisEvent || !otherEvent - return getRelativePos( - thisEvent.map.map_id,thisEvent.x,thisEvent.y, - otherEvent.map.map_id,otherEvent.x,otherEvent.y) - end - - def getThisAndOtherPosRelativePos(thisEvent,otherMapID,otherX,otherY) - return [0,0] if !thisEvent - return getRelativePos( - thisEvent.map.map_id,thisEvent.x,thisEvent.y,otherMapID,otherX,otherY) - end - - # Unused - def getOffsetEventPos(event,xOffset,yOffset) - event = $game_player if !event - return nil if !event - return getRealTilePos(event.map.map_id,event.x+xOffset,event.y+yOffset) - end - - # NOTE: Assumes the event is 1x1 tile in size. Only returns one tile. - def getFacingTile(direction=nil,event=nil,steps=1) - event = $game_player if event==nil - return [0,0,0] if !event - x = event.x - y = event.y - id = event.map.map_id - direction = event.direction if direction==nil - return getFacingTileFromPos(id,x,y,direction,steps) - end - - def getFacingTileFromPos(mapID,x,y,direction=0,steps=1) - id = mapID - case direction - when 1 - x -= steps - y += steps - when 2 - y += steps - when 3 - x += steps - y += steps - when 4 - x -= steps - when 6 - x += steps - when 7 - x -= steps - y -= steps - when 8 - y -= steps - when 9 - x += steps - y -= steps - else - return [id,x,y] - end - return getRealTilePos(mapID,x,y) - end - - def getRealTilePos(mapID, x, y) - id = mapID - return [id, x, y] if getMapNoAdd(id).valid?(x, y) - conns = MapFactoryHelper.getMapConnections - if conns[id] - for conn in conns[id] - if conn[0] == id - newX = x + conn[4] - conn[1] - newY = y + conn[5] - conn[2] - next if newX < 0 || newY < 0 - dims = MapFactoryHelper.getMapDims(conn[3]) - next if newX >= dims[0] || newY >= dims[1] - return [conn[3], newX, newY] - else - newX = x + conn[1] - conn[4] - newY = y + conn[2] - conn[5] - next if newX < 0 || newY < 0 - dims = MapFactoryHelper.getMapDims(conn[0]) - next if newX >= dims[0] || newY >= dims[1] - return [conn[0], newX, newY] - end - end - end - return nil - end - - def getFacingCoords(x,y,direction=0,steps=1) - case direction - when 1 - x -= steps - y += steps - when 2 - y += steps - when 3 - x += steps - y += steps - when 4 - x -= steps - when 6 - x += steps - when 7 - x -= steps - y -= steps - when 8 - y -= steps - when 9 - x += steps - y -= steps - end - return [x,y] - end - - def updateMaps(scene) - updateMapsInternal - $MapFactory.setSceneStarted(scene) if @mapChanged - end - - def updateMapsInternal - return if $game_player.moving? - if !MapFactoryHelper.hasConnections?($game_map.map_id) - return if @maps.length==1 - for i in 0...@maps.length - @maps[i] = nil if $game_map.map_id!=@maps[i].map_id - end - @maps.compact! - @mapIndex = getMapIndex($game_map.map_id) - return - end - setMapsInRange - deleted = false - for i in 0...@maps.length - next if MapFactoryHelper.mapInRange?(@maps[i]) - @maps[i] = nil - deleted = true - end - if deleted - @maps.compact! - @mapIndex = getMapIndex($game_map.map_id) - end - end -end - -#=============================================================================== -# Map Factory Helper (stores map connection and size data and calculations -# involving them) -#=============================================================================== -module MapFactoryHelper - @@MapConnections = nil - @@MapDims = nil - - def self.clear - @@MapConnections = nil - @@MapDims = nil - end - - def self.getMapConnections - if !@@MapConnections - @@MapConnections = [] - conns = load_data("Data/map_connections.dat") - conns.each do |conn| - # Ensure both maps in a connection are valid - dimensions = getMapDims(conn[0]) - next if dimensions[0] == 0 || dimensions[1] == 0 - dimensions = getMapDims(conn[3]) - next if dimensions[0] == 0 || dimensions[1] == 0 - # Convert first map's edge and coordinate to pair of coordinates - edge = getMapEdge(conn[0], conn[1]) - case conn[1] - when "N", "S" - conn[1] = conn[2] - conn[2] = edge - when "E", "W" - conn[1] = edge - end - # Convert second map's edge and coordinate to pair of coordinates - edge = getMapEdge(conn[3], conn[4]) - case conn[4] - when "N", "S" - conn[4] = conn[5] - conn[5] = edge - when "E", "W" - conn[4] = edge - end - # Add connection to arrays for both maps - @@MapConnections[conn[0]] = [] if !@@MapConnections[conn[0]] - @@MapConnections[conn[0]].push(conn) - @@MapConnections[conn[3]] = [] if !@@MapConnections[conn[3]] - @@MapConnections[conn[3]].push(conn) - end - end - return @@MapConnections - end - - def self.hasConnections?(id) - conns = MapFactoryHelper.getMapConnections - return conns[id] ? true : false - end - - # Gets the height and width of the map with id - def self.getMapDims(id) - # Create cache if doesn't exist - @@MapDims = [] if !@@MapDims - # Add map to cache if can't be found - if !@@MapDims[id] - begin - map = load_data(sprintf("Data/Map%03d.rxdata", id)) - @@MapDims[id] = [map.width,map.height] - rescue - @@MapDims[id] = [0,0] - end - end - # Return map in cache - return @@MapDims[id] - end - - # Returns the X or Y coordinate of an edge on the map with id. - # Considers the special strings "N","W","E","S" - def self.getMapEdge(id,edge) - return 0 if edge=="N" || edge=="W" - dims = getMapDims(id) # Get dimensions - return dims[0] if edge=="E" - return dims[1] if edge=="S" - return dims[0] # real dimension (use width) - end - - def self.mapInRange?(map) - range = 6 # Number of tiles - dispx = map.display_x - dispy = map.display_y - return false if dispx >= (map.width + range) * Game_Map::REAL_RES_X - return false if dispy >= (map.height + range) * Game_Map::REAL_RES_Y - return false if dispx <= -(Graphics.width + range * Game_Map::TILE_WIDTH) * Game_Map::X_SUBPIXELS - return false if dispy <= -(Graphics.height + range * Game_Map::TILE_HEIGHT) * Game_Map::Y_SUBPIXELS - return true - end - - def self.mapInRangeById?(id,dispx,dispy) - range = 6 # Number of tiles - dims = MapFactoryHelper.getMapDims(id) - return false if dispx >= (dims[0] + range) * Game_Map::REAL_RES_X - return false if dispy >= (dims[1] + range) * Game_Map::REAL_RES_Y - return false if dispx <= -(Graphics.width + range * Game_Map::TILE_WIDTH) * Game_Map::X_SUBPIXELS - return false if dispy <= -(Graphics.height + range * Game_Map::TILE_HEIGHT) * Game_Map::Y_SUBPIXELS - return true - end -end - -#=============================================================================== -# -#=============================================================================== -# Unused -def updateTilesets - maps = $MapFactory.maps - for map in maps - map.updateTileset if map - end -end diff --git a/Data/Scripts/004_Game classes/007_Game_Character.rb b/Data/Scripts/004_Game classes/007_Game_Character.rb deleted file mode 100644 index a1ee73ac6..000000000 --- a/Data/Scripts/004_Game classes/007_Game_Character.rb +++ /dev/null @@ -1,1176 +0,0 @@ -class Game_Character - attr_reader :id - attr_reader :original_x - attr_reader :original_y - attr_reader :x - attr_reader :y - attr_reader :real_x - attr_reader :real_y - attr_accessor :width - attr_accessor :height - attr_accessor :sprite_size - attr_reader :tile_id - attr_accessor :character_name - attr_accessor :character_hue - attr_reader :opacity - attr_reader :blend_type - attr_accessor :direction - attr_accessor :pattern - attr_accessor :pattern_surf - attr_accessor :lock_pattern - attr_reader :move_route_forcing - attr_accessor :through - attr_accessor :animation_id - attr_accessor :transparent - attr_reader :move_speed - attr_accessor :walk_anime - attr_writer :bob_height - attr_accessor :under_everything - - def initialize(map = nil) - @map = map - @id = 0 - @original_x = 0 - @original_y = 0 - @x = 0 - @y = 0 - @real_x = 0 - @real_y = 0 - @width = 1 - @height = 1 - @sprite_size = [Game_Map::TILE_WIDTH, Game_Map::TILE_HEIGHT] - @tile_id = 0 - @character_name = "" - @character_hue = 0 - @opacity = 255 - @blend_type = 0 - @direction = 2 - @pattern = 0 - @pattern_surf = 0 - @lock_pattern = false - @move_route_forcing = false - @through = false - @animation_id = 0 - @transparent = false - @original_direction = 2 - @original_pattern = 0 - @move_type = 0 - self.move_speed = 3 - self.move_frequency = 6 - @move_route = nil - @move_route_index = 0 - @original_move_route = nil - @original_move_route_index = 0 - @walk_anime = true # Whether character should animate while moving - @step_anime = false # Whether character should animate while still - @direction_fix = false - @always_on_top = false - @anime_count = 0 - @stop_count = 0 - @jump_peak = 0 # Max height while jumping - @jump_distance = 0 # Total distance of jump - @jump_distance_left = 0 # Distance left to travel - @jump_count = 0 # Frames left in a stationary jump - @bob_height = 0 - @wait_count = 0 - @moved_this_frame = false - @locked = false - @prelock_direction = 0 - @under_everything=false - end - - def at_coordinate?(check_x, check_y) - return check_x >= @x && check_x < @x + @width && - check_y > @y - @height && check_y <= @y - end - - def in_line_with_coordinate?(check_x, check_y) - return (check_x >= @x && check_x < @x + @width) || - (check_y > @y - @height && check_y <= @y) - end - - def each_occupied_tile - for i in @x...(@x + @width) - for j in (@y - @height + 1)..@y - yield i, j - end - end - end - - def set_opacity(opacity) - @opacity = opacity - end - - def move_speed=(val) - return if val == @move_speed - @move_speed = val - # @move_speed_real is the number of quarter-pixels to move each frame. There - # are 128 quarter-pixels per tile. By default, it is calculated from - # @move_speed and has these values (assuming 40 fps): - # 1 => 3.2 # 40 frames per tile - # 2 => 6.4 # 20 frames per tile - # 3 => 12.8 # 10 frames per tile - walking speed - # 4 => 25.6 # 5 frames per tile - running speed (2x walking speed) - # 5 => 32 # 4 frames per tile - cycling speed (1.25x running speed) - # 6 => 64 # 2 frames per tile - self.move_speed_real = (val == 6) ? 64 : (val == 5) ? 32 : (2 ** (val + 1)) * 0.8 - end - - def move_speed_real - self.move_speed = @move_speed if !@move_speed_real - return @move_speed_real - end - - def move_speed_real=(val) - @move_speed_real = val * 40.0 / Graphics.frame_rate - end - - def jump_speed_real - self.jump_speed_real = (2 ** (3 + 1)) * 0.8 if !@jump_speed_real # 3 is walking speed - return @jump_speed_real - end - - def jump_speed_real=(val) - @jump_speed_real = val * 40.0 / Graphics.frame_rate - end - - def move_frequency=(val) - return if val == @move_frequency - @move_frequency = val - # @move_frequency_real is the number of frames to wait between each action - # in a move route (not forced). Specifically, this is the number of frames - # to wait after the character stops moving because of the previous action. - # By default, it is calculated from @move_frequency and has these values - # (assuming 40 fps): - # 1 => 190 # 4.75 seconds - # 2 => 144 # 3.6 seconds - # 3 => 102 # 2.55 seconds - # 4 => 64 # 1.6 seconds - # 5 => 30 # 0.75 seconds - # 6 => 0 # 0 seconds, i.e. continuous movement - self.move_frequency_real = (40 - val * 2) * (6 - val) - end - - def move_frequency_real - self.move_frequency = @move_frequency if !@move_frequency_real - return @move_frequency_real - end - - def move_frequency_real=(val) - @move_frequency_real = val * Graphics.frame_rate / 40.0 - end - - def bob_height - @bob_height = 0 if !@bob_height - return @bob_height - end - - def lock - return if @locked - @prelock_direction = 0 # Was @direction but disabled - turn_toward_player - @locked = true - end - - def minilock - @prelock_direction = 0 # Was @direction but disabled - @locked = true - end - - def lock? - return @locked - end - - def unlock - return unless @locked - @locked = false - @direction = @prelock_direction if !@direction_fix && @prelock_direction != 0 - end - - #============================================================================= - # Information from map data - #============================================================================= - def map - return (@map) ? @map : $game_map - end - - def terrain_tag - return self.map.terrain_tag(@x, @y) - end - - def cancelMoveRoute() - @move_route = nil - @move_route_forcing = false - end - - def bush_depth - return @bush_depth || 0 - end - - def calculate_bush_depth - if @tile_id > 0 || @always_on_top || jumping? - @bush_depth = 0 - else - deep_bush = regular_bush = false - xbehind = @x + (@direction == 4 ? 1 : @direction == 6 ? -1 : 0) - ybehind = @y + (@direction == 8 ? 1 : @direction == 2 ? -1 : 0) - this_map = (self.map.valid?(@x, @y)) ? [self.map, @x, @y] : $MapFactory.getNewMap(@x, @y) - if this_map[0].deepBush?(this_map[1], this_map[2]) && self.map.deepBush?(xbehind, ybehind) - @bush_depth = Game_Map::TILE_HEIGHT - elsif !moving? && this_map[0].bush?(this_map[1], this_map[2]) - @bush_depth = 12 - else - @bush_depth = 0 - end - end - end - - #============================================================================= - # Passability - #============================================================================= - def pbFacingTerrainTag(dir = nil) - dir = self.direction if !dir - return $MapFactory.getFacingTerrainTag(dir, self) if $MapFactory - facing = pbFacingTile(dir, self) - return $game_map.terrain_tag(facing[1], facing[2]) - end - - - def passable?(x, y, d, strict = false) - return false if self == $game_player && $game_switches[SWITCH_LOCK_PLAYER_MOVEMENT] - new_x = x + (d == 6 ? 1 : d == 4 ? -1 : 0) - new_y = y + (d == 2 ? 1 : d == 8 ? -1 : 0) - return false unless self.map.valid?(new_x, new_y) - if self.character_name == "SHARPEDO" || self.character_name == "nightmare" - return false if pbFacingTerrainTag().id==:SharpedoObstacle - end - return true if @through - - if strict - return false unless self.map.passableStrict?(x, y, d, self) - return false unless self.map.passableStrict?(new_x, new_y, 10 - d, self) - else - return false unless self.map.passable?(x, y, d, self) - return false unless self.map.passable?(new_x, new_y, 10 - d, self) - end - for event in self.map.events.values - next if self == event || !event.at_coordinate?(new_x, new_y) || event.through - return false if self != $game_player || event.character_name != "" - end - if $game_player.x == new_x && $game_player.y == new_y - return false if !$game_player.through && @character_name != "" - end - return true - end - - def can_move_from_coordinate?(start_x, start_y, dir, strict = false) - case dir - when 2, 8 # Down, up - y_diff = (dir == 8) ? @height - 1 : 0 - for i in start_x...(start_x + @width) - return false if !passable?(i, start_y - y_diff, dir, strict) - end - return true - when 4, 6 # Left, right - x_diff = (dir == 6) ? @width - 1 : 0 - for i in (start_y - @height + 1)..start_y - return false if !passable?(start_x + x_diff, i, dir, strict) - end - return true - when 1, 3 # Down diagonals - # Treated as moving down first and then horizontally, because that - # describes which tiles the character's feet touch - for i in start_x...(start_x + @width) - return false if !passable?(i, start_y, 2, strict) - end - x_diff = (dir == 3) ? @width - 1 : 0 - for i in (start_y - @height + 1)..start_y - return false if !passable?(start_x + x_diff, i + 1, dir + 3, strict) - end - return true - when 7, 9 # Up diagonals - # Treated as moving horizontally first and then up, because that describes - # which tiles the character's feet touch - x_diff = (dir == 9) ? @width - 1 : 0 - for i in (start_y - @height + 1)..start_y - return false if !passable?(start_x + x_diff, i, dir - 3, strict) - end - x_offset = (dir == 9) ? 1 : -1 - for i in start_x...(start_x + @width) - return false if !passable?(i + x_offset, start_y - @height + 1, 8, strict) - end - return true - end - return false - end - - def can_move_in_direction?(dir, strict = false) - return can_move_from_coordinate?(@x, @y, dir, strict) - end - - #============================================================================= - # Screen position of the character - #============================================================================= - def screen_x - ret = ((@real_x.to_f - self.map.display_x) / Game_Map::X_SUBPIXELS).round - ret += @width * Game_Map::TILE_WIDTH / 2 - return ret - end - - def screen_y_ground - ret = ((@real_y.to_f - self.map.display_y) / Game_Map::Y_SUBPIXELS).round - ret += Game_Map::TILE_HEIGHT - return ret - end - - def screen_y - ret = screen_y_ground - if jumping? - if @jump_count > 0 - jump_fraction = ((@jump_count * jump_speed_real / Game_Map::REAL_RES_X) - 0.5).abs # 0.5 to 0 to 0.5 - else - jump_fraction = ((@jump_distance_left / @jump_distance) - 0.5).abs # 0.5 to 0 to 0.5 - end - ret += @jump_peak * (4 * jump_fraction ** 2 - 1) - end - return ret - end - - def screen_z(height = 0) - return -1 if @under_everything - return 999 if @always_on_top - z = screen_y_ground - if @tile_id > 0 - begin - return z + self.map.priorities[@tile_id] * 32 - rescue - return 0 - #raise "Event's graphic is an out-of-range tile (event #{@id}, map #{self.map.map_id})" - end - end - # Add z if height exceeds 32 - return z + ((height > Game_Map::TILE_HEIGHT) ? Game_Map::TILE_HEIGHT - 1 : 0) - end - - #============================================================================= - # Movement - #============================================================================= - def moving? - return @real_x != @x * Game_Map::REAL_RES_X || - @real_y != @y * Game_Map::REAL_RES_Y - end - - def jumping? - return (@jump_distance_left || 0) > 0 || @jump_count > 0 - end - - def straighten - @pattern = 0 if @walk_anime || @step_anime - @anime_count = 0 - @prelock_direction = 0 - end - - def force_move_route(move_route) - #echoln screen_z() if self == $game_player - if @original_move_route == nil - @original_move_route = @move_route - @original_move_route_index = @move_route_index - end - @move_route = move_route - @move_route_index = 0 - @move_route_forcing = true - @prelock_direction = 0 - @wait_count = 0 - move_type_custom - end - - def moveto(x, y) - @x = x % self.map.width - @y = y % self.map.height - @real_x = @x * Game_Map::REAL_RES_X - @real_y = @y * Game_Map::REAL_RES_Y - @prelock_direction = 0 - calculate_bush_depth - triggerLeaveTile - end - - def triggerLeaveTile - if @oldX && @oldY && @oldMap && - (@oldX != self.x || @oldY != self.y || @oldMap != self.map.map_id) - Events.onLeaveTile.trigger(self, self, @oldMap, @oldX, @oldY) - end - @oldX = self.x - @oldY = self.y - @oldMap = self.map.map_id - end - - def increase_steps - @stop_count = 0 - triggerLeaveTile - end - - #============================================================================= - # Movement commands - #============================================================================= - def move_type_random - case rand(6) - when 0..3 then - move_random - when 4 then - move_forward - when 5 then - @stop_count = 0 - end - end - - def move_type_toward_player - sx = @x + @width / 2.0 - ($game_player.x + $game_player.width / 2.0) - sy = @y - @height / 2.0 - ($game_player.y - $game_player.height / 2.0) - if sx.abs + sy.abs >= 20 - move_random - return - end - case rand(6) - when 0..3 then - move_toward_player - when 4 then - move_random - when 5 then - move_forward - end - end - - def move_type_custom - return if jumping? || moving? - while @move_route_index < @move_route.list.size - command = @move_route.list[@move_route_index] - if command.code == 0 - if @move_route.repeat - @move_route_index = 0 - else - if @move_route_forcing - @move_route_forcing = false - @move_route = @original_move_route - @move_route_index = @original_move_route_index - @original_move_route = nil - end - @stop_count = 0 - end - return - end - if command.code <= 14 - case command.code - when 1 then - move_down - when 2 then - move_left - when 3 then - move_right - when 4 then - move_up - when 5 then - move_lower_left - when 6 then - move_lower_right - when 7 then - move_upper_left - when 8 then - move_upper_right - when 9 then - move_random - when 10 then - move_toward_player - when 11 then - move_away_from_player - when 12 then - move_forward - when 13 then - move_backward - when 14 then - jump(command.parameters[0], command.parameters[1]) - end - @move_route_index += 1 if @move_route.skippable || moving? || jumping? - return - end - if command.code == 15 # Wait - @wait_count = (command.parameters[0] * Graphics.frame_rate / 20) - 1 - @move_route_index += 1 - return - end - if command.code >= 16 && command.code <= 26 - case command.code - when 16 then - turn_down - when 17 then - turn_left - when 18 then - turn_right - when 19 then - turn_up - when 20 then - turn_right_90 - when 21 then - turn_left_90 - when 22 then - turn_180 - when 23 then - turn_right_or_left_90 - when 24 then - turn_random - when 25 then - turn_toward_player - when 26 then - turn_away_from_player - end - @move_route_index += 1 - return - end - if command.code >= 27 - case command.code - when 27 - $game_switches[command.parameters[0]] = true - self.map.need_refresh = true - when 28 - $game_switches[command.parameters[0]] = false - self.map.need_refresh = true - when 29 then - self.move_speed = command.parameters[0] - when 30 then - self.move_frequency = command.parameters[0] - when 31 then - @walk_anime = true - when 32 then - @walk_anime = false - when 33 then - @step_anime = true - when 34 then - @step_anime = false - when 35 then - @direction_fix = true - when 36 then - @direction_fix = false - when 37 then - @through = true - when 38 then - @through = false - when 39 - old_always_on_top = @always_on_top - @always_on_top = true - calculate_bush_depth if @always_on_top != old_always_on_top - when 40 - old_always_on_top = @always_on_top - @always_on_top = false - calculate_bush_depth if @always_on_top != old_always_on_top - when 41 - old_tile_id = @tile_id - @tile_id = 0 - @character_name = command.parameters[0] - @character_hue = command.parameters[1] - if @original_direction != command.parameters[2] - @direction = command.parameters[2] - @original_direction = @direction - @prelock_direction = 0 - end - if @original_pattern != command.parameters[3] - @pattern = command.parameters[3] - @original_pattern = @pattern - end - calculate_bush_depth if @tile_id != old_tile_id - when 42 then - @opacity = command.parameters[0] - when 43 then - @blend_type = command.parameters[0] - when 44 then - pbSEPlay(command.parameters[0]) - when 45 then - eval(command.parameters[0]) - end - @move_route_index += 1 - end - end - end - - def move_generic(dir, turn_enabled = true) - turn_generic(dir) if turn_enabled - if can_move_in_direction?(dir) - turn_generic(dir) - @x += (dir == 4) ? -1 : (dir == 6) ? 1 : 0 - @y += (dir == 8) ? -1 : (dir == 2) ? 1 : 0 - increase_steps - else - check_event_trigger_touch(dir) - end - end - - def move_down(turn_enabled = true) - move_generic(2, turn_enabled) - end - - def move_left(turn_enabled = true) - move_generic(4, turn_enabled) - end - - def move_right(turn_enabled = true) - move_generic(6, turn_enabled) - end - - def move_up(turn_enabled = true) - move_generic(8, turn_enabled) - end - - # def move_upper_left - # @through=true - # unless @direction_fix - # @direction = (@direction == 6 ? 4 : @direction == 2 ? 8 : @direction) - # end - # if can_move_in_direction?(7) - # @x -= 1 - # @y -= 1 - # increase_steps - # end - # @through=false - # end - # - # def move_upper_right - # @through=true - # unless @direction_fix - # @direction = (@direction == 4 ? 6 : @direction == 2 ? 8 : @direction) - # end - # if can_move_in_direction?(9) - # @x += 1 - # @y -= 1 - # increase_steps - # end - # @through=false - # end - # - # def move_lower_left - # @through=true - # unless @direction_fix - # @direction = (@direction == 6 ? 4 : @direction == 8 ? 2 : @direction) - # end - # if can_move_in_direction?(1) - # @x -= 1 - # @y += 1 - # increase_steps - # end - # @through=false - # end - # - # def move_lower_right - # @through=true - # unless @direction_fix - # @direction = (@direction == 4 ? 6 : @direction == 8 ? 2 : @direction) - # end - # if can_move_in_direction?(3) - # @x += 1 - # @y += 1 - # increase_steps - # end - # @through=false - # end - - def move_lower_left - unless @direction_fix - @direction = ( - if @direction == DIRECTION_RIGHT - DIRECTION_LEFT - else - @direction == DIRECTION_UP ? DIRECTION_DOWN : @direction - end) - end - if (passable?(@x, @y, DIRECTION_DOWN) and passable?(@x, @y + 1, DIRECTION_LEFT)) or - (passable?(@x, @y, DIRECTION_LEFT) and passable?(@x - 1, @y, DIRECTION_DOWN)) - if destination_is_passable(@x - 1, @y + 1) - @x -= 1 - @y += 1 - increase_steps - end - end - end - - def move_lower_right - unless @direction_fix - @direction = ( - if @direction == DIRECTION_LEFT - DIRECTION_RIGHT - else - @direction == DIRECTION_UP ? DIRECTION_DOWN : @direction - end) - end - if (passable?(@x, @y, DIRECTION_DOWN) and passable?(@x, @y + 1, DIRECTION_RIGHT)) or - (passable?(@x, @y, DIRECTION_RIGHT) and passable?(@x + 1, @y, DIRECTION_DOWN)) - if destination_is_passable(@x + 1, @y + 1) - @x += 1 - @y += 1 - increase_steps - end - end - end - - def move_upper_left - unless @direction_fix - @direction = ( - if @direction == DIRECTION_RIGHT - DIRECTION_LEFT - else - @direction == DIRECTION_DOWN ? DIRECTION_UP : @direction - end) - end - if (passable?(@x, @y, DIRECTION_UP) and passable?(@x, @y - 1, DIRECTION_LEFT)) or - (passable?(@x, @y, DIRECTION_LEFT) and passable?(@x - 1, @y, DIRECTION_UP)) - if destination_is_passable(@x - 1, @y - 1) - @x -= 1 - @y -= 1 - increase_steps - end - end - end - - def move_upper_right - unless @direction_fix - @direction = ( - if @direction == DIRECTION_LEFT - DIRECTION_RIGHT - else - @direction == DIRECTION_DOWN ? DIRECTION_UP : @direction - end) - end - if (passable?(@x, @y, DIRECTION_UP) and passable?(@x, @y - 1, DIRECTION_RIGHT)) or - (passable?(@x, @y, DIRECTION_RIGHT) and passable?(@x + 1, @y, DIRECTION_UP)) - if destination_is_passable(@x + 1, @y - 1) - @x += 1 - @y -= 1 - increase_steps - end - end - end - - def destination_is_passable(x_dest, y_dest) - return passable?(x_dest, y_dest, 0) - end - - def moveLeft90 # anticlockwise - case self.direction - when 2 then - move_right # down - when 4 then - move_down # left - when 6 then - move_up # right - when 8 then - move_left # up - end - end - - def moveRight90 # clockwise - case self.direction - when 2 then - move_left # down - when 4 then - move_up # left - when 6 then - move_down # right - when 8 then - move_right # up - end - end - - def move_random - case rand(4) - when 0 then - move_down(false) - when 1 then - move_left(false) - when 2 then - move_right(false) - when 3 then - move_up(false) - end - end - - def move_random_range(xrange = -1, yrange = -1) - dirs = [] # 0=down, 1=left, 2=right, 3=up - if xrange < 0 - dirs.push(1); dirs.push(2) - elsif xrange > 0 - dirs.push(1) if @x > @original_x - xrange - dirs.push(2) if @x < @original_x + xrange - end - if yrange < 0 - dirs.push(0); dirs.push(3) - elsif yrange > 0 - dirs.push(0) if @y < @original_y + yrange - dirs.push(3) if @y > @original_y - yrange - end - return if dirs.length == 0 - case dirs[rand(dirs.length)] - when 0 then - move_down(false) - when 1 then - move_left(false) - when 2 then - move_right(false) - when 3 then - move_up(false) - end - end - - def move_random_UD(range = -1) - move_random_range(0, range) - end - - def move_random_LR(range = -1) - move_random_range(range, 0) - end - - def move_toward_player - sx = @x + @width / 2.0 - ($game_player.x + $game_player.width / 2.0) - sy = @y - @height / 2.0 - ($game_player.y - $game_player.height / 2.0) - return if sx == 0 && sy == 0 - abs_sx = sx.abs - abs_sy = sy.abs - if abs_sx == abs_sy - (rand(2) == 0) ? abs_sx += 1 : abs_sy += 1 - end - if abs_sx > abs_sy - (sx > 0) ? move_left : move_right - if !moving? && sy != 0 - (sy > 0) ? move_up : move_down - end - else - (sy > 0) ? move_up : move_down - if !moving? && sx != 0 - (sx > 0) ? move_left : move_right - end - end - end - - def move_away_from_player - sx = @x + @width / 2.0 - ($game_player.x + $game_player.width / 2.0) - sy = @y - @height / 2.0 - ($game_player.y - $game_player.height / 2.0) - return if sx == 0 && sy == 0 - abs_sx = sx.abs - abs_sy = sy.abs - if abs_sx == abs_sy - (rand(2) == 0) ? abs_sx += 1 : abs_sy += 1 - end - if abs_sx > abs_sy - (sx > 0) ? move_right : move_left - if !moving? && sy != 0 - (sy > 0) ? move_down : move_up - end - else - (sy > 0) ? move_down : move_up - if !moving? && sx != 0 - (sx > 0) ? move_right : move_left - end - end - end - - def move_forward - case @direction - when 2 then - move_down(false) - when 4 then - move_left(false) - when 6 then - move_right(false) - when 8 then - move_up(false) - end - end - - def move_backward - last_direction_fix = @direction_fix - @direction_fix = true - case @direction - when 2 then - move_up(false) - when 4 then - move_right(false) - when 6 then - move_left(false) - when 8 then - move_down(false) - end - @direction_fix = last_direction_fix - end - - def jump(x_plus, y_plus) - if x_plus != 0 || y_plus != 0 - if x_plus.abs > y_plus.abs - (x_plus < 0) ? turn_left : turn_right - else - (y_plus < 0) ? turn_up : turn_down - end - each_occupied_tile { |i, j| return if !passable?(i + x_plus, j + y_plus, 0) } - end - @x = @x + x_plus - @y = @y + y_plus - real_distance = Math::sqrt(x_plus * x_plus + y_plus * y_plus) - distance = [1, real_distance].max - @jump_peak = distance * Game_Map::TILE_HEIGHT * 3 / 8 # 3/4 of tile for ledge jumping - @jump_distance = [x_plus.abs * Game_Map::REAL_RES_X, y_plus.abs * Game_Map::REAL_RES_Y].max - @jump_distance_left = 1 # Just needs to be non-zero - if real_distance > 0 # Jumping to somewhere else - @jump_count = 0 - else - # Jumping on the spot - @jump_speed_real = nil # Reset jump speed - @jump_count = Game_Map::REAL_RES_X / jump_speed_real # Number of frames to jump one tile - end - @stop_count = 0 - if self.is_a?(Game_Player) - $PokemonTemp.dependentEvents.pbMoveDependentEvents - end - triggerLeaveTile - end - - def jumpForward - case self.direction - when 2 then - jump(0, 1) # down - when 4 then - jump(-1, 0) # left - when 6 then - jump(1, 0) # right - when 8 then - jump(0, -1) # up - end - end - - def jumpBackward - case self.direction - when 2 then - jump(0, -1) # down - when 4 then - jump(1, 0) # left - when 6 then - jump(-1, 0) # right - when 8 then - jump(0, 1) # up - end - end - - def turn_generic(dir) - return if @direction_fix - oldDirection = @direction - @direction = dir - @stop_count = 0 - pbCheckEventTriggerAfterTurning if dir != oldDirection - end - - def turn_down - turn_generic(2); - end - - def turn_left - turn_generic(4); - end - - def turn_right - turn_generic(6); - end - - def turn_up - turn_generic(8); - end - - def turn_right_90 - case @direction - when 2 then - turn_left - when 4 then - turn_up - when 6 then - turn_down - when 8 then - turn_right - end - end - - def turn_left_90 - case @direction - when 2 then - turn_right - when 4 then - turn_down - when 6 then - turn_up - when 8 then - turn_left - end - end - - def turn_180 - case @direction - when 2 then - turn_up - when 4 then - turn_right - when 6 then - turn_left - when 8 then - turn_down - end - end - - def turn_right_or_left_90 - (rand(2) == 0) ? turn_right_90 : turn_left_90 - end - - def turn_random - case rand(4) - when 0 then - turn_up - when 1 then - turn_right - when 2 then - turn_left - when 3 then - turn_down - end - end - - def turn_toward_player - sx = @x + @width / 2.0 - ($game_player.x + $game_player.width / 2.0) - sy = @y - @height / 2.0 - ($game_player.y - $game_player.height / 2.0) - return if sx == 0 && sy == 0 - if sx.abs > sy.abs - (sx > 0) ? turn_left : turn_right - else - (sy > 0) ? turn_up : turn_down - end - end - - def turn_away_from_player - sx = @x + @width / 2.0 - ($game_player.x + $game_player.width / 2.0) - sy = @y - @height / 2.0 - ($game_player.y - $game_player.height / 2.0) - return if sx == 0 && sy == 0 - if sx.abs > sy.abs - (sx > 0) ? turn_right : turn_left - else - (sy > 0) ? turn_down : turn_up - end - end - - #============================================================================= - # Updating - #============================================================================= - def update - @moved_last_frame = @moved_this_frame - @stopped_last_frame = @stopped_this_frame - if !$game_temp.in_menu - # Update command - update_command - # Update movement - (moving? || jumping?) ? update_move : update_stop - end - # Update animation - update_pattern - end - - def update_command - if @wait_count > 0 - @wait_count -= 1 - elsif @move_route_forcing - move_type_custom - elsif !@starting && !lock? && !moving? && !jumping? - update_command_new - end - end - - def update_command_new - # @stop_count is the number of frames since the last movement finished. - # @move_frequency has these values: - # 1 => @stop_count > 190 # 4.75 seconds - # 2 => @stop_count > 144 # 3.6 seconds - # 3 => @stop_count > 102 # 2.55 seconds - # 4 => @stop_count > 64 # 1.6 seconds - # 5 => @stop_count > 30 # 0.75 seconds - # 6 => @stop_count > 0 # 0 seconds - if @stop_count >= self.move_frequency_real - case @move_type - when 1 then - move_type_random - when 2 then - move_type_toward_player - when 3 then - move_type_custom - end - end - end - - def update_move - # Move the character (the 0.1 catches rounding errors) - distance = (jumping?) ? jump_speed_real : move_speed_real - dest_x = @x * Game_Map::REAL_RES_X - dest_y = @y * Game_Map::REAL_RES_Y - if @real_x < dest_x - @real_x += distance - @real_x = dest_x if @real_x > dest_x - 0.1 - else - @real_x -= distance - @real_x = dest_x if @real_x < dest_x + 0.1 - end - if @real_y < dest_y - @real_y += distance - @real_y = dest_y if @real_y > dest_y - 0.1 - else - @real_y -= distance - @real_y = dest_y if @real_y < dest_y + 0.1 - end - # Refresh how far is left to travel in a jump - if jumping? - @jump_count -= 1 if @jump_count > 0 # For stationary jumps only - @jump_distance_left = [(dest_x - @real_x).abs, (dest_y - @real_y).abs].max - end - # End of a step, so perform events that happen at this time - if !jumping? && !moving? - Events.onStepTakenFieldMovement.trigger(self, self) - calculate_bush_depth - @stopped_this_frame = true - elsif !@moved_last_frame || @stopped_last_frame # Started a new step - calculate_bush_depth - @stopped_this_frame = false - end - # Increment animation counter - @anime_count += 1 if @walk_anime || @step_anime - @moved_this_frame = true - end - - def update_stop - @anime_count += 1 if @step_anime - @stop_count += 1 if !@starting && !lock? - @moved_this_frame = false - @stopped_this_frame = false - end - - def update_pattern - return if @lock_pattern - # return if @jump_count > 0 # Don't animate if jumping on the spot - # Character has stopped moving, return to original pattern - if @moved_last_frame && !@moved_this_frame && !@step_anime - @pattern = @original_pattern - @anime_count = 0 - return - end - # Character has started to move, change pattern immediately - if !@moved_last_frame && @moved_this_frame && !@step_anime - @pattern = (@pattern + 1) % 4 if @walk_anime - @anime_count = 0 - return - end - # Calculate how many frames each pattern should display for, i.e. the time - # it takes to move half a tile (or a whole tile if cycling). We assume the - # game uses square tiles. - real_speed = (jumping?) ? jump_speed_real : move_speed_real - frames_per_pattern = Game_Map::REAL_RES_X / (real_speed * 2.0) - frames_per_pattern *= 2 if move_speed >= 5 # Cycling speed or faster - return if @anime_count < frames_per_pattern - # Advance to the next animation frame - @pattern = (@pattern + 1) % 4 - @anime_count -= frames_per_pattern - end -end diff --git a/Data/Scripts/004_Game classes/008_Game_Event.rb b/Data/Scripts/004_Game classes/008_Game_Event.rb deleted file mode 100644 index b825175f3..000000000 --- a/Data/Scripts/004_Game classes/008_Game_Event.rb +++ /dev/null @@ -1,279 +0,0 @@ -class Game_Event < Game_Character - attr_reader :map_id - attr_reader :trigger - attr_reader :list - attr_reader :starting - attr_reader :tempSwitches # Temporary self-switches - attr_accessor :need_refresh - - def initialize(map_id, event, map=nil) - super(map) - @map_id = map_id - @event = event - @id = @event.id - @original_x = @event.x - @original_y = @event.y - if @event.name[/size\((\d+),(\d+)\)/i] - @width = $~[1].to_i - @height = $~[2].to_i - end - @erased = false - @starting = false - @need_refresh = false - @route_erased = false - @through = true - @to_update = true - @tempSwitches = {} - moveto(@event.x, @event.y) if map - refresh - end - - def id; return @event.id; end - def name; return @event.name; end - - def set_starting - @starting = true - end - - def clear_starting - @starting = false - end - - def start - @starting = true if @list.size > 1 - end - - def erase - @erased = true - refresh - end - - def erase_route - @route_erased = true - refresh - end - - def tsOn?(c) - return @tempSwitches && @tempSwitches[c]==true - end - - def tsOff?(c) - return !@tempSwitches || !@tempSwitches[c] - end - - def setTempSwitchOn(c) - @tempSwitches[c]=true - refresh - end - - def setTempSwitchOff(c) - @tempSwitches[c]=false - refresh - end - - def isOff?(c) - return !$game_self_switches[[@map_id,@event.id,c]] - end - - def switchIsOn?(id) - switchname = $data_system.switches[id] - return false if !switchname - if switchname[/^s\:/] - return eval($~.post_match) - else - return $game_switches[id] - end - end - - def variable - return nil if !$PokemonGlobal.eventvars - return $PokemonGlobal.eventvars[[@map_id,@event.id]] - end - - def setVariable(variable) - $PokemonGlobal.eventvars[[@map_id,@event.id]]=variable - end - - def varAsInt - return 0 if !$PokemonGlobal.eventvars - return $PokemonGlobal.eventvars[[@map_id,@event.id]].to_i - end - - def expired?(secs=86400) - ontime=self.variable - time=pbGetTimeNow - return ontime && (time.to_i>ontime+secs) - end - - def expiredDays?(days=1) - ontime=self.variable.to_i - return false if !ontime - now=pbGetTimeNow - elapsed=(now.to_i-ontime)/86400 - elapsed+=1 if (now.to_i-ontime)%86400>(now.hour*3600+now.min*60+now.sec) - return elapsed>=days - end - - def cooledDown?(seconds) - return true if expired?(seconds) && tsOff?("A") - self.need_refresh = true - return false - end - - def cooledDownDays?(days) - return true if expiredDays?(days) && tsOff?("A") - self.need_refresh = true - return false - end - - def onEvent? - return @map_id == $game_map.map_id && at_coordinate?($game_player.x, $game_player.y) - end - - - def over_trigger? - return false if @character_name != "" && !@through - return false if @event.name[/hiddenitem/i] - each_occupied_tile do |i, j| - return true if self.map.passable?(i, j, 0, $game_player) - end - return false - end - - def pbCheckEventTriggerAfterTurning - return if $game_system.map_interpreter.running? || @starting - if @event.name[/trainer\((\d+)\)/i] - distance = $~[1].to_i - if @trigger==2 && pbEventCanReachPlayer?(self,$game_player,distance) - start if !jumping? && !over_trigger? - end - end - end - - def check_event_trigger_touch(dir) - return if $game_system.map_interpreter.running? - return if @trigger != 2 # Event touch - case dir - when 2 - return if $game_player.y != @y + 1 - when 4 - return if $game_player.x != @x - 1 - when 6 - return if $game_player.x != @x + @width - when 8 - return if $game_player.y != @y - @height - end - return if !in_line_with_coordinate?($game_player.x, $game_player.y) - return if jumping? || over_trigger? - start - end - - def check_event_trigger_auto - if @trigger == 2 # Event touch - if at_coordinate?($game_player.x, $game_player.y) - start if !jumping? && over_trigger? - end - elsif @trigger == 3 # Autorun - start - end - end - - def refresh - new_page = nil - unless @erased - for page in @event.pages.reverse - c = page.condition - next if c.switch1_valid && !switchIsOn?(c.switch1_id) - next if c.switch2_valid && !switchIsOn?(c.switch2_id) - next if c.variable_valid && $game_variables[c.variable_id] < c.variable_value - if c.self_switch_valid - key = [@map_id, @event.id, c.self_switch_ch] - next if $game_self_switches[key] != true - end - new_page = page - break - end - end - return if new_page == @page - @page = new_page - clear_starting - if @page == nil - @tile_id = 0 - @character_name = "" - @character_hue = 0 - @move_type = 0 - @through = true - @trigger = nil - @list = nil - @interpreter = nil - return - end - @tile_id = @page.graphic.tile_id - @character_name = @page.graphic.character_name - @character_hue = @page.graphic.character_hue - if @original_direction != @page.graphic.direction - @direction = @page.graphic.direction - @original_direction = @direction - @prelock_direction = 0 - end - if @original_pattern != @page.graphic.pattern - @pattern = @page.graphic.pattern - @original_pattern = @pattern - end - @opacity = @page.graphic.opacity - @blend_type = @page.graphic.blend_type - @move_type = @page.move_type - self.move_speed = @page.move_speed - self.move_frequency = @page.move_frequency - @move_route = (@route_erased) ? RPG::MoveRoute.new : @page.move_route - @move_route_index = 0 - @move_route_forcing = false - @walk_anime = @page.walk_anime - @step_anime = @page.step_anime - @direction_fix = @page.direction_fix - @through = @page.through - @always_on_top = @page.always_on_top - calculate_bush_depth - @trigger = @page.trigger - @list = @page.list - @interpreter = nil - if @trigger == 4 # Parallel Process - @interpreter = Interpreter.new - end - check_event_trigger_auto - end - - def should_update?(recalc=false) - return @to_update if !recalc - return true if @trigger && (@trigger == 3 || @trigger == 4) - return true if @move_route_forcing - return true if @event.name[/update/i] - range = 2 # Number of tiles - return false if self.screen_x - @sprite_size[0]/2 > Graphics.width + range * Game_Map::TILE_WIDTH - return false if self.screen_x + @sprite_size[0]/2 < -range * Game_Map::TILE_WIDTH - return false if self.screen_y_ground - @sprite_size[1] > Graphics.height + range * Game_Map::TILE_HEIGHT - return false if self.screen_y_ground < -range * Game_Map::TILE_HEIGHT - return true - end - - def update - @to_update = should_update?(true) - return if !@to_update - last_moving = moving? - super - if !moving? && last_moving - $game_player.pbCheckEventTriggerFromDistance([2]) - end - if @need_refresh - @need_refresh = false - refresh - end - check_event_trigger_auto - if @interpreter != nil - unless @interpreter.running? - @interpreter.setup(@list, @event.id, @map_id) - end - @interpreter.update - end - end -end diff --git a/Data/Scripts/004_Game classes/009_Game_Player.rb b/Data/Scripts/004_Game classes/009_Game_Player.rb deleted file mode 100644 index b94ebcf87..000000000 --- a/Data/Scripts/004_Game classes/009_Game_Player.rb +++ /dev/null @@ -1,447 +0,0 @@ -#=============================================================================== -# ** Game_Player -#------------------------------------------------------------------------------- -# This class handles the player. Its functions include event starting -# determinants and map scrolling. Refer to "$game_player" for the one -# instance of this class. -#=============================================================================== -class Game_Player < Game_Character - attr_accessor :bump_se - attr_accessor :charsetData - attr_accessor :encounter_count - attr_accessor :x - attr_accessor :y - - SCREEN_CENTER_X = (Settings::SCREEN_WIDTH / 2 - Game_Map::TILE_WIDTH / 2) * Game_Map::X_SUBPIXELS - SCREEN_CENTER_Y = (Settings::SCREEN_HEIGHT / 2 - Game_Map::TILE_HEIGHT / 2) * Game_Map::Y_SUBPIXELS - - def initialize(*arg) - super(*arg) - @lastdir=0 - @lastdirframe=0 - @bump_se=0 - end - - def map - @map = nil - return $game_map - end - - def pbHasDependentEvents? - return $PokemonGlobal.dependentEvents.length>0 - end - - def bump_into_object - return if @bump_se && @bump_se>0 - pbSEPlay("Player bump") - @bump_se = Graphics.frame_rate/2 - end - - def move_generic(dir, turn_enabled = true) - turn_generic(dir, true) if turn_enabled - if !$PokemonTemp.encounterTriggered - if can_move_in_direction?(dir) - x_offset = (dir == 4) ? -1 : (dir == 6) ? 1 : 0 - y_offset = (dir == 8) ? -1 : (dir == 2) ? 1 : 0 - return if pbLedge(x_offset, y_offset) - return if pbEndSurf(x_offset, y_offset) - turn_generic(dir, true) - if !$PokemonTemp.encounterTriggered - @x += x_offset - @y += y_offset - $PokemonTemp.dependentEvents.pbMoveDependentEvents - increase_steps - end - elsif !check_event_trigger_touch(dir) - bump_into_object - end - end - $PokemonTemp.encounterTriggered = false - end - - def turn_generic(dir, keep_enc_indicator = false) - old_direction = @direction - super(dir) - if @direction != old_direction && !@move_route_forcing && !pbMapInterpreterRunning? - Events.onChangeDirection.trigger(self, self) - $PokemonTemp.encounterTriggered = false if !keep_enc_indicator - end - end - - def pbTriggeredTrainerEvents(triggers,checkIfRunning=true) - result = [] - # If event is running - return result if checkIfRunning && $game_system.map_interpreter.running? - # All event loops - for event in $game_map.events.values - next if !event.name[/trainer\((\d+)\)/i] - distance = $~[1].to_i - # If event coordinates and triggers are consistent - if pbEventCanReachPlayer?(event,self,distance) && triggers.include?(event.trigger) - # If starting determinant is front event (other than jumping) - result.push(event) if !event.jumping? && !event.over_trigger? - end - end - return result - end - - def pbTriggeredCounterEvents(triggers,checkIfRunning=true) - result = [] - # If event is running - return result if checkIfRunning && $game_system.map_interpreter.running? - # All event loops - for event in $game_map.events.values - next if !event.name[/counter\((\d+)\)/i] - distance = $~[1].to_i - # If event coordinates and triggers are consistent - if pbEventFacesPlayer?(event,self,distance) && triggers.include?(event.trigger) - # If starting determinant is front event (other than jumping) - result.push(event) if !event.jumping? && !event.over_trigger? - end - end - return result - end - - def pbCheckEventTriggerAfterTurning; end - - def pbCheckEventTriggerFromDistance(triggers) - ret = pbTriggeredTrainerEvents(triggers) - ret.concat(pbTriggeredCounterEvents(triggers)) - return false if ret.length==0 - for event in ret - event.start - end - return true - end - - def pbTerrainTag(countBridge = false) - return $MapFactory.getTerrainTag(self.map.map_id, @x, @y, countBridge) if $MapFactory - return $game_map.terrain_tag(@x, @y, countBridge) - end - - def pbFacingEvent(ignoreInterpreter=false) - return nil if $game_system.map_interpreter.running? && !ignoreInterpreter - # Check the tile in front of the player for events - new_x = @x + (@direction == 6 ? 1 : @direction == 4 ? -1 : 0) - new_y = @y + (@direction == 2 ? 1 : @direction == 8 ? -1 : 0) - - return nil if !$game_map.valid?(new_x, new_y) - - for event in $game_map.events.values - next if !event.at_coordinate?(new_x, new_y) - next if event.jumping? || event.over_trigger? - return event - end - # If the tile in front is a counter, check one tile beyond that for events - if $game_map.counter?(new_x, new_y) - new_x += (@direction == 6 ? 1 : @direction == 4 ? -1 : 0) - new_y += (@direction == 2 ? 1 : @direction == 8 ? -1 : 0) - for event in $game_map.events.values - next if !event.at_coordinate?(new_x, new_y) - next if event.jumping? || event.over_trigger? - return event - end - end - return nil - end - - - - #----------------------------------------------------------------------------- - # * Passable Determinants - # x : x-coordinate - # y : y-coordinate - # d : direction (0,2,4,6,8) - # * 0 = Determines if all directions are impassable (for jumping) - #----------------------------------------------------------------------------- - def passable?(x, y, d, strict = false) - # Get new coordinates - new_x = x + (d == 6 ? 1 : d == 4 ? -1 : 0) - new_y = y + (d == 2 ? 1 : d == 8 ? -1 : 0) - # If coordinates are outside of map - return false if !$game_map.validLax?(new_x, new_y) - if !$game_map.valid?(new_x, new_y) - return false if !$MapFactory - return $MapFactory.isPassableFromEdge?(new_x, new_y) - end - # If debug mode is ON and Ctrl key was pressed - return true if $DEBUG && Input.press?(Input::CTRL) - return super - end - - #----------------------------------------------------------------------------- - # * Set Map Display Position to Center of Screen - #----------------------------------------------------------------------------- - def center(x, y) - self.map.display_x = x * Game_Map::REAL_RES_X - SCREEN_CENTER_X - self.map.display_y = y * Game_Map::REAL_RES_Y - SCREEN_CENTER_Y - end - - - def isCentered() - x_centered = self.map.display_x == x * Game_Map::REAL_RES_X - SCREEN_CENTER_X - y_centered = self.map.display_y == y * Game_Map::REAL_RES_Y - SCREEN_CENTER_Y - return x_centered && y_centered - end - #----------------------------------------------------------------------------- - # * Move to Designated Position - # x : x-coordinate - # y : y-coordinate - #----------------------------------------------------------------------------- - def moveto(x, y) - super - # Centering - center(x, y) - # Make encounter count - make_encounter_count - end - - #----------------------------------------------------------------------------- - # * Make Encounter Count - #----------------------------------------------------------------------------- - def make_encounter_count - # Image of two dice rolling - if $game_map.map_id != 0 - n = $game_map.encounter_step - @encounter_count = rand(n) + rand(n) + 1 - end - end - - #----------------------------------------------------------------------------- - # * Refresh - #----------------------------------------------------------------------------- - def refresh - @opacity = 255 - @blend_type = 0 - end - - #----------------------------------------------------------------------------- - # * Trigger event(s) at the same coordinates as self with the appropriate - # trigger(s) that can be triggered - #----------------------------------------------------------------------------- - def check_event_trigger_here(triggers) - result = false - # If event is running - return result if $game_system.map_interpreter.running? - # All event loops - for event in $game_map.events.values - # If event coordinates and triggers are consistent - next if !event.at_coordinate?(@x, @y) - next if !triggers.include?(event.trigger) - # If starting determinant is same position event (other than jumping) - next if event.jumping? || !event.over_trigger? - event.start - result = true - end - return result - end - - #----------------------------------------------------------------------------- - # * Front Event Starting Determinant - #----------------------------------------------------------------------------- - def check_event_trigger_there(triggers) - result = false - # If event is running - return result if $game_system.map_interpreter.running? - # Calculate front event coordinates - new_x = @x + (@direction == 6 ? 1 : @direction == 4 ? -1 : 0) - new_y = @y + (@direction == 2 ? 1 : @direction == 8 ? -1 : 0) - return false if !$game_map.valid?(new_x, new_y) - # All event loops - for event in $game_map.events.values - # If event coordinates and triggers are consistent - next if !event.at_coordinate?(new_x, new_y) - next if !triggers.include?(event.trigger) - # If starting determinant is front event (other than jumping) - next if event.jumping? || event.over_trigger? - event.start - result = true - end - # If fitting event is not found - if result == false - # If front tile is a counter - if $game_map.counter?(new_x, new_y) - # Calculate coordinates of 1 tile further away - new_x += (@direction == 6 ? 1 : @direction == 4 ? -1 : 0) - new_y += (@direction == 2 ? 1 : @direction == 8 ? -1 : 0) - return false if !$game_map.valid?(new_x, new_y) - # All event loops - for event in $game_map.events.values - # If event coordinates and triggers are consistent - next if !event.at_coordinate?(new_x, new_y) - next if !triggers.include?(event.trigger) - # If starting determinant is front event (other than jumping) - next if event.jumping? || event.over_trigger? - event.start - result = true - end - end - end - return result - end - - #----------------------------------------------------------------------------- - # * Touch Event Starting Determinant - #----------------------------------------------------------------------------- - def check_event_trigger_touch(dir) - result = false - return result if $game_system.map_interpreter.running? - # All event loops - x_offset = (dir == 4) ? -1 : (dir == 6) ? 1 : 0 - y_offset = (dir == 8) ? -1 : (dir == 2) ? 1 : 0 - for event in $game_map.events.values - next if ![1, 2].include?(event.trigger) # Player touch, event touch - # If event coordinates and triggers are consistent - next if !event.at_coordinate?(@x + x_offset, @y + y_offset) - if event.name[/trainer\((\d+)\)/i] - distance = $~[1].to_i - next if !pbEventCanReachPlayer?(event,self,distance) - elsif event.name[/counter\((\d+)\)/i] - distance = $~[1].to_i - next if !pbEventFacesPlayer?(event,self,distance) - end - # If starting determinant is front event (other than jumping) - next if event.jumping? || event.over_trigger? - event.start - result = true - end - return result - end - - #----------------------------------------------------------------------------- - # * Frame Update - #----------------------------------------------------------------------------- - def update - last_real_x = @real_x - last_real_y = @real_y - super - update_screen_position(last_real_x, last_real_y) - # Update dependent events - $PokemonTemp.dependentEvents.updateDependentEvents - # Count down the time between allowed bump sounds - @bump_se -= 1 if @bump_se && @bump_se>0 - # Finish up dismounting from surfing - if $PokemonTemp.endSurf && !moving? - pbCancelVehicles - $PokemonTemp.surfJump = nil - $PokemonTemp.endSurf = false - end - update_event_triggering - end - - def update_command_new - dir = Input.dir4 - unless pbMapInterpreterRunning? || $game_temp.message_window_showing || - $PokemonTemp.miniupdate || $game_temp.in_menu - # Move player in the direction the directional button is being pressed - if @moved_last_frame || - (dir > 0 && dir == @lastdir && Graphics.frame_count - @lastdirframe > Graphics.frame_rate / 20) - case dir - when 2 then move_down - when 4 then move_left - when 6 then move_right - when 8 then move_up - end - elsif dir != @lastdir - case dir - when 2 then turn_down - when 4 then turn_left - when 6 then turn_right - when 8 then turn_up - end - end - end - # Record last direction input - @lastdirframe = Graphics.frame_count if dir != @lastdir - @lastdir = dir - end - - # Center player on-screen - def update_screen_position(last_real_x, last_real_y) - return if self.map.scrolling? || !(@moved_last_frame || @moved_this_frame) - self.map.display_x = @real_x - SCREEN_CENTER_X - self.map.display_y = @real_y - SCREEN_CENTER_Y - end - - def update_event_triggering - return if moving? - # Try triggering events upon walking into them/in front of them - if @moved_this_frame - $PokemonTemp.dependentEvents.pbTurnDependentEvents - result = pbCheckEventTriggerFromDistance([2]) - # Event determinant is via touch of same position event - result |= check_event_trigger_here([1,2]) - # No events triggered, try other event triggers upon finishing a step - pbOnStepTaken(result) - end - # Try to manually interact with events - if Input.trigger?(Input::USE) && !$PokemonTemp.miniupdate - # Same position and front event determinant - check_event_trigger_here([0]) - check_event_trigger_there([0,2]) - end - end -end - - - -def pbGetPlayerCharset(meta,charset,trainer=nil,force=false) - trainer = $Trainer if !trainer - outfit = (trainer) ? trainer.outfit : 0 - if $game_player && $game_player.charsetData && !force - return nil if $game_player.charsetData[0] == $Trainer.character_ID && - $game_player.charsetData[1] == charset && - $game_player.charsetData[2] == outfit - end - $game_player.charsetData = [$Trainer.character_ID,charset,outfit] if $game_player - ret = meta[charset] - ret = meta[1] if nil_or_empty?(ret) - # if pbResolveBitmap("Graphics/Characters/player/"+ret+"_"+outfit.to_s) - # ret = ret+"_"+outfit.to_s - # end - return ret -end - -def pbUpdateVehicle - meta = GameData::Metadata.get_player($Trainer.character_ID) - if meta - charset = 1 # Regular graphic - if $PokemonGlobal.diving; charset = 5 # Diving graphic - elsif $PokemonGlobal.surfing; charset = 3 # Surfing graphic - elsif $PokemonGlobal.bicycle; charset = 2 # Bicycle graphic - end - newCharName = pbGetPlayerCharset(meta,charset) - $game_player.character_name = newCharName if newCharName - end -end - -def pbCancelVehicles(destination=nil) - $PokemonGlobal.surfing = false - $PokemonGlobal.diving = false - $PokemonGlobal.bicycle = false if !destination || !pbCanUseBike?(destination) - pbUpdateVehicle -end - -def pbCanUseBike?(map_id) - map_metadata = GameData::MapMetadata.try_get(map_id) - return false if !map_metadata - return true if map_metadata.always_bicycle - val = map_metadata.can_bicycle || map_metadata.outdoor_map - return (val) ? true : false -end - -def pbMountBike - return if $PokemonGlobal.bicycle - $PokemonGlobal.bicycle = true - pbUpdateVehicle - bike_bgm = GameData::Metadata.get.bicycle_BGM - pbCueBGM(bike_bgm, 0.5) if bike_bgm - pbPokeRadarCancel -end - -def pbDismountBike - return if !$PokemonGlobal.bicycle - $PokemonGlobal.bicycle = false - pbUpdateVehicle - $game_map.autoplayAsCue -end diff --git a/Data/Scripts/004_Game classes/010_Game_Player_Visuals.rb b/Data/Scripts/004_Game classes/010_Game_Player_Visuals.rb deleted file mode 100644 index dc11a491d..000000000 --- a/Data/Scripts/004_Game classes/010_Game_Player_Visuals.rb +++ /dev/null @@ -1,126 +0,0 @@ -class Game_Player < Game_Character - @@bobFrameSpeed = 1.0/15 - - def fullPattern - case self.direction - when 2 then return self.pattern - when 4 then return self.pattern + 4 - when 6 then return self.pattern + 8 - when 8 then return self.pattern + 12 - end - return 0 - end - - def setDefaultCharName(chname,pattern,lockpattern=false) - return if pattern<0 || pattern>=16 - @defaultCharacterName = chname - @direction = [2,4,6,8][pattern/4] - @pattern = pattern%4 - @lock_pattern = lockpattern - end - - def pbCanRun? - return false if $game_temp.in_menu || $game_temp.in_battle || - @move_route_forcing || $game_temp.message_window_showing || - pbMapInterpreterRunning? - input = ($PokemonSystem.runstyle == 1) ^ Input.press?(Input::ACTION) - return input && $Trainer.has_running_shoes && !jumping? && - !$PokemonGlobal.diving && !$PokemonGlobal.surfing && - !$PokemonGlobal.bicycle && !$game_player.pbTerrainTag.must_walk - end - - def pbIsRunning? - return moving? && !@move_route_forcing && pbCanRun? - end - - def character_name - @defaultCharacterName = "" if !@defaultCharacterName - return @defaultCharacterName if @defaultCharacterName!="" - if !@move_route_forcing && $Trainer.character_ID>=0 - meta = GameData::Metadata.get_player($Trainer.character_ID) - if meta && !$PokemonGlobal.bicycle && !$PokemonGlobal.diving && !$PokemonGlobal.surfing - charset = 1 # Display normal character sprite - - - player_is_moving = moving? - if pbCanRun? && (player_is_moving || @wasmoving) && Input.dir4!=0 && meta[4] && meta[4]!="" - charset = 4 # Display running character sprite - end - - newCharName = pbGetPlayerCharset(meta,charset) - - if newCharName - # echoln caller - # echoln newCharName - # echoln "moving: " + moving?.to_s - # echoln "was moving: " + @wasmoving.to_s - # - # echoln "can run: " + pbCanRun?.to_s - # echoln "Input.dir4 " + Input.dir4.to_s - # - # - # echoln (moving? || @wasmoving) - # echoln charset - # echoln "" - end - - - - - @character_name = newCharName if newCharName - @wasmoving = player_is_moving - end - end - return @character_name - end - - def update_command - self.move_speed = 0.5 if $game_switches[SWITCH_SUPER_SLOW_SPEED] - if $game_player.pbTerrainTag.ice - self.move_speed = 4 # Sliding on ice - elsif !moving? && !@move_route_forcing && $PokemonGlobal - if $PokemonGlobal.bicycle - self.move_speed = $game_switches[SWITCH_RACE_BIKE] && !Input.press?(Input::ACTION) ? 5.5 : 5 # Cycling - elsif pbCanRun? || $PokemonGlobal.surfing - self.move_speed = 4 # Running, surfing - else - self.move_speed = 3 # Walking, diving - end - end - super - end - - def update_pattern - if $PokemonGlobal.surfing || $PokemonGlobal.diving - p = ((Graphics.frame_count%60)*@@bobFrameSpeed).floor - @pattern = p if !@lock_pattern - @pattern_surf = p - @bob_height = (p>=2) ? 2 : 0 - else - @bob_height = 0 - super - end - end -end - - -=begin -class Game_Character - alias update_old2 update - - def update - if self.is_a?(Game_Event) - if @dependentEvents - for i in 0...@dependentEvents.length - if @dependentEvents[i][0]==$game_map.map_id && - @dependentEvents[i][1]==self.id - self.move_speed_real = $game_player.move_speed_real - break - end - end - end - end - update_old2 - end -end -=end diff --git a/Data/Scripts/004_Game classes/011_Game_CommonEvent.rb b/Data/Scripts/004_Game classes/011_Game_CommonEvent.rb deleted file mode 100644 index 194f61519..000000000 --- a/Data/Scripts/004_Game classes/011_Game_CommonEvent.rb +++ /dev/null @@ -1,82 +0,0 @@ -#=============================================================================== -# ** Game_CommonEvent -#------------------------------------------------------------------------------- -# This class handles common events. It includes execution of parallel process -# event. This class is used within the Game_Map class ($game_map). -#=============================================================================== -class Game_CommonEvent - #----------------------------------------------------------------------------- - # * Object Initialization - # common_event_id : common event ID - #----------------------------------------------------------------------------- - def initialize(common_event_id) - @common_event_id = common_event_id - - @interpreter = nil - refresh - end - #----------------------------------------------------------------------------- - # * Get Name - #----------------------------------------------------------------------------- - def name - return $data_common_events[@common_event_id].name - end - #----------------------------------------------------------------------------- - # * Get Trigger - #----------------------------------------------------------------------------- - def trigger - return $data_common_events[@common_event_id].trigger - end - #----------------------------------------------------------------------------- - # * Get Condition Switch ID - #----------------------------------------------------------------------------- - def switch_id - return $data_common_events[@common_event_id].switch_id - end - #----------------------------------------------------------------------------- - # * Get List of Event Commands - #----------------------------------------------------------------------------- - def list - return $data_common_events[@common_event_id].list - end - #----------------------------------------------------------------------------- - # * Checks if switch is on - #----------------------------------------------------------------------------- - def switchIsOn?(id) - switchName = $data_system.switches[id] - return false if !switchName - if switchName[/^s\:/] - return eval($~.post_match) - else - return $game_switches[id] - end - end - #----------------------------------------------------------------------------- - # * Refresh - #----------------------------------------------------------------------------- - def refresh - # Create an interpreter for parallel process if necessary - if self.trigger == 2 && switchIsOn?(self.switch_id) - if @interpreter == nil - @interpreter = Interpreter.new - end - else - @interpreter = nil - end - end - #----------------------------------------------------------------------------- - # * Frame Update - #----------------------------------------------------------------------------- - def update - # If parallel process is valid - if @interpreter != nil - # If not running - unless @interpreter.running? - # Set up event - @interpreter.setup(self.list, 0) - end - # Update interpreter - @interpreter.update - end - end -end diff --git a/Data/Scripts/004_Game classes/012_Game_DependentEvents.rb b/Data/Scripts/004_Game classes/012_Game_DependentEvents.rb deleted file mode 100644 index 10dfb0cf3..000000000 --- a/Data/Scripts/004_Game classes/012_Game_DependentEvents.rb +++ /dev/null @@ -1,588 +0,0 @@ -class PokemonTemp - attr_writer :dependentEvents - - def dependentEvents - @dependentEvents = DependentEvents.new if !@dependentEvents - return @dependentEvents - end -end - - - -def pbRemoveDependencies() - $PokemonTemp.dependentEvents.removeAllEvents() - pbDeregisterPartner() rescue nil -end - -def pbAddDependency(event,follows=true) - $PokemonTemp.dependentEvents.addEvent(event) - $PokemonTemp.dependentEvents.follows_player = follows -end - -def pbRemoveDependency(event) - $PokemonTemp.dependentEvents.removeEvent(event) -end - -def pbAddDependency2(eventID, eventName, commonEvent) - $PokemonTemp.dependentEvents.addEvent($game_map.events[eventID],eventName,commonEvent) -end - -# Gets the Game_Character object associated with a dependent event. -def pbGetDependency(eventName) - return $PokemonTemp.dependentEvents.getEventByName(eventName) -end - -def pbRemoveDependency2(eventName) - $PokemonTemp.dependentEvents.removeEventByName(eventName) -end - - - -class PokemonGlobalMetadata - attr_writer :dependentEvents - - def dependentEvents - @dependentEvents = [] if !@dependentEvents - return @dependentEvents - end -end - - - -def pbTestPass(follower,x,y,_direction=nil) - return $MapFactory.isPassableStrict?(follower.map.map_id,x,y,follower) -end - -# Same map only -def moveThrough(follower,direction) - oldThrough=follower.through - follower.through=true - case direction - when 2 then follower.move_down - when 4 then follower.move_left - when 6 then follower.move_right - when 8 then follower.move_up - end - follower.through=oldThrough -end - -# Same map only -def moveFancy(follower,direction) - deltaX=(direction == 6 ? 1 : (direction == 4 ? -1 : 0)) - deltaY=(direction == 2 ? 1 : (direction == 8 ? -1 : 0)) - newX = follower.x + deltaX - newY = follower.y + deltaY - # Move if new position is the player's, or the new position is passable, - # or the current position is not passable - if ($game_player.x==newX && $game_player.y==newY) || - pbTestPass(follower,newX,newY,0) || - !pbTestPass(follower,follower.x,follower.y,0) - oldThrough=follower.through - follower.through=true - case direction - when 2 then follower.move_down - when 4 then follower.move_left - when 6 then follower.move_right - when 8 then follower.move_up - end - follower.through=oldThrough - end -end - -# Same map only -def jumpFancy(follower,direction,leader) - deltaX=(direction == 6 ? 2 : (direction == 4 ? -2 : 0)) - deltaY=(direction == 2 ? 2 : (direction == 8 ? -2 : 0)) - halfDeltaX=(direction == 6 ? 1 : (direction == 4 ? -1 : 0)) - halfDeltaY=(direction == 2 ? 1 : (direction == 8 ? -1 : 0)) - middle=pbTestPass(follower,follower.x+halfDeltaX,follower.y+halfDeltaY,0) - ending=pbTestPass(follower,follower.x+deltaX, follower.y+deltaY, 0) - if middle - moveFancy(follower,direction) - moveFancy(follower,direction) - elsif ending - if pbTestPass(follower,follower.x,follower.y,0) - if leader.jumping? - follower.jump_speed_real = leader.jump_speed_real * Graphics.frame_rate / 40.0 - else - follower.jump_speed_real = leader.move_speed_real * Graphics.frame_rate / 20.0 - end - follower.jump(deltaX,deltaY) - else - moveThrough(follower,direction) - moveThrough(follower,direction) - end - end -end - -def pbFancyMoveTo(follower,newX,newY,leader) - if follower.x-newX==-1 && follower.y==newY - moveFancy(follower,6) - elsif follower.x-newX==1 && follower.y==newY - moveFancy(follower,4) - elsif follower.y-newY==-1 && follower.x==newX - moveFancy(follower,2) - elsif follower.y-newY==1 && follower.x==newX - moveFancy(follower,8) - elsif follower.x-newX==-2 && follower.y==newY - jumpFancy(follower,6,leader) - elsif follower.x-newX==2 && follower.y==newY - jumpFancy(follower,4,leader) - elsif follower.y-newY==-2 && follower.x==newX - jumpFancy(follower,2,leader) - elsif follower.y-newY==2 && follower.x==newX - jumpFancy(follower,8,leader) - elsif follower.x!=newX || follower.y!=newY - follower.moveto(newX,newY) - end -end - - - -class DependentEvents - attr_reader :lastUpdate - attr_reader :realEvents - attr_writer :follows_player - - def createEvent(eventData) - rpgEvent = RPG::Event.new(eventData[3],eventData[4]) - rpgEvent.id = eventData[1] - if eventData[9] - # Must setup common event list here and now - commonEvent = Game_CommonEvent.new(eventData[9]) - rpgEvent.pages[0].list = commonEvent.list - end - newEvent = Game_Event.new(eventData[0],rpgEvent,$MapFactory.getMap(eventData[2])) - newEvent.character_name = eventData[6] - newEvent.character_hue = eventData[7] - case eventData[5] # direction - when 2 then newEvent.turn_down - when 4 then newEvent.turn_left - when 6 then newEvent.turn_right - when 8 then newEvent.turn_up - end - return newEvent - end - - def initialize - # Original map, Event ID, Current map, X, Y, Direction - events=$PokemonGlobal.dependentEvents - @realEvents=[] - @lastUpdate=-1 - for event in events - @realEvents.push(createEvent(event)) - end - @follows_player=true - end - - def pbEnsureEvent(event, newMapID) - events=$PokemonGlobal.dependentEvents - for i in 0...events.length - # Check original map ID and original event ID - if events[i][0]==event.map_id && events[i][1]==event.id - # Change current map ID - events[i][2]=newMapID - newEvent=createEvent(events[i]) - # Replace event - @realEvents[i]=newEvent - @lastUpdate+=1 - return i - end - end - return -1 - end - - def pbFollowEventAcrossMaps(leader,follower,instant=false,leaderIsTrueLeader=true) - d=leader.direction - areConnected=$MapFactory.areConnected?(leader.map.map_id,follower.map.map_id) - # Get the rear facing tile of leader - facingDirection=10-d - if !leaderIsTrueLeader && areConnected - relativePos=$MapFactory.getThisAndOtherEventRelativePos(leader,follower) - # Assumes leader and follower are both 1x1 tile in size - if (relativePos[1]==0 && relativePos[0]==2) # 2 spaces to the right of leader - facingDirection=6 - elsif (relativePos[1]==0 && relativePos[0]==-2) # 2 spaces to the left of leader - facingDirection=4 - elsif relativePos[1]==-2 && relativePos[0]==0 # 2 spaces above leader - facingDirection=8 - elsif relativePos[1]==2 && relativePos[0]==0 # 2 spaces below leader - facingDirection=2 - end - end - facings=[facingDirection] # Get facing from behind -# facings.push([0,0,4,0,8,0,2,0,6][d]) # Get right facing -# facings.push([0,0,6,0,2,0,8,0,4][d]) # Get left facing - if !leaderIsTrueLeader - facings.push(d) # Get forward facing - end - mapTile=nil - - if areConnected - bestRelativePos=-1 - oldthrough=follower.through - follower.through=false - for i in 0...facings.length - facing=facings[i] - tile=$MapFactory.getFacingTile(facing,leader) - # Assumes leader is 1x1 tile in size - passable=tile && $MapFactory.isPassableStrict?(tile[0],tile[1],tile[2],follower) - if i==0 && !passable && tile && - $MapFactory.getTerrainTag(tile[0],tile[1],tile[2]).ledge - # If the tile isn't passable and the tile is a ledge, - # get tile from further behind - tile=$MapFactory.getFacingTileFromPos(tile[0],tile[1],tile[2],facing) - passable=tile && $MapFactory.isPassableStrict?(tile[0],tile[1],tile[2],follower) - end - if passable - relativePos=$MapFactory.getThisAndOtherPosRelativePos( - follower,tile[0],tile[1],tile[2]) - # Assumes follower is 1x1 tile in size - distance=Math.sqrt(relativePos[0]*relativePos[0]+relativePos[1]*relativePos[1]) - if bestRelativePos==-1 || bestRelativePos>distance - bestRelativePos=distance - mapTile=tile - end - if i==0 && distance<=1 # Prefer behind if tile can move up to 1 space - break - end - end - end - follower.through=oldthrough - else - tile=$MapFactory.getFacingTile(facings[0],leader) - # Assumes leader is 1x1 tile in size - passable=tile && $MapFactory.isPassableStrict?(tile[0],tile[1],tile[2],follower) - mapTile=passable ? mapTile : nil - end - if mapTile && follower.map.map_id==mapTile[0] - return if !@follows_player - # Follower is on same map - newX=mapTile[1] - newY=mapTile[2] - deltaX=(d == 6 ? -1 : d == 4 ? 1 : 0) - deltaY=(d == 2 ? -1 : d == 8 ? 1 : 0) - posX = newX + deltaX - posY = newY + deltaY - - # if !@follows_player - # posX=follower.original_x - # posY=follower.original_y - # - # end - - follower.move_speed=leader.move_speed # sync movespeed - if (follower.x-newX==-1 && follower.y==newY) || - (follower.x-newX==1 && follower.y==newY) || - (follower.y-newY==-1 && follower.x==newX) || - (follower.y-newY==1 && follower.x==newX) - if instant - follower.moveto(newX,newY) - else - pbFancyMoveTo(follower,newX,newY,leader) - end - elsif (follower.x-newX==-2 && follower.y==newY) || - (follower.x-newX==2 && follower.y==newY) || - (follower.y-newY==-2 && follower.x==newX) || - (follower.y-newY==2 && follower.x==newX) - if instant - follower.moveto(newX,newY) - else - pbFancyMoveTo(follower,newX,newY,leader) - end - elsif follower.x!=posX || follower.y!=posY - if instant - follower.moveto(newX,newY) - else - pbFancyMoveTo(follower,posX,posY,leader) - pbFancyMoveTo(follower,newX,newY,leader) - end - end - else - if !mapTile - # Make current position into leader's position - mapTile=[leader.map.map_id,leader.x,leader.y] - end - if follower.map.map_id==mapTile[0] - # Follower is on same map as leader - follower.moveto(leader.x,leader.y) - else - # Follower will move to different map - events=$PokemonGlobal.dependentEvents - eventIndex=pbEnsureEvent(follower,mapTile[0]) - if eventIndex>=0 - newFollower=@realEvents[eventIndex] - newEventData=events[eventIndex] - newFollower.moveto(mapTile[1],mapTile[2]) - newEventData[3]=mapTile[1] - newEventData[4]=mapTile[2] - end - end - end - end - - def debugEcho - self.eachEvent { |e,d| - echoln d - echoln [e.map_id,e.map.map_id,e.id] - } - end - - def pbMapChangeMoveDependentEvents - events=$PokemonGlobal.dependentEvents - updateDependentEvents - leader=$game_player - for i in 0...events.length - event=@realEvents[i] - pbFollowEventAcrossMaps(leader,event,true,i==0) - # Update X and Y for this event - events[i][3]=event.x - events[i][4]=event.y - events[i][5]=event.direction - # Set leader to this event - leader=event - end - end - - def pbMoveDependentEvents - events=$PokemonGlobal.dependentEvents - updateDependentEvents - leader=$game_player - for i in 0...events.length - event=@realEvents[i] - if !@follows_player - pbRemoveDependencies if leader.map.map_id != event.map.map_id - pbFollowEventAcrossMaps(leader,event,false,i==0) - events[i][3]=event.original_x - events[i][4]=event.original_y - else - pbFollowEventAcrossMaps(leader,event,false,i==0) - # Update X and Y for this event - events[i][3]=event.x - events[i][4]=event.y - events[i][5]=event.direction - # Set leader to this event - leader=event - end - end - end - - def pbTurnDependentEvents - events=$PokemonGlobal.dependentEvents - updateDependentEvents - leader=$game_player - for i in 0...events.length - event=@realEvents[i] - pbTurnTowardEvent(event,leader) - # Update direction for this event - events[i][5]=event.direction - # Set leader to this event - leader=event - end - end - - def eachEvent - events=$PokemonGlobal.dependentEvents - for i in 0...events.length - yield @realEvents[i],events[i] - end - end - - def updateDependentEvents - events=$PokemonGlobal.dependentEvents - return if events.length==0 - for i in 0...events.length - break if !@follows_player - - event=@realEvents[i] - next if !@realEvents[i] - event.transparent=$game_player.transparent - if event.jumping? || event.moving? || - !($game_player.jumping? || $game_player.moving?) - event.update - elsif !event.starting - event.set_starting - event.update - event.clear_starting - end - events[i][3]=event.x - events[i][4]=event.y - events[i][5]=event.direction - end - # Check event triggers - # - if Input.trigger?(Input::USE) && !$game_temp.in_menu && !$game_temp.in_battle && - !$game_player.move_route_forcing && !$game_temp.message_window_showing && - !pbMapInterpreterRunning? - # Get position of tile facing the player - facingTile=$MapFactory.getFacingTile() - # Assumes player is 1x1 tile in size - self.eachEvent { |e,d| - next if !d[9] - if e.at_coordinate?($game_player.x, $game_player.y) - # On same position - if !e.jumping? && (!e.respond_to?("over_trigger") || e.over_trigger?) - if e.list.size>1 - # Start event - $game_map.refresh if $game_map.need_refresh - e.lock - pbMapInterpreter.setup(e.list,e.id,e.map.map_id) - end - end - elsif facingTile && e.map.map_id==facingTile[0] && - e.at_coordinate?(facingTile[1], facingTile[2]) - # On facing tile - if !e.jumping? && (!e.respond_to?("over_trigger") || !e.over_trigger?) - if e.list.size>1 - # Start event - $game_map.refresh if $game_map.need_refresh - e.lock - pbMapInterpreter.setup(e.list,e.id,e.map.map_id) - end - end - end - } - end - end - - def removeEvent(event) - events=$PokemonGlobal.dependentEvents - mapid=$game_map.map_id - for i in 0...events.length - if events[i][2]==mapid && # Refer to current map - events[i][0]==event.map_id && # Event's map ID is original ID - events[i][1]==event.id - events[i]=nil - @realEvents[i]=nil - @lastUpdate+=1 - end - end - events.compact! - @realEvents.compact! - end - - def getEventByName(name) - events=$PokemonGlobal.dependentEvents - for i in 0...events.length - if events[i] && events[i][8]==name # Arbitrary name given to dependent event - return @realEvents[i] - end - end - return nil - end - - def removeAllEvents - events=$PokemonGlobal.dependentEvents - events.clear - @realEvents.clear - @lastUpdate+=1 - end - - def removeEventByName(name) - events=$PokemonGlobal.dependentEvents - for i in 0...events.length - if events[i] && events[i][8]==name # Arbitrary name given to dependent event - events[i]=nil - @realEvents[i]=nil - @lastUpdate+=1 - end - end - events.compact! - @realEvents.compact! - end - - def addEvent(event,eventName=nil,commonEvent=nil) - return if !event - events=$PokemonGlobal.dependentEvents - - - for i in 0...events.length - if events[i] && events[i][0]==$game_map.map_id && events[i][1]==event.id - # Already exists - return - end - end - # Original map ID, original event ID, current map ID, - # event X, event Y, event direction, - # event's filename, - # event's hue, event's name, common event ID - eventData=[ - $game_map.map_id,event.id,$game_map.map_id, - event.x,event.y,event.direction, - event.character_name.clone, - event.character_hue,eventName,commonEvent - ] - newEvent=createEvent(eventData) - events.push(eventData) - @realEvents.push(newEvent) - @lastUpdate+=1 - event.erase - end -end - - - -class DependentEventSprites - def initialize(viewport,map) - @disposed=false - @sprites=[] - @map=map - @viewport=viewport - refresh - @lastUpdate=nil - end - - def refresh - for sprite in @sprites - sprite.dispose - end - @sprites.clear - $PokemonTemp.dependentEvents.eachEvent { |event,data| - if data[0]==@map.map_id # Check original map - @map.events[data[1]].erase - end - if data[2]==@map.map_id # Check current map - @sprites.push(Sprite_Character.new(@viewport,event)) - end - } - end - - def update - if $PokemonTemp.dependentEvents.lastUpdate!=@lastUpdate - refresh - @lastUpdate=$PokemonTemp.dependentEvents.lastUpdate - end - for sprite in @sprites - sprite.update - end - end - - def dispose - return if @disposed - for sprite in @sprites - sprite.dispose - end - @sprites.clear - @disposed=true - end - - def disposed? - @disposed - end -end - - - -Events.onSpritesetCreate += proc { |_sender,e| - spriteset = e[0] # Spriteset being created - viewport = e[1] # Viewport used for tilemap and characters - map = spriteset.map # Map associated with the spriteset (not necessarily the current map) - spriteset.addUserSprite(DependentEventSprites.new(viewport,map)) -} - -Events.onMapSceneChange += proc { |_sender,e| - mapChanged = e[1] - if mapChanged - $PokemonTemp.dependentEvents.pbMapChangeMoveDependentEvents - end -} diff --git a/Data/Scripts/005_Map renderer/001_Tilemap_XP.rb b/Data/Scripts/005_Map renderer/001_Tilemap_XP.rb deleted file mode 100644 index 5f197cacf..000000000 --- a/Data/Scripts/005_Map renderer/001_Tilemap_XP.rb +++ /dev/null @@ -1,921 +0,0 @@ -#=============================================================================== -# -#=============================================================================== -class CustomTilemapAutotiles - attr_accessor :changed - - def initialize - @changed = true - @tiles = [nil,nil,nil,nil,nil,nil,nil] - end - - def [](i) - return @tiles[i] - end - - def []=(i,value) - @tiles[i] = value - @changed = true - end -end - - - -#Console::setup_console -class CustomTilemapSprite < Sprite -end - - - -#=============================================================================== -# -#=============================================================================== -class CustomTilemap - attr_reader :tileset - attr_reader :autotiles - attr_reader :map_data - attr_reader :flash_data - attr_reader :priorities - attr_reader :terrain_tags - attr_reader :visible - attr_reader :viewport - attr_reader :graphicsWidth - attr_reader :graphicsHeight - attr_reader :ox - attr_reader :oy - attr_accessor :tone - attr_accessor :color - - Autotiles = [ - [ [27, 28, 33, 34], [ 5, 28, 33, 34], [27, 6, 33, 34], [ 5, 6, 33, 34], - [27, 28, 33, 12], [ 5, 28, 33, 12], [27, 6, 33, 12], [ 5, 6, 33, 12] ], - [ [27, 28, 11, 34], [ 5, 28, 11, 34], [27, 6, 11, 34], [ 5, 6, 11, 34], - [27, 28, 11, 12], [ 5, 28, 11, 12], [27, 6, 11, 12], [ 5, 6, 11, 12] ], - [ [25, 26, 31, 32], [25, 6, 31, 32], [25, 26, 31, 12], [25, 6, 31, 12], - [15, 16, 21, 22], [15, 16, 21, 12], [15, 16, 11, 22], [15, 16, 11, 12] ], - [ [29, 30, 35, 36], [29, 30, 11, 36], [ 5, 30, 35, 36], [ 5, 30, 11, 36], - [39, 40, 45, 46], [ 5, 40, 45, 46], [39, 6, 45, 46], [ 5, 6, 45, 46] ], - [ [25, 30, 31, 36], [15, 16, 45, 46], [13, 14, 19, 20], [13, 14, 19, 12], - [17, 18, 23, 24], [17, 18, 11, 24], [41, 42, 47, 48], [ 5, 42, 47, 48] ], - [ [37, 38, 43, 44], [37, 6, 43, 44], [13, 18, 19, 24], [13, 14, 43, 44], - [37, 42, 43, 48], [17, 18, 47, 48], [13, 18, 43, 48], [ 1, 2, 7, 8] ] - ] - Animated_Autotiles_Frames = 5*Graphics.frame_rate/20 # Frequency of updating animated autotiles - FlashOpacity = [100,90,80,70,80,90] - - def initialize(viewport) - @tileset = nil # Refers to Map Tileset Name - @autotiles = CustomTilemapAutotiles.new - @map_data = nil # Refers to 3D Array Of Tile Settings - @flash_data = nil # Refers to 3D Array of Tile Flashdata - @priorities = nil # Refers to Tileset Priorities - @terrain_tags = nil # Refers to Tileset Terrain Tags - @visible = true # Refers to Tileset Visibleness - @ox = 0 # Bitmap Offsets - @oy = 0 # Bitmap Offsets - @plane = false - @haveGraphicsWH = (Graphics.width!=nil rescue false) - if @haveGraphicsWH - @graphicsWidth = Graphics.width - @graphicsHeight = Graphics.height - else - @graphicsWidth = 640 - @graphicsHeight = 480 - end - @tileWidth = Game_Map::TILE_WIDTH rescue 32 - @tileHeight = Game_Map::TILE_HEIGHT rescue 32 - @tileSrcWidth = 32 - @tileSrcHeight = 32 - @diffsizes = (@tileWidth!=@tileSrcWidth) || (@tileHeight!=@tileSrcHeight) - @tone = Tone.new(0,0,0,0) - @oldtone = Tone.new(0,0,0,0) - @color = Color.new(0,0,0,0) - @oldcolor = Color.new(0,0,0,0) - @selfviewport = Viewport.new(0,0,graphicsWidth,graphicsHeight) - @viewport = (viewport) ? viewport : @selfviewport - @tiles = [] - @autotileInfo = [] - @regularTileInfo = [] - @oldOx = 0 - @oldOy = 0 - @oldViewportOx = 0 - @oldViewportOy = 0 - @layer0 = CustomTilemapSprite.new(viewport) - @layer0.visible = true - @nowshown = false - @layer0.bitmap = Bitmap.new([graphicsWidth+320,1].max,[graphicsHeight+320,1].max) - @layer0.z = 0 - @layer0.ox = 0 - @layer0.oy = 0 - @oxLayer0 = 0 - @oyLayer0 = 0 - @flash = nil - @oxFlash = 0 - @oyFlash = 0 - @priotiles = {} - @priotilesfast = [] - @prioautotiles = {} - @autosprites = [] - @framecount = [0,0,0,0,0,0,0,0] # For autotiles - @tilesetChanged = true - @flashChanged = false - @firsttime = true - @disposed = false - @usedsprites = false - @layer0clip = true - @firsttimeflash = true - @fullyrefreshed = false - @fullyrefreshedautos = false - end - - def dispose - return if disposed? - @help.dispose if @help - @help = nil - i = 0; len = @autotileInfo.length - while i=xsize - xEnd = (@ox+@viewport.rect.width)/@tileWidth + 1 - xEnd = 0 if xEnd<0 - xEnd = xsize-1 if xEnd>=xsize - return false if xStart>=xEnd - ysize = @map_data.ysize - yStart = @oy/@tileHeight - 1 - yStart = 0 if yStart<0 - yStart = ysize-1 if yStart>=ysize - yEnd = (@oy+@viewport.rect.height)/@tileHeight + 1 - yEnd = 0 if yEnd<0 - yEnd = ysize-1 if yEnd>=ysize - return false if yStart>=yEnd - return true - end - - def autotileNumFrames(id) - autotile = @autotiles[id/48-1] - return 0 if !autotile || autotile.disposed? - frames = 1 - if autotile.height==@tileHeight - frames = autotile.width/@tileWidth - else - frames = autotile.width/(3*@tileWidth) - end - return frames - end - - def autotileFrame(id) - autotile = @autotiles[id/48-1] - return -1 if !autotile || autotile.disposed? - frames = 1 - if autotile.height==@tileHeight - frames = autotile.width/@tileWidth - else - frames = autotile.width/(3*@tileWidth) - end - return (Graphics.frame_count/Animated_Autotiles_Frames)%frames - end - - def repaintAutotiles - for i in 0...@autotileInfo.length - next if !@autotileInfo[i] - frame = autotileFrame(i) - @autotileInfo[i].clear - bltAutotile(@autotileInfo[i],0,0,i,frame) - end - end - - def bltAutotile(bitmap,x,y,id,frame) - return if frame<0 - autotile = @autotiles[id/48-1] - return if !autotile || autotile.disposed? - if autotile.height==@tileSrcHeight - anim = frame*@tileSrcWidth - src_rect = Rect.new(anim,0,@tileSrcWidth,@tileSrcHeight) - if @diffsizes - bitmap.stretch_blt(Rect.new(x,y,@tileWidth,@tileHeight),autotile,src_rect) - else - bitmap.blt(x,y,autotile,src_rect) - end - else - anim = frame*3*@tileSrcWidth - id %= 48 - tiles = Autotiles[id>>3][id&7] - src = Rect.new(0,0,0,0) - halfTileWidth = @tileWidth>>1 - halfTileHeight = @tileHeight>>1 - halfTileSrcWidth = @tileSrcWidth>>1 - halfTileSrcHeight = @tileSrcHeight>>1 - for i in 0...4 - tile_position = tiles[i] - 1 - src.set( (tile_position % 6)*halfTileSrcWidth + anim, - (tile_position / 6)*halfTileSrcHeight, halfTileSrcWidth, halfTileSrcHeight) - if @diffsizes - bitmap.stretch_blt( - Rect.new(i%2*halfTileWidth+x,i/2*halfTileHeight+y,halfTileWidth,halfTileHeight), - autotile,src) - else - bitmap.blt(i%2*halfTileWidth+x,i/2*halfTileHeight+y, autotile, src) - end - end - end - end - - def getAutotile(sprite,id) - frames = @framecount[id/48-1] - if frames<=1 - anim = 0 - else - anim = (Graphics.frame_count/Animated_Autotiles_Frames)%frames - end - return if anim<0 - bitmap = @autotileInfo[id] - if !bitmap - bitmap = Bitmap.new(@tileWidth,@tileHeight) - bltAutotile(bitmap,0,0,id,anim) - @autotileInfo[id] = bitmap - end - sprite.bitmap = bitmap if sprite.bitmap!=bitmap - end - - def getRegularTile(sprite,id) - if @diffsizes - bitmap = @regularTileInfo[id] - if !bitmap - bitmap = Bitmap.new(@tileWidth,@tileHeight) - rect = Rect.new(((id - 384)&7)*@tileSrcWidth,((id - 384)>>3)*@tileSrcHeight, - @tileSrcWidth,@tileSrcHeight) - bitmap.stretch_blt(Rect.new(0,0,@tileWidth,@tileHeight),@tileset,rect) - @regularTileInfo[id] = bitmap - end - sprite.bitmap = bitmap if sprite.bitmap!=bitmap - else - sprite.bitmap = @tileset if sprite.bitmap!=@tileset - sprite.src_rect.set(((id - 384)&7)*@tileSrcWidth,((id - 384)>>3)*@tileSrcHeight, - @tileSrcWidth,@tileSrcHeight) - end - end - - def addTile(tiles,count,xpos,ypos,id) - terrain = @terrain_tags[id] - priority = @priorities[id] - if id >= 384 # Tileset tile - if count>=tiles.length - sprite = CustomTilemapSprite.new(@viewport) - tiles.push(sprite,0) - else - sprite = tiles[count] - tiles[count+1] = 0 - end - sprite.visible = @visible - sprite.x = xpos - sprite.y = ypos - sprite.tone = @tone - sprite.color = @color - getRegularTile(sprite,id) - else # Autotile - if count>=tiles.length - sprite = CustomTilemapSprite.new(@viewport) - tiles.push(sprite,1) - else - sprite = tiles[count] - tiles[count+1] = 1 - end - sprite.visible = @visible - sprite.x = xpos - sprite.y = ypos - sprite.tone = @tone - sprite.color = @color - getAutotile(sprite,id) - end - if PBTerrain.hasReflections?(terrain) - spriteZ = -100 - elsif $PokemonGlobal.bridge>0 && PBTerrain.isBridge?(terrain) - spriteZ = 1 - else - spriteZ = (priority==0) ? 0 : ypos+priority*32+32 - end - sprite.z = spriteZ - count += 2 - return count - end - - def refresh_flash - if @flash_data && !@flash - @flash = CustomTilemapSprite.new(viewport) - @flash.visible = true - @flash.z = 1 - @flash.tone = tone - @flash.color = color - @flash.blend_type = 1 - @flash.bitmap = Bitmap.new([graphicsWidth*2,1].max,[graphicsHeight*2,1].max) - @firsttimeflash = true - elsif !@flash_data && @flash - @flash.bitmap.dispose if @flash.bitmap - @flash.dispose - @flash = nil - @firsttimeflash = false - end - end - - def refreshFlashSprite - return if !@flash || @flash_data.nil? - ptX = @ox-@oxFlash - ptY = @oy-@oyFlash - if !@firsttimeflash && !@usedsprites && - ptX>=0 && ptX+@viewport.rect.width<=@flash.bitmap.width && - ptY>=0 && ptY+@viewport.rect.height<=@flash.bitmap.height - @flash.ox = 0 - @flash.oy = 0 - @flash.src_rect.set(ptX.round,ptY.round, - @viewport.rect.width,@viewport.rect.height) - return - end - width = @flash.bitmap.width - height = @flash.bitmap.height - bitmap = @flash.bitmap - ysize = @map_data.ysize - xsize = @map_data.xsize - @firsttimeflash = false - @oxFlash = @ox-(width>>2) - @oyFlash = @oy-(height>>2) - @flash.ox = 0 - @flash.oy = 0 - @flash.src_rect.set(width>>2,height>>2, - @viewport.rect.width,@viewport.rect.height) - @flash.bitmap.clear - @oxFlash = @oxFlash.floor - @oyFlash = @oyFlash.floor - xStart = @oxFlash/@tileWidth - xStart = 0 if xStart<0 - yStart = @oyFlash/@tileHeight - yStart = 0 if yStart<0 - xEnd = xStart+(width/@tileWidth)+1 - yEnd = yStart+(height/@tileHeight)+1 - xEnd = xsize if xEnd>=xsize - yEnd = ysize if yEnd>=ysize - if xStart>8)&15 - g = (id>>4)&15 - b = (id)&15 - tmpcolor.set(r<<4,g<<4,b<<4) - bitmap.fill_rect(xpos,ypos,@tileWidth,@tileHeight,tmpcolor) - end - end - end - end - - def refresh_tileset - i = 0 - len = @regularTileInfo.length - while i < len - if @regularTileInfo[i] - @regularTileInfo[i].dispose - @regularTileInfo[i] = nil - end - i += 1 - end - @regularTileInfo.clear - @priotiles.clear - ysize = @map_data.ysize - xsize = @map_data.xsize - zsize = @map_data.zsize - if xsize > 100 || ysize > 100 - @fullyrefreshed = false - else - for z in 0...zsize - for y in 0...ysize - for x in 0...xsize - id = @map_data[x, y, z] - next if id == 0 - next if @priorities[id] == 0 && !PBTerrain.hasReflections?(@terrain_tags[id]) - @priotiles[[x, y]] = [] if !@priotiles[[x, y]] - @priotiles[[x, y]].push([z, id]) - end - end - end - @fullyrefreshed = true - end - end - - def refresh_autotiles - i = 0 - len = @autotileInfo.length - while i < len - if @autotileInfo[i] - @autotileInfo[i].dispose - @autotileInfo[i] = nil - end - i += 1 - end - i = 0 - len = @autosprites.length - while i < len - if @autosprites[i] - @autosprites[i].dispose - @autosprites[i] = nil - end - i += 2 - end - @autosprites.clear - @autotileInfo.clear - @prioautotiles.clear - @priorect = nil - @priorectautos = nil - hasanimated = false - for i in 0...7 - numframes = autotileNumFrames(48 * (i + 1)) - hasanimated = true if numframes >= 2 - @framecount[i] = numframes - end - if hasanimated - ysize = @map_data.ysize - xsize = @map_data.xsize - zsize = @map_data.zsize - if xsize > 100 || ysize > 100 - @fullyrefreshedautos = false - else - for y in 0...ysize - for x in 0...xsize - for z in 0...zsize - id = @map_data[x, y, z] - next if id == 0 || id >= 384 # Skip non-autotiles - next if @priorities[id] != 0 || PBTerrain.hasReflections?(@terrain_tags[id]) - next if @framecount[id / 48 - 1] < 2 - @prioautotiles[[x, y]] = true - break - end - end - end - @fullyrefreshedautos = true - end - else - @fullyrefreshedautos = true - end - end - - def refreshLayer0(autotiles = false) - return true if autotiles && !shown? - ptX = @ox - @oxLayer0 - ptY = @oy - @oyLayer0 - if !autotiles && !@firsttime && !@usedsprites && - ptX >= 0 && ptX + @viewport.rect.width <= @layer0.bitmap.width && - ptY >= 0 && ptY + @viewport.rect.height <= @layer0.bitmap.height - if @layer0clip && @viewport.ox == 0 && @viewport.oy == 0 - @layer0.ox = 0 - @layer0.oy = 0 - @layer0.src_rect.set(ptX.round, ptY.round, @viewport.rect.width, @viewport.rect.height) - else - @layer0.ox = ptX.round - @layer0.oy = ptY.round - @layer0.src_rect.set(0, 0, @layer0.bitmap.width, @layer0.bitmap.height) - end - return true - end - width = @layer0.bitmap.width - height = @layer0.bitmap.height - bitmap = @layer0.bitmap - ysize = @map_data.ysize - xsize = @map_data.xsize - zsize = @map_data.zsize - twidth = @tileWidth - theight = @tileHeight - mapdata = @map_data - if autotiles - return true if @fullyrefreshedautos && @prioautotiles.length == 0 - xStart = @oxLayer0 / twidth - xStart = 0 if xStart < 0 - yStart = @oyLayer0 / theight - yStart = 0 if yStart < 0 - xEnd = xStart + (width / twidth) + 1 - xEnd = xsize if xEnd > xsize - yEnd = yStart + (height / theight) + 1 - yEnd = ysize if yEnd > ysize - return true if xStart >= xEnd || yStart >= yEnd - trans = Color.new(0, 0, 0, 0) - temprect = Rect.new(0, 0, 0, 0) - tilerect = Rect.new(0, 0, twidth, theight) - zrange = 0...zsize - overallcount = 0 - count = 0 - if !@fullyrefreshedautos - for y in yStart..yEnd - for x in xStart..xEnd - for z in zrange - id = mapdata[x, y, z] - next if !id || id < 48 || id >= 384 # Skip non-autotiles - prioid = @priorities[id] - next if prioid != 0 || PBTerrain.hasReflections?(@terrain_tags[id]) - fcount = @framecount[id / 48 - 1] - next if !fcount || fcount < 2 - overallcount += 1 - xpos = (x * twidth) - @oxLayer0 - ypos = (y * theight) - @oyLayer0 - bitmap.fill_rect(xpos, ypos, twidth, theight, trans) if overallcount <= 2000 - break - end - for z in zrange - id = mapdata[x, y, z] - next if !id || id < 48 - prioid = @priorities[id] - next if prioid != 0 || PBTerrain.hasReflections?(@terrain_tags[id]) - if overallcount > 2000 - xpos = (x * twidth) - @oxLayer0 - ypos = (y * theight) - @oyLayer0 - count = addTile(@autosprites, count, xpos, ypos, id) - elsif id >= 384 # Tileset tiles - temprect.set(((id - 384) & 7) * @tileSrcWidth, - ((id - 384) >> 3) * @tileSrcHeight, - @tileSrcWidth, @tileSrcHeight) - xpos = (x * twidth) - @oxLayer0 - ypos = (y * theight) - @oyLayer0 - if @diffsizes - bitmap.stretch_blt(Rect.new(xpos, ypos, twidth, theight), @tileset, temprect) - else - bitmap.blt(xpos, ypos, @tileset, temprect) - end - else # Autotiles - tilebitmap = @autotileInfo[id] - if !tilebitmap - anim = autotileFrame(id) - next if anim < 0 - tilebitmap = Bitmap.new(twidth, theight) - bltAutotile(tilebitmap, 0, 0, id, anim) - @autotileInfo[id] = tilebitmap - end - xpos = (x * twidth) - @oxLayer0 - ypos = (y * theight) - @oyLayer0 - bitmap.blt(xpos, ypos, tilebitmap, tilerect) - end - end - end - end - Graphics.frame_reset - else - if !@priorect || !@priorectautos || - @priorect[0] != xStart || @priorect[1] != yStart || - @priorect[2] != xEnd || @priorect[3] != yEnd - @priorect = [xStart, yStart, xEnd, yEnd] - @priorectautos = [] - for y in yStart..yEnd - for x in xStart..xEnd - @priorectautos.push([x, y]) if @prioautotiles[[x, y]] - end - end - end - for tile in @priorectautos - x = tile[0] - y = tile[1] - overallcount += 1 - xpos = (x * twidth) - @oxLayer0 - ypos = (y * theight) - @oyLayer0 - bitmap.fill_rect(xpos, ypos, twidth, theight, trans) - z = 0 - while z < zsize - id = mapdata[x, y, z] - z += 1 - next if !id || id < 48 - prioid = @priorities[id] - next if prioid != 0 || PBTerrain.hasReflections?(@terrain_tags[id]) - if id >= 384 # Tileset tiles - temprect.set(((id - 384) & 7) * @tileSrcWidth, - ((id - 384) >> 3) * @tileSrcHeight, - @tileSrcWidth, @tileSrcHeight) - if @diffsizes - bitmap.stretch_blt(Rect.new(xpos, ypos, twidth, theight), @tileset, temprect) - else - bitmap.blt(xpos, ypos, @tileset, temprect) - end - else # Autotiles - tilebitmap = @autotileInfo[id] - if !tilebitmap - anim = autotileFrame(id) - next if anim < 0 - tilebitmap = Bitmap.new(twidth, theight) - bltAutotile(tilebitmap, 0, 0, id, anim) - @autotileInfo[id] = tilebitmap - end - bitmap.blt(xpos, ypos, tilebitmap, tilerect) - end - end - end - Graphics.frame_reset if overallcount > 500 - end - @usedsprites = false - return true - end - return false if @usedsprites - @firsttime = false - @oxLayer0 = @ox - (width >> 2) - @oyLayer0 = @oy - (height >> 2) - if @layer0clip - @layer0.ox = 0 - @layer0.oy = 0 - @layer0.src_rect.set(width >> 2, height >> 2, @viewport.rect.width, @viewport.rect.height) - else - @layer0.ox = (width >> 2) - @layer0.oy = (height >> 2) - end - @layer0.bitmap.clear - @oxLayer0 = @oxLayer0.round - @oyLayer0 = @oyLayer0.round - xStart = @oxLayer0 / twidth - xStart = 0 if xStart < 0 - yStart = @oyLayer0 / theight - yStart = 0 if yStart < 0 - xEnd = xStart + (width / twidth) + 1 - xEnd = xsize if xEnd >= xsize - yEnd = yStart + (height / theight) + 1 - yEnd = ysize if yEnd >= ysize - if xStart < xEnd && yStart < yEnd - tmprect = Rect.new(0, 0, 0, 0) - yrange = yStart...yEnd - xrange = xStart...xEnd - for z in 0...zsize - for y in yrange - ypos = (y * theight) - @oyLayer0 - for x in xrange - xpos = (x * twidth) - @oxLayer0 - id = mapdata[x, y, z] - next if id == 0 || @priorities[id] != 0 || PBTerrain.hasReflections?(@terrain_tags[id]) - if id >= 384 # Tileset tiles - tmprect.set(((id - 384) & 7) * @tileSrcWidth, - ((id - 384) >> 3) * @tileSrcHeight, - @tileSrcWidth, @tileSrcHeight) - if @diffsizes - bitmap.stretch_blt(Rect.new(xpos, ypos, twidth, theight), @tileset, tmprect) - else - bitmap.blt(xpos, ypos, @tileset, tmprect) - end - else # Autotiles - frames = @framecount[id / 48 - 1] - if frames <= 1 - frame = 0 - else - frame = (Graphics.frame_count / Animated_Autotiles_Frames) % frames - end - bltAutotile(bitmap, xpos, ypos, id, frame) - end - end - end - end - Graphics.frame_reset - end - return true - end - - def refresh(autotiles = false) - @oldOx = @ox - @oldOy = @oy - usesprites = false - if @layer0 - @layer0.visible = @visible - usesprites = !refreshLayer0(autotiles) - return if autotiles && !usesprites - else - usesprites = true - end - refreshFlashSprite - xsize = @map_data.xsize - ysize = @map_data.ysize - minX = (@ox / @tileWidth) - 1 - minX.clamp(0, xsize - 1) - maxX = ((@ox + @viewport.rect.width) / @tileWidth) + 1 - maxX.clamp(0, xsize - 1) - minY = (@oy / @tileHeight) - 1 - minY.clamp(0, ysize - 1) - maxY = ((@oy + @viewport.rect.height) / @tileHeight) + 1 - maxY.clamp(0, ysize - 1) - count = 0 - if minX < maxX && minY < maxY - @usedsprites = usesprites || @usedsprites - @layer0.visible = false if usesprites && @layer0 - if !@priotilesrect || !@priotilesfast || - @priotilesrect[0] != minX || @priotilesrect[1] != minY || - @priotilesrect[2] != maxX || @priotilesrect[3] != maxY - @priotilesrect = [minX, minY, maxX, maxY] - @priotilesfast = [] - if @fullyrefreshed - for y in minY..maxY - for x in minX..maxX - next if !@priotiles[[x, y]] - @priotiles[[x, y]].each { |tile| @priotilesfast.push([x, y, tile[0], tile[1]]) } - end - end - else - for z in 0...@map_data.zsize - for y in minY..maxY - for x in minX..maxX - id = @map_data[x, y, z] - next if id == 0 - next if @priorities[id] == 0 && !PBTerrain.hasReflections?(@terrain_tags[id]) - @priotilesfast.push([x, y, z, id]) - end - end - end - end - end - for prio in @priotilesfast - xpos = (prio[0] * @tileWidth) - @ox - ypos = (prio[1] * @tileHeight) - @oy - count = addTile(@tiles, count, xpos, ypos, prio[3]) - end - end - if count < @tiles.length - bigchange = (count <= (@tiles.length * 2 / 3)) && @tiles.length > 40 - j = count - len = @tiles.length - while j < len - sprite = @tiles[j] - @tiles[j + 1] = -1 - if bigchange - sprite.dispose - @tiles[j] = nil - @tiles[j + 1] = nil - elsif !@tiles[j].disposed? - sprite.visible = false if sprite.visible - end - j += 2 - end - @tiles.compact! if bigchange - end - end - - def update - if @haveGraphicsWH - @graphicsWidth = Graphics.width - @graphicsHeight = Graphics.height - end - # Update tone - if @oldtone != @tone - @layer0.tone = @tone - @flash.tone = @tone if @flash - for sprite in @autosprites - sprite.tone = @tone if sprite.is_a?(Sprite) - end - for sprite in @tiles - sprite.tone = @tone if sprite.is_a?(Sprite) - end - @oldtone = @tone.clone - end - # Update color - if @oldcolor != @color - @layer0.color = @color - @flash.color = @color if @flash - for sprite in @autosprites - sprite.color = @color if sprite.is_a?(Sprite) - end - for sprite in @tiles - sprite.color = @color if sprite.is_a?(Sprite) - end - @oldcolor = @color.clone - end - # Refresh anything that has changed - if @autotiles.changed - refresh_autotiles - repaintAutotiles - end - refresh_flash if @flashChanged - refresh_tileset if @tilesetChanged - @flash.opacity = FlashOpacity[(Graphics.frame_count / 2) % 6] if @flash - mustrefresh = (@oldOx != @ox || @oldOy != @oy || @tilesetChanged || @autotiles.changed) - if @viewport.ox != @oldViewportOx || @viewport.oy != @oldViewportOy - mustrefresh = true - @oldViewportOx = @viewport.ox - @oldViewportOy = @viewport.oy - end - refresh if mustrefresh - if (Graphics.frame_count % Animated_Autotiles_Frames) == 0 || @nowshown - repaintAutotiles - refresh(true) - end - @nowshown = false - @autotiles.changed = false - @tilesetChanged = false - end -end diff --git a/Data/Scripts/005_Sprites/001_Sprite_Picture.rb b/Data/Scripts/005_Sprites/001_Sprite_Picture.rb deleted file mode 100644 index 47ed370eb..000000000 --- a/Data/Scripts/005_Sprites/001_Sprite_Picture.rb +++ /dev/null @@ -1,58 +0,0 @@ -class Sprite_Picture - def initialize(viewport, picture) - @viewport = viewport - @picture = picture - @sprite = nil - update - end - - def dispose - @sprite.dispose if @sprite - end - - def update - @sprite.update if @sprite - # If picture file name is different from current one - if @picture_name != @picture.name - # Remember file name to instance variables - @picture_name = @picture.name - # If file name is not empty - if @picture_name != "" - # Get picture graphic - @sprite=IconSprite.new(0,0,@viewport) if !@sprite - @sprite.setBitmap("Graphics/Pictures/"+@picture_name) - end - end - # If file name is empty - if @picture_name == "" - # Set sprite to invisible - if @sprite - @sprite.dispose if @sprite - @sprite=nil - end - return - end - # Set sprite to visible - @sprite.visible = true - # Set transfer starting point - if @picture.origin == 0 - @sprite.ox = 0 - @sprite.oy = 0 - else - @sprite.ox = @sprite.bitmap.width / 2 - @sprite.oy = @sprite.bitmap.height / 2 - end - # Set sprite coordinates - @sprite.x = @picture.x - @sprite.y = @picture.y - @sprite.z = @picture.number - # Set zoom rate, opacity level, and blend method - @sprite.zoom_x = @picture.zoom_x / 100.0 - @sprite.zoom_y = @picture.zoom_y / 100.0 - @sprite.opacity = @picture.opacity - @sprite.blend_type = @picture.blend_type - # Set rotation angle and color tone - @sprite.angle = @picture.angle - @sprite.tone = @picture.tone - end -end diff --git a/Data/Scripts/005_Sprites/002_Sprite_Timer.rb b/Data/Scripts/005_Sprites/002_Sprite_Timer.rb deleted file mode 100644 index 4e5b26274..000000000 --- a/Data/Scripts/005_Sprites/002_Sprite_Timer.rb +++ /dev/null @@ -1,45 +0,0 @@ -class Sprite_Timer - def initialize(viewport=nil) - @viewport=viewport - @timer=nil - @total_sec=nil - @disposed=false - end - - def dispose - @timer.dispose if @timer - @timer=nil - @disposed=true - end - - def disposed? - @disposed - end - - def update - return if disposed? - if $game_system.timer_working - @timer.visible = true if @timer - if !@timer - @timer=Window_AdvancedTextPokemon.newWithSize("",Graphics.width-120,0,120,64) - @timer.width=@timer.borderX+96 - @timer.x=Graphics.width-@timer.width - @timer.viewport=@viewport - @timer.z=99998 - end - curtime=$game_system.timer / Graphics.frame_rate - curtime=0 if curtime<0 - if curtime != @total_sec - # Calculate total number of seconds - @total_sec = curtime - # Make a string for displaying the timer - min = @total_sec / 60 - sec = @total_sec % 60 - @timer.text = _ISPRINTF("{1:02d}:{2:02d}", min, sec) - end - @timer.update - else - @timer.visible=false if @timer - end - end -end diff --git a/Data/Scripts/005_Sprites/003_Sprite_Character.rb b/Data/Scripts/005_Sprites/003_Sprite_Character.rb deleted file mode 100644 index bc49eabd6..000000000 --- a/Data/Scripts/005_Sprites/003_Sprite_Character.rb +++ /dev/null @@ -1,264 +0,0 @@ -class BushBitmap - def initialize(bitmap, isTile, depth) - @bitmaps = [] - @bitmap = bitmap - @isTile = isTile - @isBitmap = @bitmap.is_a?(Bitmap) - @depth = depth - @manual_refresh = false - end - - def dispose - @bitmaps.each { |b| b.dispose if b } - end - - def bitmap - thisBitmap = (@isBitmap) ? @bitmap : @bitmap.bitmap - current = (@isBitmap) ? 0 : @bitmap.currentIndex - if !@bitmaps[current] - if @isTile - @bitmaps[current] = pbBushDepthTile(thisBitmap, @depth) - else - @bitmaps[current] = pbBushDepthBitmap(thisBitmap, @depth) - end - end - return @bitmaps[current] - end - - def pbBushDepthBitmap(bitmap, depth) - ret = Bitmap.new(bitmap.width, bitmap.height) - charheight = ret.height / 4 - cy = charheight - depth - 2 - for i in 0...4 - y = i * charheight - if cy >= 0 - ret.blt(0, y, bitmap, Rect.new(0, y, ret.width, cy)) - ret.blt(0, y + cy, bitmap, Rect.new(0, y + cy, ret.width, 2), 170) - end - ret.blt(0, y + cy + 2, bitmap, Rect.new(0, y + cy + 2, ret.width, 2), 85) if cy + 2 >= 0 - end - return ret - end - - def pbBushDepthTile(bitmap, depth) - ret = Bitmap.new(bitmap.width, bitmap.height) - charheight = ret.height - cy = charheight - depth - 2 - y = charheight - if cy >= 0 - ret.blt(0, y, bitmap, Rect.new(0, y, ret.width, cy)) - ret.blt(0, y + cy, bitmap, Rect.new(0, y + cy, ret.width, 2), 170) - end - ret.blt(0, y + cy + 2, bitmap, Rect.new(0, y + cy + 2, ret.width, 2), 85) if cy + 2 >= 0 - return ret - end -end - -def event_is_trainer(event) - return $game_map.events[event.id] && event.name[/trainer\((\d+)\)/i] -end - -class Sprite_Character < RPG::Sprite - attr_accessor :character - attr_accessor :pending_bitmap - attr_accessor :bitmap_override - attr_accessor :charbitmap - - def initialize(viewport, character = nil) - super(viewport) - @character = character - if darknessEffectOnCurrentMap() - if @character.is_a?(Game_Event) - $game_map.events[@character.id].erase if event_is_trainer(@character) - end - end - - @oldbushdepth = 0 - @spriteoffset = false - if !character || character == $game_player || (character.name[/reflection/i] rescue false) - @reflection = Sprite_Reflection.new(self, character, viewport) - end - @surfbase = Sprite_SurfBase.new(self, character, viewport) if character == $game_player - checkModifySpriteGraphics(@character) if @character - update - end - - def checkModifySpriteGraphics(character) - return if character == $game_player || !character.name - if TYPE_EXPERTS_APPEARANCES.keys.include?(character.name.to_sym) - typeExpert = character.name.to_sym - setSpriteToAppearance(TYPE_EXPERTS_APPEARANCES[typeExpert]) - end - end - - def setSpriteToAppearance(trainerAppearance) - #return if !@charbitmap || !@charbitmap.bitmap - begin - new_bitmap = AnimatedBitmap.new(getBaseOverworldSpriteFilename()) #@charbitmap - new_bitmap.bitmap = generateNPCClothedBitmapStatic(trainerAppearance) - @bitmap_override = new_bitmap - updateBitmap - rescue - end - end - - def clearBitmapOverride() - @bitmap_override = nil - updateBitmap - end - - def setSurfingPokemon(pokemonSpecies) - @surfingPokemon = pokemonSpecies - @surfbase.setPokemon(pokemonSpecies) if @surfbase - end - - def groundY - return @character.screen_y_ground - end - - def visible=(value) - super(value) - @reflection.visible = value if @reflection - end - - def dispose - @bushbitmap.dispose if @bushbitmap - @bushbitmap = nil - @charbitmap.dispose if @charbitmap - @charbitmap = nil - @reflection.dispose if @reflection - @reflection = nil - @surfbase.dispose if @surfbase - @surfbase = nil - super - end - - def updateBitmap - @manual_refresh = true - end - - def pbLoadOutfitBitmap(outfitFileName) - # Construct the file path for the outfit bitmap based on the given value - #outfitFileName = sprintf("Graphics/Outfits/%s", value) - - # Attempt to load the outfit bitmap - begin - outfitBitmap = RPG::Cache.load_bitmap("", outfitFileName) - return outfitBitmap - rescue - return nil - end - end - - def generateClothedBitmap() - return - end - - def applyDayNightTone() - if @character.is_a?(Game_Event) && @character.name[/regulartone/i] - self.tone.set(0, 0, 0, 0) - else - pbDayNightTint(self) - end - end - - def updateCharacterBitmap - AnimatedBitmap.new('Graphics/Characters/' + @character_name, @character_hue) - end - - def should_update? - return @tile_id != @character.tile_id || - @character_name != @character.character_name || - @character_hue != @character.character_hue || - @oldbushdepth != @character.bush_depth || - @manual_refresh - end - - def refreshOutfit() - self.pending_bitmap = getClothedPlayerSprite(true) - end - - def update - if self.pending_bitmap - self.bitmap = self.pending_bitmap - self.pending_bitmap = nil - end - return if @character.is_a?(Game_Event) && !@character.should_update? - super - if should_update? - @manual_refresh = false - @tile_id = @character.tile_id - @character_name = @character.character_name - @character_hue = @character.character_hue - @oldbushdepth = @character.bush_depth - if @tile_id >= 384 - @charbitmap.dispose if @charbitmap - @charbitmap = pbGetTileBitmap(@character.map.tileset_name, @tile_id, - @character_hue, @character.width, @character.height) - @charbitmapAnimated = false - @bushbitmap.dispose if @bushbitmap - @bushbitmap = nil - @spriteoffset = false - @cw = Game_Map::TILE_WIDTH * @character.width - @ch = Game_Map::TILE_HEIGHT * @character.height - self.src_rect.set(0, 0, @cw, @ch) - self.ox = @cw / 2 - self.oy = @ch - @character.sprite_size = [@cw, @ch] - else - @charbitmap.dispose if @charbitmap - - @charbitmap = updateCharacterBitmap() - @charbitmap = @bitmap_override.clone if @bitmap_override - - RPG::Cache.retain('Graphics/Characters/', @character_name, @character_hue) if @charbitmapAnimated = true - @bushbitmap.dispose if @bushbitmap - @bushbitmap = nil - #@spriteoffset = @character_name[/offset/i] - @spriteoffset = @character_name[/fish/i] || @character_name[/dive/i] || @character_name[/surf/i] - @cw = @charbitmap.width / 4 - @ch = @charbitmap.height / 4 - self.ox = @cw / 2 - @character.sprite_size = [@cw, @ch] - end - end - @charbitmap.update if @charbitmapAnimated - bushdepth = @character.bush_depth - if bushdepth == 0 - if @character == $game_player - self.bitmap = getClothedPlayerSprite() #generateClothedBitmap() - else - self.bitmap = (@charbitmapAnimated) ? @charbitmap.bitmap : @charbitmap - end - else - @bushbitmap = BushBitmap.new(@charbitmap, (@tile_id >= 384), bushdepth) if !@bushbitmap - self.bitmap = @bushbitmap.bitmap - end - self.visible = !@character.transparent - if @tile_id == 0 - sx = @character.pattern * @cw - sy = ((@character.direction - 2) / 2) * @ch - self.src_rect.set(sx, sy, @cw, @ch) - self.oy = (@spriteoffset rescue false) ? @ch - 16 : @ch - self.oy -= @character.bob_height - end - if self.visible - applyDayNightTone() - end - self.x = @character.screen_x - self.y = @character.screen_y - self.z = @character.screen_z(@ch) - # self.zoom_x = Game_Map::TILE_WIDTH / 32.0 - # self.zoom_y = Game_Map::TILE_HEIGHT / 32.0 - self.opacity = @character.opacity - self.blend_type = @character.blend_type - # self.bush_depth = @character.bush_depth - if @character.animation_id != 0 - animation = $data_animations[@character.animation_id] - animation(animation, true) - @character.animation_id = 0 - end - @reflection.update if @reflection - @surfbase.update if @surfbase - end -end diff --git a/Data/Scripts/005_Sprites/004_Sprite_Reflection.rb b/Data/Scripts/005_Sprites/004_Sprite_Reflection.rb deleted file mode 100644 index 615e7137b..000000000 --- a/Data/Scripts/005_Sprites/004_Sprite_Reflection.rb +++ /dev/null @@ -1,87 +0,0 @@ -class Sprite_Reflection - attr_reader :visible - attr_accessor :event - - def initialize(sprite,event,viewport=nil) - @rsprite = sprite - @sprite = nil - @event = event - @height = 0 - @fixedheight = false - if @event && @event!=$game_player - if @event.name[/reflection\((\d+)\)/i] - @height = $~[1].to_i || 0 - @fixedheight = true - end - end - @viewport = viewport - @disposed = false - update - end - - def dispose - if !@disposed - @sprite.dispose if @sprite - @sprite = nil - @disposed = true - end - end - - def disposed? - @disposed - end - - def visible=(value) - @visible = value - @sprite.visible = value if @sprite && !@sprite.disposed? - end - - def update - return - # return if disposed? - # shouldShow = @rsprite.visible - # if !shouldShow - # # Just-in-time disposal of sprite - # if @sprite - # @sprite.dispose - # @sprite = nil - # end - # return - # end - # # Just-in-time creation of sprite - # @sprite = Sprite.new(@viewport) if !@sprite - # if @sprite - # x = @rsprite.x-@rsprite.ox - # y = @rsprite.y-@rsprite.oy - # y -= 32 if @rsprite.character.character_name[/offset/i] - # @height = $PokemonGlobal.bridge if !@fixedheight - # y += @height*16 - # width = @rsprite.src_rect.width - # height = @rsprite.src_rect.height - # @sprite.x = x+width/2 - # @sprite.y = y+height+height/2 - # @sprite.ox = width/2 - # @sprite.oy = height/2-2 # Hard-coded 2 pixel shift up - # @sprite.oy -= @rsprite.character.bob_height*2 - # @sprite.z = -50 # Still water is -100, map is 0 and above - # @sprite.zoom_x = @rsprite.zoom_x - # @sprite.zoom_y = @rsprite.zoom_y - # frame = (Graphics.frame_count%40)/10 - # @sprite.zoom_x *= [1.0, 0.95, 1.0, 1.05][frame] - # @sprite.angle = 180.0 - # @sprite.mirror = true - # @sprite.bitmap = @rsprite.bitmap - # @sprite.tone = @rsprite.tone - # if @height>0 - # @sprite.color = Color.new(48,96,160,255) # Dark still water - # @sprite.opacity = @rsprite.opacity - # @sprite.visible = !Settings::TIME_SHADING # Can't time-tone a colored sprite - # else - # @sprite.color = Color.new(224,224,224,96) - # @sprite.opacity = @rsprite.opacity*3/4 - # @sprite.visible = true - # end - # @sprite.src_rect = @rsprite.src_rect - # end - end -end diff --git a/Data/Scripts/005_Sprites/005_Sprite_SurfBase.rb b/Data/Scripts/005_Sprites/005_Sprite_SurfBase.rb deleted file mode 100644 index cf2cb10ff..000000000 --- a/Data/Scripts/005_Sprites/005_Sprite_SurfBase.rb +++ /dev/null @@ -1,150 +0,0 @@ -class Sprite_SurfBase - attr_reader :visible - attr_accessor :event - - def initialize(sprite, event, viewport = nil) - @rsprite = sprite - @sprite = nil - @event = event - @viewport = viewport - @disposed = false - #@surfbitmap = AnimatedBitmap.new("Graphics/Characters/base_surf") - @surfbitmap = update_surf_bitmap(:SURF) - @divebitmap = update_surf_bitmap(:DIVE) - # RPG::Cache.retain("Graphics/Characters/base_surf") - # RPG::Cache.retain("Graphics/Characters/base_dive") - @cws = @surfbitmap.width / 4 - @chs = @surfbitmap.height / 4 - @cwd = @divebitmap.width / 4 - @chd = @divebitmap.height / 4 - update - end - - def dispose - return if @disposed - @sprite.dispose if @sprite - @sprite = nil - @surfbitmap.dispose - @divebitmap.dispose - @disposed = true - end - - def disposed? - @disposed - end - - def visible=(value) - @visible = value - @sprite.visible = value if @sprite && !@sprite.disposed? - end - - def update_surf_bitmap(type) - species = $Trainer.surfing_pokemon - path = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_SURFBASE_FOLDER + "surfmon_board" if type == :SURF - #path = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_SURFBASE_FOLDER + "divemon_scuba" if type == :DIVE - path = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_SURFBASE_FOLDER + "divemon_Head" if type == :DIVE - if species - shape = species.shape - basePath = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_SURFBASE_FOLDER - action = "divemon" if type == :DIVE - action = "surfmon" if type == :SURF - path = "#{basePath}#{action}_#{shape.to_s}" - end - return AnimatedBitmap.new(path) - end - - - # case species.shape - # when :Head - # path = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_SURFBASE_FOLDER + "divemon_Head" if type == :DIVE - # path = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_SURFBASE_FOLDER + "surfmon_Head" if type == :SURF - # when :Serpentine - # path = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_SURFBASE_FOLDER + "divemon_HeadBase" if type == :DIVE - # path = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_SURFBASE_FOLDER + "surfmon_HeadBase" if type == :SURF - # when :Finned - # path = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_SURFBASE_FOLDER + "divemon_HeadBase" if type == :DIVE - # path = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_SURFBASE_FOLDER + "surfmon_HeadBase" if type == :SURF - # when :HeadArms - # path = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_SURFBASE_FOLDER + "divemon_HeadBase" if type == :DIVE - # path = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_SURFBASE_FOLDER + "surfmon_HeadBase" if type == :SURF - # when :HeadBase - # path = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_SURFBASE_FOLDER + "divemon_HeadBase" if type == :DIVE - # path = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_SURFBASE_FOLDER + "surfmon_HeadBase" if type == :SURF - # when :BipedalTail - # path = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_SURFBASE_FOLDER + "divemon_HeadBase" if type == :DIVE - # path = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_SURFBASE_FOLDER + "surfmon_HeadBase" if type == :SURF - # when :HeadLegs - # path = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_SURFBASE_FOLDER + "divemon_HeadBase" if type == :DIVE - # path = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_SURFBASE_FOLDER + "surfmon_HeadBase" if type == :SURF - # when :Quadruped - # path = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_SURFBASE_FOLDER + "divemon_HeadBase" if type == :DIVE - # path = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_SURFBASE_FOLDER + "surfmon_HeadBase" if type == :SURF - # when :Winged - # path = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_SURFBASE_FOLDER + "divemon_HeadBase" if type == :DIVE - # path = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_SURFBASE_FOLDER + "surfmon_HeadBase" if type == :SURF - # when :Multiped - # path = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_SURFBASE_FOLDER + "divemon_HeadBase" if type == :DIVE - # path = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_SURFBASE_FOLDER + "surfmon_HeadBase" if type == :SURF - # when :MultiBody - # path = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_SURFBASE_FOLDER + "divemon_HeadBase" if type == :DIVE - # path = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_SURFBASE_FOLDER + "surfmon_HeadBase" if type == :SURF - # when :Bipedal - # path = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_SURFBASE_FOLDER + "divemon_HeadBase" if type == :DIVE - # path = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_SURFBASE_FOLDER + "surfmon_HeadBase" if type == :SURF - # when :MultiWinged - # path = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_SURFBASE_FOLDER + "divemon_HeadBase" if type == :DIVE - # path = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_SURFBASE_FOLDER + "surfmon_HeadBase" if type == :SURF - # when :Insectoid - # path = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_SURFBASE_FOLDER + "divemon_HeadBase" if type == :DIVE - # path = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_SURFBASE_FOLDER + "surfmon_HeadBase" if type == :SURF - # else - # path = Settings::PLAYER_GRAPHICS_FOLDER + Settings::PLAYER_SURFBASE_FOLDER + "divemon_01" - # end - - - def update - return if disposed? - if !$PokemonGlobal.surfing && !$PokemonGlobal.diving - # Just-in-time disposal of sprite - if @sprite - @sprite.dispose - @sprite = nil - end - return - end - # Just-in-time creation of sprite - @sprite = Sprite.new(@viewport) if !@sprite - if @sprite - if $PokemonGlobal.surfing - @surfbitmap = update_surf_bitmap(:SURF) - @sprite.bitmap = @surfbitmap.bitmap - cw = @cws - ch = @chs - elsif $PokemonGlobal.diving - @divebitmap = update_surf_bitmap(:DIVE) - @sprite.bitmap = @divebitmap.bitmap - cw = @cwd - ch = @chd - end - sx = @event.pattern_surf * cw - sy = ((@event.direction - 2) / 2) * ch - @sprite.src_rect.set(sx, sy, cw, ch) - if $PokemonTemp.surfJump - @sprite.x = ($PokemonTemp.surfJump[0] * Game_Map::REAL_RES_X - @event.map.display_x + 3) / 4 + (Game_Map::TILE_WIDTH / 2) - @sprite.y = ($PokemonTemp.surfJump[1] * Game_Map::REAL_RES_Y - @event.map.display_y + 3) / 4 + (Game_Map::TILE_HEIGHT / 2) + 16 - else - @sprite.x = @rsprite.x - @sprite.y = @rsprite.y - end - @sprite.ox = cw / 2 - @sprite.oy = ch - 16 # Assume base needs offsetting - @sprite.oy -= @event.bob_height - @sprite.z = @event.screen_z(ch) - 1 - @sprite.zoom_x = @rsprite.zoom_x - @sprite.zoom_y = @rsprite.zoom_y - @sprite.tone = @rsprite.tone - @sprite.color = @rsprite.color - @sprite.opacity = @rsprite.opacity - end - end -end diff --git a/Data/Scripts/005_Sprites/006_Spriteset_Global.rb b/Data/Scripts/005_Sprites/006_Spriteset_Global.rb deleted file mode 100644 index c10b611c4..000000000 --- a/Data/Scripts/005_Sprites/006_Spriteset_Global.rb +++ /dev/null @@ -1,30 +0,0 @@ -class Spriteset_Global - attr_reader :playersprite - @@viewport2 = Viewport.new(0, 0, Settings::SCREEN_WIDTH, Settings::SCREEN_HEIGHT) - @@viewport2.z = 200 - - def initialize - @playersprite = Sprite_Player.new(Spriteset_Map.viewport, $game_player) - @picture_sprites = [] - for i in 1..100 - @picture_sprites.push(Sprite_Picture.new(@@viewport2, $game_screen.pictures[i])) - end - @timer_sprite = Sprite_Timer.new - update - end - - def dispose - @playersprite.dispose - @picture_sprites.each { |sprite| sprite.dispose } - @timer_sprite.dispose - @playersprite = nil - @picture_sprites.clear - @timer_sprite = nil - end - - def update - @playersprite.update - @picture_sprites.each { |sprite| sprite.update } - @timer_sprite.update - end -end diff --git a/Data/Scripts/005_Sprites/007_Spriteset_Map.rb b/Data/Scripts/005_Sprites/007_Spriteset_Map.rb deleted file mode 100644 index d03e9fe47..000000000 --- a/Data/Scripts/005_Sprites/007_Spriteset_Map.rb +++ /dev/null @@ -1,168 +0,0 @@ -# Unused -class ClippableSprite < Sprite_Character - def initialize(viewport,event,tilemap) - @tilemap = tilemap - @_src_rect = Rect.new(0,0,0,0) - super(viewport,event) - end - - def update - super - @_src_rect = self.src_rect - tmright = @tilemap.map_data.xsize*Game_Map::TILE_WIDTH-@tilemap.ox - echoln("x=#{self.x},ox=#{self.ox},tmright=#{tmright},tmox=#{@tilemap.ox}") - if @tilemap.ox-self.ox<-self.x - # clipped on left - diff = -self.x-@tilemap.ox+self.ox - self.src_rect = Rect.new(@_src_rect.x+diff,@_src_rect.y, - @_src_rect.width-diff,@_src_rect.height) - echoln("clipped out left: #{diff} #{@tilemap.ox-self.ox} #{self.x}") - elsif tmright-self.ox 1) ? params[1] : 0 - @anglemax = (params.size > 2) ? params[2] : 0 - @self_opacity = (params.size > 4) ? params[4] : 100 - @distancemax = (params.size > 3) ? params[3] : 350 - @character = character - update - end - - def dispose - @chbitmap&.dispose - super - end - - def update - if !in_range?(@character, @source, @distancemax) - self.opacity = 0 - return - end - super - if @tile_id != @character.tile_id || - @character_name != @character.character_name || - @character_hue != @character.character_hue - @tile_id = @character.tile_id - @character_name = @character.character_name - @character_hue = @character.character_hue - @chbitmap&.dispose - if @tile_id >= 384 - @chbitmap = pbGetTileBitmap(@character.map.tileset_name, - @tile_id, @character.character_hue) - self.src_rect.set(0, 0, 32, 32) - @ch = 32 - @cw = 32 - self.ox = 16 - self.oy = 32 - else - @chbitmap = AnimatedBitmap.new('Graphics/Characters/' + @character.character_name, - @character.character_hue) - @cw = @chbitmap.width / 4 - @ch = @chbitmap.height / 4 - self.ox = @cw / 2 - self.oy = @ch - end - end - if @chbitmap.is_a?(AnimatedBitmap) - @chbitmap.update - self.bitmap = @chbitmap.bitmap - else - self.bitmap = @chbitmap - end - self.visible = !@character.transparent - if @tile_id == 0 - sx = @character.pattern * @cw - sy = (@character.direction - 2) / 2 * @ch - if self.angle > 90 || angle < -90 - case @character.direction - when 2 then sy = @ch * 3 - when 4 then sy = @ch * 2 - when 6 then sy = @ch - when 8 then sy = 0 - end - end - self.src_rect.set(sx, sy, @cw, @ch) - end - self.x = ScreenPosHelper.pbScreenX(@character) - self.y = ScreenPosHelper.pbScreenY(@character) - 5 - self.z = ScreenPosHelper.pbScreenZ(@character, @ch) - 1 - self.zoom_x = ScreenPosHelper.pbScreenZoomX(@character) - self.zoom_y = ScreenPosHelper.pbScreenZoomY(@character) - self.blend_type = @character.blend_type - self.bush_depth = @character.bush_depth - if @character.animation_id != 0 - animation = $data_animations[@character.animation_id] - animation(animation, true) - @character.animation_id = 0 - end - @deltax = ScreenPosHelper.pbScreenX(@source) - self.x - @deltay = ScreenPosHelper.pbScreenY(@source) - self.y - self.color = Color.new(0, 0, 0) - @distance = ((@deltax**2) + (@deltay**2)) - self.opacity = @self_opacity * 13_000 / ((@distance * 370 / @distancemax) + 6000) - self.angle = 57.3 * Math.atan2(@deltax, @deltay) - @angle_trigo = self.angle + 90 - @angle_trigo += 360 if @angle_trigo < 0 - if @anglemin != 0 || @anglemax != 0 - if (@angle_trigo < @anglemin || @angle_trigo > @anglemax) && @anglemin < @anglemax - self.opacity = 0 - return - end - if @angle_trigo < @anglemin && @angle_trigo > @anglemax && @anglemin > @anglemax - self.opacity = 0 - return - end - end - end - - def in_range?(element, object, range) # From Near's Anti Lag Script, edited - elemScreenX = ScreenPosHelper.pbScreenX(element) - elemScreenY = ScreenPosHelper.pbScreenY(element) - objScreenX = ScreenPosHelper.pbScreenX(object) - objScreenY = ScreenPosHelper.pbScreenY(object) - x = (elemScreenX - objScreenX) * (elemScreenX - objScreenX) - y = (elemScreenY - objScreenY) * (elemScreenY - objScreenY) - r = x + y - return r <= range * range - end -end - - - -#=================================================== -# ? CLASS Sprite_Character edit -#=================================================== -class Sprite_Character < RPG::Sprite - alias shadow_initialize initialize unless method_defined?(:shadow_initialize) - - def initialize(viewport, character = nil) - @ombrelist = [] - @character = character - shadow_initialize(viewport, @character) - end - - def setShadows(map, shadows) - if character.is_a?(Game_Event) && shadows.length > 0 - params = XPML_read(map, "Shadow", @character, 4) - if params != nil - shadows.each do |shadow| - @ombrelist.push(Sprite_Shadow.new(viewport, @character, shadows)) - end - end - end - if character.is_a?(Game_Player) && shadows.length > 0 - shadows.each do |shadow| - @ombrelist.push(Sprite_Shadow.new(viewport, $game_player, shadow)) - end - end - update - end - - def clearShadows - @ombrelist.each { |s| s&.dispose } - @ombrelist.clear - end - - alias shadow_update update unless method_defined?(:shadow_update) - - def update - shadow_update - @ombrelist.each { |ombre| ombre.update } - end -end - - - -#=================================================== -# ? CLASS Game_Event edit -#=================================================== -class Game_Event - attr_accessor :id -end - - - -#=================================================== -# ? CLASS Spriteset_Map edit -#=================================================== -class Spriteset_Map - attr_accessor :shadows - - alias shadow_initialize initialize unless method_defined?(:shadow_initialize) - - def initialize(map = nil) - @shadows = [] - warn = false - map = $game_map if !map - map.events.keys.sort.each do |k| - ev = map.events[k] - warn = true if ev.list != nil && ev.list.length > 0 && ev.list[0].code == 108 && - (ev.list[0].parameters == ["s"] || ev.list[0].parameters == ["o"]) - params = XPML_read(map, "Shadow Source", ev, 4) - @shadows.push([ev] + params) if params != nil - end - if warn == true - p "Warning : At least one event on this map uses the obsolete way to add shadows" - end - shadow_initialize(map) - @character_sprites.each do |sprite| - sprite.setShadows(map, @shadows) - end - $scene.spritesetGlobal.playersprite.setShadows(map, @shadows) - end -end - - - -#=================================================== -# ? XPML Definition, by Rataime, using ideas from Near Fantastica -# -# Returns nil if the markup wasn't present at all, -# returns [] if there wasn't any parameters, else -# returns a parameters list with "int" converted as int -# eg : -# begin first -# begin second -# param1 1 -# param2 two -# begin third -# anything 3 -# -# p XPML_read("first", event_id) -> [] -# p XPML_read("second", event_id) -> [1, "two"] -# p XPML_read("third", event_id) -> [3] -# p XPML_read("forth", event_id) -> nil -#=================================================== -def XPML_read(map, markup, event, max_param_number = 0) - parameter_list = nil - return nil if !event || event.list.nil? - event.list.size.times do |i| - if event.list[i].code == 108 && - event.list[i].parameters[0].downcase == "begin " + markup.downcase - parameter_list = [] if parameter_list.nil? - ((i + 1)...event.list.size).each do |j| - if event.list[j].code == 108 - parts = event.list[j].parameters[0].split - if parts.size != 1 && parts[0].downcase != "begin" - if parts[1].to_i != 0 || parts[1] == "0" - parameter_list.push(parts[1].to_i) - else - parameter_list.push(parts[1]) - end - else - return parameter_list - end - else - return parameter_list - end - return parameter_list if max_param_number != 0 && j == i + max_param_number - end - end - end - return parameter_list -end diff --git a/Data/Scripts/005_Sprites/010_ParticleEngine.rb b/Data/Scripts/005_Sprites/010_ParticleEngine.rb deleted file mode 100644 index 01037b8ed..000000000 --- a/Data/Scripts/005_Sprites/010_ParticleEngine.rb +++ /dev/null @@ -1,586 +0,0 @@ -# Particle Engine, Peter O., 2007-11-03 -# Based on version 2 by Near Fantastica, 04.01.06 -# In turn based on the Particle Engine designed by PinkMan -class Particle_Engine - def initialize(viewport = nil, map = nil) - @map = (map) ? map : $game_map - @viewport = viewport - @effect = [] - @disposed = false - @firsttime = true - @effects = { - # PinkMan's Effects - "fire" => Particle_Engine::Fire, - "smoke" => Particle_Engine::Smoke, - "teleport" => Particle_Engine::Teleport, - "spirit" => Particle_Engine::Spirit, - "explosion" => Particle_Engine::Explosion, - "aura" => Particle_Engine::Aura, - # BlueScope's Effects - "soot" => Particle_Engine::Soot, - "sootsmoke" => Particle_Engine::SootSmoke, - "rocket" => Particle_Engine::Rocket, - "fixteleport" => Particle_Engine::FixedTeleport, - "smokescreen" => Particle_Engine::Smokescreen, - "flare" => Particle_Engine::Flare, - "splash" => Particle_Engine::Splash, - # By Peter O. - "starteleport" => Particle_Engine::StarTeleport - } - end - - def dispose - return if disposed? - @effect.each do |particle| - next if particle.nil? - particle.dispose - end - @effect.clear - @map = nil - @disposed = true - end - - def disposed? - return @disposed - end - - def add_effect(event) - @effect[event.id] = pbParticleEffect(event) - end - - def remove_effect(event) - return if @effect[event.id].nil? - @effect[event.id].dispose - @effect.delete_at(event.id) - end - - def realloc_effect(event, particle) - type = pbEventCommentInput(event, 1, "Particle Engine Type") - if type.nil? - particle&.dispose - return nil - end - type = type[0].downcase - cls = @effects[type] - if cls.nil? - particle&.dispose - return nil - end - if !particle || !particle.is_a?(cls) - particle&.dispose - particle = cls.new(event, @viewport) - end - return particle - end - - def pbParticleEffect(event) - return realloc_effect(event, nil) - end - - def update - if @firsttime - @firsttime = false - @map.events.values.each do |event| - remove_effect(event) - add_effect(event) - end - end - @effect.each_with_index do |particle, i| - next if particle.nil? - if particle.event.pe_refresh - event = particle.event - event.pe_refresh = false - particle = realloc_effect(event, particle) - @effect[i] = particle - end - particle&.update - end - end -end - - - -class ParticleEffect - attr_accessor :x, :y, :z - - def initialize - @x = 0 - @y = 0 - @z = 0 - end - - def update; end - def dispose; end -end - - - -class ParticleSprite - attr_accessor :x, :y, :z, :ox, :oy, :opacity, :blend_type - attr_reader :bitmap - - def initialize(viewport) - @viewport = viewport - @sprite = nil - @x = 0 - @y = 0 - @z = 0 - @ox = 0 - @oy = 0 - @opacity = 255 - @bitmap = nil - @blend_type = 0 - @minleft = 0 - @mintop = 0 - end - - def dispose - @sprite&.dispose - end - - def bitmap=(value) - @bitmap = value - if value - @minleft = -value.width - @mintop = -value.height - else - @minleft = 0 - @mintop = 0 - end - end - - def update - w = Graphics.width - h = Graphics.height - if !@sprite && @x >= @minleft && @y >= @mintop && @x < w && @y < h - @sprite = Sprite.new(@viewport) - elsif @sprite && (@x < @minleft || @y < @mintop || @x >= w || @y >= h) - @sprite.dispose - @sprite = nil - end - if @sprite - @sprite.x = @x if @sprite.x != @x - @sprite.x -= @ox - @sprite.y = @y if @sprite.y != @y - @sprite.y -= @oy - @sprite.z = @z if @sprite.z != @z - @sprite.opacity = @opacity if @sprite.opacity != @opacity - @sprite.blend_type = @blend_type if @sprite.blend_type != @blend_type - @sprite.bitmap = @bitmap if @sprite.bitmap != @bitmap - end - end -end - - - -class ParticleEffect_Event < ParticleEffect - attr_accessor :event - - def initialize(event, viewport = nil) - @event = event - @viewport = viewport - @particles = [] - @bitmaps = {} - end - - def setParameters(params) - @randomhue, @leftright, @fade, - @maxparticless, @hue, @slowdown, - @ytop, @ybottom, @xleft, @xright, - @xgravity, @ygravity, @xoffset, @yoffset, - @opacityvar, @originalopacity = params - end - - def loadBitmap(filename, hue) - key = [filename, hue] - bitmap = @bitmaps[key] - if !bitmap || bitmap.disposed? - bitmap = AnimatedBitmap.new("Graphics/Fogs/" + filename, hue).deanimate - @bitmaps[key] = bitmap - end - return bitmap - end - - def initParticles(filename, opacity, zOffset = 0, blendtype = 1) - @particles = [] - @particlex = [] - @particley = [] - @opacity = [] - @startingx = self.x + @xoffset - @startingy = self.y + @yoffset - @screen_x = self.x - @screen_y = self.y - @real_x = @event.real_x - @real_y = @event.real_y - @filename = filename - @zoffset = zOffset - @bmwidth = 32 - @bmheight = 32 - @maxparticless.times do |i| - @particlex[i] = -@xoffset - @particley[i] = -@yoffset - @particles[i] = ParticleSprite.new(@viewport) - @particles[i].bitmap = loadBitmap(filename, @hue) if filename - if i == 0 && @particles[i].bitmap - @bmwidth = @particles[i].bitmap.width - @bmheight = @particles[i].bitmap.height - end - @particles[i].blend_type = blendtype - @particles[i].y = @startingy - @particles[i].x = @startingx - @particles[i].z = self.z + zOffset - @opacity[i] = rand(opacity / 4) - @particles[i].opacity = @opacity[i] - @particles[i].update - end - end - - def x; return ScreenPosHelper.pbScreenX(@event); end - def y; return ScreenPosHelper.pbScreenY(@event); end - def z; return ScreenPosHelper.pbScreenZ(@event); end - - def update - if @viewport && - (@viewport.rect.x >= Graphics.width || - @viewport.rect.y >= Graphics.height) - return - end - selfX = self.x - selfY = self.y - selfZ = self.z - newRealX = @event.real_x - newRealY = @event.real_y - @startingx = selfX + @xoffset - @startingy = selfY + @yoffset - @__offsetx = (@real_x == newRealX) ? 0 : selfX - @screen_x - @__offsety = (@real_y == newRealY) ? 0 : selfY - @screen_y - @screen_x = selfX - @screen_y = selfY - @real_x = newRealX - @real_y = newRealY - if @opacityvar > 0 && @viewport - opac = 255.0 / @opacityvar - minX = (opac * (-@xgravity.to_f / @slowdown).floor) + @startingx - maxX = (opac * (@xgravity.to_f / @slowdown).floor) + @startingx - minY = (opac * (-@ygravity.to_f / @slowdown).floor) + @startingy - maxY = @startingy - minX -= @bmwidth - minY -= @bmheight - maxX += @bmwidth - maxY += @bmheight - if maxX < 0 || maxY < 0 || minX >= Graphics.width || minY >= Graphics.height -# echo "skipped" - return - end - end - particleZ = selfZ + @zoffset - @maxparticless.times do |i| - @particles[i].z = particleZ - if @particles[i].y <= @ytop - @particles[i].y = @startingy + @yoffset - @particles[i].x = @startingx + @xoffset - @particlex[i] = 0.0 - @particley[i] = 0.0 - end - if @particles[i].x <= @xleft - @particles[i].y = @startingy + @yoffset - @particles[i].x = @startingx + @xoffset - @particlex[i] = 0.0 - @particley[i] = 0.0 - end - if @particles[i].y >= @ybottom - @particles[i].y = @startingy + @yoffset - @particles[i].x = @startingx + @xoffset - @particlex[i] = 0.0 - @particley[i] = 0.0 - end - if @particles[i].x >= @xright - @particles[i].y = @startingy + @yoffset - @particles[i].x = @startingx + @xoffset - @particlex[i] = 0.0 - @particley[i] = 0.0 - end - if @fade == 0 - if @opacity[i] <= 0 - @opacity[i] = @originalopacity - @particles[i].y = @startingy + @yoffset - @particles[i].x = @startingx + @xoffset - @particlex[i] = 0.0 - @particley[i] = 0.0 - end - elsif @opacity[i] <= 0 - @opacity[i] = 250 - @particles[i].y = @startingy + @yoffset - @particles[i].x = @startingx + @xoffset - @particlex[i] = 0.0 - @particley[i] = 0.0 - end - calcParticlePos(i) - if @randomhue == 1 - @hue += 0.5 - @hue = 0 if @hue >= 360 - @particles[i].bitmap = loadBitmap(@filename, @hue) if @filename - end - @opacity[i] = @opacity[i] - rand(@opacityvar) - @particles[i].opacity = @opacity[i] - @particles[i].update - end - end - - def calcParticlePos(i) - @leftright = rand(2) - if @leftright == 1 - xo = -@xgravity.to_f / @slowdown - else - xo = @xgravity.to_f / @slowdown - end - yo = -@ygravity.to_f / @slowdown - @particlex[i] += xo - @particley[i] += yo - @particlex[i] -= @__offsetx - @particley[i] -= @__offsety - @particlex[i] = @particlex[i].floor - @particley[i] = @particley[i].floor - @particles[i].x = @particlex[i] + @startingx + @xoffset - @particles[i].y = @particley[i] + @startingy + @yoffset - end - - def dispose - @particles.each do |particle| - particle.dispose - end - @bitmaps.values.each do |bitmap| - bitmap.dispose - end - @particles.clear - @bitmaps.clear - end -end - - - -class Particle_Engine::Fire < ParticleEffect_Event - def initialize(event, viewport) - super - setParameters([0, 0, 1, 20, 40, 0.5, -64, - Graphics.height, -64, Graphics.width, 0.5, 0.10, -5, -13, 30, 0]) - initParticles("particle", 250) - end -end - - - -class Particle_Engine::Smoke < ParticleEffect_Event - def initialize(event, viewport) - super - setParameters([0, 0, 0, 80, 20, 0.5, -64, - Graphics.height, -64, Graphics.width, 0.5, 0.10, -5, -15, 5, 80]) - initParticles("smoke", 250) - end -end - - - -class Particle_Engine::Teleport < ParticleEffect_Event - def initialize(event, viewport) - super - setParameters([1, 1, 1, 10, rand(360), 1, -64, - Graphics.height, -64, Graphics.width, 0, 3, -8, -15, 20, 0]) - initParticles("wideportal", 250) - @maxparticless.times do |i| - @particles[i].ox = 16 - @particles[i].oy = 16 - end - end -end - - - -class Particle_Engine::Spirit < ParticleEffect_Event - def initialize(event, viewport) - super - setParameters([1, 0, 1, 20, rand(360), 0.5, -64, - Graphics.height, -64, Graphics.width, 0.5, 0.10, -5, -13, 30, 0]) - initParticles("particle", 250) - end -end - - - -class Particle_Engine::Explosion < ParticleEffect_Event - def initialize(event, viewport) - super - setParameters([0, 0, 1, 20, 0, 0.5, -64, - Graphics.height, -64, Graphics.width, 0.5, 0.10, -5, -13, 30, 0]) - initParticles("explosion", 250) - end -end - - - -class Particle_Engine::Aura < ParticleEffect_Event - def initialize(event, viewport) - super - setParameters([0, 0, 1, 20, 0, 1, -64, - Graphics.height, -64, Graphics.width, 2, 2, -5, -13, 30, 0]) - initParticles("particle", 250) - end -end - - - -class Particle_Engine::Soot < ParticleEffect_Event - def initialize(event, viewport) - super - setParameters([0, 0, 0, 20, 0, 0.5, -64, - Graphics.height, -64, Graphics.width, 0.5, 0.10, -5, -15, 5, 80]) - initParticles("smoke", 100, 0, 2) - end -end - - - -class Particle_Engine::SootSmoke < ParticleEffect_Event - def initialize(event, viewport) - super - setParameters([0, 0, 0, 30, 0, 0.5, -64, - Graphics.height, -64, Graphics.width, 0.5, 0.10, -5, -15, 5, 80]) - initParticles("smoke", 100, 0) - @maxparticless.times do |i| - @particles[i].blend_type = rand(6) < 3 ? 1 : 2 - end - end -end - - - -class Particle_Engine::Rocket < ParticleEffect_Event - def initialize(event, viewport) - super - setParameters([0, 0, 0, 60, 0, 0.5, -64, - Graphics.height, -64, Graphics.width, 0.5, 0, -5, -15, 5, 80]) - initParticles("smoke", 100, -1) - end -end - - - -class Particle_Engine::FixedTeleport < ParticleEffect_Event - def initialize(event, viewport) - super - setParameters([1, 0, 1, 10, rand(360), 1, - -Graphics.height, Graphics.height, 0, Graphics.width, 0, 3, -8, -15, 20, 0]) - initParticles("wideportal", 250) - @maxparticless.times do |i| - @particles[i].ox = 16 - @particles[i].oy = 16 - end - end -end - - - -# By Peter O. -class Particle_Engine::StarTeleport < ParticleEffect_Event - def initialize(event, viewport) - super - setParameters([0, 0, 1, 10, 0, 1, - -Graphics.height, Graphics.height, 0, Graphics.width, 0, 3, -8, -15, 10, 0]) - initParticles("star", 250) - @maxparticless.times do |i| - @particles[i].ox = 48 - @particles[i].oy = 48 - end - end -end - - - -class Particle_Engine::Smokescreen < ParticleEffect_Event - def initialize(event, viewport) - super - setParameters([0, 0, 0, 250, 0, 0.2, -64, - Graphics.height, -64, Graphics.width, 0.8, 0.8, -5, -15, 5, 80]) - initParticles(nil, 100) - @maxparticless.times do |i| - rnd = rand(3) - @opacity[i] = (rnd == 0) ? 1 : 100 - filename = (rnd == 0) ? "explosionsmoke" : "smoke" - @particles[i].bitmap = loadBitmap(filename, @hue) - end - end - - def calcParticlePos(i) - if @randomhue == 1 - filename = (rand(3) == 0) ? "explosionsmoke" : "smoke" - @particles[i].bitmap = loadBitmap(filename, @hue) - end - multiple = 1.7 - xgrav = @xgravity * multiple / @slowdown - xgrav = -xgrav if rand(2) == 1 - ygrav = @ygravity * multiple / @slowdown - ygrav = -ygrav if rand(2) == 1 - @particlex[i] += xgrav - @particley[i] += ygrav - @particlex[i] -= @__offsetx - @particley[i] -= @__offsety - @particlex[i] = @particlex[i].floor - @particley[i] = @particley[i].floor - @particles[i].x = @particlex[i] + @startingx + @xoffset - @particles[i].y = @particley[i] + @startingy + @yoffset - end -end - - - -class Particle_Engine::Flare < ParticleEffect_Event - def initialize(event, viewport) - super - setParameters([0, 0, 1, 30, 10, 1, -64, - Graphics.height, -64, Graphics.width, 2, 2, -5, -12, 30, 0]) - initParticles("particle", 255) - end -end - - - -class Particle_Engine::Splash < ParticleEffect_Event - def initialize(event, viewport) - super - setParameters([0, 0, 1, 30, 255, 1, -64, - Graphics.height, -64, Graphics.width, 4, 2, -5, -12, 30, 0]) - initParticles("smoke", 50) - end - - def update - super - @maxparticless.times do |i| - @particles[i].opacity = 50 - @particles[i].update - end - end -end - - - -class Game_Event < Game_Character - attr_accessor :pe_refresh - - alias nf_particles_game_map_initialize initialize unless method_defined?(:nf_particles_game_map_initialize) - - def initialize(map_id, event, map = nil) - @pe_refresh = false - begin - nf_particles_game_map_initialize(map_id, event, map) - rescue ArgumentError - nf_particles_game_map_initialize(map_id, event) - end - end - - alias nf_particles_game_map_refresh refresh unless method_defined?(:nf_particles_game_map_refresh) - - def refresh - nf_particles_game_map_refresh - @pe_refresh = true - end -end diff --git a/Data/Scripts/005_Sprites/011_PictureEx.rb b/Data/Scripts/005_Sprites/011_PictureEx.rb deleted file mode 100644 index 404924d91..000000000 --- a/Data/Scripts/005_Sprites/011_PictureEx.rb +++ /dev/null @@ -1,519 +0,0 @@ -class PictureOrigin - TopLeft = 0 - Center = 1 - TopRight = 2 - BottomLeft = 3 - LowerLeft = 3 - BottomRight = 4 - LowerRight = 4 - Top = 5 - Bottom = 6 - Left = 7 - Right = 8 -end - - - -class Processes - XY = 0 - DeltaXY = 1 - Z = 2 - Curve = 3 - Zoom = 4 - Angle = 5 - Tone = 6 - Color = 7 - Hue = 8 - Opacity = 9 - Visible = 10 - BlendType = 11 - SE = 12 - Name = 13 - Origin = 14 - Src = 15 - SrcSize = 16 - CropBottom = 17 -end - - - -def getCubicPoint2(src,t) - x0 = src[0]; y0 = src[1] - cx0 = src[2]; cy0 = src[3] - cx1 = src[4]; cy1 = src[5] - x1 = src[6]; y1 = src[7] - - x1 = cx1+(x1-cx1)*t - x0 = x0+(cx0-x0)*t - cx0 = cx0+(cx1-cx0)*t - cx1 = cx0+(x1-cx0)*t - cx0 = x0+(cx0-x0)*t - cx = cx0+(cx1-cx0)*t - # a = x1 - 3 * cx1 + 3 * cx0 - x0 - # b = 3 * (cx1 - 2 * cx0 + x0) - # c = 3 * (cx0 - x0) - # d = x0 - # cx = a*t*t*t + b*t*t + c*t + d - y1 = cy1+(y1-cy1)*t - y0 = y0+(cy0-y0)*t - cy0 = cy0+(cy1-cy0)*t - cy1 = cy0+(y1-cy0)*t - cy0 = y0+(cy0-y0)*t - cy = cy0+(cy1-cy0)*t - # a = y1 - 3 * cy1 + 3 * cy0 - y0 - # b = 3 * (cy1 - 2 * cy0 + y0) - # c = 3 * (cy0 - y0) - # d = y0 - # cy = a*t*t*t + b*t*t + c*t + d - return [cx,cy] -end - - - -#=============================================================================== -# PictureEx -#=============================================================================== -class PictureEx - attr_accessor :x # x-coordinate - attr_accessor :y # y-coordinate - attr_accessor :z # z value - attr_accessor :zoom_x # x directional zoom rate - attr_accessor :zoom_y # y directional zoom rate - attr_accessor :angle # rotation angle - attr_accessor :tone # tone - attr_accessor :color # color - attr_accessor :hue # filename hue - attr_accessor :opacity # opacity level - attr_accessor :visible # visibility boolean - attr_accessor :blend_type # blend method - attr_accessor :name # file name - attr_accessor :origin # starting point - attr_reader :src_rect # source rect - attr_reader :cropBottom # crops sprite to above this y-coordinate - attr_reader :frameUpdates # Array of processes updated in a frame - - def initialize(z) - # process: [type, delay, total_duration, frame_counter, cb, etc.] - @processes = [] - @x = 0.0 - @y = 0.0 - @z = z - @zoom_x = 100.0 - @zoom_y = 100.0 - @angle = 0 - @rotate_speed = 0 - @tone = Tone.new(0, 0, 0, 0) - @tone_duration = 0 - @color = Color.new(0, 0, 0, 0) - @hue = 0 - @opacity = 255.0 - @visible = true - @blend_type = 0 - @name = "" - @origin = PictureOrigin::TopLeft - @src_rect = Rect.new(0,0,-1,-1) - @cropBottom = -1 - @frameUpdates = [] - end - - def callback(cb) - if cb.is_a?(Proc); cb.call(self) - elsif cb.is_a?(Array); cb[0].method(cb[1]).call(self) - elsif cb.is_a?(Method); cb.call(self) - end - end - - def setCallback(delay, cb=nil) - delay = ensureDelayAndDuration(delay) - @processes.push([nil,delay,0,0,cb]) - end - - def running? - return @processes.length>0 - end - - def totalDuration - ret = 0 - for process in @processes - dur = process[1]+process[2] - ret = dur if dur>ret - end - ret *= 20.0/Graphics.frame_rate - return ret.to_i - end - - def ensureDelayAndDuration(delay, duration=nil) - delay = self.totalDuration if delay<0 - delay *= Graphics.frame_rate/20.0 - if !duration.nil? - duration *= Graphics.frame_rate/20.0 - return delay.to_i, duration.to_i - end - return delay.to_i - end - - def ensureDelay(delay) - return ensureDelayAndDuration(delay) - end - - # speed is the angle to change by in 1/20 of a second. @rotate_speed is the - # angle to change by per frame. - # NOTE: This is not compatible with manually changing the angle at a certain - # point. If you make a sprite auto-rotate, you should not try to alter - # the angle another way too. - def rotate(speed) - @rotate_speed = speed*20.0/Graphics.frame_rate - while @rotate_speed<0; @rotate_speed += 360; end - @rotate_speed %= 360 - end - - def erase - self.name = "" - end - - def clearProcesses - @processes = [] - end - - def adjustPosition(xOffset, yOffset) - for process in @processes - next if process[0]!=Processes::XY - process[5] += xOffset - process[6] += yOffset - process[7] += xOffset - process[8] += yOffset - end - end - - def move(delay, duration, origin, x, y, zoom_x=100.0, zoom_y=100.0, opacity=255) - setOrigin(delay,duration,origin) - moveXY(delay,duration,x,y) - moveZoomXY(delay,duration,zoom_x,zoom_y) - moveOpacity(delay,duration,opacity) - end - - def moveXY(delay, duration, x, y, cb=nil) - delay, duration = ensureDelayAndDuration(delay,duration) - @processes.push([Processes::XY,delay,duration,0,cb,@x,@y,x,y]) - end - - def setXY(delay, x, y, cb=nil) - moveXY(delay,0,x,y,cb) - end - - def moveCurve(delay, duration, x1, y1, x2, y2, x3, y3, cb=nil) - delay, duration = ensureDelayAndDuration(delay,duration) - @processes.push([Processes::Curve,delay,duration,0,cb,[@x,@y,x1,y1,x2,y2,x3,y3]]) - end - - def moveDelta(delay, duration, x, y, cb=nil) - delay, duration = ensureDelayAndDuration(delay,duration) - @processes.push([Processes::DeltaXY,delay,duration,0,cb,@x,@y,x,y]) - end - - def setDelta(delay, x, y, cb=nil) - moveDelta(delay,0,x,y,cb) - end - - def moveZ(delay, duration, z, cb=nil) - delay, duration = ensureDelayAndDuration(delay,duration) - @processes.push([Processes::Z,delay,duration,0,cb,@z,z]) - end - - def setZ(delay, z, cb=nil) - moveZ(delay,0,z,cb) - end - - def moveZoomXY(delay, duration, zoom_x, zoom_y, cb=nil) - delay, duration = ensureDelayAndDuration(delay,duration) - @processes.push([Processes::Zoom,delay,duration,0,cb,@zoom_x,@zoom_y,zoom_x,zoom_y]) - end - - def setZoomXY(delay, zoom_x, zoom_y, cb=nil) - moveZoomXY(delay,0,zoom_x,zoom_y,cb) - end - - def moveZoom(delay, duration, zoom, cb=nil) - moveZoomXY(delay,duration,zoom,zoom,cb) - end - - def setZoom(delay, zoom, cb=nil) - moveZoomXY(delay,0,zoom,zoom,cb) - end - - def moveAngle(delay, duration, angle, cb=nil) - delay, duration = ensureDelayAndDuration(delay,duration) - @processes.push([Processes::Angle,delay,duration,0,cb,@angle,angle]) - end - - def setAngle(delay, angle, cb=nil) - moveAngle(delay,0,angle,cb) - end - - def moveTone(delay, duration, tone, cb=nil) - delay, duration = ensureDelayAndDuration(delay,duration) - target = (tone) ? tone.clone : Tone.new(0,0,0,0) - @processes.push([Processes::Tone,delay,duration,0,cb,@tone.clone,target]) - end - - def setTone(delay, tone, cb=nil) - moveTone(delay,0,tone,cb) - end - - def moveColor(delay, duration, color, cb=nil) - delay, duration = ensureDelayAndDuration(delay,duration) - target = (color) ? color.clone : Color.new(0,0,0,0) - @processes.push([Processes::Color,delay,duration,0,cb,@color.clone,target]) - end - - def setColor(delay, color, cb=nil) - moveColor(delay,0,color,cb) - end - - # Hue changes don't actually work. - def moveHue(delay, duration, hue, cb=nil) - delay, duration = ensureDelayAndDuration(delay,duration) - @processes.push([Processes::Hue,delay,duration,0,cb,@hue,hue]) - end - - # Hue changes don't actually work. - def setHue(delay, hue, cb=nil) - moveHue(delay,0,hue,cb) - end - - def moveOpacity(delay, duration, opacity, cb=nil) - delay, duration = ensureDelayAndDuration(delay,duration) - @processes.push([Processes::Opacity,delay,duration,0,cb,@opacity,opacity]) - end - - def setOpacity(delay, opacity, cb=nil) - moveOpacity(delay,0,opacity,cb) - end - - def setVisible(delay, visible, cb=nil) - delay = ensureDelay(delay) - @processes.push([Processes::Visible,delay,0,0,cb,visible]) - end - - # Only values of 0 (normal), 1 (additive) and 2 (subtractive) are allowed. - def setBlendType(delay, blend, cb=nil) - delay = ensureDelayAndDuration(delay) - @processes.push([Processes::BlendType,delay,0,0,cb,blend]) - end - - def setSE(delay, seFile, volume=nil, pitch=nil, cb=nil) - delay = ensureDelay(delay) - @processes.push([Processes::SE,delay,0,0,cb,seFile,volume,pitch]) - end - - def setName(delay, name, cb=nil) - delay = ensureDelay(delay) - @processes.push([Processes::Name,delay,0,0,cb,name]) - end - - def setOrigin(delay, origin, cb=nil) - delay = ensureDelay(delay) - @processes.push([Processes::Origin,delay,0,0,cb,origin]) - end - - def setSrc(delay, srcX, srcY, cb=nil) - delay = ensureDelay(delay) - @processes.push([Processes::Src,delay,0,0,cb,srcX,srcY]) - end - - def setSrcSize(delay, srcWidth, srcHeight, cb=nil) - delay = ensureDelay(delay) - @processes.push([Processes::SrcSize,delay,0,0,cb,srcWidth,srcHeight]) - end - - # Used to cut Pokémon sprites off when they faint and sink into the ground. - def setCropBottom(delay, y, cb=nil) - delay = ensureDelay(delay) - @processes.push([Processes::CropBottom,delay,0,0,cb,y]) - end - - def update - procEnded = false - @frameUpdates.clear - for i in 0...@processes.length - process = @processes[i] - # Decrease delay of processes that are scheduled to start later - if process[1]>=0 - # Set initial values if the process will start this frame - if process[1]==0 - case process[0] - when Processes::XY - process[5] = @x - process[6] = @y - when Processes::DeltaXY - process[5] = @x - process[6] = @y - process[7] += @x - process[8] += @y - when Processes::Curve - process[5][0] = @x - process[5][1] = @y - when Processes::Z - process[5] = @z - when Processes::Zoom - process[5] = @zoom_x - process[6] = @zoom_y - when Processes::Angle - process[5] = @angle - when Processes::Tone - process[5] = @tone.clone - when Processes::Color - process[5] = @color.clone - when Processes::Hue - process[5] = @hue - when Processes::Opacity - process[5] = @opacity - end - end - # Decrease delay counter - process[1] -= 1 - # Process hasn't started yet, skip to the next one - next if process[1]>=0 - end - # Update process - @frameUpdates.push(process[0]) if !@frameUpdates.include?(process[0]) - fra = (process[2]==0) ? 1 : process[3] # Frame counter - dur = (process[2]==0) ? 1 : process[2] # Total duration of process - case process[0] - when Processes::XY, Processes::DeltaXY - @x = process[5] + fra * (process[7] - process[5]) / dur - @y = process[6] + fra * (process[8] - process[6]) / dur - when Processes::Curve - @x, @y = getCubicPoint2(process[5],fra.to_f/dur) - when Processes::Z - @z = process[5] + fra * (process[6] - process[5]) / dur - when Processes::Zoom - @zoom_x = process[5] + fra * (process[7] - process[5]) / dur - @zoom_y = process[6] + fra * (process[8] - process[6]) / dur - when Processes::Angle - @angle = process[5] + fra * (process[6] - process[5]) / dur - when Processes::Tone - @tone.red = process[5].red + fra * (process[6].red - process[5].red) / dur - @tone.green = process[5].green + fra * (process[6].green - process[5].green) / dur - @tone.blue = process[5].blue + fra * (process[6].blue - process[5].blue) / dur - @tone.gray = process[5].gray + fra * (process[6].gray - process[5].gray) / dur - when Processes::Color - @color.red = process[5].red + fra * (process[6].red - process[5].red) / dur - @color.green = process[5].green + fra * (process[6].green - process[5].green) / dur - @color.blue = process[5].blue + fra * (process[6].blue - process[5].blue) / dur - @color.alpha = process[5].alpha + fra * (process[6].alpha - process[5].alpha) / dur - when Processes::Hue - @hue = (process[6] - process[5]).to_f / dur - when Processes::Opacity - @opacity = process[5] + fra * (process[6] - process[5]) / dur - when Processes::Visible - @visible = process[5] - when Processes::BlendType - @blend_type = process[5] - when Processes::SE - pbSEPlay(process[5],process[6],process[7]) - when Processes::Name - @name = process[5] - when Processes::Origin - @origin = process[5] - when Processes::Src - @src_rect.x = process[5] - @src_rect.y = process[6] - when Processes::SrcSize - @src_rect.width = process[5] - @src_rect.height = process[6] - when Processes::CropBottom - @cropBottom = process[5] - end - # Increase frame counter - process[3] += 1 - if process[3]>process[2] - # Process has ended, erase it - callback(process[4]) if process[4] - @processes[i] = nil - procEnded = true - end - end - # Clear out empty spaces in @processes array caused by finished processes - @processes.compact! if procEnded - # Add the constant rotation speed - if @rotate_speed != 0 - @frameUpdates.push(Processes::Angle) if !@frameUpdates.include?(Processes::Angle) - @angle += @rotate_speed - while @angle<0; @angle += 360; end - @angle %= 360 - end - end -end - - - -#=============================================================================== -# -#=============================================================================== -def setPictureSprite(sprite, picture, iconSprite=false) - return if picture.frameUpdates.length==0 - for i in 0...picture.frameUpdates.length - case picture.frameUpdates[i] - when Processes::XY, Processes::DeltaXY - sprite.x = picture.x.round - sprite.y = picture.y.round - when Processes::Z - sprite.z = picture.z - when Processes::Zoom - sprite.zoom_x = picture.zoom_x / 100.0 - sprite.zoom_y = picture.zoom_y / 100.0 - when Processes::Angle - sprite.angle = picture.angle - when Processes::Tone - sprite.tone = picture.tone - when Processes::Color - sprite.color = picture.color - when Processes::Hue - # This doesn't do anything. - when Processes::BlendType - sprite.blend_type = picture.blend_type - when Processes::Opacity - sprite.opacity = picture.opacity - when Processes::Visible - sprite.visible = picture.visible - when Processes::Name - sprite.name = picture.name if iconSprite && sprite.name != picture.name - when Processes::Origin - case picture.origin - when PictureOrigin::TopLeft, PictureOrigin::Left, PictureOrigin::BottomLeft - sprite.ox = 0 - when PictureOrigin::Top, PictureOrigin::Center, PictureOrigin::Bottom - sprite.ox = (sprite.bitmap && !sprite.bitmap.disposed?) ? sprite.src_rect.width/2 : 0 - when PictureOrigin::TopRight, PictureOrigin::Right, PictureOrigin::BottomRight - sprite.ox = (sprite.bitmap && !sprite.bitmap.disposed?) ? sprite.src_rect.width : 0 - end - case picture.origin - when PictureOrigin::TopLeft, PictureOrigin::Top, PictureOrigin::TopRight - sprite.oy = 0 - when PictureOrigin::Left, PictureOrigin::Center, PictureOrigin::Right - sprite.oy = (sprite.bitmap && !sprite.bitmap.disposed?) ? sprite.src_rect.height/2 : 0 - when PictureOrigin::BottomLeft, PictureOrigin::Bottom, PictureOrigin::BottomRight - sprite.oy = (sprite.bitmap && !sprite.bitmap.disposed?) ? sprite.src_rect.height : 0 - end - when Processes::Src - next unless iconSprite && sprite.src_rect - sprite.src_rect.x = picture.src_rect.x - sprite.src_rect.y = picture.src_rect.y - when Processes::SrcSize - next unless iconSprite && sprite.src_rect - sprite.src_rect.width = picture.src_rect.width - sprite.src_rect.height = picture.src_rect.height - end - end - if iconSprite && sprite.src_rect && picture.cropBottom>=0 - spriteBottom = sprite.y-sprite.oy+sprite.src_rect.height - if spriteBottom>picture.cropBottom - sprite.src_rect.height = [picture.cropBottom-sprite.y+sprite.oy,0].max - end - end -end - -def setPictureIconSprite(sprite, picture) - setPictureSprite(sprite,picture,true) -end diff --git a/Data/Scripts/005_Sprites/012_Interpolators.rb b/Data/Scripts/005_Sprites/012_Interpolators.rb deleted file mode 100644 index 567defb50..000000000 --- a/Data/Scripts/005_Sprites/012_Interpolators.rb +++ /dev/null @@ -1,172 +0,0 @@ -class Interpolator - ZOOM_X = 1 - ZOOM_Y = 2 - X = 3 - Y = 4 - OPACITY = 5 - COLOR = 6 - WAIT = 7 - - def initialize - @tweening = false - @tweensteps = [] - @sprite = nil - @frames = 0 - @step = 0 - end - - def tweening? - return @tweening - end - - def tween(sprite,items,frames) - @tweensteps = [] - if sprite && !sprite.disposed? && frames>0 - @frames = frames - @step = 0 - @sprite = sprite - for item in items - case item[0] - when ZOOM_X - @tweensteps[item[0]] = [sprite.zoom_x,item[1]-sprite.zoom_x] - when ZOOM_Y - @tweensteps[item[0]] = [sprite.zoom_y,item[1]-sprite.zoom_y] - when X - @tweensteps[item[0]] = [sprite.x,item[1]-sprite.x] - when Y - @tweensteps[item[0]] = [sprite.y,item[1]-sprite.y] - when OPACITY - @tweensteps[item[0]] = [sprite.opacity,item[1]-sprite.opacity] - when COLOR - @tweensteps[item[0]] = [sprite.color.clone,Color.new( - item[1].red-sprite.color.red, - item[1].green-sprite.color.green, - item[1].blue-sprite.color.blue, - item[1].alpha-sprite.color.alpha - )] - end - end - @tweening = true - end - end - - def update - if @tweening - t = (@step*1.0)/@frames - for i in 0...@tweensteps.length - item = @tweensteps[i] - next if !item - case i - when ZOOM_X - @sprite.zoom_x = item[0]+item[1]*t - when ZOOM_Y - @sprite.zoom_y = item[0]+item[1]*t - when X - @sprite.x = item[0]+item[1]*t - when Y - @sprite.y = item[0]+item[1]*t - when OPACITY - @sprite.opacity = item[0]+item[1]*t - when COLOR - @sprite.color = Color.new( - item[0].red+item[1].red*t, - item[0].green+item[1].green*t, - item[0].blue+item[1].blue*t, - item[0].alpha+item[1].alpha*t - ) - end - end - @step += 1 - if @step==@frames - @step = 0 - @frames = 0 - @tweening = false - end - end - end -end - - - -class RectInterpolator - def initialize(oldrect,newrect,frames) - restart(oldrect,newrect,frames) - end - - def restart(oldrect,newrect,frames) - @oldrect = oldrect - @newrect = newrect - @frames = [frames,1].max - @curframe = 0 - @rect = oldrect.clone - end - - def set(rect) - rect.set(@rect.x,@rect.y,@rect.width,@rect.height) - end - - def done? - @curframe>@frames - end - - def update - return if done? - t = (@curframe*1.0/@frames) - x1 = @oldrect.x - x2 = @newrect.x - x = x1+t*(x2-x1) - y1 = @oldrect.y - y2 = @newrect.y - y = y1+t*(y2-y1) - rx1 = @oldrect.x+@oldrect.width - rx2 = @newrect.x+@newrect.width - rx = rx1+t*(rx2-rx1) - ry1 = @oldrect.y+@oldrect.height - ry2 = @newrect.y+@newrect.height - ry = ry1+t*(ry2-ry1) - minx = xrx ? x : rx - miny = yry ? y : ry - @rect.set(minx,miny,maxx-minx,maxy-miny) - @curframe += 1 - end -end - - - -class PointInterpolator - attr_reader :x - attr_reader :y - - def initialize(oldx,oldy,newx,newy,frames) - restart(oldx,oldy,newx,newy,frames) - end - - def restart(oldx,oldy,newx,newy,frames) - @oldx = oldx - @oldy = oldy - @newx = newx - @newy = newy - @frames = frames - @curframe = 0 - @x = oldx - @y = oldy - end - - def done? - @curframe>@frames - end - - def update - return if done? - t = (@curframe*1.0/@frames) - rx1 = @oldx - rx2 = @newx - @x = rx1+t*(rx2-rx1) - ry1 = @oldy - ry2 = @newy - @y = ry1+t*(ry2-ry1) - @curframe += 1 - end -end diff --git a/Data/Scripts/005_Sprites/013_ScreenPosHelper.rb b/Data/Scripts/005_Sprites/013_ScreenPosHelper.rb deleted file mode 100644 index 418bbd9bf..000000000 --- a/Data/Scripts/005_Sprites/013_ScreenPosHelper.rb +++ /dev/null @@ -1,43 +0,0 @@ -module ScreenPosHelper - def self.pbScreenZoomX(ch) - return Game_Map::TILE_WIDTH/32.0 - end - - def self.pbScreenZoomY(ch) - return Game_Map::TILE_HEIGHT/32.0 - end - - def self.pbScreenX(ch) - return ch.screen_x - end - - def self.pbScreenY(ch) - return ch.screen_y - end - - @heightcache={} - - def self.bmHeight(bm) - h=@heightcache[bm] - if !h - bmap=AnimatedBitmap.new("Graphics/Characters/"+bm,0) - h=bmap.height - @heightcache[bm]=h - bmap.dispose - end - return h - end - - def self.pbScreenZ(ch,height=nil) - if height==nil - height=0 - if ch.tile_id > 0 - height=32 - elsif ch.character_name!="" - height=bmHeight(ch.character_name)/4 - end - end - ret=ch.screen_z(height) - return ret - end -end diff --git a/Data/Scripts/005_Sprites/013_Sprite_Player_Offsets.rb b/Data/Scripts/005_Sprites/013_Sprite_Player_Offsets.rb deleted file mode 100644 index 3618c71e5..000000000 --- a/Data/Scripts/005_Sprites/013_Sprite_Player_Offsets.rb +++ /dev/null @@ -1,35 +0,0 @@ - -#[FRAME1 [x,y]],[FRAME2 [x,y], etc.] -# -# exact number of pixels that the sprite needs to be moved for each frame -# add 2 pixels on even frames -module Outfit_Offsets - BASE_OFFSET = [[0, 0], [0, 0], [0, 0], [0, 0]] - - - RUN_OFFSETS_DOWN = [[0, 2], [0, 6], [0, 2], [0, 6]] - RUN_OFFSETS_LEFT = [[-2, -2], [-2, -2], [-2, -2], [-2, -2]] - RUN_OFFSETS_RIGHT = [[2, -2], [2, -2], [2, -2], [2, -2]] - RUN_OFFSETS_UP = [[0, -2], [0, -2], [0, -2], [0, -2]] - - SURF_OFFSETS_DOWN = [[0, -6], [0, -4], [0, -6], [0, -4]] - SURF_OFFSETS_LEFT = [[-2, -10], [-2, -8], [-2, -10], [-2, -8]] - SURF_OFFSETS_RIGHT = [[4, -10], [4, -8], [4, -10], [4, -8]] - #SURF_OFFSETS_UP = [[0, -6], [0, -4], [0, -6], [0, -4]] - SURF_OFFSETS_UP = [[0, -10], [0, -8], [0, -10], [0, -8]] - - DIVE_OFFSETS_DOWN = [[0, -6], [0, -4], [0, -6], [0, -4]] - DIVE_OFFSETS_LEFT = [[6, -8], [6, -6], [6, -8], [6, -6]] - DIVE_OFFSETS_RIGHT = [[-6, -8], [-6, -6], [-6, -8], [-6, -6]] - DIVE_OFFSETS_UP = [[0, -2], [0, 0], [0, -2], [0, 0]] - - BIKE_OFFSETS_DOWN = [[0, -2], [2, 0], [0, -2], [-2, 0]] - BIKE_OFFSETS_LEFT = [[-4, -4], [-2, -2], [-4, -4], [-6, -2]] - BIKE_OFFSETS_RIGHT = [[4, -4], [2, -2], [4, -4], [6, -2]] - BIKE_OFFSETS_UP = [[0, -2], [-2, 0], [0, -2], [2, 0]] - - FISH_OFFSETS_DOWN = [[0, -6], [0, -2], [0, -8], [2, -6]] - FISH_OFFSETS_LEFT = [[0, -8], [-6, -6], [0, -8], [2, -8]] - FISH_OFFSETS_RIGHT = [[0, -8], [6, -6], [0, -8], [-2, -8]] - FISH_OFFSETS_UP = [[0, -6], [0, -6], [0, -6], [2, -4]] -end diff --git a/Data/Scripts/005_Sprites/013_Sprite_Wearable.rb b/Data/Scripts/005_Sprites/013_Sprite_Wearable.rb deleted file mode 100644 index dc8bf2173..000000000 --- a/Data/Scripts/005_Sprites/013_Sprite_Wearable.rb +++ /dev/null @@ -1,170 +0,0 @@ -class Sprite_Wearable < RPG::Sprite - attr_accessor :filename - attr_accessor :action - attr_accessor :sprite - - def initialize(player_sprite, filename, action, viewport, relative_z=0) - @player_sprite = player_sprite - @viewport = viewport - @sprite = Sprite.new(@viewport) - @wearableBitmap = AnimatedBitmap.new(filename) if pbResolveBitmap(filename) - @filename = filename - @sprite.bitmap = @wearableBitmap.bitmap if @wearableBitmap - @action = action - @color = 0 - @frameWidth = 80 #@sprite.width - @frameHeight = 80 #@sprite.height / 4 - @sprite.z = 0 - @relative_z=relative_z #relative to player - echoln(_INTL("init had at z = {1}, player sprite at {2}",@sprite.z,@player_sprite.z)) - - #Unused position offset - # @x_pos_base_offset = 0 - # @y_pos_base_offset = 0 - end - - def apply_sprite_offset(offsets_array, current_frame) - @sprite.x += offsets_array[current_frame][0] - @sprite.y += offsets_array[current_frame][1] - end - - def adjustPositionForScreenScrolling - return if !$game_map.scrolling? && !@was_just_scrolling - if $game_map.scrolling? - @was_just_scrolling=true - else - @was_just_scrolling=false - end - offset_x = 0 - offset_y = 0 - case $game_map.scroll_direction - when DIRECTION_RIGHT - offset_x=-8 - when DIRECTION_LEFT - offset_x=8 - when DIRECTION_UP - offset_y=8 - @sprite.z+=50 #weird layering glitch for some reason otherwise. It's reset to the correct value in the next animation frame - when DIRECTION_DOWN - offset_y=-8 - end - @sprite.x+=offset_x - @sprite.y+=offset_y - end - - - def set_sprite_position(action, direction, current_frame) - @sprite.x = @player_sprite.x - @player_sprite.ox - @sprite.y = @player_sprite.y - @player_sprite.oy - case action - when "run" - if direction == DIRECTION_DOWN - apply_sprite_offset(Outfit_Offsets::RUN_OFFSETS_DOWN, current_frame) - elsif direction == DIRECTION_LEFT - apply_sprite_offset(Outfit_Offsets::RUN_OFFSETS_LEFT, current_frame) - elsif direction == DIRECTION_RIGHT - apply_sprite_offset(Outfit_Offsets::RUN_OFFSETS_RIGHT, current_frame) - elsif direction == DIRECTION_UP - apply_sprite_offset(Outfit_Offsets::RUN_OFFSETS_UP, current_frame) - end - when "surf" - if direction == DIRECTION_DOWN - apply_sprite_offset(Outfit_Offsets::SURF_OFFSETS_DOWN,current_frame) - elsif direction == DIRECTION_LEFT - apply_sprite_offset( Outfit_Offsets::SURF_OFFSETS_LEFT,current_frame) - elsif direction == DIRECTION_RIGHT - apply_sprite_offset( Outfit_Offsets::SURF_OFFSETS_RIGHT,current_frame) - elsif direction == DIRECTION_UP - apply_sprite_offset( Outfit_Offsets::SURF_OFFSETS_UP,current_frame) - end - when "dive" - if direction == DIRECTION_DOWN - apply_sprite_offset(Outfit_Offsets::DIVE_OFFSETS_DOWN,current_frame) - elsif direction == DIRECTION_LEFT - apply_sprite_offset( Outfit_Offsets::DIVE_OFFSETS_LEFT,current_frame) - elsif direction == DIRECTION_RIGHT - apply_sprite_offset( Outfit_Offsets::DIVE_OFFSETS_RIGHT,current_frame) - elsif direction == DIRECTION_UP - apply_sprite_offset( Outfit_Offsets::DIVE_OFFSETS_UP,current_frame) - end - when "bike" - if direction == DIRECTION_DOWN - apply_sprite_offset(Outfit_Offsets::BIKE_OFFSETS_DOWN,current_frame) - elsif direction == DIRECTION_LEFT - apply_sprite_offset( Outfit_Offsets::BIKE_OFFSETS_LEFT,current_frame) - elsif direction == DIRECTION_RIGHT - apply_sprite_offset( Outfit_Offsets::BIKE_OFFSETS_RIGHT,current_frame) - elsif direction == DIRECTION_UP - apply_sprite_offset( Outfit_Offsets::BIKE_OFFSETS_UP,current_frame) - end - when "fish" - if direction == DIRECTION_DOWN - apply_sprite_offset(Outfit_Offsets::FISH_OFFSETS_DOWN,current_frame) - elsif direction == DIRECTION_LEFT - apply_sprite_offset( Outfit_Offsets::FISH_OFFSETS_LEFT,current_frame) - elsif direction == DIRECTION_RIGHT - apply_sprite_offset( Outfit_Offsets::FISH_OFFSETS_RIGHT,current_frame) - elsif direction == DIRECTION_UP - apply_sprite_offset( Outfit_Offsets::FISH_OFFSETS_UP,current_frame) - end - else - @sprite.x = @player_sprite.x - @player_sprite.ox - @sprite.y = @player_sprite.y - @player_sprite.oy - end - adjustPositionForScreenScrolling() - - @sprite.y -= 2 if current_frame % 2 == 1 - end - - - def animate(action, frame=nil) - @action = action - current_frame = @player_sprite.character.pattern if !frame - direction = @player_sprite.character.direction - crop_spritesheet(direction) - adjust_layer() - set_sprite_position(@action, direction, current_frame) - end - - def update(action, filename,color) - @sprite.opacity = @player_sprite.opacity if @wearableBitmap - if filename != @filename || color != @color - if pbResolveBitmap(filename) - #echoln pbResolveBitmap(filename) - @wearableBitmap = AnimatedBitmap.new(filename,color) - @sprite.bitmap = @wearableBitmap.bitmap - else - @wearableBitmap = nil - @sprite.bitmap = nil - end - @color =color - @filename = filename - end - animate(action) - end - - def adjust_layer() - if @sprite.z != @player_sprite.z+@relative_z - @sprite.z = @player_sprite.z+@relative_z - end - end - - def crop_spritesheet(direction) - sprite_x = 0 - sprite_y = ((direction - 2) / 2) * @frameHeight - @sprite.src_rect.set(sprite_x, sprite_y, @frameWidth, @frameHeight) - end - - def dispose - return if @disposed - @sprite.dispose if @sprite - @sprite = nil - @disposed = true - end - - def disposed? - @disposed - end - - -end diff --git a/Data/Scripts/005_Sprites/014_Sprite_Hair.rb b/Data/Scripts/005_Sprites/014_Sprite_Hair.rb deleted file mode 100644 index e020e7145..000000000 --- a/Data/Scripts/005_Sprites/014_Sprite_Hair.rb +++ /dev/null @@ -1,85 +0,0 @@ -class Sprite_Hair < Sprite_Wearable - def initialize(player_sprite, filename, action, viewport) - super - @relative_z = 1 - - #@sprite.z = @player_sprite.z + 1 - end - - def animate(action, frame = nil) - @action = action - current_frame = @player_sprite.character.pattern if !frame - direction = @player_sprite.character.direction - crop_spritesheet(direction, current_frame, action) - adjust_layer() - set_sprite_position(@action, direction, current_frame) - end - - def crop_spritesheet(direction, current_frame, action) - sprite_x = ((current_frame)) * @frameWidth - # Don't animate surf - sprite_x = 0 if action == "surf" - - sprite_y = ((direction - 2) / 2) * @frameHeight - @sprite.src_rect.set(sprite_x, sprite_y, @frameWidth, @frameHeight) - end - - def set_sprite_position(action, direction, current_frame) - @sprite.x = @player_sprite.x - @player_sprite.ox - @sprite.y = @player_sprite.y - @player_sprite.oy - case action - when "run" - if direction == DIRECTION_DOWN - apply_sprite_offset(Outfit_Offsets::RUN_OFFSETS_DOWN, current_frame) - elsif direction == DIRECTION_LEFT - apply_sprite_offset(Outfit_Offsets::RUN_OFFSETS_LEFT, current_frame) - elsif direction == DIRECTION_RIGHT - apply_sprite_offset(Outfit_Offsets::RUN_OFFSETS_RIGHT, current_frame) - elsif direction == DIRECTION_UP - apply_sprite_offset(Outfit_Offsets::RUN_OFFSETS_UP, current_frame) - end - when "surf" - if direction == DIRECTION_DOWN # Always animate as if on the first frame - apply_sprite_offset(Outfit_Offsets::SURF_OFFSETS_DOWN, 0) - elsif direction == DIRECTION_LEFT - apply_sprite_offset(Outfit_Offsets::SURF_OFFSETS_LEFT, 0) - elsif direction == DIRECTION_RIGHT - apply_sprite_offset(Outfit_Offsets::SURF_OFFSETS_RIGHT, 0) - elsif direction == DIRECTION_UP - apply_sprite_offset(Outfit_Offsets::SURF_OFFSETS_UP, 0) - end - when "dive" - if direction == DIRECTION_DOWN - apply_sprite_offset(Outfit_Offsets::DIVE_OFFSETS_DOWN, current_frame) - elsif direction == DIRECTION_LEFT - apply_sprite_offset(Outfit_Offsets::DIVE_OFFSETS_LEFT, current_frame) - elsif direction == DIRECTION_RIGHT - apply_sprite_offset(Outfit_Offsets::DIVE_OFFSETS_RIGHT, current_frame) - elsif direction == DIRECTION_UP - apply_sprite_offset(Outfit_Offsets::DIVE_OFFSETS_UP, current_frame) - end - when "bike" - if direction == DIRECTION_DOWN - apply_sprite_offset(Outfit_Offsets::BIKE_OFFSETS_DOWN, current_frame) - elsif direction == DIRECTION_LEFT - apply_sprite_offset(Outfit_Offsets::BIKE_OFFSETS_LEFT, current_frame) - elsif direction == DIRECTION_RIGHT - apply_sprite_offset(Outfit_Offsets::BIKE_OFFSETS_RIGHT, current_frame) - elsif direction == DIRECTION_UP - apply_sprite_offset(Outfit_Offsets::BIKE_OFFSETS_UP, current_frame) - end - when "fish" - if direction == DIRECTION_DOWN - apply_sprite_offset(Outfit_Offsets::FISH_OFFSETS_DOWN, current_frame) - elsif direction == DIRECTION_LEFT - apply_sprite_offset(Outfit_Offsets::FISH_OFFSETS_LEFT, current_frame) - elsif direction == DIRECTION_RIGHT - apply_sprite_offset(Outfit_Offsets::FISH_OFFSETS_RIGHT, current_frame) - elsif direction == DIRECTION_UP - apply_sprite_offset(Outfit_Offsets::FISH_OFFSETS_UP, current_frame) - end - end - adjustPositionForScreenScrolling() - end - -end \ No newline at end of file diff --git a/Data/Scripts/005_Sprites/014_Sprite_Hat.rb b/Data/Scripts/005_Sprites/014_Sprite_Hat.rb deleted file mode 100644 index 75191ab3d..000000000 --- a/Data/Scripts/005_Sprites/014_Sprite_Hat.rb +++ /dev/null @@ -1,8 +0,0 @@ -class Sprite_Hat < Sprite_Wearable - def initialize(player_sprite, filename, action, viewport, relative_z=2) - super - @relative_z = relative_z - #@sprite.z = @player_sprite.z + 2 - - end -end \ No newline at end of file diff --git a/Data/Scripts/005_Sprites/016_Sprite_Player.rb b/Data/Scripts/005_Sprites/016_Sprite_Player.rb deleted file mode 100644 index b3f069d80..000000000 --- a/Data/Scripts/005_Sprites/016_Sprite_Player.rb +++ /dev/null @@ -1,116 +0,0 @@ -class Sprite_Player < Sprite_Character - def initialize(viewport, character = nil) - super - @viewport = viewport - @outfit_bitmap = nil - # @hat_bitmap = nil - # @hat2_bitmap = nil - - hatFilename = "" - hairFilename = "" - @hat = Sprite_Hat.new(self, hatFilename, @character_name, @viewport,3) - @hat2 = Sprite_Hat.new(self, hatFilename, @character_name, @viewport,2) - @hair = Sprite_Hair.new(self, hairFilename, @character_name, @viewport) - - @previous_skinTone = 0 - - @current_bitmap = nil - @previous_action =nil - echoln "init playa" - getClothedPlayerSprite(true) - end - - - def updateCharacterBitmap - skinTone = $Trainer.skin_tone ? $Trainer.skin_tone : 0 - baseBitmapFilename = getBaseOverworldSpriteFilename(@character_name, skinTone) - if !pbResolveBitmap(baseBitmapFilename) - baseBitmapFilename = Settings::PLAYER_GRAPHICS_FOLDER + @character_name - end - AnimatedBitmap.new(baseBitmapFilename, @character_hue) - end - - def applyDayNightTone - super - pbDayNightTint(@hat.sprite) if @hat && @hat.sprite.bitmap - pbDayNightTint(@hat2.sprite) if @hat2 && @hat2.sprite.bitmap - pbDayNightTint(@hair.sprite) if @hair && @hair.sprite.bitmap - end - - def opacity=(value) - super - @hat.sprite.opacity= value if @hat && @hat.sprite.bitmap - @hat2.sprite.opacity= value if @hat2 && @hat2.sprite.bitmap - @hair.sprite.opacity= value if @hair && @hair.sprite.bitmap - end - - def getClothedPlayerSprite(forceUpdate=false) - if @previous_action != @character_name || forceUpdate - @current_bitmap = generateClothedBitmap - end - @previous_action = @character_name - @hair.animate(@character_name) if @hair - @hat.animate(@character_name) if @hat - @hat2.animate(@character_name) if @hat2 - return @current_bitmap - end - - - def generateClothedBitmap() - @charbitmap.bitmap.clone #nekkid sprite - baseBitmap = @charbitmap.bitmap.clone #nekkid sprite - - outfitFilename = getOverworldOutfitFilename($Trainer.clothes, @character_name) # - outfitFilename = getOverworldOutfitFilename(Settings::PLAYER_TEMP_OUTFIT_FALLBACK) if !pbResolveBitmap(outfitFilename) - hairFilename = getOverworldHairFilename($Trainer.hair) - hatFilename = getOverworldHatFilename($Trainer.hat) - hat2Filename = getOverworldHatFilename($Trainer.hat2) - - hair_color_shift = $Trainer.hair_color - hat_color_shift = $Trainer.hat_color - hat2_color_shift = $Trainer.hat2_color - - clothes_color_shift = $Trainer.clothes_color - - hair_color_shift = 0 if !hair_color_shift - hat_color_shift = 0 if !hat_color_shift - hat2_color_shift = 0 if !hat2_color_shift - - clothes_color_shift = 0 if !clothes_color_shift - @hair.update(@character_name, hairFilename, hair_color_shift) if @hair - @hat.update(@character_name, hatFilename, hat_color_shift) if @hat - @hat2.update(@character_name, hat2Filename, hat2_color_shift) if @hat2 - - if !pbResolveBitmap(outfitFilename) - raise "No temp clothes graphics available" - end - - outfitBitmap = AnimatedBitmap.new(outfitFilename, clothes_color_shift) if pbResolveBitmap(outfitFilename) - baseBitmap.blt(0, 0, outfitBitmap.bitmap, outfitBitmap.bitmap.rect) if outfitBitmap - @previous_action = @character_name - return baseBitmap - end - - - - - def update - super - end - - def dispose - super - @hat.dispose if @hat - @hat2.dispose if @hat2 - @hair.dispose if @hair - end - - def pbLoadOutfitBitmap(outfitFileName) - begin - outfitBitmap = RPG::Cache.load_bitmap("", outfitFileName) - return outfitBitmap - rescue - return nil - end - end -end diff --git a/Data/Scripts/006_Map renderer/001_TilemapRenderer.rb b/Data/Scripts/006_Map renderer/001_TilemapRenderer.rb deleted file mode 100644 index 0e715f959..000000000 --- a/Data/Scripts/006_Map renderer/001_TilemapRenderer.rb +++ /dev/null @@ -1,670 +0,0 @@ -#=============================================================================== -# -#=============================================================================== -class TilemapRenderer - attr_reader :tilesets - attr_reader :autotiles - attr_reader :custom_autotile_ids - attr_accessor :tone - attr_accessor :color - attr_reader :viewport - attr_accessor :ox # Does nothing - attr_accessor :oy # Does nothing - attr_accessor :visible # Does nothing - - DISPLAY_TILE_WIDTH = Game_Map::TILE_WIDTH rescue 32 - DISPLAY_TILE_HEIGHT = Game_Map::TILE_HEIGHT rescue 32 - SOURCE_TILE_WIDTH = 32 - SOURCE_TILE_HEIGHT = 32 - ZOOM_X = DISPLAY_TILE_WIDTH / SOURCE_TILE_WIDTH - ZOOM_Y = DISPLAY_TILE_HEIGHT / SOURCE_TILE_HEIGHT - TILESET_TILES_PER_ROW = 8 - AUTOTILES_COUNT = 8 # Counting the blank tile as an autotile - TILES_PER_AUTOTILE = 48 - TILESET_START_ID = AUTOTILES_COUNT * TILES_PER_AUTOTILE - # If an autotile's filename ends with "[x]", its frame duration will be x/20 - # seconds instead. - AUTOTILE_FRAME_DURATION = 5 # In 1/20ths of a second - - # Filenames of extra autotiles for each tileset. Each tileset's entry is an - # array containing two other arrays (you can leave either of those empty, but - # they must be defined): - # - The first sub-array is for large autotiles, i.e. ones with 48 different - # tile layouts. For example, "Brick path" and "Sea". - # - The second is for single tile autotiles. For example, "Flowers1" and - # "Waterfall" - # The top tiles of the tileset will instead use these autotiles. Large - # autotiles come first, in the same 8x6 layout as you see when you double- - # click on a real autotile in RMXP. After that are the single tile autotiles. - # Extra autotiles are only useful if the tiles are animated, because otherwise - # you just have some tiles which belong in the tileset instead. - - # Examples: - # 1 => [["Sand shore"], ["Flowers2"]], - # 2 => [[], ["Flowers2", "Waterfall", "Waterfall crest", "Waterfall bottom"]], - # 6 => [["Water rock", "Sea deep"], []] - - EXTRA_AUTOTILES = { - 23 => { - 1232 => "flowers_orange[10]", - 1240 => "flowers_pink[10]", - 1248 => "flowers_yellow[10]", - 1256 => "flowers_blue[10]", - 1264 => "flowers_purple[10]", - 1272 => "flowers_red[10]", - 1280 => "flowers_grey[10]", - 1288 => "flowers_white[10]", - - }, - 30 => { - 2620 => "flowers_orange[10]", - 2628 => "flowers_pink[10]", - 2636 => "flowers_yellow[10]", - 2644 => "flowers_blue[10]", - 2652 => "flowers_purple[10]", - 2660 => "flowers_red[10]", - 2668 => "flowers_grey[10]", - 2676 => "flowers_white[10]", - } - } - - #============================================================================= - # - #============================================================================= - class TilesetBitmaps - attr_accessor :changed - attr_accessor :bitmaps - - def initialize - @bitmaps = {} - @bitmap_wraps = {} # Whether each tileset is a mega texture and has multiple columns - @load_counts = {} - @bridge = 0 - @changed = true - end - - def [](filename) - return @bitmaps[filename] - end - - def []=(filename, bitmap) - return if nil_or_empty?(filename) - @bitmaps[filename] = bitmap - @bitmap_wraps[filename] = false - @changed = true - end - - def add(filename) - return if nil_or_empty?(filename) - if @bitmaps[filename] - @load_counts[filename] += 1 - return - end - bitmap = pbGetTileset(filename) - @bitmap_wraps[filename] = false - if bitmap.mega? - self[filename] = TilemapRenderer::TilesetWrapper.wrapTileset(bitmap) - @bitmap_wraps[filename] = true - bitmap.dispose - else - self[filename] = bitmap - end - @load_counts[filename] = 1 - end - - def remove(filename) - return if nil_or_empty?(filename) || !@bitmaps[filename] - if @load_counts[filename] > 1 - @load_counts[filename] -= 1 - return - end - @bitmaps[filename].dispose - @bitmaps.delete(filename) - @bitmap_wraps.delete(filename) - @load_counts.delete(filename) - end - - def set_src_rect(tile, tile_id) - return if nil_or_empty?(tile.filename) - return if !@bitmaps[tile.filename] - tile.src_rect.x = ((tile_id - TILESET_START_ID) % TILESET_TILES_PER_ROW) * SOURCE_TILE_WIDTH - tile.src_rect.y = ((tile_id - TILESET_START_ID) / TILESET_TILES_PER_ROW) * SOURCE_TILE_HEIGHT - if @bitmap_wraps[tile.filename] - height = @bitmaps[tile.filename].height - col = (tile_id - TILESET_START_ID) * SOURCE_TILE_HEIGHT / (TILESET_TILES_PER_ROW * height) - tile.src_rect.x += col * TILESET_TILES_PER_ROW * SOURCE_TILE_WIDTH - tile.src_rect.y -= col * height - end - end - - def update; end - end - - #============================================================================= - # - #============================================================================= - class AutotileBitmaps < TilesetBitmaps - attr_reader :current_frames - - def initialize - super - @frame_counts = {} # Number of frames in each autotile - @frame_durations = {} # How long each frame lasts per autotile - @current_frames = {} # Which frame each autotile is currently showing - @timer = 0.0 # System.uptime - end - - def []=(filename, value) - super - return if nil_or_empty?(filename) - frame_count(filename, true) - set_current_frame(filename) - end - - def add(filename) - return if nil_or_empty?(filename) - if @bitmaps[filename] - @load_counts[filename] += 1 - return - end - orig_bitmap = pbGetAutotile(filename) - @bitmap_wraps[filename] = false - duration = AUTOTILE_FRAME_DURATION - if filename[/\[\s*(\d+?)\s*\]\s*$/] - duration = $~[1].to_i - end - @frame_durations[filename] = duration.to_f / 20 - bitmap = AutotileExpander.expand(orig_bitmap) - self[filename] = bitmap - if bitmap.height > SOURCE_TILE_HEIGHT && bitmap.height < TILES_PER_AUTOTILE * SOURCE_TILE_HEIGHT - @bitmap_wraps[filename] = true - end - orig_bitmap.dispose if orig_bitmap != bitmap - @load_counts[filename] = 1 - end - - def remove(filename) - super - return if @load_counts[filename] && @load_counts[filename] > 0 - @frame_counts.delete(filename) - @current_frames.delete(filename) - @frame_durations.delete(filename) - end - - def frame_count(filename, force_recalc = false) - if !@frame_counts[filename] || force_recalc - return 0 if !@bitmaps[filename] - bitmap = @bitmaps[filename] - @frame_counts[filename] = [bitmap.width / SOURCE_TILE_WIDTH, 1].max - if bitmap.height > SOURCE_TILE_HEIGHT && @bitmap_wraps[filename] - @frame_counts[filename] /= 2 - end - end - return @frame_counts[filename] - end - - def animated?(filename) - return frame_count(filename) > 1 - end - - def current_frame(filename) - set_current_frame(filename) if !@current_frames[filename] - return @current_frames[filename] - end - - def set_current_frame(filename) - frames = frame_count(filename) - if frames < 2 - @current_frames[filename] = 0 - else - @current_frames[filename] = (@timer / @frame_durations[filename]).floor % frames - end - end - - def set_src_rect(tile, tile_id) - filename = tile.filename - - # Check if this tile_id was overridden to use a specific autotile - override_filename = @custom_autotile_ids && @custom_autotile_ids[tile_id] - filename = override_filename if override_filename - - return if nil_or_empty?(filename) - return unless @bitmaps[filename] - - frame = current_frame(filename) - - if @bitmaps[filename].height == SOURCE_TILE_HEIGHT - tile.src_rect.x = frame * SOURCE_TILE_WIDTH - tile.src_rect.y = 0 - return - end - - wraps = @bitmap_wraps[filename] - high_id = ((tile_id % TILES_PER_AUTOTILE) >= TILES_PER_AUTOTILE / 2) - tile.src_rect.x = 0 - tile.src_rect.y = (tile_id % TILES_PER_AUTOTILE) * SOURCE_TILE_HEIGHT - if wraps && high_id - tile.src_rect.x = SOURCE_TILE_WIDTH - tile.src_rect.y -= SOURCE_TILE_HEIGHT * TILES_PER_AUTOTILE / 2 - end - tile.src_rect.x += frame * SOURCE_TILE_WIDTH * (wraps ? 2 : 1) - - # Override the filename in the tile object for consistency - tile.filename = filename if override_filename - end - - def update - super - @timer += Graphics.delta_s - # Update the current frame for each autotile - @bitmaps.each_key do |filename| - next if !@bitmaps[filename] || @bitmaps[filename].disposed? - old_frame = @current_frames[filename] - set_current_frame(filename) - @changed = true if @current_frames[filename] != old_frame - end - end - end - - #============================================================================= - # - #============================================================================= - class TileSprite < Sprite - attr_accessor :filename - attr_accessor :tile_id - attr_accessor :is_autotile - attr_accessor :animated - attr_accessor :priority - attr_accessor :shows_reflection - attr_accessor :bridge - attr_accessor :need_refresh - - def set_bitmap(filename, tile_id, autotile, animated, priority, bitmap) - self.bitmap = bitmap - self.src_rect = Rect.new(0, 0, SOURCE_TILE_WIDTH, SOURCE_TILE_HEIGHT) - self.zoom_x = ZOOM_X - self.zoom_y = ZOOM_Y - @filename = filename - @tile_id = tile_id - @is_autotile = autotile - @animated = animated - @priority = priority - @shows_reflection = false - @bridge = false - self.visible = !bitmap.nil? - @need_refresh = true - end - end - - #----------------------------------------------------------------------------- - - def initialize(viewport) - @tilesets = TilesetBitmaps.new - @autotiles = AutotileBitmaps.new - @custom_autotile_ids = {} # key: tile_id, value: filename - @tiles_horizontal_count = (Graphics.width.to_f / DISPLAY_TILE_WIDTH).ceil + 1 - @tiles_vertical_count = (Graphics.height.to_f / DISPLAY_TILE_HEIGHT).ceil + 1 - @tone = Tone.new(0, 0, 0, 0) - @old_tone = Tone.new(0, 0, 0, 0) - @color = Color.new(0, 0, 0, 0) - @old_color = Color.new(0, 0, 0, 0) - @self_viewport = Viewport.new(0, 0, Graphics.width, Graphics.height) - @viewport = (viewport) ? viewport : @self_viewport - @old_viewport_ox = 0 - @old_viewport_oy = 0 - # NOTE: The extra tiles horizontally/vertically hang off the left and top - # edges of the screen, because the pixel_offset values are positive - # and are added to the tile sprite coordinates. - @tiles = [] - @tiles_horizontal_count.times do |i| - @tiles[i] = [] - @tiles_vertical_count.times do |j| - @tiles[i][j] = Array.new(3) { TileSprite.new(@viewport) } - end - end - @current_map_id = 0 - @tile_offset_x = 0 - @tile_offset_y = 0 - @pixel_offset_x = 0 - @pixel_offset_y = 0 - @ox = 0 - @oy = 0 - @visible = true - @need_refresh = true - @disposed = false - end - - def dispose - return if disposed? - @tiles.each do |col| - col.each do |coord| - coord.each { |tile| tile.dispose } - coord.clear - end - end - @tiles.clear - @tilesets.bitmaps.each_value { |bitmap| bitmap.dispose } - @tilesets.bitmaps.clear - @autotiles.bitmaps.each_value { |bitmap| bitmap.dispose } - @autotiles.bitmaps.clear - @self_viewport.dispose - @self_viewport = nil - @disposed = true - end - - def disposed? - return @disposed - end - - #----------------------------------------------------------------------------- - - def add_tileset(filename) - @tilesets.add(filename) - end - - def remove_tileset(filename) - @tilesets.remove(filename) - end - - def add_autotile(filename) - @autotiles.add(filename) - end - - def remove_autotile(filename) - @autotiles.remove(filename) - end - - def add_extra_autotiles(tileset_id) - overrides = EXTRA_AUTOTILES[tileset_id] - return unless overrides - overrides.each do |tile_id, filename| - @autotiles.add(filename) - @custom_autotile_ids[tile_id] = filename - end - end - - def remove_extra_autotiles(tileset_id) - return if !EXTRA_AUTOTILES[tileset_id] - EXTRA_AUTOTILES[tileset_id].each do |arr| - arr.each { |filename| remove_autotile(filename) } - end - end - - #----------------------------------------------------------------------------- - - def refresh - @need_refresh = true - end - - def refresh_tile_bitmap(tile, map, tile_id) - tile.tile_id = tile_id - if tile_id < TILES_PER_AUTOTILE - tile.set_bitmap("", tile_id, false, false, 0, nil) - tile.shows_reflection = false - tile.bridge = false - else - terrain_tag = map.terrain_tags[tile_id] || 0 - terrain_tag_data = GameData::TerrainTag.try_get(terrain_tag) - priority = map.priorities[tile_id] || 0 - single_autotile_start_id = TILESET_START_ID - true_tileset_start_id = TILESET_START_ID - # extra_autotile_arrays = EXTRA_AUTOTILES[map.tileset_id] - # if extra_autotile_arrays - # large_autotile_count = extra_autotile_arrays[0].length - # single_autotile_count = extra_autotile_arrays[1].length - # single_autotile_start_id += large_autotile_count * TILES_PER_AUTOTILE - # true_tileset_start_id += large_autotile_count * TILES_PER_AUTOTILE - # true_tileset_start_id += single_autotile_count - # end - - filename = nil - extra_autotile_hash = EXTRA_AUTOTILES[map.tileset_id] - - if extra_autotile_hash && extra_autotile_hash[tile_id] - # Custom tile_id override - filename = extra_autotile_hash[tile_id] - tile.set_bitmap(filename, tile_id, true, @autotiles.animated?(filename), - priority, @autotiles[filename]) - elsif tile_id < true_tileset_start_id - # Default behavior - if tile_id < TILESET_START_ID # Real autotiles - filename = map.autotile_names[(tile_id / TILES_PER_AUTOTILE) - 1] - elsif tile_id < single_autotile_start_id # Large extra autotiles - filename = extra_autotile_arrays[0][(tile_id - TILESET_START_ID) / TILES_PER_AUTOTILE] - else - # Single extra autotiles - filename = extra_autotile_arrays[1][tile_id - single_autotile_start_id] - end - tile.set_bitmap(filename, tile_id, true, @autotiles.animated?(filename), - priority, @autotiles[filename]) - else - filename = map.tileset_name - tile.set_bitmap(filename, tile_id, false, false, priority, @tilesets[filename]) - end - - tile.shows_reflection = terrain_tag_data&.shows_reflections - tile.bridge = terrain_tag_data&.bridge - end - refresh_tile_src_rect(tile, tile_id) - end - - def refresh_tile_src_rect(tile, tile_id) - if tile.is_autotile - @autotiles.set_src_rect(tile, tile_id) - else - @tilesets.set_src_rect(tile, tile_id) - end - end - - # For animated autotiles only - def refresh_tile_frame(tile, tile_id) - return if !tile.animated - @autotiles.set_src_rect(tile, tile_id) - end - - # x and y are the positions of tile within @tiles, not a map x/y - def refresh_tile_coordinates(tile, x, y) - tile.x = (x * DISPLAY_TILE_WIDTH) - @pixel_offset_x - tile.y = (y * DISPLAY_TILE_HEIGHT) - @pixel_offset_y - end - - def refresh_tile_z(tile, map, y, layer, tile_id) - if tile.shows_reflection - tile.z = -100 - elsif tile.bridge && $PokemonGlobal.bridge > 0 - tile.z = 0 - else - priority = tile.priority - tile.z = (priority == 0) ? 0 : y * DISPLAY_TILE_HEIGHT + priority * 32 + 32 - end - end - - def refresh_tile(tile, x, y, map, layer, tile_id) - refresh_tile_bitmap(tile, map, tile_id) - refresh_tile_coordinates(tile, x, y) - refresh_tile_z(tile, map, y, layer, tile_id) - tile.need_refresh = false - end - - #----------------------------------------------------------------------------- - - def check_if_screen_moved - ret = false - # Check for map change - if @current_map_id != $game_map.map_id - if MapFactoryHelper.hasConnections?(@current_map_id) - offsets = $MapFactory.getRelativePos(@current_map_id, 0, 0, $game_map.map_id, 0, 0) - if offsets - @tile_offset_x -= offsets[0] - @tile_offset_y -= offsets[1] - else - ret = true # Need a full refresh - end - else - ret = true - end - @current_map_id = $game_map.map_id - end - # Check for tile movement - current_map_display_x = ($game_map.display_x.to_f / Game_Map::X_SUBPIXELS).round - current_map_display_y = ($game_map.display_y.to_f / Game_Map::Y_SUBPIXELS).round - new_tile_offset_x = (current_map_display_x / SOURCE_TILE_WIDTH) * ZOOM_X - new_tile_offset_y = (current_map_display_y / SOURCE_TILE_HEIGHT) * ZOOM_Y - if new_tile_offset_x != @tile_offset_x - if new_tile_offset_x > @tile_offset_x - # Take tile stacks off the right and insert them at the beginning (left) - (new_tile_offset_x - @tile_offset_x).times do - c = @tiles.shift - @tiles.push(c) - c.each do |coord| - coord.each { |tile| tile.need_refresh = true } - end - end - else - # Take tile stacks off the beginning (left) and push them onto the end (right) - (@tile_offset_x - new_tile_offset_x).times do - c = @tiles.pop - @tiles.prepend(c) - c.each do |coord| - coord.each { |tile| tile.need_refresh = true } - end - end - end - @screen_moved = true - @tile_offset_x = new_tile_offset_x - end - if new_tile_offset_y != @tile_offset_y - if new_tile_offset_y > @tile_offset_y - # Take tile stacks off the bottom and insert them at the beginning (top) - @tiles.each do |col| - (new_tile_offset_y - @tile_offset_y).times do - c = col.shift - col.push(c) - c.each { |tile| tile.need_refresh = true } - end - end - else - # Take tile stacks off the beginning (top) and push them onto the end (bottom) - @tiles.each do |col| - (@tile_offset_y - new_tile_offset_y).times do - c = col.pop - col.prepend(c) - c.each { |tile| tile.need_refresh = true } - end - end - end - @screen_moved = true - @screen_moved_vertically = true - @tile_offset_y = new_tile_offset_y - end - # Check for pixel movement - new_pixel_offset_x = (current_map_display_x % SOURCE_TILE_WIDTH) * ZOOM_X - new_pixel_offset_y = (current_map_display_y % SOURCE_TILE_HEIGHT) * ZOOM_Y - if new_pixel_offset_x != @pixel_offset_x - @screen_moved = true - @pixel_offset_x = new_pixel_offset_x - end - if new_pixel_offset_y != @pixel_offset_y - @screen_moved = true - @screen_moved_vertically = true - @pixel_offset_y = new_pixel_offset_y - end - return ret - end - - #----------------------------------------------------------------------------- - - def update - # Update tone - if @old_tone != @tone - @tiles.each do |col| - col.each do |coord| - coord.each { |tile| tile.tone = @tone } - end - end - @old_tone = @tone.clone - end - # Update color - if @old_color != @color - @tiles.each do |col| - col.each do |coord| - coord.each { |tile| tile.color = @color } - end - end - @old_color = @color.clone - end - # Recalculate autotile frames - @tilesets.update - @autotiles.update - do_full_refresh = @need_refresh - if @viewport.ox != @old_viewport_ox || @viewport.oy != @old_viewport_oy - @old_viewport_ox = @viewport.ox - @old_viewport_oy = @viewport.oy - do_full_refresh = true - end - # Check whether the screen has moved since the last update - @screen_moved = false - @screen_moved_vertically = false - if $PokemonGlobal.bridge != @bridge - @bridge = $PokemonGlobal.bridge - @screen_moved_vertically = true # To update bridge tiles' z values - end - do_full_refresh = true if check_if_screen_moved - # Update all tile sprites - visited = [] - @tiles_horizontal_count.times do |i| - visited[i] = [] - @tiles_vertical_count.times { |j| visited[i][j] = false } - end - $MapFactory.maps.each do |map| - # Calculate x/y ranges of tile sprites that represent them - map_display_x = (map.display_x.to_f / Game_Map::X_SUBPIXELS).round - map_display_x = ((map_display_x + (Graphics.width / 2)) * ZOOM_X) - (Graphics.width / 2) if ZOOM_X != 1 - map_display_y = (map.display_y.to_f / Game_Map::Y_SUBPIXELS).round - map_display_y = ((map_display_y + (Graphics.height / 2)) * ZOOM_Y) - (Graphics.height / 2) if ZOOM_Y != 1 - map_display_x_tile = map_display_x / DISPLAY_TILE_WIDTH - map_display_y_tile = map_display_y / DISPLAY_TILE_HEIGHT - start_x = [-map_display_x_tile, 0].max - start_y = [-map_display_y_tile, 0].max - end_x = @tiles_horizontal_count - 1 - end_x = [end_x, map.width - map_display_x_tile - 1].min - end_y = @tiles_vertical_count - 1 - end_y = [end_y, map.height - map_display_y_tile - 1].min - next if start_x > end_x || start_y > end_y || end_x < 0 || end_y < 0 - # Update all tile sprites representing this map - (start_x..end_x).each do |i| - tile_x = i + map_display_x_tile - (start_y..end_y).each do |j| - tile_y = j + map_display_y_tile - @tiles[i][j].each_with_index do |tile, layer| - tile_id = map.data[tile_x, tile_y, layer] - if do_full_refresh || tile.need_refresh || tile.tile_id != tile_id - refresh_tile(tile, i, j, map, layer, tile_id) - else - refresh_tile_frame(tile, tile_id) if tile.animated && @autotiles.changed - # Update tile's x/y coordinates - refresh_tile_coordinates(tile, i, j) if @screen_moved - # Update tile's z value - refresh_tile_z(tile, map, j, layer, tile_id) if @screen_moved_vertically - end - end - # Record x/y as visited - visited[i][j] = true - end - end - end - # Clear all unvisited tile sprites - @tiles.each_with_index do |col, i| - col.each_with_index do |coord, j| - next if visited[i][j] - coord.each do |tile| - tile.set_bitmap("", 0, false, false, 0, nil) - tile.shows_reflection = false - tile.bridge = false - end - end - end - @need_refresh = false - @autotiles.changed = false - end -end diff --git a/Data/Scripts/006_Map renderer/002_TilesetWrapper.rb b/Data/Scripts/006_Map renderer/002_TilesetWrapper.rb deleted file mode 100644 index 8873ccfbc..000000000 --- a/Data/Scripts/006_Map renderer/002_TilesetWrapper.rb +++ /dev/null @@ -1,97 +0,0 @@ -#=============================================================================== -# This module is a little fix that works around PC hardware limitations. Since -# Essentials isn't working with software rendering anymore, it now has to deal -# with the limits of the GPU. For the most part this is no big deal, but people -# do have some really big tilesets. -# -# The fix is simple enough: If your tileset is too big, a new bitmap will be -# constructed with all the excess pixels sent to the image's right side. This -# basically means that you now have a limit far higher than you should ever -# actually need. -# -# Hardware limit -> max tileset length: -# 1024px -> 4096px -# 2048px -> 16384px (enough to get the normal limit) -# 4096px -> 65536px (enough to load pretty much any tileset) -# 8192px -> 262144px -# 16384px -> 1048576px (what most people have at this point) -#=============================================================================== -class TilemapRenderer - module TilesetWrapper - TILESET_WIDTH = SOURCE_TILE_WIDTH * TILESET_TILES_PER_ROW - # Looks useless, but covers weird numbers given to mkxp.json or a funky driver - MAX_TEX_SIZE = (Bitmap.max_size / 1024) * 1024 - MAX_TEX_SIZE_BOOSTED = (MAX_TEX_SIZE**2) / TILESET_WIDTH - - module_function - - def wrapTileset(originalbmp) - width = originalbmp.width - height = originalbmp.height - if width == TILESET_WIDTH && originalbmp.mega? - columns = (height / MAX_TEX_SIZE.to_f).ceil - if columns * TILESET_WIDTH > MAX_TEX_SIZE - raise "Tileset is too long!\n\nSIZE: #{originalbmp.height}px\nHARDWARE LIMIT: #{MAX_TEX_SIZE}px\nBOOSTED LIMIT: #{MAX_TEX_SIZE_BOOSTED}px" - end - bmp = Bitmap.new(TILESET_WIDTH * columns, MAX_TEX_SIZE) - remainder = height % MAX_TEX_SIZE - remainder = MAX_TEX_SIZE if remainder == 0 - columns.times do |col| - srcrect = Rect.new(0, col * MAX_TEX_SIZE, width, (col + 1 == columns) ? remainder : MAX_TEX_SIZE) - bmp.blt(col * TILESET_WIDTH, 0, originalbmp, srcrect) - end - return bmp - end - return originalbmp - end - - def getWrappedRect(src_rect) - ret = Rect.new(0, 0, 0, 0) - col = (src_rect.y / MAX_TEX_SIZE.to_f).floor - ret.x = (col * TILESET_WIDTH) + src_rect.x.clamp(0, TILESET_WIDTH) - ret.y = src_rect.y % MAX_TEX_SIZE - ret.width = src_rect.width.clamp(0, TILESET_WIDTH - src_rect.x) - ret.height = src_rect.height.clamp(0, MAX_TEX_SIZE) - return ret - end - - #--------------------------------------------------------------------------- - - private - - def blitWrappedPixels(destX, destY, dest, src, srcrect) - if srcrect.y + srcrect.width < MAX_TEX_SIZE - # Save the processing power - dest.blt(destX, destY, src, srcrect) - return - end - merge = (srcrect.y % MAX_TEX_SIZE) > ((srcrect.y + srcrect.height) % MAX_TEX_SIZE) - srcrect_mod = getWrappedRect(srcrect) - if merge - # FIXME: won't work on heights longer than two columns, but nobody should need - # more than 32k pixels high at once anyway - side = { - :a => MAX_TEX_SIZE - srcrect_mod.y, - :b => srcrect_mod.height - MAX_TEX_SIZE + srcrect_mod.y - } - dest.blt(destX, destY, src, Rect.new(srcrect_mod.x, srcrect_mod.y, srcrect_mod.width, side[:a])) - dest.blt(destX, destY + side[:a], src, Rect.new(srcrect_mod.x + TILESET_WIDTH, 0, srcrect_mod.width, side[:b])) - else - dest.blt(destX, destY, src, srcrect_mod) - end - end - - def stretchBlitWrappedPixels(destrect, dest, src, srcrect) - if srcrect.y + srcrect.width < MAX_TEX_SIZE - # Save the processing power - dest.stretch_blt(destrect, src, srcrect) - return - end - # Does a regular blit to a non-megasurface, then stretch_blts that to - # the destination. Yes it is slow - tmp = Bitmap.new(srcrect.width, srcrect.height) - blitWrappedPixels(0, 0, tmp, src, srcrect) - dest.stretch_blt(destrect, tmp, Rect.new(0, 0, srcrect.width, srcrect.height)) - end - end -end diff --git a/Data/Scripts/006_Map renderer/003_AutotileExpander.rb b/Data/Scripts/006_Map renderer/003_AutotileExpander.rb deleted file mode 100644 index 2b0468a2b..000000000 --- a/Data/Scripts/006_Map renderer/003_AutotileExpander.rb +++ /dev/null @@ -1,75 +0,0 @@ -#=============================================================================== -# -#=============================================================================== -class TilemapRenderer - module AutotileExpander - MAX_TEXTURE_SIZE = (Bitmap.max_size / 1024) * 1024 - - module_function - - # This doesn't allow for cache sizes smaller than 768, but if that applies - # to you, you've got bigger problems. - def expand(bitmap) - return bitmap if bitmap.height == SOURCE_TILE_HEIGHT - expanded_format = (bitmap.height == SOURCE_TILE_HEIGHT * 6) - wrap = false - if MAX_TEXTURE_SIZE < TILES_PER_AUTOTILE * SOURCE_TILE_HEIGHT - wrap = true # Each autotile will occupy two columns instead of one - end - frames_count = [bitmap.width / (3 * SOURCE_TILE_WIDTH), 1].max - new_bitmap = Bitmap.new(frames_count * (wrap ? 2 : 1) * SOURCE_TILE_WIDTH, - TILES_PER_AUTOTILE * SOURCE_TILE_HEIGHT / (wrap ? 2 : 1)) - rect = Rect.new(0, 0, SOURCE_TILE_WIDTH / 2, SOURCE_TILE_HEIGHT / 2) - TILES_PER_AUTOTILE.times do |id| - pattern = TileDrawingHelper::AUTOTILE_PATTERNS[id >> 3][id % TILESET_TILES_PER_ROW] - wrap_offset_x = (wrap && id >= TILES_PER_AUTOTILE / 2) ? SOURCE_TILE_WIDTH : 0 - wrap_offset_y = (wrap && id >= TILES_PER_AUTOTILE / 2) ? (TILES_PER_AUTOTILE / 2) * SOURCE_TILE_HEIGHT : 0 - frames_count.times do |frame| - if expanded_format && [1, 2, 4, 8].include?(id) - dest_x = frame * SOURCE_TILE_WIDTH * (wrap ? 2 : 1) - dest_x += wrap_offset_x - next if dest_x > MAX_TEXTURE_SIZE - dest_y = id * SOURCE_TILE_HEIGHT - dest_y -= wrap_offset_y - next if dest_y > MAX_TEXTURE_SIZE - case id - when 1 # Top left corner - new_bitmap.blt(dest_x, dest_y, bitmap, - Rect.new(frame * SOURCE_TILE_WIDTH * 3, SOURCE_TILE_HEIGHT * 4, - SOURCE_TILE_WIDTH, SOURCE_TILE_HEIGHT)) - when 2 # Top right corner - new_bitmap.blt(dest_x, dest_y, bitmap, - Rect.new(SOURCE_TILE_WIDTH + (frame * SOURCE_TILE_WIDTH * 3), SOURCE_TILE_HEIGHT * 4, - SOURCE_TILE_WIDTH, SOURCE_TILE_HEIGHT)) - when 4 # Bottom right corner - new_bitmap.blt(dest_x, dest_y, bitmap, - Rect.new(SOURCE_TILE_WIDTH + (frame * SOURCE_TILE_WIDTH * 3), SOURCE_TILE_HEIGHT * 5, - SOURCE_TILE_WIDTH, SOURCE_TILE_HEIGHT)) - when 8 # Bottom left corner - new_bitmap.blt(dest_x, dest_y, bitmap, - Rect.new(frame * SOURCE_TILE_WIDTH * 3, SOURCE_TILE_HEIGHT * 5, - SOURCE_TILE_WIDTH, SOURCE_TILE_HEIGHT)) - end - next - end - pattern.each_with_index do |src_chunk, i| - real_src_chunk = src_chunk - 1 - dest_x = (i % 2) * SOURCE_TILE_WIDTH / 2 - dest_x += frame * SOURCE_TILE_WIDTH * (wrap ? 2 : 1) - dest_x += wrap_offset_x - next if dest_x > MAX_TEXTURE_SIZE - dest_y = (i / 2) * SOURCE_TILE_HEIGHT / 2 - dest_y += id * SOURCE_TILE_HEIGHT - dest_y -= wrap_offset_y - next if dest_y > MAX_TEXTURE_SIZE - rect.x = (real_src_chunk % 6) * SOURCE_TILE_WIDTH / 2 - rect.x += SOURCE_TILE_WIDTH * 3 * frame - rect.y = (real_src_chunk / 6) * SOURCE_TILE_HEIGHT / 2 - new_bitmap.blt(dest_x, dest_y, bitmap, rect) - end - end - end - return new_bitmap - end - end -end diff --git a/Data/Scripts/006_Map renderer/004_TileDrawingHelper.rb b/Data/Scripts/006_Map renderer/004_TileDrawingHelper.rb deleted file mode 100644 index a7e61c33a..000000000 --- a/Data/Scripts/006_Map renderer/004_TileDrawingHelper.rb +++ /dev/null @@ -1,246 +0,0 @@ -#=============================================================================== -# -#=============================================================================== -class TileDrawingHelper - attr_accessor :tileset - attr_accessor :autotiles - - AUTOTILE_PATTERNS = [ - [[27, 28, 33, 34], [5, 28, 33, 34], [27, 6, 33, 34], [5, 6, 33, 34], - [27, 28, 33, 12], [5, 28, 33, 12], [27, 6, 33, 12], [5, 6, 33, 12]], - [[27, 28, 11, 34], [5, 28, 11, 34], [27, 6, 11, 34], [5, 6, 11, 34], - [27, 28, 11, 12], [5, 28, 11, 12], [27, 6, 11, 12], [5, 6, 11, 12]], - [[25, 26, 31, 32], [25, 6, 31, 32], [25, 26, 31, 12], [25, 6, 31, 12], - [15, 16, 21, 22], [15, 16, 21, 12], [15, 16, 11, 22], [15, 16, 11, 12]], - [[29, 30, 35, 36], [29, 30, 11, 36], [5, 30, 35, 36], [5, 30, 11, 36], - [39, 40, 45, 46], [5, 40, 45, 46], [39, 6, 45, 46], [5, 6, 45, 46]], - [[25, 30, 31, 36], [15, 16, 45, 46], [13, 14, 19, 20], [13, 14, 19, 12], - [17, 18, 23, 24], [17, 18, 11, 24], [41, 42, 47, 48], [5, 42, 47, 48]], - [[37, 38, 43, 44], [37, 6, 43, 44], [13, 18, 19, 24], [13, 14, 43, 44], - [37, 42, 43, 48], [17, 18, 47, 48], [13, 18, 43, 48], [1, 2, 7, 8]] - ] - - # converts neighbors returned from tableNeighbors to tile indexes - NEIGHBORS_TO_AUTOTILE_INDEX = [ - 46, 44, 46, 44, 43, 41, 43, 40, 46, 44, 46, 44, 43, 41, 43, 40, - 42, 32, 42, 32, 35, 19, 35, 18, 42, 32, 42, 32, 34, 17, 34, 16, - 46, 44, 46, 44, 43, 41, 43, 40, 46, 44, 46, 44, 43, 41, 43, 40, - 42, 32, 42, 32, 35, 19, 35, 18, 42, 32, 42, 32, 34, 17, 34, 16, - 45, 39, 45, 39, 33, 31, 33, 29, 45, 39, 45, 39, 33, 31, 33, 29, - 37, 27, 37, 27, 23, 15, 23, 13, 37, 27, 37, 27, 22, 11, 22, 9, - 45, 39, 45, 39, 33, 31, 33, 29, 45, 39, 45, 39, 33, 31, 33, 29, - 36, 26, 36, 26, 21, 7, 21, 5, 36, 26, 36, 26, 20, 3, 20, 1, - 46, 44, 46, 44, 43, 41, 43, 40, 46, 44, 46, 44, 43, 41, 43, 40, - 42, 32, 42, 32, 35, 19, 35, 18, 42, 32, 42, 32, 34, 17, 34, 16, - 46, 44, 46, 44, 43, 41, 43, 40, 46, 44, 46, 44, 43, 41, 43, 40, - 42, 32, 42, 32, 35, 19, 35, 18, 42, 32, 42, 32, 34, 17, 34, 16, - 45, 38, 45, 38, 33, 30, 33, 28, 45, 38, 45, 38, 33, 30, 33, 28, - 37, 25, 37, 25, 23, 14, 23, 12, 37, 25, 37, 25, 22, 10, 22, 8, - 45, 38, 45, 38, 33, 30, 33, 28, 45, 38, 45, 38, 33, 30, 33, 28, - 36, 24, 36, 24, 21, 6, 21, 4, 36, 24, 36, 24, 20, 2, 20, 0 - ] - - def self.tableNeighbors(data, x, y, layer = nil) - return 0 if x < 0 || x >= data.xsize - return 0 if y < 0 || y >= data.ysize - if layer.nil? - t = data[x, y] - else - t = data[x, y, layer] - end - xp1 = [x + 1, data.xsize - 1].min - yp1 = [y + 1, data.ysize - 1].min - xm1 = [x - 1, 0].max - ym1 = [y - 1, 0].max - i = 0 - if layer.nil? - i |= 0x01 if data[ x, ym1] == t # N - i |= 0x02 if data[xp1, ym1] == t # NE - i |= 0x04 if data[xp1, y] == t # E - i |= 0x08 if data[xp1, yp1] == t # SE - i |= 0x10 if data[ x, yp1] == t # S - i |= 0x20 if data[xm1, yp1] == t # SW - i |= 0x40 if data[xm1, y] == t # W - i |= 0x80 if data[xm1, ym1] == t # NW - else - i |= 0x01 if data[ x, ym1, layer] == t # N - i |= 0x02 if data[xp1, ym1, layer] == t # NE - i |= 0x04 if data[xp1, y, layer] == t # E - i |= 0x08 if data[xp1, yp1, layer] == t # SE - i |= 0x10 if data[ x, yp1, layer] == t # S - i |= 0x20 if data[xm1, yp1, layer] == t # SW - i |= 0x40 if data[xm1, y, layer] == t # W - i |= 0x80 if data[xm1, ym1, layer] == t # NW - end - return i - end - - def self.fromTileset(tileset) - bmtileset = pbGetTileset(tileset.tileset_name) - bmautotiles = [] - 7.times do |i| - bmautotiles.push(pbGetAutotile(tileset.autotile_names[i])) - end - return self.new(bmtileset, bmautotiles) - end - - #----------------------------------------------------------------------------- - - def initialize(tileset, autotiles) - if tileset.mega? - @tileset = TilemapRenderer::TilesetWrapper.wrapTileset(tileset) - tileset.dispose - @shouldWrap = true - else - @tileset = tileset - @shouldWrap = false - end - @autotiles = autotiles - end - - def dispose - @tileset&.dispose - @tileset = nil - @autotiles.each_with_index do |autotile, i| - autotile.dispose - @autotiles[i] = nil - end - end - - def bltSmallAutotile(bitmap, x, y, cxTile, cyTile, id, frame) - return if id >= 384 || frame < 0 || !@autotiles - autotile = @autotiles[(id / 48) - 1] - return if !autotile || autotile.disposed? - cxTile = [cxTile / 2, 1].max - cyTile = [cyTile / 2, 1].max - if autotile.height == 32 - anim = frame * 32 - src_rect = Rect.new(anim, 0, 32, 32) - bitmap.stretch_blt(Rect.new(x, y, cxTile * 2, cyTile * 2), autotile, src_rect) - else - anim = frame * 96 - id %= 48 - tiles = AUTOTILE_PATTERNS[id >> 3][id & 7] - src = Rect.new(0, 0, 0, 0) - 4.times do |i| - tile_position = tiles[i] - 1 - src.set(((tile_position % 6) * 16) + anim, (tile_position / 6) * 16, 16, 16) - bitmap.stretch_blt(Rect.new((i % 2 * cxTile) + x, (i / 2 * cyTile) + y, cxTile, cyTile), - autotile, src) - end - end - end - - def bltSmallRegularTile(bitmap, x, y, cxTile, cyTile, id) - return if id < 384 || !@tileset || @tileset.disposed? - rect = Rect.new(((id - 384) % 8) * 32, ((id - 384) / 8) * 32, 32, 32) - rect = TilemapRenderer::TilesetWrapper.getWrappedRect(rect) if @shouldWrap - bitmap.stretch_blt(Rect.new(x, y, cxTile, cyTile), @tileset, rect) - end - - def bltSmallTile(bitmap, x, y, cxTile, cyTile, id, frame = 0) - if id >= 384 - bltSmallRegularTile(bitmap, x, y, cxTile, cyTile, id) - elsif id > 0 - bltSmallAutotile(bitmap, x, y, cxTile, cyTile, id, frame) - end - end - - def bltAutotile(bitmap, x, y, id, frame) - bltSmallAutotile(bitmap, x, y, 32, 32, id, frame) - end - - def bltRegularTile(bitmap, x, y, id) - bltSmallRegularTile(bitmap, x, y, 32, 32, id) - end - - def bltTile(bitmap, x, y, id, frame = 0) - if id >= 384 - bltRegularTile(bitmap, x, y, id) - elsif id > 0 - bltAutotile(bitmap, x, y, id, frame) - end - end -end - -#=============================================================================== -# -#=============================================================================== -def createMinimap(mapid) - map = load_data(sprintf("Data/Map%03d.rxdata", mapid)) rescue nil - return Bitmap.new(32, 32) if !map - bitmap = Bitmap.new(map.width * 4, map.height * 4) - black=Color.new(0,0,0) - tilesets = $data_tilesets - tileset = tilesets[map.tileset_id] - return bitmap if !tileset - helper = TileDrawingHelper.fromTileset(tileset) - map.height.times do |y| - map.width.times do |x| - 3.times do |z| - id = map.data[x, y, z] - id = 0 if !id - helper.bltSmallTile(bitmap, x * 4, y * 4, 4, 4, id) - end - end - end - bitmap.fill_rect(0, 0, bitmap.width, 1, black) - bitmap.fill_rect(0, bitmap.height - 1, bitmap.width, 1, black) - bitmap.fill_rect(0, 0, 1, bitmap.height, black) - bitmap.fill_rect(bitmap.width - 1, 0, 1, bitmap.height, black) - return bitmap -end - -def bltMinimapAutotile(dstBitmap, x, y, srcBitmap, id) - return if id >= 48 || !srcBitmap || srcBitmap.disposed? - anim = 0 - cxTile = 3 - cyTile = 3 - tiles = TileDrawingHelper::AUTOTILE_PATTERNS[id >> 3][id & 7] - src = Rect.new(0, 0, 0, 0) - 4.times do |i| - tile_position = tiles[i] - 1 - src.set((tile_position % 6 * cxTile) + anim, - tile_position / 6 * cyTile, cxTile, cyTile) - dstBitmap.blt((i % 2 * cxTile) + x, (i / 2 * cyTile) + y, srcBitmap, src) - end -end - -def passable?(passages, tile_id) - return false if tile_id.nil? - passage = passages[tile_id] - return (passage && passage < 15) -end - -# Unused -def getPassabilityMinimap(mapid) - map = load_data(sprintf("Data/Map%03d.rxdata", mapid)) - tileset = $data_tilesets[map.tileset_id] - minimap = AnimatedBitmap.new("Graphics/UI/minimap_tiles") - ret = Bitmap.new(map.width * 6, map.height * 6) - passtable = Table.new(map.width, map.height) - passages = tileset.passages - map.width.times do |i| - map.height.times do |j| - pass = true - [2, 1, 0].each do |z| - if !passable?(passages, map.data[i, j, z]) - pass = false - break - end - end - passtable[i, j] = pass ? 1 : 0 - end - end - neighbors = TileDrawingHelper::NEIGHBORS_TO_AUTOTILE_INDEX - map.width.times do |i| - map.height.times do |j| - next if passtable[i, j] != 0 - nb = TileDrawingHelper.tableNeighbors(passtable, i, j) - tile = neighbors[nb] - bltMinimapAutotile(ret, i * 6, j * 6, minimap.bitmap, tile) - end - end - minimap.dispose - return ret -end diff --git a/Data/Scripts/007_Objects and windows/001_RPG_Cache.rb b/Data/Scripts/007_Objects and windows/001_RPG_Cache.rb deleted file mode 100644 index 9983699a4..000000000 --- a/Data/Scripts/007_Objects and windows/001_RPG_Cache.rb +++ /dev/null @@ -1,167 +0,0 @@ -class Hangup < Exception; end - - - -module RPG - module Cache - def self.debug - t = Time.now - filename = t.strftime("%H %M %S.%L.txt") - File.open("cache_" + filename, "wb") { |f| - @cache.each do |key, value| - if !value - f.write("#{key} (nil)\r\n") - elsif value.disposed? - f.write("#{key} (disposed)\r\n") - else - f.write("#{key} (#{value.refcount}, #{value.width}x#{value.height})\r\n") - end - end - } - end - - def self.setKey(key, obj) - @cache[key] = obj - end - - def self.fromCache(i) - return nil if !@cache.include?(i) - obj = @cache[i] - return nil if obj && obj.disposed? - return obj - end - - def self.need_clearing() - return @cache.size >= 100 - end - - - def self.load_bitmap(folder_name, filename, hue = 0) - path = folder_name + filename - cached = true - ret = fromCache(path) - if !ret - if filename == "" - ret = BitmapWrapper.new(32, 32) - else - ret = BitmapWrapper.new(path) - end - @cache[path] = ret - cached = false - end - if hue == 0 - ret.addRef if cached - return ret - end - key = [path, hue] - ret2 = fromCache(key) - if ret2 - ret2.addRef - else - ret2 = ret.copy - ret2.hue_change(hue) - @cache[key] = ret2 - end - return ret2 - end - - def self.load_bitmap_path(path, hue = 0) - cached = true - ret = fromCache(path) - if !ret - if path == "" - ret = BitmapWrapper.new(32, 32) - else - ret = BitmapWrapper.new(path) - end - @cache[path] = ret - cached = false - end - if hue == 0 - ret.addRef if cached - return ret - end - key = [path, hue] - ret2 = fromCache(key) - if ret2 - ret2.addRef - else - ret2 = ret.copy - ret2.hue_change(hue) - @cache[key] = ret2 - end - return ret2 - end - - def self.tileEx(filename, tile_id, hue, width = 1, height = 1) - key = [filename, tile_id, hue, width, height] - ret = fromCache(key) - if ret - ret.addRef - else - ret = BitmapWrapper.new(32 * width, 32 * height) - x = (tile_id - 384) % 8 * 32 - y = (((tile_id - 384) / 8) - height + 1) * 32 - tileset = yield(filename) - ret.blt(0, 0, tileset, Rect.new(x, y, 32 * width, 32 * height)) - tileset.dispose - ret.hue_change(hue) if hue != 0 - @cache[key] = ret - end - return ret - end - - def self.tile(filename, tile_id, hue) - return self.tileEx(filename, tile_id, hue) { |f| self.tileset(f) } - end - - def self.transition(filename) - self.load_bitmap("Graphics/Transitions/", filename) - end - - def self.retain(folder_name, filename = "", hue = 0) - path = folder_name + filename - ret = fromCache(path) - if hue > 0 - key = [path, hue] - ret2 = fromCache(key) - if ret2 - ret2.never_dispose = true - return - end - end - ret.never_dispose = true if ret - end - end -end - - - -class BitmapWrapper < Bitmap - attr_reader :refcount - attr_accessor :never_dispose - def dispose - return if self.disposed? - @refcount -= 1 - super if @refcount <= 0 && !never_dispose - end - - def initialize(*arg) - super - @refcount = 1 - end - - def resetRef - @refcount = 1 - end - - def copy - bm = self.clone - bm.resetRef - return bm - end - - def addRef - @refcount += 1 - end -end diff --git a/Data/Scripts/007_Objects and windows/002_MessageConfig.rb b/Data/Scripts/007_Objects and windows/002_MessageConfig.rb deleted file mode 100644 index 7633a927d..000000000 --- a/Data/Scripts/007_Objects and windows/002_MessageConfig.rb +++ /dev/null @@ -1,818 +0,0 @@ -module MessageConfig - LIGHT_TEXT_MAIN_COLOR = Color.new(248, 248, 248) - LIGHT_TEXT_SHADOW_COLOR = Color.new(72, 80, 88) - DARK_TEXT_MAIN_COLOR = Color.new(80, 80, 88) - DARK_TEXT_SHADOW_COLOR = Color.new(160, 160, 168) - - BLUE_TEXT_MAIN_COLOR = Color.new(35, 130, 200) - BLUE_TEXT_SHADOW_COLOR = Color.new(20, 75, 115) - - FONT_NAME = "Power Green" - FONT_SIZE = 29 - SMALL_FONT_NAME = "Power Green Small" - SMALL_FONT_SIZE = 25 - NARROW_FONT_NAME = "Power Green Narrow" - NARROW_FONT_SIZE = 29 - - BUBBLE_TEXT_BASE = Color.new(248,248,248)#(72,80,88)#DIALOG - BUBBLE_TEXT_SHADOW= Color.new(166,160,151) - - # 0 = Pause cursor is displayed at end of text - # 1 = Pause cursor is displayed at bottom right - # 2 = Pause cursor is displayed at lower middle side - CURSOR_POSITION = 1 - WINDOW_OPACITY = 255 - TEXT_SPEED = nil # can be positive to wait frames or negative to - # show multiple characters in a single frame - @@systemFrame = nil - @@defaultTextSkin = nil - @@textSpeed = nil - @@systemFont = nil - @@smallFont = nil - @@narrowFont = nil - - def self.pbDefaultSystemFrame - if $PokemonSystem - return pbResolveBitmap("Graphics/Windowskins/" + Settings::MENU_WINDOWSKINS[$PokemonSystem.frame]) || "" - else - return pbResolveBitmap("Graphics/Windowskins/" + Settings::MENU_WINDOWSKINS[0]) || "" - end - end - - def self.pbDefaultSpeechFrame - if $PokemonSystem - return pbResolveBitmap("Graphics/Windowskins/" + Settings::SPEECH_WINDOWSKINS[$PokemonSystem.textskin]) || "" - else - return pbResolveBitmap("Graphics/Windowskins/" + Settings::SPEECH_WINDOWSKINS[0]) || "" - end - end - - def self.pbDefaultWindowskin - skin=($data_system) ? $data_system.windowskin_name : nil - if skin && skin!="" - skin=pbResolveBitmap("Graphics/Windowskins/"+skin) || "" - end - skin=pbResolveBitmap("Graphics/System/Window") if nil_or_empty?(skin) - skin=pbResolveBitmap("Graphics/Windowskins/001-Blue01") if nil_or_empty?(skin) - return skin || "" - end - - def self.pbGetSystemFrame - if !@@systemFrame - skin=MessageConfig.pbDefaultSystemFrame - skin=MessageConfig.pbDefaultWindowskin if nil_or_empty?(skin) - @@systemFrame=skin || "" - end - return @@systemFrame - end - - def self.pbGetSpeechFrame - if !@@defaultTextSkin - skin=MessageConfig.pbDefaultSpeechFrame - skin=MessageConfig.pbDefaultWindowskin if nil_or_empty?(skin) - @@defaultTextSkin=skin || "" - end - return @@defaultTextSkin - end - - def self.pbSetSystemFrame(value) - @@systemFrame=pbResolveBitmap(value) || "" - end - - def self.pbSetSpeechFrame(value) - @@defaultTextSkin=pbResolveBitmap(value) || "" - end - - #----------------------------------------------------------------------------- - - def self.pbDefaultTextSpeed - return ($PokemonSystem) ? pbSettingToTextSpeed($PokemonSystem.textspeed) : pbSettingToTextSpeed(nil) - end - - def self.pbGetTextSpeed - @@textSpeed=pbDefaultTextSpeed if !@@textSpeed - return @@textSpeed - end - - def self.pbSetTextSpeed(value) - @@textSpeed=value - end - - def self.pbSettingToTextSpeed(speed) - case speed - when 0 then return 1 - when 1 then return -3 - when 2 then return -999 - end - return TEXT_SPEED || 1 - end - - #----------------------------------------------------------------------------- - - def self.pbDefaultSystemFontName - return MessageConfig.pbTryFonts(FONT_NAME) - end - - def self.pbDefaultSmallFontName - return MessageConfig.pbTryFonts(SMALL_FONT_NAME) - end - - def self.pbDefaultNarrowFontName - return MessageConfig.pbTryFonts(NARROW_FONT_NAME) - end - - def self.pbGetSystemFontName - @@systemFont = pbDefaultSystemFontName if !@@systemFont - return @@systemFont - end - - def self.pbGetSmallFontName - @@smallFont = pbDefaultSmallFontName if !@@smallFont - return @@smallFont - end - - def self.pbGetNarrowFontName - @@narrowFont = pbDefaultNarrowFontName if !@@narrowFont - return @@narrowFont - end - - def self.pbSetSystemFontName(value) - @@systemFont = MessageConfig.pbTryFonts(value) - @@systemFont = MessageConfig.pbDefaultSystemFontName if @@systemFont == "" - end - - def self.pbSetSmallFontName(value) - @@smallFont = MessageConfig.pbTryFonts(value) - @@smallFont = MessageConfig.pbDefaultSmallFontName if @@smallFont == "" - end - - def self.pbSetNarrowFontName(value) - @@narrowFont = MessageConfig.pbTryFonts(value) - @@narrowFont = MessageConfig.pbDefaultNarrowFontName if @@narrowFont == "" - end - - def self.pbTryFonts(*args) - for a in args - next if !a - if a.is_a?(String) - return a if Font.exist?(a) - elsif a.is_a?(Array) - for aa in a - ret = MessageConfig.pbTryFonts(aa) - return ret if ret != "" - end - end - end - return "" - end -end - - - -#=============================================================================== -# Position a window -#=============================================================================== -def pbBottomRight(window) - window.x=Graphics.width-window.width - window.y=Graphics.height-window.height -end - -def pbBottomLeft(window) - window.x=0 - window.y=Graphics.height-window.height -end - -def pbBottomLeftLines(window,lines,width=nil) - window.x=0 - window.width=width ? width : Graphics.width - window.height=(window.borderY rescue 32)+lines*32 - window.y=Graphics.height-window.height -end - -def pbPositionFaceWindow(facewindow,msgwindow) - return if !facewindow - if msgwindow - if facewindow.height<=msgwindow.height - facewindow.y=msgwindow.y - else - facewindow.y=msgwindow.y+msgwindow.height-facewindow.height - end - facewindow.x=Graphics.width-facewindow.width - msgwindow.x=0 - msgwindow.width=Graphics.width-facewindow.width - else - facewindow.height=Graphics.height if facewindow.height>Graphics.height - facewindow.x=0 - facewindow.y=0 - end -end - -def pbPositionNearMsgWindow(cmdwindow,msgwindow,side, x_offset=nil,y_offset=nil) - return if !cmdwindow - if msgwindow - height=[cmdwindow.height,Graphics.height-msgwindow.height].min - if cmdwindow.height!=height - cmdwindow.height=height - end - cmdwindow.y=msgwindow.y-cmdwindow.height - if cmdwindow.y<0 - cmdwindow.y=msgwindow.y+msgwindow.height - if cmdwindow.y+cmdwindow.height>Graphics.height - cmdwindow.y=msgwindow.y-cmdwindow.height - end - end - case side - when :left - cmdwindow.x=msgwindow.x - when :right - cmdwindow.x=msgwindow.x+msgwindow.width-cmdwindow.width - else - cmdwindow.x=msgwindow.x+msgwindow.width-cmdwindow.width - end - else - cmdwindow.height=Graphics.height if cmdwindow.height>Graphics.height - cmdwindow.x=0 - cmdwindow.y=0 - end - cmdwindow.x+= x_offset if x_offset - cmdwindow.y+= y_offset if y_offset - - -end - -# internal function -def pbRepositionMessageWindow(msgwindow, linecount=2) - msgwindow.height=32*linecount+msgwindow.borderY - msgwindow.y=(Graphics.height)-(msgwindow.height) - if $game_system && $game_system.respond_to?("message_position") - case $game_system.message_position - when 0 # up - msgwindow.y=0 - when 1 # middle - msgwindow.y=(Graphics.height/2)-(msgwindow.height/2) - when 2 - msgwindow.y=(Graphics.height)-(msgwindow.height) - end - end - if $game_system && $game_system.respond_to?("message_frame") - if $game_system.message_frame != 0 - msgwindow.opacity = 0 - end - end -end - -# internal function -def pbUpdateMsgWindowPos(msgwindow,event,eventChanged=false) - if event - if eventChanged - msgwindow.resizeToFit2(msgwindow.text,Graphics.width*2/3,msgwindow.height) - end - msgwindow.y=event.screen_y-48-msgwindow.height - if msgwindow.y<0 - msgwindow.y=event.screen_y+24 - end - msgwindow.x=event.screen_x-(msgwindow.width/2) - msgwindow.x=0 if msgwindow.x<0 - if msgwindow.x>Graphics.width-msgwindow.width - msgwindow.x=Graphics.width-msgwindow.width - end - else - curwidth=msgwindow.width - if curwidth!=Graphics.width - msgwindow.width=Graphics.width - msgwindow.width=Graphics.width - end - end -end - -#=============================================================================== -# Determine the colour of a background -#=============================================================================== -def isDarkBackground(background,rect=nil) - return true if !background || background.disposed? - rect = background.rect if !rect - return true if rect.width<=0 || rect.height<=0 - xSeg = (rect.width/16) - xLoop = (xSeg==0) ? 1 : 16 - xStart = (xSeg==0) ? rect.x+(rect.width/2) : rect.x+xSeg/2 - ySeg = (rect.height/16) - yLoop = (ySeg==0) ? 1 : 16 - yStart = (ySeg==0) ? rect.y+(rect.height/2) : rect.y+ySeg/2 - count = 0 - y = yStart - r = 0; g = 0; b = 0 - yLoop.times do - x = xStart - xLoop.times do - clr = background.get_pixel(x,y) - if clr.alpha!=0 - r += clr.red - g += clr.green - b += clr.blue - count += 1 - end - x += xSeg - end - y += ySeg - end - return true if count==0 - r /= count - g /= count - b /= count - return (r*0.299+g*0.587+b*0.114)<160 -end - -def isDarkWindowskin(windowskin) - if $PokemonTemp.speechbubble_bubble - return false if $PokemonTemp.speechbubble_bubble > 0 - end - return true if !windowskin || windowskin.disposed? - if windowskin.width==192 && windowskin.height==128 - return isDarkBackground(windowskin,Rect.new(0,0,128,128)) - elsif windowskin.width==128 && windowskin.height==128 - return isDarkBackground(windowskin,Rect.new(0,0,64,64)) - elsif windowskin.width==96 && windowskin.height==48 - return isDarkBackground(windowskin,Rect.new(32,16,16,16)) - else - clr = windowskin.get_pixel(windowskin.width/2, windowskin.height/2) - return (clr.red*0.299+clr.green*0.587+clr.blue*0.114)<160 - end -end - -#=============================================================================== -# Determine which text colours to use based on the darkness of the background -#=============================================================================== -def getSkinColor(windowskin,color,isDarkSkin) - if !windowskin || windowskin.disposed? || - windowskin.width!=128 || windowskin.height!=128 - # Base color, shadow color (these are reversed on dark windowskins) - textcolors = [ - "0070F8","78B8E8", # 1 Blue - "E82010","F8A8B8", # 2 Red - "60B048","B0D090", # 3 Green - "48D8D8","A8E0E0", # 4 Cyan - "D038B8","E8A0E0", # 5 Magenta - "E8D020","F8E888", # 6 Yellow - "A0A0A8","D0D0D8", # 7 Grey - "F0F0F8","C8C8D0", # 8 White - "9040E8","B8A8E0", # 9 Purple - "F89818","F8C898", # 10 Orange - colorToRgb32(MessageConfig::DARK_TEXT_MAIN_COLOR), - colorToRgb32(MessageConfig::DARK_TEXT_SHADOW_COLOR), # 11 Dark default - colorToRgb32(MessageConfig::LIGHT_TEXT_MAIN_COLOR), - colorToRgb32(MessageConfig::LIGHT_TEXT_SHADOW_COLOR) # 12 Light default - ] - if color==0 || color>textcolors.length/2 # No special colour, use default - if isDarkSkin # Dark background, light text - return shadowc3tag(MessageConfig::LIGHT_TEXT_MAIN_COLOR, MessageConfig::LIGHT_TEXT_SHADOW_COLOR) - end - # Light background, dark text - return shadowc3tag(MessageConfig::DARK_TEXT_MAIN_COLOR, MessageConfig::DARK_TEXT_SHADOW_COLOR) - end - # Special colour as listed above - if isDarkSkin && color!=12 # Dark background, light text - return sprintf("",textcolors[2*(color-1)+1],textcolors[2*(color-1)]) - end - # Light background, dark text - return sprintf("",textcolors[2*(color-1)],textcolors[2*(color-1)+1]) - else # VX windowskin - color = 0 if color>=32 - x = 64 + (color % 8) * 8 - y = 96 + (color / 8) * 8 - pixel = windowskin.get_pixel(x, y) - return shadowctagFromColor(pixel) - end -end - -def getDefaultTextColors(windowskin) - if !windowskin || windowskin.disposed? || - windowskin.width!=128 || windowskin.height!=128 - if isDarkWindowskin(windowskin) - return [MessageConfig::LIGHT_TEXT_MAIN_COLOR, MessageConfig::LIGHT_TEXT_SHADOW_COLOR] # White - else - return [MessageConfig::DARK_TEXT_MAIN_COLOR, MessageConfig::DARK_TEXT_SHADOW_COLOR] # Dark gray - end - else # VX windowskin - color = windowskin.get_pixel(64, 96) - shadow = nil - isDark = (color.red+color.green+color.blue)/3 < 128 - if isDark - shadow = Color.new(color.red+64,color.green+64,color.blue+64) - else - shadow = Color.new(color.red-64,color.green-64,color.blue-64) - end - return [color,shadow] - end -end - -#=============================================================================== -# Makes sure a bitmap exists -#=============================================================================== -def pbDoEnsureBitmap(bitmap,dwidth,dheight) - if !bitmap || bitmap.disposed? || bitmap.width0 : false -end - -# pbFadeOutIn(z) { block } -# Fades out the screen before a block is run and fades it back in after the -# block exits. z indicates the z-coordinate of the viewport used for this effect -def pbFadeOutIn(z=99999,nofadeout=false) - col=Color.new(0,0,0,0) - viewport=Viewport.new(0,0,Graphics.width,Graphics.height) - viewport.z=z - numFrames = (Graphics.frame_rate*Settings::FADEOUT_SPEED).floor - alphaDiff = (255.0/numFrames).ceil - for j in 0..numFrames - col.set(0,0,0,j*alphaDiff) - viewport.color=col - Graphics.update - Input.update - end - pbPushFade - begin - yield if block_given? - ensure - pbPopFade - if !nofadeout - for j in 0..numFrames - col.set(0,0,0,(numFrames-j)*alphaDiff) - viewport.color=col - Graphics.update - Input.update - end - end - viewport.dispose - end -end - -def pbFadeOutInWithUpdate(z,sprites,nofadeout=false) - col=Color.new(0,0,0,0) - viewport=Viewport.new(0,0,Graphics.width,Graphics.height) - viewport.z=z - numFrames = (Graphics.frame_rate*Settings::FADEOUT_SPEED).floor - alphaDiff = (255.0/numFrames).ceil - for j in 0..numFrames - col.set(0,0,0,j*alphaDiff) - viewport.color=col - pbUpdateSpriteHash(sprites) - Graphics.update - Input.update - end - pbPushFade - begin - yield if block_given? - ensure - pbPopFade - if !nofadeout - for j in 0..numFrames - col.set(0,0,0,(numFrames-j)*alphaDiff) - viewport.color=col - pbUpdateSpriteHash(sprites) - Graphics.update - Input.update - end - end - viewport.dispose - end -end - -# Similar to pbFadeOutIn, but pauses the music as it fades out. -# Requires scripts "Audio" (for bgm_pause) and "SpriteWindow" (for pbFadeOutIn). -def pbFadeOutInWithMusic(zViewport=99999) - playingBGS = $game_system.getPlayingBGS - playingBGM = $game_system.getPlayingBGM - $game_system.bgm_pause(1.0) - $game_system.bgs_pause(1.0) - pos = $game_system.bgm_position - pbFadeOutIn(zViewport) { - yield - $game_system.bgm_position = pos - $game_system.bgm_resume(playingBGM) - $game_system.bgs_resume(playingBGS) - } -end - -def pbFadeOutAndHide(sprites) - visiblesprites = {} - numFrames = (Graphics.frame_rate*Settings::FADEOUT_SPEED).floor - alphaDiff = (255.0/numFrames).ceil - pbDeactivateWindows(sprites) { - for j in 0..numFrames - pbSetSpritesToColor(sprites,Color.new(0,0,0,j*alphaDiff)) - (block_given?) ? yield : pbUpdateSpriteHash(sprites) - end - } - for i in sprites - next if !i[1] - next if pbDisposed?(i[1]) - visiblesprites[i[0]] = true if i[1].visible - i[1].visible = false - end - return visiblesprites -end - -def pbFadeInAndShow(sprites,visiblesprites=nil) - if visiblesprites - for i in visiblesprites - if i[1] && sprites[i[0]] && !pbDisposed?(sprites[i[0]]) - sprites[i[0]].visible = true - end - end - end - numFrames = (Graphics.frame_rate*Settings::FADEOUT_SPEED).floor - alphaDiff = (255.0/numFrames).ceil - pbDeactivateWindows(sprites) { - for j in 0..numFrames - pbSetSpritesToColor(sprites,Color.new(0,0,0,((numFrames-j)*alphaDiff))) - (block_given?) ? yield : pbUpdateSpriteHash(sprites) - end - } -end - -# Restores which windows are active for the given sprite hash. -# _activeStatuses_ is the result of a previous call to pbActivateWindows -def pbRestoreActivations(sprites,activeStatuses) - return if !sprites || !activeStatuses - for k in activeStatuses.keys - if sprites[k] && sprites[k].is_a?(Window) && !pbDisposed?(sprites[k]) - sprites[k].active=activeStatuses[k] ? true : false - end - end -end - -# Deactivates all windows. If a code block is given, deactivates all windows, -# runs the code in the block, and reactivates them. -def pbDeactivateWindows(sprites) - if block_given? - pbActivateWindow(sprites,nil) { yield } - else - pbActivateWindow(sprites,nil) - end -end - -# Activates a specific window of a sprite hash. _key_ is the key of the window -# in the sprite hash. If a code block is given, deactivates all windows except -# the specified window, runs the code in the block, and reactivates them. -def pbActivateWindow(sprites,key) - return if !sprites - activeStatuses={} - for i in sprites - if i[1] && i[1].is_a?(Window) && !pbDisposed?(i[1]) - activeStatuses[i[0]]=i[1].active - i[1].active=(i[0]==key) - end - end - if block_given? - begin - yield - ensure - pbRestoreActivations(sprites,activeStatuses) - end - return {} - else - return activeStatuses - end -end - -#=============================================================================== -# Create background planes for a sprite hash -#=============================================================================== -# Adds a background to the sprite hash. -# _planename_ is the hash key of the background. -# _background_ is a filename within the Graphics/Pictures/ folder and can be -# an animated image. -# _viewport_ is a viewport to place the background in. -def addBackgroundPlane(sprites,planename,background,viewport=nil) - sprites[planename]=AnimatedPlane.new(viewport) - bitmapName=pbResolveBitmap("Graphics/Pictures/#{background}") - if bitmapName==nil - # Plane should exist in any case - sprites[planename].bitmap=nil - sprites[planename].visible=false - else - sprites[planename].setBitmap(bitmapName) - for spr in sprites.values - if spr.is_a?(Window) - spr.windowskin=nil - end - end - end -end - -# Adds a background to the sprite hash. -# _planename_ is the hash key of the background. -# _background_ is a filename within the Graphics/Pictures/ folder and can be -# an animated image. -# _color_ is the color to use if the background can't be found. -# _viewport_ is a viewport to place the background in. -def addBackgroundOrColoredPlane(sprites,planename,background,color,viewport=nil) - bitmapName=pbResolveBitmap("Graphics/Pictures/#{background}") - if bitmapName==nil - # Plane should exist in any case - sprites[planename]=ColoredPlane.new(color,@viewport) - else - sprites[planename]=AnimatedPlane.new(viewport) - sprites[planename].setBitmap(bitmapName) - for spr in sprites.values - if spr.is_a?(Window) - spr.windowskin=nil - end - end - end -end - - - -#=============================================================================== -# Ensure required method definitions -#=============================================================================== -module Graphics - if !self.respond_to?("width") - def self.width; return 640; end - end - if !self.respond_to?("height") - def self.height; return 480; end - end -end - - - -if !defined?(_INTL) - def _INTL(*args) - string=args[0].clone - for i in 1...args.length - string.gsub!(/\{#{i}\}/,"#{args[i]}") - end - return string - end -end - -if !defined?(_ISPRINTF) - def _ISPRINTF(*args) - string=args[0].clone - for i in 1...args.length - string.gsub!(/\{#{i}\:([^\}]+?)\}/) { |m| - next sprintf("%"+$1,args[i]) - } - end - return string - end -end - -if !defined?(_MAPINTL) - def _MAPINTL(*args) - string=args[1].clone - for i in 2...args.length - string.gsub!(/\{#{i}\}/,"#{args[i+1]}") - end - return string - end -end diff --git a/Data/Scripts/007_Objects and windows/003_Window.rb b/Data/Scripts/007_Objects and windows/003_Window.rb deleted file mode 100644 index 0bd0a6f01..000000000 --- a/Data/Scripts/007_Objects and windows/003_Window.rb +++ /dev/null @@ -1,604 +0,0 @@ -class WindowCursorRect < Rect - def initialize(window) - super(0, 0, 0, 0) - @window = window - end - - def empty - return unless needs_update?(0, 0, 0, 0) - - set(0, 0, 0, 0) - end - - def empty? - return self.x == 0 && self.y == 0 && self.width == 0 && self.height == 0 - end - - def set(x, y, width, height) - return unless needs_update?(x, y, width, height) - - super(x, y, width, height) - - @window.width = @window.width - end - - def height=(value) - super(value) - @window.width = @window.width - end - - def width=(value) - super(value) - @window.width = @window.width - end - - def x=(value) - super(value) - @window.width = @window.width - end - - def y=(value) - super(value) - @window.width = @window.width - end - - private - - def needs_update?(x, y, width, height) - return self.x != x || self.y != y || self.width != width || self.height != height - end -end - - -class Window - attr_reader :tone - attr_reader :color - attr_reader :blend_type - attr_reader :contents_blend_type - attr_reader :viewport - attr_reader :contents - attr_reader :ox - attr_reader :oy - attr_reader :x - attr_reader :y - attr_reader :z - attr_reader :width - attr_reader :active - attr_reader :pause - attr_reader :height - attr_reader :opacity - attr_reader :back_opacity - attr_reader :contents_opacity - attr_reader :visible - attr_reader :cursor_rect - attr_reader :openness - attr_reader :stretch - - def windowskin - @_windowskin - end - - def initialize(viewport=nil) - @sprites={} - @spritekeys=[ - "back", - "corner0","side0","scroll0", - "corner1","side1","scroll1", - "corner2","side2","scroll2", - "corner3","side3","scroll3", - "cursor","contents","pause" - ] - @sidebitmaps=[nil,nil,nil,nil] - @cursorbitmap=nil - @bgbitmap=nil - @viewport=viewport - for i in @spritekeys - @sprites[i]=Sprite.new(@viewport) - end - @disposed=false - @tone=Tone.new(0,0,0) - @color=Color.new(0,0,0,0) - @blankcontents=Bitmap.new(1,1) # RGSS2 requires this - @contents=@blankcontents - @_windowskin=nil - @rpgvx=false # Set to true to emulate RPGVX windows - @x=0 - @y=0 - @width=0 - @openness=255 - @height=0 - @ox=0 - @oy=0 - @z=0 - @stretch=true - @visible=true - @active=true - @blend_type=0 - @contents_blend_type=0 - @opacity=255 - @back_opacity=255 - @contents_opacity=255 - @cursor_rect=WindowCursorRect.new(self) - @cursorblink=0 - @cursoropacity=255 - @pause=false - @pauseopacity=255 - @pauseframe=0 - privRefresh(true) - end - - def dispose - if !self.disposed? - for i in @sprites - i[1].dispose if i[1] - @sprites[i[0]]=nil - end - for i in 0...@sidebitmaps.length - @sidebitmaps[i].dispose if @sidebitmaps[i] - @sidebitmaps[i]=nil - end - @blankcontents.dispose - @cursorbitmap.dispose if @cursorbitmap - @backbitmap.dispose if @backbitmap - @sprites.clear - @sidebitmaps.clear - @_windowskin=nil - @_contents=nil - @disposed=true - end - end - - def openness=(value) - @openness=value - @openness=0 if @openness<0 - @openness=255 if @openness>255 - privRefresh - end - - def stretch=(value) - @stretch=value - privRefresh(true) - end - - def visible=(value) - @visible=value - privRefresh - end - - def viewport=(value) - @viewport=value - for i in @spritekeys - @sprites[i].dispose - if @sprites[i].is_a?(Sprite) - @sprites[i]=Sprite.new(@viewport) - else - @sprites[i]=nil - end - end - privRefresh(true) - end - - def z=(value) - @z=value - privRefresh - end - - def disposed? - return @disposed - end - - def contents=(value) - @contents=value - privRefresh - end - - def windowskin=(value) - @_windowskin=value - if value && value.is_a?(Bitmap) && !value.disposed? && value.width==128 - @rpgvx=true - else - @rpgvx=false - end - privRefresh(true) - end - - def ox=(value) - @ox=value - privRefresh - end - - def active=(value) - @active=value - privRefresh(true) - end - - def cursor_rect=(value) - if !value - @cursor_rect.empty - else - @cursor_rect.set(value.x,value.y,value.width,value.height) - end - end - - def oy=(value) - @oy=value - privRefresh - end - - def width=(value) - @width=value - privRefresh(true) - end - - def height=(value) - @height=value - privRefresh(true) - end - - def pause=(value) - @pause=value - @pauseopacity=0 if !value - privRefresh - end - - def x=(value) - @x=value - privRefresh - end - - def y=(value) - @y=value - privRefresh - end - - def opacity=(value) - @opacity=value - @opacity=0 if @opacity<0 - @opacity=255 if @opacity>255 - privRefresh - end - - def back_opacity=(value) - @back_opacity=value - @back_opacity=0 if @back_opacity<0 - @back_opacity=255 if @back_opacity>255 - privRefresh - end - - def contents_opacity=(value) - @contents_opacity=value - @contents_opacity=0 if @contents_opacity<0 - @contents_opacity=255 if @contents_opacity>255 - privRefresh - end - - def tone=(value) - @tone=value - privRefresh - end - - def color=(value) - @color=value - privRefresh - end - - def blend_type=(value) - @blend_type=value - privRefresh - end - - def flash(color,duration) - return if disposed? - for i in @sprites - i[1].flash(color,duration) - end - end - - def update - return if disposed? - mustchange=false - if @active - if @cursorblink==0 - @cursoropacity-=8 - @cursorblink=1 if @cursoropacity<=128 - else - @cursoropacity+=8 - @cursorblink=0 if @cursoropacity>=255 - end - mustchange=true if !@cursor_rect.empty? - else - mustchange=true if @cursoropacity!=128 - @cursoropacity=128 - end - if @pause - @pauseframe=(Graphics.frame_count / 8) % 4 - @pauseopacity=[@pauseopacity+64,255].min - mustchange=true - end - privRefresh if mustchange - for i in @sprites - i[1].update - end - end - - private - - def ensureBitmap(bitmap,dwidth,dheight) - if !bitmap||bitmap.disposed?||bitmap.width 0 - @sprites["scroll1"].visible = @visible && hascontents && @ox > 0 - @sprites["scroll2"].visible = @visible && hascontents && - (@contents.width - @ox) > @width-32 - @sprites["scroll3"].visible = @visible && hascontents && - (@contents.height - @oy) > @height-32 - else - for i in 0...4 - @sprites["corner#{i}"].visible=false - @sprites["side#{i}"].visible=false - @sprites["scroll#{i}"].visible=false - end - @sprites["contents"].visible=@visible && @openness==255 - @sprites["contents"].color=@color - @sprites["contents"].tone=@tone - @sprites["contents"].blend_type=@contents_blend_type - @sprites["contents"].opacity=contopac - @sprites["back"].visible=false - @sprites["pause"].visible=false - @sprites["cursor"].visible=false - end - for i in @sprites - i[1].z=@z - end - if @rpgvx - @sprites["cursor"].z=@z # For Compatibility - @sprites["contents"].z=@z # For Compatibility - @sprites["pause"].z=@z # For Compatibility - else - @sprites["cursor"].z=@z+1 # For Compatibility - @sprites["contents"].z=@z+2 # For Compatibility - @sprites["pause"].z=@z+2 # For Compatibility - end - if @rpgvx - trimX=64 - trimY=0 - backRect=Rect.new(0,0,64,64) - blindsRect=Rect.new(0,64,64,64) - else - trimX=128 - trimY=0 - backRect=Rect.new(0,0,128,128) - blindsRect=nil - end - @sprites["corner0"].src_rect.set(trimX,trimY+0,16,16); - @sprites["corner1"].src_rect.set(trimX+48,trimY+0,16,16); - @sprites["corner2"].src_rect.set(trimX,trimY+48,16,16); - @sprites["corner3"].src_rect.set(trimX+48,trimY+48,16,16); - @sprites["scroll0"].src_rect.set(trimX+24, trimY+16, 16, 8) # up - @sprites["scroll3"].src_rect.set(trimX+24, trimY+40, 16, 8) # down - @sprites["scroll1"].src_rect.set(trimX+16, trimY+24, 8, 16) # left - @sprites["scroll2"].src_rect.set(trimX+40, trimY+24, 8, 16) # right - cursorX=trimX - cursorY=trimY+64 - sideRects=[ - Rect.new(trimX+16,trimY+0,32,16), - Rect.new(trimX,trimY+16,16,32), - Rect.new(trimX+48,trimY+16,16,32), - Rect.new(trimX+16,trimY+48,32,16) - ] - if @width>32 && @height>32 - @sprites["contents"].src_rect.set(@ox,@oy,@width-32,@height-32) - else - @sprites["contents"].src_rect.set(0,0,0,0) - end - pauseRects=[ - trimX+32,trimY+64, - trimX+48,trimY+64, - trimX+32,trimY+80, - trimX+48,trimY+80, - ] - pauseWidth=16 - pauseHeight=16 - @sprites["pause"].src_rect.set( - pauseRects[@pauseframe*2], - pauseRects[@pauseframe*2+1], - pauseWidth,pauseHeight - ) - @sprites["pause"].x=@x+(@width/2)-(pauseWidth/2) - @sprites["pause"].y=@y+@height-16 # 16 refers to skin margin - @sprites["contents"].x=@x+16 - @sprites["contents"].y=@y+16 - @sprites["corner0"].x=@x - @sprites["corner0"].y=@y - @sprites["corner1"].x=@x+@width-16 - @sprites["corner1"].y=@y - @sprites["corner2"].x=@x - @sprites["corner2"].y=@y+@height-16 - @sprites["corner3"].x=@x+@width-16 - @sprites["corner3"].y=@y+@height-16 - @sprites["side0"].x=@x+16 - @sprites["side0"].y=@y - @sprites["side1"].x=@x - @sprites["side1"].y=@y+16 - @sprites["side2"].x=@x+@width-16 - @sprites["side2"].y=@y+16 - @sprites["side3"].x=@x+16 - @sprites["side3"].y=@y+@height-16 - @sprites["scroll0"].x = @x+@width / 2 - 8 - @sprites["scroll0"].y = @y+8 - @sprites["scroll1"].x = @x+8 - @sprites["scroll1"].y = @y+@height / 2 - 8 - @sprites["scroll2"].x = @x+@width - 16 - @sprites["scroll2"].y = @y+@height / 2 - 8 - @sprites["scroll3"].x = @x+@width / 2 - 8 - @sprites["scroll3"].y = @y+@height - 16 - @sprites["back"].x=@x+2 - @sprites["back"].y=@y+2 - @sprites["cursor"].x=@x+16+@cursor_rect.x - @sprites["cursor"].y=@y+16+@cursor_rect.y - if changeBitmap && @_windowskin && !@_windowskin.disposed? - width=@cursor_rect.width - height=@cursor_rect.height - if width > 0 && height > 0 - cursorrects=[ - # sides - Rect.new(cursorX+2, cursorY+0, 28, 2), - Rect.new(cursorX+0, cursorY+2, 2, 28), - Rect.new(cursorX+30, cursorY+2, 2, 28), - Rect.new(cursorX+2, cursorY+30, 28, 2), - # corners - Rect.new(cursorX+0, cursorY+0, 2, 2), - Rect.new(cursorX+30, cursorY+0, 2, 2), - Rect.new(cursorX+0, cursorY+30, 2, 2), - Rect.new(cursorX+30, cursorY+30, 2, 2), - # back - Rect.new(cursorX+2, cursorY+2, 28, 28) - ] - margin=2 - fullmargin=4 - @cursorbitmap = ensureBitmap(@cursorbitmap, width, height) - @cursorbitmap.clear - @sprites["cursor"].bitmap=@cursorbitmap - @sprites["cursor"].src_rect.set(0,0,width,height) - rect = Rect.new(margin,margin, - width - fullmargin, height - fullmargin) - @cursorbitmap.stretch_blt(rect, @_windowskin, cursorrects[8]) - @cursorbitmap.blt(0, 0, @_windowskin, cursorrects[4])# top left - @cursorbitmap.blt(width-margin, 0, @_windowskin, cursorrects[5]) # top right - @cursorbitmap.blt(0, height-margin, @_windowskin, cursorrects[6]) # bottom right - @cursorbitmap.blt(width-margin, height-margin, @_windowskin, cursorrects[7]) # bottom left - rect = Rect.new(margin, 0, - width - fullmargin, margin) - @cursorbitmap.stretch_blt(rect, @_windowskin, cursorrects[0]) - rect = Rect.new(0, margin, - margin, height - fullmargin) - @cursorbitmap.stretch_blt(rect, @_windowskin, cursorrects[1]) - rect = Rect.new(width - margin, margin, - margin, height - fullmargin) - @cursorbitmap.stretch_blt(rect, @_windowskin, cursorrects[2]) - rect = Rect.new(margin, height-margin, - width - fullmargin, margin) - @cursorbitmap.stretch_blt(rect, @_windowskin, cursorrects[3]) - else - @sprites["cursor"].visible=false - @sprites["cursor"].src_rect.set(0,0,0,0) - end - for i in 0...4 - dwidth = (i==0 || i==3) ? @width-32 : 16 - dheight = (i==0 || i==3) ? 16 : @height-32 - @sidebitmaps[i]=ensureBitmap(@sidebitmaps[i],dwidth,dheight) - @sprites["side#{i}"].bitmap=@sidebitmaps[i] - @sprites["side#{i}"].src_rect.set(0,0,dwidth,dheight) - @sidebitmaps[i].clear - if sideRects[i].width>0 && sideRects[i].height>0 - @sidebitmaps[i].stretch_blt(@sprites["side#{i}"].src_rect, - @_windowskin,sideRects[i]) - end - end - backwidth=@width-4 - backheight=@height-4 - if backwidth>0 && backheight>0 - @backbitmap=ensureBitmap(@backbitmap,backwidth,backheight) - @sprites["back"].bitmap=@backbitmap - @sprites["back"].src_rect.set(0,0,backwidth,backheight) - @backbitmap.clear - if @stretch - @backbitmap.stretch_blt(@sprites["back"].src_rect,@_windowskin,backRect) - else - tileBitmap(@backbitmap,@sprites["back"].src_rect,@_windowskin,backRect) - end - if blindsRect - tileBitmap(@backbitmap,@sprites["back"].src_rect,@_windowskin,blindsRect) - end - else - @sprites["back"].visible=false - @sprites["back"].src_rect.set(0,0,0,0) - end - end - if @openness!=255 - opn=@openness/255.0 - for k in @spritekeys - sprite=@sprites[k] - ratio=(@height<=0) ? 0 : (sprite.y-@y)*1.0/@height - sprite.zoom_y=opn - sprite.oy=0 - sprite.y=(@y+(@height/2.0)+(@height*ratio*opn)-(@height/2*opn)).floor - end - else - for k in @spritekeys - sprite=@sprites[k] - sprite.zoom_y=1.0 - end - end - i=0 - # Ensure Z order - for k in @spritekeys - sprite=@sprites[k] - y=sprite.y - sprite.y=i - sprite.oy=(sprite.zoom_y<=0) ? 0 : (i-y)/sprite.zoom_y - end - end -end diff --git a/Data/Scripts/007_Objects and windows/004_SpriteWindow.rb b/Data/Scripts/007_Objects and windows/004_SpriteWindow.rb deleted file mode 100644 index 0188cd94e..000000000 --- a/Data/Scripts/007_Objects and windows/004_SpriteWindow.rb +++ /dev/null @@ -1,936 +0,0 @@ -#=============================================================================== -# SpriteWindow is a class based on Window which emulates Window's functionality. -# This class is necessary in order to change the viewport of windows (with -# viewport=) and to make windows fade in and out (with tone=). -#=============================================================================== -class SpriteWindow < Window - attr_reader :tone - attr_reader :color - attr_reader :viewport - attr_reader :contents - attr_reader :ox - attr_reader :oy - attr_reader :x - attr_reader :y - attr_reader :z - attr_reader :zoom_x - attr_reader :zoom_y - attr_reader :offset_x - attr_reader :offset_y - attr_reader :width - attr_reader :active - attr_reader :pause - attr_reader :height - attr_reader :opacity - attr_reader :back_opacity - attr_reader :contents_opacity - attr_reader :visible - attr_reader :cursor_rect - attr_reader :contents_blend_type - attr_reader :blend_type - attr_reader :openness - - def windowskin - @_windowskin - end - - # Flags used to preserve compatibility - # with RGSS/RGSS2's version of Window - module CompatBits - CorrectZ = 1 - ExpandBack = 2 - ShowScrollArrows = 4 - StretchSides = 8 - ShowPause = 16 - ShowCursor = 32 - end - - attr_reader :compat - - def compat=(value) - @compat=value - privRefresh(true) - end - - def initialize(viewport=nil) - @sprites={} - @spritekeys=[ - "back", - "corner0","side0","scroll0", - "corner1","side1","scroll1", - "corner2","side2","scroll2", - "corner3","side3","scroll3", - "cursor","contents","pause" - ] - @viewport=viewport - @sidebitmaps=[nil,nil,nil,nil] - @cursorbitmap=nil - @bgbitmap=nil - for i in @spritekeys - @sprites[i]=Sprite.new(@viewport) - end - @disposed=false - @tone=Tone.new(0,0,0) - @color=Color.new(0,0,0,0) - @blankcontents=Bitmap.new(1,1) # RGSS2 requires this - @contents=@blankcontents - @_windowskin=nil - @rpgvx=false - @compat=CompatBits::ExpandBack|CompatBits::StretchSides - @x=0 - @y=0 - @width=0 - @height=0 - @offset_x=0 - @offset_y=0 - @zoom_x=1.0 - @zoom_y=1.0 - @ox=0 - @oy=0 - @z=0 - @stretch=true - @visible=true - @active=true - @openness=255 - @opacity=255 - @back_opacity=255 - @blend_type=0 - @contents_blend_type=0 - @contents_opacity=255 - @cursor_rect=WindowCursorRect.new(self) - @cursorblink=0 - @cursoropacity=255 - @pause=false - @pauseframe=0 - @flash=0 - @pauseopacity=0 - @skinformat=0 - @skinrect=Rect.new(0,0,0,0) - @trim=[16,16,16,16] - privRefresh(true) - end - - def dispose - if !self.disposed? - for i in @sprites - i[1].dispose if i[1] - @sprites[i[0]]=nil - end - for i in 0...@sidebitmaps.length - @sidebitmaps[i].dispose if @sidebitmaps[i] - @sidebitmaps[i]=nil - end - @blankcontents.dispose - @cursorbitmap.dispose if @cursorbitmap - @backbitmap.dispose if @backbitmap - @sprites.clear - @sidebitmaps.clear - @_windowskin=nil - @disposed=true - end - end - - def stretch=(value) - @stretch=value - privRefresh(true) - end - - def visible=(value) - @visible=value - privRefresh - end - - def viewport=(value) - @viewport=value - for i in @spritekeys - @sprites[i].dispose if @sprites[i] - end - for i in @spritekeys - if @sprites[i].is_a?(Sprite) - @sprites[i]=Sprite.new(@viewport) - else - @sprites[i]=nil - end - end - privRefresh(true) - end - - def z=(value) - @z=value - privRefresh - end - - def disposed? - return @disposed - end - - def contents=(value) - if @contents!=value - @contents=value - privRefresh if @visible - end - end - - def ox=(value) - if @ox!=value - @ox=value - privRefresh if @visible - end - end - - def oy=(value) - if @oy!=value - @oy=value - privRefresh if @visible - end - end - - def active=(value) - @active=value - privRefresh(true) - end - - def cursor_rect=(value) - if !value - @cursor_rect.empty - else - @cursor_rect.set(value.x,value.y,value.width,value.height) - end - end - - def openness=(value) - @openness=value - @openness=0 if @openness<0 - @openness=255 if @openness>255 - privRefresh - end - - def width=(value) - @width=value - privRefresh(true) - end - - def height=(value) - @height=value - privRefresh(true) - end - - def pause=(value) - @pause=value - @pauseopacity=0 if !value - privRefresh if @visible - end - - def x=(value) - @x=value - privRefresh if @visible - end - - def y=(value) - @y=value - privRefresh if @visible - end - - def zoom_x=(value) - @zoom_x=value - privRefresh if @visible - end - - def zoom_y=(value) - @zoom_y=value - privRefresh if @visible - end - - def offset_x=(value) - @x=value - privRefresh if @visible - end - - def offset_y=(value) - @y=value - privRefresh if @visible - end - - def opacity=(value) - @opacity=value - @opacity=0 if @opacity<0 - @opacity=255 if @opacity>255 - privRefresh if @visible - end - - def back_opacity=(value) - @back_opacity=value - @back_opacity=0 if @back_opacity<0 - @back_opacity=255 if @back_opacity>255 - privRefresh if @visible - end - - def contents_opacity=(value) - @contents_opacity=value - @contents_opacity=0 if @contents_opacity<0 - @contents_opacity=255 if @contents_opacity>255 - privRefresh if @visible - end - - def tone=(value) - @tone=value - privRefresh if @visible - end - - def color=(value) - @color=value - privRefresh if @visible - end - - def blend_type=(value) - @blend_type=value - privRefresh if @visible - end - - def flash(color,duration) - return if disposed? - @flash=duration+1 - for i in @sprites - i[1].flash(color,duration) - end - end - - def update - return if disposed? - mustchange=false - if @active - if @cursorblink==0 - @cursoropacity-=8 - @cursorblink=1 if @cursoropacity<=128 - else - @cursoropacity+=8 - @cursorblink=0 if @cursoropacity>=255 - end - privRefreshCursor - else - @cursoropacity=128 - privRefreshCursor - end - if @pause - oldpauseframe=@pauseframe - oldpauseopacity=@pauseopacity - @pauseframe=(Graphics.frame_count / 8) % 4 - @pauseopacity=[@pauseopacity+64,255].min - mustchange=@pauseframe!=oldpauseframe || @pauseopacity!=oldpauseopacity - end - privRefresh if mustchange - if @flash>0 - for i in @sprites.values - i.update - end - @flash-=1 - end - end - - ############# - attr_reader :skinformat - attr_reader :skinrect - - def loadSkinFile(_file) - if (self.windowskin.width==80 || self.windowskin.width==96) && - self.windowskin.height==48 - # Body = X, Y, width, height of body rectangle within windowskin - @skinrect.set(32,16,16,16) - # Trim = X, Y, width, height of trim rectangle within windowskin - @trim=[32,16,16,16] - elsif self.windowskin.width==80 && self.windowskin.height==80 - @skinrect.set(32,32,16,16) - @trim=[32,16,16,48] - end - end - - def windowskin=(value) - oldSkinWidth=(@_windowskin && !@_windowskin.disposed?) ? @_windowskin.width : -1 - oldSkinHeight=(@_windowskin && !@_windowskin.disposed?) ? @_windowskin.height : -1 - @_windowskin=value - if @skinformat==1 - @rpgvx=false - if @_windowskin && !@_windowskin.disposed? - if @_windowskin.width!=oldSkinWidth || @_windowskin.height!=oldSkinHeight - # Update skinrect and trim if windowskin's dimensions have changed - @skinrect.set((@_windowskin.width-16)/2,(@_windowskin.height-16)/2,16,16) - @trim=[@skinrect.x,@skinrect.y,@skinrect.x,@skinrect.y] - end - else - @skinrect.set(16,16,16,16) - @trim=[16,16,16,16] - end - else - if value && value.is_a?(Bitmap) && !value.disposed? && value.width==128 - @rpgvx=true - else - @rpgvx=false - end - @trim=[16,16,16,16] - end - privRefresh(true) - end - - def skinrect=(value) - @skinrect=value - privRefresh - end - - def skinformat=(value) - if @skinformat!=value - @skinformat=value - privRefresh(true) - end - end - - def borderX - return 32 if !@trim || skinformat==0 - if @_windowskin && !@_windowskin.disposed? - return @trim[0]+(@_windowskin.width-@trim[2]-@trim[0]) - end - return 32 - end - - def borderY - return 32 if !@trim || skinformat==0 - if @_windowskin && !@_windowskin.disposed? - return @trim[1]+(@_windowskin.height-@trim[3]-@trim[1]) - end - return 32 - end - - def leftEdge; self.startX; end - def topEdge; self.startY; end - def rightEdge; self.borderX-self.leftEdge; end - def bottomEdge; self.borderY-self.topEdge; end - - def startX - return !@trim || skinformat==0 ? 16 : @trim[0] - end - - def startY - return !@trim || skinformat==0 ? 16 : @trim[1] - end - - def endX - return !@trim || skinformat==0 ? 16 : @trim[2] - end - - def endY - return !@trim || skinformat==0 ? 16 : @trim[3] - end - - def startX=(value) - @trim[0]=value - privRefresh - end - - def startY=(value) - @trim[1]=value - privRefresh - end - - def endX=(value) - @trim[2]=value - privRefresh - end - - def endY=(value) - @trim[3]=value - privRefresh - end - - ############# - private - - def ensureBitmap(bitmap,dwidth,dheight) - if !bitmap||bitmap.disposed?||bitmap.width0 && @skinformat==0 && !@rpgvx - # Compatibility Mode: Cursor, pause, and contents have higher Z - @sprites["cursor"].z=@z+1 - @sprites["contents"].z=@z+2 - @sprites["pause"].z=@z+2 - end - if @skinformat==0 - startX=16 - startY=16 - endX=16 - endY=16 - trimStartX=16 - trimStartY=16 - trimWidth=32 - trimHeight=32 - if @rpgvx - trimX=64 - trimY=0 - backRect=Rect.new(0,0,64,64) - blindsRect=Rect.new(0,64,64,64) - else - trimX=128 - trimY=0 - backRect=Rect.new(0,0,128,128) - blindsRect=nil - end - if @_windowskin && !@_windowskin.disposed? - @sprites["corner0"].src_rect.set(trimX,trimY+0,16,16); - @sprites["corner1"].src_rect.set(trimX+48,trimY+0,16,16); - @sprites["corner2"].src_rect.set(trimX,trimY+48,16,16); - @sprites["corner3"].src_rect.set(trimX+48,trimY+48,16,16); - @sprites["scroll0"].src_rect.set(trimX+24, trimY+16, 16, 8) # up - @sprites["scroll3"].src_rect.set(trimX+24, trimY+40, 16, 8) # down - @sprites["scroll1"].src_rect.set(trimX+16, trimY+24, 8, 16) # left - @sprites["scroll2"].src_rect.set(trimX+40, trimY+24, 8, 16) # right - cursorX=trimX - cursorY=trimY+64 - sideRects=[ - Rect.new(trimX+16,trimY+0,32,16), - Rect.new(trimX,trimY+16,16,32), - Rect.new(trimX+48,trimY+16,16,32), - Rect.new(trimX+16,trimY+48,32,16) - ] - pauseRects=[ - trimX+32,trimY+64, - trimX+48,trimY+64, - trimX+32,trimY+80, - trimX+48,trimY+80, - ] - pauseWidth=16 - pauseHeight=16 - @sprites["pause"].src_rect.set( - pauseRects[@pauseframe*2], - pauseRects[@pauseframe*2+1], - pauseWidth,pauseHeight - ) - end - else - trimStartX=@trim[0] - trimStartY=@trim[1] - trimWidth=@trim[0]+(@skinrect.width-@trim[2]+@trim[0]) - trimHeight=@trim[1]+(@skinrect.height-@trim[3]+@trim[1]) - if @_windowskin && !@_windowskin.disposed? - # width of left end of window - startX=@skinrect.x - # width of top end of window - startY=@skinrect.y - cx=@skinrect.x+@skinrect.width # right side of BODY rect - cy=@skinrect.y+@skinrect.height # bottom side of BODY rect - # width of right end of window - endX=(!@_windowskin || @_windowskin.disposed?) ? @skinrect.x : @_windowskin.width-cx - # height of bottom end of window - endY=(!@_windowskin || @_windowskin.disposed?) ? @skinrect.y : @_windowskin.height-cy - @sprites["corner0"].src_rect.set(0,0,startX,startY); - @sprites["corner1"].src_rect.set(cx,0,endX,startY); - @sprites["corner2"].src_rect.set(0,cy,startX,endY); - @sprites["corner3"].src_rect.set(cx,cy,endX,endY); - backRect=Rect.new(@skinrect.x,@skinrect.y, - @skinrect.width,@skinrect.height); - blindsRect=nil - sideRects=[ - Rect.new(startX,0,@skinrect.width,startY), # side0 (top) - Rect.new(0,startY,startX,@skinrect.height), # side1 (left) - Rect.new(cx,startY,endX,@skinrect.height), # side2 (right) - Rect.new(startX,cy,@skinrect.width,endY) # side3 (bottom) - ] - end - end - if @width>trimWidth && @height>trimHeight - @sprites["contents"].src_rect.set(@ox,@oy,@width-trimWidth,@height-trimHeight) - else - @sprites["contents"].src_rect.set(0,0,0,0) - end - @sprites["contents"].x=@x+trimStartX - @sprites["contents"].y=@y+trimStartY - if (@compat & CompatBits::ShowScrollArrows)>0 && @skinformat==0 - # Compatibility mode: Make scroll arrows visible - if @skinformat==0 && @_windowskin && !@_windowskin.disposed? && - @contents && !@contents.disposed? - @sprites["scroll0"].visible = @visible && hascontents && @oy > 0 - @sprites["scroll1"].visible = @visible && hascontents && @ox > 0 - @sprites["scroll2"].visible = @visible && (@contents.width - @ox) > @width-trimWidth - @sprites["scroll3"].visible = @visible && (@contents.height - @oy) > @height-trimHeight - end - end - if @_windowskin && !@_windowskin.disposed? - borderX=startX+endX - borderY=startY+endY - @sprites["corner0"].x=@x - @sprites["corner0"].y=@y - @sprites["corner1"].x=@x+@width-endX - @sprites["corner1"].y=@y - @sprites["corner2"].x=@x - @sprites["corner2"].y=@y+@height-endY - @sprites["corner3"].x=@x+@width-endX - @sprites["corner3"].y=@y+@height-endY - @sprites["side0"].x=@x+startX - @sprites["side0"].y=@y - @sprites["side1"].x=@x - @sprites["side1"].y=@y+startY - @sprites["side2"].x=@x+@width-endX - @sprites["side2"].y=@y+startY - @sprites["side3"].x=@x+startX - @sprites["side3"].y=@y+@height-endY - @sprites["scroll0"].x = @x+@width / 2 - 8 - @sprites["scroll0"].y = @y+8 - @sprites["scroll1"].x = @x+8 - @sprites["scroll1"].y = @y+@height / 2 - 8 - @sprites["scroll2"].x = @x+@width - 16 - @sprites["scroll2"].y = @y+@height / 2 - 8 - @sprites["scroll3"].x = @x+@width / 2 - 8 - @sprites["scroll3"].y = @y+@height - 16 - @sprites["cursor"].x=@x+startX+@cursor_rect.x - @sprites["cursor"].y=@y+startY+@cursor_rect.y - if (@compat & CompatBits::ExpandBack)>0 && @skinformat==0 - # Compatibility mode: Expand background - @sprites["back"].x=@x+2 - @sprites["back"].y=@y+2 - else - @sprites["back"].x=@x+startX - @sprites["back"].y=@y+startY - end - end - if changeBitmap && @_windowskin && !@_windowskin.disposed? - if @skinformat==0 - @sprites["cursor"].x=@x+startX+@cursor_rect.x - @sprites["cursor"].y=@y+startY+@cursor_rect.y - width=@cursor_rect.width - height=@cursor_rect.height - if width > 0 && height > 0 - cursorrects=[ - # sides - Rect.new(cursorX+2, cursorY+0, 28, 2), - Rect.new(cursorX+0, cursorY+2, 2, 28), - Rect.new(cursorX+30, cursorY+2, 2, 28), - Rect.new(cursorX+2, cursorY+30, 28, 2), - # corners - Rect.new(cursorX+0, cursorY+0, 2, 2), - Rect.new(cursorX+30, cursorY+0, 2, 2), - Rect.new(cursorX+0, cursorY+30, 2, 2), - Rect.new(cursorX+30, cursorY+30, 2, 2), - # back - Rect.new(cursorX+2, cursorY+2, 28, 28) - ] - margin=2 - fullmargin=4 - @cursorbitmap = ensureBitmap(@cursorbitmap, width, height) - @cursorbitmap.clear - @sprites["cursor"].bitmap=@cursorbitmap - @sprites["cursor"].src_rect.set(0,0,width,height) - rect = Rect.new(margin,margin,width - fullmargin, height - fullmargin) - @cursorbitmap.stretch_blt(rect, @_windowskin, cursorrects[8]) - @cursorbitmap.blt(0, 0, @_windowskin, cursorrects[4])# top left - @cursorbitmap.blt(width-margin, 0, @_windowskin, cursorrects[5]) # top right - @cursorbitmap.blt(0, height-margin, @_windowskin, cursorrects[6]) # bottom right - @cursorbitmap.blt(width-margin, height-margin, @_windowskin, cursorrects[7]) # bottom left - rect = Rect.new(margin, 0,width - fullmargin, margin) - @cursorbitmap.stretch_blt(rect, @_windowskin, cursorrects[0]) - rect = Rect.new(0, margin,margin, height - fullmargin) - @cursorbitmap.stretch_blt(rect, @_windowskin, cursorrects[1]) - rect = Rect.new(width - margin, margin, margin, height - fullmargin) - @cursorbitmap.stretch_blt(rect, @_windowskin, cursorrects[2]) - rect = Rect.new(margin, height-margin, width - fullmargin, margin) - @cursorbitmap.stretch_blt(rect, @_windowskin, cursorrects[3]) - else - @sprites["cursor"].visible=false - @sprites["cursor"].src_rect.set(0,0,0,0) - end - end - for i in 0..3 - case i - when 0 - dwidth = @width-startX-endX - dheight = startY - when 1 - dwidth = startX - dheight = @height-startY-endY - when 2 - dwidth = endX - dheight = @height-startY-endY - when 3 - dwidth = @width-startX-endX - dheight = endY - end - @sidebitmaps[i]=ensureBitmap(@sidebitmaps[i],dwidth,dheight) - @sprites["side#{i}"].bitmap=@sidebitmaps[i] - @sprites["side#{i}"].src_rect.set(0,0,dwidth,dheight) - @sidebitmaps[i].clear - if sideRects[i].width>0 && sideRects[i].height>0 - if (@compat & CompatBits::StretchSides)>0 && @skinformat==0 - # Compatibility mode: Stretch sides - @sidebitmaps[i].stretch_blt(@sprites["side#{i}"].src_rect, - @_windowskin,sideRects[i]) - else - tileBitmap(@sidebitmaps[i],@sprites["side#{i}"].src_rect, - @_windowskin,sideRects[i]) - end - end - end - if (@compat & CompatBits::ExpandBack)>0 && @skinformat==0 - # Compatibility mode: Expand background - backwidth=@width-4 - backheight=@height-4 - else - backwidth=@width-borderX - backheight=@height-borderY - end - if backwidth>0 && backheight>0 - @backbitmap=ensureBitmap(@backbitmap,backwidth,backheight) - @sprites["back"].bitmap=@backbitmap - @sprites["back"].src_rect.set(0,0,backwidth,backheight) - @backbitmap.clear - if @stretch - @backbitmap.stretch_blt(@sprites["back"].src_rect,@_windowskin,backRect) - else - tileBitmap(@backbitmap,@sprites["back"].src_rect,@_windowskin,backRect) - end - if blindsRect - tileBitmap(@backbitmap,@sprites["back"].src_rect,@_windowskin,blindsRect) - end - else - @sprites["back"].visible=false - @sprites["back"].src_rect.set(0,0,0,0) - end - end - if @openness!=255 - opn=@openness/255.0 - for k in @spritekeys - sprite=@sprites[k] - ratio=(@height<=0) ? 0 : (sprite.y-@y)*1.0/@height - sprite.zoom_y=opn - sprite.zoom_x=1.0 - sprite.oy=0 - sprite.y=(@y+(@height/2.0)+(@height*ratio*opn)-(@height/2*opn)).floor - end - else - for k in @spritekeys - sprite=@sprites[k] - sprite.zoom_x=1.0 - sprite.zoom_y=1.0 - end - end - i=0 - # Ensure Z order - for k in @spritekeys - sprite=@sprites[k] - y=sprite.y - sprite.y=i - sprite.oy=(sprite.zoom_y<=0) ? 0 : (i-y)/sprite.zoom_y - sprite.zoom_x*=@zoom_x - sprite.zoom_y*=@zoom_y - sprite.x*=@zoom_x - sprite.y*=@zoom_y - sprite.x+=(@offset_x/sprite.zoom_x) - sprite.y+=(@offset_y/sprite.zoom_y) - end - end -end - - - -#=============================================================================== -# -#=============================================================================== -class SpriteWindow_Base < SpriteWindow - TEXTPADDING=4 # In pixels - - def initialize(x, y, width, height) - super() - self.x = x - self.y = y - self.width = width - self.height = height - self.z = 100 - @curframe=MessageConfig.pbGetSystemFrame() - @curfont=MessageConfig.pbGetSystemFontName() - @sysframe=AnimatedBitmap.new(@curframe) - RPG::Cache.retain(@curframe) if @curframe && !@curframe.empty? - @customskin=nil - __setWindowskin(@sysframe.bitmap) - __resolveSystemFrame() - pbSetSystemFont(self.contents) if self.contents - end - - def __setWindowskin(skin) - if skin && (skin.width==192 && skin.height==128) || # RPGXP Windowskin - (skin.width==128 && skin.height==128) # RPGVX Windowskin - self.skinformat=0 - else - self.skinformat=1 - end - self.windowskin=skin - end - - def __resolveSystemFrame - if self.skinformat==1 - if !@resolvedFrame - @resolvedFrame=MessageConfig.pbGetSystemFrame() - @resolvedFrame.sub!(/\.[^\.\/\\]+$/,"") - end - self.loadSkinFile("#{@resolvedFrame}.txt") if @resolvedFrame!="" - end - end - - def setSkin(skin) # Filename of windowskin to apply. Supports XP, VX, and animated skins. - @customskin.dispose if @customskin - @customskin=nil - resolvedName=pbResolveBitmap(skin) - return if nil_or_empty?(resolvedName) - @customskin=AnimatedBitmap.new(resolvedName) - RPG::Cache.retain(resolvedName) - __setWindowskin(@customskin.bitmap) - if self.skinformat==1 - skinbase=resolvedName.sub(/\.[^\.\/\\]+$/,"") - self.loadSkinFile("#{skinbase}.txt") - end - end - - def setSystemFrame - @customskin.dispose if @customskin - @customskin=nil - __setWindowskin(@sysframe.bitmap) - __resolveSystemFrame() - end - - def update - super - if self.windowskin - if @customskin - if @customskin.totalFrames>1 - @customskin.update - __setWindowskin(@customskin.bitmap) - end - elsif @sysframe - if @sysframe.totalFrames>1 - @sysframe.update - __setWindowskin(@sysframe.bitmap) - end - end - end - if @curframe!=MessageConfig.pbGetSystemFrame() - @curframe=MessageConfig.pbGetSystemFrame() - if @sysframe && !@customskin - @sysframe.dispose if @sysframe - @sysframe=AnimatedBitmap.new(@curframe) - RPG::Cache.retain(@curframe) if @curframe && !@curframe.empty? - @resolvedFrame=nil - __setWindowskin(@sysframe.bitmap) - __resolveSystemFrame() - end - begin - refresh - rescue NoMethodError - end - end - if @curfont!=MessageConfig.pbGetSystemFontName() - @curfont=MessageConfig.pbGetSystemFontName() - if self.contents && !self.contents.disposed? - pbSetSystemFont(self.contents) - end - begin - refresh - rescue NoMethodError - end - end - end - - def dispose - self.contents.dispose if self.contents - @sysframe.dispose - @customskin.dispose if @customskin - super - end -end diff --git a/Data/Scripts/007_Objects and windows/005_SpriteWindow_text.rb b/Data/Scripts/007_Objects and windows/005_SpriteWindow_text.rb deleted file mode 100644 index a05882c85..000000000 --- a/Data/Scripts/007_Objects and windows/005_SpriteWindow_text.rb +++ /dev/null @@ -1,1401 +0,0 @@ -#=============================================================================== -# -#=============================================================================== -# Represents a window with no formatting capabilities. Its text color can be set, -# though, and line breaks are supported, but the text is generally unformatted. -class Window_UnformattedTextPokemon < SpriteWindow_Base - attr_reader :text - attr_reader :baseColor - attr_reader :shadowColor - # Letter-by-letter mode. This mode is not supported in this class. - attr_accessor :letterbyletter - - def text=(value) - @text=value - refresh - end - - def baseColor=(value) - @baseColor=value - refresh - end - - def shadowColor=(value) - @shadowColor=value - refresh - end - - def initialize(text="") - super(0,0,33,33) - self.contents=Bitmap.new(1,1) - pbSetSystemFont(self.contents) - @text=text - @letterbyletter=false # Not supported in this class - colors=getDefaultTextColors(self.windowskin) - @baseColor=colors[0] - @shadowColor=colors[1] - resizeToFit(text) - end - - def self.newWithSize(text,x,y,width,height,viewport=nil) - ret=self.new(text) - ret.x=x - ret.y=y - ret.width=width - ret.height=height - ret.viewport=viewport - ret.refresh - return ret - end - - def resizeToFitInternal(text,maxwidth) # maxwidth is maximum acceptable window width - dims=[0,0] - cwidth=maxwidth<0 ? Graphics.width : maxwidth - getLineBrokenChunks(self.contents,text, - cwidth-self.borderX-SpriteWindow_Base::TEXTPADDING,dims,true) - return dims - end - - def setTextToFit(text,maxwidth=-1) - resizeToFit(text,maxwidth) - self.text=text - end - - def resizeToFit(text, maxwidth = -1) # maxwidth is maximum acceptable window width - dims = resizeToFitInternal(text,maxwidth) - self.width = dims[0] + self.borderX + SpriteWindow_Base::TEXTPADDING - self.height = dims[1] + self.borderY - refresh - end - - def resizeHeightToFit(text, width = -1) # width is current window width - dims = resizeToFitInternal(text,width) - self.width = (width < 0) ? Graphics.width : width - self.height = dims[1] + self.borderY - refresh - end - - def setSkin(skin) - super(skin) - privRefresh(true) - oldbaser = @baseColor.red - oldbaseg = @baseColor.green - oldbaseb = @baseColor.blue - oldbasea = @baseColor.alpha - oldshadowr = @shadowColor.red - oldshadowg = @shadowColor.green - oldshadowb = @shadowColor.blue - oldshadowa = @shadowColor.alpha - colors = getDefaultTextColors(self.windowskin) - @baseColor = colors[0] - @shadowColor = colors[1] - if oldbaser!=@baseColor.red || oldbaseg!=@baseColor.green || - oldbaseb!=@baseColor.blue || oldbasea!=@baseColor.alpha || - oldshadowr!=@shadowColor.red || oldshadowg!=@shadowColor.green || - oldshadowb!=@shadowColor.blue || oldshadowa!=@shadowColor.alpha - self.text = self.text - end - end - - def refresh - self.contents=pbDoEnsureBitmap(self.contents,self.width-self.borderX, - self.height-self.borderY) - self.contents.clear - drawTextEx(self.contents,0,4,self.contents.width,0, - @text.gsub(/\r/,""),@baseColor,@shadowColor) - end -end - - - -#=============================================================================== -# -#=============================================================================== -class Window_AdvancedTextPokemon < SpriteWindow_Base - attr_reader :text - attr_reader :baseColor - attr_reader :shadowColor - attr_accessor :letterbyletter - attr_reader :waitcount - - def initialize(text="") - @cursorMode = MessageConfig::CURSOR_POSITION - @endOfText = nil - @scrollstate = 0 - @realframes = 0 - @scrollY = 0 - @nodraw = false - @lineHeight = 32 - @linesdrawn = 0 - @bufferbitmap = nil - @letterbyletter = false - @starting = true - @displaying = false - @lastDrawnChar = -1 - @fmtchars = [] - @frameskipChanged = false - @frameskip = MessageConfig.pbGetTextSpeed() - super(0,0,33,33) - @pausesprite = nil - @text = "" - self.contents = Bitmap.new(1,1) - pbSetSystemFont(self.contents) - self.resizeToFit(text,Graphics.width) - colors = getDefaultTextColors(self.windowskin) - @baseColor = colors[0] - @shadowColor = colors[1] - self.text = text - @starting = false - end - - def self.newWithSize(text,x,y,width,height,viewport=nil) - ret = self.new(text) - ret.x = x - ret.y = y - ret.width = width - ret.height = height - ret.viewport = viewport - return ret - end - - def dispose - return if disposed? - @pausesprite.dispose if @pausesprite - @pausesprite = nil - super - end - - def waitcount=(value) - @waitcount = (value<=0) ? 0 : value - end - - attr_reader :cursorMode - - def cursorMode=(value) - @cursorMode = value - moveCursor - end - - def lineHeight(value) - @lineHeight = value - self.text = self.text - end - - def baseColor=(value) - @baseColor = value - refresh - end - - def shadowColor=(value) - @shadowColor = value - refresh - end - - def textspeed - @frameskip - end - - def textspeed=(value) - @frameskipChanged = true if @frameskip!=value - @frameskip = value - end - - def width=(value) - super - self.text = self.text if !@starting - end - - def height=(value) - super - self.text = self.text if !@starting - end - - def resizeToFit(text,maxwidth=-1) - dims = resizeToFitInternal(text,maxwidth) - oldstarting = @starting - @starting = true - self.width = dims[0]+self.borderX+SpriteWindow_Base::TEXTPADDING - self.height = dims[1]+self.borderY - @starting = oldstarting - redrawText - end - - def resizeToFit2(text,maxwidth,maxheight) - dims = resizeToFitInternal(text,maxwidth) - oldstarting = @starting - @starting = true - self.width = [dims[0]+self.borderX+SpriteWindow_Base::TEXTPADDING,maxwidth].min - self.height = [dims[1]+self.borderY,maxheight].min - @starting = oldstarting - redrawText - end - - def resizeToFitInternal(text,maxwidth) - dims = [0,0] - cwidth = (maxwidth<0) ? Graphics.width : maxwidth - chars = getFormattedTextForDims(self.contents,0,0, - cwidth-self.borderX-2-6,-1,text,@lineHeight,true) - for ch in chars - dims[0] = [dims[0],ch[1]+ch[3]].max - dims[1] = [dims[1],ch[2]+ch[4]].max - end - return dims - end - - def resizeHeightToFit(text,width=-1) - dims = resizeToFitInternal(text,width) - oldstarting = @starting - @starting = true - self.width = (width < 0) ? Graphics.width : width - self.height = dims[1] + self.borderY - @starting = oldstarting - redrawText - end - - def setSkin(skin,redrawText=true) - super(skin) - privRefresh(true) - oldbaser = @baseColor.red - oldbaseg = @baseColor.green - oldbaseb = @baseColor.blue - oldbasea = @baseColor.alpha - oldshadowr = @shadowColor.red - oldshadowg = @shadowColor.green - oldshadowb = @shadowColor.blue - oldshadowa = @shadowColor.alpha - colors = getDefaultTextColors(self.windowskin) - @baseColor = colors[0] - @shadowColor = colors[1] - if redrawText && - (oldbaser!=@baseColor.red || oldbaseg!=@baseColor.green || - oldbaseb!=@baseColor.blue || oldbasea!=@baseColor.alpha || - oldshadowr!=@shadowColor.red || oldshadowg!=@shadowColor.green || - oldshadowb!=@shadowColor.blue || oldshadowa!=@shadowColor.alpha) - setText(self.text) - end - end - - def setTextToFit(text,maxwidth=-1) - resizeToFit(text,maxwidth) - self.text = text - end - - def text=(value) - setText(value) - end - - def setText(value) - @waitcount = 0 - @curchar = 0 - @drawncurchar = -1 - @lastDrawnChar = -1 - @text = value - @textlength = unformattedTextLength(value) - @scrollstate = 0 - @scrollY = 0 - @linesdrawn = 0 - @realframes = 0 - @textchars = [] - width = 1 - height = 1 - numlines = 0 - visiblelines = (self.height-self.borderY)/32 - if value.length==0 - @fmtchars = [] - @bitmapwidth = width - @bitmapheight = height - @numtextchars = 0 - else - if @letterbyletter - @fmtchars = [] - fmt = getFormattedText(self.contents,0,0, - self.width-self.borderX-SpriteWindow_Base::TEXTPADDING,-1, - shadowctag(@baseColor,@shadowColor)+value,32,true) - @oldfont = self.contents.font.clone - for ch in fmt - chx = ch[1]+ch[3] - chy = ch[2]+ch[4] - width = chx if width=visiblelines - fclone = ch.clone - fclone[0] = "\1" - @fmtchars.push(fclone) - @textchars.push("\1") - end - end - # Don't add newline characters, since they - # can slow down letter-by-letter display - if ch[5] || (ch[0]!="\r") - @fmtchars.push(ch) - @textchars.push(ch[5] ? "" : ch[0]) - end - end - fmt.clear - else - @fmtchars = getFormattedText(self.contents,0,0, - self.width-self.borderX-SpriteWindow_Base::TEXTPADDING,-1, - shadowctag(@baseColor,@shadowColor)+value,32,true) - @oldfont = self.contents.font.clone - for ch in @fmtchars - chx = ch[1]+ch[3] - chy = ch[2]+ch[4] - width = chx if width=@fmtchars.length - # index after the last character's index - return @fmtchars[@lastDrawnChar][14]+1 - end - - def maxPosition - pos = 0 - for ch in @fmtchars - # index after the last character's index - pos = ch[14]+1 if pos=@fmtchars.length # End of message - if @textchars[@curchar]=="\1" # Pause message - @pausing = true if @curchar<@numtextchars-1 - self.startPause - refresh - break - end - break if @textchars[@curchar]!="\n" # Skip past newlines only - break if @linesdrawn>=visiblelines-1 # No more empty lines to continue to - @linesdrawn += 1 - end - end - - def allocPause - return if @pausesprite - @pausesprite = AnimatedSprite.create("Graphics/Pictures/pause",4,3) - @pausesprite.z = 100000 - @pausesprite.visible = false - end - - def startPause - allocPause - @pausesprite.visible = true - @pausesprite.frame = 0 - @pausesprite.start - moveCursor - end - - def stopPause - return if !@pausesprite - @pausesprite.stop - @pausesprite.visible = false - end - - def moveCursor - return if !@pausesprite - cursor = @cursorMode - cursor = 2 if cursor==0 && !@endOfText - case cursor - when 0 # End of text - @pausesprite.x = self.x+self.startX+@endOfText.x+@endOfText.width-2 - @pausesprite.y = self.y+self.startY+@endOfText.y-@scrollY - when 1 # Lower right - pauseWidth = @pausesprite.bitmap ? @pausesprite.framewidth : 16 - pauseHeight = @pausesprite.bitmap ? @pausesprite.frameheight : 16 - @pausesprite.x = self.x+self.width-(20*2)+(pauseWidth/2) - @pausesprite.y = self.y+self.height-(30*2)+(pauseHeight/2) - when 2 # Lower middle - pauseWidth = @pausesprite.bitmap ? @pausesprite.framewidth : 16 - pauseHeight = @pausesprite.bitmap ? @pausesprite.frameheight : 16 - @pausesprite.x = self.x+(self.width/2)-(pauseWidth/2) - @pausesprite.y = self.y+self.height-(18*2)+(pauseHeight/2) - end - end - - def refresh - oldcontents = self.contents - self.contents = pbDoEnsureBitmap(oldcontents,@bitmapwidth,@bitmapheight) - self.oy = @scrollY - numchars = @numtextchars - numchars = [@curchar,@numtextchars].min if self.letterbyletter - return if busy? && @drawncurchar==@curchar && @scrollstate==0 - if !self.letterbyletter || !oldcontents.equal?(self.contents) - @drawncurchar = -1 - @needclear = true - end - if @needclear - self.contents.font = @oldfont if @oldfont - self.contents.clear - @needclear = false - end - if @nodraw - @nodraw = false - return - end - maxX = self.width-self.borderX - maxY = self.height-self.borderY - for i in @drawncurchar+1..numchars - next if i>=@fmtchars.length - if !self.letterbyletter - next if @fmtchars[i][1]>=maxX - next if @fmtchars[i][2]>=maxY - end - drawSingleFormattedChar(self.contents,@fmtchars[i]) - @lastDrawnChar = i - end - if !self.letterbyletter - # all characters were drawn, reset old font - self.contents.font = @oldfont if @oldfont - end - if numchars>0 && numchars!=@numtextchars - fch = @fmtchars[numchars-1] - if fch - rcdst = Rect.new(fch[1],fch[2],fch[3],fch[4]) - if @textchars[numchars]=="\1" - @endOfText = rcdst - allocPause - moveCursor - else - @endOfText = Rect.new(rcdst.x+rcdst.width,rcdst.y,8,1) - end - end - end - @drawncurchar = @curchar - end - - def redrawText - if @letterbyletter - oldPosition = self.position - self.text = self.text - oldPosition = @numtextchars if oldPosition>@numtextchars - while self.position!=oldPosition - refresh - updateInternal - end - else - self.text = self.text - end - end - - def updateInternal - curcharskip = @frameskip<0 ? @frameskip.abs : 1 - visiblelines = (self.height-self.borderY)/@lineHeight - if @textchars[@curchar]=="\1" - if !@pausing - @realframes += 1 - if @realframes>=@frameskip || @frameskip<0 - curcharSkip(curcharskip) - @realframes = 0 - end - end - elsif @textchars[@curchar]=="\n" - if @linesdrawn>=visiblelines-1 - if @scrollstate<@lineHeight - @scrollstate += [(@lineHeight/4),1].max - @scrollY += [(@lineHeight/4),1].max - end - if @scrollstate>=@lineHeight - @realframes += 1 - if @realframes>=@frameskip || @frameskip<0 - curcharSkip(curcharskip) - @linesdrawn += 1 - @realframes = 0 - @scrollstate = 0 - end - end - else - @realframes += 1 - if @realframes>=@frameskip || @frameskip<0 - curcharSkip(curcharskip) - @linesdrawn += 1 - @realframes = 0 - end - end - elsif @curchar<=@numtextchars - @realframes += 1 - if @realframes>=@frameskip || @frameskip<0 - curcharSkip(curcharskip) - @realframes = 0 - end - if @textchars[@curchar]=="\1" - @pausing = true if @curchar<@numtextchars-1 - self.startPause - refresh - end - else - @displaying = false - @scrollstate = 0 - @scrollY = 0 - @linesdrawn = 0 - end - end - - def update - super - @pausesprite.update if @pausesprite && @pausesprite.visible - if @waitcount>0 - @waitcount -= 1 - return - end - if busy? - refresh if !@frameskipChanged - updateInternal - # following line needed to allow "textspeed=-999" to work seamlessly - refresh if @frameskipChanged - end - @frameskipChanged = false - end - - private - - def curcharSkip(skip) - skip.times do - @curchar += 1 - break if @textchars[@curchar]=="\n" || # newline - @textchars[@curchar]=="\1" || # pause - @textchars[@curchar]=="\2" || # letter-by-letter break - @textchars[@curchar]==nil - end - end -end - - - -#=============================================================================== -# -#=============================================================================== -class Window_InputNumberPokemon < SpriteWindow_Base - attr_reader :sign - - def initialize(digits_max) - @digits_max=digits_max - @number=0 - @frame=0 - @sign=false - @negative=false - super(0,0,32,32) - self.width=digits_max*24+8+self.borderX - self.height=32+self.borderY - colors=getDefaultTextColors(self.windowskin) - @baseColor=colors[0] - @shadowColor=colors[1] - @index=digits_max-1 - self.active=true - refresh - end - - def active=(value) - super - refresh - end - - def number - @number*(@sign && @negative ? -1 : 1) - end - - def number=(value) - value=0 if !value.is_a?(Numeric) - if @sign - @negative=(value<0) - @number = [value.abs, 10 ** @digits_max - 1].min - else - @number = [[value, 0].max, 10 ** @digits_max - 1].min - end - refresh - end - - def sign=(value) - @sign=value - self.width=@digits_max*24+8+self.borderX+(@sign ? 24 : 0) - @index=(@digits_max-1)+(@sign ? 1 : 0) - refresh - end - - def refresh - self.contents=pbDoEnsureBitmap(self.contents, - self.width-self.borderX,self.height-self.borderY) - pbSetSystemFont(self.contents) - self.contents.clear - s=sprintf("%0*d",@digits_max,@number.abs) - if @sign - textHelper(0,0,@negative ? "-" : "+",0) - end - for i in 0...@digits_max - index=i+(@sign ? 1 : 0) - textHelper(index*24,0,s[i,1],index) - end - end - - def update - super - digits=@digits_max+(@sign ? 1 : 0) - refresh if @frame%15==0 - if self.active - if Input.repeat?(Input::UP) || Input.repeat?(Input::DOWN) - pbPlayCursorSE() - if @index==0 && @sign - @negative=!@negative - else - place = 10 ** (digits - 1 - @index) - n = @number / place % 10 - @number -= n*place - if Input.repeat?(Input::UP) - n = (n + 1) % 10 - elsif Input.repeat?(Input::DOWN) - n = (n + 9) % 10 - end - @number += n*place - end - refresh - elsif Input.repeat?(Input::RIGHT) - if digits >= 2 - pbPlayCursorSE() - @index = (@index + 1) % digits - @frame=0 - refresh - end - elsif Input.repeat?(Input::LEFT) - if digits >= 2 - pbPlayCursorSE() - @index = (@index + digits - 1) % digits - @frame=0 - refresh - end - end - end - @frame=(@frame+1)%30 - end - - private - - def textHelper(x,y,text,i) - textwidth=self.contents.text_size(text).width - pbDrawShadowText(self.contents, x+(12-textwidth/2), y, textwidth+4, 32, text, @baseColor, @shadowColor) - if @index==i && @active && @frame/15==0 - self.contents.fill_rect(x+(12-textwidth/2), y+30, textwidth, 2, @baseColor) - end - end -end - - - -#=============================================================================== -# -#=============================================================================== -class SpriteWindow_Selectable < SpriteWindow_Base - attr_reader :index - - def initialize(x, y, width, height) - super(x, y, width, height) - @item_max = 1 - @column_max = 1 - @virtualOy=0 - @index = -1 - @row_height = 32 - @column_spacing = 32 - @ignore_input = false - @allow_arrows_jump=false - end - - def itemCount - return @item_max || 0 - end - - def index=(index) - if @index!=index - @index = index - priv_update_cursor_rect(true) - end - end - - def rowHeight - return @row_height || 32 - end - - def rowHeight=(value) - if @row_height!=value - oldTopRow=self.top_row - @row_height=[1,value].max - self.top_row=oldTopRow - update_cursor_rect - end - end - - def setAllowArrowsJump(value) - @allow_arrows_jump=value - end - - def columns - return @column_max || 1 - end - - def columns=(value) - if @column_max!=value - @column_max=[1,value].max - update_cursor_rect - end - end - - def columnSpacing - return @column_spacing || 32 - end - - def columnSpacing=(value) - if @column_spacing!=value - @column_spacing=[0,value].max - update_cursor_rect - end - end - - def ignore_input=(value) - @ignore_input=value - end - - def count - return @item_max - end - - def row_max - return ((@item_max + @column_max - 1) / @column_max).to_i - end - - def top_row - return (@virtualOy / (@row_height || 32)).to_i - end - - def top_row=(row) - row = row_max-1 if row>row_max-1 - row = 0 if row<0 - @virtualOy = row*@row_height - end - - def top_item - return top_row * @column_max - end - - def page_row_max - return priv_page_row_max.to_i - end - - def page_item_max - return priv_page_item_max.to_i - end - - def itemRect(item) - if item<0 || item>=@item_max || itemself.top_item+self.page_item_max - return Rect.new(0,0,0,0) - else - cursor_width = (self.width-self.borderX-(@column_max-1)*@column_spacing) / @column_max - x = item % @column_max * (cursor_width + @column_spacing) - y = item / @column_max * @row_height - @virtualOy - return Rect.new(x, y, cursor_width, @row_height) - end - end - - def refresh; end - - def changedPosition; end - - def update_cursor_rect - priv_update_cursor_rect - changedPosition - end - - def update - super - if self.active && @item_max > 0 && @index >= 0 && !@ignore_input - if Input.repeat?(Input::UP) - scroll_up() - elsif Input.repeat?(Input::DOWN) - scroll_down() - elsif Input.repeat?(Input::LEFT) && !@allow_arrows_jump - scroll_left() - elsif Input.repeat?(Input::RIGHT) && !@allow_arrows_jump - scroll_right() - elsif Input.repeat?(Input::JUMPUP) || (Input.repeat?(Input::LEFT) && @allow_arrows_jump) - jump_up() - elsif Input.repeat?(Input::JUMPDOWN) || (Input.repeat?(Input::RIGHT) && @allow_arrows_jump) - jump_down() - end - end - end - - def scroll_up() - if @index >= @column_max || - (Input.trigger?(Input::UP) && (@item_max % @column_max)==0) - oldindex = @index - @index = (@index - @column_max + @item_max) % @item_max - if @index!=oldindex - pbPlayCursorSE() - update_cursor_rect - end - end - end - - def scroll_down() - if @index < @item_max - @column_max || - (Input.trigger?(Input::DOWN) && (@item_max % @column_max)==0) - oldindex = @index - @index = (@index + @column_max) % @item_max - if @index!=oldindex - pbPlayCursorSE() - update_cursor_rect - end - end - end - - def scroll_left() - if @column_max >= 2 && @index < @item_max - 1 - oldindex = @index - @index += 1 - if @index!=oldindex - pbPlayCursorSE() - update_cursor_rect - end - end - end - - def scroll_right() - if @column_max >= 2 && @index > 0 - oldindex = @index - @index -= 1 - if @index!=oldindex - pbPlayCursorSE() - update_cursor_rect - end - end - end - - - def jump_up() - if @index > 0 - oldindex = @index - @index = [self.index-self.page_item_max, 0].max - if @index!=oldindex - pbPlayCursorSE() - self.top_row -= self.page_row_max - update_cursor_rect - end - end - end - - - def jump_down() - if @index < @item_max-1 - oldindex = @index - @index = [self.index+self.page_item_max, @item_max-1].min - if @index!=oldindex - pbPlayCursorSE() - self.top_row += self.page_row_max - update_cursor_rect - end - end - end - - private - - def priv_page_row_max - return (self.height - self.borderY) / @row_height - end - - def priv_page_item_max - return (self.height - self.borderY) / @row_height * @column_max - end - - def priv_update_cursor_rect(force=false) - if @index < 0 - self.cursor_rect.empty - self.refresh - return - end - dorefresh = false - row = @index / @column_max - # This code makes lists scroll only when the cursor hits the top and bottom - # of the visible list. -# if row < self.top_row -# self.top_row = row -# dorefresh=true -# end -# if row > self.top_row + (self.page_row_max - 1) -# self.top_row = row - (self.page_row_max - 1) -# dorefresh=true -# end -# if oldindex-self.top_item>=((self.page_item_max - 1)/2) -# self.top_row+=1 -# end -# self.top_row = [self.top_row, self.row_max - self.page_row_max].min - # This code makes the cursor stay in the middle of the visible list as much - # as possible. - new_top_row = row - ((self.page_row_max - 1)/2).floor - new_top_row = [[new_top_row, self.row_max - self.page_row_max].min, 0].max - if self.top_row != new_top_row - self.top_row = new_top_row -# dorefresh = true - end - # End of code - cursor_width = (self.width-self.borderX) / @column_max - x = self.index % @column_max * (cursor_width + @column_spacing) - y = self.index / @column_max * @row_height - @virtualOy - self.cursor_rect.set(x, y, cursor_width, @row_height) - self.refresh if dorefresh || force - end -end - - - -#=============================================================================== -# -#=============================================================================== -module UpDownArrowMixin - def initUpDownArrow - @uparrow = AnimatedSprite.create("Graphics/Pictures/uparrow",8,2,self.viewport) - @downarrow = AnimatedSprite.create("Graphics/Pictures/downarrow",8,2,self.viewport) - RPG::Cache.retain("Graphics/Pictures/uparrow") - RPG::Cache.retain("Graphics/Pictures/downarrow") - @uparrow.z = 99998 - @downarrow.z = 99998 - @uparrow.visible = false - @downarrow.visible = false - @uparrow.play - @downarrow.play - end - - def dispose - @uparrow.dispose - @downarrow.dispose - super - end - - def viewport=(value) - super - @uparrow.viewport = self.viewport - @downarrow.viewport = self.viewport - end - - def color=(value) - super - @uparrow.color = value - @downarrow.color = value - end - - def adjustForZoom(sprite) - sprite.zoom_x = self.zoom_x - sprite.zoom_y = self.zoom_y - sprite.x = sprite.x*self.zoom_x + self.offset_x/self.zoom_x - sprite.y = sprite.y*self.zoom_y + self.offset_y/self.zoom_y - end - - def update - super - @uparrow.x = self.x+(self.width/2)-(@uparrow.framewidth/2) - @downarrow.x = self.x+(self.width/2)-(@downarrow.framewidth/2) - @uparrow.y = self.y - @downarrow.y = self.y+self.height-@downarrow.frameheight - @uparrow.visible = self.visible && self.active && (self.top_item!=0 && - @item_max > self.page_item_max) - @downarrow.visible = self.visible && self.active && - (self.top_item+self.page_item_max<@item_max && @item_max > self.page_item_max) - @uparrow.z = self.z+1 - @downarrow.z = self.z+1 - adjustForZoom(@uparrow) - adjustForZoom(@downarrow) - @uparrow.viewport = self.viewport - @downarrow.viewport = self.viewport - @uparrow.update - @downarrow.update - end -end - - - -#=============================================================================== -# -#=============================================================================== -class SpriteWindow_SelectableEx < SpriteWindow_Selectable - include UpDownArrowMixin - - def initialize(*arg) - super(*arg) - initUpDownArrow - end -end - - - -#=============================================================================== -# -#=============================================================================== -class Window_DrawableCommand < SpriteWindow_SelectableEx - attr_reader :baseColor - attr_reader :shadowColor - attr_reader :index - - def initialize(x,y,width,height,viewport=nil) - super(x,y,width,height) - self.viewport = viewport if viewport - if isDarkWindowskin(self.windowskin) - @selarrow = AnimatedBitmap.new("Graphics/Pictures/selarrow_white") - RPG::Cache.retain("Graphics/Pictures/selarrow_white") - else - @selarrow = AnimatedBitmap.new("Graphics/Pictures/selarrow") - RPG::Cache.retain("Graphics/Pictures/selarrow") - end - @index = 0 - colors = getDefaultTextColors(self.windowskin) - @baseColor = Color.new(150, 150, 150)#colors[0] - @shadowColor = colors[1] - refresh - end - - - def dispose - @selarrow.dispose - super - end - - def baseColor=(value) - @baseColor = value - refresh - end - - def shadowColor=(value) - @shadowColor = value - refresh - end - - def textWidth(bitmap,text) - return bitmap.text_size(text).width - end - - def getAutoDims(commands,dims,width=nil) - rowMax = ((commands.length + self.columns - 1) / self.columns).to_i - windowheight = (rowMax*self.rowHeight) - windowheight += self.borderY - if !width || width<0 - width=0 - tmpbitmap = BitmapWrapper.new(1,1) - pbSetSystemFont(tmpbitmap) - for i in commands - width = [width,tmpbitmap.text_size(i).width].max - end - # one 16 to allow cursor - width += 16+16+SpriteWindow_Base::TEXTPADDING - tmpbitmap.dispose - end - # Store suggested width and height of window - dims[0] = [self.borderX+1,(width*self.columns)+self.borderX+ - (self.columns-1)*self.columnSpacing].max - dims[1] = [self.borderY+1,windowheight].max - dims[1] = [dims[1],Graphics.height].min - end - - def setSkin(skin) - super(skin) - privRefresh(true) - colors = getDefaultTextColors(self.windowskin) - @baseColor = colors[0] - @shadowColor = colors[1] - end - - def drawCursor(index,rect) - if self.index==index - pbCopyBitmap(self.contents,@selarrow.bitmap,rect.x,rect.y) - end - return Rect.new(rect.x+16,rect.y,rect.width-16,rect.height) - end - - def itemCount # to be implemented by derived classes - return 0 - end - - def drawItem(index,count,rect) # to be implemented by derived classes - end - - def refresh - @item_max = itemCount() - dwidth = self.width-self.borderX - dheight = self.height-self.borderY - self.contents = pbDoEnsureBitmap(self.contents,dwidth,dheight) - self.contents.clear - for i in 0...@item_max - next if iself.top_item+self.page_item_max - drawItem(i,@item_max,itemRect(i)) - end - end - - def update - oldindex = self.index - super - refresh if self.index!=oldindex - end -end - - - -#=============================================================================== -# -#=============================================================================== -class Window_CommandPokemon < Window_DrawableCommand - attr_reader :commands - - def initialize(commands,width=nil) - @starting=true - @commands=[] - dims=[] - super(0,0,32,32) - getAutoDims(commands,dims,width) - self.width=dims[0] - self.height=dims[1] - @commands=commands - self.active=true - colors=getDefaultTextColors(self.windowskin) - self.baseColor=colors[0] - self.shadowColor=colors[1] - refresh - @starting=false - end - - def self.newWithSize(commands,x,y,width,height,viewport=nil) - ret=self.new(commands,width) - ret.x=x - ret.y=y - ret.width=width - ret.height=height - ret.viewport=viewport - return ret - end - - def self.newEmpty(x,y,width,height,viewport=nil) - ret=self.new([],width) - ret.x=x - ret.y=y - ret.width=width - ret.height=height - ret.viewport=viewport - return ret - end - - def index=(value) - super - refresh if !@starting - end - - def commands=(value) - @commands=value - @item_max=commands.length - self.update_cursor_rect - self.refresh - end - - def width=(value) - super - if !@starting - self.index=self.index - self.update_cursor_rect - end - end - - def height=(value) - super - if !@starting - self.index=self.index - self.update_cursor_rect - end - end - - def resizeToFit(commands,width=nil) - dims=[] - getAutoDims(commands,dims,width) - self.width=dims[0] - self.height=dims[1] - end - - def itemCount - return @commands ? @commands.length : 0 - end - - def drawItem(index,_count,rect) - pbSetSystemFont(self.contents) if @starting - rect=drawCursor(index,rect) - pbDrawShadowText(self.contents,rect.x,rect.y,rect.width,rect.height, - @commands[index],self.baseColor,self.shadowColor) - end -end - - - -#=============================================================================== -# -#=============================================================================== -class Window_CommandPokemonEx < Window_CommandPokemon -end - - -#=============================================================================== -# -#=============================================================================== -class Window_AdvancedCommandPokemon < Window_DrawableCommand - attr_reader :commands - - def textWidth(bitmap,text) - dims=[nil,0] - chars=getFormattedText(bitmap,0,0, - Graphics.width-self.borderX-SpriteWindow_Base::TEXTPADDING-16, - -1,text,self.rowHeight,true,true) - for ch in chars - dims[0]=dims[0] ? [dims[0],ch[1]].min : ch[1] - dims[1]=[dims[1],ch[1]+ch[3]].max - end - dims[0]=0 if !dims[0] - return dims[1]-dims[0] - end - - def initialize(commands,width=nil) - @starting=true - @commands=[] - dims=[] - super(0,0,32,32) - getAutoDims(commands,dims,width) - self.width=dims[0] - self.height=dims[1] - @commands=commands - self.active=true - colors=getDefaultTextColors(self.windowskin) - self.baseColor=colors[0] - self.shadowColor=colors[1] - refresh - @starting=false - end - - def self.newWithSize(commands,x,y,width,height,viewport=nil) - ret=self.new(commands,width) - ret.x=x - ret.y=y - ret.width=width - ret.height=height - ret.viewport=viewport - return ret - end - - def self.newEmpty(x,y,width,height,viewport=nil) - ret=self.new([],width) - ret.x=x - ret.y=y - ret.width=width - ret.height=height - ret.viewport=viewport - return ret - end - - def index=(value) - super - refresh if !@starting - end - - def commands=(value) - @commands=value - @item_max=commands.length - self.update_cursor_rect - self.refresh - end - - def width=(value) - oldvalue=self.width - super - if !@starting && oldvalue!=value - self.index=self.index - self.update_cursor_rect - end - end - - def height=(value) - oldvalue=self.height - super - if !@starting && oldvalue!=value - self.index=self.index - self.update_cursor_rect - end - end - - def resizeToFit(commands,width=nil) - dims=[] - getAutoDims(commands,dims,width) - self.width=dims[0] - self.height=dims[1] - 6 - end - - def itemCount - return @commands ? @commands.length : 0 - end - - def drawItem(index,_count,rect) - pbSetSystemFont(self.contents) - rect=drawCursor(index,rect) - if toUnformattedText(@commands[index]).gsub(/\n/,"")==@commands[index] - # Use faster alternative for unformatted text without line breaks - pbDrawShadowText(self.contents,rect.x,rect.y,rect.width,rect.height, - @commands[index],self.baseColor,self.shadowColor) - else - chars=getFormattedText( - self.contents,rect.x,rect.y+4,rect.width,rect.height, - @commands[index],rect.height,true,true) - drawFormattedChars(self.contents,chars) - end - end -end - - - -#=============================================================================== -# -#=============================================================================== -class Window_AdvancedCommandPokemonEx < Window_AdvancedCommandPokemon -end diff --git a/Data/Scripts/007_Objects and windows/006_SpriteWindow_pictures.rb b/Data/Scripts/007_Objects and windows/006_SpriteWindow_pictures.rb deleted file mode 100644 index f9ce0aed1..000000000 --- a/Data/Scripts/007_Objects and windows/006_SpriteWindow_pictures.rb +++ /dev/null @@ -1,123 +0,0 @@ -#=============================================================================== -# Displays an icon bitmap in a window. Supports animated images. -#=============================================================================== -class IconWindow < SpriteWindow_Base - attr_reader :name - - def initialize(x,y,width,height,viewport=nil) - super(x,y,width,height) - self.viewport=viewport - self.contents=nil - @name="" - @_iconbitmap=nil - end - - def dispose - clearBitmaps() - super - end - - def update - super - if @_iconbitmap - @_iconbitmap.update - self.contents=@_iconbitmap.bitmap - end - end - - def clearBitmaps - @_iconbitmap.dispose if @_iconbitmap - @_iconbitmap=nil - self.contents=nil if !self.disposed? - end - - # Sets the icon's filename. Alias for setBitmap. - def name=(value) - setBitmap(value) - end - - # Sets the icon's filename. - def setBitmap(file,hue=0) - clearBitmaps() - @name=file - return if file==nil - if file!="" - @_iconbitmap=AnimatedBitmap.new(file,hue) - # for compatibility - self.contents=@_iconbitmap ? @_iconbitmap.bitmap : nil - else - @_iconbitmap=nil - end - end -end - - - -#=============================================================================== -# Displays an icon bitmap in a window. Supports animated images. -# Accepts bitmaps and paths to bitmap files in its constructor. -#=============================================================================== -class PictureWindow < SpriteWindow_Base - def initialize(pathOrBitmap) - super(0,0,32,32) - self.viewport=viewport - self.contents=nil - @_iconbitmap=nil - setBitmap(pathOrBitmap) - end - - def picture; @_iconbitmap; end - - def dispose - clearBitmaps() - super - end - - def update - super - if @_iconbitmap - if @_iconbitmap.is_a?(Bitmap) - self.contents=@_iconbitmap - else - @_iconbitmap.update - self.contents=@_iconbitmap.bitmap - end - end - end - - def clearBitmaps - @_iconbitmap.dispose if @_iconbitmap - @_iconbitmap=nil - self.contents=nil if !self.disposed? - end - - # Sets the icon's bitmap or filename. (hue parameter - # is ignored unless pathOrBitmap is a filename) - def setBitmap(pathOrBitmap,hue=0) - clearBitmaps() - if pathOrBitmap!=nil && pathOrBitmap!="" - if pathOrBitmap.is_a?(Bitmap) - @_iconbitmap=pathOrBitmap - self.contents=@_iconbitmap - self.width=@_iconbitmap.width+self.borderX - self.height=@_iconbitmap.height+self.borderY - elsif pathOrBitmap.is_a?(AnimatedBitmap) - @_iconbitmap=pathOrBitmap - self.contents=@_iconbitmap.bitmap - self.width=@_iconbitmap.bitmap.width+self.borderX - self.height=@_iconbitmap.bitmap.height+self.borderY - else - @_iconbitmap=AnimatedBitmap.new(pathOrBitmap,hue) - self.contents=@_iconbitmap ? @_iconbitmap.bitmap : nil - self.width=@_iconbitmap ? @_iconbitmap.bitmap.width+self.borderX : - 32+self.borderX - self.height=@_iconbitmap ? @_iconbitmap.bitmap.height+self.borderY : - 32+self.borderY - end - else - @_iconbitmap=nil - self.width=32+self.borderX - self.height=32+self.borderY - end - end -end diff --git a/Data/Scripts/007_Objects and windows/007_SpriteWrapper.rb b/Data/Scripts/007_Objects and windows/007_SpriteWrapper.rb deleted file mode 100644 index 9541069f7..000000000 --- a/Data/Scripts/007_Objects and windows/007_SpriteWrapper.rb +++ /dev/null @@ -1,496 +0,0 @@ -#=============================================================================== -# SpriteWrapper is a class which wraps (most of) Sprite's properties. -#=============================================================================== -class SpriteWrapper - def initialize(viewport = nil) - @sprite = Sprite.new(viewport) - end - - def dispose - @sprite.dispose; - end - - def disposed? - return @sprite.disposed?; - end - - def viewport - return @sprite.viewport; - end - - def flash(color, duration) - ; return @sprite.flash(color, duration); - end - - def update - return @sprite.update; - end - - def x - @sprite.x; - end - - def x=(value) - ; @sprite.x = value; - end - - def y - @sprite.y; - end - - def y=(value) - ; @sprite.y = value; - end - - def bitmap - @sprite.bitmap; - end - - def bitmap=(value) - ; @sprite.bitmap = value; - end - - def src_rect - @sprite.src_rect; - end - - def src_rect=(value) - ; @sprite.src_rect = value; - end - - def visible - @sprite.visible; - end - - def visible=(value) - ; @sprite.visible = value; - end - - def z - @sprite.z; - end - - def z=(value) - ; @sprite.z = value; - end - - def ox - @sprite.ox; - end - - def ox=(value) - ; @sprite.ox = value; - end - - def oy - @sprite.oy; - end - - def oy=(value) - ; @sprite.oy = value; - end - - def zoom_x - @sprite.zoom_x; - end - - def zoom_x=(value) - ; @sprite.zoom_x = value; - end - - def zoom_y - @sprite.zoom_y; - end - - def zoom_y=(value) - ; @sprite.zoom_y = value; - end - - def angle - @sprite.angle; - end - - def angle=(value) - ; @sprite.angle = value; - end - - def mirror - @sprite.mirror; - end - - def mirror=(value) - ; @sprite.mirror = value; - end - - def bush_depth - @sprite.bush_depth; - end - - def bush_depth=(value) - ; @sprite.bush_depth = value; - end - - def opacity - @sprite.opacity; - end - - def opacity=(value) - ; @sprite.opacity = value; - end - - def blend_type - @sprite.blend_type; - end - - def blend_type=(value) - ; @sprite.blend_type = value; - end - - def color - @sprite.color; - end - - def color=(value) - ; @sprite.color = value; - end - - def tone - @sprite.tone; - end - - def tone=(value) - ; @sprite.tone = value; - end - - def viewport=(value) - return if self.viewport == value - bitmap = @sprite.bitmap - src_rect = @sprite.src_rect - visible = @sprite.visible - x = @sprite.x - y = @sprite.y - z = @sprite.z - ox = @sprite.ox - oy = @sprite.oy - zoom_x = @sprite.zoom_x - zoom_y = @sprite.zoom_y - angle = @sprite.angle - mirror = @sprite.mirror - bush_depth = @sprite.bush_depth - opacity = @sprite.opacity - blend_type = @sprite.blend_type - color = @sprite.color - tone = @sprite.tone - @sprite.dispose - @sprite = Sprite.new(value) - @sprite.bitmap = bitmap - @sprite.src_rect = src_rect - @sprite.visible = visible - @sprite.x = x - @sprite.y = y - @sprite.z = z - @sprite.ox = ox - @sprite.oy = oy - @sprite.zoom_x = zoom_x - @sprite.zoom_y = zoom_y - @sprite.angle = angle - @sprite.mirror = mirror - @sprite.bush_depth = bush_depth - @sprite.opacity = opacity - @sprite.blend_type = blend_type - @sprite.color = color - @sprite.tone = tone - end -end - -#=============================================================================== -# Sprite class that maintains a bitmap of its own. -# This bitmap can't be changed to a different one. -#=============================================================================== -class BitmapSprite < SpriteWrapper - def initialize(width, height, viewport = nil) - super(viewport) - self.bitmap = Bitmap.new(width, height) - @initialized = true - end - - def bitmap=(value) - super(value) if !@initialized - end - - def dispose - self.bitmap.dispose if !self.disposed? - super - end -end - -#=============================================================================== -# -#=============================================================================== -class AnimatedSprite < SpriteWrapper - attr_reader :frame - attr_reader :framewidth - attr_reader :frameheight - attr_reader :framecount - attr_reader :animname - attr_reader :playing - - def initializeLong(animname, framecount, framewidth, frameheight, frameskip) - @animname = pbBitmapName(animname) - @realframes = 0 - @frameskip = [1, frameskip].max - @frameskip *= Graphics.frame_rate / 20 - raise _INTL("Frame width is 0") if framewidth == 0 - raise _INTL("Frame height is 0") if frameheight == 0 - begin - @animbitmap = AnimatedBitmap.new(animname).deanimate - rescue - @animbitmap = Bitmap.new(framewidth, frameheight) - end - if @animbitmap.width % framewidth != 0 - raise _INTL("Bitmap's width ({1}) is not a multiple of frame width ({2}) [Bitmap={3}]", - @animbitmap.width, framewidth, animname) - end - if @animbitmap.height % frameheight != 0 - raise _INTL("Bitmap's height ({1}) is not a multiple of frame height ({2}) [Bitmap={3}]", - @animbitmap.height, frameheight, animname) - end - @framecount = framecount - @framewidth = framewidth - @frameheight = frameheight - @framesperrow = @animbitmap.width / @framewidth - @playing = false - self.bitmap = @animbitmap - self.src_rect.width = @framewidth - self.src_rect.height = @frameheight - self.frame = 0 - end - - # Shorter version of AnimationSprite. All frames are placed on a single row - # of the bitmap, so that the width and height need not be defined beforehand - def initializeShort(animname, framecount, frameskip) - @animname = pbBitmapName(animname) - @realframes = 0 - @frameskip = [1, frameskip].max - @frameskip *= Graphics.frame_rate / 20 - begin - @animbitmap = AnimatedBitmap.new(animname).deanimate - rescue - @animbitmap = Bitmap.new(framecount * 4, 32) - end - if @animbitmap.width % framecount != 0 - raise _INTL("Bitmap's width ({1}) is not a multiple of frame count ({2}) [Bitmap={3}]", - @animbitmap.width, framewidth, animname) - end - @framecount = framecount - @framewidth = @animbitmap.width / @framecount - @frameheight = @animbitmap.height - @framesperrow = framecount - @playing = false - self.bitmap = @animbitmap - self.src_rect.width = @framewidth - self.src_rect.height = @frameheight - self.frame = 0 - end - - def initialize(*args) - if args.length == 1 - super(args[0][3]) - initializeShort(args[0][0], args[0][1], args[0][2]) - else - super(args[5]) - initializeLong(args[0], args[1], args[2], args[3], args[4]) - end - end - - def self.create(animname, framecount, frameskip, viewport = nil) - return self.new([animname, framecount, frameskip, viewport]) - end - - def dispose - return if disposed? - @animbitmap.dispose - @animbitmap = nil - super - end - - def playing? - return @playing - end - - def frame=(value) - @frame = value - @realframes = 0 - self.src_rect.x = @frame % @framesperrow * @framewidth - self.src_rect.y = @frame / @framesperrow * @frameheight - end - - def start - @playing = true - @realframes = 0 - end - - alias play start - - def stop - @playing = false - end - - def reset - @frame=0 - @realframes = 0 - end - - def update - super - if @playing - @realframes += 1 - if @realframes == @frameskip - @realframes = 0 - self.frame += 1 - self.frame %= self.framecount - end - end - end -end - -#=============================================================================== -# Displays an icon bitmap in a sprite. Supports animated images. -#=============================================================================== -class IconSprite < SpriteWrapper - attr_reader :name - def initialize(*args) - if args.length == 0 - super(nil) - self.bitmap = nil - elsif args.length == 1 - super(args[0]) - self.bitmap = nil - elsif args.length == 2 - super(nil) - self.x = args[0] - self.y = args[1] - else - super(args[2]) - self.x = args[0] - self.y = args[1] - end - @name = "" - @_iconbitmap = nil - end - - def dispose - clearBitmaps() - super - end - - # Sets the icon's filename. Alias for setBitmap. - def name=(value) - setBitmap(value) - end - - def setBitmapDirectly(bitmap) - oldrc = self.src_rect - clearBitmaps() - @name = "" - return if bitmap == nil - @_iconbitmap = bitmap - # for compatibility - # - self.bitmap = @_iconbitmap ? @_iconbitmap.bitmap : nil - self.src_rect = oldrc - end - - def setColor(r = 0, g = 0, b = 0, a = 255) - @_iconbitmap.pbSetColor(r,g,b,a) - end - - # Sets the icon's filename. - def setBitmap(file, hue = 0) - oldrc = self.src_rect - clearBitmaps() - @name = file - return if file == nil - if file != "" - @_iconbitmap = AnimatedBitmap.new(file, hue) - # for compatibility - self.bitmap = @_iconbitmap ? @_iconbitmap.bitmap : nil - self.src_rect = oldrc - else - @_iconbitmap = nil - end - end - - def getBitmap - return @_iconbitmap - end - - def clearBitmaps - @_iconbitmap.dispose if @_iconbitmap - @_iconbitmap = nil - self.bitmap = nil if !self.disposed? - end - - def update - super - return if !@_iconbitmap - @_iconbitmap.update - if self.bitmap != @_iconbitmap.bitmap - oldrc = self.src_rect - self.bitmap = @_iconbitmap.bitmap - self.src_rect = oldrc - end - end - - -end - -#=============================================================================== -# Old GifSprite class, retained for compatibility -#=============================================================================== -class GifSprite < IconSprite - def initialize(path) - super(0, 0) - setBitmap(path) - end -end - -#=============================================================================== -# SpriteWrapper that stores multiple bitmaps, and displays only one at once. -#=============================================================================== -class ChangelingSprite < SpriteWrapper - def initialize(x = 0, y = 0, viewport = nil) - super(viewport) - self.x = x - self.y = y - @bitmaps = {} - @currentBitmap = nil - end - - def addBitmap(key, path) - @bitmaps[key].dispose if @bitmaps[key] - @bitmaps[key] = AnimatedBitmap.new(path) - end - - def changeBitmap(key) - @currentBitmap = @bitmaps[key] - self.bitmap = (@currentBitmap) ? @currentBitmap.bitmap : nil - end - - def dispose - return if disposed? - for bm in @bitmaps.values; - bm.dispose; - end - @bitmaps.clear - super - end - - def update - return if disposed? - for bm in @bitmaps.values; - bm.update; - end - self.bitmap = (@currentBitmap) ? @currentBitmap.bitmap : nil - end -end diff --git a/Data/Scripts/007_Objects and windows/008_AnimatedBitmap.rb b/Data/Scripts/007_Objects and windows/008_AnimatedBitmap.rb deleted file mode 100644 index e9d737529..000000000 --- a/Data/Scripts/007_Objects and windows/008_AnimatedBitmap.rb +++ /dev/null @@ -1,360 +0,0 @@ -#=============================================================================== -# -#=============================================================================== - -class AnimatedBitmap - attr_reader :path - attr_reader :filename - - def initialize(file, hue = 0) - raise "Filename is nil (missing graphic)." if file.nil? - path = file - filename = "" - if file.last != '/' # Isn't just a directory - split_file = file.split(/[\\\/]/) - filename = split_file.pop - path = split_file.join('/') + '/' - end - @filename = filename - @path = path - if filename[/^\[\d+(?:,\d+)?\]/] # Starts with 1 or 2 numbers in square brackets - @bitmap = PngAnimatedBitmap.new(path, filename, hue) - else - @bitmap = GifBitmap.new(path, filename, hue) - end - end - - def setup_from_bitmap(bitmap,hue=0) - @path = "" - @filename = "" - @bitmap = GifBitmap.new("", '', hue) - @bitmap.bitmap = bitmap; - end - - def self.from_bitmap(bitmap, hue=0) - obj = allocate - obj.send(:setup_from_bitmap, bitmap, hue) - obj - end - - def pbSetColor(r = 0, g = 0, b = 0, a = 255) - color = Color.new(r, g, b, a) - pbSetColorValue(color) - end - - def pbSetColorValue(color) - for i in 0..@bitmap.bitmap.width - for j in 0..@bitmap.bitmap.height - if @bitmap.bitmap.get_pixel(i, j).alpha != 0 - @bitmap.bitmap.set_pixel(i, j, color) - end - end - end - end - - - def shiftColors(offset = 0) - @bitmap.bitmap.hue_change(offset) - end - - def [](index) - ; @bitmap[index]; - end - - def width - @bitmap.bitmap.width; - end - - def height - @bitmap.bitmap.height; - end - - def length - @bitmap.length; - end - - def each - @bitmap.each { |item| yield item }; - end - - def bitmap - @bitmap.bitmap; - end - - def bitmap=(bitmap) - @bitmap.bitmap = bitmap; - end - - def currentIndex - @bitmap.currentIndex; - end - - def totalFrames - @bitmap.totalFrames; - end - - def disposed? - @bitmap.disposed?; - end - - def update - @bitmap.update; - end - - def dispose - @bitmap.dispose; - end - - def deanimate - @bitmap.deanimate; - end - - def copy - @bitmap.copy; - end - - def scale_bitmap(scale) - return if scale == 1 - new_width = @bitmap.bitmap.width * scale - new_height = @bitmap.bitmap.height * scale - - destination_rect = Rect.new(0, 0, new_width, new_height) - source_rect = Rect.new(0, 0, @bitmap.bitmap.width, @bitmap.bitmap.height) - new_bitmap = Bitmap.new(new_width, new_height) - new_bitmap.stretch_blt( - destination_rect, - @bitmap.bitmap, - source_rect - ) - @bitmap.bitmap = new_bitmap - end - - # def mirror - # for x in 0..@bitmap.bitmap.width / 2 - # for y in 0..@bitmap.bitmap.height - 2 - # temp = @bitmap.bitmap.get_pixel(x, y) - # newPix = @bitmap.bitmap.get_pixel((@bitmap.bitmap.width - x), y) - # - # @bitmap.bitmap.set_pixel(x, y, newPix) - # @bitmap.bitmap.set_pixel((@bitmap.bitmap.width - x), y, temp) - # end - # end - # end - - def mirror - @bitmap.bitmap - end - -end - - -#=============================================================================== -# -#=============================================================================== -class PngAnimatedBitmap - attr_accessor :frames - - # Creates an animated bitmap from a PNG file. - def initialize(dir, filename, hue = 0) - @frames = [] - @currentFrame = 0 - @framecount = 0 - panorama = RPG::Cache.load_bitmap(dir, filename, hue) - if filename[/^\[(\d+)(?:,(\d+))?\]/] # Starts with 1 or 2 numbers in brackets - # File has a frame count - numFrames = $1.to_i - delay = $2.to_i - delay = 10 if delay == 0 - raise "Invalid frame count in #{filename}" if numFrames <= 0 - raise "Invalid frame delay in #{filename}" if delay <= 0 - if panorama.width % numFrames != 0 - raise "Bitmap's width (#{panorama.width}) is not divisible by frame count: #{filename}" - end - @frameDelay = delay - subWidth = panorama.width / numFrames - for i in 0...numFrames - subBitmap = BitmapWrapper.new(subWidth, panorama.height) - subBitmap.blt(0, 0, panorama, Rect.new(subWidth * i, 0, subWidth, panorama.height)) - @frames.push(subBitmap) - end - panorama.dispose - else - @frames = [panorama] - end - end - - def [](index) - return @frames[index] - end - - def width - self.bitmap.width; - end - - def height - self.bitmap.height; - end - - def deanimate - for i in 1...@frames.length - @frames[i].dispose - end - @frames = [@frames[0]] - @currentFrame = 0 - return @frames[0] - end - - def bitmap - return @frames[@currentFrame] - end - - def currentIndex - return @currentFrame - end - - def frameDelay(_index) - return @frameDelay - end - - def length - return @frames.length - end - - def each - @frames.each { |item| yield item } - end - - def totalFrames - return @frameDelay * @frames.length - end - - def disposed? - return @disposed - end - - def update - return if disposed? - if @frames.length > 1 - @framecount += 1 - if @framecount >= @frameDelay - @framecount = 0 - @currentFrame += 1 - @currentFrame %= @frames.length - end - end - end - - def dispose - if !@disposed - @frames.each { |f| f.dispose } - end - @disposed = true - end - - def copy - x = self.clone - x.frames = x.frames.clone - for i in 0...x.frames.length - x.frames[i] = x.frames[i].copy - end - return x - end -end - -#=============================================================================== -# -#=============================================================================== -class GifBitmap - attr_accessor :bitmap - attr_reader :loaded_from_cache - # Creates a bitmap from a GIF file. Can also load non-animated bitmaps. - def initialize(dir, filename, hue = 0) - @bitmap = nil - @disposed = false - @loaded_from_cache = false - filename = "" if !filename - begin - @bitmap = RPG::Cache.load_bitmap(dir, filename, hue) - @loaded_from_cache = true - rescue - @bitmap = nil - end - @bitmap = BitmapWrapper.new(32, 32) if @bitmap.nil? - @bitmap.play if @bitmap&.animated? - end - - def [](_index) - return @bitmap - end - - def deanimate - @bitmap&.goto_and_stop(0) if @bitmap&.animated? - return @bitmap - end - - def currentIndex - return @bitmap&.current_frame || 0 - end - - def length - return @bitmap&.frame_count || 1 - end - - def each - yield @bitmap - end - - def totalFrames - f_rate = @bitmap.frame_rate - f_rate = 1 if f_rate.nil? || f_rate == 0 - return (@bitmap) ? (@bitmap.frame_count / f_rate).floor : 1 - end - - def disposed? - return @disposed - end - - def width - return @bitmap&.width || 0 - end - - def height - return @bitmap&.height || 0 - end - - # Gifs are animated automatically by mkxp-z. This function does nothing. - def update; end - - def dispose - return if @disposed - @bitmap.dispose - @disposed = true - end - - def copy - x = self.clone - x.bitmap = @bitmap.copy if @bitmap - return x - end -end - -#=============================================================================== -# -#=============================================================================== -def pbGetTileBitmap(filename, tile_id, hue, width = 1, height = 1) - return RPG::Cache.tileEx(filename, tile_id, hue, width, height) { |f| - AnimatedBitmap.new("Graphics/Tilesets/" + filename).deanimate - } -end - -def pbGetTileset(name, hue = 0) - return AnimatedBitmap.new("Graphics/Tilesets/" + name, hue).deanimate -end - -def pbGetAutotile(name, hue = 0) - return AnimatedBitmap.new("Graphics/Autotiles/" + name, hue).deanimate -end - -def pbGetAnimation(name, hue = 0) - return AnimatedBitmap.new("Graphics/Animations/" + name, hue).deanimate -end diff --git a/Data/Scripts/007_Objects and windows/009_Planes.rb b/Data/Scripts/007_Objects and windows/009_Planes.rb deleted file mode 100644 index 26258bc24..000000000 --- a/Data/Scripts/007_Objects and windows/009_Planes.rb +++ /dev/null @@ -1,230 +0,0 @@ -#=============================================================================== -# -#=============================================================================== -class Plane - def update; end - def refresh; end -end - - - -#=============================================================================== -# This class works around a limitation that planes are always -# 640 by 480 pixels in size regardless of the window's size. -#=============================================================================== -class LargePlane < Plane - attr_accessor :borderX - attr_accessor :borderY - - def initialize(viewport=nil) - @__sprite=Sprite.new(viewport) - @__disposed=false - @__ox=0 - @__oy=0 - @__bitmap=nil - @__visible=true - @__sprite.visible=false - @borderX=0 - @borderY=0 - end - - def disposed? - return @__disposed - end - - def dispose - if !@__disposed - @__sprite.bitmap.dispose if @__sprite.bitmap - @__sprite.dispose - @__sprite=nil - @__bitmap=nil - @__disposed=true - end - #super - end - - def ox; @__ox; end - def oy; @__oy; end - - def ox=(value); - return if @__ox==value - @__ox = value - refresh - end - - def oy=(value); - return if @__oy==value - @__oy = value - refresh - end - - def bitmap - return @__bitmap - end - - def bitmap=(value) - if value==nil - if @__bitmap!=nil - @__bitmap=nil - @__sprite.visible=(@__visible && !@__bitmap.nil?) - end - elsif @__bitmap!=value && !value.disposed? - @__bitmap=value - refresh - elsif value.disposed? - if @__bitmap!=nil - @__bitmap=nil - @__sprite.visible=(@__visible && !@__bitmap.nil?) - end - end - end - - def viewport; @__sprite.viewport; end - def zoom_x; @__sprite.zoom_x; end - def zoom_y; @__sprite.zoom_y; end - def opacity; @__sprite.opacity; end - def blend_type; @__sprite.blend_type; end - def visible; @__visible; end - def z; @__sprite.z; end - def color; @__sprite.color; end - def tone; @__sprite.tone; end - - def zoom_x=(v); - return if @__sprite.zoom_x==v - @__sprite.zoom_x = v - refresh - end - - def zoom_y=(v); - return if @__sprite.zoom_y==v - @__sprite.zoom_y = v - refresh - end - - def opacity=(v); @__sprite.opacity=(v); end - def blend_type=(v); @__sprite.blend_type=(v); end - def visible=(v); @__visible=v; @__sprite.visible=(@__visible && !@__bitmap.nil?); end - def z=(v); @__sprite.z=(v); end - def color=(v); @__sprite.color=(v); end - def tone=(v); @__sprite.tone=(v); end - def update; ;end - - def refresh - @__sprite.visible = (@__visible && !@__bitmap.nil?) - if @__bitmap - if !@__bitmap.disposed? - @__ox += @__bitmap.width*@__sprite.zoom_x if @__ox<0 - @__oy += @__bitmap.height*@__sprite.zoom_y if @__oy<0 - @__ox -= @__bitmap.width*@__sprite.zoom_x if @__ox>@__bitmap.width - @__oy -= @__bitmap.height*@__sprite.zoom_y if @__oy>@__bitmap.height - dwidth = (Graphics.width/@__sprite.zoom_x+@borderX).to_i # +2 - dheight = (Graphics.height/@__sprite.zoom_y+@borderY).to_i # +2 - @__sprite.bitmap = ensureBitmap(@__sprite.bitmap,dwidth,dheight) - @__sprite.bitmap.clear - tileBitmap(@__sprite.bitmap,@__bitmap,@__bitmap.rect) - else - @__sprite.visible = false - end - end - end - - private - - def ensureBitmap(bitmap,dwidth,dheight) - if !bitmap || bitmap.disposed? || bitmap.width0; left -= srcbitmap.width; end - while top>0; top -= srcbitmap.height; end - y = top - while y",ret) -end - -def shadowctag(base,shadow) - return sprintf("",colorToRgb16(base),colorToRgb16(shadow)) -end - -def shadowc3tag(base,shadow) - return sprintf("",colorToRgb32(base),colorToRgb32(shadow)) -end - -def shadowctagFromColor(color) - return shadowc3tag(color,getContrastColor(color)) -end - -def shadowctagFromRgb(param) - return shadowctagFromColor(rgbToColor(param)) -end - -def colorToRgb32(color) - return "" if !color - if color.alpha.to_i==255 - return sprintf("%02X%02X%02X",color.red.to_i,color.green.to_i,color.blue.to_i) - else - return sprintf("%02X%02X%02X%02X", - color.red.to_i,color.green.to_i,color.blue.to_i,color.alpha.to_i) - end -end - -def colorToRgb16(color) - ret=(color.red.to_i>>3) - ret|=((color.green.to_i>>3)<<5) - ret|=((color.blue.to_i>>3)<<10) - return sprintf("%04X",ret) -end - -def rgbToColor(param) - return Font.default_color if !param - baseint=param.to_i(16) - if param.length==8 # 32-bit hex - return Color.new( - (baseint>>24)&0xFF, - (baseint>>16)&0xFF, - (baseint>>8)&0xFF, - (baseint)&0xFF - ) - elsif param.length==6 # 24-bit hex - return Color.new( - (baseint>>16)&0xFF, - (baseint>>8)&0xFF, - (baseint)&0xFF - ) - elsif param.length==4 # 16-bit hex - return Color.new( - ((baseint)&0x1F)<<3, - ((baseint>>5)&0x1F)<<3, - ((baseint>>10)&0x1F)<<3 - ) - elsif param.length==1 # Color number - i=param.to_i - return Font.default_color if i>=8 - return [ - Color.new(255, 255, 255, 255), - Color.new(128, 128, 255, 255), - Color.new(255, 128, 128, 255), - Color.new(128, 255, 128, 255), - Color.new(128, 255, 255, 255), - Color.new(255, 128, 255, 255), - Color.new(255, 255, 128, 255), - Color.new(192, 192, 192, 255) - ][i] - else - return Font.default_color - end -end - -def Rgb16ToColor(param) - baseint=param.to_i(16) - return Color.new( - ((baseint)&0x1F)<<3, - ((baseint>>5)&0x1F)<<3, - ((baseint>>10)&0x1F)<<3 - ) -end - -def getContrastColor(color) - raise "No color given" if !color - r=color.red; g=color.green; b=color.blue - yuv=[ - r * 0.299 + g * 0.587 + b * 0.114, - r * -0.1687 + g * -0.3313 + b * 0.500 + 0.5, - r * 0.500 + g * -0.4187 + b * -0.0813 + 0.5 - ] - if yuv[0]<127.5 - yuv[0]+=(255-yuv[0])/2 - else - yuv[0]=yuv[0]/2 - end - return Color.new( - yuv[0] + 1.4075 * (yuv[2] - 0.5), - yuv[0] - 0.3455 * (yuv[1] - 0.5) - 0.7169 * (yuv[2] - 0.5), - yuv[0] + 1.7790 * (yuv[1] - 0.5), - color.alpha - ) -end - - - -#=============================================================================== -# Format text -#=============================================================================== -FORMATREGEXP = /<(\/?)(c|c2|c3|o|fn|br|fs|i|b|r|pg|pog|u|s|icon|img|ac|ar|al|outln|outln2)(\s*\=\s*([^>]*))?>/i - -def fmtescape(text) - if text[/[&<>]/] - text2=text.gsub(/&/,"&") - text2.gsub!(//,">") - return text2 - end - return text -end - -def toUnformattedText(text) - text2=text.gsub(FORMATREGEXP,"") - text2.gsub!(/</,"<") - text2.gsub!(/>/,">") - text2.gsub!(/'/,"'") - text2.gsub!(/"/,"\"") - text2.gsub!(/&/,"&") - return text2 -end - -def unformattedTextLength(text) - return toUnformattedText(text).scan(/./m).length -end - -def itemIconTag(item) - return "" if !item - if item.respond_to?("icon_name") - return sprintf("",item.icon_name) - else - ix=item.icon_index % 16 * 24 - iy=item.icon_index / 16 * 24 - return sprintf("",ix,iy) - end -end - -def getFormattedTextForDims(bitmap,xDst,yDst,widthDst,heightDst,text,lineheight, - newlineBreaks=true,explicitBreaksOnly=false) - text2=text.gsub(/<(\/?)(c|c2|c3|o|u|s)(\s*\=\s*([^>]*))?>/i,"") - if newlineBreaks - text2.gsub!(/<(\/?)(br)(\s*\=\s*([^>]*))?>/i,"\n") - end - return getFormattedText( - bitmap,xDst,yDst,widthDst,heightDst, - text2,lineheight,newlineBreaks, - explicitBreaksOnly,true) -end - -def getFormattedTextFast(bitmap,xDst,yDst,widthDst,heightDst,text,lineheight, - newlineBreaks=true,explicitBreaksOnly=false) - x=y=0 - characters=[] - textchunks=[] - textchunks.push(text) - text=textchunks.join("") - textchars=text.scan(/./m) - lastword=[0,0] # position of last word - hadspace=false - hadnonspace=false - bold=bitmap.font.bold - italic=bitmap.font.italic - colorclone=bitmap.font.color - defaultfontname=bitmap.font.name - if defaultfontname.is_a?(Array) - defaultfontname=defaultfontname.find { |i| Font.exist?(i) } || "Arial" - elsif !Font.exist?(defaultfontname) - defaultfontname="Arial" - end - defaultfontname=defaultfontname.clone - havenl=false - position=0 - while positionwidthDst && lastword[1]!=0 && - (!hadnonspace || !hadspace) - havenl=true - characters.insert(lastword[0],["\n",x,y*lineheight+yDst,0,lineheight, - false,false,false,colorclone,nil,false,false,"",8,position]) - lastword[0]+=1 - y+=1 - x=0 - for i in lastword[0]...characters.length - characters[i][2]+=lineheight - charwidth=characters[i][3]-2 - characters[i][1]=x - x+=charwidth - end - lastword[1]=0 - end - position+=1 - end - # This code looks at whether the text occupies exactly two lines when - # displayed. If it does, it balances the length of each line. -=begin - # Count total number of lines - numlines = (x==0 && y>0) ? y-1 : y - realtext = (newlineBreaks) ? text : text.gsub(/\n/," ") - if numlines==2 && !explicitBreaksOnly && !realtext[/\n/] && realtext.length>=50 - # Set half to middle of text (known to contain no formatting) - half = realtext.length/2 - leftSearch = 0 - rightSearch = 0 - # Search left for a space - i = half; while i>=0 - break if realtext[i,1][/\s/]||isWaitChar(realtext[i]) # found a space - leftSearch += 1 - i -= 1 - end - # Search right for a space - i = half; while i=0 - for j in firstspace...i - characters[j]=nil - end - firstspace=-1 - elsif characters[i][0][/[ \r\t]/] - if firstspace<0 - firstspace=i - end - else - firstspace=-1 - end - end - if firstspace>0 - for j in firstspace...characters.length - characters[j]=nil - end - end - characters.compact! - end - for i in 0...characters.length - characters[i][1]=xDst+characters[i][1] - end - # Remove all characters with Y greater or equal to _yDst_+_heightDst_ - if heightDst>=0 - for i in 0...characters.length - if characters[i][2]>=yDst+heightDst - characters[i]=nil - end - end - characters.compact! - end - return characters -end - -def isWaitChar(x) - return (x=="\001" || x=="\002") -end - -def getLastParam(array,default) - i=array.length-1 - while i>=0 - return array[i] if array[i] - i-=1 - end - return default -end - -def getLastColors(colorstack,opacitystack,defaultcolors) - colors=getLastParam(colorstack,defaultcolors) - opacity=getLastParam(opacitystack,255) - if opacity!=255 - colors=[Color.new(colors[0].red,colors[0].green,colors[0].blue, - colors[0].alpha*opacity/255), - colors[1] ? Color.new(colors[1].red,colors[1].green,colors[1].blue, - colors[1].alpha*opacity/255) : nil] - end - return colors -end - - - -#=============================================================================== -# Formats a string of text and returns an array containing a list of formatted -# characters. -#=============================================================================== -=begin -Parameters: -bitmap: Source bitmap. Will be used to determine the default font of - the text. -xDst: X coordinate of the text's top left corner. -yDst: Y coordinate of the text's top left corner. -widthDst: Width of the text. Used to determine line breaks. -heightDst: Height of the text. If -1, there is no height restriction. If - 1 or greater, any characters exceeding the height are removed - from the returned list. -newLineBreaks: If true, newline characters will be treated as line breaks. The - default is true. - -Return Values: -A list of formatted characters. Returns an empty array if _bitmap_ is nil -or disposed, or if _widthDst_ is 0 or less or _heightDst_ is 0. - -Formatting Specification: -This function uses the following syntax when formatting the text. - ... - Formats the text in bold. - ... - Formats the text in italics. - ... - Underlines the text. - ... - Draws a strikeout line over the text. - ... - Left-aligns the text. Causes line breaks before and after - the text. - - Right-aligns the text until the next line break. - ... - Right-aligns the text. Causes line breaks before and after - the text. - ... - Centers the text. Causes line breaks before and after the - text. -
- Causes a line break. - ... - Color specification. A total of four formats are supported: - RRGGBBAA, RRGGBB, 16-bit RGB, and Window_Base color numbers. - ... - Color specification where the first half is the base color - and the second half is the shadow color. 16-bit RGB is - supported. -Added 2009-10-20 - ... - Color specification where B is the base color and S is the - shadow color. B and/or S can be omitted. A total of four - formats are supported: - RRGGBBAA, RRGGBB, 16-bit RGB, and Window_Base color numbers. -Added 2009-9-12 - - Displays the text in the given opacity (0-255) -Added 2009-10-19 - - Displays the text in outline format. -Added 2010-05-12 - - Displays the text in outline format (outlines more - exaggerated. - ... - Formats the text in the specified font, or Arial if the - font doesn't exist. - ... - Changes the font size to X. - - Displays the icon X (in Graphics/Icons/). - -In addition, the syntax supports the following: -' - Converted to "'". -< - Converted to "<". -> - Converted to ">". -& - Converted to "&". -" - Converted to double quotation mark. - -To draw the characters, pass the returned array to the -_drawFormattedChars_ function. -=end - -def getFormattedText(bitmap,xDst,yDst,widthDst,heightDst,text,lineheight=32, - newlineBreaks=true,explicitBreaksOnly=false, - collapseAlignments=false) - dummybitmap=nil - if !bitmap || bitmap.disposed? # allows function to be called with nil bitmap - dummybitmap=Bitmap.new(1,1) - bitmap=dummybitmap - return - end - if !bitmap || bitmap.disposed? || widthDst<=0 || heightDst==0 || text.length==0 - return [] - end - textchunks=[] - controls=[] - oldtext=text - while text[FORMATREGEXP] - textchunks.push($~.pre_match) - if $~[3] - controls.push([$~[2].downcase,$~[4],-1,$~[1]=="/" ? true : false]) - else - controls.push([$~[2].downcase,"",-1,$~[1]=="/" ? true : false]) - end - text=$~.post_match - end - if controls.length==0 - ret=getFormattedTextFast(bitmap,xDst,yDst,widthDst,heightDst,text,lineheight, - newlineBreaks,explicitBreaksOnly) - dummybitmap.dispose if dummybitmap - return ret - end - x=y=0 - characters=[] - charactersInternal=[] - realtext=nil - realtextStart="" - if !explicitBreaksOnly && textchunks.join("").length==0 - # All commands occurred at the beginning of the text string - realtext=(newlineBreaks) ? text : text.gsub(/\n/," ") - realtextStart=oldtext[0,oldtext.length-realtext.length] - realtextHalf=text.length/2 - end - textchunks.push(text) - for chunk in textchunks - chunk.gsub!(/</,"<") - chunk.gsub!(/>/,">") - chunk.gsub!(/'/,"'") - chunk.gsub!(/"/,"\"") - chunk.gsub!(/&/,"&") - end - textlen=0 - for i in 0...controls.length - textlen+=textchunks[i].scan(/./m).length - controls[i][2]=textlen - end - text=textchunks.join("") - textchars=text.scan(/./m) - colorstack=[] - boldcount=0 - italiccount=0 - outlinecount=0 - underlinecount=0 - strikecount=0 - rightalign=0 - outline2count=0 - opacitystack=[] - oldfont=bitmap.font.clone - defaultfontname=bitmap.font.name - defaultfontsize=bitmap.font.size - fontsize=defaultfontsize - fontnamestack=[] - fontsizestack=[] - defaultcolors=[oldfont.color.clone,nil] - if defaultfontname.is_a?(Array) - defaultfontname=defaultfontname.find { |i| Font.exist?(i) } || "Arial" - elsif !Font.exist?(defaultfontname) - defaultfontname="Arial" - end - defaultfontname=defaultfontname.clone - fontname=defaultfontname - alignstack=[] - lastword=[0,0] # position of last word - hadspace=false - hadnonspace=false - havenl=false - position=0 - while position0 && nextline==0 - else - alignstack.pop - nextline=1 if x>0 && nextline==0 - end - elsif control=="al" # Left align - if !endtag - alignstack.push(0) - nextline=1 if x>0 && nextline==0 - else - alignstack.pop - nextline=1 if x>0 && nextline==0 - end - elsif control=="ac" # Center align - if !endtag - alignstack.push(2) - nextline=1 if x>0 && nextline==0 - else - alignstack.pop - nextline=1 if x>0 && nextline==0 - end - elsif control=="icon" # Icon - if !endtag - param=param.sub(/\s+$/,"") - graphic="Graphics/Icons/#{param}" - controls[i]=nil - break - end - elsif control=="img" # Icon - if !endtag - param=param.sub(/\s+$/,"") - param=param.split("|") - graphic=param[0] - if param.length>1 - graphicX=param[1].to_i - graphicY=param[2].to_i - graphicWidth=param[3].to_i - graphicHeight=param[4].to_i - end - controls[i]=nil - break - end - elsif control=="br" # Line break - if !endtag - nextline+=1 - end - elsif control=="r" # Right align this line - if !endtag - x=0 - rightalign=1; lastword=[characters.length,x] - end - end - controls[i]=nil - end - end - bitmap.font.bold=(boldcount>0) - bitmap.font.italic=(italiccount>0) - if graphic - if !graphicWidth - tempgraphic=Bitmap.new(graphic) - graphicWidth=tempgraphic.width - graphicHeight=tempgraphic.height - tempgraphic.dispose - end - width=graphicWidth # +8 # No padding - xStart=0 # 4 - yStart=[(lineheight/2)-(graphicHeight/2),0].max - graphicRect=Rect.new(graphicX,graphicY,graphicWidth,graphicHeight) - else - xStart=0 - yStart=0 - width=isWaitChar(textchars[position]) ? 0 : bitmap.text_size(textchars[position]).width - width+=2 if width>0 && outline2count>0 - end - if rightalign==1 && nextline==0 - alignment=1 - else - alignment=getLastParam(alignstack,0) - end - nextline.times do - havenl=true - characters.push(["\n",x,y*lineheight+yDst,0,lineheight,false,false,false, - defaultcolors[0],defaultcolors[1],false,false,"",8,position,nil,0]) - charactersInternal.push([alignment,y,0]) - y+=1 - x=0 - rightalign=0 - lastword=[characters.length,x] - hadspace=false - hadnonspace=false - end - if textchars[position]=="\n" - if newlineBreaks - if nextline==0 - havenl=true - characters.push(["\n",x,y*lineheight+yDst,0,lineheight,false,false,false, - defaultcolors[0],defaultcolors[1],false,false,"",8,position,nil,0]) - charactersInternal.push([alignment,y,0]) - y+=1 - x=0 - end - rightalign=0 - hadspace=true - hadnonspace=false - position+=1 - next - else - textchars[position]=" " - if !graphic - width=bitmap.text_size(textchars[position]).width - width+=2 if width>0 && outline2count>0 - end - end - end - isspace=(textchars[position][/\s/] || isWaitChar(textchars[position])) ? true : false - if hadspace && !isspace - # set last word to here - lastword[0]=characters.length - lastword[1]=x - hadspace=false - hadnonspace=true - elsif isspace - hadspace=true - end - texty=(lineheight*y)+yDst+yStart - colors=getLastColors(colorstack,opacitystack,defaultcolors) - # Push character - if heightDst<0 || texty0) ? 2+(width/2) : 2 - characters.push([ - graphic ? graphic : textchars[position], - x+xStart,texty,width+extraspace,lineheight, - graphic ? true : false, - (boldcount>0),(italiccount>0),colors[0],colors[1], - (underlinecount>0),(strikecount>0),fontname,fontsize, - position,graphicRect, - ((outlinecount>0) ? 1 : 0)+((outline2count>0) ? 2 : 0) - ]) - charactersInternal.push([alignment,y,xStart,textchars[position],extraspace]) - end - x+=width - if !explicitBreaksOnly && x+2>widthDst && lastword[1]!=0 && - (!hadnonspace || !hadspace) - havenl=true - characters.insert(lastword[0],["\n",x,y*lineheight+yDst,0,lineheight,false, - false,false,defaultcolors[0],defaultcolors[1],false,false,"",8,position, - nil]) - charactersInternal.insert(lastword[0],[alignment,y,0]) - lastword[0]+=1 - y+=1 - x=0 - for i in lastword[0]...characters.length - characters[i][2]+=lineheight - charactersInternal[i][1]+=1 - extraspace=(charactersInternal[i][4]) ? charactersInternal[i][4] : 0 - charwidth=characters[i][3]-extraspace - characters[i][1]=x+charactersInternal[i][2] - x+=charwidth - end - lastword[1]=0 - end - position+=1 if !graphic - end - # This code looks at whether the text occupies exactly two lines when - # displayed. If it does, it balances the length of each line. -=begin - # Count total number of lines - numlines = (x==0 && y>0) ? y : y+1 - if numlines==2 && realtext && !realtext[/\n/] && realtext.length>=50 - # Set half to middle of text (known to contain no formatting) - half = realtext.length/2 - leftSearch = 0 - rightSearch = 0 - # Search left for a space - i = half; while i>=0 - break if realtext[i,1][/\s/]||isWaitChar(realtext[i,1]) # found a space - leftSearch += 1 - i -= 1 - end - # Search right for a space - i = half; while i=0 - for j in firstspace...i - characters[j]=nil - charactersInternal[j]=nil - end - firstspace=-1 - elsif characters[i][0][/[ \r\t]/] - if firstspace<0 - firstspace=i - end - else - firstspace=-1 - end - end - if firstspace>0 - for j in firstspace...characters.length - characters[j]=nil - charactersInternal[j]=nil - end - end - characters.compact! - charactersInternal.compact! - end - # Calculate Xs based on alignment - # First, find all text runs with the same alignment on the same line - totalwidth=0 - widthblocks=[] - lastalign=0 - lasty=0 - runstart=0 - for i in 0...characters.length - c=characters[i] - if i>0 && (charactersInternal[i][0]!=lastalign || - charactersInternal[i][1]!=lasty) - # Found end of run - widthblocks.push([runstart,i,lastalign,totalwidth,lasty]) - runstart=i - totalwidth=0 - end - lastalign=charactersInternal[i][0] - lasty=charactersInternal[i][1] - extraspace=(charactersInternal[i][4]) ? charactersInternal[i][4] : 0 - totalwidth+=c[3]-extraspace - end - widthblocks.push([runstart,characters.length,lastalign,totalwidth,lasty]) - if collapseAlignments - # Calculate the total width of each line - totalLineWidths=[] - for block in widthblocks - y=block[4] - if !totalLineWidths[y] - totalLineWidths[y]=0 - end - if totalLineWidths[y]!=0 - # padding in case more than one line has different alignments - totalLineWidths[y]+=16 - end - totalLineWidths[y]+=block[3] - end - # Calculate a new width for the next step - widthDst=[widthDst,(totalLineWidths.compact.max || 0)].min - end - # Now, based on the text runs found, recalculate Xs - for block in widthblocks - next if block[0]>=block[1] - for i in block[0]...block[1] - case block[2] - when 1 then characters[i][1] = xDst + (widthDst - block[3] - 4) + characters[i][1] - when 2 then characters[i][1] = xDst + ((widthDst / 2) - (block[3] / 2)) + characters[i][1] - else characters[i][1] = xDst + characters[i][1] - end - end - end - # Remove all characters with Y greater or equal to _yDst_+_heightDst_ - if heightDst>=0 - for i in 0...characters.length - if characters[i][2]>=yDst+heightDst - characters[i]=nil - end - end - characters.compact! - end - bitmap.font=oldfont - dummybitmap.dispose if dummybitmap - return characters -end - - - -#=============================================================================== -# Draw text and images on a bitmap -#=============================================================================== -def getLineBrokenText(bitmap,value,width,dims) - x=0 - y=0 - textheight=0 - ret=[] - if dims - dims[0]=0 - dims[1]=0 - end - line=0 - position=0 - column=0 - return ret if !bitmap || bitmap.disposed? || width<=0 - textmsg=value.clone - ret.push(["",0,0,0,bitmap.text_size("X").height,0,0,0,0]) - while ((c = textmsg.slice!(/\n|(\S*([ \r\t\f]?))/)) != nil) - break if c=="" - length=c.scan(/./m).length - ccheck=c - if ccheck=="\n" - ret.push(["\n",x,y,0,textheight,line,position,column,0]) - x=0 - y+=(textheight==0) ? bitmap.text_size("X").height : textheight - line+=1 - textheight=0 - column=0 - position+=length - ret.push(["",x,y,0,textheight,line,position,column,0]) - next - end - words=[ccheck] - for i in 0...words.length - word=words[i] - if word && word!="" - textSize=bitmap.text_size(word) - textwidth=textSize.width - if x>0 && x+textwidth>=width-2 - # Zero-length word break - ret.push(["",x,y,0,textheight,line,position,column,0]) - x=0 - column=0 - y+=(textheight==0) ? bitmap.text_size("X").height : textheight - line+=1 - textheight=0 - end - textheight=[textheight,textSize.height].max - ret.push([word,x,y,textwidth,textheight,line,position,column,length]) - x+=textwidth - dims[0]=x if dims && dims[0]]+)>/ - reNoMatch=/]+>/ - return ret if !bitmap || bitmap.disposed? || width<=0 - textmsg=value.clone - color=Font.default_color - while (c = textmsg.slice!(/\n|[^ \r\t\f\n\-]*\-+|(\S*([ \r\t\f]?))/)) != nil - break if c=="" - ccheck=c - if ccheck=="\n" - x=0 - y+=32 - next - end - if ccheck[/0 && x+textwidth>width - minTextSize=bitmap.text_size(word.gsub(/\s*/,"")) - if x>0 && x+minTextSize.width>width - x=0 - y+=32 - end - end - ret.push([word,x,y,textwidth,32,color]) - x+=textwidth - dims[0]=x if dims && dims[0]"+text - chars=getFormattedText(bitmap,x,y,width,-1,text,lineheight) - drawFormattedChars(bitmap,chars) -end - -# Unused -def pbDrawShadow(bitmap,x,y,width,height,string) - return if !bitmap || !string - pbDrawShadowText(bitmap,x,y,width,height,string,nil,bitmap.font.color) -end - -def pbDrawShadowText(bitmap,x,y,width,height,string,baseColor,shadowColor=nil,align=0) - return if !bitmap || !string - width=(width<0) ? bitmap.text_size(string).width+1 : width - height=(height<0) ? bitmap.text_size(string).height+1 : height - y += 4 - if shadowColor && shadowColor.alpha>0 - bitmap.font.color=shadowColor - bitmap.draw_text(x+2,y,width,height,string,align) - bitmap.draw_text(x,y+2,width,height,string,align) - bitmap.draw_text(x+2,y+2,width,height,string,align) - end - if baseColor && baseColor.alpha>0 - bitmap.font.color=baseColor - bitmap.draw_text(x,y,width,height,string,align) - end -end - -def pbDrawOutlineText(bitmap,x,y,width,height,string,baseColor,shadowColor=nil,align=0) - return if !bitmap || !string - width=(width<0) ? bitmap.text_size(string).width+4 : width - height=(height<0) ? bitmap.text_size(string).height+4 : height - if shadowColor && shadowColor.alpha>0 - bitmap.font.color=shadowColor - bitmap.draw_text(x-2,y-2,width,height,string,align) - bitmap.draw_text(x,y-2,width,height,string,align) - bitmap.draw_text(x+2,y-2,width,height,string,align) - bitmap.draw_text(x-2,y,width,height,string,align) - bitmap.draw_text(x+2,y,width,height,string,align) - bitmap.draw_text(x-2,y+2,width,height,string,align) - bitmap.draw_text(x,y+2,width,height,string,align) - bitmap.draw_text(x+2,y+2,width,height,string,align) - end - if baseColor && baseColor.alpha>0 - bitmap.font.color=baseColor - bitmap.draw_text(x,y,width,height,string,align) - end -end - -# Draws text on a bitmap. _textpos_ is an array of text commands. Each text -# command is an array that contains the following: -# 0 - Text to draw -# 1 - X coordinate -# 2 - Y coordinate -# 3 - If true or 1, the text is right aligned. If 2, the text is centered. -# Otherwise, the text is left aligned. -# 4 - Base color -# 5 - Shadow color -# 6 - If true or 1, the text has an outline. Otherwise, the text has a shadow. -def pbDrawTextPositions(bitmap,textpos) - for i in textpos - textsize = bitmap.text_size(i[0]) - - x = i[1] - y = i[2] + 6 - if i[3]==true || i[3]==1 # right align - x -= textsize.width - elsif i[3]==2 # centered - x -= (textsize.width/2) - end - if i[6]==true || i[6]==1 # outline text - pbDrawOutlineText(bitmap,x,y,textsize.width,textsize.height,i[0],i[4],i[5]) - else - pbDrawShadowText(bitmap,x,y,textsize.width,textsize.height,i[0],i[4],i[5]) - end - end -end - - - -#=============================================================================== -# Draw images on a bitmap -#=============================================================================== -def pbCopyBitmap(dstbm,srcbm,x,y,opacity=255) - rc = Rect.new(0,0,srcbm.width,srcbm.height) - dstbm.blt(x,y,srcbm,rc,opacity) -end - -def pbDrawImagePositions(bitmap,textpos) - for i in textpos - srcbitmap=AnimatedBitmap.new(pbBitmapName(i[0])) - x=i[1] - y=i[2] - srcx=i[3] || 0 - srcy=i[4] || 0 - width=(i[5] && i[5]>=0) ? i[5] : srcbitmap.width - height=(i[6] && i[6]>=0) ? i[6] : srcbitmap.height - color = i[7] || nil - if color - srcbitmap.pbSetColorValue(color) - end - srcrect=Rect.new(srcx,srcy,width,height) - bitmap.blt(x,y,srcbitmap.bitmap,srcrect) - - - srcbitmap.dispose - end -end - - -#added for quest log script ( edit ) -def renderMultiLine(bitmap,xDst,yDst,normtext,maxheight,baseColor,shadowColor) - for i in 0...normtext.length - width=normtext[i][3] - textx=normtext[i][1]+xDst - texty=normtext[i][2]+yDst - if shadowColor - height=normtext[i][4] - text=normtext[i][0] - bitmap.font.color=shadowColor - bitmap.draw_text(textx-2,texty-2,width,height,text,0) - bitmap.draw_text(textx,texty-2,width,height,text,0) - bitmap.draw_text(textx+2,texty-2,width,height,text,0) - bitmap.draw_text(textx-2,texty,width,height,text,0) - bitmap.draw_text(textx+2,texty,width,height,text,0) - bitmap.draw_text(textx-2,texty+2,width,height,text,0) - bitmap.draw_text(textx,texty+2,width,height,text,0) - bitmap.draw_text(textx+2,texty+2,width,height,text,0) - end - if baseColor - height=normtext[i][4] - text=normtext[i][0] - bitmap.font.color=baseColor - bitmap.draw_text(textx,texty,width,height,text,0) - end - end -end - -def drawTextExMulti(bitmap,x,y,width,numlines,text,baseColor,shadowColor) - normtext=getLineBrokenChunks(bitmap,text,width,nil,true) - renderMultiLine(bitmap,x,y,normtext,numlines*32,baseColor,shadowColor) -end \ No newline at end of file diff --git a/Data/Scripts/007_Objects and windows/011_Messages.rb b/Data/Scripts/007_Objects and windows/011_Messages.rb deleted file mode 100644 index 99b90a966..000000000 --- a/Data/Scripts/007_Objects and windows/011_Messages.rb +++ /dev/null @@ -1,1057 +0,0 @@ -#=============================================================================== -# -#=============================================================================== -class Scene_Map - def updatemini - oldmws = $game_temp.message_window_showing - $game_temp.message_window_showing = true - loop do - $game_map.update - $game_player.update - $game_system.update - if $game_screen - $game_screen.update - else - $game_map.screen.update - end - break unless $game_temp.player_transferring - transfer_player - break if $game_temp.transition_processing - end - $game_temp.message_window_showing = oldmws - @spriteset.update if @spriteset - @message_window.update if @message_window - end -end - -class Scene_Battle - def updatemini - if self.respond_to?("update_basic") - update_basic(true) - update_info_viewport # Update information viewport - else - oldmws = $game_temp.message_window_showing - $game_temp.message_window_showing = true - # Update system (timer) and screen - $game_system.update - if $game_screen - $game_screen.update - else - $game_map.screen.update - end - # If timer has reached 0 - if $game_system.timer_working && $game_system.timer == 0 - # Abort battle - $game_temp.battle_abort = true - end - # Update windows - @help_window.update if @help_window - @party_command_window.update if @party_command_window - @actor_command_window.update if @actor_command_window - @status_window.update if @status_window - $game_temp.message_window_showing = oldmws - @message_window.update if @message_window - # Update sprite set - @spriteset.update if @spriteset - end - end -end - -def pbMapInterpreter - if $game_map.respond_to?("interpreter") - return $game_map.interpreter - elsif $game_system - return $game_system.map_interpreter - end - return nil -end - -def pbMapInterpreterRunning? - interp = pbMapInterpreter - return interp && interp.running? -end - -def pbRefreshSceneMap - if $scene && $scene.is_a?(Scene_Map) - if $scene.respond_to?("miniupdate") - $scene.miniupdate - else - $scene.updatemini - end - elsif $scene && $scene.is_a?(Scene_Battle) - $scene.updatemini - end -end - -def pbUpdateSceneMap - if $scene && $scene.is_a?(Scene_Map) && !pbIsFaded? - if $scene.respond_to?("miniupdate") - $scene.miniupdate - else - $scene.updatemini - end - elsif $scene && $scene.is_a?(Scene_Battle) - $scene.updatemini - end -end - -#=============================================================================== -# -#=============================================================================== -def pbEventCommentInput(*args) - parameters = [] - list = *args[0].list # Event or event page - elements = *args[1] # Number of elements - trigger = *args[2] # Trigger - return nil if list == nil - return nil unless list.is_a?(Array) - for item in list - next unless item.code == 108 || item.code == 408 - if item.parameters[0] == trigger - start = list.index(item) + 1 - finish = start + elements - for id in start...finish - next if !list[id] - parameters.push(list[id].parameters[0]) - end - return parameters - end - end - return nil -end - -def pbCurrentEventCommentInput(elements, trigger) - return nil if !pbMapInterpreterRunning? - event = pbMapInterpreter.get_character(0) - return nil if !event - return pbEventCommentInput(event, elements, trigger) -end - -#=============================================================================== -# -#=============================================================================== -class ChooseNumberParams - def initialize - @maxDigits = 0 - @minNumber = 0 - @maxNumber = 0 - @skin = nil - @messageSkin = nil - @negativesAllowed = false - @initialNumber = 0 - @cancelNumber = nil - end - - def setMessageSkin(value) - @messageSkin = value - end - - def messageSkin # Set the full path for the message's window skin - @messageSkin - end - - def setSkin(value) - @skin = value - end - - def skin - @skin - end - - def setNegativesAllowed(value) - @negativeAllowed = value - end - - def negativesAllowed - @negativeAllowed ? true : false - end - - def setRange(minNumber, maxNumber) - maxNumber = minNumber if minNumber > maxNumber - @maxDigits = 0 - @minNumber = minNumber - @maxNumber = maxNumber - end - - def setDefaultValue(number) - @initialNumber = number - @cancelNumber = nil - end - - def setInitialValue(number) - @initialNumber = number - end - - def setCancelValue(number) - @cancelNumber = number - end - - def initialNumber - return clamp(@initialNumber, self.minNumber, self.maxNumber) - end - - def cancelNumber - return @cancelNumber || self.initialNumber - end - - def minNumber - ret = 0 - if @maxDigits > 0 - ret = -((10 ** @maxDigits) - 1) - else - ret = @minNumber - end - ret = 0 if !@negativeAllowed && ret < 0 - return ret - end - - def maxNumber - ret = 0 - if @maxDigits > 0 - ret = ((10 ** @maxDigits) - 1) - else - ret = @maxNumber - end - ret = 0 if !@negativeAllowed && ret < 0 - return ret - end - - def setMaxDigits(value) - @maxDigits = [1, value].max - end - - def maxDigits - if @maxDigits > 0 - return @maxDigits - else - return [numDigits(self.minNumber), numDigits(self.maxNumber)].max - end - end - - private - - def clamp(v, mn, mx) - return v < mn ? mn : (v > mx ? mx : v) - end - - def numDigits(number) - ans = 1 - number = number.abs - while number >= 10 - ans += 1 - number /= 10 - end - return ans - end -end - -def pbChooseNumber(msgwindow, params) - return 0 if !params - ret = 0 - maximum = params.maxNumber - minimum = params.minNumber - defaultNumber = params.initialNumber - cancelNumber = params.cancelNumber - cmdwindow = Window_InputNumberPokemon.new(params.maxDigits) - cmdwindow.z = 99999 - cmdwindow.visible = true - cmdwindow.setSkin(params.skin) if params.skin - cmdwindow.sign = params.negativesAllowed # must be set before number - cmdwindow.number = defaultNumber - pbPositionNearMsgWindow(cmdwindow, msgwindow, :right) - loop do - Graphics.update - Input.update - pbUpdateSceneMap - cmdwindow.update - msgwindow.update if msgwindow - yield if block_given? - if Input.trigger?(Input::USE) - ret = cmdwindow.number - if ret > maximum - pbPlayBuzzerSE() - elsif ret < minimum - pbPlayBuzzerSE() - else - pbPlayDecisionSE() - break - end - elsif Input.trigger?(Input::BACK) - pbPlayCancelSE() - ret = cancelNumber - break - end - end - cmdwindow.dispose - Input.update - return ret -end - -#=============================================================================== -# -#=============================================================================== -class FaceWindowVX < SpriteWindow_Base - def initialize(face) - super(0, 0, 128, 128) - faceinfo = face.split(",") - facefile = pbResolveBitmap("Graphics/Faces/" + faceinfo[0]) - facefile = pbResolveBitmap("Graphics/Pictures/" + faceinfo[0]) if !facefile - self.contents.dispose if self.contents - @faceIndex = faceinfo[1].to_i - @facebitmaptmp = AnimatedBitmap.new(facefile) - @facebitmap = BitmapWrapper.new(96, 96) - @facebitmap.blt(0, 0, @facebitmaptmp.bitmap, Rect.new( - (@faceIndex % 4) * 96, - (@faceIndex / 4) * 96, 96, 96 - )) - self.contents = @facebitmap - end - - def update - super - if @facebitmaptmp.totalFrames > 1 - @facebitmaptmp.update - @facebitmap.blt(0, 0, @facebitmaptmp.bitmap, Rect.new( - (@faceIndex % 4) * 96, - (@faceIndex / 4) * 96, 96, 96 - )) - end - end - - def dispose - @facebitmaptmp.dispose - @facebitmap.dispose if @facebitmap - super - end -end - -#=============================================================================== -# -#=============================================================================== -def pbGetBasicMapNameFromId(id) - begin - map = pbLoadMapInfos - return "" if !map - return map[id].name - rescue - return "" - end -end - -def pbGetMapNameFromId(id) - map = pbGetBasicMapNameFromId(id) - map.gsub!(/\\PN/, $Trainer.name) if $Trainer - return map -end - -def pbCsvField!(str) - ret = "" - str.sub!(/\A\s*/, "") - if str[0, 1] == "\"" - str[0, 1] = "" - escaped = false - fieldbytes = 0 - str.scan(/./) do |s| - fieldbytes += s.length - break if s == "\"" && !escaped - if s == "\\" && !escaped - escaped = true - else - ret += s - escaped = false - end - end - str[0, fieldbytes] = "" - if !str[/\A\s*,/] && !str[/\A\s*$/] - raise _INTL("Invalid quoted field (in: {1})", ret) - end - str[0, str.length] = $~.post_match - else - if str[/,/] - str[0, str.length] = $~.post_match - ret = $~.pre_match - else - ret = str.clone - str[0, str.length] = "" - end - ret.gsub!(/\s+$/, "") - end - return ret -end - -def pbCsvPosInt!(str) - ret = pbCsvField!(str) - if !ret[/\A\d+$/] - raise _INTL("Field {1} is not a positive integer", ret) - end - return ret.to_i -end - -#=============================================================================== -# Money and coins windows -#=============================================================================== -def pbGetGoldString - moneyString = "" - begin - moneyString = _INTL("${1}", $Trainer.money.to_s_formatted) - rescue - if $data_system.respond_to?("words") - moneyString = _INTL("{1} {2}", $game_party.gold, $data_system.words.gold) - else - moneyString = _INTL("{1} {2}", $game_party.gold, Vocab.gold) - end - end - return moneyString -end - -def pbDisplayGoldWindow(msgwindow) - moneyString = pbGetGoldString() - goldwindow = Window_AdvancedTextPokemon.new(_INTL("Money:\n{1}", moneyString)) - goldwindow.setSkin("Graphics/Windowskins/goldskin") - goldwindow.resizeToFit(goldwindow.text, Graphics.width) - goldwindow.width = 160 if goldwindow.width <= 160 - if msgwindow.y <= 10 - goldwindow.y = Graphics.height - goldwindow.height - else - goldwindow.y = 0 - end - goldwindow.viewport = msgwindow.viewport - goldwindow.z = msgwindow.z - return goldwindow -end - -def pbDisplayBattleFactoryPointsWindow(msgwindow) - pbDisplayVariableWindow(msgwindow, "Tokens", VAR_BATTLE_FACTORY_TOKENS) -end - -def pbDisplayVariableWindow(msgwindow, name, variable_id) - pointsString = $game_variables[variable_id].to_s - pointswindow = Window_AdvancedTextPokemon.new(_INTL("{1}:\n{2}", name, pointsString)) - pointswindow.setSkin("Graphics/Windowskins/goldskin") - pointswindow.resizeToFit(pointswindow.text, Graphics.width) - pointswindow.width = 160 if pointswindow.width <= 160 - if msgwindow.y == 0 - pointswindow.y = Graphics.height - pointswindow.height - else - pointswindow.y = 0 - end - pointswindow.viewport = msgwindow.viewport - pointswindow.z = msgwindow.z - return pointswindow -end - -def pbDisplayTwoVariableWindow(msgwindow, name1, variable1_id, name2, variable2_id) - pointsString1 = $game_variables[variable1_id].to_s - pointsString2 = $game_variables[variable2_id].to_s - - pointswindow = Window_AdvancedTextPokemon.new(_INTL("{1}:{2}\n{3}:{4}", name1, pointsString1, name2, pointsString2)) - pointswindow.setSkin("Graphics/Windowskins/goldskin") - pointswindow.resizeToFit(pointswindow.text, Graphics.width) - pointswindow.width = 160 if pointswindow.width <= 160 - if msgwindow.y == 0 - pointswindow.y = Graphics.height - pointswindow.height - else - pointswindow.y = 0 - end - pointswindow.viewport = msgwindow.viewport - pointswindow.z = msgwindow.z - return pointswindow -end - -def pbDisplayHeartScalesWindow(msgwindow) - pointsString = $PokemonBag.pbQuantity(:HEARTSCALE).to_s - pointswindow = Window_AdvancedTextPokemon.new(_INTL("Heart Scales:\n{1}", pointsString)) - pointswindow.setSkin("Graphics/Windowskins/goldskin") - pointswindow.resizeToFit(pointswindow.text, Graphics.width) - pointswindow.width = 160 if pointswindow.width <= 160 - if msgwindow.y == 0 - pointswindow.y = Graphics.height - pointswindow.height - else - pointswindow.y = 0 - end - pointswindow.viewport = msgwindow.viewport - pointswindow.z = msgwindow.z - return pointswindow -end - -def pbDisplayCoinsWindow(msgwindow, goldwindow) - coinString = ($Trainer) ? $Trainer.coins.to_s_formatted : "0" - coinwindow = Window_AdvancedTextPokemon.new(_INTL("Coins:\n{1}", coinString)) - coinwindow.setSkin("Graphics/Windowskins/goldskin") - coinwindow.resizeToFit(coinwindow.text, Graphics.width) - coinwindow.width = 160 if coinwindow.width <= 160 - if msgwindow.y == 0 - coinwindow.y = (goldwindow) ? goldwindow.y - coinwindow.height : Graphics.height - coinwindow.height - else - coinwindow.y = (goldwindow) ? goldwindow.height : 0 - end - coinwindow.viewport = msgwindow.viewport - coinwindow.z = msgwindow.z - return coinwindow -end - -def pbDisplayBattlePointsWindow(msgwindow) - pointsString = ($Trainer) ? $Trainer.battle_points.to_s_formatted : "0" - pointswindow = Window_AdvancedTextPokemon.new(_INTL("Battle Points:\n{1}", pointsString)) - pointswindow.setSkin("Graphics/Windowskins/goldskin") - pointswindow.resizeToFit(pointswindow.text, Graphics.width) - pointswindow.width = 160 if pointswindow.width <= 160 - if msgwindow.y == 0 - pointswindow.y = Graphics.height - pointswindow.height - else - pointswindow.y = 0 - end - pointswindow.viewport = msgwindow.viewport - pointswindow.z = msgwindow.z - return pointswindow -end - -#=============================================================================== -# -#=============================================================================== -def pbCreateStatusWindow(viewport = nil) - msgwindow = Window_AdvancedTextPokemon.new("") - if !viewport - msgwindow.z = 99999 - else - msgwindow.viewport = viewport - end - msgwindow.visible = false - msgwindow.letterbyletter = false - pbBottomLeftLines(msgwindow, 2) - skinfile = MessageConfig.pbGetSpeechFrame() - msgwindow.setSkin(skinfile) - return msgwindow -end - -def pbCreateMessageWindow(viewport = nil, skin = nil) - msgwindow = Window_AdvancedTextPokemon.new("") - if !viewport - msgwindow.z = 99999 - else - msgwindow.viewport = viewport - end - msgwindow.visible = true - msgwindow.letterbyletter = true - msgwindow.back_opacity = MessageConfig::WINDOW_OPACITY - pbBottomLeftLines(msgwindow, 2) - $game_temp.message_window_showing = true if $game_temp - skin = MessageConfig.pbGetSpeechFrame() if !skin - msgwindow.setSkin(skin) - return msgwindow -end - -def pbDisposeMessageWindow(msgwindow) - $game_temp.message_window_showing = false if $game_temp - msgwindow.dispose -end - -#=============================================================================== -# Main message-displaying function -#=============================================================================== -def pbMessageDisplayNoSound(msgwindow, message, letterbyletter = true, commandProc = nil) - pbMessageDisplay(msgwindow, message, letterbyletter, commandProc, false) -end - -def pbMessageDisplay(msgwindow, message, letterbyletter = true, commandProc = nil, withSound = true) - return if !msgwindow - oldletterbyletter = msgwindow.letterbyletter - msgwindow.letterbyletter = (letterbyletter) ? true : false - ret = nil - commands = nil - facewindow = nil - goldwindow = nil - coinwindow = nil - battlepointswindow = nil - cmdvariable = 0 - cmdIfCancel = 0 - msgwindow.waitcount = 0 - autoresume = false - text = message.clone - msgback = nil - linecount = (Graphics.height > 400) ? 3 : 2 - ### Text replacement - text.gsub!(/\\sign\[([^\]]*)\]/i) { # \sign[something] gets turned into - next "\\op\\cl\\ts[]\\w[" + $1 + "]" # \op\cl\ts[]\w[something] - } - text.gsub!(/\\\\/, "\5") - text.gsub!(/\\1/, "\1") - if $game_actors - text.gsub!(/\\n\[([1-8])\]/i) { - m = $1.to_i - next $game_actors[m].name - } - end - text.gsub!(/\\pn/i, $Trainer.name) if $Trainer - text.gsub!(/\\pm/i, _INTL("${1}", $Trainer.money.to_s_formatted)) if $Trainer - text.gsub!(/\\n/i, "\n") - text.gsub!(/\\\[([0-9a-f]{8,8})\]/i) { "" } - text.gsub!(/\\pg/i, "\\b") if $Trainer && $Trainer.male? - text.gsub!(/\\pg/i, "\\r") if $Trainer && $Trainer.female? - text.gsub!(/\\pog/i, "\\r") if $Trainer && $Trainer.male? - text.gsub!(/\\pog/i, "\\b") if $Trainer && $Trainer.female? - text.gsub!(/\\pg/i, "") - text.gsub!(/\\pog/i, "") - text.gsub!(/\\b/i, "") - text.gsub!(/\\r/i, "") - text.gsub!(/\\[Ww]\[([^\]]*)\]/) { - w = $1.to_s - if w == "" - msgwindow.windowskin = nil - else - msgwindow.setSkin("Graphics/Windowskins/#{w}", false) - end - next "" - } - isDarkSkin = isDarkWindowskin(msgwindow.windowskin) - text.gsub!(/\\[Cc]\[([0-9]+)\]/) { - m = $1.to_i - next getSkinColor(msgwindow.windowskin, m, isDarkSkin) - } - loop do - last_text = text.clone - text.gsub!(/\\v\[([0-9]+)\]/i) { $game_variables[$1.to_i] } - break if text == last_text - end - loop do - last_text = text.clone - text.gsub!(/\\l\[([0-9]+)\]/i) { - linecount = [1, $1.to_i].max - next "" - } - break if text == last_text - end - colortag = "" - if $game_system && $game_system.respond_to?("message_frame") && - $game_system.message_frame != 0 - colortag = getSkinColor(msgwindow.windowskin, 0, true) - else - colortag = getSkinColor(msgwindow.windowskin, 0, isDarkSkin) - end - text = colortag + text - ### Controls - textchunks = [] - controls = [] - while text[/(?:\\(f|ff|ts|cl|me|se|wt|wtnp|ch)\[([^\]]*)\]|\\(g|cn|pt|ft|hs|wd|wm|op|cl|wu|\.|\||\!|\^))/i] - textchunks.push($~.pre_match) - if $~[1] - controls.push([$~[1].downcase, $~[2], -1]) - else - controls.push([$~[3].downcase, "", -1]) - end - text = $~.post_match - end - textchunks.push(text) - for chunk in textchunks - chunk.gsub!(/\005/, "\\") - end - textlen = 0 - for i in 0...controls.length - control = controls[i][0] - case control - when "wt", "wtnp", ".", "|" - textchunks[i] += "\2" - when "!" - textchunks[i] += "\1" - end - textlen += toUnformattedText(textchunks[i]).scan(/./m).length - controls[i][2] = textlen - end - text = textchunks.join("") - signWaitCount = 0 - signWaitTime = Graphics.frame_rate / 2 - haveSpecialClose = false - specialCloseSE = "" - for i in 0...controls.length - control = controls[i][0] - param = controls[i][1] - case control - when "op" - signWaitCount = signWaitTime + 1 - when "cl" - text = text.sub(/\001\z/, "") # fix: '$' can match end of line as well - haveSpecialClose = true - specialCloseSE = param - when "f" - facewindow.dispose if facewindow - facewindow = PictureWindow.new("Graphics/Pictures/#{param}") - when "ff" - facewindow.dispose if facewindow - facewindow = FaceWindowVX.new(param) - when "ch" - cmds = param.clone - cmdvariable = pbCsvPosInt!(cmds) - cmdIfCancel = pbCsvField!(cmds).to_i - commands = [] - while cmds.length > 0 - commands.push(pbCsvField!(cmds)) - end - when "wtnp", "^" - text = text.sub(/\001\z/, "") # fix: '$' can match end of line as well - when "se" - if controls[i][2] == 0 - startSE = param - controls[i] = nil - end - end - end - if withSound - if startSE != nil - pbSEPlay(pbStringToAudioFile(startSE)) - elsif signWaitCount == 0 && letterbyletter - pbPlayDecisionSE() - end - end - ########## Position message window ############## - pbRepositionMessageWindow(msgwindow, linecount) - if facewindow - pbPositionNearMsgWindow(facewindow, msgwindow, :left) - facewindow.viewport = msgwindow.viewport - facewindow.z = msgwindow.z - end - atTop = (msgwindow.y == 0) - ########## Show text ############################# - msgwindow.text = text - Graphics.frame_reset if Graphics.frame_rate > 40 - loop do - if signWaitCount > 0 - signWaitCount -= 1 - if atTop - msgwindow.y = -msgwindow.height * signWaitCount / signWaitTime - else - msgwindow.y = Graphics.height - msgwindow.height * (signWaitTime - signWaitCount) / signWaitTime - end - end - for i in 0...controls.length - next if !controls[i] - next if controls[i][2] > msgwindow.position || msgwindow.waitcount != 0 - control = controls[i][0] - param = controls[i][1] - case control - when "f" - if param.to_i > 0 - isFusion = param.to_i > NB_POKEMON - head = getBasePokemonID(param.to_i, false) - body = getBasePokemonID(param.to_i, true) - facewindow.dispose if facewindow - #path = obtainPokemonSpritePath(body, head, true) if isFusion - - spriteLoader = BattleSpriteLoader.new - facewindow = isFusion ? PictureWindow.new(spriteLoader.load_fusion_sprite(head,body)) : PictureWindow.new(spriteLoader.load_base_sprite(head)) - pbPositionNearMsgWindow(facewindow, msgwindow, :left) - facewindow.viewport = msgwindow.viewport - facewindow.z = msgwindow.z - end - when "ff" - facewindow.dispose if facewindow - facewindow = FaceWindowVX.new(param) - pbPositionNearMsgWindow(facewindow, msgwindow, :left) - facewindow.viewport = msgwindow.viewport - facewindow.z = msgwindow.z - when "g" # Display gold window - goldwindow.dispose if goldwindow - goldwindow = pbDisplayGoldWindow(msgwindow) - when "ft" # Display battle factory tokens - goldwindow.dispose if goldwindow - goldwindow = pbDisplayBattleFactoryPointsWindow(msgwindow) - when "hs" # Display heartscakes - goldwindow.dispose if goldwindow - goldwindow = pbDisplayHeartScalesWindow(msgwindow) - when "cn" # Display coins window - coinwindow.dispose if coinwindow - coinwindow = pbDisplayCoinsWindow(msgwindow, goldwindow) - when "pt" # Display battle points window - battlepointswindow.dispose if battlepointswindow - battlepointswindow = pbDisplayBattlePointsWindow(msgwindow) - when "wu" - msgwindow.y = 0 - atTop = true - msgback.y = msgwindow.y if msgback - pbPositionNearMsgWindow(facewindow, msgwindow, :left) - msgwindow.y = -msgwindow.height * signWaitCount / signWaitTime - when "wm" - atTop = false - msgwindow.y = (Graphics.height - msgwindow.height) / 2 - msgback.y = msgwindow.y if msgback - pbPositionNearMsgWindow(facewindow, msgwindow, :left) - when "wd" - atTop = false - msgwindow.y = Graphics.height - msgwindow.height - msgback.y = msgwindow.y if msgback - pbPositionNearMsgWindow(facewindow, msgwindow, :left) - msgwindow.y = Graphics.height - msgwindow.height * (signWaitTime - signWaitCount) / signWaitTime - when "ts" # Change text speed - msgwindow.textspeed = (param == "") ? -999 : param.to_i - when "." # Wait 0.25 seconds - msgwindow.waitcount += Graphics.frame_rate / 4 - when "|" # Wait 1 second - msgwindow.waitcount += Graphics.frame_rate - when "wt" # Wait X/20 seconds - param = param.sub(/\A\s+/, "").sub(/\s+\z/, "") - msgwindow.waitcount += param.to_i * Graphics.frame_rate / 20 - when "wtnp" # Wait X/20 seconds, no pause - param = param.sub(/\A\s+/, "").sub(/\s+\z/, "") - msgwindow.waitcount = param.to_i * Graphics.frame_rate / 20 - autoresume = true - when "^" # Wait, no pause - autoresume = true - when "se" # Play SE - pbSEPlay(pbStringToAudioFile(param)) - when "me" # Play ME - pbMEPlay(pbStringToAudioFile(param)) - end - controls[i] = nil - end - break if !letterbyletter - Graphics.update - Input.update - facewindow.update if facewindow - if autoresume && msgwindow.waitcount == 0 - msgwindow.resume if msgwindow.busy? - break if !msgwindow.busy? - end - if Input.trigger?(Input::USE) || Input.trigger?(Input::BACK) - if msgwindow.busy? - pbPlayDecisionSE if msgwindow.pausing? - msgwindow.resume - else - break if signWaitCount == 0 - end - end - pbUpdateSceneMap - msgwindow.update - yield if block_given? - break if (!letterbyletter || commandProc || commands) && !msgwindow.busy? - end - Input.update # Must call Input.update again to avoid extra triggers - msgwindow.letterbyletter = oldletterbyletter - if commands - $game_variables[cmdvariable] = pbShowCommands(msgwindow, commands, cmdIfCancel) - $game_map.need_refresh = true if $game_map - end - if commandProc - ret = commandProc.call(msgwindow) - end - msgback.dispose if msgback - goldwindow.dispose if goldwindow - coinwindow.dispose if coinwindow - battlepointswindow.dispose if battlepointswindow - facewindow.dispose if facewindow - if haveSpecialClose - pbSEPlay(pbStringToAudioFile(specialCloseSE)) - atTop = (msgwindow.y == 0) - for i in 0..signWaitTime - if atTop - msgwindow.y = -msgwindow.height * i / signWaitTime - else - msgwindow.y = Graphics.height - msgwindow.height * (signWaitTime - i) / signWaitTime - end - Graphics.update - Input.update - pbUpdateSceneMap - msgwindow.update - end - end - return ret -end - -#=============================================================================== -# Message-displaying functions -#=============================================================================== -def pbMessage(message, commands = nil, cmdIfCancel = 0, skin = nil, defaultCmd = 0, &block) - ret = 0 - msgwindow = pbCreateMessageWindow(nil, skin) - if commands - ret = pbMessageDisplay(msgwindow, message, true, - proc { |msgwindow| - next Kernel.pbShowCommands(msgwindow, commands, cmdIfCancel, defaultCmd, &block) - }, &block) - else - pbMessageDisplay(msgwindow, message, &block) - end - pbDisposeMessageWindow(msgwindow) - Input.update - return ret -end - -def pbMessageNoSound(message, commands = nil, cmdIfCancel = 0, skin = nil, defaultCmd = 0, &block) - ret = 0 - msgwindow = pbCreateMessageWindow(nil, skin) - if commands - ret = pbMessageDisplayNoSound(msgwindow, message, true, - proc { |msgwindow| - next Kernel.pbShowCommands(msgwindow, commands, cmdIfCancel, defaultCmd, &block) - }, &block) - else - pbMessageDisplay(msgwindow, message, &block) - end - pbDisposeMessageWindow(msgwindow) - Input.update - return ret -end - -def pbConfirmMessage(message, &block) - return (pbMessage(message, [_INTL("Yes"), _INTL("No")], 2, &block) == 0) -end - -def pbConfirmMessageSerious(message, &block) - return (pbMessage(message, [_INTL("No"), _INTL("Yes")], 1, &block) == 1) -end - -def pbMessageChooseNumber(message, params, &block) - msgwindow = pbCreateMessageWindow(nil, params.messageSkin) - ret = pbMessageDisplay(msgwindow, message, true, - proc { |msgwindow| - next pbChooseNumber(msgwindow, params, &block) - }, &block) - pbDisposeMessageWindow(msgwindow) - return ret -end - - -def pbShowCommands(msgwindow, commands = nil, cmdIfCancel = 0, defaultCmd = 0, x_offset=nil, y_offset=nil) - return 0 if !commands - $PokemonTemp.speechbubble_arrow.visible =false if $PokemonTemp.speechbubble_arrow && !$PokemonTemp.speechbubble_arrow.disposed? - if defaultCmd == 0 && ($game_variables && $game_variables[VAR_COMMAND_WINDOW_INDEX] != 0) - defaultCmd = $game_variables[VAR_COMMAND_WINDOW_INDEX] - end - cmdwindow = Window_CommandPokemonEx.new(commands) - cmdwindow.z = 99999 - cmdwindow.visible = true - cmdwindow.resizeToFit(cmdwindow.commands) - pbPositionNearMsgWindow(cmdwindow, msgwindow, :right, x_offset, y_offset) - cmdwindow.index = defaultCmd - command = 0 - loop do - Graphics.update - Input.update - cmdwindow.update - msgwindow.update if msgwindow - yield if block_given? - if Input.trigger?(Input::BACK) - if cmdIfCancel > 0 - command = cmdIfCancel - 1 - break - elsif cmdIfCancel < 0 - command = cmdIfCancel - break - end - end - if Input.trigger?(Input::USE) - command = cmdwindow.index - break - end - pbUpdateSceneMap - end - ret = command - cmdwindow.dispose - Input.update - return ret -end - -def pbShowCommandsWithHelp(msgwindow, commands, help, cmdIfCancel = 0, defaultCmd = 0) - msgwin = msgwindow - msgwin = pbCreateMessageWindow(nil) if !msgwindow - oldlbl = msgwin.letterbyletter - msgwin.letterbyletter = false - if commands - cmdwindow = Window_CommandPokemonEx.new(commands) - cmdwindow.z = 99999 - cmdwindow.visible = true - cmdwindow.resizeToFit(cmdwindow.commands) - cmdwindow.height = msgwin.y if cmdwindow.height > msgwin.y - cmdwindow.index = defaultCmd - command = 0 - msgwin.text = help[cmdwindow.index] - msgwin.width = msgwin.width # Necessary evil to make it use the proper margins - loop do - Graphics.update - Input.update - oldindex = cmdwindow.index - cmdwindow.update - if oldindex != cmdwindow.index - msgwin.text = help[cmdwindow.index] - end - msgwin.update - yield if block_given? - if Input.trigger?(Input::BACK) - if cmdIfCancel > 0 - command = cmdIfCancel - 1 - break - elsif cmdIfCancel < 0 - command = cmdIfCancel - break - end - end - if Input.trigger?(Input::USE) - command = cmdwindow.index - break - end - pbUpdateSceneMap - end - ret = command - cmdwindow.dispose - Input.update - end - msgwin.letterbyletter = oldlbl - msgwin.dispose if !msgwindow - return ret -end - -# frames is the number of 1/20 seconds to wait for -def pbMessageWaitForInput(msgwindow, frames, showPause = false) - return if !frames || frames <= 0 - msgwindow.startPause if msgwindow && showPause - frames = frames * Graphics.frame_rate / 20 - frames.times do - Graphics.update - Input.update - msgwindow.update if msgwindow - pbUpdateSceneMap - if Input.trigger?(Input::USE) || Input.trigger?(Input::BACK) - break - end - yield if block_given? - end - msgwindow.stopPause if msgwindow && showPause -end - -def pbFreeText(msgwindow, currenttext, passwordbox, maxlength, width = 240) - window = Window_TextEntry_Keyboard.new(currenttext, 0, 0, width, 64) - ret = "" - window.maxlength = maxlength - window.visible = true - window.z = 99999 - pbPositionNearMsgWindow(window, msgwindow, :right) - window.text = currenttext - window.passwordChar = "*" if passwordbox - Input.text_input = true - loop do - Graphics.update - Input.update - if Input.triggerex?(:ESCAPE) - ret = currenttext - break - elsif Input.triggerex?(:RETURN) - ret = window.text - break - end - window.update - msgwindow.update if msgwindow - yield if block_given? - end - Input.text_input = false - window.dispose - Input.update - return ret -end - -def pbMessageFreeText(message, currenttext, passwordbox, maxlength, width = 240, &block) - msgwindow = pbCreateMessageWindow - retval = pbMessageDisplay(msgwindow, message, true, - proc { |msgwindow| - next pbFreeText(msgwindow, currenttext, passwordbox, maxlength, width, &block) - }, &block) - pbDisposeMessageWindow(msgwindow) - return retval -end diff --git a/Data/Scripts/007_Objects and windows/012_TextEntry.rb b/Data/Scripts/007_Objects and windows/012_TextEntry.rb deleted file mode 100644 index 2e5d201a9..000000000 --- a/Data/Scripts/007_Objects and windows/012_TextEntry.rb +++ /dev/null @@ -1,564 +0,0 @@ -#=============================================================================== -# -#=============================================================================== -class CharacterEntryHelper - attr_reader :text - attr_accessor :maxlength - attr_reader :passwordChar - attr_accessor :cursor - - def initialize(text) - @maxlength=-1 - @text=text - @passwordChar="" - @cursor=text.scan(/./m).length - end - - def text=(value) - @text=value - end - - def textChars - chars=text.scan(/./m) - if @passwordChar!="" - chars.length.times { |i| chars[i] = @passwordChar } - end - return chars - end - - def passwordChar=(value) - @passwordChar=value ? value : "" - end - - def length - return self.text.scan(/./m).length - end - - def canInsert? - chars=self.text.scan(/./m) - return false if @maxlength>=0 && chars.length>=@maxlength - return true - end - - def insert(ch) - chars=self.text.scan(/./m) - return false if @maxlength>=0 && chars.length>=@maxlength - chars.insert(@cursor,ch) - @text="" - for ch in chars - @text+=ch if ch - end - @cursor+=1 - return true - end - - def canDelete? - chars=self.text.scan(/./m) - return false if chars.length<=0 || @cursor<=0 - return true - end - - def delete - chars=self.text.scan(/./m) - return false if chars.length<=0 || @cursor<=0 - chars.delete_at(@cursor-1) - @text="" - for ch in chars - @text+=ch if ch - end - @cursor-=1 - return true - end - - private - - def ensure - return if @maxlength<0 - chars=self.text.scan(/./m) - if chars.length>@maxlength && @maxlength>=0 - chars=chars[0,@maxlength] - end - @text="" - for ch in chars - @text+=ch if ch - end - end -end - - - -#=============================================================================== -# -#=============================================================================== -class Window_TextEntry < SpriteWindow_Base - def initialize(text,x,y,width,height,heading=nil,usedarkercolor=false) - super(x,y,width,height) - colors=getDefaultTextColors(self.windowskin) - @baseColor=colors[0] - @shadowColor=colors[1] - if usedarkercolor - @baseColor=Color.new(16,24,32) - @shadowColor=Color.new(168,184,184) - end - @helper=CharacterEntryHelper.new(text) - @heading=heading - self.active=true - @frame=0 - refresh - end - - def text - @helper.text - end - - def maxlength - @helper.maxlength - end - - def passwordChar - @helper.passwordChar - end - - def text=(value) - @helper.text=value - self.refresh - end - - def passwordChar=(value) - @helper.passwordChar=value - refresh - end - - def maxlength=(value) - @helper.maxlength=value - self.refresh - end - - def insert(ch) - if @helper.insert(ch) - @frame=0 - self.refresh - return true - end - return false - end - - def delete - if @helper.delete - @frame=0 - self.refresh - return true - end - return false - end - - def update - @frame += 1 - @frame %= 20 - self.refresh if (@frame%10)==0 - return if !self.active - # Moving cursor - if Input.repeat?(Input::LEFT) && Input.press?(Input::ACTION) - if @helper.cursor > 0 - @helper.cursor -= 1 - @frame = 0 - self.refresh - end - elsif Input.repeat?(Input::RIGHT) && Input.press?(Input::ACTION) - if @helper.cursor < self.text.scan(/./m).length - @helper.cursor += 1 - @frame = 0 - self.refresh - end - elsif Input.repeat?(Input::BACK) # Backspace - self.delete if @helper.cursor > 0 - end - end - - def refresh - self.contents=pbDoEnsureBitmap(self.contents,self.width-self.borderX, - self.height-self.borderY) - bitmap=self.contents - bitmap.clear - x=0 - y=0 - if @heading - textwidth=bitmap.text_size(@heading).width - pbDrawShadowText(bitmap,x,y, textwidth+4, 32, @heading,@baseColor,@shadowColor) - y+=32 - end - x+=4 - width=self.width-self.borderX - cursorcolor=Color.new(16,24,32) - textscan=self.text.scan(/./m) - scanlength=textscan.length - @helper.cursor=scanlength if @helper.cursor>scanlength - @helper.cursor=0 if @helper.cursor<0 - startpos=@helper.cursor - fromcursor=0 - while (startpos>0) - c=(@helper.passwordChar!="") ? @helper.passwordChar : textscan[startpos-1] - fromcursor+=bitmap.text_size(c).width - break if fromcursor>width-4 - startpos-=1 - end - for i in startpos...scanlength - c=(@helper.passwordChar!="") ? @helper.passwordChar : textscan[i] - textwidth=bitmap.text_size(c).width - next if c=="\n" - # Draw text - pbDrawShadowText(bitmap,x,y, textwidth+4, 32, c,@baseColor,@shadowColor) - # Draw cursor if necessary - if ((@frame/10)&1) == 0 && i==@helper.cursor - bitmap.fill_rect(x,y+4,2,24,cursorcolor) - end - # Add x to drawn text width - x += textwidth - end - if ((@frame/10)&1) == 0 && textscan.length==@helper.cursor - bitmap.fill_rect(x,y+4,2,24,cursorcolor) - end - end -end - - - -#=============================================================================== -# -#=============================================================================== -class Window_TextEntry_Keyboard < Window_TextEntry - def update - @frame+=1 - @frame%=20 - self.refresh if ((@frame%10)==0) - return if !self.active - # Moving cursor - if Input.triggerex?(:LEFT) || Input.repeatex?(:LEFT) - if @helper.cursor > 0 - @helper.cursor-=1 - @frame=0 - self.refresh - end - return - elsif Input.triggerex?(:RIGHT) || Input.repeatex?(:RIGHT) - if @helper.cursor < self.text.scan(/./m).length - @helper.cursor+=1 - @frame=0 - self.refresh - end - return - elsif Input.triggerex?(:BACKSPACE) || Input.repeatex?(:BACKSPACE) - self.delete if @helper.cursor>0 - return - elsif Input.triggerex?(:RETURN) || Input.triggerex?(:ESCAPE) - return - end - Input.gets.each_char { |c| insert(c) } - end -end - - - -#=============================================================================== -# -#=============================================================================== -class Window_MultilineTextEntry < SpriteWindow_Base - def initialize(text,x,y,width,height) - super(x,y,width,height) - colors=getDefaultTextColors(self.windowskin) - @baseColor=colors[0] - @shadowColor=colors[1] - @helper=CharacterEntryHelper.new(text) - @firstline=0 - @cursorLine=0 - @cursorColumn=0 - @frame=0 - self.active=true - refresh - end - - attr_reader :baseColor - attr_reader :shadowColor - - def baseColor=(value) - @baseColor=value - refresh - end - - def shadowColor=(value) - @shadowColor=value - refresh - end - - def text - @helper.text - end - - def maxlength - @helper.maxlength - end - - def text=(value) - @helper.text=value - @textchars=nil - self.refresh - end - - def maxlength=(value) - @helper.maxlength=value - @textchars=nil - self.refresh - end - - def insert(ch) - @helper.cursor=getPosFromLineAndColumn(@cursorLine,@cursorColumn) - if @helper.insert(ch) - @frame=0 - @textchars=nil - moveCursor(0,1) - self.refresh - return true - end - return false - end - - def delete - @helper.cursor=getPosFromLineAndColumn(@cursorLine,@cursorColumn) - if @helper.delete - @frame=0 - moveCursor(0,-1) # use old textchars - @textchars=nil - self.refresh - return true - end - return false - end - - def getTextChars - if !@textchars - @textchars=getLineBrokenText(self.contents,@helper.text, - self.contents.width,nil) - end - return @textchars - end - - def getTotalLines - textchars=getTextChars - return 1 if textchars.length==0 - tchar=textchars[textchars.length-1] - return tchar[5]+1 - end - - def getLineY(line) - textchars=getTextChars - return 0 if textchars.length==0 - totallines=getTotalLines() - line=0 if line<0 - line=totallines-1 if line>=totallines - maximumY=0 - for i in 0...textchars.length - thisline=textchars[i][5] - y=textchars[i][2] - return y if thisline==line - maximumY=y if maximumY=totallines - endpos=0 - for i in 0...textchars.length - thisline=textchars[i][5] - thislength=textchars[i][8] - endpos+=thislength if thisline==line - end - return endpos - end - - def getPosFromLineAndColumn(line,column) - textchars=getTextChars - return 0 if textchars.length==0 - totallines=getTotalLines() - line=0 if line<0 - line=totallines-1 if line>=totallines - endpos=0 - for i in 0...textchars.length - thisline=textchars[i][5] - thispos=textchars[i][6] - thiscolumn=textchars[i][7] - thislength=textchars[i][8] - if thisline==line - endpos=thispos+thislength -# echoln [endpos,thispos+(column-thiscolumn),textchars[i]] - if column>=thiscolumn && column<=thiscolumn+thislength && thislength>0 - return thispos+(column-thiscolumn) - end - end - end -# if endpos==0 -# echoln [totallines,line,column] -# echoln textchars -# end -# echoln "endpos=#{endpos}" - return endpos - end - - def getLastVisibleLine - getTextChars() - textheight=[1,self.contents.text_size("X").height].max - lastVisible=@firstline+((self.height-self.borderY)/textheight)-1 - return lastVisible - end - - def updateCursorPos(doRefresh) - # Calculate new cursor position - @helper.cursor=getPosFromLineAndColumn(@cursorLine,@cursorColumn) - if doRefresh - @frame=0 - self.refresh - end - @firstline=@cursorLine if @cursorLine<@firstline - lastVisible=getLastVisibleLine() - @firstline+=(@cursorLine-lastVisible) if @cursorLine>lastVisible - end - - def moveCursor(lineOffset, columnOffset) - # Move column offset first, then lines (since column offset - # can affect line offset) -# echoln ["beforemoving",@cursorLine,@cursorColumn] - totalColumns=getColumnsInLine(@cursorLine) # check current line - totalLines=getTotalLines() - oldCursorLine=@cursorLine - oldCursorColumn=@cursorColumn - @cursorColumn+=columnOffset - if @cursorColumn<0 && @cursorLine>0 - # Will happen if cursor is moved left from the beginning of a line - @cursorLine-=1 - @cursorColumn=getColumnsInLine(@cursorLine) - elsif @cursorColumn>totalColumns && @cursorLinetotalColumns - @cursorColumn=0 if @cursorColumn<0 # totalColumns can be 0 - # Move line offset - @cursorLine+=lineOffset - @cursorLine=0 if @cursorLine<0 - @cursorLine=totalLines-1 if @cursorLine>=totalLines - # Ensure column bounds again - totalColumns=getColumnsInLine(@cursorLine) - @cursorColumn=totalColumns if @cursorColumn>totalColumns - @cursorColumn=0 if @cursorColumn<0 # totalColumns can be 0 - updateCursorPos( - oldCursorLine!=@cursorLine || - oldCursorColumn!=@cursorColumn - ) -# echoln ["aftermoving",@cursorLine,@cursorColumn] - end - - def update - @frame+=1 - @frame%=20 - self.refresh if ((@frame%10)==0) - return if !self.active - # Moving cursor - if Input.triggerex?(:UP) || Input.repeatex?(:UP) - moveCursor(-1,0) - return - elsif Input.triggerex?(:DOWN) || Input.repeatex?(:DOWN) - moveCursor(1,0) - return - elsif Input.triggerex?(:LEFT) || Input.repeatex?(:LEFT) - moveCursor(0,-1) - return - elsif Input.triggerex?(:RIGHT) || Input.repeatex?(:RIGHT) - moveCursor(0,1) - return - end - if Input.press?(Input::CTRL) && Input.triggerex?(:HOME) - # Move cursor to beginning - @cursorLine=0 - @cursorColumn=0 - updateCursorPos(true) - return - elsif Input.press?(Input::CTRL) && Input.triggerex?(:END) - # Move cursor to end - @cursorLine=getTotalLines()-1 - @cursorColumn=getColumnsInLine(@cursorLine) - updateCursorPos(true) - return - elsif Input.triggerex?(:RETURN) || Input.repeatex?(:RETURN) - self.insert("\n") - return - elsif Input.triggerex?(:BACKSPACE) || Input.repeatex?(:BACKSPACE) # Backspace - self.delete - return - end - Input.gets.each_char{|c|insert(c)} - end - - def refresh - newContents=pbDoEnsureBitmap(self.contents,self.width-self.borderX, - self.height-self.borderY) - @textchars=nil if self.contents!=newContents - self.contents=newContents - bitmap=self.contents - bitmap.clear - getTextChars - height=self.height-self.borderY - cursorcolor=Color.new(0,0,0) - textchars=getTextChars() - startY=getLineY(@firstline) - for i in 0...textchars.length - thisline=textchars[i][5] - thiscolumn=textchars[i][7] - thislength=textchars[i][8] - textY=textchars[i][2]-startY - # Don't draw lines before the first or zero-length segments - next if thisline<@firstline || thislength==0 - # Don't draw lines beyond the window's height - break if textY >= height - c=textchars[i][0] - # Don't draw spaces - next if c==" " - textwidth=textchars[i][3]+4 # add 4 to prevent draw_text from stretching text - textheight=textchars[i][4] - # Draw text - pbDrawShadowText(bitmap, textchars[i][1], textY, textwidth, textheight, c, @baseColor, @shadowColor) - end - # Draw cursor - if ((@frame/10)&1) == 0 - textheight=bitmap.text_size("X").height - cursorY=(textheight*@cursorLine)-startY - cursorX=0 - for i in 0...textchars.length - thisline=textchars[i][5] - thiscolumn=textchars[i][7] - thislength=textchars[i][8] - if thisline==@cursorLine && @cursorColumn>=thiscolumn && - @cursorColumn<=thiscolumn+thislength - cursorY=textchars[i][2]-startY - cursorX=textchars[i][1] - textheight=textchars[i][4] - posToCursor=@cursorColumn-thiscolumn - if posToCursor>=0 - partialString=textchars[i][0].scan(/./m)[0,posToCursor].join("") - cursorX+=bitmap.text_size(partialString).width - end - break - end - end - cursorY+=4 - cursorHeight=[4,textheight-4,bitmap.text_size("X").height-4].max - bitmap.fill_rect(cursorX,cursorY,2,cursorHeight,cursorcolor) - end - end -end diff --git a/Data/Scripts/008_Audio/001_Audio.rb b/Data/Scripts/008_Audio/001_Audio.rb deleted file mode 100644 index c0ebc8301..000000000 --- a/Data/Scripts/008_Audio/001_Audio.rb +++ /dev/null @@ -1,171 +0,0 @@ -##################################### -# Needed because RGSS doesn't call at_exit procs on exit -# Exit is not called when game is reset (using F12) -$AtExitProcs=[] if !$AtExitProcs - -def exit(code=0) - for p in $AtExitProcs - p.call - end - raise SystemExit.new(code) -end - -def at_exit(&block) - $AtExitProcs.push(Proc.new(&block)) -end - -#=============================================================================== -# Methods that determine the duration of an audio file. -#=============================================================================== -def getOggPage(file) - fgetdw = proc { |file| - (file.eof? ? 0 : (file.read(4).unpack("V")[0] || 0)) - } - dw = fgetdw.call(file) - return nil if dw != 0x5367674F - header = file.read(22) - bodysize = 0 - hdrbodysize = (file.read(1)[0].ord rescue 0) - hdrbodysize.times do - bodysize += (file.read(1)[0].ord rescue 0) - end - ret = [header, file.pos, bodysize, file.pos + bodysize] - return ret -end - -# internal function -def oggfiletime(file) - fgetdw = proc { |file| - (file.eof? ? 0 : (file.read(4).unpack("V")[0] || 0)) - } - pages = [] - page = nil - loop do - page = getOggPage(file) - break if !page - pages.push(page) - file.pos = page[3] - end - return -1 if pages.length == 0 - curserial = nil - i = -1 - pcmlengths = [] - rates = [] - for page in pages - header = page[0] - serial = header[10, 4].unpack("V") - frame = header[2, 8].unpack("C*") - frameno = frame[7] - frameno = (frameno << 8) | frame[6] - frameno = (frameno << 8) | frame[5] - frameno = (frameno << 8) | frame[4] - frameno = (frameno << 8) | frame[3] - frameno = (frameno << 8) | frame[2] - frameno = (frameno << 8) | frame[1] - frameno = (frameno << 8) | frame[0] - if serial != curserial - curserial = serial - file.pos = page[1] - packtype = (file.read(1)[0].ord rescue 0) - string = file.read(6) - return -1 if string != "vorbis" - return -1 if packtype != 1 - i += 1 - version = fgetdw.call(file) - return -1 if version != 0 - rates[i] = fgetdw.call(file) - end - pcmlengths[i] = frameno - end - ret = 0.0 - for i in 0...pcmlengths.length - ret += pcmlengths[i].to_f / rates[i].to_f - end - return ret * 256.0 -end - -# Gets the length of an audio file in seconds. Supports WAV, MP3, and OGG files. -def getPlayTime(filename) - if safeExists?(filename) - return [getPlayTime2(filename), 0].max - elsif safeExists?(filename + ".wav") - return [getPlayTime2(filename + ".wav"), 0].max - elsif safeExists?(filename + ".mp3") - return [getPlayTime2(filename + ".mp3"), 0].max - elsif safeExists?(filename + ".ogg") - return [getPlayTime2(filename + ".ogg"), 0].max - end - return 0 -end - -def getPlayTime2(filename) - return -1 if !safeExists?(filename) - time = -1 - fgetdw = proc { |file| - (file.eof? ? 0 : (file.read(4).unpack("V")[0] || 0)) - } - fgetw = proc { |file| - (file.eof? ? 0 : (file.read(2).unpack("v")[0] || 0)) - } - File.open(filename, "rb") { |file| - file.pos = 0 - fdw = fgetdw.call(file) - if fdw == 0x46464952 # "RIFF" - filesize = fgetdw.call(file) - wave = fgetdw.call(file) - return -1 if wave != 0x45564157 # "WAVE" - fmt = fgetdw.call(file) - return -1 if fmt != 0x20746d66 # "fmt " - fmtsize = fgetdw.call(file) - format = fgetw.call(file) - channels = fgetw.call(file) - rate = fgetdw.call(file) - bytessec = fgetdw.call(file) - return -1 if bytessec == 0 - bytessample = fgetw.call(file) - bitssample = fgetw.call(file) - data = fgetdw.call(file) - return -1 if data != 0x61746164 # "data" - datasize = fgetdw.call(file) - time = (datasize*1.0)/bytessec - return time - elsif fdw == 0x5367674F # "OggS" - file.pos = 0 - time = oggfiletime(file) - return time - end - file.pos = 0 - # Find the length of an MP3 file - while true - rstr = "" - ateof = false - while !file.eof? - if (file.read(1)[0] rescue 0) == 0xFF - begin - rstr = file.read(3) - rescue - ateof = true - end - break - end - end - break if ateof || !rstr || rstr.length != 3 - if rstr[0] == 0xFB - t = rstr[1] >> 4 - next if t == 0 || t == 15 - freqs = [44100, 22050, 11025, 48000] - bitrates = [32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320] - bitrate = bitrates[t] - t = (rstr[1] >> 2) & 3 - freq = freqs[t] - t = (rstr[1] >> 1) & 1 - filesize = FileTest.size(filename) - frameLength = ((144000 * bitrate) / freq) + t - numFrames = filesize / (frameLength + 4) - time = (numFrames * 1152.0 / freq) - break - end - end - } - return time -end diff --git a/Data/Scripts/008_Audio/002_Audio_Play.rb b/Data/Scripts/008_Audio/002_Audio_Play.rb deleted file mode 100644 index 7cc37e756..000000000 --- a/Data/Scripts/008_Audio/002_Audio_Play.rb +++ /dev/null @@ -1,293 +0,0 @@ -def pbStringToAudioFile(str) - if str[/^(.*)\:\s*(\d+)\s*\:\s*(\d+)\s*$/] # Of the format "XXX: ###: ###" - file = $1 - volume = $2.to_i - pitch = $3.to_i - return RPG::AudioFile.new(file,volume,pitch) - elsif str[/^(.*)\:\s*(\d+)\s*$/] # Of the format "XXX: ###" - file = $1 - volume = $2.to_i - return RPG::AudioFile.new(file,volume,100) - else - return RPG::AudioFile.new(str,100,100) - end -end - -# Converts an object to an audio file. -# str -- Either a string showing the filename or an RPG::AudioFile object. -# Possible formats for _str_: -# filename volume and pitch 100 -# filename:volume pitch 100 -# filename:volume:pitch -# volume -- Volume of the file, up to 100 -# pitch -- Pitch of the file, normally 100 -def pbResolveAudioFile(str,volume=nil,pitch=nil) - if str.is_a?(String) - str = pbStringToAudioFile(str) - str.volume = volume || 100 - str.pitch = pitch || 100 - end - if str.is_a?(RPG::AudioFile) - if volume || pitch - return RPG::AudioFile.new(str.name,volume || str.volume || 100 , - pitch || str.pitch || 100) - else - return str - end - end - return str -end - -################################################################################ - -# Plays a BGM file. -# param -- Either a string showing the filename -# (relative to Audio/BGM/) or an RPG::AudioFile object. -# Possible formats for _param_: -# filename volume and pitch 100 -# filename:volume pitch 100 -# filename:volume:pitch -# volume -- Volume of the file, up to 100 -# pitch -- Pitch of the file, normally 100 -def pbBGMPlay(param,volume=nil,pitch=nil) - return if !param - param=pbResolveAudioFile(param,volume,pitch) - param = pbResolveAudioFile("ultra_metropolis", volume, pitch) if darknessEffectOnCurrentMap() && !$PokemonTemp.during_battle - if param.name && param.name!="" - if $game_system && $game_system.respond_to?("bgm_play") - $game_system.bgm_play(param) - return - elsif (RPG.const_defined?(:BGM) rescue false) - b=RPG::BGM.new(param.name,param.volume,param.pitch) - if b && b.respond_to?("play") - b.play - return - end - end - Audio.bgm_play(canonicalize("Audio/BGM/"+param.name),param.volume,param.pitch) - end -end - -# Fades out or stops BGM playback. 'x' is the time in seconds to fade out. -def pbBGMFade(x=0.0); pbBGMStop(x);end - -# Fades out or stops BGM playback. 'x' is the time in seconds to fade out. -def pbBGMStop(timeInSeconds=0.0) - if $game_system && timeInSeconds>0.0 && $game_system.respond_to?("bgm_fade") - $game_system.bgm_fade(timeInSeconds) - return - elsif $game_system && $game_system.respond_to?("bgm_stop") - $game_system.bgm_stop - return - elsif (RPG.const_defined?(:BGM) rescue false) - begin - (timeInSeconds>0.0) ? RPG::BGM.fade((timeInSeconds*1000).floor) : RPG::BGM.stop - return - rescue - end - end - (timeInSeconds>0.0) ? Audio.bgm_fade((timeInSeconds*1000).floor) : Audio.bgm_stop -end - -################################################################################ - -# Plays an ME file. -# param -- Either a string showing the filename -# (relative to Audio/ME/) or an RPG::AudioFile object. -# Possible formats for _param_: -# filename volume and pitch 100 -# filename:volume pitch 100 -# filename:volume:pitch -# volume -- Volume of the file, up to 100 -# pitch -- Pitch of the file, normally 100 -def pbMEPlay(param,volume=nil,pitch=nil) - return if !param - param=pbResolveAudioFile(param,volume,pitch) - if param.name && param.name!="" - if $game_system && $game_system.respond_to?("me_play") - $game_system.me_play(param) - return - elsif (RPG.const_defined?(:ME) rescue false) - b=RPG::ME.new(param.name,param.volume,param.pitch) - if b && b.respond_to?("play") - b.play; return - end - end - Audio.me_play(canonicalize("Audio/ME/"+param.name),param.volume,param.pitch) - end -end - -# Fades out or stops ME playback. 'x' is the time in seconds to fade out. -def pbMEFade(x=0.0); pbMEStop(x);end - -# Fades out or stops ME playback. 'x' is the time in seconds to fade out. -def pbMEStop(timeInSeconds=0.0) - if $game_system && timeInSeconds>0.0 && $game_system.respond_to?("me_fade") - $game_system.me_fade(timeInSeconds) - return - elsif $game_system && $game_system.respond_to?("me_stop") - $game_system.me_stop(nil) - return - elsif (RPG.const_defined?(:ME) rescue false) - begin - (timeInSeconds>0.0) ? RPG::ME.fade((timeInSeconds*1000).floor) : RPG::ME.stop - return - rescue - end - end - (timeInSeconds>0.0) ? Audio.me_fade((timeInSeconds*1000).floor) : Audio.me_stop -end - -################################################################################ - -# Plays a BGS file. -# param -- Either a string showing the filename -# (relative to Audio/BGS/) or an RPG::AudioFile object. -# Possible formats for _param_: -# filename volume and pitch 100 -# filename:volume pitch 100 -# filename:volume:pitch -# volume -- Volume of the file, up to 100 -# pitch -- Pitch of the file, normally 100 -def pbBGSPlay(param,volume=nil,pitch=nil) - return if !param - param=pbResolveAudioFile(param,volume,pitch) - if param.name && param.name!="" - if $game_system && $game_system.respond_to?("bgs_play") - $game_system.bgs_play(param) - return - elsif (RPG.const_defined?(:BGS) rescue false) - b=RPG::BGS.new(param.name,param.volume,param.pitch) - if b && b.respond_to?("play") - b.play; return - end - end - Audio.bgs_play(canonicalize("Audio/BGS/"+param.name),param.volume,param.pitch) - end -end - -# Fades out or stops BGS playback. 'x' is the time in seconds to fade out. -def pbBGSFade(x=0.0); pbBGSStop(x);end - -# Fades out or stops BGS playback. 'x' is the time in seconds to fade out. -def pbBGSStop(timeInSeconds=0.0) - if $game_system && timeInSeconds>0.0 && $game_system.respond_to?("bgs_fade") - $game_system.bgs_fade(timeInSeconds) - return - elsif $game_system && $game_system.respond_to?("bgs_play") - $game_system.bgs_play(nil) - return - elsif (RPG.const_defined?(:BGS) rescue false) - begin - (timeInSeconds>0.0) ? RPG::BGS.fade((timeInSeconds*1000).floor) : RPG::BGS.stop - return - rescue - end - end - (timeInSeconds>0.0) ? Audio.bgs_fade((timeInSeconds*1000).floor) : Audio.bgs_stop -end - -################################################################################ - -# Plays an SE file. -# param -- Either a string showing the filename -# (relative to Audio/SE/) or an RPG::AudioFile object. -# Possible formats for _param_: -# filename volume and pitch 100 -# filename:volume pitch 100 -# filename:volume:pitch -# volume -- Volume of the file, up to 100 -# pitch -- Pitch of the file, normally 100 -def pbSEPlay(param,volume=nil,pitch=nil) - return if !param - param = pbResolveAudioFile(param,volume,pitch) - if param.name && param.name!="" - if $game_system && $game_system.respond_to?("se_play") - $game_system.se_play(param) - return - end - if (RPG.const_defined?(:SE) rescue false) - b = RPG::SE.new(param.name,param.volume,param.pitch) - if b && b.respond_to?("play") - b.play - return - end - end - Audio.se_play(canonicalize("Audio/SE/"+param.name),param.volume,param.pitch) - end -end - -# Stops SE playback. -def pbSEFade(x=0.0); pbSEStop(x);end - -# Stops SE playback. -def pbSEStop(_timeInSeconds=0.0) - if $game_system - $game_system.se_stop - elsif (RPG.const_defined?(:SE) rescue false) - RPG::SE.stop rescue nil - else - Audio.se_stop - end -end - -################################################################################ - -# Plays a sound effect that plays when the player moves the cursor. -def pbPlayCursorSE - if $data_system && $data_system.respond_to?("cursor_se") && - $data_system.cursor_se && $data_system.cursor_se.name!="" - pbSEPlay($data_system.cursor_se) - elsif $data_system && $data_system.respond_to?("sounds") && - $data_system.sounds && $data_system.sounds[0] && $data_system.sounds[0].name!="" - pbSEPlay($data_system.sounds[0]) - elsif FileTest.audio_exist?("Audio/SE/GUI sel cursor") - pbSEPlay("GUI sel cursor",80) - end -end - -# Plays a sound effect that plays when a decision is confirmed or a choice is made. -def pbPlayDecisionSE - if $data_system && $data_system.respond_to?("decision_se") && - $data_system.decision_se && $data_system.decision_se.name!="" - pbSEPlay($data_system.decision_se) - elsif $data_system && $data_system.respond_to?("sounds") && - $data_system.sounds && $data_system.sounds[1] && $data_system.sounds[1].name!="" - pbSEPlay($data_system.sounds[1]) - elsif FileTest.audio_exist?("Audio/SE/GUI sel decision") - pbSEPlay("GUI sel decision",80) - end -end - -# Plays a sound effect that plays when a choice is canceled. -def pbPlayCancelSE - if $data_system && $data_system.respond_to?("cancel_se") && - $data_system.cancel_se && $data_system.cancel_se.name!="" - pbSEPlay($data_system.cancel_se) - elsif $data_system && $data_system.respond_to?("sounds") && - $data_system.sounds && $data_system.sounds[2] && $data_system.sounds[2].name!="" - pbSEPlay($data_system.sounds[2]) - elsif FileTest.audio_exist?("Audio/SE/GUI sel cancel") - pbSEPlay("GUI sel cancel",80) - end -end - -# Plays a buzzer sound effect. -def pbPlayBuzzerSE - if $data_system && $data_system.respond_to?("buzzer_se") && - $data_system.buzzer_se && $data_system.buzzer_se.name!="" - pbSEPlay($data_system.buzzer_se) - elsif $data_system && $data_system.respond_to?("sounds") && - $data_system.sounds && $data_system.sounds[3] && $data_system.sounds[3].name!="" - pbSEPlay($data_system.sounds[3]) - elsif FileTest.audio_exist?("Audio/SE/GUI sel buzzer") - pbSEPlay("GUI sel buzzer",80) - end -end - -# Plays a sound effect that plays when the player moves the cursor. -def pbPlayCloseMenuSE - if FileTest.audio_exist?("Audio/SE/GUI menu close") - pbSEPlay("GUI menu close",80) - end -end diff --git a/Data/Scripts/009_Scenes/001_Transitions.rb b/Data/Scripts/009_Scenes/001_Transitions.rb deleted file mode 100644 index 4222ab80d..000000000 --- a/Data/Scripts/009_Scenes/001_Transitions.rb +++ /dev/null @@ -1,1627 +0,0 @@ -module Graphics - @@transition = nil - STOP_WHILE_TRANSITION = true - - unless defined?(transition_KGC_SpecialTransition) - class << Graphics - alias transition_KGC_SpecialTransition transition - end - - class << Graphics - alias update_KGC_SpecialTransition update - end - end - - def self.transition(duration = 8, filename = "", vague = 20) - duration = duration.floor - if judge_special_transition(duration, filename) - duration = 0 - filename = "" - end - begin - transition_KGC_SpecialTransition(duration, filename, vague) - rescue Exception - if filename != "" - transition_KGC_SpecialTransition(duration, "", vague) - end - end - if STOP_WHILE_TRANSITION && !@_interrupt_transition - while @@transition && !@@transition.disposed? - update - end - end - end - - def self.update - update_KGC_SpecialTransition -=begin - if Graphics.frame_count % 40 == 0 - count = 0 - ObjectSpace.each_object(Object) { |o| count += 1 } - echoln("Objects: #{count}") - end -=end - @@transition.update if @@transition && !@@transition.disposed? - @@transition = nil if @@transition && @@transition.disposed? - end - - def self.judge_special_transition(duration,filename) - return false if @_interrupt_transition - ret = true - if @@transition && !@@transition.disposed? - @@transition.dispose - @@transition = nil - end - dc = File.basename(filename).downcase - case dc - # Other coded transitions - when "breakingglass" then @@transition = Transitions::BreakingGlass.new(duration) - when "rotatingpieces" then @@transition = Transitions::ShrinkingPieces.new(duration, true) - when "shrinkingpieces" then @@transition = Transitions::ShrinkingPieces.new(duration, false) - when "splash" then @@transition = Transitions::SplashTransition.new(duration) - when "random_stripe_v" then @@transition = Transitions::RandomStripeTransition.new(duration, 0) - when "random_stripe_h" then @@transition = Transitions::RandomStripeTransition.new(duration, 1) - when "zoomin" then @@transition = Transitions::ZoomInTransition.new(duration) - when "scrolldown" then @@transition = Transitions::ScrollScreen.new(duration, 2) - when "scrollleft" then @@transition = Transitions::ScrollScreen.new(duration, 4) - when "scrollright" then @@transition = Transitions::ScrollScreen.new(duration, 6) - when "scrollup" then @@transition = Transitions::ScrollScreen.new(duration, 8) - when "scrolldownleft" then @@transition = Transitions::ScrollScreen.new(duration, 1) - when "scrolldownright" then @@transition = Transitions::ScrollScreen.new(duration, 3) - when "scrollupleft" then @@transition = Transitions::ScrollScreen.new(duration, 7) - when "scrollupright" then @@transition = Transitions::ScrollScreen.new(duration, 9) - when "mosaic" then @@transition = Transitions::MosaicTransition.new(duration) - # HGSS transitions - when "snakesquares" then @@transition = Transitions::SnakeSquares.new(duration) - when "diagonalbubbletl" then @@transition = Transitions::DiagonalBubble.new(duration, 0) - when "diagonalbubbletr" then @@transition = Transitions::DiagonalBubble.new(duration, 1) - when "diagonalbubblebl" then @@transition = Transitions::DiagonalBubble.new(duration, 2) - when "diagonalbubblebr" then @@transition = Transitions::DiagonalBubble.new(duration, 3) - when "risingsplash" then @@transition = Transitions::RisingSplash.new(duration) - when "twoballpass" then @@transition = Transitions::TwoBallPass.new(duration) - when "spinballsplit" then @@transition = Transitions::SpinBallSplit.new(duration) - when "threeballdown" then @@transition = Transitions::ThreeBallDown.new(duration) - when "balldown" then @@transition = Transitions::BallDown.new(duration) - when "wavythreeballup" then @@transition = Transitions::WavyThreeBallUp.new(duration) - when "wavyspinball" then @@transition = Transitions::WavySpinBall.new(duration) - when "fourballburst" then @@transition = Transitions::FourBallBurst.new(duration) - # Graphic transitions - when "fadetoblack" then @@transition = Transitions::FadeToBlack.new(duration) - when "" then @@transition = Transitions::FadeFromBlack.new(duration) - else ret = false - end - Graphics.frame_reset if ret - return ret - end -end - - - -#=============================================================================== -# Screen transition classes -#=============================================================================== -module Transitions - #============================================================================= - # - #============================================================================= - class BreakingGlass - def initialize(numframes) - @disposed = false - @numframes = numframes - @opacitychange = (numframes<=0) ? 255 : 255.0/numframes - cx = 6 - cy = 5 - @bitmap = Graphics.snap_to_bitmap - if !@bitmap - @disposed = true - return - end - width = @bitmap.width/cx - height = @bitmap.height/cy - @numtiles = cx*cy - @viewport = Viewport.new(0,0,Graphics.width,Graphics.height) - @viewport.z = 99999 - @sprites = [] - @offset = [] - @y = [] - for i in 0...@numtiles - @sprites[i] = Sprite.new(@viewport) - @sprites[i].bitmap = @bitmap - @sprites[i].x = width*(i%cx) - @sprites[i].y = height*(i/cx) - @sprites[i].src_rect.set(@sprites[i].x,@sprites[i].y,width,height) - @offset[i] = (rand(100)+1)*3.0/100.0 - @y[i] = @sprites[i].y - end - end - - def disposed?; @disposed; end - - def dispose - if !disposed? - @bitmap.dispose - for i in 0...@numtiles - @sprites[i].visible = false - @sprites[i].dispose - end - @sprites.clear - @viewport.dispose if @viewport - @disposed = true - end - end - - def update - return if disposed? - continue = false - for i in 0...@numtiles - @sprites[i].opacity -= @opacitychange - @y[i] += @offset[i] - @sprites[i].y = @y[i] - continue = true if @sprites[i].opacity>0 - end - self.dispose if !continue - end - end - - #============================================================================= - # - #============================================================================= - class ShrinkingPieces - def initialize(numframes,rotation) - @disposed = false - @rotation = rotation - @numframes = numframes - @opacitychange = (numframes<=0) ? 255 : 255.0/numframes - cx = 6 - cy = 5 - @bitmap = Graphics.snap_to_bitmap - if !@bitmap - @disposed = true - return - end - width = @bitmap.width/cx - height = @bitmap.height/cy - @numtiles = cx*cy - @viewport = Viewport.new(0,0,Graphics.width,Graphics.height) - @viewport.z = 99999 - @sprites = [] - for i in 0...@numtiles - @sprites[i] = Sprite.new(@viewport) - @sprites[i].bitmap = @bitmap - @sprites[i].ox = width/2 - @sprites[i].oy = height/2 - @sprites[i].x = width*(i%cx)+@sprites[i].ox - @sprites[i].y = height*(i/cx)+@sprites[i].oy - @sprites[i].src_rect.set(width*(i%cx),height*(i/cx),width,height) - end - end - - def disposed?; @disposed; end - - def dispose - if !disposed? - @bitmap.dispose - for i in 0...@numtiles - @sprites[i].visible = false - @sprites[i].dispose - end - @sprites.clear - @viewport.dispose if @viewport - @disposed = true - end - end - - def update - return if disposed? - continue = false - for i in 0...@numtiles - @sprites[i].opacity -= @opacitychange - if @rotation - @sprites[i].angle += 40 - @sprites[i].angle %= 360 - end - @sprites[i].zoom_x = @sprites[i].opacity/255.0 - @sprites[i].zoom_y = @sprites[i].opacity/255.0 - continue = true if @sprites[i].opacity>0 - end - self.dispose if !continue - end - end - - #============================================================================= - # - #============================================================================= - class SplashTransition - SPLASH_SIZE = 32 - - def initialize(numframes,vague=9.6) - @duration = numframes - @numframes = numframes - @splash_dir = [] - @disposed = false - if @numframes<=0 - @disposed = true - return - end - @buffer = Graphics.snap_to_bitmap - if !@buffer - @disposed = true - return - end - @viewport = Viewport.new(0,0,Graphics.width,Graphics.height) - @viewport.z = 99999 - @sprite = Sprite.new(@viewport) - @sprite.bitmap = Bitmap.new(Graphics.width, Graphics.height) - size = SPLASH_SIZE - size = [size,1].max - cells = Graphics.width*Graphics.height/(size**2) - rows = Graphics.width/size - rect = Rect.new(0,0,size,size) - mag = 40.0/@numframes - cells.times { |i| - rect.x = i%rows*size - rect.y = i/rows*size - x = rect.x/size-(rows>>1) - y = rect.y/size-((cells/rows)>>1) - r = Math.sqrt(x**2+y**2)/vague - @splash_dir[i] = [] - if r!=0 - @splash_dir[i][0] = x/r - @splash_dir[i][1] = y/r - else - @splash_dir[i][0] = (x!= 0) ? x*1.5 : pmrand*vague - @splash_dir[i][1] = (y!= 0) ? y*1.5 : pmrand*vague - end - @splash_dir[i][0] += (rand-0.5)*vague - @splash_dir[i][1] += (rand-0.5)*vague - @splash_dir[i][0] *= mag - @splash_dir[i][1] *= mag - } - @sprite.bitmap.blt(0,0,@buffer,@buffer.rect) - end - - def disposed?; @disposed; end - - def dispose - return if disposed? - @buffer.dispose if @buffer - @buffer = nil - @sprite.visible = false - @sprite.bitmap.dispose - @sprite.dispose - @viewport.dispose if @viewport - @disposed = true - end - - def update - return if disposed? - if @duration==0 - dispose - else - size = SPLASH_SIZE - cells = Graphics.width*Graphics.height/(size**2) - rows = Graphics.width/size - rect = Rect.new(0,0,size,size) - buffer = @buffer - sprite = @sprite - phase = @numframes-@duration - sprite.bitmap.clear - cells.times { |i| - rect.x = (i%rows)*size - rect.y = (i/rows)*size - dx = rect.x+@splash_dir[i][0]*phase - dy = rect.y+@splash_dir[i][1]*phase - sprite.bitmap.blt(dx,dy,buffer,rect) - } - sprite.opacity = 384*@duration/@numframes - @duration -= 1 - end - end - - private - - def pmrand - return (rand(2)==0) ? 1 : -1 - end - end - - #============================================================================= - # - #============================================================================= - class RandomStripeTransition - RAND_STRIPE_SIZE = 2 - - def initialize(numframes,direction) - @duration = numframes - @numframes = numframes - @disposed = false - if @numframes<=0 - @disposed = true - return - end - @buffer = Graphics.snap_to_bitmap - if !@buffer - @disposed = true - return - end - @viewport = Viewport.new(0,0,Graphics.width,Graphics.height) - @viewport.z = 99999 - @sprite = Sprite.new(@viewport) - @sprite.bitmap = Bitmap.new(Graphics.width,Graphics.height) - ########## - @direction = direction - size = RAND_STRIPE_SIZE - bands = ((@direction==0) ? Graphics.width : Graphics.height)/size - @rand_stripe_deleted = [] - @rand_stripe_deleted_count = 0 - ary = (0...bands).to_a - @rand_stripe_index_array = ary.sort_by { rand } - ########## - @sprite.bitmap.blt(0,0,@buffer,@buffer.rect) - end - - def disposed?; @disposed; end - - def dispose - return if disposed? - @buffer.dispose if @buffer - @buffer = nil - @sprite.visible = false - @sprite.bitmap.dispose - @sprite.dispose - @viewport.dispose if @viewport - @disposed = true - end - - def update - return if disposed? - if @duration==0 - dispose - else - dir = @direction - size = RAND_STRIPE_SIZE - bands = ((dir==0) ? Graphics.width : Graphics.height)/size - rect = Rect.new(0,0,(dir==0) ? size : Graphics.width,(dir==0) ? Graphics.height : size) - buffer = @buffer - sprite = @sprite - count = (bands-bands*@duration/@numframes)-@rand_stripe_deleted_count - while count > 0 - @rand_stripe_deleted[@rand_stripe_index_array.pop] = true - @rand_stripe_deleted_count += 1 - count -= 1 - end - sprite.bitmap.clear - bands.to_i.times { |i| - unless @rand_stripe_deleted[i] - if dir==0 - rect.x = i*size - sprite.bitmap.blt(rect.x,0,buffer,rect) - else - rect.y = i*size - sprite.bitmap.blt(0,rect.y,buffer,rect) - end - end - } - @duration -= 1 - end - end - end - - #============================================================================= - # - #============================================================================= - class ZoomInTransition - def initialize(numframes) - @duration = numframes - @numframes = numframes - @disposed = false - if @numframes<=0 - @disposed = true - return - end - @buffer = Graphics.snap_to_bitmap - if !@buffer - @disposed = true - return - end - @width = @buffer.width - @height = @buffer.height - @viewport = Viewport.new(0,0,@width,@height) - @viewport.z = 99999 - @sprite = Sprite.new(@viewport) - @sprite.bitmap = @buffer - @sprite.ox = @width/2 - @sprite.oy = @height/2 - @sprite.x = @width/2 - @sprite.y = @height/2 - end - - def disposed?; @disposed; end - - def dispose - return if disposed? - @buffer.dispose if @buffer - @buffer = nil - @sprite.dispose if @sprite - @viewport.dispose if @viewport - @disposed = true - end - - def update - return if disposed? - if @duration==0 - dispose - else - @sprite.zoom_x += 0.2 - @sprite.zoom_y += 0.2 - @sprite.opacity = (@duration-1)*255/@numframes - @duration -= 1 - end - end - end - - #============================================================================= - # - #============================================================================= - class ScrollScreen - def initialize(numframes,direction) - @numframes = numframes - @duration = numframes - @dir = direction - @disposed = false - if @numframes<=0 - @disposed = true - return - end - @buffer = Graphics.snap_to_bitmap - if !@buffer - @disposed = true - return - end - @width = @buffer.width - @height = @buffer.height - @viewport = Viewport.new(0,0,@width,@height) - @viewport.z = 99999 - @sprite = Sprite.new(@viewport) - @sprite.bitmap = @buffer - end - - def disposed?; @disposed; end - - def dispose - return if disposed? - @buffer.dispose if @buffer - @buffer = nil - @sprite.dispose if @sprite - @viewport.dispose if @viewport - @disposed = true - end - - def update - return if disposed? - if @duration==0 - dispose - else - case @dir - when 1 # down left - @sprite.y += (@height/@numframes) - @sprite.x -= (@width/@numframes) - when 2 # down - @sprite.y += (@height/@numframes) - when 3 # down right - @sprite.y += (@height/@numframes) - @sprite.x += (@width/@numframes) - when 4 # left - @sprite.x -= (@width/@numframes) - when 6 # right - @sprite.x += (@width/@numframes) - when 7 # up left - @sprite.y -= (@height/@numframes) - @sprite.x -= (@width/@numframes) - when 8 # up - @sprite.y -= (@height/@numframes) - when 9 # up right - @sprite.y -= (@height/@numframes) - @sprite.x += (@width/@numframes) - end - @duration -= 1 - end - end - end - - #============================================================================= - # - #============================================================================= - class MosaicTransition - def initialize(numframes) - @duration = numframes - @numframes = numframes - @disposed = false - if @numframes<=0 - @disposed = true - return - end - @buffer = Graphics.snap_to_bitmap - if !@buffer - @disposed = true - return - end - @viewport = Viewport.new(0,0,Graphics.width,Graphics.height) - @viewport.z = 99999 - @sprite = Sprite.new(@viewport) - @sprite.bitmap = @buffer - @bitmapclone = @buffer.clone - @bitmapclone2 = @buffer.clone - end - - def disposed?; @disposed; end - - def dispose - return if disposed? - @buffer.dispose if @buffer - @buffer = nil - @sprite.dispose if @sprite - @viewport.dispose if @viewport - @disposed = true - end - - def update - return if disposed? - if @duration==0 - dispose - else - @bitmapclone2.stretch_blt( - Rect.new(0,0,@buffer.width*@duration/@numframes,@buffer.height*@duration/@numframes), - @bitmapclone, - Rect.new(0,0,@buffer.width,@buffer.height)) - @buffer.stretch_blt( - Rect.new(0,0,@buffer.width,@buffer.height), - @bitmapclone2, - Rect.new(0,0,@buffer.width*@duration/@numframes,@buffer.height*@duration/@numframes)) - @duration -= 1 - end - end - end - - #============================================================================= - # - #============================================================================= - class FadeToBlack - def initialize(numframes) - @duration = numframes - @numframes = numframes - @disposed = false - if @duration<=0 - @disposed = true - return - end - @viewport = Viewport.new(0,0,Graphics.width,Graphics.height) - @viewport.z = 99999 - @sprite = BitmapSprite.new(Graphics.width,Graphics.height,@viewport) - @sprite.bitmap.fill_rect(0,0,Graphics.width,Graphics.height,Color.new(0,0,0)) - @sprite.opacity = 0 - end - - def disposed?; @disposed; end - - def dispose - return if disposed? - @sprite.dispose if @sprite - @viewport.dispose if @viewport - @disposed = true - end - - def update - return if disposed? - if @duration==0 - dispose - else - @sprite.opacity = (@numframes - @duration + 1) * 255 / @numframes - @duration -= 1 - end - end - end - - #============================================================================= - # - #============================================================================= - class FadeFromBlack - def initialize(numframes) - @duration = numframes - @numframes = numframes - @disposed = false - if @duration<=0 - @disposed = true - return - end - @viewport = Viewport.new(0,0,Graphics.width,Graphics.height) - @viewport.z = 99999 - @sprite = BitmapSprite.new(Graphics.width,Graphics.height,@viewport) - @sprite.bitmap.fill_rect(0,0,Graphics.width,Graphics.height,Color.new(0,0,0)) - @sprite.opacity = 255 - end - - def disposed?; @disposed; end - - def dispose - return if disposed? - @sprite.dispose if @sprite - @viewport.dispose if @viewport - @disposed = true - end - - def update - return if disposed? - if @duration==0 - dispose - else - @sprite.opacity = (@duration-1)*255/@numframes - @duration -= 1 - end - end - end - - #============================================================================= - # HGSS wild outdoor - #============================================================================= - class SnakeSquares - def initialize(numframes) - @numframes = numframes - @duration = numframes - @disposed = false - @bitmap = RPG::Cache.transition("black_square") - if !@bitmap - @disposed = true - return - end - width = @bitmap.width - height = @bitmap.height - cx = Graphics.width/width # 8 - cy = Graphics.height/height # 6 - @numtiles = cx*cy - @viewport = Viewport.new(0,0,Graphics.width,Graphics.height) - @viewport.z = 99999 - @sprites = [] - @frame = [] - @addzoom = 0.125*50/@numframes - for i in 0...cy - for j in 0...cx - k = i*cx+j - x = width*(j%cx) - x = (cx-1)*width-x if (i<3 && i%2==1) || (i>=3 && i%2==0) - @sprites[k] = Sprite.new(@viewport) - @sprites[k].x = x+width/2 - @sprites[k].y = height*i - @sprites[k].ox = width/2 - @sprites[k].visible = false - @sprites[k].bitmap = @bitmap - if k>=@numtiles/2 - @frame[k] = 2*(@numtiles-k-1)*(@numframes-1/@addzoom)/50 - else - @frame[k] = 2*k*(@numframes-1/@addzoom)/50 - end - end - end - end - - def disposed?; @disposed; end - - def dispose - if !disposed? - @bitmap.dispose - for i in 0...@numtiles - if @sprites[i] - @sprites[i].visible = false - @sprites[i].dispose - end - end - @sprites.clear - @viewport.dispose if @viewport - @disposed = true - end - end - - def update - return if disposed? - if @duration==0 - dispose - else - count = @numframes-@duration - for i in 0...@numtiles - if @frame[i]=count - @sprites[i].visible = true - @sprites[i].zoom_x = @addzoom*(count-@frame[i]) - @sprites[i].zoom_x = 1.0 if @sprites[i].zoom_x>1.0 - end - end - end - @duration -= 1 - end - end - - #============================================================================= - # HGSS wild indoor day (origin=0) - # HGSS wild indoor night (origin=3) - # HGSS wild cave (origin=3) - #============================================================================= - class DiagonalBubble - def initialize(numframes,origin=0) - @numframes = numframes - @duration = numframes - @disposed = false - @bitmap = RPG::Cache.transition("black_square") - if !@bitmap - @disposed = true - return - end - width = @bitmap.width - height = @bitmap.height - cx = Graphics.width/width # 8 - cy = Graphics.height/height # 6 - @numtiles = cx*cy - @viewport = Viewport.new(0,0,Graphics.width,Graphics.height) - @viewport.z = 99999 - @sprites = [] - @frame = [] - # 1.2, 0.6 and 0.8 determined by trigonometry of default screen size - l = 1.2*Graphics.width/(@numtiles-8) - for i in 0...cy - for j in 0...cx - k = i*cx+j - @sprites[k] = Sprite.new(@viewport) - @sprites[k].x = width*j+width/2 - @sprites[k].y = height*i+height/2 - @sprites[k].ox = width/2 - @sprites[k].oy = height/2 - @sprites[k].visible = false - @sprites[k].bitmap = @bitmap - case origin - when 1 then k = i*cx+(cx-1-j) # Top right - when 2 then k = @numtiles-1-(i*cx+(cx-1-j)) # Bottom left - when 3 then k = @numtiles-1-k # Bottom right - end - @frame[k] = ((0.6*j*width+0.8*i*height)*(@numframes/50.0)/l).floor - end - end - @addzoom = 0.125*50/@numframes - end - - def disposed?; @disposed; end - - def dispose - if !disposed? - @bitmap.dispose - for i in 0...@numtiles - if @sprites[i] - @sprites[i].visible = false - @sprites[i].dispose - end - end - @sprites.clear - @viewport.dispose if @viewport - @disposed = true - end - end - - def update - return if disposed? - if @duration==0 - dispose - else - count = @numframes-@duration - for i in 0...@numtiles - if @frame[i]=count - @sprites[i].visible = true - @sprites[i].zoom_x = @addzoom*(count-@frame[i]) - @sprites[i].zoom_x = 1.0 if @sprites[i].zoom_x>1.0 - @sprites[i].zoom_y = @sprites[i].zoom_x - end - end - end - @duration -= 1 - end - end - - #============================================================================= - # HGSS wild water - #============================================================================= - class RisingSplash - def initialize(numframes) - @numframes = numframes - @duration = numframes - @disposed = false - if @numframes<=0 - @disposed = true - return - end - @bubblebitmap = RPG::Cache.transition("water_1") - @splashbitmap = RPG::Cache.transition("water_2") - @blackbitmap = RPG::Cache.transition("black_half") - @buffer = Graphics.snap_to_bitmap - if !@bubblebitmap || !@splashbitmap || !@blackbitmap || !@buffer - @disposed = true - return - end - @width = @buffer.width - @height = @buffer.height - @viewport = Viewport.new(0,0,@width,@height) - @viewport.z = 99999 - @rearsprite = Sprite.new(@viewport) - @rearsprite.z = 1 - @rearsprite.zoom_y = 2.0 - @rearsprite.bitmap = @blackbitmap - @bgsprites = [] - rect = Rect.new(0,0,@width,2) - for i in 0...@height/2 - @bgsprites[i] = Sprite.new(@viewport) - @bgsprites[i].y = i*2 - @bgsprites[i].z = 2 - @bgsprites[i].bitmap = @buffer - rect.y = i*2 - @bgsprites[i].src_rect = rect - end - @bubblesprite = Sprite.new(@viewport) - @bubblesprite.y = @height - @bubblesprite.z = 3 - @bubblesprite.bitmap = @bubblebitmap - @splashsprite = Sprite.new(@viewport) - @splashsprite.y = @height - @splashsprite.z = 4 - @splashsprite.bitmap = @splashbitmap - @blacksprite = Sprite.new(@viewport) - @blacksprite.y = @height - @blacksprite.z = 5 - @blacksprite.zoom_y = 2.0 - @blacksprite.bitmap = @blackbitmap - @bubblesuby = @height*2/@numframes - @splashsuby = @bubblesuby*2 - @blacksuby = @height/(@numframes*0.1).floor - @angmult = 2/(@numframes/50.0) - end - - def disposed?; @disposed; end - - def dispose - return if disposed? - @buffer.dispose if @buffer - @buffer = nil - @bubblebitmap.dispose if @bubblebitmap - @bubblebitmap = nil - @splashbitmap.dispose if @splashbitmap - @splashbitmap = nil - @blackbitmap.dispose if @blackbitmap - @blackbitmap = nil - @rearsprite.dispose if @rearsprite - for i in @bgsprites; i.dispose if i; end - @bgsprites.clear - @bubblesprite.dispose if @bubblesprite - @splashsprite.dispose if @splashsprite - @blacksprite.dispose if @blacksprite - @viewport.dispose if @viewport - @disposed = true - end - - def update - return if disposed? - if @duration==0 - dispose - else - angadd = (@numframes-@duration)*@angmult - amp = 6*angadd/8; amp = 6 if amp>6 - for i in 0...@bgsprites.length - @bgsprites[i].x = amp*Math.sin((i+angadd)*Math::PI/10) - end - @bubblesprite.x = (@width-@bubblebitmap.width)/2 - @bubblesprite.x -= 32*Math.sin((@numframes-@duration)/(@numframes/50)*3*Math::PI/60) - @bubblesprite.y -= @bubblesuby - if @duration<@numframes*0.5 - @splashsprite.y -= @splashsuby - end - if @duration<@numframes*0.1 - @blacksprite.y -= @blacksuby - @blacksprite.y = 0 if @blacksprite.y<0 - end - end - @duration -= 1 - end - end - - #============================================================================= - # HGSS trainer outdoor day - #============================================================================= - class TwoBallPass - def initialize(numframes) - @numframes = numframes - @duration = numframes - @disposed = false - if @numframes<=0 - @disposed = true - return - end - @blackbitmap = RPG::Cache.transition("black_half") - @ballbitmap = RPG::Cache.transition("ball_small") - @buffer = Graphics.snap_to_bitmap - if !@blackbitmap || !@ballbitmap || !@buffer - @disposed = true - return - end - @width = @buffer.width - @height = @buffer.height - @viewport = Viewport.new(0,0,@width,@height) - @viewport.z = 99999 - @bgsprite = Sprite.new(@viewport) - @bgsprite.x = @width/2 - @bgsprite.y = @height/2 - @bgsprite.ox = @width/2 - @bgsprite.oy = @height/2 - @bgsprite.bitmap = @buffer - @blacksprites = [] - @ballsprites = [] - for i in 0...2 - @blacksprites[i] = Sprite.new(@viewport) - @blacksprites[i].x = (1-i*2)*@width - @blacksprites[i].y = i*@height/2 - @blacksprites[i].z = 1 - @blacksprites[i].bitmap = @blackbitmap - @ballsprites[i] = Sprite.new(@viewport) - @ballsprites[i].x = (1-i)*@width + (1-i*2)*@ballbitmap.width/2 - @ballsprites[i].y = @height/2 + (i*2-1)*@ballbitmap.height/2 - @ballsprites[i].z = 2 - @ballsprites[i].ox = @ballbitmap.width/2 - @ballsprites[i].oy = @ballbitmap.height/2 - @ballsprites[i].bitmap = @ballbitmap - end - @blacksprites[2] = Sprite.new(@viewport) - @blacksprites[2].y = @height/2 - @blacksprites[2].z = 1 - @blacksprites[2].oy = @height/4 - @blacksprites[2].zoom_y = 0.0 - @blacksprites[2].bitmap = @blackbitmap - @addxmult = 2.0*@width/((@numframes*0.6)**2) - @addzoom = 0.02*50/@numframes - end - - def disposed?; @disposed; end - - def dispose - return if disposed? - @buffer.dispose if @buffer - @buffer = nil - @blackbitmap.dispose if @blackbitmap - @blackbitmap = nil - @ballbitmap.dispose if @ballbitmap - @ballbitmap = nil - @bgsprite.dispose if @bgsprite - for i in @blacksprites; i.dispose if i; end - @blacksprites.clear - for i in @ballsprites; i.dispose if i; end - @ballsprites.clear - @viewport.dispose if @viewport - @disposed = true - end - - def update - return if disposed? - if @duration==0 - dispose - elsif @duration>=@numframes*0.6 - for i in 0...2 - @ballsprites[i].x += (2*i-1)*((@width+@ballbitmap.width)/(0.4*@numframes)) - @ballsprites[i].angle += (2*i-1)*(360.0/(0.2*@numframes)) - end - else - addx = (@numframes*0.6-@duration)*@addxmult - for i in 0...2 - @bgsprite.zoom_x += @addzoom - @bgsprite.zoom_y += @addzoom - @blacksprites[i].x += (2*i-1)*addx - end - @blacksprites[2].zoom_y += 2*addx/@width - @blacksprites[0].x = 0 if @blacksprites[0].x<0 - @blacksprites[1].x = 0 if @blacksprites[1].x>0 - end - @duration -= 1 - end - end - - #============================================================================= - # HGSS trainer outdoor night - #============================================================================= - class SpinBallSplit - def initialize(numframes) - @numframes = numframes - @duration = numframes - @disposed = false - if @numframes<=0 - @disposed = true - return - end - @blackbitmap = RPG::Cache.transition("black_half") - @ballbitmap = RPG::Cache.transition("ball_large") - @buffer = Graphics.snap_to_bitmap - if !@blackbitmap || !@ballbitmap || !@buffer - @disposed = true - return - end - @width = @buffer.width - @height = @buffer.height - @viewport = Viewport.new(0,0,@width,@height) - @viewport.z = 99999 - @bgsprites = [] - @blacksprites = [] - @ballsprites = [] - for i in 0...2 - @bgsprites[i] = Sprite.new(@viewport) - @bgsprites[i].x = @width/2 - @bgsprites[i].y = @height/2 - @bgsprites[i].ox = @width/2 - @bgsprites[i].oy = (1-i)*@height/2 - @bgsprites[i].bitmap = @buffer - @bgsprites[i].src_rect.set(0,i*@height/2,@width,@height/2) - @blacksprites[i] = Sprite.new(@viewport) - @blacksprites[i].x = (1-i*2)*@width - @blacksprites[i].y = i*@height/2 - @blacksprites[i].z = 1 - @blacksprites[i].bitmap = @blackbitmap - @ballsprites[i] = Sprite.new(@viewport) - @ballsprites[i].x = @width/2 - @ballsprites[i].y = @height/2 - @ballsprites[i].z = 2 - @ballsprites[i].ox = @ballbitmap.width/2 - @ballsprites[i].oy = (1-i)*@ballbitmap.height/2 - @ballsprites[i].zoom_x = 0.0 - @ballsprites[i].zoom_y = 0.0 - @ballsprites[i].bitmap = @ballbitmap - end - @addxmult = 2.0*@width/((@numframes*0.5)**2) - @addzoom = 0.02*50/@numframes - end - - def disposed?; @disposed; end - - def dispose - return if disposed? - @buffer.dispose if @buffer - @buffer = nil - @blackbitmap.dispose if @blackbitmap - @blackbitmap = nil - @ballbitmap.dispose if @ballbitmap - @ballbitmap = nil - for i in @bgsprites; i.dispose if i; end - @bgsprites.clear - for i in @blacksprites; i.dispose if i; end - @blacksprites.clear - for i in @ballsprites; i.dispose if i; end - @ballsprites.clear - @viewport.dispose if @viewport - @disposed = true - end - - def update - return if disposed? - if @duration==0 - dispose - elsif @duration>=@numframes*0.6 - if @ballsprites[0].zoom_x<1.0 - @ballsprites[0].zoom_x += (1.0/(0.4*@numframes)) - @ballsprites[0].zoom_y += (1.0/(0.4*@numframes)) - @ballsprites[0].angle -= (360.0/(0.4*@numframes)) - if @ballsprites[0].zoom_x>=1.0 - for i in 0...2 - @ballsprites[i].src_rect.set(0,i*@ballbitmap.height/2, - @ballbitmap.width,@ballbitmap.height/2) - @ballsprites[i].zoom_x = @ballsprites[i].zoom_y = 1.0 - @ballsprites[i].angle = 0.0 - end - end - end - # Gap between 0.6*@numframes and 0.5*@numframes - elsif @duration<@numframes*0.5 - addx = (@numframes*0.5-@duration)*@addxmult - for i in 0...2 - @bgsprites[i].x += (2*i-1)*addx - @bgsprites[i].zoom_x += @addzoom - @bgsprites[i].zoom_y += @addzoom - @blacksprites[i].x += (2*i-1)*addx - @ballsprites[i].x += (2*i-1)*addx - end - @blacksprites[0].x = 0 if @blacksprites[0].x<0 - @blacksprites[1].x = 0 if @blacksprites[1].x>0 - end - @duration -= 1 - end - end - - #============================================================================= - # HGSS trainer indoor day - #============================================================================= - class ThreeBallDown - def initialize(numframes) - @numframes = numframes - @duration = numframes - @disposed = false - if @numframes<=0 - @disposed = true - return - end - @blackbitmap = RPG::Cache.transition("black_square") - @ballbitmap = RPG::Cache.transition("ball_small") - @buffer = Graphics.snap_to_bitmap - if !@blackbitmap || !@ballbitmap || !@buffer - @disposed = true - return - end - @width = @buffer.width - @height = @buffer.height - cx = Graphics.width/@blackbitmap.width # 8 - cy = Graphics.height/@blackbitmap.height # 6 - @numtiles = cx*cy - @viewport = Viewport.new(0,0,@width,@height) - @viewport.z = 99999 - @bgsprite = Sprite.new(@viewport) - @bgsprite.x = @width/2 - @bgsprite.y = @height/2 - @bgsprite.ox = @width/2 - @bgsprite.oy = @height/2 - @bgsprite.bitmap = @buffer - @frame = [] - @blacksprites = [] - for i in 0...cy - for j in 0...cx - k = i*cx+j - @blacksprites[k] = Sprite.new(@viewport) - @blacksprites[k].x = @blackbitmap.width*j - @blacksprites[k].y = @blackbitmap.height*i - @blacksprites[k].visible = false - @blacksprites[k].bitmap = @blackbitmap - @frame[k] = (((cy-i-1)*8+[0,4,1,6,7,2,5,3][j])*(@numframes*0.75)/@numtiles).floor - end - end - @ballsprites = [] - for i in 0...3 - @ballsprites[i] = Sprite.new(@viewport) - @ballsprites[i].x = 96+i*160 - @ballsprites[i].y = -@ballbitmap.height-[400,0,100][i] - @ballsprites[i].z = 2 - @ballsprites[i].ox = @ballbitmap.width/2 - @ballsprites[i].oy = @ballbitmap.height/2 - @ballsprites[i].bitmap = @ballbitmap - end - @addyball = (@height+400+@ballbitmap.height*2)/(0.25*@numframes) - @addangle = 1.5*360/(0.25*@numframes) - @addzoom = 0.02*50/@numframes - end - - def disposed?; @disposed; end - - def dispose - return if disposed? - @buffer.dispose if @buffer - @buffer = nil - @blackbitmap.dispose if @blackbitmap - @blackbitmap = nil - @ballbitmap.dispose if @ballbitmap - @ballbitmap = nil - @bgsprite.dispose if @bgsprite - for i in @blacksprites; i.dispose if i; end - @blacksprites.clear - for i in @ballsprites; i.dispose if i; end - @ballsprites.clear - @viewport.dispose if @viewport - @disposed = true - end - - def update - return if disposed? - if @duration==0 - dispose - elsif @duration>=@numframes*0.75 - for i in 0...@ballsprites.length - @ballsprites[i].y += @addyball - @ballsprites[i].angle -= @addangle*([1,-1][(i==2) ? 1 : 0]) - end - else - count = (@numframes*0.75).floor-@duration - for i in 0...@numtiles - @blacksprites[i].visible = true if @frame[i]<=count - end - @bgsprite.zoom_x += @addzoom - @bgsprite.zoom_y += @addzoom - end - @duration -= 1 - end - end - - #============================================================================= - # HGSS trainer indoor night - # HGSS trainer cave - #============================================================================= - class BallDown - def initialize(numframes) - @numframes = numframes - @duration = numframes - @disposed = false - if @numframes<=0 - @disposed = true - return - end - @blackbitmap = RPG::Cache.transition("black_half") - @curvebitmap = RPG::Cache.transition("black_curve") - @ballbitmap = RPG::Cache.transition("ball_small") - @buffer = Graphics.snap_to_bitmap - if !@blackbitmap || !@curvebitmap || !@ballbitmap || !@buffer - @disposed = true - return - end - @width = @buffer.width - @height = @buffer.height - @viewport = Viewport.new(0,0,@width,@height) - @viewport.z = 99999 - @bgsprite = Sprite.new(@viewport) - @bgsprite.x = @width/2 - @bgsprite.y = @height/2 - @bgsprite.ox = @width/2 - @bgsprite.oy = @height/2 - @bgsprite.bitmap = @buffer - @blacksprites = [] - @blacksprites[0] = Sprite.new(@viewport) - @blacksprites[0].y = -@curvebitmap.height - @blacksprites[0].z = 1 - @blacksprites[0].oy = @blackbitmap.height - @blacksprites[0].zoom_y = 2.0 - @blacksprites[0].bitmap = @blackbitmap - @blacksprites[1] = Sprite.new(@viewport) - @blacksprites[1].y = -@curvebitmap.height - @blacksprites[1].z = 1 - @blacksprites[1].bitmap = @curvebitmap - @ballsprite = Sprite.new(@viewport) - @ballsprite.x = @width/2 - @ballsprite.y = -@ballbitmap.height/2 - @ballsprite.z = 2 - @ballsprite.ox = @ballbitmap.width/2 - @ballsprite.oy = @ballbitmap.height/2 - @ballsprite.zoom_x = 0.25 - @ballsprite.zoom_y = 0.25 - @ballsprite.bitmap = @ballbitmap - @addyball = (@height+@ballbitmap.height*2.5)/(0.5*@numframes) - @addangle = 1.5*360/(0.5*@numframes) - @addzoomball = 2.5/(0.5*@numframes) - @addy = (@height+@curvebitmap.height)/(@numframes*0.5) - @addzoom = 0.02*50/@numframes - end - - def disposed?; @disposed; end - - def dispose - return if disposed? - @buffer.dispose if @buffer - @buffer = nil - @blackbitmap.dispose if @blackbitmap - @blackbitmap = nil - @curvebitmap.dispose if @curvebitmap - @curvebitmap = nil - @ballbitmap.dispose if @ballbitmap - @ballbitmap = nil - @bgsprite.dispose if @bgsprite - for i in @blacksprites; i.dispose if i; end - @blacksprites.clear - @ballsprite.dispose - @viewport.dispose if @viewport - @disposed = true - end - - def update - return if disposed? - if @duration==0 - dispose - elsif @duration>=@numframes*0.5 - @ballsprite.y += @addyball - @ballsprite.angle -= @addangle - @ballsprite.zoom_x += @addzoomball - @ballsprite.zoom_y += @addzoomball - else - @blacksprites[1].y += @addy - @blacksprites[0].y = @blacksprites[1].y - @bgsprite.zoom_x += @addzoom - @bgsprite.zoom_y += @addzoom - end - @duration -= 1 - end - end - - #============================================================================= - # HGSS trainer water day - #============================================================================= - class WavyThreeBallUp - def initialize(numframes) - @numframes = numframes - @duration = numframes - @disposed = false - if @numframes<=0 - @disposed = true - return - end - @blackbitmap = RPG::Cache.transition("black_half") - @ballbitmap = RPG::Cache.transition("ball_small") - @buffer = Graphics.snap_to_bitmap - if !@blackbitmap || !@ballbitmap || !@buffer - @disposed = true - return - end - @width = @buffer.width - @height = @buffer.height - @viewport = Viewport.new(0,0,@width,@height) - @viewport.z = 99999 - @rearsprite = Sprite.new(@viewport) - @rearsprite.z = 1 - @rearsprite.zoom_y = 2.0 - @rearsprite.bitmap = @blackbitmap - @bgsprites = [] - rect = Rect.new(0,0,@width,2) - for i in 0...@height/2 - @bgsprites[i] = Sprite.new(@viewport) - @bgsprites[i].y = i*2 - @bgsprites[i].z = 2 - @bgsprites[i].bitmap = @buffer - rect.y = i*2 - @bgsprites[i].src_rect = rect - end - @blacksprites = [] - @ballsprites = [] - for i in 0...3 - @blacksprites[i] = Sprite.new(@viewport) - @blacksprites[i].x = (i-1)*@width*2/3 - @blacksprites[i].y = [@height*1.5,@height*3.25,@height*2.5][i] - @blacksprites[i].z = 3 - @blacksprites[i].zoom_y = 2.0 - @blacksprites[i].bitmap = @blackbitmap - @ballsprites[i] = Sprite.new(@viewport) - @ballsprites[i].x = (2*i+1)*@width/6 - @ballsprites[i].y = [@height*1.5,@height*3.25,@height*2.5][i] - @ballsprites[i].z = 4 - @ballsprites[i].ox = @ballbitmap.width/2 - @ballsprites[i].oy = @ballbitmap.height/2 - @ballsprites[i].bitmap = @ballbitmap - end - @suby = (@height*3.5)/(@numframes*0.6) - @angmult = 4/(@numframes/50.0) - end - - def disposed?; @disposed; end - - def dispose - return if disposed? - @buffer.dispose if @buffer - @buffer = nil - @blackbitmap.dispose if @blackbitmap - @blackbitmap = nil - @ballbitmap.dispose if @ballbitmap - @ballbitmap = nil - @rearsprite.dispose if @rearsprite - for i in @bgsprites; i.dispose if i; end - @bgsprites.clear - for i in @blacksprites; i.dispose if i; end - @blacksprites.clear - for i in @ballsprites; i.dispose if i; end - @ballsprites.clear - @viewport.dispose if @viewport - @disposed = true - end - - def update - return if disposed? - if @duration==0 - dispose - else - angadd = (@numframes-@duration)*@angmult - amp = 24*angadd/16; amp = 24 if amp>24 - for i in 0...@bgsprites.length - @bgsprites[i].x = amp*Math.sin((i+angadd)*Math::PI/48)*((i%2)*2-1) - end - if @duration<@numframes*0.6 - for i in 0...3 - @blacksprites[i].y -= @suby - @blacksprites[i].y = 0 if @blacksprites[i].y<0 - @ballsprites[i].y -= @suby - @ballsprites[i].angle += (2*(i%2)-1)*(360.0/(0.2*@numframes)) - end - end - end - @duration -= 1 - end - end - - #============================================================================= - # HGSS trainer water night - #============================================================================= - class WavySpinBall - def initialize(numframes) - @numframes = numframes - @duration = numframes - @disposed = false - if @numframes<=0 - @disposed = true - return - end - @blackbitmap = RPG::Cache.transition("black_half") - @ballbitmap = RPG::Cache.transition("ball_large") - @buffer = Graphics.snap_to_bitmap - if !@blackbitmap || !@ballbitmap || !@buffer - @disposed = true - return - end - @width = @buffer.width - @height = @buffer.height - @viewport = Viewport.new(0,0,@width,@height) - @viewport.z = 99999 - @rearsprite = Sprite.new(@viewport) - @rearsprite.z = 1 - @rearsprite.zoom_y = 2.0 - @rearsprite.bitmap = @blackbitmap - @bgsprites = [] - rect = Rect.new(0,0,@width,2) - for i in 0...@height/2 - @bgsprites[i] = Sprite.new(@viewport) - @bgsprites[i].y = i*2 - @bgsprites[i].z = 2 - @bgsprites[i].bitmap = @buffer - rect.y = i*2 - @bgsprites[i].src_rect = rect - end - @ballsprite = Sprite.new(@viewport) - @ballsprite.x = @width/2 - @ballsprite.y = @height/2 - @ballsprite.z = 3 - @ballsprite.ox = @ballbitmap.width/2 - @ballsprite.oy = @ballbitmap.height/2 - @ballsprite.visible = false - @ballsprite.bitmap = @ballbitmap - @blacksprite = Sprite.new(@viewport) - @blacksprite.x = @width/2 - @blacksprite.y = @height/2 - @blacksprite.z = 4 - @blacksprite.ox = @blackbitmap.width/2 - @blacksprite.oy = @blackbitmap.height/2 - @blacksprite.visible = false - @blacksprite.bitmap = @blackbitmap - @angmult = 4/(@numframes/50.0) - end - - def disposed?; @disposed; end - - def dispose - return if disposed? - @buffer.dispose if @buffer - @buffer = nil - @blackbitmap.dispose if @blackbitmap - @blackbitmap = nil - @ballbitmap.dispose if @ballbitmap - @ballbitmap = nil - @rearsprite.dispose if @rearsprite - for i in @bgsprites; i.dispose if i; end - @bgsprites.clear - @ballsprite.dispose if @ballsprite - @blacksprite.dispose if @blacksprite - @viewport.dispose if @viewport - @disposed = true - end - - def update - return if disposed? - if @duration==0 - dispose - else - angadd = (@numframes-@duration)*@angmult - amp = 24*angadd/16; amp = 24 if amp>24 - for i in 0...@bgsprites.length - @bgsprites[i].x = amp*Math.sin((i+angadd)*Math::PI/48)*((i%2)*2-1) - end - @ballsprite.visible = true - if @duration>=@numframes*0.6 - @ballsprite.opacity = 255*(@numframes-@duration)/(@numframes*0.4) - @ballsprite.angle = -360.0*(@numframes-@duration)/(@numframes*0.4) - elsif @duration<@numframes*0.5 - @blacksprite.visible = true - @blacksprite.zoom_x = (@numframes*0.5-@duration)/(@numframes*0.5) - @blacksprite.zoom_y = 2*(@numframes*0.5-@duration)/(@numframes*0.5) - end - end - @duration -= 1 - end - end - - #============================================================================= - # HGSS double trainers - #============================================================================= - class FourBallBurst - def initialize(numframes) - @numframes = numframes - @duration = numframes - @disposed = false - if @numframes<=0 - @disposed = true - return - end - @black1bitmap = RPG::Cache.transition("black_wedge_1") - @black2bitmap = RPG::Cache.transition("black_wedge_2") - @black3bitmap = RPG::Cache.transition("black_wedge_3") - @black4bitmap = RPG::Cache.transition("black_wedge_4") - @ballbitmap = RPG::Cache.transition("ball_small") - if !@black1bitmap || !@black2bitmap || !@black3bitmap || !@black4bitmap || !@ballbitmap - @disposed = true - return - end - @width = Graphics.width - @height = Graphics.height - @viewport = Viewport.new(0,0,@width,@height) - @viewport.z = 99999 - @ballsprites = [] - for i in 0...4 - @ballsprites[i] = Sprite.new(@viewport) - @ballsprites[i].x = @width/2 - @ballsprites[i].y = @height/2 - @ballsprites[i].z = [2,1,3,0][i] - @ballsprites[i].ox = @ballbitmap.width/2 - @ballsprites[i].oy = @ballbitmap.height/2 - @ballsprites[i].bitmap = @ballbitmap - end - @blacksprites = [] - for i in 0...4 - b = [@black1bitmap,@black2bitmap,@black3bitmap,@black4bitmap][i] - @blacksprites[i] = Sprite.new(@viewport) - @blacksprites[i].x = (i==1) ? 0 : @width/2 - @blacksprites[i].y = (i==2) ? 0 : @height/2 - @blacksprites[i].ox = (i%2==0) ? b.width/2 : 0 - @blacksprites[i].oy = (i%2==0) ? 0 : b.height/2 - @blacksprites[i].zoom_x = (i%2==0) ? 0.0 : 1.0 - @blacksprites[i].zoom_y = (i%2==0) ? 1.0 : 0.0 - @blacksprites[i].visible = false - @blacksprites[i].bitmap = b - end - @addxball = (@width/2+@ballbitmap.width/2)/(@numframes*0.4) - @addyball = (@height/2+@ballbitmap.height/2)/(@numframes*0.4) - @addzoom = 1.0/(@numframes*0.6) - end - - def disposed?; @disposed; end - - def dispose - return if disposed? - @black1bitmap.dispose if @black1bitmap - @black1bitmap = nil - @black2bitmap.dispose if @black2bitmap - @black2bitmap = nil - @black3bitmap.dispose if @black3bitmap - @black3bitmap = nil - @black4bitmap.dispose if @black4bitmap - @black4bitmap = nil - @ballbitmap.dispose if @ballbitmap - @ballbitmap = nil - for i in @ballsprites; i.dispose if i; end - @ballsprites.clear - for i in @blacksprites; i.dispose if i; end - @blacksprites.clear - @viewport.dispose if @viewport - @disposed = true - end - - def update - return if disposed? - if @duration==0 - dispose - elsif @duration>=@numframes*0.6 - for i in 0...@ballsprites.length - @ballsprites[i].x += (i==1) ? @addxball : (i==3) ? -@addxball : 0 - @ballsprites[i].y += (i==0) ? @addyball : (i==2) ? -@addyball : 0 - end - else - for i in 0...@blacksprites.length - @blacksprites[i].visible = true - @blacksprites[i].zoom_x += (i%2==0) ? @addzoom : 0 - @blacksprites[i].zoom_y += (i%2==0) ? 0 : @addzoom - end - end - @duration -= 1 - end - end -end diff --git a/Data/Scripts/009_Scenes/002_EventScene.rb b/Data/Scripts/009_Scenes/002_EventScene.rb deleted file mode 100644 index 94e9de3e1..000000000 --- a/Data/Scripts/009_Scenes/002_EventScene.rb +++ /dev/null @@ -1,198 +0,0 @@ -class PictureSprite < SpriteWrapper - def initialize(viewport, picture) - super(viewport) - @picture = picture - @pictureBitmap = nil - @customBitmap = nil - @customBitmapIsBitmap = true - @hue = 0 - update - end - - def dispose - @pictureBitmap.dispose if @pictureBitmap - super - end - - # Doesn't free the bitmap - def setCustomBitmap(bitmap) - @customBitmap = bitmap - @customBitmapIsBitmap = @customBitmap.is_a?(Bitmap) - end - - def update - super - @pictureBitmap.update if @pictureBitmap - # If picture file name is different from current one - if @customBitmap && @picture.name=="" - self.bitmap = (@customBitmapIsBitmap) ? @customBitmap : @customBitmap.bitmap - elsif @picture_name != @picture.name || @picture.hue.to_i != @hue.to_i - # Remember file name to instance variables - @picture_name = @picture.name - @hue = @picture.hue.to_i - # If file name is not empty - if @picture_name == "" - @pictureBitmap.dispose if @pictureBitmap - @pictureBitmap = nil - self.visible = false - return - end - # Get picture graphic - @pictureBitmap.dispose if @pictureBitmap - @pictureBitmap = AnimatedBitmap.new(@picture_name, @hue) - self.bitmap = (@pictureBitmap) ? @pictureBitmap.bitmap : nil - elsif @picture_name == "" - # Set sprite to invisible - self.visible = false - return - end - setPictureSprite(self,@picture) - end -end - - - -def pbTextBitmap(text, maxwidth=Graphics.width) - tmp = Bitmap.new(maxwidth,Graphics.height) - pbSetSystemFont(tmp) - drawFormattedTextEx(tmp,0,0,maxwidth,text,Color.new(248,248,248),Color.new(168,184,184)) - return tmp -end - - - -#=============================================================================== -# EventScene -#=============================================================================== -class EventScene - attr_accessor :onCTrigger,:onBTrigger,:onUpdate - - def initialize(viewport=nil) - @viewport = viewport - @onCTrigger = Event.new - @onBTrigger = Event.new - @onUpdate = Event.new - @pictures = [] - @picturesprites = [] - @usersprites = [] - @disposed = false - end - - def dispose - return if disposed? - for sprite in @picturesprites - sprite.dispose - end - for sprite in @usersprites - sprite.dispose - end - @onCTrigger.clear - @onBTrigger.clear - @onUpdate.clear - @pictures.clear - @picturesprites.clear - @usersprites.clear - @disposed = true - end - - def disposed? - return @disposed - end - - def addBitmap(x, y, bitmap) - # _bitmap_ can be a Bitmap or an AnimatedBitmap - # (update method isn't called if it's animated) - # EventScene doesn't take ownership of the passed-in bitmap - num = @pictures.length - picture = PictureEx.new(num) - picture.setXY(0,x,y) - picture.setVisible(0,true) - @pictures[num] = picture - @picturesprites[num] = PictureSprite.new(@viewport,picture) - @picturesprites[num].setCustomBitmap(bitmap) - return picture - end - - def addLabel(x, y, width, text) - addBitmap(x,y,pbTextBitmap(text,width)) - end - - def addImage(x, y, name) - num = @pictures.length - picture = PictureEx.new(num) - picture.name = name - picture.setXY(0,x,y) - picture.setVisible(0,true) - @pictures[num] = picture - @picturesprites[num] = PictureSprite.new(@viewport,picture) - return picture - end - - def addUserSprite(sprite) - @usersprites.push(sprite) - end - - def getPicture(num) - return @pictures[num] - end - - def wait(frames) - frames.times { update } - end - - def pictureWait(extraframes=0) - loop do - hasRunning = false - for pic in @pictures - hasRunning = true if pic.running? - end - break if !hasRunning - update - end - extraframes.times { update } - end - - def update - return if disposed? - Graphics.update - Input.update - for picture in @pictures - picture.update - end - for sprite in @picturesprites - sprite.update - end - for sprite in @usersprites - next if !sprite || sprite.disposed? || !sprite.is_a?(Sprite) - sprite.update - end - @onUpdate.trigger(self) - if Input.trigger?(Input::BACK) - @onBTrigger.trigger(self) - elsif Input.trigger?(Input::USE) - @onCTrigger.trigger(self) - end - end - - def main - while !disposed? - update - end - end -end - - - -#=============================================================================== -# -#=============================================================================== -def pbEventScreen(cls) - pbFadeOutIn { - viewport = Viewport.new(0,0,Graphics.width,Graphics.height) - viewport.z = 99999 - PBDebug.logonerr { - cls.new(viewport).main - } - viewport.dispose - } -end diff --git a/Data/Scripts/010_Data/001_GameData.rb b/Data/Scripts/010_Data/001_GameData.rb deleted file mode 100644 index 432544dcd..000000000 --- a/Data/Scripts/010_Data/001_GameData.rb +++ /dev/null @@ -1,273 +0,0 @@ -module GameData - #============================================================================= - # A mixin module for data classes which provides common class methods (called - # by GameData::Thing.method) that provide access to data held within. - # Assumes the data class's data is stored in a class constant hash called DATA. - # For data that is known by a symbol or an ID number. - #============================================================================= - module ClassMethods - def register(hash) - self::DATA[hash[:id]] = self::DATA[hash[:id_number]] = self.new(hash) - end - - # @param other [Symbol, self, String, Integer] - # @return [Boolean] whether the given other is defined as a self - def exists?(other) - return false if other.nil? - validate other => [Symbol, self, String, Integer] - other = other.id if other.is_a?(self) - other = other.to_sym if other.is_a?(String) - - if self == GameData::Species - return !get(other).nil? - end - - return !self::DATA[other].nil? - end - - # @param other [Symbol, self, String, Integer] - # @return [self] - def get(other) - validate other => [Symbol, self, String, Integer] - - return other if other.is_a?(self) - other = other.to_sym if other.is_a?(String) - - if other.to_s.match?(/\AB\d+H\d+\z/) - species = GameData::FusedSpecies.new(other) - return species - end - - if other.is_a?(Integer) && self == GameData::Species - if other > NB_POKEMON - body_id = getBodyID(other) - head_id = getHeadID(other, body_id) - pokemon_id = getFusedPokemonIdFromDexNum(body_id, head_id) - return GameData::FusedSpecies.new(pokemon_id) - end - end - - if !self::DATA.has_key?(other) - #echoln _INTL("Unknown ID {1}.", other) - return self::get(:PIKACHU) - end - - #if other == :Species - - # end - - return self::DATA[other] - end - - # @param other [Symbol, self, String, Integer] - # @return [self, nil] - def try_get(other) - return nil if other.nil? - validate other => [Symbol, self, String, Integer] - return other if other.is_a?(self) - other = other.to_sym if other.is_a?(String) - - if other.to_s.match?(/\AB\d+H\d+\z/) - species = GameData::FusedSpecies.new(other) - return species - end - if other.is_a?(Integer) && self == GameData::Species - if other > NB_POKEMON - body_id = getBodyID(other) - head_id = getHeadID(other, body_id) - pokemon_id = getFusedPokemonIdFromDexNum(body_id, head_id) - return GameData::FusedSpecies.new(pokemon_id) - end - end - - # if other.is_a?(Integer) - # p "Please switch to symbols, thanks." - # end - return (self::DATA.has_key?(other)) ? self::DATA[other] : nil - end - - # Returns the array of keys for the data. - # @return [Array] - def keys - return self::DATA.keys - end - - # Yields all data in order of their id_number. - def each - keys = self::DATA.keys.sort { |a, b| self::DATA[a].id_number <=> self::DATA[b].id_number } - keys.each { |key| yield self::DATA[key] if !key.is_a?(Integer) } - end - - def load - const_set(:DATA, load_data("Data/#{self::DATA_FILENAME}")) - end - - def save - save_data(self::DATA, "Data/#{self::DATA_FILENAME}") - end - end - - #============================================================================= - # A mixin module for data classes which provides common class methods (called - # by GameData::Thing.method) that provide access to data held within. - # Assumes the data class's data is stored in a class constant hash called DATA. - # For data that is only known by a symbol. - #============================================================================= - module ClassMethodsSymbols - def register(hash) - self::DATA[hash[:id]] = self.new(hash) - end - - # @param other [Symbol, self, String] - # @return [Boolean] whether the given other is defined as a self - def exists?(other) - return false if other.nil? - validate other => [Symbol, self, String] - other = other.id if other.is_a?(self) - other = other.to_sym if other.is_a?(String) - return !self::DATA[other].nil? - end - - # @param other [Symbol, self, String] - # @return [self] - def get(other) - validate other => [Symbol, self, String] - return other if other.is_a?(self) - other = other.to_sym if other.is_a?(String) - raise "Unknown ID #{other}." unless self::DATA.has_key?(other) - return self::DATA[other] - end - - # @param other [Symbol, self, String] - # @return [self, nil] - def try_get(other) - return nil if other.nil? - validate other => [Symbol, self, String] - return other if other.is_a?(self) - other = other.to_sym if other.is_a?(String) - return (self::DATA.has_key?(other)) ? self::DATA[other] : nil - end - - # Returns the array of keys for the data. - # @return [Array] - def keys - return self::DATA.keys - end - - # Yields all data in alphabetical order. - def each - keys = self::DATA.keys.sort { |a, b| self::DATA[a].real_name <=> self::DATA[b].real_name } - keys.each { |key| yield self::DATA[key] } - end - - def load - const_set(:DATA, load_data("Data/#{self::DATA_FILENAME}")) - end - - def save - save_data(self::DATA, "Data/#{self::DATA_FILENAME}") - end - end - - #============================================================================= - # A mixin module for data classes which provides common class methods (called - # by GameData::Thing.method) that provide access to data held within. - # Assumes the data class's data is stored in a class constant hash called DATA. - # For data that is only known by an ID number. - #============================================================================= - module ClassMethodsIDNumbers - def register(hash) - self::DATA[hash[:id]] = self.new(hash) - end - - # @param other [self, Integer] - # @return [Boolean] whether the given other is defined as a self - def exists?(other) - return false if other.nil? - validate other => [self, Integer] - other = other.id if other.is_a?(self) - return !self::DATA[other].nil? - end - - # @param other [self, Integer] - # @return [self] - def get(other) - validate other => [self, Integer] - return other if other.is_a?(self) - raise "Unknown ID #{other}." unless self::DATA.has_key?(other) - return self::DATA[other] - end - - def try_get(other) - return nil if other.nil? - validate other => [self, Integer] - return other if other.is_a?(self) - return (self::DATA.has_key?(other)) ? self::DATA[other] : nil - end - - # Returns the array of keys for the data. - # @return [Array] - def keys - return self::DATA.keys - end - - # Yields all data in numberical order. - def each - keys = self::DATA.keys.sort - keys.each { |key| yield self::DATA[key] } - end - - def load - const_set(:DATA, load_data("Data/#{self::DATA_FILENAME}")) - end - - def save - save_data(self::DATA, "Data/#{self::DATA_FILENAME}") - end - end - - #============================================================================= - # A mixin module for data classes which provides common instance methods - # (called by thing.method) that analyse the data of a particular thing which - # the instance represents. - #============================================================================= - module InstanceMethods - # @param other [Symbol, self.class, String, Integer] - # @return [Boolean] whether other represents the same thing as this thing - def ==(other) - return false if other.nil? - if other.is_a?(Symbol) - return @id == other - elsif other.is_a?(self.class) - return @id == other.id - elsif other.is_a?(String) - return @id_number == other.to_sym - elsif other.is_a?(Integer) - return @id_number == other - end - return false - end - end - - #============================================================================= - # A bulk loader method for all data stored in .dat files in the Data folder. - #============================================================================= - def self.load_all - Type.load - Ability.load - Move.load - Item.load - BerryPlant.load - Species.load - Ribbon.load - Encounter.load - EncounterModern.load - EncounterRandom.load - TrainerType.load - Trainer.load - TrainerModern.load - TrainerExpert.load - Metadata.load - MapMetadata.load - end -end diff --git a/Data/Scripts/010_Data/001_Hardcoded data/001_GrowthRate.rb b/Data/Scripts/010_Data/001_Hardcoded data/001_GrowthRate.rb deleted file mode 100644 index 9df096a61..000000000 --- a/Data/Scripts/010_Data/001_Hardcoded data/001_GrowthRate.rb +++ /dev/null @@ -1,190 +0,0 @@ -module GameData - class GrowthRate - attr_reader :id - attr_reader :real_name - attr_reader :exp_values - attr_reader :exp_formula - - DATA = {} - - extend ClassMethodsSymbols - include InstanceMethods - - def self.load; end - def self.save; end - - # Calculates the maximum level a Pokémon can attain. This can vary during a - # game, and here is where you would make it do so. Note that this method is - # called by the Compiler, which happens before anything (e.g. Game Switches/ - # Variables, the player's data) is loaded, so code in this method should - # check whether the needed variables exist before using them; if they don't, - # this method should return the maximum possible level ever. - # @return [Integer] the maximum level attainable by a Pokémon - def self.max_level - return Settings::MAXIMUM_LEVEL - end - - def initialize(hash) - @id = hash[:id] - @real_name = hash[:name] || "Unnamed" - @exp_values = hash[:exp_values] - @exp_formula = hash[:exp_formula] - end - - # @return [String] the translated name of this growth rate - def name - return _INTL(@real_name) - end - - # @param level [Integer] a level number - # @return [Integer] the minimum Exp needed to be at the given level - def minimum_exp_for_level(level) - return ArgumentError.new("Level #{level} is invalid.") if !level || level <= 0 - level = [level, GrowthRate.max_level].min - return @exp_values[level] if level < @exp_values.length - raise "No Exp formula is defined for growth rate #{name}" if !@exp_formula - return @exp_formula.call(level) - end - - # @return [Integer] the maximum Exp a Pokémon with this growth rate can have - def maximum_exp - return minimum_exp_for_level(GrowthRate.max_level) - end - - # @param exp1 [Integer] an Exp amount - # @param exp2 [Integer] an Exp amount - # @return [Integer] the sum of the two given Exp amounts - def add_exp(exp1, exp2) - return (exp1 + exp2).clamp(0, maximum_exp) - end - - # @param exp [Integer] an Exp amount - # @return [Integer] the level of a Pokémon that has the given Exp amount - def level_from_exp(exp) - return ArgumentError.new("Exp amount #{level} is invalid.") if !exp || exp < 0 - max = GrowthRate.max_level - return max if exp >= maximum_exp - for level in 1..max - return level - 1 if exp < minimum_exp_for_level(level) - end - return max - end - end -end - -#=============================================================================== - -GameData::GrowthRate.register({ - :id => :Medium, # Also known as Medium Fast - :name => _INTL("Medium"), - :exp_values => [-1, - 0, 8, 27, 64, 125, 216, 343, 512, 729, 1000, - 1331, 1728, 2197, 2744, 3375, 4096, 4913, 5832, 6859, 8000, - 9261, 10648, 12167, 13824, 15625, 17576, 19683, 21952, 24389, 27000, - 29791, 32768, 35937, 39304, 42875, 46656, 50653, 54872, 59319, 64000, - 68921, 74088, 79507, 85184, 91125, 97336, 103823, 110592, 117649, 125000, - 132651, 140608, 148877, 157464, 166375, 175616, 185193, 195112, 205379, 216000, - 226981, 238328, 250047, 262144, 274625, 287496, 300763, 314432, 328509, 343000, - 357911, 373248, 389017, 405224, 421875, 438976, 456533, 474552, 493039, 512000, - 531441, 551368, 571787, 592704, 614125, 636056, 658503, 681472, 704969, 729000, - 753571, 778688, 804357, 830584, 857375, 884736, 912673, 941192, 970299, 1000000], - :exp_formula => proc { |level| next level ** 3 } -}) - -# Erratic (600000): -# For levels 0-50: n**3 * (100 - n) / 50 -# For levels 51-68: n**3 * (150 - n) / 100 -# For levels 69-98: n**3 * 1.274 - (n / 150) - p(n mod 3) -# where p(x) = array(0.000, 0.008, 0.014)[x] -# For levels 99-100: n**3 * (160 - n) / 100 -GameData::GrowthRate.register({ - :id => :Erratic, - :name => _INTL("Erratic"), - :exp_values => [-1, - 0, 15, 52, 122, 237, 406, 637, 942, 1326, 1800, - 2369, 3041, 3822, 4719, 5737, 6881, 8155, 9564, 11111, 12800, - 14632, 16610, 18737, 21012, 23437, 26012, 28737, 31610, 34632, 37800, - 41111, 44564, 48155, 51881, 55737, 59719, 63822, 68041, 72369, 76800, - 81326, 85942, 90637, 95406, 100237, 105122, 110052, 115015, 120001, 125000, - 131324, 137795, 144410, 151165, 158056, 165079, 172229, 179503, 186894, 194400, - 202013, 209728, 217540, 225443, 233431, 241496, 249633, 257834, 267406, 276458, - 286328, 296358, 305767, 316074, 326531, 336255, 346965, 357812, 367807, 378880, - 390077, 400293, 411686, 423190, 433572, 445239, 457001, 467489, 479378, 491346, - 501878, 513934, 526049, 536557, 548720, 560922, 571333, 583539, 591882, 600000], - :exp_formula => proc { |level| next (level ** 4) * 3 / 500 } -}) - -# Fluctuating (1640000): -# For levels 0-15 : n**3 * (24 + ((n + 1) / 3)) / 50 -# For levels 16-35: n**3 * (14 + n) / 50 -# For levels 36-100: n**3 * (32 + (n / 2)) / 50 -GameData::GrowthRate.register({ - :id => :Fluctuating, - :name => _INTL("Fluctuating"), - :exp_values => [-1, - 0, 4, 13, 32, 65, 112, 178, 276, 393, 540, - 745, 967, 1230, 1591, 1957, 2457, 3046, 3732, 4526, 5440, - 6482, 7666, 9003, 10506, 12187, 14060, 16140, 18439, 20974, 23760, - 26811, 30146, 33780, 37731, 42017, 46656, 50653, 55969, 60505, 66560, - 71677, 78533, 84277, 91998, 98415, 107069, 114205, 123863, 131766, 142500, - 151222, 163105, 172697, 185807, 196322, 210739, 222231, 238036, 250562, 267840, - 281456, 300293, 315059, 335544, 351520, 373744, 390991, 415050, 433631, 459620, - 479600, 507617, 529063, 559209, 582187, 614566, 639146, 673863, 700115, 737280, - 765275, 804997, 834809, 877201, 908905, 954084, 987754, 1035837, 1071552, 1122660, - 1160499, 1214753, 1254796, 1312322, 1354652, 1415577, 1460276, 1524731, 1571884, 1640000], - :exp_formula => proc { |level| - rate = [82 - (level - 100) / 2.0, 40].max - next (level ** 4) * rate / 5000 - } -}) - -GameData::GrowthRate.register({ - :id => :Parabolic, # Also known as Medium Slow - :name => _INTL("Parabolic"), - :exp_values => [-1, - 0, 9, 57, 96, 135, 179, 236, 314, 419, 560, - 742, 973, 1261, 1612, 2035, 2535, 3120, 3798, 4575, 5460, - 6458, 7577, 8825, 10208, 11735, 13411, 15244, 17242, 19411, 21760, - 24294, 27021, 29949, 33084, 36435, 40007, 43808, 47846, 52127, 56660, - 61450, 66505, 71833, 77440, 83335, 89523, 96012, 102810, 109923, 117360, - 125126, 133229, 141677, 150476, 159635, 169159, 179056, 189334, 199999, 211060, - 222522, 234393, 246681, 259392, 272535, 286115, 300140, 314618, 329555, 344960, - 360838, 377197, 394045, 411388, 429235, 447591, 466464, 485862, 505791, 526260, - 547274, 568841, 590969, 613664, 636935, 660787, 685228, 710266, 735907, 762160, - 789030, 816525, 844653, 873420, 902835, 932903, 963632, 995030, 1027103, 1059860], - :exp_formula => proc { |level| next ((level ** 3) * 6 / 5) - 15 * (level ** 2) + 100 * level - 140 } -}) - -GameData::GrowthRate.register({ - :id => :Fast, - :name => _INTL("Fast"), - :exp_values => [-1, - 0, 6, 21, 51, 100, 172, 274, 409, 583, 800, - 1064, 1382, 1757, 2195, 2700, 3276, 3930, 4665, 5487, 6400, - 7408, 8518, 9733, 11059, 12500, 14060, 15746, 17561, 19511, 21600, - 23832, 26214, 28749, 31443, 34300, 37324, 40522, 43897, 47455, 51200, - 55136, 59270, 63605, 68147, 72900, 77868, 83058, 88473, 94119, 100000, - 106120, 112486, 119101, 125971, 133100, 140492, 148154, 156089, 164303, 172800, - 181584, 190662, 200037, 209715, 219700, 229996, 240610, 251545, 262807, 274400, - 286328, 298598, 311213, 324179, 337500, 351180, 365226, 379641, 394431, 409600, - 425152, 441094, 457429, 474163, 491300, 508844, 526802, 545177, 563975, 583200, - 602856, 622950, 643485, 664467, 685900, 707788, 730138, 752953, 776239, 800000], - :exp_formula => proc { |level| (level ** 3) * 4 / 5 } -}) - -GameData::GrowthRate.register({ - :id => :Slow, - :name => _INTL("Slow"), - :exp_values => [-1, - 0, 10, 33, 80, 156, 270, 428, 640, 911, 1250, - 1663, 2160, 2746, 3430, 4218, 5120, 6141, 7290, 8573, 10000, - 11576, 13310, 15208, 17280, 19531, 21970, 24603, 27440, 30486, 33750, - 37238, 40960, 44921, 49130, 53593, 58320, 63316, 68590, 74148, 80000, - 86151, 92610, 99383, 106480, 113906, 121670, 129778, 138240, 147061, 156250, - 165813, 175760, 186096, 196830, 207968, 219520, 231491, 243890, 256723, 270000, - 283726, 297910, 312558, 327680, 343281, 359370, 375953, 393040, 410636, 428750, - 447388, 466560, 486271, 506530, 527343, 548720, 570666, 593190, 616298, 640000, - 664301, 689210, 714733, 740880, 767656, 795070, 823128, 851840, 881211, 911250, - 941963, 973360, 1005446, 1038230, 1071718, 1105920, 1140841, 1176490, 1212873, 1250000], - :exp_formula => proc { |level| (level ** 3) * 5 / 4 } -}) diff --git a/Data/Scripts/010_Data/001_Hardcoded data/002_GenderRatio.rb b/Data/Scripts/010_Data/001_Hardcoded data/002_GenderRatio.rb deleted file mode 100644 index b2d75ff50..000000000 --- a/Data/Scripts/010_Data/001_Hardcoded data/002_GenderRatio.rb +++ /dev/null @@ -1,77 +0,0 @@ -# If a Pokémon's gender ratio is none of :AlwaysMale, :AlwaysFemale or -# :Genderless, then it will choose a random number between 0 and 255 inclusive, -# and compare it to the @female_chance. If the random number is lower than this -# chance, it will be female; otherwise, it will be male. -module GameData - class GenderRatio - attr_reader :id - attr_reader :real_name - attr_reader :female_chance - - DATA = {} - - extend ClassMethodsSymbols - include InstanceMethods - - def self.load; end - def self.save; end - - def initialize(hash) - @id = hash[:id] - @real_name = hash[:name] || "Unnamed" - @female_chance = hash[:female_chance] - end - - # @return [String] the translated name of this gender ratio - def name - return _INTL(@real_name) - end - end -end - -#=============================================================================== - -GameData::GenderRatio.register({ - :id => :AlwaysMale, - :name => _INTL("Always Male") -}) - -GameData::GenderRatio.register({ - :id => :AlwaysFemale, - :name => _INTL("Always Female") -}) - -GameData::GenderRatio.register({ - :id => :Genderless, - :name => _INTL("Genderless") -}) - -GameData::GenderRatio.register({ - :id => :FemaleOneEighth, - :name => _INTL("Female One Eighth"), - :female_chance => 32 -}) - -GameData::GenderRatio.register({ - :id => :Female25Percent, - :name => _INTL("Female 25 Percent"), - :female_chance => 64 -}) - -GameData::GenderRatio.register({ - :id => :Female50Percent, - :name => _INTL("Female 50 Percent"), - :female_chance => 128 -}) - -GameData::GenderRatio.register({ - :id => :Female75Percent, - :name => _INTL("Female 75 Percent"), - :female_chance => 192 -}) - -GameData::GenderRatio.register({ - :id => :FemaleSevenEighths, - :name => _INTL("Female Seven Eighths"), - :female_chance => 224 -}) diff --git a/Data/Scripts/010_Data/001_Hardcoded data/003_EggGroup.rb b/Data/Scripts/010_Data/001_Hardcoded data/003_EggGroup.rb deleted file mode 100644 index 496116bdc..000000000 --- a/Data/Scripts/010_Data/001_Hardcoded data/003_EggGroup.rb +++ /dev/null @@ -1,102 +0,0 @@ -module GameData - class EggGroup - attr_reader :id - attr_reader :real_name - - DATA = {} - - extend ClassMethodsSymbols - include InstanceMethods - - def self.load; end - - def self.save; end - - def initialize(hash) - @id = hash[:id] - @real_name = hash[:name] || "Unnamed" - end - - # @return [String] the translated name of this egg group - def name - return _INTL(@real_name) - end - end -end - -#=============================================================================== - -GameData::EggGroup.register({ - :id => :Undiscovered, - :name => _INTL("Undiscovered") - }) - -GameData::EggGroup.register({ - :id => :Monster, - :name => _INTL("Monster") - }) - -GameData::EggGroup.register({ - :id => :Water1, - :name => _INTL("Water 1") - }) - -GameData::EggGroup.register({ - :id => :Bug, - :name => _INTL("Bug") - }) - -GameData::EggGroup.register({ - :id => :Flying, - :name => _INTL("Flying") - }) - -GameData::EggGroup.register({ - :id => :Field, - :name => _INTL("Field") - }) - -GameData::EggGroup.register({ - :id => :Fairy, - :name => _INTL("Fairy") - }) - -GameData::EggGroup.register({ - :id => :Grass, - :name => _INTL("Grass") - }) - -GameData::EggGroup.register({ - :id => :Humanlike, - :name => _INTL("Humanlike") - }) - -GameData::EggGroup.register({ - :id => :Water3, - :name => _INTL("Water 3") - }) - -GameData::EggGroup.register({ - :id => :Mineral, - :name => _INTL("Mineral") - }) - -GameData::EggGroup.register({ - :id => :Amorphous, - :name => _INTL("Amorphous") - }) - -GameData::EggGroup.register({ - :id => :Water2, - :name => _INTL("Water 2") - }) - -GameData::EggGroup.register({ - :id => :Ditto, - :name => _INTL("Ditto") - }) - -GameData::EggGroup.register({ - :id => :Dragon, - :name => _INTL("Dragon") - }) diff --git a/Data/Scripts/010_Data/001_Hardcoded data/004_BodyShape.rb b/Data/Scripts/010_Data/001_Hardcoded data/004_BodyShape.rb deleted file mode 100644 index ff3b4465f..000000000 --- a/Data/Scripts/010_Data/001_Hardcoded data/004_BodyShape.rb +++ /dev/null @@ -1,117 +0,0 @@ -# NOTE: The id_number is only used to determine the order that body shapes are -# listed in the Pokédex search screen. Number 0 (:None) is ignored; they -# start with shape 1. -# "Graphics/Pictures/Pokedex/icon_shapes.png" contains icons for these -# shapes. -module GameData - class BodyShape - attr_reader :id - attr_reader :id_number - attr_reader :real_name - - DATA = {} - - extend ClassMethods - include InstanceMethods - - def self.load; end - def self.save; end - - def initialize(hash) - @id = hash[:id] - @id_number = hash[:id_number] || -1 - @real_name = hash[:name] || "Unnamed" - end - - # @return [String] the translated name of this body shape - def name - return _INTL(@real_name) - end - end -end - -#=============================================================================== - -GameData::BodyShape.register({ - :id => :Head, - :id_number => 1, - :name => _INTL("Head") -}) - -GameData::BodyShape.register({ - :id => :Serpentine, - :id_number => 2, - :name => _INTL("Serpentine") -}) - -GameData::BodyShape.register({ - :id => :Finned, - :id_number => 3, - :name => _INTL("Finned") -}) - -GameData::BodyShape.register({ - :id => :HeadArms, - :id_number => 4, - :name => _INTL("Head and arms") -}) - -GameData::BodyShape.register({ - :id => :HeadBase, - :id_number => 5, - :name => _INTL("Head and base") -}) - -GameData::BodyShape.register({ - :id => :BipedalTail, - :id_number => 6, - :name => _INTL("Bipedal with tail") -}) - -GameData::BodyShape.register({ - :id => :HeadLegs, - :id_number => 7, - :name => _INTL("Head and legs") -}) - -GameData::BodyShape.register({ - :id => :Quadruped, - :id_number => 8, - :name => _INTL("Quadruped") -}) - -GameData::BodyShape.register({ - :id => :Winged, - :id_number => 9, - :name => _INTL("Winged") -}) - -GameData::BodyShape.register({ - :id => :Multiped, - :id_number => 10, - :name => _INTL("Multiped") -}) - -GameData::BodyShape.register({ - :id => :MultiBody, - :id_number => 11, - :name => _INTL("Multi Body") -}) - -GameData::BodyShape.register({ - :id => :Bipedal, - :id_number => 12, - :name => _INTL("Bipedal") -}) - -GameData::BodyShape.register({ - :id => :MultiWinged, - :id_number => 13, - :name => _INTL("Multi Winged") -}) - -GameData::BodyShape.register({ - :id => :Insectoid, - :id_number => 14, - :name => _INTL("Insectoid") -}) diff --git a/Data/Scripts/010_Data/001_Hardcoded data/005_BodyColor.rb b/Data/Scripts/010_Data/001_Hardcoded data/005_BodyColor.rb deleted file mode 100644 index 542c723be..000000000 --- a/Data/Scripts/010_Data/001_Hardcoded data/005_BodyColor.rb +++ /dev/null @@ -1,90 +0,0 @@ -# NOTE: The id_number is only used to determine the order that body colors are -# listed in the Pokédex search screen. -module GameData - class BodyColor - attr_reader :id - attr_reader :id_number - attr_reader :real_name - - DATA = {} - - extend ClassMethods - include InstanceMethods - - def self.load; end - def self.save; end - - def initialize(hash) - @id = hash[:id] - @id_number = hash[:id_number] || -1 - @real_name = hash[:name] || "Unnamed" - end - - # @return [String] the translated name of this body color - def name - return _INTL(@real_name) - end - end -end - -#=============================================================================== - -GameData::BodyColor.register({ - :id => :Red, - :id_number => 0, - :name => _INTL("Red") -}) - -GameData::BodyColor.register({ - :id => :Blue, - :id_number => 1, - :name => _INTL("Blue") -}) - -GameData::BodyColor.register({ - :id => :Yellow, - :id_number => 2, - :name => _INTL("Yellow") -}) - -GameData::BodyColor.register({ - :id => :Green, - :id_number => 3, - :name => _INTL("Green") -}) - -GameData::BodyColor.register({ - :id => :Black, - :id_number => 4, - :name => _INTL("Black") -}) - -GameData::BodyColor.register({ - :id => :Brown, - :id_number => 5, - :name => _INTL("Brown") -}) - -GameData::BodyColor.register({ - :id => :Purple, - :id_number => 6, - :name => _INTL("Purple") -}) - -GameData::BodyColor.register({ - :id => :Gray, - :id_number => 7, - :name => _INTL("Gray") -}) - -GameData::BodyColor.register({ - :id => :White, - :id_number => 8, - :name => _INTL("White") -}) - -GameData::BodyColor.register({ - :id => :Pink, - :id_number => 9, - :name => _INTL("Pink") -}) diff --git a/Data/Scripts/010_Data/001_Hardcoded data/006_Habitat.rb b/Data/Scripts/010_Data/001_Hardcoded data/006_Habitat.rb deleted file mode 100644 index cfe1521c8..000000000 --- a/Data/Scripts/010_Data/001_Hardcoded data/006_Habitat.rb +++ /dev/null @@ -1,76 +0,0 @@ -module GameData - class Habitat - attr_reader :id - attr_reader :real_name - - DATA = {} - - extend ClassMethodsSymbols - include InstanceMethods - - def self.load; end - def self.save; end - - def initialize(hash) - @id = hash[:id] - @real_name = hash[:name] || "Unnamed" - end - - # @return [String] the translated name of this habitat - def name - return _INTL(@real_name) - end - end -end - -#=============================================================================== - -GameData::Habitat.register({ - :id => :None, - :name => _INTL("None") -}) - -GameData::Habitat.register({ - :id => :Grassland, - :name => _INTL("Grassland") -}) - -GameData::Habitat.register({ - :id => :Forest, - :name => _INTL("Forest") -}) - -GameData::Habitat.register({ - :id => :WatersEdge, - :name => _INTL("Water's Edge") -}) - -GameData::Habitat.register({ - :id => :Sea, - :name => _INTL("Sea") -}) - -GameData::Habitat.register({ - :id => :Cave, - :name => _INTL("Cave") -}) - -GameData::Habitat.register({ - :id => :Mountain, - :name => _INTL("Mountain") -}) - -GameData::Habitat.register({ - :id => :RoughTerrain, - :name => _INTL("Rough Terrain") -}) - -GameData::Habitat.register({ - :id => :Urban, - :name => _INTL("Urban") -}) - -GameData::Habitat.register({ - :id => :Rare, - :name => _INTL("Rare") -}) diff --git a/Data/Scripts/010_Data/001_Hardcoded data/007_Evolution.rb b/Data/Scripts/010_Data/001_Hardcoded data/007_Evolution.rb deleted file mode 100644 index 896845700..000000000 --- a/Data/Scripts/010_Data/001_Hardcoded data/007_Evolution.rb +++ /dev/null @@ -1,599 +0,0 @@ -module GameData - class Evolution - attr_reader :id - attr_reader :real_name - attr_reader :parameter - attr_reader :minimum_level # 0 means parameter is the minimum level - attr_reader :level_up_proc - attr_reader :use_item_proc - attr_reader :on_trade_proc - attr_reader :after_evolution_proc - - DATA = {} - - extend ClassMethodsSymbols - include InstanceMethods - - def self.load; end - def self.save; end - - def initialize(hash) - @id = hash[:id] - @real_name = hash[:id].to_s || "Unnamed" - @parameter = hash[:parameter] - @minimum_level = hash[:minimum_level] || 0 - @level_up_proc = hash[:level_up_proc] - @use_item_proc = hash[:use_item_proc] - @on_trade_proc = hash[:on_trade_proc] - @after_evolution_proc = hash[:after_evolution_proc] - end - - def call_level_up(*args) - return (@level_up_proc) ? @level_up_proc.call(*args) : nil - end - - def call_use_item(*args) - return (@use_item_proc) ? @use_item_proc.call(*args) : nil - end - - def call_on_trade(*args) - return (@on_trade_proc) ? @on_trade_proc.call(*args) : nil - end - - def call_after_evolution(*args) - @after_evolution_proc.call(*args) if @after_evolution_proc - end - end -end - -#=============================================================================== - -GameData::Evolution.register({ - :id => :None -}) - -GameData::Evolution.register({ - :id => :Level, - :parameter => Integer, - :level_up_proc => proc { |pkmn, parameter| - next pkmn.level >= parameter - } -}) - -GameData::Evolution.register({ - :id => :LevelMale, - :parameter => Integer, - :level_up_proc => proc { |pkmn, parameter| - next pkmn.level >= parameter && pkmn.male? - } -}) - -GameData::Evolution.register({ - :id => :LevelFemale, - :parameter => Integer, - :level_up_proc => proc { |pkmn, parameter| - next pkmn.level >= parameter && pkmn.female? - } -}) - -GameData::Evolution.register({ - :id => :LevelDay, - :parameter => Integer, - :level_up_proc => proc { |pkmn, parameter| - next pkmn.level >= parameter && PBDayNight.isDay? - } -}) - -GameData::Evolution.register({ - :id => :LevelNight, - :parameter => Integer, - :level_up_proc => proc { |pkmn, parameter| - next pkmn.level >= parameter && PBDayNight.isNight? - } -}) - -GameData::Evolution.register({ - :id => :LevelMorning, - :parameter => Integer, - :level_up_proc => proc { |pkmn, parameter| - next pkmn.level >= parameter && PBDayNight.isMorning? - } -}) - -GameData::Evolution.register({ - :id => :LevelAfternoon, - :parameter => Integer, - :level_up_proc => proc { |pkmn, parameter| - next pkmn.level >= parameter && PBDayNight.isAfternoon? - } -}) - -GameData::Evolution.register({ - :id => :LevelEvening, - :parameter => Integer, - :level_up_proc => proc { |pkmn, parameter| - next pkmn.level >= parameter && PBDayNight.isEvening? - } -}) - -GameData::Evolution.register({ - :id => :LevelNoWeather, - :parameter => Integer, - :level_up_proc => proc { |pkmn, parameter| - next pkmn.level >= parameter && $game_screen && $game_screen.weather_type == :None - } -}) - -GameData::Evolution.register({ - :id => :LevelSun, - :parameter => Integer, - :level_up_proc => proc { |pkmn, parameter| - next pkmn.level >= parameter && $game_screen && - GameData::Weather.get($game_screen.weather_type).category == :Sun - } -}) - -GameData::Evolution.register({ - :id => :LevelRain, - :parameter => Integer, - :level_up_proc => proc { |pkmn, parameter| - next pkmn.level >= parameter && $game_screen && - [:Rain, :Fog].include?(GameData::Weather.get($game_screen.weather_type).category) - } -}) - -GameData::Evolution.register({ - :id => :LevelSnow, - :parameter => Integer, - :level_up_proc => proc { |pkmn, parameter| - next pkmn.level >= parameter && $game_screen && - GameData::Weather.get($game_screen.weather_type).category == :Hail - } -}) - -GameData::Evolution.register({ - :id => :LevelSandstorm, - :parameter => Integer, - :level_up_proc => proc { |pkmn, parameter| - next pkmn.level >= parameter && $game_screen && - GameData::Weather.get($game_screen.weather_type).category == :Sandstorm - } -}) - -GameData::Evolution.register({ - :id => :LevelCycling, - :parameter => Integer, - :level_up_proc => proc { |pkmn, parameter| - next pkmn.level >= parameter && $PokemonGlobal && $PokemonGlobal.bicycle - } -}) - -GameData::Evolution.register({ - :id => :LevelSurfing, - :parameter => Integer, - :level_up_proc => proc { |pkmn, parameter| - next pkmn.level >= parameter && $PokemonGlobal && $PokemonGlobal.surfing - } -}) - -GameData::Evolution.register({ - :id => :LevelDiving, - :parameter => Integer, - :level_up_proc => proc { |pkmn, parameter| - next pkmn.level >= parameter && $PokemonGlobal && $PokemonGlobal.diving - } -}) - -GameData::Evolution.register({ - :id => :LevelDarkness, - :parameter => Integer, - :level_up_proc => proc { |pkmn, parameter| - map_metadata = GameData::MapMetadata.try_get($game_map.map_id) - next pkmn.level >= parameter && map_metadata && map_metadata.dark_map - } -}) - -GameData::Evolution.register({ - :id => :LevelDarkInParty, - :parameter => Integer, - :level_up_proc => proc { |pkmn, parameter| - next pkmn.level >= parameter && $Trainer.has_pokemon_of_type?(:DARK) - } -}) - -GameData::Evolution.register({ - :id => :AttackGreater, # Hitmonlee - :parameter => Integer, - :level_up_proc => proc { |pkmn, parameter| - next pkmn.level >= parameter && pkmn.attack > pkmn.defense - } -}) - -GameData::Evolution.register({ - :id => :AtkDefEqual, # Hitmontop - :parameter => Integer, - :level_up_proc => proc { |pkmn, parameter| - next pkmn.level >= parameter && pkmn.attack == pkmn.defense - } -}) - -GameData::Evolution.register({ - :id => :DefenseGreater, # Hitmonchan - :parameter => Integer, - :level_up_proc => proc { |pkmn, parameter| - next pkmn.level >= parameter && pkmn.attack < pkmn.defense - } -}) - -GameData::Evolution.register({ - :id => :Silcoon, - :parameter => Integer, - :level_up_proc => proc { |pkmn, parameter| - next pkmn.level >= parameter && (((pkmn.personalID >> 16) & 0xFFFF) % 10) < 5 - } -}) - -GameData::Evolution.register({ - :id => :Cascoon, - :parameter => Integer, - :level_up_proc => proc { |pkmn, parameter| - next pkmn.level >= parameter && (((pkmn.personalID >> 16) & 0xFFFF) % 10) >= 5 - } -}) - -GameData::Evolution.register({ - :id => :Ninjask, - :parameter => Integer, - :level_up_proc => proc { |pkmn, parameter| - next pkmn.level >= parameter - } -}) - -GameData::Evolution.register({ - :id => :Shedinja, - :parameter => Integer, - :level_up_proc => proc { |pkmn, parameter| - next false # This is a dummy proc and shouldn't next true - }, - :after_evolution_proc => proc { |pkmn, new_species, parameter, evo_species| - next false if $Trainer.party_full? - next false if !$PokemonBag.pbHasItem?(:POKEBALL) - PokemonEvolutionScene.pbDuplicatePokemon(pkmn, new_species) - $PokemonBag.pbDeleteItem(:POKEBALL) - next true - } -}) - -GameData::Evolution.register({ - :id => :Happiness, - :minimum_level => 1, # Needs any level up - :level_up_proc => proc { |pkmn, parameter| - next pkmn.happiness >= 220 - } -}) - -GameData::Evolution.register({ - :id => :HappinessMale, - :minimum_level => 1, # Needs any level up - :level_up_proc => proc { |pkmn, parameter| - next pkmn.happiness >= 220 && pkmn.male? - } -}) - -GameData::Evolution.register({ - :id => :HappinessFemale, - :minimum_level => 1, # Needs any level up - :level_up_proc => proc { |pkmn, parameter| - next pkmn.happiness >= 220 && pkmn.female? - } -}) - -GameData::Evolution.register({ - :id => :HappinessDay, - :minimum_level => 1, # Needs any level up - :level_up_proc => proc { |pkmn, parameter| - next pkmn.happiness >= 220 && PBDayNight.isDay? - } -}) - -GameData::Evolution.register({ - :id => :HappinessNight, - :minimum_level => 1, # Needs any level up - :level_up_proc => proc { |pkmn, parameter| - next pkmn.happiness >= 220 && PBDayNight.isNight? - } -}) - -GameData::Evolution.register({ - :id => :HappinessMove, - :parameter => :Move, - :minimum_level => 1, # Needs any level up - :level_up_proc => proc { |pkmn, parameter| - if pkmn.happiness >= 220 - next pkmn.moves.any? { |m| m && m.id == parameter } - end - } -}) - -GameData::Evolution.register({ - :id => :HappinessMoveType, - :parameter => :Type, - :minimum_level => 1, # Needs any level up - :level_up_proc => proc { |pkmn, parameter| - if pkmn.happiness >= 220 - next pkmn.moves.any? { |m| m && m.id > 0 && m.type == parameter } - end - } -}) - -GameData::Evolution.register({ - :id => :HappinessHoldItem, - :parameter => :Item, - :minimum_level => 1, # Needs any level up - :level_up_proc => proc { |pkmn, parameter| - next pkmn.item == parameter && pkmn.happiness >= 220 - }, - :after_evolution_proc => proc { |pkmn, new_species, parameter, evo_species| - next false if evo_species != new_species || !pkmn.hasItem?(parameter) - pkmn.item = nil # Item is now consumed - next true - } -}) - -GameData::Evolution.register({ - :id => :MaxHappiness, - :minimum_level => 1, # Needs any level up - :level_up_proc => proc { |pkmn, parameter| - next pkmn.happiness == 255 - } -}) - -GameData::Evolution.register({ - :id => :Beauty, # Feebas - :parameter => Integer, - :minimum_level => 1, # Needs any level up - :level_up_proc => proc { |pkmn, parameter| - next pkmn.beauty >= parameter - } -}) - -GameData::Evolution.register({ - :id => :HoldItem, - :parameter => :Item, - :minimum_level => 1, # Needs any level up - :level_up_proc => proc { |pkmn, parameter| - next pkmn.item == parameter - }, - :after_evolution_proc => proc { |pkmn, new_species, parameter, evo_species| - next false if evo_species != new_species || !pkmn.hasItem?(parameter) - pkmn.item = nil # Item is now consumed - next true - } -}) - -GameData::Evolution.register({ - :id => :HoldItemMale, - :parameter => :Item, - :minimum_level => 1, # Needs any level up - :level_up_proc => proc { |pkmn, parameter| - next pkmn.item == parameter && pkmn.male? - }, - :after_evolution_proc => proc { |pkmn, new_species, parameter, evo_species| - next false if evo_species != new_species || !pkmn.hasItem?(parameter) - pkmn.item = nil # Item is now consumed - next true - } -}) - -GameData::Evolution.register({ - :id => :HoldItemFemale, - :parameter => :Item, - :minimum_level => 1, # Needs any level up - :level_up_proc => proc { |pkmn, parameter| - next pkmn.item == parameter && pkmn.female? - }, - :after_evolution_proc => proc { |pkmn, new_species, parameter, evo_species| - next false if evo_species != new_species || !pkmn.hasItem?(parameter) - pkmn.item = nil # Item is now consumed - next true - } -}) - -GameData::Evolution.register({ - :id => :DayHoldItem, - :parameter => :Item, - :minimum_level => 1, # Needs any level up - :level_up_proc => proc { |pkmn, parameter| - next pkmn.item == parameter && PBDayNight.isDay? - }, - :after_evolution_proc => proc { |pkmn, new_species, parameter, evo_species| - next false if evo_species != new_species || !pkmn.hasItem?(parameter) - pkmn.item = nil # Item is now consumed - next true - } -}) - -GameData::Evolution.register({ - :id => :NightHoldItem, - :parameter => :Item, - :minimum_level => 1, # Needs any level up - :level_up_proc => proc { |pkmn, parameter| - next pkmn.item == parameter && PBDayNight.isNight? - }, - :after_evolution_proc => proc { |pkmn, new_species, parameter, evo_species| - next false if evo_species != new_species || !pkmn.hasItem?(parameter) - pkmn.item = nil # Item is now consumed - next true - } -}) - -GameData::Evolution.register({ - :id => :HoldItemHappiness, - :parameter => :Item, - :minimum_level => 1, # Needs any level up - :level_up_proc => proc { |pkmn, parameter| - next pkmn.item == parameter && pkmn.happiness >= 220 - }, - :after_evolution_proc => proc { |pkmn, new_species, parameter, evo_species| - next false if evo_species != new_species || !pkmn.hasItem?(parameter) - pkmn.item = nil # Item is now consumed - next true - } -}) - -GameData::Evolution.register({ - :id => :HasMove, - :parameter => :Move, - :minimum_level => 1, # Needs any level up - :level_up_proc => proc { |pkmn, parameter| - next pkmn.moves.any? { |m| m && m.id == parameter } - } -}) - -GameData::Evolution.register({ - :id => :HasMoveType, - :parameter => :Type, - :minimum_level => 1, # Needs any level up - :level_up_proc => proc { |pkmn, parameter| - next pkmn.moves.any? { |m| m && m.type == parameter } - } -}) - -GameData::Evolution.register({ - :id => :HasInParty, - :parameter => :Species, - :minimum_level => 1, # Needs any level up - :level_up_proc => proc { |pkmn, parameter| - next $Trainer.has_species?(parameter) - } -}) - -GameData::Evolution.register({ - :id => :Location, - :parameter => Integer, - :minimum_level => 1, # Needs any level up - :level_up_proc => proc { |pkmn, parameter| - next $game_map.map_id == parameter - } -}) - -GameData::Evolution.register({ - :id => :Region, - :parameter => Integer, - :minimum_level => 1, # Needs any level up - :level_up_proc => proc { |pkmn, parameter| - map_metadata = GameData::MapMetadata.try_get($game_map.map_id) - next map_metadata && map_metadata.town_map_position && - map_metadata.town_map_position[0] == parameter - } -}) - -#=============================================================================== -# Evolution methods that trigger when using an item on the Pokémon -#=============================================================================== -GameData::Evolution.register({ - :id => :Item, - :parameter => :Item, - :use_item_proc => proc { |pkmn, parameter, item| - next item == parameter - } -}) - -GameData::Evolution.register({ - :id => :ItemMale, - :parameter => :Item, - :use_item_proc => proc { |pkmn, parameter, item| - next item == parameter && pkmn.male? - } -}) - -GameData::Evolution.register({ - :id => :ItemFemale, - :parameter => :Item, - :use_item_proc => proc { |pkmn, parameter, item| - next item == parameter && pkmn.female? - } -}) - -GameData::Evolution.register({ - :id => :ItemDay, - :parameter => :Item, - :use_item_proc => proc { |pkmn, parameter, item| - next item == parameter && PBDayNight.isDay? - } -}) - -GameData::Evolution.register({ - :id => :ItemNight, - :parameter => :Item, - :use_item_proc => proc { |pkmn, parameter, item| - next item == parameter && PBDayNight.isNight? - } -}) - -GameData::Evolution.register({ - :id => :ItemHappiness, - :parameter => :Item, - :use_item_proc => proc { |pkmn, parameter, item| - next item == parameter && pkmn.happiness >= 220 - } -}) - -#=============================================================================== -# Evolution methods that trigger when the Pokémon is obtained in a trade -#=============================================================================== -GameData::Evolution.register({ - :id => :Trade, - :on_trade_proc => proc { |pkmn, parameter, other_pkmn| - next true - } -}) - -GameData::Evolution.register({ - :id => :TradeMale, - :on_trade_proc => proc { |pkmn, parameter, other_pkmn| - next pkmn.male? - } -}) - -GameData::Evolution.register({ - :id => :TradeFemale, - :on_trade_proc => proc { |pkmn, parameter, other_pkmn| - next pkmn.female? - } -}) - -GameData::Evolution.register({ - :id => :TradeDay, - :on_trade_proc => proc { |pkmn, parameter, other_pkmn| - next PBDayNight.isDay? - } -}) - -GameData::Evolution.register({ - :id => :TradeNight, - :on_trade_proc => proc { |pkmn, parameter, other_pkmn| - next PBDayNight.isNight? - } -}) - -GameData::Evolution.register({ - :id => :TradeItem, - :parameter => :Item, - :on_trade_proc => proc { |pkmn, parameter, other_pkmn| - next pkmn.item == parameter - }, - :after_evolution_proc => proc { |pkmn, new_species, parameter, evo_species| - next false if evo_species != new_species || !pkmn.hasItem?(parameter) - pkmn.item = nil # Item is now consumed - next true - } -}) - -GameData::Evolution.register({ - :id => :TradeSpecies, - :parameter => :Species, - :on_trade_proc => proc { |pkmn, parameter, other_pkmn| - next pkmn.species == parameter && !other_pkmn.hasItem?(:EVERSTONE) - } -}) diff --git a/Data/Scripts/010_Data/001_Hardcoded data/008_Stat.rb b/Data/Scripts/010_Data/001_Hardcoded data/008_Stat.rb deleted file mode 100644 index 07e6e4d80..000000000 --- a/Data/Scripts/010_Data/001_Hardcoded data/008_Stat.rb +++ /dev/null @@ -1,131 +0,0 @@ -# The id_number value determines which order the stats are iterated through by -# the "each" methods. -# The pbs_order value determines the order in which the stats are written in -# several PBS files, where base stats/IVs/EVs/EV yields are defined. Only stats -# which are yielded by the "each_main" method can have stat numbers defined in -# those places. The values of pbs_order defined below should start with 0 and -# increase without skipping any numbers. -module GameData - class Stat - attr_reader :id - attr_reader :id_number - attr_reader :real_name - attr_reader :real_name_brief - attr_reader :type - attr_reader :pbs_order - - DATA = {} - - extend ClassMethods - include InstanceMethods - - def self.load; end - def self.save; end - - # These stats are defined in PBS files, and should have the :pbs_order - # property. - def self.each_main - self.each { |s| yield s if [:main, :main_battle].include?(s.type) } - end - - def self.each_main_battle - self.each { |s| yield s if [:main_battle].include?(s.type) } - end - - # These stats have associated stat stages in battle. - def self.each_battle - self.each { |s| yield s if [:main_battle, :battle].include?(s.type) } - end - - def initialize(hash) - @id = hash[:id] - @id_number = hash[:id_number] || -1 - @real_name = hash[:name] || "Unnamed" - @real_name_brief = hash[:name_brief] || "None" - @type = hash[:type] || :none - @pbs_order = hash[:pbs_order] || -1 - end - - # @return [String] the translated name of this stat - def name - return _INTL(@real_name) - end - - # @return [String] the translated brief name of this stat - def name_brief - return _INTL(@real_name_brief) - end - end -end - -#=============================================================================== - -GameData::Stat.register({ - :id => :HP, - :id_number => 0, - :name => _INTL("HP"), - :name_brief => _INTL("HP"), - :type => :main, - :pbs_order => 0 -}) - -GameData::Stat.register({ - :id => :ATTACK, - :id_number => 1, - :name => _INTL("Attack"), - :name_brief => _INTL("Atk"), - :type => :main_battle, - :pbs_order => 1 -}) - -GameData::Stat.register({ - :id => :DEFENSE, - :id_number => 2, - :name => _INTL("Defense"), - :name_brief => _INTL("Def"), - :type => :main_battle, - :pbs_order => 2 -}) - -GameData::Stat.register({ - :id => :SPECIAL_ATTACK, - :id_number => 3, - :name => _INTL("Special Attack"), - :name_brief => _INTL("SpAtk"), - :type => :main_battle, - :pbs_order => 4 -}) - -GameData::Stat.register({ - :id => :SPECIAL_DEFENSE, - :id_number => 4, - :name => _INTL("Special Defense"), - :name_brief => _INTL("SpDef"), - :type => :main_battle, - :pbs_order => 5 -}) - -GameData::Stat.register({ - :id => :SPEED, - :id_number => 5, - :name => _INTL("Speed"), - :name_brief => _INTL("Spd"), - :type => :main_battle, - :pbs_order => 3 -}) - -GameData::Stat.register({ - :id => :ACCURACY, - :id_number => 6, - :name => _INTL("accuracy"), - :name_brief => _INTL("Acc"), - :type => :battle -}) - -GameData::Stat.register({ - :id => :EVASION, - :id_number => 7, - :name => _INTL("evasiveness"), - :name_brief => _INTL("Eva"), - :type => :battle -}) diff --git a/Data/Scripts/010_Data/001_Hardcoded data/009_Nature.rb b/Data/Scripts/010_Data/001_Hardcoded data/009_Nature.rb deleted file mode 100644 index f745ef21d..000000000 --- a/Data/Scripts/010_Data/001_Hardcoded data/009_Nature.rb +++ /dev/null @@ -1,200 +0,0 @@ -module GameData - class Nature - attr_reader :id - attr_reader :id_number - attr_reader :real_name - attr_reader :stat_changes - - DATA = {} - - extend ClassMethods - include InstanceMethods - - def self.load; end - def self.save; end - - def initialize(hash) - @id = hash[:id] - @id_number = hash[:id_number] || -1 - @real_name = hash[:name] || "Unnamed" - @stat_changes = hash[:stat_changes] || [] - end - - # @return [String] the translated name of this nature - def name - return _INTL(@real_name) - end - end -end - -#=============================================================================== - -GameData::Nature.register({ - :id => :HARDY, - :id_number => 0, - :name => _INTL("Hardy") -}) - -GameData::Nature.register({ - :id => :LONELY, - :id_number => 1, - :name => _INTL("Lonely"), - :stat_changes => [[:ATTACK, 10], [:DEFENSE, -10]] -}) - -GameData::Nature.register({ - :id => :BRAVE, - :id_number => 2, - :name => _INTL("Brave"), - :stat_changes => [[:ATTACK, 10], [:SPEED, -10]] -}) - -GameData::Nature.register({ - :id => :ADAMANT, - :id_number => 3, - :name => _INTL("Adamant"), - :stat_changes => [[:ATTACK, 10], [:SPECIAL_ATTACK, -10]] -}) - -GameData::Nature.register({ - :id => :NAUGHTY, - :id_number => 4, - :name => _INTL("Naughty"), - :stat_changes => [[:ATTACK, 10], [:SPECIAL_DEFENSE, -10]] -}) - -GameData::Nature.register({ - :id => :BOLD, - :id_number => 5, - :name => _INTL("Bold"), - :stat_changes => [[:DEFENSE, 10], [:ATTACK, -10]] -}) - -GameData::Nature.register({ - :id => :DOCILE, - :id_number => 6, - :name => _INTL("Docile") -}) - -GameData::Nature.register({ - :id => :RELAXED, - :id_number => 7, - :name => _INTL("Relaxed"), - :stat_changes => [[:DEFENSE, 10], [:SPEED, -10]] -}) - -GameData::Nature.register({ - :id => :IMPISH, - :id_number => 8, - :name => _INTL("Impish"), - :stat_changes => [[:DEFENSE, 10], [:SPECIAL_ATTACK, -10]] -}) - -GameData::Nature.register({ - :id => :LAX, - :id_number => 9, - :name => _INTL("Lax"), - :stat_changes => [[:DEFENSE, 10], [:SPECIAL_DEFENSE, -10]] -}) - -GameData::Nature.register({ - :id => :TIMID, - :id_number => 10, - :name => _INTL("Timid"), - :stat_changes => [[:SPEED, 10], [:ATTACK, -10]] -}) - -GameData::Nature.register({ - :id => :HASTY, - :id_number => 11, - :name => _INTL("Hasty"), - :stat_changes => [[:SPEED, 10], [:DEFENSE, -10]] -}) - -GameData::Nature.register({ - :id => :SERIOUS, - :id_number => 12, - :name => _INTL("Serious") -}) - -GameData::Nature.register({ - :id => :JOLLY, - :id_number => 13, - :name => _INTL("Jolly"), - :stat_changes => [[:SPEED, 10], [:SPECIAL_ATTACK, -10]] -}) - -GameData::Nature.register({ - :id => :NAIVE, - :id_number => 14, - :name => _INTL("Naive"), - :stat_changes => [[:SPEED, 10], [:SPECIAL_DEFENSE, -10]] -}) - -GameData::Nature.register({ - :id => :MODEST, - :id_number => 15, - :name => _INTL("Modest"), - :stat_changes => [[:SPECIAL_ATTACK, 10], [:ATTACK, -10]] -}) - -GameData::Nature.register({ - :id => :MILD, - :id_number => 16, - :name => _INTL("Mild"), - :stat_changes => [[:SPECIAL_ATTACK, 10], [:DEFENSE, -10]] -}) - -GameData::Nature.register({ - :id => :QUIET, - :id_number => 17, - :name => _INTL("Quiet"), - :stat_changes => [[:SPECIAL_ATTACK, 10], [:SPEED, -10]] -}) - -GameData::Nature.register({ - :id => :BASHFUL, - :id_number => 18, - :name => _INTL("Bashful") -}) - -GameData::Nature.register({ - :id => :RASH, - :id_number => 19, - :name => _INTL("Rash"), - :stat_changes => [[:SPECIAL_ATTACK, 10], [:SPECIAL_DEFENSE, -10]] -}) - -GameData::Nature.register({ - :id => :CALM, - :id_number => 20, - :name => _INTL("Calm"), - :stat_changes => [[:SPECIAL_DEFENSE, 10], [:ATTACK, -10]] -}) - -GameData::Nature.register({ - :id => :GENTLE, - :id_number => 21, - :name => _INTL("Gentle"), - :stat_changes => [[:SPECIAL_DEFENSE, 10], [:DEFENSE, -10]] -}) - -GameData::Nature.register({ - :id => :SASSY, - :id_number => 22, - :name => _INTL("Sassy"), - :stat_changes => [[:SPECIAL_DEFENSE, 10], [:SPEED, -10]] -}) - -GameData::Nature.register({ - :id => :CAREFUL, - :id_number => 23, - :name => _INTL("Careful"), - :stat_changes => [[:SPECIAL_DEFENSE, 10], [:SPECIAL_ATTACK, -10]] -}) - -GameData::Nature.register({ - :id => :QUIRKY, - :id_number => 24, - :name => _INTL("Quirky") -}) diff --git a/Data/Scripts/010_Data/001_Hardcoded data/010_Status.rb b/Data/Scripts/010_Data/001_Hardcoded data/010_Status.rb deleted file mode 100644 index 0b852bd04..000000000 --- a/Data/Scripts/010_Data/001_Hardcoded data/010_Status.rb +++ /dev/null @@ -1,79 +0,0 @@ -# NOTE: The id_number is only used to determine the order of the status icons in -# the graphics containing them. Number 0 (:NONE) is ignored; they start -# with status 1. -# "Graphics/Pictures/statuses.png" also contains icons for being fainted -# and for having Pokérus, in that order, at the bottom of the graphic. -# "Graphics/Pictures/Battle/icon_statuses.png" also contains an icon for -# bad poisoning (toxic), at the bottom of the graphic. -# Both graphics automatically handle varying numbers of defined statuses. -module GameData - class Status - attr_reader :id - attr_reader :id_number - attr_reader :real_name - attr_reader :animation - - DATA = {} - - extend ClassMethods - include InstanceMethods - - def self.load; end - def self.save; end - - def initialize(hash) - @id = hash[:id] - @id_number = hash[:id_number] - @real_name = hash[:name] || "Unnamed" - @animation = hash[:animation] - end - - # @return [String] the translated name of this status condition - def name - return _INTL(@real_name) - end - end -end - -#=============================================================================== - -GameData::Status.register({ - :id => :NONE, - :id_number => 0, - :name => _INTL("None") -}) - -GameData::Status.register({ - :id => :SLEEP, - :id_number => 1, - :name => _INTL("Sleep"), - :animation => "Sleep" -}) - -GameData::Status.register({ - :id => :POISON, - :id_number => 2, - :name => _INTL("Poison"), - :animation => "Poison" -}) - -GameData::Status.register({ - :id => :BURN, - :id_number => 3, - :name => _INTL("Burn"), - :animation => "Burn" -}) - -GameData::Status.register({ - :id => :PARALYSIS, - :id_number => 4, - :name => _INTL("Paralysis"), - :animation => "Paralysis" -}) - -GameData::Status.register({ - :id => :FROZEN, - :id_number => 5, - :name => _INTL("Frozen"), - :animation => "Frozen" -}) diff --git a/Data/Scripts/010_Data/001_Hardcoded data/011_TerrainTag.rb b/Data/Scripts/010_Data/001_Hardcoded data/011_TerrainTag.rb deleted file mode 100644 index bacc882cc..000000000 --- a/Data/Scripts/010_Data/001_Hardcoded data/011_TerrainTag.rb +++ /dev/null @@ -1,289 +0,0 @@ -module GameData - class TerrainTag - attr_reader :id - attr_reader :id_number - attr_reader :real_name - attr_reader :can_surf - attr_reader :waterfall # The main part only, not the crest - attr_reader :waterfall_crest - attr_reader :can_fish - attr_reader :can_dive - attr_reader :deep_bush - attr_reader :shows_grass_rustle - attr_reader :land_wild_encounters - attr_reader :double_wild_encounters - attr_reader :battle_environment - attr_reader :ledge - attr_reader :ice - attr_reader :bridge - attr_reader :waterCurrent - attr_reader :shows_reflections - attr_reader :must_walk - attr_reader :ignore_passability - - #oricorio - attr_reader :flowerRed - attr_reader :flowerPink - attr_reader :flowerYellow - attr_reader :flowerBlue - attr_reader :flower - attr_reader :trashcan - attr_reader :sharpedoObstacle - - DATA = {} - - extend ClassMethods - include InstanceMethods - - # @param other [Symbol, self, String, Integer] - # @return [self] - def self.try_get(other) - return self.get(:None) if other.nil? - validate other => [Symbol, self, String, Integer] - return other if other.is_a?(self) - other = other.to_sym if other.is_a?(String) - return (self::DATA.has_key?(other)) ? self::DATA[other] : self.get(:None) - end - - def self.load; end - - def self.save; end - - def initialize(hash) - @id = hash[:id] - @id_number = hash[:id_number] - @real_name = hash[:id].to_s || "Unnamed" - @can_surf = hash[:can_surf] || false - @waterfall = hash[:waterfall] || false - @waterfall_crest = hash[:waterfall_crest] || false - @can_fish = hash[:can_fish] || false - @can_dive = hash[:can_dive] || false - @deep_bush = hash[:deep_bush] || false - @shows_grass_rustle = hash[:shows_grass_rustle] || false - @land_wild_encounters = hash[:land_wild_encounters] || false - @double_wild_encounters = hash[:double_wild_encounters] || false - @battle_environment = hash[:battle_environment] - @ledge = hash[:ledge] || false - @ice = hash[:ice] || false - @waterCurrent = hash[:waterCurrent] || false - @bridge = hash[:bridge] || false - @shows_reflections = false #= hash[:shows_reflections] || false - @must_walk = hash[:must_walk] || false - @ignore_passability = hash[:ignore_passability] || false - - @flowerRed = hash[:flowerRed] || false - @flowerYellow = hash[:flowerYellow] || false - @flowerPink = hash[:flowerPink] || false - @flowerBlue = hash[:flowerBlue] || false - @flower = hash[:flower] || false - @trashcan = hash[:trashcan] || false - @sharpedoObstacle = hash[:sharpedoObstacle] || false - - end - - def can_surf_freely - return @can_surf && !@waterfall && !@waterfall_crest - end - end -end - -#=============================================================================== - -GameData::TerrainTag.register({ - :id => :None, - :id_number => 0 - }) - -GameData::TerrainTag.register({ - :id => :Ledge, - :id_number => 1, - :ledge => true - }) - -GameData::TerrainTag.register({ - :id => :Grass, - :id_number => 2, - :shows_grass_rustle => true, - :land_wild_encounters => true, - :battle_environment => :Grass - }) - -GameData::TerrainTag.register({ - :id => :Sand, - :id_number => 3, - :battle_environment => :Sand - }) - -GameData::TerrainTag.register({ - :id => :Rock, - :id_number => 15, - :battle_environment => :Rock - }) - -GameData::TerrainTag.register({ - :id => :DeepWater, - :id_number => 5, - :can_surf => true, - :can_fish => true, - :can_dive => true, - :battle_environment => :MovingWater - }) - -GameData::TerrainTag.register({ - :id => :WaterCurrent, - :id_number => 6, - :can_surf => true, - :can_fish => true, - :waterCurrent => true, - :battle_environment => :MovingWater - }) - -GameData::TerrainTag.register({ - :id => :StillWater, - :id_number => 17, - :can_surf => true, - :can_fish => true, - :battle_environment => :StillWater - #:shows_reflections => true - }) - -GameData::TerrainTag.register({ - :id => :Water, - :id_number => 7, - :can_surf => true, - :can_fish => true, - :battle_environment => :MovingWater - }) - -GameData::TerrainTag.register({ - :id => :Waterfall, - :id_number => 8, - :can_surf => true, - :waterfall => true - }) - -GameData::TerrainTag.register({ - :id => :WaterfallCrest, - :id_number => 9, - :can_surf => true, - :can_fish => true, - :waterfall_crest => true - }) - -GameData::TerrainTag.register({ - :id => :TallGrass, - :id_number => 10, - :deep_bush => true, - :land_wild_encounters => true, - :double_wild_encounters => true, - :battle_environment => :TallGrass, - :must_walk => true - }) - -GameData::TerrainTag.register({ - :id => :UnderwaterGrass, - :id_number => 11, - :land_wild_encounters => true - }) - -GameData::TerrainTag.register({ - :id => :Ice, - :id_number => 12, - :battle_environment => :Ice, - :ice => true, - :must_walk => true - }) - -GameData::TerrainTag.register({ - :id => :Neutral, - :id_number => 13, - :ignore_passability => true - }) - -# NOTE: This is referenced by ID in an Events.onStepTakenFieldMovement proc that -# adds soot to the Soot Sack if the player walks over one of these tiles. -GameData::TerrainTag.register({ - :id => :SootGrass, - :id_number => 14, - :shows_grass_rustle => true, - :land_wild_encounters => true, - :battle_environment => :Grass - }) - -GameData::TerrainTag.register({ - :id => :Bridge, - :id_number => 4, - :bridge => true - }) - -GameData::TerrainTag.register({ - :id => :Puddle, - :id_number => 16, - :battle_environment => :Puddle, - :shows_reflections => true - }) - -GameData::TerrainTag.register({ - :id => :FlowerRed, - :id_number => 17, - :flowerRed => true, - :flower => true - }) -GameData::TerrainTag.register({ - :id => :FlowerYellow, - :id_number => 18, - :flowerYellow => true, - :flower => true - }) -GameData::TerrainTag.register({ - :id => :FlowerPink, - :id_number => 19, - :flowerPink => true, - :flower => true - }) -GameData::TerrainTag.register({ - :id => :FlowerBlue, - :id_number => 20, - :flowerBlue => true, - :flower => true - }) -GameData::TerrainTag.register({ - :id => :FlowerOther, - :id_number => 21, - :flower => true - }) -GameData::TerrainTag.register({ - :id => :Trashcan, - :id_number => 22, - :trashcan => true - }) - -GameData::TerrainTag.register({ - :id => :SharpedoObstacle, - :id_number => 23, - :sharpedoObstacle => true - }) - -GameData::TerrainTag.register({ - :id => :Grass_alt1, - :id_number => 24, - :shows_grass_rustle => true, - :land_wild_encounters => true, - :battle_environment => :Grass - }) - -GameData::TerrainTag.register({ - :id => :Grass_alt2, - :id_number => 25, - :shows_grass_rustle => true, - :land_wild_encounters => true, - :battle_environment => :Grass - }) - -GameData::TerrainTag.register({ - :id => :Grass_alt3, - :id_number => 26, - :shows_grass_rustle => true, - :land_wild_encounters => true, - :battle_environment => :Grass - }) \ No newline at end of file diff --git a/Data/Scripts/010_Data/001_Hardcoded data/012_Weather.rb b/Data/Scripts/010_Data/001_Hardcoded data/012_Weather.rb deleted file mode 100644 index 75f5d49b7..000000000 --- a/Data/Scripts/010_Data/001_Hardcoded data/012_Weather.rb +++ /dev/null @@ -1,173 +0,0 @@ -# Category has the following effects: -# - Determines the in-battle weather. -# - Some abilities reduce the encounter rate in certain categories of weather. -# - Some evolution methods check the current weather's category. -# - The :Rain category treats the last listed particle graphic as a water splash rather -# than a raindrop, which behaves differently. -# - :Rain auto-waters berry plants. -# Delta values are per second. -# For the tone_proc, strength goes from 0 to RPG::Weather::MAX_SPRITES (60) and -# will typically be the maximum. -module GameData - class - Weather - attr_reader :id - attr_reader :id_number - attr_reader :real_name - attr_reader :category # :None, :Rain, :Hail, :Sandstorm, :Sun, :Fog - attr_reader :graphics # [[particle file names], [tile file names]] - attr_reader :particle_delta_x - attr_reader :particle_delta_y - attr_reader :particle_delta_opacity - attr_reader :tile_delta_x - attr_reader :tile_delta_y - attr_reader :tone_proc - - DATA = {} - - extend ClassMethods - include InstanceMethods - - def self.load; end - def self.save; end - - def initialize(hash) - @id = hash[:id] - @id_number = hash[:id_number] - @real_name = hash[:id].to_s || "Unnamed" - @category = hash[:category] || :None - @particle_delta_x = hash[:particle_delta_x] || 0 - @particle_delta_y = hash[:particle_delta_y] || 0 - @particle_delta_opacity = hash[:particle_delta_opacity] || 0 - @tile_delta_x = hash[:tile_delta_x] || 0 - @tile_delta_y = hash[:tile_delta_y] || 0 - @graphics = hash[:graphics] || [] - @tone_proc = hash[:tone_proc] - end - - def has_particles? - return @graphics[0] && @graphics[0].length > 0 - end - - def has_tiles? - return @graphics[1] && @graphics[1].length > 0 - end - - def tone(strength) - return (@tone_proc) ? @tone_proc.call(strength) : Tone.new(0, 0, 0, 0) - end - end -end - -#=============================================================================== - -GameData::Weather.register({ - :id => :None, - :id_number => 0 # Must be 0 (preset RMXP weather) -}) - -GameData::Weather.register({ - :id => :Rain, - :id_number => 1, # Must be 1 (preset RMXP weather) - :category => :Rain, - :graphics => [["rain_1", "rain_2", "rain_3", "rain_4"]], # Last is splash - :particle_delta_x => -1200, - :particle_delta_y => 4800, - :tone_proc => proc { |strength| - next Tone.new(-strength * 3 / 4, -strength * 3 / 4, -strength * 3 / 4, 10) - } -}) - -# NOTE: This randomly flashes the screen in RPG::Weather#update. -GameData::Weather.register({ - :id => :Storm, - :id_number => 2, # Must be 2 (preset RMXP weather) - :category => :Rain, - :graphics => [["storm_1", "storm_2", "storm_3", "storm_4"]], # Last is splash - :particle_delta_x => -4800, - :particle_delta_y => 4800, - :tone_proc => proc { |strength| - next Tone.new(-strength * 3 / 2, -strength * 3 / 2, -strength * 3 / 2, 20) - } -}) - -# NOTE: This alters the movement of snow particles in RPG::Weather#update_sprite_position. -GameData::Weather.register({ - :id => :Snow, - :id_number => 3, # Must be 3 (preset RMXP weather) - :category => :Hail, - :graphics => [["hail_1", "hail_2", "hail_3"]], - :particle_delta_x => -240, - :particle_delta_y => 240, - :tone_proc => proc { |strength| - next Tone.new(strength / 2, strength / 2, strength / 2, 0) - } -}) - -GameData::Weather.register({ - :id => :Blizzard, - :id_number => 4, - :category => :Hail, - :graphics => [["blizzard_1", "blizzard_2", "blizzard_3", "blizzard_4"], ["blizzard_tile"]], - :particle_delta_x => -960, - :particle_delta_y => 240, - :tile_delta_x => -1440, - :tile_delta_y => 720, - :tone_proc => proc { |strength| - next Tone.new(strength * 3 / 4, strength * 3 / 4, strength * 3 / 4, 0) - } -}) - -GameData::Weather.register({ - :id => :Sandstorm, - :id_number => 5, - :category => :Sandstorm, - :graphics => [["sandstorm_1", "sandstorm_2", "sandstorm_3", "sandstorm_4"], ["sandstorm_tile"]], - :particle_delta_x => -1200, - :particle_delta_y => 640, - :tile_delta_x => -720, - :tile_delta_y => 360, - :tone_proc => proc { |strength| - next Tone.new(strength / 2, 0, -strength / 2, 0) - } -}) - -GameData::Weather.register({ - :id => :HeavyRain, - :id_number => 6, - :category => :Rain, - :graphics => [["storm_1", "storm_2", "storm_3", "storm_4"]], # Last is splash - :particle_delta_x => -4800, - :particle_delta_y => 4800, - :tone_proc => proc { |strength| - next Tone.new(-strength * 3 / 2, -strength * 3 / 2, -strength * 3 / 2, 20) - } -}) - -# NOTE: This alters the screen tone in RPG::Weather#update_screen_tone. -GameData::Weather.register({ - :id => :Sunny, - :id_number => 7, - :category => :Sun, - :tone_proc => proc { |strength| - next Tone.new(64, 64, 32, 0) - } -}) - -GameData::Weather.register({ - :id => :Fog, - :category => :Fog, - :id_number => 8, - :tile_delta_x => -32, - :tile_delta_y => 0, - :graphics => [nil, ["fog_tile"]] -}) - -GameData::Weather.register({ - :id => :StrongWinds, - :category => :StrongWinds, - :id_number => 9, - :tile_delta_x => -1200, - :tile_delta_y => 0, - :graphics => [nil, ["strong_winds"]] -}) diff --git a/Data/Scripts/010_Data/001_Hardcoded data/013_EncounterType.rb b/Data/Scripts/010_Data/001_Hardcoded data/013_EncounterType.rb deleted file mode 100644 index bbed7e1a2..000000000 --- a/Data/Scripts/010_Data/001_Hardcoded data/013_EncounterType.rb +++ /dev/null @@ -1,219 +0,0 @@ -module GameData - - class EncounterType - attr_reader :id - attr_reader :real_name - attr_reader :type # :land, :cave, :water, :fishing, :contest, :none - attr_reader :trigger_chance - attr_reader :old_slots - - DATA = {} - - extend ClassMethodsSymbols - include InstanceMethods - - def self.load; end - def self.save; end - - def initialize(hash) - @id = hash[:id] - @real_name = hash[:id].to_s || "Unnamed" - @type = hash[:type] || :none - @trigger_chance = hash[:trigger_chance] || 0 - @old_slots = hash[:old_slots] - end - end -end - -#=============================================================================== - -GameData::EncounterType.register({ - :id => :Land, - :type => :land, - :trigger_chance => 21, - :old_slots => [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] -}) - -GameData::EncounterType.register({ - :id => :Land1, - :type => :land, - :trigger_chance => 21, - :old_slots => [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] - }) - -GameData::EncounterType.register({ - :id => :Land2, - :type => :land, - :trigger_chance => 21, - :old_slots => [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] - }) - -GameData::EncounterType.register({ - :id => :Land3, - :type => :land, - :trigger_chance => 21, - :old_slots => [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] - }) - -GameData::EncounterType.register({ - :id => :LandDay, - :type => :land, - :trigger_chance => 21, - :old_slots => [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] -}) - -GameData::EncounterType.register({ - :id => :LandNight, - :type => :land, - :trigger_chance => 21, - :old_slots => [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] -}) - -GameData::EncounterType.register({ - :id => :LandMorning, - :type => :land, - :trigger_chance => 21, - :old_slots => [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] -}) - -GameData::EncounterType.register({ - :id => :LandAfternoon, - :type => :land, - :trigger_chance => 21, - :old_slots => [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] -}) - -GameData::EncounterType.register({ - :id => :LandEvening, - :type => :land, - :trigger_chance => 21, - :old_slots => [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] -}) - -GameData::EncounterType.register({ - :id => :Cave, - :type => :cave, - :trigger_chance => 5, - :old_slots => [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] -}) - -GameData::EncounterType.register({ - :id => :CaveDay, - :type => :cave, - :trigger_chance => 5, - :old_slots => [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] -}) - -GameData::EncounterType.register({ - :id => :CaveNight, - :type => :cave, - :trigger_chance => 5, - :old_slots => [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] -}) - -GameData::EncounterType.register({ - :id => :CaveMorning, - :type => :cave, - :trigger_chance => 5, - :old_slots => [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] -}) - -GameData::EncounterType.register({ - :id => :CaveAfternoon, - :type => :cave, - :trigger_chance => 5, - :old_slots => [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] -}) - -GameData::EncounterType.register({ - :id => :CaveEvening, - :type => :cave, - :trigger_chance => 5, - :old_slots => [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] -}) - -GameData::EncounterType.register({ - :id => :Water, - :type => :water, - :trigger_chance => 2, - :old_slots => [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] -}) - -GameData::EncounterType.register({ - :id => :WaterDay, - :type => :water, - :trigger_chance => 2, - :old_slots => [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] -}) - -GameData::EncounterType.register({ - :id => :WaterNight, - :type => :water, - :trigger_chance => 2, - :old_slots => [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] -}) - -GameData::EncounterType.register({ - :id => :WaterMorning, - :type => :water, - :trigger_chance => 2, - :old_slots => [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] -}) - -GameData::EncounterType.register({ - :id => :WaterAfternoon, - :type => :water, - :trigger_chance => 2, - :old_slots => [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] -}) - -GameData::EncounterType.register({ - :id => :WaterEvening, - :type => :water, - :trigger_chance => 2, - :old_slots => [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] -}) - -GameData::EncounterType.register({ - :id => :OldRod, - :type => :fishing, - :old_slots => [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] -}) - -GameData::EncounterType.register({ - :id => :GoodRod, - :type => :fishing, - :old_slots => [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] -}) - -GameData::EncounterType.register({ - :id => :SuperRod, - :type => :fishing, - :old_slots => [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] -}) - -GameData::EncounterType.register({ - :id => :RockSmash, - :type => :none, - :trigger_chance => 50, - :old_slots => [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] -}) - -GameData::EncounterType.register({ - :id => :HeadbuttLow, - :type => :none, - :old_slots => [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] -}) - -GameData::EncounterType.register({ - :id => :HeadbuttHigh, - :type => :none, - :old_slots => [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] -}) - -GameData::EncounterType.register({ - :id => :BugContest, - :type => :contest, - :trigger_chance => 21, - :old_slots => [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] -}) diff --git a/Data/Scripts/010_Data/001_Hardcoded data/014_Environment.rb b/Data/Scripts/010_Data/001_Hardcoded data/014_Environment.rb deleted file mode 100644 index c7923ac01..000000000 --- a/Data/Scripts/010_Data/001_Hardcoded data/014_Environment.rb +++ /dev/null @@ -1,131 +0,0 @@ -module GameData - class Environment - attr_reader :id - attr_reader :real_name - attr_reader :battle_base - - DATA = {} - - extend ClassMethodsSymbols - include InstanceMethods - - def self.load; end - def self.save; end - - def initialize(hash) - @id = hash[:id] - @real_name = hash[:name] || "Unnamed" - @battle_base = hash[:battle_base] - end - - # @return [String] the translated name of this environment - def name - return _INTL(@real_name) - end - end -end - -#=============================================================================== - -GameData::Environment.register({ - :id => :None, - :name => _INTL("None") -}) - -GameData::Environment.register({ - :id => :Grass, - :name => _INTL("Grass"), - :battle_base => "grass" -}) - -GameData::Environment.register({ - :id => :TallGrass, - :name => _INTL("Tall grass"), - :battle_base => "grass" -}) - -GameData::Environment.register({ - :id => :MovingWater, - :name => _INTL("Moving water"), - :battle_base => "water" -}) - -GameData::Environment.register({ - :id => :StillWater, - :name => _INTL("Still water"), - :battle_base => "water" -}) - -GameData::Environment.register({ - :id => :Puddle, - :name => _INTL("Puddle"), - :battle_basec => "puddle" -}) - -GameData::Environment.register({ - :id => :Underwater, - :name => _INTL("Underwater") -}) - -GameData::Environment.register({ - :id => :Cave, - :name => _INTL("Cave") -}) - -GameData::Environment.register({ - :id => :Rock, - :name => _INTL("Rock") -}) - -GameData::Environment.register({ - :id => :Sand, - :name => _INTL("Sand"), - :battle_base => "sand" -}) - -GameData::Environment.register({ - :id => :Forest, - :name => _INTL("Forest") -}) - -GameData::Environment.register({ - :id => :ForestGrass, - :name => _INTL("Forest grass"), - :battle_base => "grass" -}) - -GameData::Environment.register({ - :id => :Snow, - :name => _INTL("Snow") -}) - -GameData::Environment.register({ - :id => :Ice, - :name => _INTL("Ice"), - :battle_base => "ice" -}) - -GameData::Environment.register({ - :id => :Volcano, - :name => _INTL("Volcano") -}) - -GameData::Environment.register({ - :id => :Graveyard, - :name => _INTL("Graveyard") -}) - -GameData::Environment.register({ - :id => :Sky, - :name => _INTL("Sky") -}) - -GameData::Environment.register({ - :id => :Space, - :name => _INTL("Space") -}) - -GameData::Environment.register({ - :id => :UltraSpace, - :name => _INTL("Ultra Space") -}) diff --git a/Data/Scripts/010_Data/001_Hardcoded data/015_BattleWeather.rb b/Data/Scripts/010_Data/001_Hardcoded data/015_BattleWeather.rb deleted file mode 100644 index 27e7eb5e3..000000000 --- a/Data/Scripts/010_Data/001_Hardcoded data/015_BattleWeather.rb +++ /dev/null @@ -1,81 +0,0 @@ -module GameData - class BattleWeather - attr_reader :id - attr_reader :real_name - attr_reader :animation - - DATA = {} - - extend ClassMethodsSymbols - include InstanceMethods - - def self.load; end - def self.save; end - - def initialize(hash) - @id = hash[:id] - @real_name = hash[:name] || "Unnamed" - @animation = hash[:animation] - end - - # @return [String] the translated name of this battle weather - def name - return _INTL(@real_name) - end - end -end - -#=============================================================================== - -GameData::BattleWeather.register({ - :id => :None, - :name => _INTL("None") -}) - -GameData::BattleWeather.register({ - :id => :Sun, - :name => _INTL("Sun"), - :animation => "Sun" -}) - -GameData::BattleWeather.register({ - :id => :Rain, - :name => _INTL("Rain"), - :animation => "Rain" -}) - -GameData::BattleWeather.register({ - :id => :Sandstorm, - :name => _INTL("Sandstorm"), - :animation => "Sandstorm" -}) - -GameData::BattleWeather.register({ - :id => :Hail, - :name => _INTL("Hail"), - :animation => "Hail" -}) - -GameData::BattleWeather.register({ - :id => :HarshSun, - :name => _INTL("Harsh Sun"), - :animation => "HarshSun" -}) - -GameData::BattleWeather.register({ - :id => :HeavyRain, - :name => _INTL("Heavy Rain"), - :animation => "HeavyRain" -}) - -GameData::BattleWeather.register({ - :id => :StrongWinds, - :name => _INTL("Strong Winds"), - :animation => "StrongWinds" -}) - -GameData::BattleWeather.register({ - :id => :ShadowSky, - :name => _INTL("Shadow Sky"), - :animation => "ShadowSky" -}) diff --git a/Data/Scripts/010_Data/001_Hardcoded data/016_BattleTerrain.rb b/Data/Scripts/010_Data/001_Hardcoded data/016_BattleTerrain.rb deleted file mode 100644 index 5a8f99c3f..000000000 --- a/Data/Scripts/010_Data/001_Hardcoded data/016_BattleTerrain.rb +++ /dev/null @@ -1,58 +0,0 @@ -# These are in-battle terrain effects caused by moves like Electric Terrain. -module GameData - class BattleTerrain - attr_reader :id - attr_reader :real_name - attr_reader :animation - - DATA = {} - - extend ClassMethodsSymbols - include InstanceMethods - - def self.load; end - def self.save; end - - def initialize(hash) - @id = hash[:id] - @real_name = hash[:name] || "Unnamed" - @animation = hash[:animation] - end - - # @return [String] the translated name of this battle terrain - def name - return _INTL(@real_name) - end - end -end - -#=============================================================================== - -GameData::BattleTerrain.register({ - :id => :None, - :name => _INTL("None") -}) - -GameData::BattleTerrain.register({ - :id => :Electric, - :name => _INTL("Electric"), - :animation => "ElectricTerrain" -}) - -GameData::BattleTerrain.register({ - :id => :Grassy, - :name => _INTL("Grassy"), - :animation => "GrassyTerrain" -}) - -GameData::BattleTerrain.register({ - :id => :Misty, - :name => _INTL("Misty"), - :animation => "MistyTerrain" -}) - -GameData::BattleTerrain.register({ - :id => :Psychic, - :name => _INTL("Psychic"), - :animation => "PsychicTerrain" -}) diff --git a/Data/Scripts/010_Data/001_Hardcoded data/017_Target.rb b/Data/Scripts/010_Data/001_Hardcoded data/017_Target.rb deleted file mode 100644 index 1eea4e43f..000000000 --- a/Data/Scripts/010_Data/001_Hardcoded data/017_Target.rb +++ /dev/null @@ -1,194 +0,0 @@ -# NOTE: If adding a new target, you will need to add code in several places to -# make them work properly: -# - def pbFindTargets -# - def pbMoveCanTarget? -# - def pbCreateTargetTexts -# - def pbFirstTarget -# - def pbTargetsMultiple? -module GameData - class Target - attr_reader :id - attr_reader :id_number - attr_reader :real_name - attr_reader :num_targets # 0, 1 or 2 (meaning 2+) - attr_reader :targets_foe # Is able to target one or more foes - attr_reader :targets_all # Crafty Shield can't protect from these moves - attr_reader :affects_foe_side # Pressure also affects these moves - attr_reader :long_range # Hits non-adjacent targets - - DATA = {} - - extend ClassMethods - include InstanceMethods - - def self.load; end - def self.save; end - - def initialize(hash) - @id = hash[:id] - @real_name = hash[:name] || "Unnamed" - @num_targets = hash[:num_targets] || 0 - @targets_foe = hash[:targets_foe] || false - @targets_all = hash[:targets_all] || false - @affects_foe_side = hash[:affects_foe_side] || false - @long_range = hash[:long_range] || false - end - - # @return [String] the translated name of this target - def name - return _INTL(@real_name) - end - - def can_choose_distant_target? - return @num_targets == 1 && @long_range - end - - def can_target_one_foe? - return @num_targets == 1 && @targets_foe - end - end -end - -#=============================================================================== - -# Bide, Counter, Metal Burst, Mirror Coat (calculate a target) -GameData::Target.register({ - :id => :None, - :id_number => 1, - :name => _INTL("None") -}) - -GameData::Target.register({ - :id => :User, - :id_number => 10, - :name => _INTL("User") -}) - -# Aromatic Mist, Helping Hand, Hold Hands -GameData::Target.register({ - :id => :NearAlly, - :id_number => 100, - :name => _INTL("Near Ally"), - :num_targets => 1 -}) - -# Acupressure -GameData::Target.register({ - :id => :UserOrNearAlly, - :id_number => 200, - :name => _INTL("User or Near Ally"), - :num_targets => 1 -}) - -# Aromatherapy, Gear Up, Heal Bell, Life Dew, Magnetic Flux, Howl (in Gen 8+) -GameData::Target.register({ - :id => :UserAndAllies, - :id_number => 5, - :name => _INTL("User and Allies"), - :num_targets => 2, - :long_range => true -}) - -# Me First -GameData::Target.register({ - :id => :NearFoe, - :id_number => 400, - :name => _INTL("Near Foe"), - :num_targets => 1, - :targets_foe => true -}) - -# Petal Dance, Outrage, Struggle, Thrash, Uproar -GameData::Target.register({ - :id => :RandomNearFoe, - :id_number => 2, - :name => _INTL("Random Near Foe"), - :num_targets => 1, - :targets_foe => true -}) - -GameData::Target.register({ - :id => :AllNearFoes, - :id_number => 4, - :name => _INTL("All Near Foes"), - :num_targets => 2, - :targets_foe => true -}) - -# For throwing a Poké Ball -GameData::Target.register({ - :id => :Foe, - :id_number => 9, - :name => _INTL("Foe"), - :num_targets => 1, - :targets_foe => true, - :long_range => true -}) - -# Unused -GameData::Target.register({ - :id => :AllFoes, - :id_number => 6, - :name => _INTL("All Foes"), - :num_targets => 2, - :targets_foe => true, - :long_range => true -}) - -GameData::Target.register({ - :id => :NearOther, - :id_number => 0, - :name => _INTL("Near Other"), - :num_targets => 1, - :targets_foe => true -}) - -GameData::Target.register({ - :id => :AllNearOthers, - :id_number => 8, - :name => _INTL("All Near Others"), - :num_targets => 2, - :targets_foe => true -}) - -# Most Flying-type moves, pulse moves (hits non-near targets) -GameData::Target.register({ - :id => :Other, - :id_number => 3, - :name => _INTL("Other"), - :num_targets => 1, - :targets_foe => true, - :long_range => true -}) - -# Flower Shield, Perish Song, Rototiller, Teatime -GameData::Target.register({ - :id => :AllBattlers, - :id_number => 7, - :name => _INTL("All Battlers"), - :num_targets => 2, - :targets_foe => true, - :targets_all => true, - :long_range => true -}) - -GameData::Target.register({ - :id => :UserSide, - :id_number => 40, - :name => _INTL("User Side") -}) - -# Entry hazards -GameData::Target.register({ - :id => :FoeSide, - :id_number => 80, - :name => _INTL("Foe Side"), - :affects_foe_side => true -}) - -GameData::Target.register({ - :id => :BothSides, - :id_number => 20, - :name => _INTL("Both Sides"), - :affects_foe_side => true -}) diff --git a/Data/Scripts/010_Data/002_PBS data/001_MiscPBSData.rb b/Data/Scripts/010_Data/002_PBS data/001_MiscPBSData.rb deleted file mode 100644 index f60186d91..000000000 --- a/Data/Scripts/010_Data/002_PBS data/001_MiscPBSData.rb +++ /dev/null @@ -1,107 +0,0 @@ -#=============================================================================== -# Data caches. -#=============================================================================== -class PokemonTemp - attr_accessor :townMapData - attr_accessor :phoneData - attr_accessor :speciesShadowMovesets - attr_accessor :regionalDexes - attr_accessor :battleAnims - attr_accessor :moveToAnim - attr_accessor :mapInfos -end - -def pbClearData - if $PokemonTemp - $PokemonTemp.townMapData = nil - $PokemonTemp.phoneData = nil - $PokemonTemp.speciesShadowMovesets = nil - $PokemonTemp.regionalDexes = nil - $PokemonTemp.battleAnims = nil - $PokemonTemp.moveToAnim = nil - $PokemonTemp.mapInfos = nil - end - MapFactoryHelper.clear - $PokemonEncounters.setup($game_map.map_id) if $game_map && $PokemonEncounters - if pbRgssExists?("Data/Tilesets.rxdata") - $data_tilesets = load_data("Data/Tilesets.rxdata") - end -end - -#=============================================================================== -# Method to get Town Map data. -#=============================================================================== -def pbLoadTownMapData - $PokemonTemp = PokemonTemp.new if !$PokemonTemp - if !$PokemonTemp.townMapData - $PokemonTemp.townMapData = load_data("Data/town_map.dat") - end - return $PokemonTemp.townMapData -end - -#=============================================================================== -# Method to get phone call data. -#=============================================================================== -def pbLoadPhoneData - $PokemonTemp = PokemonTemp.new if !$PokemonTemp - if !$PokemonTemp.phoneData - if pbRgssExists?("Data/phone.dat") - $PokemonTemp.phoneData = load_data("Data/phone.dat") - end - end - return $PokemonTemp.phoneData -end - -#=============================================================================== -# Method to get Shadow Pokémon moveset data. -#=============================================================================== -def pbLoadShadowMovesets - $PokemonTemp = PokemonTemp.new if !$PokemonTemp - if !$PokemonTemp.speciesShadowMovesets - $PokemonTemp.speciesShadowMovesets = load_data("Data/shadow_movesets.dat") || [] - end - return $PokemonTemp.speciesShadowMovesets -end - -#=============================================================================== -# Method to get Regional Dexes data. -#=============================================================================== -def pbLoadRegionalDexes - $PokemonTemp = PokemonTemp.new if !$PokemonTemp - if !$PokemonTemp.regionalDexes - $PokemonTemp.regionalDexes = load_data("Data/regional_dexes.dat") - end - return $PokemonTemp.regionalDexes -end - -#=============================================================================== -# Methods relating to battle animations data. -#=============================================================================== -def pbLoadBattleAnimations - $PokemonTemp = PokemonTemp.new if !$PokemonTemp - if !$PokemonTemp.battleAnims - if pbRgssExists?("Data/PkmnAnimations.rxdata") - $PokemonTemp.battleAnims = load_data("Data/PkmnAnimations.rxdata") - end - end - return $PokemonTemp.battleAnims -end - -def pbLoadMoveToAnim - $PokemonTemp = PokemonTemp.new if !$PokemonTemp - if !$PokemonTemp.moveToAnim - $PokemonTemp.moveToAnim = load_data("Data/move2anim.dat") || [] - end - return $PokemonTemp.moveToAnim -end - -#=============================================================================== -# Method relating to map infos data. -#=============================================================================== -def pbLoadMapInfos - $PokemonTemp = PokemonTemp.new if !$PokemonTemp - if !$PokemonTemp.mapInfos - $PokemonTemp.mapInfos = load_data("Data/MapInfos.rxdata") - end - return $PokemonTemp.mapInfos -end diff --git a/Data/Scripts/010_Data/002_PBS data/002_PhoneDatabase.rb b/Data/Scripts/010_Data/002_PBS data/002_PhoneDatabase.rb deleted file mode 100644 index 903cf125e..000000000 --- a/Data/Scripts/010_Data/002_PBS data/002_PhoneDatabase.rb +++ /dev/null @@ -1,31 +0,0 @@ -#=============================================================================== -# Phone data -#=============================================================================== -class PhoneDatabase - attr_accessor :generics - attr_accessor :greetings - attr_accessor :greetingsMorning - attr_accessor :greetingsEvening - attr_accessor :bodies1 - attr_accessor :bodies2 - attr_accessor :battleRequests - attr_accessor :trainers - - def initialize - @generics = [] - @greetings = [] - @greetingsMorning = [] - @greetingsEvening = [] - @bodies1 = [] - @bodies2 = [] - @battleRequests = [] - @trainers = [] - end -end - -module PhoneMsgType - Generic = 0 - Greeting = 1 - Body = 2 - BattleRequest = 3 -end diff --git a/Data/Scripts/010_Data/002_PBS data/003_Type.rb b/Data/Scripts/010_Data/002_PBS data/003_Type.rb deleted file mode 100644 index 6853ffcb5..000000000 --- a/Data/Scripts/010_Data/002_PBS data/003_Type.rb +++ /dev/null @@ -1,132 +0,0 @@ -module GameData - class Type - attr_reader :id - attr_reader :id_number - attr_reader :real_name - attr_reader :special_type - attr_reader :pseudo_type - attr_reader :weaknesses - attr_reader :resistances - attr_reader :immunities - - DATA = {} - DATA_FILENAME = "types.dat" - - SCHEMA = { - "Name" => [1, "s"], - "InternalName" => [2, "s"], - "IsPseudoType" => [3, "b"], - "IsSpecialType" => [4, "b"], - "Weaknesses" => [5, "*s"], - "Resistances" => [6, "*s"], - "Immunities" => [7, "*s"] - } - - extend ClassMethods - include InstanceMethods - - def initialize(hash) - @id = hash[:id] - @id_number = hash[:id_number] || -1 - @real_name = hash[:name] || "Unnamed" - @pseudo_type = hash[:pseudo_type] || false - @special_type = hash[:special_type] || false - @weaknesses = hash[:weaknesses] || [] - @weaknesses = [@weaknesses] if !@weaknesses.is_a?(Array) - @resistances = hash[:resistances] || [] - @resistances = [@resistances] if !@resistances.is_a?(Array) - @immunities = hash[:immunities] || [] - @immunities = [@immunities] if !@immunities.is_a?(Array) - end - - # @return [String] the translated name of this item - def name - return pbGetMessage(MessageTypes::Types, @id_number) - end - - def physical?; return !@special_type; end - def special?; return @special_type; end - - def effectiveness(other_type) - return Effectiveness::NORMAL_EFFECTIVE_ONE if !other_type - return Effectiveness::SUPER_EFFECTIVE_ONE if @weaknesses.include?(other_type) - return Effectiveness::NOT_VERY_EFFECTIVE_ONE if @resistances.include?(other_type) - return Effectiveness::INEFFECTIVE if @immunities.include?(other_type) - return Effectiveness::NORMAL_EFFECTIVE_ONE - end - end -end - -#=============================================================================== - -module Effectiveness - INEFFECTIVE = 0 - NOT_VERY_EFFECTIVE_ONE = 1 - NORMAL_EFFECTIVE_ONE = 2 - SUPER_EFFECTIVE_ONE = 4 - NORMAL_EFFECTIVE = NORMAL_EFFECTIVE_ONE ** 3 - - module_function - - def ineffective?(value) - return value == INEFFECTIVE - end - - def not_very_effective?(value) - return value > INEFFECTIVE && value < NORMAL_EFFECTIVE - end - - def resistant?(value) - return value < NORMAL_EFFECTIVE - end - - def normal?(value) - return value == NORMAL_EFFECTIVE - end - - def super_effective?(value) - return value > NORMAL_EFFECTIVE - end - - def ineffective_type?(attack_type, defend_type1, defend_type2 = nil, defend_type3 = nil) - value = calculate(attack_type, defend_type1, defend_type2, defend_type3) - return ineffective?(value) - end - - def not_very_effective_type?(attack_type, defend_type1, defend_type2 = nil, defend_type3 = nil) - value = calculate(attack_type, defend_type1, defend_type2, defend_type3) - return not_very_effective?(value) - end - - def resistant_type?(attack_type, defend_type1, defend_type2 = nil, defend_type3 = nil) - value = calculate(attack_type, defend_type1, defend_type2, defend_type3) - return resistant?(value) - end - - def normal_type?(attack_type, defend_type1, defend_type2 = nil, defend_type3 = nil) - value = calculate(attack_type, defend_type1, defend_type2, defend_type3) - return normal?(value) - end - - def super_effective_type?(attack_type, defend_type1, defend_type2 = nil, defend_type3 = nil) - value = calculate(attack_type, defend_type1, defend_type2, defend_type3) - return super_effective?(value) - end - - def calculate_one(attack_type, defend_type) - return GameData::Type.get(defend_type).effectiveness(attack_type) - end - - def calculate(attack_type, defend_type1, defend_type2 = nil, defend_type3 = nil) - mod1 = calculate_one(attack_type, defend_type1) - mod2 = NORMAL_EFFECTIVE_ONE - mod3 = NORMAL_EFFECTIVE_ONE - if defend_type2 && defend_type1 != defend_type2 - mod2 = calculate_one(attack_type, defend_type2) - end - if defend_type3 && defend_type1 != defend_type3 && defend_type2 != defend_type3 - mod3 = calculate_one(attack_type, defend_type3) - end - return mod1 * mod2 * mod3 - end -end diff --git a/Data/Scripts/010_Data/002_PBS data/004_Ability.rb b/Data/Scripts/010_Data/002_PBS data/004_Ability.rb deleted file mode 100644 index 2de14fccf..000000000 --- a/Data/Scripts/010_Data/002_PBS data/004_Ability.rb +++ /dev/null @@ -1,31 +0,0 @@ -module GameData - class Ability - attr_reader :id - attr_reader :id_number - attr_reader :real_name - attr_reader :real_description - - DATA = {} - DATA_FILENAME = "abilities.dat" - - extend ClassMethods - include InstanceMethods - - def initialize(hash) - @id = hash[:id] - @id_number = hash[:id_number] || -1 - @real_name = hash[:name] || "Unnamed" - @real_description = hash[:description] || "???" - end - - # @return [String] the translated name of this ability - def name - return pbGetMessage(MessageTypes::Abilities, @id_number) - end - - # @return [String] the translated description of this ability - def description - return pbGetMessage(MessageTypes::AbilityDescs, @id_number) - end - end -end diff --git a/Data/Scripts/010_Data/002_PBS data/005_Move.rb b/Data/Scripts/010_Data/002_PBS data/005_Move.rb deleted file mode 100644 index eeff3c73f..000000000 --- a/Data/Scripts/010_Data/002_PBS data/005_Move.rb +++ /dev/null @@ -1,85 +0,0 @@ -module GameData - class Move - attr_reader :id - attr_reader :id_number - attr_reader :real_name - attr_reader :function_code - attr_reader :base_damage - attr_reader :type - attr_reader :category - attr_reader :accuracy - attr_reader :total_pp - attr_reader :effect_chance - attr_reader :target - attr_reader :priority - attr_reader :flags - attr_reader :real_description - - DATA = {} - DATA_FILENAME = "moves.dat" - - extend ClassMethods - include InstanceMethods - - def initialize(hash) - @id = hash[:id] - @id_number = hash[:id_number] || -1 - @real_name = hash[:name] || "Unnamed" - @function_code = hash[:function_code] - @base_damage = hash[:base_damage] - @type = hash[:type] - @category = hash[:category] - @accuracy = hash[:accuracy] - @total_pp = hash[:total_pp] - @effect_chance = hash[:effect_chance] - @target = hash[:target] - @priority = hash[:priority] - @flags = hash[:flags] - @real_description = hash[:description] || "???" - end - - # @return [String] the translated name of this move - def name - return pbGetMessage(MessageTypes::Moves, @id_number) - end - - # @return [String] the translated description of this move - def description - return pbGetMessage(MessageTypes::MoveDescriptions, @id_number) - end - - def physical? - return false if @base_damage == 0 - return @category == 0 if Settings::MOVE_CATEGORY_PER_MOVE - return GameData::Type.get(@type).physical? - end - - def special? - return false if @base_damage == 0 - return @category == 1 if Settings::MOVE_CATEGORY_PER_MOVE - return GameData::Type.get(@type).special? - end - - def hidden_move? - GameData::Item.each do |i| - return true if i.is_HM? && i.move == @id - end - return false - end - end -end - -#=============================================================================== -# Deprecated methods -#=============================================================================== -# @deprecated This alias is slated to be removed in v20. -def pbGetMoveData(move_id, move_data_type = -1) - Deprecation.warn_method('pbGetMoveData', 'v20', 'GameData::Move.get(move_id)') - return GameData::Move.get(move_id) -end - -# @deprecated This alias is slated to be removed in v20. -def pbIsHiddenMove?(move) - Deprecation.warn_method('pbIsHiddenMove?', 'v20', 'GameData::Move.get(move).hidden_move?') - return GameData::Move.get(move).hidden_move? -end diff --git a/Data/Scripts/010_Data/002_PBS data/006_Item.rb b/Data/Scripts/010_Data/002_PBS data/006_Item.rb deleted file mode 100644 index 09e0257e7..000000000 --- a/Data/Scripts/010_Data/002_PBS data/006_Item.rb +++ /dev/null @@ -1,324 +0,0 @@ -module GameData - class Item - attr_reader :id - attr_reader :id_number - attr_reader :real_name - attr_reader :real_name_plural - attr_reader :pocket - attr_reader :price - attr_reader :real_description - attr_reader :field_use - attr_reader :battle_use - attr_reader :type - attr_reader :move - - DATA = {} - DATA_FILENAME = "items.dat" - - extend ClassMethods - include InstanceMethods - - def self.icon_filename(item) - return "Graphics/Items/back" if item.nil? - item_data = self.try_get(item) - return "Graphics/Items/000" if item_data.nil? - # Check for files - ret = sprintf("Graphics/Items/%s", item_data.id) - return ret if pbResolveBitmap(ret) - # Check for TM/HM type icons - if item_data.is_machine? - prefix = "machine" - if item_data.is_HM? - prefix = "machine_hm" - elsif item_data.is_TR? - prefix = "machine_tr" - end - move_type = GameData::Move.get(item_data.move).type - type_data = GameData::Type.get(move_type) - ret = sprintf("Graphics/Items/%s_%s", prefix, type_data.id) - return ret if pbResolveBitmap(ret) - if !item_data.is_TM? - ret = sprintf("Graphics/Items/machine_%s", type_data.id) - return ret if pbResolveBitmap(ret) - end - end - return "Graphics/Items/000" - end - - def self.list_all() - return self::DATA - end - - def self.held_icon_filename(item) - item_data = self.try_get(item) - return nil if !item_data - name_base = (item_data.is_mail?) ? "mail" : "item" - # Check for files - ret = sprintf("Graphics/Pictures/Party/icon_%s_%s", name_base, item_data.id) - return ret if pbResolveBitmap(ret) - return sprintf("Graphics/Pictures/Party/icon_%s", name_base) - end - - def self.mail_filename(item) - item_data = self.try_get(item) - return nil if !item_data - # Check for files - ret = sprintf("Graphics/Pictures/Mail/mail_%s", item_data.id) - return pbResolveBitmap(ret) ? ret : nil - end - - def initialize(hash) - @id = hash[:id] - @id_number = hash[:id_number] || -1 - @real_name = hash[:name] || "Unnamed" - @real_name_plural = hash[:name_plural] || "Unnamed" - @pocket = hash[:pocket] || 1 - @price = hash[:price] || 0 - @real_description = hash[:description] || "???" - @field_use = hash[:field_use] || 0 - @battle_use = hash[:battle_use] || 0 - @type = hash[:type] || 0 - @move = hash[:move] - end - - - - # @return [String] the translated name of this item - def name - return pbGetMessage(MessageTypes::Items, @id_number) - end - - # @return [String] the translated plural version of the name of this item - def name_plural - return pbGetMessage(MessageTypes::ItemPlurals, @id_number) - end - - # @return [String] the translated description of this item - def description - return pbGetMessage(MessageTypes::ItemDescriptions, @id_number) - end - - def has_battle_use? - return @battle_use != 0 - end - def is_TM?; return @field_use == 3; end - def is_HM?; return @field_use == 4; end - def is_TR?; return @field_use == 6; end - def is_machine?; return is_TM? || is_HM? || is_TR?; end - def is_mail?; return @type == 1 || @type == 2; end - def is_icon_mail?; return @type == 2; end - def is_poke_ball?; return @type == 3 || @type == 4; end - def is_snag_ball?; return @type == 3 || (@type == 4 && $Trainer.has_snag_machine); end - def is_berry?; return @type == 5; end - def is_key_item?; return @type == 6; end - def is_evolution_stone?; return @type == 7; end - def is_fossil?; return @type == 8; end - def is_apricorn?; return @type == 9; end - def is_gem?; return @type == 10; end - def is_mulch?; return @type == 11; end - def is_mega_stone?; return @type == 12; end # Does NOT include Red Orb/Blue Orb - - UNTOSSABLE_ITEMS =[:PINKANBERRY,:DYNAMITE, :TM00] - def is_important? - return true if is_key_item? || is_HM? || is_TM? - return true if UNTOSSABLE_ITEMS.include?(@id) - return false - end - - def can_hold?; return !is_important?; end - - def unlosable?(species, ability) - return true if $game_switches[SWITCH_RANDOM_HELD_ITEMS] - return false if species == :ARCEUS && ability != :MULTITYPE - return false if species == :SILVALLY && ability != :RKSSYSTEM - combos = { - :ARCEUS => [:FISTPLATE, :FIGHTINIUMZ, - :SKYPLATE, :FLYINIUMZ, - :TOXICPLATE, :POISONIUMZ, - :EARTHPLATE, :GROUNDIUMZ, - :STONEPLATE, :ROCKIUMZ, - :INSECTPLATE, :BUGINIUMZ, - :SPOOKYPLATE, :GHOSTIUMZ, - :IRONPLATE, :STEELIUMZ, - :FLAMEPLATE, :FIRIUMZ, - :SPLASHPLATE, :WATERIUMZ, - :MEADOWPLATE, :GRASSIUMZ, - :ZAPPLATE, :ELECTRIUMZ, - :MINDPLATE, :PSYCHIUMZ, - :ICICLEPLATE, :ICIUMZ, - :DRACOPLATE, :DRAGONIUMZ, - :DREADPLATE, :DARKINIUMZ, - :PIXIEPLATE, :FAIRIUMZ], - :SILVALLY => [:FIGHTINGMEMORY, - :FLYINGMEMORY, - :POISONMEMORY, - :GROUNDMEMORY, - :ROCKMEMORY, - :BUGMEMORY, - :GHOSTMEMORY, - :STEELMEMORY, - :FIREMEMORY, - :WATERMEMORY, - :GRASSMEMORY, - :ELECTRICMEMORY, - :PSYCHICMEMORY, - :ICEMEMORY, - :DRAGONMEMORY, - :DARKMEMORY, - :FAIRYMEMORY], - :GIRATINA => [:GRISEOUSORB], - :GENESECT => [:BURNDRIVE, :CHILLDRIVE, :DOUSEDRIVE, :SHOCKDRIVE], - :KYOGRE => [:BLUEORB], - :GROUDON => [:REDORB] - } - return combos[species] && combos[species].include?(@id) - end - end -end - -#=============================================================================== -# Deprecated methods -#=============================================================================== -# @deprecated This alias is slated to be removed in v20. -def pbGetPocket(item) - Deprecation.warn_method('pbGetPocket', 'v20', 'GameData::Item.get(item).pocket') - return GameData::Item.get(item).pocket -end - -# @deprecated This alias is slated to be removed in v20. -def pbGetPrice(item) - Deprecation.warn_method('pbGetPrice', 'v20', 'GameData::Item.get(item).price') - return GameData::Item.get(item).price -end - -# @deprecated This alias is slated to be removed in v20. -def pbGetMachine(item) - Deprecation.warn_method('pbGetMachine', 'v20', 'GameData::Item.get(item).move') - return GameData::Item.get(item).move -end - -# @deprecated This alias is slated to be removed in v20. -def pbIsTechnicalMachine?(item) - Deprecation.warn_method('pbIsTechnicalMachine?', 'v20', 'GameData::Item.get(item).is_TM?') - return GameData::Item.get(item).is_TM? -end - -# @deprecated This alias is slated to be removed in v20. -def pbIsHiddenMachine?(item) - Deprecation.warn_method('pbIsHiddenMachine?', 'v20', 'GameData::Item.get(item).is_HM?') - return GameData::Item.get(item).is_HM? -end - -# @deprecated This alias is slated to be removed in v20. -def pbIsMachine?(item) - Deprecation.warn_method('pbIsMachine?', 'v20', 'GameData::Item.get(item).is_machine?') - return GameData::Item.get(item).is_machine? -end - -# @deprecated This alias is slated to be removed in v20. -def pbIsMail?(item) - Deprecation.warn_method('pbIsMail?', 'v20', 'GameData::Item.get(item).is_mail?') - return GameData::Item.get(item).is_mail? -end - -# @deprecated This alias is slated to be removed in v20. -def pbIsMailWithPokemonIcons?(item) - Deprecation.warn_method('pbIsMailWithPokemonIcons?', 'v20', 'GameData::Item.get(item).is_icon_mail?') - return GameData::Item.get(item).is_icon_mail? -end - -# @deprecated This alias is slated to be removed in v20. -def pbIsPokeBall?(item) - Deprecation.warn_method('pbIsPokeBall?', 'v20', 'GameData::Item.get(item).is_poke_ball?') - return GameData::Item.get(item).is_poke_ball? -end - -# @deprecated This alias is slated to be removed in v20. -def pbIsSnagBall?(item) - Deprecation.warn_method('pbIsSnagBall?', 'v20', 'GameData::Item.get(item).is_snag_ball?') - return GameData::Item.get(item).is_snag_ball? -end - -# @deprecated This alias is slated to be removed in v20. -def pbIsBerry?(item) - Deprecation.warn_method('pbIsBerry?', 'v20', 'GameData::Item.get(item).is_berry?') - return GameData::Item.get(item).is_berry? -end - -# @deprecated This alias is slated to be removed in v20. -def pbIsKeyItem?(item) - Deprecation.warn_method('pbIsKeyItem?', 'v20', 'GameData::Item.get(item).is_key_item?') - return GameData::Item.get(item).is_key_item? -end - -# @deprecated This alias is slated to be removed in v20. -def pbIsEvolutionStone?(item) - Deprecation.warn_method('pbIsEvolutionStone?', 'v20', 'GameData::Item.get(item).is_evolution_stone?') - return GameData::Item.get(item).is_evolution_stone? -end - -# @deprecated This alias is slated to be removed in v20. -def pbIsFossil?(item) - Deprecation.warn_method('pbIsFossil?', 'v20', 'GameData::Item.get(item).is_fossil?') - return GameData::Item.get(item).is_fossil? -end - -# @deprecated This alias is slated to be removed in v20. -def pbIsApricorn?(item) - Deprecation.warn_method('pbIsApricorn?', 'v20', 'GameData::Item.get(item).is_apricorn?') - return GameData::Item.get(item).is_apricorn? -end - -# @deprecated This alias is slated to be removed in v20. -def pbIsGem?(item) - Deprecation.warn_method('pbIsGem?', 'v20', 'GameData::Item.get(item).is_gem?') - return GameData::Item.get(item).is_gem? -end - -# @deprecated This alias is slated to be removed in v20. -def pbIsMulch?(item) - Deprecation.warn_method('pbIsMulch?', 'v20', 'GameData::Item.get(item).is_mulch?') - return GameData::Item.get(item).is_mulch? -end - -# @deprecated This alias is slated to be removed in v20. -def pbIsMegaStone?(item) - Deprecation.warn_method('pbIsMegaStone?', 'v20', 'GameData::Item.get(item).is_mega_stone?') - return GameData::Item.get(item).is_mega_stone? -end - -# @deprecated This alias is slated to be removed in v20. -def pbIsImportantItem?(item) - Deprecation.warn_method('pbIsImportantItem?', 'v20', 'GameData::Item.get(item).is_important?') - return GameData::Item.get(item).is_important? -end - -# @deprecated This alias is slated to be removed in v20. -def pbCanHoldItem?(item) - Deprecation.warn_method('pbCanHoldItem?', 'v20', 'GameData::Item.get(item).can_hold?') - return GameData::Item.get(item).can_hold? -end - -# @deprecated This alias is slated to be removed in v20. -def pbIsUnlosableItem?(check_item, species, ability) - Deprecation.warn_method('pbIsUnlosableItem?', 'v20', 'GameData::Item.get(item).unlosable?') - return GameData::Item.get(check_item).unlosable?(species, ability) -end - -# @deprecated This alias is slated to be removed in v20. -def pbItemIconFile(item) - Deprecation.warn_method('pbItemIconFile', 'v20', 'GameData::Item.icon_filename(item)') - return GameData::Item.icon_filename(item) -end - -# @deprecated This alias is slated to be removed in v20. -def pbHeldItemIconFile(item) - Deprecation.warn_method('pbHeldItemIconFile', 'v20', 'GameData::Item.held_icon_filename(item)') - return GameData::Item.held_icon_filename(item) -end - -# @deprecated This alias is slated to be removed in v20. -def pbMailBackFile(item) - Deprecation.warn_method('pbMailBackFile', 'v20', 'GameData::Item.mail_filename(item)') - return GameData::Item.mail_filename(item) -end diff --git a/Data/Scripts/010_Data/002_PBS data/007_BerryPlant.rb b/Data/Scripts/010_Data/002_PBS data/007_BerryPlant.rb deleted file mode 100644 index ad47a4e75..000000000 --- a/Data/Scripts/010_Data/002_PBS data/007_BerryPlant.rb +++ /dev/null @@ -1,36 +0,0 @@ -module GameData - class BerryPlant - attr_reader :id - attr_reader :id_number - attr_reader :hours_per_stage - attr_reader :drying_per_hour - attr_reader :minimum_yield - attr_reader :maximum_yield - - DATA = {} - DATA_FILENAME = "berry_plants.dat" - - NUMBER_OF_REPLANTS = 9 - - extend ClassMethods - include InstanceMethods - - def initialize(hash) - @id = hash[:id] - @id_number = hash[:id_number] || -1 - @hours_per_stage = hash[:hours_per_stage] || 3 - @drying_per_hour = hash[:drying_per_hour] || 15 - @minimum_yield = hash[:minimum_yield] || 2 - @maximum_yield = hash[:maximum_yield] || 5 - end - end -end - -#=============================================================================== -# Deprecated methods -#=============================================================================== -# @deprecated This alias is slated to be removed in v20. -def pbGetBerryPlantData(item) - Deprecation.warn_method('pbGetBerryPlantData', 'v20', 'GameData::BerryPlant.get(item)') - return GameData::BerryPlant.get(item) -end diff --git a/Data/Scripts/010_Data/002_PBS data/008_Species.rb b/Data/Scripts/010_Data/002_PBS data/008_Species.rb deleted file mode 100644 index 0136dbce2..000000000 --- a/Data/Scripts/010_Data/002_PBS data/008_Species.rb +++ /dev/null @@ -1,444 +0,0 @@ -module GameData - class Species - attr_reader :id - attr_reader :id_number - attr_reader :species - attr_reader :form - attr_reader :real_name - attr_reader :real_form_name - attr_reader :real_category - attr_reader :real_pokedex_entry - attr_reader :pokedex_form - attr_reader :type1 - attr_reader :type2 - attr_reader :base_stats - attr_reader :evs - attr_reader :base_exp - attr_reader :growth_rate - attr_reader :gender_ratio - attr_reader :catch_rate - attr_reader :happiness - attr_reader :moves - attr_reader :tutor_moves - attr_reader :egg_moves - attr_reader :abilities - attr_reader :hidden_abilities - attr_reader :wild_item_common - attr_reader :wild_item_uncommon - attr_reader :wild_item_rare - attr_reader :egg_groups - attr_reader :hatch_steps - attr_reader :incense - attr_reader :evolutions - attr_reader :height - attr_reader :weight - attr_reader :color - attr_reader :shape - attr_reader :habitat - attr_reader :generation - attr_reader :mega_stone - attr_reader :mega_move - attr_reader :unmega_form - attr_reader :mega_message - attr_accessor :back_sprite_x - attr_accessor :back_sprite_y - attr_accessor :front_sprite_x - attr_accessor :front_sprite_y - attr_accessor :front_sprite_altitude - attr_accessor :shadow_x - attr_accessor :shadow_size - attr_accessor :alwaysUseGeneratedSprite - - DATA = {} - DATA_FILENAME = "species.dat" - - extend ClassMethods - include InstanceMethods - - # @param species [Symbol, self, String, Integer] - # @param form [Integer] - # @return [self, nil] - def self.get_species_form(species, form) - return GameData::Species.get(species) rescue nil - # return nil if !species || !form - # validate species => [Symbol, self, String, Integer] - # validate form => Integer - # # if other.is_a?(Integer) - # # p "Please switch to symbols, thanks." - # # end - # species = species.species if species.is_a?(self) - # species = DATA[species].species if species.is_a?(Integer) - # species = species.to_sym if species.is_a?(String) - # trial = sprintf("%s_%d", species, form).to_sym - # species_form = (DATA[trial].nil?) ? species : trial - # return (DATA.has_key?(species_form)) ? DATA[species_form] : nil - end - - def self.schema(compiling_forms = false) - ret = { - "FormName" => [0, "q"], - "Kind" => [0, "s"], - "Pokedex" => [0, "q"], - "Type1" => [0, "e", :Type], - "Type2" => [0, "e", :Type], - "BaseStats" => [0, "vvvvvv"], - "EffortPoints" => [0, "uuuuuu"], - "BaseEXP" => [0, "v"], - "Rareness" => [0, "u"], - "Happiness" => [0, "u"], - "Moves" => [0, "*ue", nil, :Move], - "TutorMoves" => [0, "*e", :Move], - "EggMoves" => [0, "*e", :Move], - "Abilities" => [0, "*e", :Ability], - "HiddenAbility" => [0, "*e", :Ability], - "WildItemCommon" => [0, "e", :Item], - "WildItemUncommon" => [0, "e", :Item], - "WildItemRare" => [0, "e", :Item], - "Compatibility" => [0, "*e", :EggGroup], - "StepsToHatch" => [0, "v"], - "Height" => [0, "f"], - "Weight" => [0, "f"], - "Color" => [0, "e", :BodyColor], - "Shape" => [0, "y", :BodyShape], - "Habitat" => [0, "e", :Habitat], - "Generation" => [0, "i"], - "BattlerPlayerX" => [0, "i"], - "BattlerPlayerY" => [0, "i"], - "BattlerEnemyX" => [0, "i"], - "BattlerEnemyY" => [0, "i"], - "BattlerAltitude" => [0, "i"], - "BattlerShadowX" => [0, "i"], - "BattlerShadowSize" => [0, "u"] - } - if compiling_forms - ret["PokedexForm"] = [0, "u"] - ret["Evolutions"] = [0, "*ees", :Species, :Evolution, nil] - ret["MegaStone"] = [0, "e", :Item] - ret["MegaMove"] = [0, "e", :Move] - ret["UnmegaForm"] = [0, "u"] - ret["MegaMessage"] = [0, "u"] - else - ret["InternalName"] = [0, "n"] - ret["Name"] = [0, "s"] - ret["GrowthRate"] = [0, "e", :GrowthRate] - ret["GenderRate"] = [0, "e", :GenderRatio] - ret["Incense"] = [0, "e", :Item] - ret["Evolutions"] = [0, "*ses", nil, :Evolution, nil] - end - return ret - end - - def initialize(hash) - @id = hash[:id] - @id_number = hash[:id_number] || -1 - @species = hash[:species] || @id - @form = hash[:form] || 0 - @real_name = hash[:name] || "Unnamed" - @real_form_name = hash[:form_name] - @real_category = hash[:category] || "???" - @real_pokedex_entry = hash[:pokedex_entry] || "???" - @pokedex_form = hash[:pokedex_form] || @form - @type1 = hash[:type1] || :NORMAL - @type2 = hash[:type2] || @type1 - @base_stats = hash[:base_stats] || {} - @evs = hash[:evs] || {} - GameData::Stat.each_main do |s| - @base_stats[s.id] = 1 if !@base_stats[s.id] || @base_stats[s.id] <= 0 - @evs[s.id] = 0 if !@evs[s.id] || @evs[s.id] < 0 - end - @base_exp = hash[:base_exp] || 100 - @growth_rate = hash[:growth_rate] || :Medium - @gender_ratio = hash[:gender_ratio] || :Female50Percent - @catch_rate = hash[:catch_rate] || 255 - @happiness = hash[:happiness] || 70 - @moves = hash[:moves] || [] - @tutor_moves = hash[:tutor_moves] || [] - @egg_moves = hash[:egg_moves] || [] - @abilities = hash[:abilities] || [] - @hidden_abilities = hash[:hidden_abilities] || [] - @wild_item_common = hash[:wild_item_common] - @wild_item_uncommon = hash[:wild_item_uncommon] - @wild_item_rare = hash[:wild_item_rare] - @egg_groups = hash[:egg_groups] || [:Undiscovered] - @hatch_steps = hash[:hatch_steps] || 1 - @incense = hash[:incense] - @evolutions = hash[:evolutions] || [] - @height = hash[:height] || 1 - @weight = hash[:weight] || 1 - @color = hash[:color] || :Red - @shape = hash[:shape] || :Head - @habitat = hash[:habitat] || :None - @generation = hash[:generation] || 0 - @mega_stone = hash[:mega_stone] - @mega_move = hash[:mega_move] - @unmega_form = hash[:unmega_form] || 0 - @mega_message = hash[:mega_message] || 0 - @back_sprite_x = hash[:back_sprite_x] || 0 - @back_sprite_y = hash[:back_sprite_y] || 0 - @front_sprite_x = hash[:front_sprite_x] || 0 - @front_sprite_y = hash[:front_sprite_y] || 0 - @front_sprite_altitude = hash[:front_sprite_altitude] || 0 - @shadow_x = hash[:shadow_x] || 0 - @shadow_size = hash[:shadow_size] || 2 - @alwaysUseGeneratedSprite=false - end - - def set_always_use_generated_sprite(useGeneratedSprite) - @alwaysUseGeneratedSprite=useGeneratedSprite - end - - def always_use_generated - return @alwaysUseGeneratedSprite - end - # @return [String] the translated name of this species - def name - return @real_name - #return pbGetMessage(MessageTypes::Species, @id_number) - end - - # @return [String] the translated name of this form of this species - def form_name - return @real_form_name - #return pbGetMessage(MessageTypes::FormNames, @id_number) - end - - # @return [String] the translated Pokédex category of this species - def category - return @real_category - #return pbGetMessage(MessageTypes::Kinds, @id_number) - end - - # @return [String] the translated Pokédex entry of this species - def pokedex_entry - return @real_pokedex_entry - #return pbGetMessage(MessageTypes::Entries, @id_number) - end - - def is_fusion - return @id_number > Settings::NB_POKEMON - end - - def is_triple_fusion - return @id_number >= Settings::ZAPMOLCUNO_NB - end - def get_body_species - return @species - end - - def get_head_species - return @species - end - - def hasType?(type) - type = GameData::Type.get(type).id - return self.types.include?(type) - end - - def types - types = [@type1] - types << @type2 if @type2 && @type2 != @type1 - return types - end - - def apply_metrics_to_sprite(sprite, index, shadow = false) - front_sprite_y = self.is_fusion ? GameData::Species.get(getBodyID(@id_number)).front_sprite_y: @front_sprite_y - - if shadow - if (index & 1) == 1 # Foe Pokémon - sprite.x += @shadow_x * 2 - end - else - if (index & 1) == 0 # Player's Pokémon - sprite.x += @back_sprite_x * 2 - sprite.y += (@back_sprite_y * 2) + Settings::BACKSPRITE_POSITION_OFFSET - else - # Foe Pokémon - sprite.x += @front_sprite_x * 2 - sprite.y += (front_sprite_y * 2) + Settings::FRONTSPRITE_POSITION_OFFSET - sprite.y -= @front_sprite_altitude * 2 - end - end - end - - def shows_shadow? - return true - # return @front_sprite_altitude > 0 - end - - def get_evolutions(exclude_invalid = false) - ret = [] - @evolutions.each do |evo| - next if evo[3] # Is the prevolution - next if evo[1] == :None && exclude_invalid - ret.push([evo[0], evo[1], evo[2]]) # [Species, method, parameter] - end - return ret - end - - def get_family_evolutions(exclude_invalid = true) - evos = self.get_evolutions(exclude_invalid) - evos = evos.sort { |a, b| GameData::Species.get(a[0]).id_number <=> GameData::Species.get(b[0]).id_number } - ret = [] - evos.each do |evo| - ret.push([@species].concat(evo)) # [Prevo species, evo species, method, parameter] - evo_array = GameData::Species.get(evo[0]).get_family_evolutions(exclude_invalid) - ret.concat(evo_array) if evo_array && evo_array.length > 0 - end - return ret - end - - def get_previous_species - return @species if @evolutions.length == 0 - @evolutions.each { |evo| return evo[0] if evo[3] } # Is the prevolution - return @species - end - - def get_baby_species(check_items = false, item1 = nil, item2 = nil) - ret = @species - return ret if @evolutions.length == 0 - @evolutions.each do |evo| - next if !evo[3] # Not the prevolution - if check_items - incense = GameData::Species.get(evo[0]).incense - ret = evo[0] if !incense || item1 == incense || item2 == incense - else - ret = evo[0] # Species of prevolution - end - break - end - ret = GameData::Species.get(ret).get_baby_species(check_items, item1, item2) if ret != @species - return ret - end - - def get_related_species - sp = self.get_baby_species - evos = GameData::Species.get(sp).get_family_evolutions(false) - return [sp] if evos.length == 0 - return [sp].concat(evos.map { |e| e[1] }).uniq - end - - def family_evolutions_have_method?(check_method, check_param = nil) - sp = self.get_baby_species - evos = GameData::Species.get(sp).get_family_evolutions - return false if evos.length == 0 - evos.each do |evo| - if check_method.is_a?(Array) - next if !check_method.include?(evo[2]) - else - next if evo[2] != check_method - end - return true if check_param.nil? || evo[3] == check_param - end - return false - end - - # Used by the Moon Ball when checking if a Pokémon's evolution family - # includes an evolution that uses the Moon Stone. - def family_item_evolutions_use_item?(check_item = nil) - sp = self.get_baby_species - evos = GameData::Species.get(sp).get_family_evolutions - return false if !evos || evos.length == 0 - evos.each do |evo| - next if GameData::Evolution.get(evo[2]).use_item_proc.nil? - return true if check_item.nil? || evo[3] == check_item - end - return false - end - - def minimum_level - return 1 if @evolutions.length == 0 - @evolutions.each do |evo| - next if !evo[3] # Not the prevolution - evo_method_data = GameData::Evolution.get(evo[1]) - next if evo_method_data.level_up_proc.nil? - min_level = evo_method_data.minimum_level - return (min_level == 0) ? evo[2] : min_level + 1 - end - return 1 - end - end -end - -#=============================================================================== -# Deprecated methods -#=============================================================================== -# @deprecated This alias is slated to be removed in v20. -def pbGetSpeciesData(species, form = 0, species_data_type = -1) - Deprecation.warn_method('pbGetSpeciesData', 'v20', 'GameData::Species.get_species_form(species, form).something') - return GameData::Species.get_species_form(species, form) -end - -# @deprecated This alias is slated to be removed in v20. -def pbGetSpeciesEggMoves(species, form = 0) - Deprecation.warn_method('pbGetSpeciesEggMoves', 'v20', 'GameData::Species.get_species_form(species, form).egg_moves') - return GameData::Species.get_species_form(species, form).egg_moves -end - -# @deprecated This alias is slated to be removed in v20. -def pbGetSpeciesMoveset(species, form = 0) - Deprecation.warn_method('pbGetSpeciesMoveset', 'v20', 'GameData::Species.get_species_form(species, form).moves') - return GameData::Species.get_species_form(species, form).moves -end - -# @deprecated This alias is slated to be removed in v20. -def pbGetEvolutionData(species) - Deprecation.warn_method('pbGetEvolutionData', 'v20', 'GameData::Species.get(species).evolutions') - return GameData::Species.get(species).evolutions -end - -# @deprecated This alias is slated to be removed in v20. -def pbApplyBattlerMetricsToSprite(sprite, index, species_data, shadow = false, metrics = nil) - Deprecation.warn_method('pbApplyBattlerMetricsToSprite', 'v20', 'GameData::Species.get(species).apply_metrics_to_sprite') - GameData::Species.get(species).apply_metrics_to_sprite(sprite, index, shadow) -end - -# @deprecated This alias is slated to be removed in v20. -def showShadow?(species) - Deprecation.warn_method('showShadow?', 'v20', 'GameData::Species.get(species).shows_shadow?') - return GameData::Species.get(species).shows_shadow? -end - -# @deprecated Use {GameData#Species#get_evolutions} instead. This alias is slated to be removed in v20. -def pbGetEvolvedFormData(species, exclude_invalid = false) - Deprecation.warn_method('pbGetEvolvedFormData', 'v20', 'GameData::Species.get(species).get_evolutions') - return GameData::Species.get(species).get_evolutions(exclude_invalid) -end - -# @deprecated Use {GameData#Species#get_family_evolutions} instead. This alias is slated to be removed in v20. -def pbGetEvolutionFamilyData(species) - # Unused - Deprecation.warn_method('pbGetEvolutionFamilyData', 'v20', 'GameData::Species.get(species).get_family_evolutions') - return GameData::Species.get(species).get_family_evolutions -end - -# @deprecated Use {GameData#Species#get_previous_species} instead. This alias is slated to be removed in v20. -def pbGetPreviousForm(species) - # Unused - Deprecation.warn_method('pbGetPreviousForm', 'v20', 'GameData::Species.get(species).get_previous_species') - return GameData::Species.get(species).get_previous_species -end - -# @deprecated Use {GameData#Species#get_baby_species} instead. This alias is slated to be removed in v20. -def pbGetBabySpecies(species, check_items = false, item1 = nil, item2 = nil) - Deprecation.warn_method('pbGetBabySpecies', 'v20', 'GameData::Species.get(species).get_baby_species') - return GameData::Species.get(species).get_baby_species(check_items, item1, item2) -end - -# @deprecated Use {GameData#Species#family_evolutions_have_method?} instead. This alias is slated to be removed in v20. -def pbCheckEvolutionFamilyForMethod(species, method, param = nil) - # Unused - Deprecation.warn_method('pbCheckEvolutionFamilyForMethod', 'v20', 'GameData::Species.get(species).family_evolutions_have_method?(method)') - return GameData::Species.get(species).family_evolutions_have_method?(method, param) -end - -# @deprecated Use {GameData#Species#family_item_evolutions_use_item?} instead. This alias is slated to be removed in v20. -def pbCheckEvolutionFamilyForItemMethodItem(species, param = nil) - Deprecation.warn_method('pbCheckEvolutionFamilyForItemMethodItem', 'v20', 'GameData::Species.get(species).family_item_evolutions_use_item?(item)') - return GameData::Species.get(species).family_item_evolutions_use_item?(param) -end - -# @deprecated Use {GameData#Species#minimum_level} instead. This alias is slated to be removed in v20. -def pbGetMinimumLevel(species) - Deprecation.warn_method('pbGetMinimumLevel', 'v20', 'GameData::Species.get(species).minimum_level') - return GameData::Species.get(species).minimum_level -end diff --git a/Data/Scripts/010_Data/002_PBS data/009_Species_Files.rb b/Data/Scripts/010_Data/002_PBS data/009_Species_Files.rb deleted file mode 100644 index 1baf52909..000000000 --- a/Data/Scripts/010_Data/002_PBS data/009_Species_Files.rb +++ /dev/null @@ -1,388 +0,0 @@ -module GameData - class Species - def self.check_graphic_file(path, species, form = "", gender = 0, shiny = false, shadow = false, subfolder = "") - try_subfolder = sprintf("%s/", subfolder) - try_species = species - - try_form = form ? sprintf("_%s", form) : "" - try_gender = (gender == 1) ? "_female" : "" - try_shadow = (shadow) ? "_shadow" : "" - factors = [] - factors.push([4, sprintf("%s shiny/", subfolder), try_subfolder]) if shiny - factors.push([3, try_shadow, ""]) if shadow - factors.push([2, try_gender, ""]) if gender == 1 - factors.push([1, try_form, ""]) if form - factors.push([0, try_species, "000"]) - # Go through each combination of parameters in turn to find an existing sprite - for i in 0...2 ** factors.length - # Set try_ parameters for this combination - factors.each_with_index do |factor, index| - value = ((i / (2 ** index)) % 2 == 0) ? factor[1] : factor[2] - case factor[0] - when 0 then - try_species = value - when 1 then - try_form = value - when 2 then - try_gender = value - when 3 then - try_shadow = value - when 4 then - try_subfolder = value # Shininess - end - end - # Look for a graphic matching this combination's parameters - try_species_text = try_species - ret = pbResolveBitmap(sprintf("%s%s%s%s%s%s", path, try_subfolder, - try_species_text, try_form, try_gender, try_shadow)) - return ret if ret - end - return nil - end - - def self.check_egg_graphic_file(path, species, form, suffix = "") - species_data = self.get_species_form(species, form) - return nil if species_data.nil? - if form > 0 - ret = pbResolveBitmap(sprintf("%s%s_%d%s", path, species_data.species, form, suffix)) - return ret if ret - end - return pbResolveBitmap(sprintf("%s%s%s", path, species_data.species, suffix)) - end - - def self.front_sprite_filename(species, form = 0, gender = 0, shiny = false, shadow = false) - return self.check_graphic_file("Graphics/Pokemon/", species, form, gender, shiny, shadow, "Front") - end - - def self.back_sprite_filename(species, form = 0, gender = 0, shiny = false, shadow = false) - return self.check_graphic_file("Graphics/Pokemon/", species, form, gender, shiny, shadow, "Back") - end - - # def self.egg_sprite_filename(species, form) - # ret = self.check_egg_graphic_file("Graphics/Pokemon/Eggs/", species, form) - # return (ret) ? ret : pbResolveBitmap("Graphics/Pokemon/Eggs/000") - # end - def self.egg_sprite_filename(species, form) - return "Graphics/Battlers/Eggs/000" if $PokemonSystem.use_custom_eggs - dexNum = getDexNumberForSpecies(species) - bitmapFileName = sprintf("Graphics/Battlers/Eggs/%03d", dexNum) rescue nil - if !pbResolveBitmap(bitmapFileName) - if isTripleFusion?(dexNum) - bitmapFileName = "Graphics/Battlers/Eggs/egg_base" - else - bitmapFileName = sprintf("Graphics/Battlers/Eggs/%03d", dexNum) - if !pbResolveBitmap(bitmapFileName) - bitmapFileName = sprintf("Graphics/Battlers/Eggs/000") - end - end - end - return bitmapFileName - end - - def self.sprite_filename(species, form = 0, gender = 0, shiny = false, shadow = false, back = false, egg = false) - return self.egg_sprite_filename(species, form) if egg - return self.back_sprite_filename(species, form, gender, shiny, shadow) if back - return self.front_sprite_filename(species, form, gender, shiny, shadow) - end - - def self.front_sprite_bitmap(species, form = 0, gender = 0, shiny = false, shadow = false) - #filename = self.front_sprite_filename(species, form, gender, shiny, shadow) - filename = self.front_sprite_filename(GameData::Species.get(species).id_number) - return (filename) ? AnimatedBitmap.new(filename) : nil - end - - def self.back_sprite_bitmap(species, form = 0, gender = 0, shiny = false, shadow = false) - filename = self.back_sprite_filename(species, form, gender, shiny, shadow) - return (filename) ? AnimatedBitmap.new(filename) : nil - end - - def self.egg_sprite_bitmap(species, form = 0) - filename = self.egg_sprite_filename(species, form) - return (filename) ? AnimatedBitmap.new(filename) : nil - end - - def self.sprite_bitmap(species, form = 0, gender = 0, shiny = false, shadow = false, back = false, egg = false) - return self.egg_sprite_bitmap(species, form) if egg - return self.back_sprite_bitmap(species, form, gender, shiny, shadow) if back - return self.front_sprite_bitmap(species, shiny,) - end - - def self.sprite_bitmap_from_pokemon(pkmn, back = false, species = nil) - species = pkmn.species if !species - species = GameData::Species.get(species).species # Just to be sure it's a symbol - return self.egg_sprite_bitmap(species, pkmn.form) if pkmn.egg? - if back - ret = self.back_sprite_bitmap(species, pkmn.form, pkmn.gender, pkmn.shiny?, pkmn.shadowPokemon?) - else - ret = self.front_sprite_bitmap(species, pkmn.form, pkmn.gender, pkmn.shiny?, pkmn.shadowPokemon?) - end - alter_bitmap_function = MultipleForms.getFunction(species, "alterBitmap") - if ret && alter_bitmap_function - new_ret = ret.copy - ret.dispose - new_ret.each { |bitmap| alter_bitmap_function.call(pkmn, bitmap) } - ret = new_ret - end - print "hat" - add_hat_to_bitmap(ret,pkmn.hat,pkmn.hat_x,pkmn.hat_y) if pkmn.hat - return ret - end - - #=========================================================================== - - def self.egg_icon_filename(species, form) - ret = self.check_egg_graphic_file("Graphics/Pokemon/Eggs/", species, form, "_icon") - return (ret) ? ret : pbResolveBitmap("Graphics/Pokemon/Eggs/000_icon") - end - - def self.icon_filename(species, spriteform= nil, gender=nil, shiny = false, shadow = false, egg = false) - return self.egg_icon_filename(species, 0) if egg - return self.check_graphic_file("Graphics/Pokemon/", species, spriteform, gender, shiny, shadow, "Icons") - end - - def self.icon_filename_from_pokemon(pkmn) - return pbResolveBitmap(sprintf("Graphics/Icons/iconEgg")) if pkmn.egg? - if pkmn.isFusion? - return pbResolveBitmap(sprintf("Graphics/Icons/iconDNA")) - end - return self.icon_filename(pkmn.species, pkmn.spriteform_head, pkmn.gender, pkmn.shiny?, pkmn.shadowPokemon?, pkmn.egg?) - end - - def self.icon_filename_from_species(species) - return self.icon_filename(species, 0, 0, false, false, false) - end - - def self.egg_icon_bitmap(species, form) - filename = self.egg_icon_filename(species, form) - return (filename) ? AnimatedBitmap.new(filename).deanimate : nil - end - - def self.icon_bitmap(species, form = 0, gender = 0, shiny = false, shadow = false) - filename = self.icon_filename(species, form, gender, shiny, shadow) - return (filename) ? AnimatedBitmap.new(filename).deanimate : nil - end - - def self.icon_bitmap_from_pokemon(pkmn) - return self.icon_bitmap(pkmn.species, pkmn.form, pkmn.gender, pkmn.shiny?, pkmn.shadowPokemon?, pkmn.egg?) - end - - #=========================================================================== - - def self.footprint_filename(species, form = 0) - species_data = self.get_species_form(species, form) - return nil if species_data.nil? - if form > 0 - ret = pbResolveBitmap(sprintf("Graphics/Pokemon/Footprints/%s_%d", species_data.species, form)) - return ret if ret - end - return pbResolveBitmap(sprintf("Graphics/Pokemon/Footprints/%s", species_data.species)) - end - - #=========================================================================== - - def self.shadow_filename(species, form = 0) - species_data = self.get_species_form(species, form) - return nil if species_data.nil? - # Look for species-specific shadow graphic - if form > 0 - ret = pbResolveBitmap(sprintf("Graphics/Pokemon/Shadow/%s_%d", species_data.species, form)) - return ret if ret - end - ret = pbResolveBitmap(sprintf("Graphics/Pokemon/Shadow/%s", species_data.species)) - return ret if ret - # Use general shadow graphic - return pbResolveBitmap(sprintf("Graphics/Pokemon/Shadow/%d", species_data.shadow_size)) - end - - def self.shadow_bitmap(species, form = 0) - filename = self.shadow_filename(species, form) - return (filename) ? AnimatedBitmap.new(filename) : nil - end - - def self.shadow_bitmap_from_pokemon(pkmn) - filename = self.shadow_filename(pkmn.species, pkmn.form) - return (filename) ? AnimatedBitmap.new(filename) : nil - end - - #=========================================================================== - - def self.check_cry_file(species, form) - species_data = self.get_species_form(species, form) - return nil if species_data.nil? - if species_data.is_fusion - species_data = GameData::Species.get(getHeadID(species_data)) - end - ret = sprintf("Cries/%s", species_data.species) - return (pbResolveAudioSE(ret)) ? ret : nil - end - - def self.cry_filename(species, form = 0) - return self.check_cry_file(species, form) - end - - def self.cry_filename_from_pokemon(pkmn) - return self.check_cry_file(pkmn.species, pkmn.form) - end - - def self.play_cry_from_species(species, form = 0, volume = 90, pitch = 100) - dex_num = getDexNumberForSpecies(species) - return if !dex_num - return play_triple_fusion_cry(species, volume, pitch) if dex_num > Settings::ZAPMOLCUNO_NB - if dex_num > NB_POKEMON - body_number = getBodyID(dex_num) - head_number = getHeadID(dex_num,body_number) - return play_fusion_cry(GameData::Species.get(head_number).species,GameData::Species.get(body_number).species, volume, pitch) - end - filename = self.cry_filename(species, form) - return if !filename - pbSEPlay(RPG::AudioFile.new(filename, volume, pitch)) rescue nil - end - - def self.play_cry_from_pokemon(pkmn, volume = 90, pitch = nil) - return if !pkmn || pkmn.egg? - - species_data = pkmn.species_data - return play_triple_fusion_cry(pkmn.species, volume, pitch) if species_data.is_triple_fusion - if pkmn.species_data.is_fusion - return play_fusion_cry(species_data.get_head_species,species_data.get_body_species, volume, pitch) - end - filename = self.cry_filename_from_pokemon(pkmn) - return if !filename - pitch ||= 75 + (pkmn.hp * 25 / pkmn.totalhp) - pbSEPlay(RPG::AudioFile.new(filename, volume, pitch)) rescue nil - end - - def self.play_triple_fusion_cry(species_id, volume, pitch) - fusion_components = get_triple_fusion_components(species_id) - - echoln fusion_components - echoln species_id - for id in fusion_components - cry_filename = self.check_cry_file(id,nil) - pbSEPlay(cry_filename,volume-10) rescue nil - end - end - def self.play_fusion_cry(head_id,body_id, volume = 90, pitch = 100) - head_cry_filename = self.check_cry_file(head_id,nil) - body_cry_filename = self.check_cry_file(body_id,nil) - - pbSEPlay(body_cry_filename,volume-10) rescue nil - pbSEPlay(head_cry_filename,volume) rescue nil - end - def self.play_cry(pkmn, volume = 90, pitch = nil) - if pkmn.is_a?(Pokemon) - self.play_cry_from_pokemon(pkmn, volume, pitch) - else - self.play_cry_from_species(pkmn, nil, volume, pitch) - end - end - - def self.cry_length(species, form = 0, pitch = 100) - return 0 if !species || pitch <= 0 - pitch = pitch.to_f / 100 - ret = 0.0 - if species.is_a?(Pokemon) - if !species.egg? - filename = pbResolveAudioSE(GameData::Species.cry_filename_from_pokemon(species)) - ret = getPlayTime(filename) if filename - end - else - filename = pbResolveAudioSE(GameData::Species.cry_filename(species, form)) - ret = getPlayTime(filename) if filename - end - ret /= pitch # Sound played at a lower pitch lasts longer - return (ret * Graphics.frame_rate).ceil + 4 # 4 provides a buffer between sounds - end - end -end - -#=============================================================================== -# Deprecated methods -#=============================================================================== -# @deprecated This alias is slated to be removed in v20. -def pbLoadSpeciesBitmap(species, gender = 0, form = 0, shiny = false, shadow = false, back = false, egg = false) - Deprecation.warn_method('pbLoadSpeciesBitmap', 'v20', 'GameData::Species.sprite_bitmap(species, form, gender, shiny, shadow, back, egg)') - return GameData::Species.sprite_bitmap(species, form, gender, shiny, shadow, back, egg) -end - -# @deprecated This alias is slated to be removed in v20. -def pbLoadPokemonBitmap(pkmn, back = false) - Deprecation.warn_method('pbLoadPokemonBitmap', 'v20', 'GameData::Species.sprite_bitmap_from_pokemon(pkmn)') - return GameData::Species.sprite_bitmap_from_pokemon(pkmn, back) -end - -# @deprecated This alias is slated to be removed in v20. -def pbLoadPokemonBitmapSpecies(pkmn, species, back = false) - Deprecation.warn_method('pbLoadPokemonBitmapSpecies', 'v20', 'GameData::Species.sprite_bitmap_from_pokemon(pkmn, back, species)') - return GameData::Species.sprite_bitmap_from_pokemon(pkmn, back, species) -end - -# @deprecated This alias is slated to be removed in v20. -def pbPokemonIconFile(pkmn) - Deprecation.warn_method('pbPokemonIconFile', 'v20', 'GameData::Species.icon_filename_from_pokemon(pkmn)') - return GameData::Species.icon_filename_from_pokemon(pkmn) -end - -# @deprecated This alias is slated to be removed in v20. -def pbLoadPokemonIcon(pkmn) - Deprecation.warn_method('pbLoadPokemonIcon', 'v20', 'GameData::Species.icon_bitmap_from_pokemon(pkmn)') - return GameData::Species.icon_bitmap_from_pokemon(pkmn) -end - -# @deprecated This alias is slated to be removed in v20. -def pbPokemonFootprintFile(species, form = 0) - Deprecation.warn_method('pbPokemonFootprintFile', 'v20', 'GameData::Species.footprint_filename(species, form)') - return GameData::Species.footprint_filename(species, form) -end - -# @deprecated This alias is slated to be removed in v20. -def pbCheckPokemonShadowBitmapFiles(species, form = 0) - Deprecation.warn_method('pbCheckPokemonShadowBitmapFiles', 'v20', 'GameData::Species.shadow_filename(species, form)') - return GameData::Species.shadow_filename(species, form) -end - -# @deprecated This alias is slated to be removed in v20. -def pbLoadPokemonShadowBitmap(pkmn) - Deprecation.warn_method('pbLoadPokemonShadowBitmap', 'v20', 'GameData::Species.shadow_bitmap_from_pokemon(pkmn)') - return GameData::Species.shadow_bitmap_from_pokemon(pkmn) -end - -# @deprecated This alias is slated to be removed in v20. -def pbCryFile(species, form = 0) - if species.is_a?(Pokemon) - Deprecation.warn_method('pbCryFile', 'v20', 'GameData::Species.cry_filename_from_pokemon(pkmn)') - return GameData::Species.cry_filename_from_pokemon(species) - end - Deprecation.warn_method('pbCryFile', 'v20', 'GameData::Species.cry_filename(species, form)') - return GameData::Species.cry_filename(species, form) -end - -# @deprecated This alias is slated to be removed in v20. -def pbPlayCry(pkmn, volume = 90, pitch = nil) - Deprecation.warn_method('pbPlayCry', 'v20', 'GameData::Species.play_cry(pkmn)') - GameData::Species.play_cry(pkmn, volume, pitch) -end - - -def play_cry(species, volume = 90, pitch = 100) - echoln species - GameData::Species.play_cry_from_species(species,0,volume, pitch) -end - -# @deprecated This alias is slated to be removed in v20. -def pbPlayCrySpecies(species, form = 0, volume = 90, pitch = nil) - Deprecation.warn_method('pbPlayCrySpecies', 'v20', 'Pokemon.play_cry(species, form)') - Pokemon.play_cry(species, form, volume, pitch) -end - -# @deprecated This alias is slated to be removed in v20. -def pbPlayCryPokemon(pkmn, volume = 90, pitch = nil) - Deprecation.warn_method('pbPlayCryPokemon', 'v20', 'pkmn.play_cry') - pkmn.play_cry(volume, pitch) -end - -# @deprecated This alias is slated to be removed in v20. -def pbCryFrameLength(species, form = 0, pitch = 100) - Deprecation.warn_method('pbCryFrameLength', 'v20', 'GameData::Species.cry_length(species, form)') - return GameData::Species.cry_length(species, form, pitch) -end diff --git a/Data/Scripts/010_Data/002_PBS data/010_Ribbon.rb b/Data/Scripts/010_Data/002_PBS data/010_Ribbon.rb deleted file mode 100644 index 77195cac5..000000000 --- a/Data/Scripts/010_Data/002_PBS data/010_Ribbon.rb +++ /dev/null @@ -1,31 +0,0 @@ -module GameData - class Ribbon - attr_reader :id - attr_reader :id_number - attr_reader :real_name - attr_reader :real_description - - DATA = {} - DATA_FILENAME = "ribbons.dat" - - extend ClassMethods - include InstanceMethods - - def initialize(hash) - @id = hash[:id] - @id_number = hash[:id_number] || -1 - @real_name = hash[:name] || "Unnamed" - @real_description = hash[:description] || "???" - end - - # @return [String] the translated name of this ribbon - def name - return pbGetMessage(MessageTypes::RibbonNames, @id_number) - end - - # @return [String] the translated description of this ribbon - def description - return pbGetMessage(MessageTypes::RibbonDescriptions, @id_number) - end - end -end diff --git a/Data/Scripts/010_Data/002_PBS data/011_Encounter.rb b/Data/Scripts/010_Data/002_PBS data/011_Encounter.rb deleted file mode 100644 index 8085c6435..000000000 --- a/Data/Scripts/010_Data/002_PBS data/011_Encounter.rb +++ /dev/null @@ -1,78 +0,0 @@ -module GameData - class Encounter - attr_accessor :id - attr_accessor :map - attr_accessor :version - - attr_reader :step_chances - attr_reader :types - - DATA = {} - DATA_FILENAME = "encounters.dat" - - extend ClassMethodsSymbols - include InstanceMethods - - # @param map_id [Integer] - # @param map_version [Integer, nil] - # @return [Boolean] whether there is encounter data for the given map ID/version - def self.exists?(map_id, map_version = 0) - validate map_id => [Integer] - validate map_version => [Integer] - key = sprintf("%s_%d", map_id, map_version).to_sym - return !self::DATA[key].nil? - end - - # @param map_id [Integer] - # @param map_version [Integer, nil] - # @return [self, nil] - def self.get(map_id, map_version = 0) - validate map_id => Integer - validate map_version => Integer - trial_key = sprintf("%s_%d", map_id, map_version).to_sym - key = (self::DATA.has_key?(trial_key)) ? trial_key : sprintf("%s_0", map_id).to_sym - return self::DATA[key] - end - - # Yields all encounter data in order of their map and version numbers. - def self.each - keys = self::DATA.keys.sort do |a, b| - if self::DATA[a].map == self::DATA[b].map - self::DATA[a].version <=> self::DATA[b].version - else - self::DATA[a].map <=> self::DATA[b].map - end - end - keys.each { |key| yield self::DATA[key] } - end - - # Yields all encounter data for the given version. Also yields encounter - # data for version 0 of a map if that map doesn't have encounter data for - # the given version. - def self.each_of_version(version = 0) - self.each do |data| - yield data if data.version == version - if version > 0 - yield data if data.version == 0 && !self::DATA.has_key?([data.map, version]) - end - end - end - - def initialize(hash) - @id = hash[:id] - @map = hash[:map] - @version = hash[:version] || 0 - @step_chances = hash[:step_chances] - @types = hash[:types] || {} - end - end -end - -#=============================================================================== -# Deprecated methods -#=============================================================================== -# @deprecated This alias is slated to be removed in v20. -def pbLoadEncountersData - Deprecation.warn_method('pbLoadEncountersData', 'v20', 'GameData::Encounter.get(map_id, version)') - return nil -end diff --git a/Data/Scripts/010_Data/002_PBS data/011_EncounterModern.rb b/Data/Scripts/010_Data/002_PBS data/011_EncounterModern.rb deleted file mode 100644 index a1791bcad..000000000 --- a/Data/Scripts/010_Data/002_PBS data/011_EncounterModern.rb +++ /dev/null @@ -1,77 +0,0 @@ -module GameData - class EncounterModern - attr_accessor :id - attr_accessor :map - attr_accessor :version - attr_reader :step_chances - attr_reader :types - - DATA = {} - DATA_FILENAME = "encounters_remix.dat" - - extend ClassMethodsSymbols - include InstanceMethods - - # @param map_id [Integer] - # @param map_version [Integer, nil] - # @return [Boolean] whether there is encounter data for the given map ID/version - def self.exists?(map_id, map_version = 0) - validate map_id => [Integer] - validate map_version => [Integer] - key = sprintf("%s_%d", map_id, map_version).to_sym - return !self::DATA[key].nil? - end - - # @param map_id [Integer] - # @param map_version [Integer, nil] - # @return [self, nil] - def self.get(map_id, map_version = 0) - validate map_id => Integer - validate map_version => Integer - trial_key = sprintf("%s_%d", map_id, map_version).to_sym - key = (self::DATA.has_key?(trial_key)) ? trial_key : sprintf("%s_0", map_id).to_sym - return self::DATA[key] - end - - # Yields all encounter data in order of their map and version numbers. - def self.each - keys = self::DATA.keys.sort do |a, b| - if self::DATA[a].map == self::DATA[b].map - self::DATA[a].version <=> self::DATA[b].version - else - self::DATA[a].map <=> self::DATA[b].map - end - end - keys.each { |key| yield self::DATA[key] } - end - - # Yields all encounter data for the given version. Also yields encounter - # data for version 0 of a map if that map doesn't have encounter data for - # the given version. - def self.each_of_version(version = 0) - self.each do |data| - yield data if data.version == version - if version > 0 - yield data if data.version == 0 && !self::DATA.has_key?([data.map, version]) - end - end - end - - def initialize(hash) - @id = hash[:id] - @map = hash[:map] - @version = hash[:version] || 0 - @step_chances = hash[:step_chances] - @types = hash[:types] || {} - end - end -end - -#=============================================================================== -# Deprecated methods -#=============================================================================== -# @deprecated This alias is slated to be removed in v20. -def pbLoadEncountersData - Deprecation.warn_method('pbLoadEncountersData', 'v20', 'GameData::Encounter.get(map_id, version)') - return nil -end diff --git a/Data/Scripts/010_Data/002_PBS data/011_Encounter_random.rb b/Data/Scripts/010_Data/002_PBS data/011_Encounter_random.rb deleted file mode 100644 index a87311705..000000000 --- a/Data/Scripts/010_Data/002_PBS data/011_Encounter_random.rb +++ /dev/null @@ -1,77 +0,0 @@ -module GameData - class EncounterRandom - attr_accessor :id - attr_accessor :map - attr_accessor :version - attr_reader :step_chances - attr_reader :types - - DATA = {} - DATA_FILENAME = "encounters_randomized.dat" - - extend ClassMethodsSymbols - include InstanceMethods - - # @param map_id [Integer] - # @param map_version [Integer, nil] - # @return [Boolean] whether there is encounter data for the given map ID/version - def self.exists?(map_id, map_version = 0) - validate map_id => [Integer] - validate map_version => [Integer] - key = sprintf("%s_%d", map_id, map_version).to_sym - return !self::DATA[key].nil? - end - - # @param map_id [Integer] - # @param map_version [Integer, nil] - # @return [self, nil] - def self.get(map_id, map_version = 0) - validate map_id => Integer - validate map_version => Integer - trial_key = sprintf("%s_%d", map_id, map_version).to_sym - key = (self::DATA.has_key?(trial_key)) ? trial_key : sprintf("%s_0", map_id).to_sym - return self::DATA[key] - end - - # Yields all encounter data in order of their map and version numbers. - def self.each - keys = self::DATA.keys.sort do |a, b| - if self::DATA[a].map == self::DATA[b].map - self::DATA[a].version <=> self::DATA[b].version - else - self::DATA[a].map <=> self::DATA[b].map - end - end - keys.each { |key| yield self::DATA[key] } - end - - # Yields all encounter data for the given version. Also yields encounter - # data for version 0 of a map if that map doesn't have encounter data for - # the given version. - def self.each_of_version(version = 0) - self.each do |data| - yield data if data.version == version - if version > 0 - yield data if data.version == 0 && !self::DATA.has_key?([data.map, version]) - end - end - end - - def initialize(hash) - @id = hash[:id] - @map = hash[:map] - @version = hash[:version] || 0 - @step_chances = hash[:step_chances] - @types = hash[:types] || {} - end - end -end - -#=============================================================================== -# Deprecated methods -#=============================================================================== -# @deprecated This alias is slated to be removed in v20. -def pbLoadEncountersData - Deprecation.warn_method('pbLoadEncountersData', 'v20', 'GameData::Encounter.get(map_id, version)') - return nil -end diff --git a/Data/Scripts/010_Data/002_PBS data/012_TrainerType.rb b/Data/Scripts/010_Data/002_PBS data/012_TrainerType.rb deleted file mode 100644 index e583703dd..000000000 --- a/Data/Scripts/010_Data/002_PBS data/012_TrainerType.rb +++ /dev/null @@ -1,157 +0,0 @@ -module GameData - class TrainerType - attr_reader :id - attr_reader :id_number - attr_reader :real_name - attr_reader :base_money - attr_reader :battle_BGM - attr_reader :victory_ME - attr_reader :intro_ME - attr_reader :gender - attr_reader :skill_level - attr_reader :skill_code - - DATA = {} - DATA_FILENAME = "trainer_types.dat" - - extend ClassMethods - include InstanceMethods - - def self.check_file(tr_type, path, optional_suffix = "", suffix = "") - tr_type_data = self.try_get(tr_type) - return nil if tr_type_data.nil? - # Check for files - if optional_suffix && !optional_suffix.empty? - ret = path + tr_type_data.id.to_s + optional_suffix + suffix - return ret if pbResolveBitmap(ret) - ret = path + sprintf("%03d", tr_type_data.id_number) + optional_suffix + suffix - return ret if pbResolveBitmap(ret) - end - ret = path + tr_type_data.id.to_s + suffix - return ret if pbResolveBitmap(ret) - ret = path + sprintf("%03d", tr_type_data.id_number) + suffix - return (pbResolveBitmap(ret)) ? ret : nil - end - - def self.charset_filename(tr_type) - return self.check_file(tr_type, "Graphics/Characters/trainer_") - end - - def self.charset_filename_brief(tr_type) - ret = self.charset_filename(tr_type) - ret.slice!("Graphics/Characters/") if ret - return ret - end - - def self.front_sprite_filename(tr_type) - tr_type_data = self.try_get(tr_type) - path = "Graphics/Trainers/" - file = sprintf("trainer%03d", tr_type_data.id_number) - ret = path + file - return ret if pbResolveBitmap(ret) - end - - def self.player_front_sprite_filename(tr_type) - #outfit = ($Trainer) ? $Trainer.outfit : 0 - outfit=0 - return self.check_file(tr_type, "Graphics/Trainers/", sprintf("_%d", outfit)) - end - - def self.back_sprite_filename(tr_type) - return self.check_file(tr_type, "Graphics/Trainers/", "", "_back") - end - - def self.player_back_sprite_filename(tr_type) - #outfit = ($Trainer) ? $Trainer.outfit : 0 - outfit=0 - return self.check_file(tr_type, "Graphics/Trainers/", sprintf("_%d", outfit), "_back") - end - - def self.map_icon_filename(tr_type) - return self.check_file(tr_type, "Graphics/Pictures/mapPlayer") - end - - def self.player_map_icon_filename(tr_type) - outfit = ($Trainer) ? $Trainer.outfit : 0 - return self.check_file(tr_type, "Graphics/Pictures/mapPlayer", sprintf("_%d", outfit)) - end - - def initialize(hash) - @id = hash[:id] - @id_number = hash[:id_number] || -1 - @real_name = hash[:name] || "Unnamed" - @base_money = hash[:base_money] || 30 - @battle_BGM = hash[:battle_BGM] - @victory_ME = hash[:victory_ME] - @intro_ME = hash[:intro_ME] - @gender = hash[:gender] || 2 - @skill_level = hash[:skill_level] || @base_money - @skill_code = hash[:skill_code] - end - - # @return [String] the translated name of this trainer type - def name - return pbGetMessage(MessageTypes::TrainerTypes, @id_number) - end - - def male?; return @gender == 0; end - def female?; return @gender == 1; end - end -end - -#=============================================================================== -# Deprecated methods -#=============================================================================== -# @deprecated This alias is slated to be removed in v20. -def pbGetTrainerTypeData(tr_type) - Deprecation.warn_method('pbGetTrainerTypeData', 'v20', 'GameData::TrainerType.get(trainer_type)') - return GameData::TrainerType.get(tr_type) -end - -# @deprecated This alias is slated to be removed in v20. -def pbTrainerCharFile(tr_type) # Used by the phone - Deprecation.warn_method('pbTrainerCharFile', 'v20', 'GameData::TrainerType.charset_filename(trainer_type)') - return GameData::TrainerType.charset_filename(tr_type) -end - -# @deprecated This alias is slated to be removed in v20. -def pbTrainerCharNameFile(tr_type) # Used by Battle Frontier and compiler - Deprecation.warn_method('pbTrainerCharNameFile', 'v20', 'GameData::TrainerType.charset_filename_brief(trainer_type)') - return GameData::TrainerType.charset_filename_brief(tr_type) -end - -# @deprecated This alias is slated to be removed in v20. -def pbTrainerSpriteFile(tr_type) - Deprecation.warn_method('pbTrainerSpriteFile', 'v20', 'GameData::TrainerType.front_sprite_filename(trainer_type)') - return GameData::TrainerType.front_sprite_filename(tr_type) -end - -# @deprecated This alias is slated to be removed in v20. -def pbTrainerSpriteBackFile(tr_type) - Deprecation.warn_method('pbTrainerSpriteBackFile', 'v20', 'GameData::TrainerType.back_sprite_filename(trainer_type)') - return GameData::TrainerType.back_sprite_filename(tr_type) -end - -# @deprecated This alias is slated to be removed in v20. -def pbPlayerSpriteFile(tr_type) - Deprecation.warn_method('pbPlayerSpriteFile', 'v20', 'GameData::TrainerType.player_front_sprite_filename(trainer_type)') - return GameData::TrainerType.player_front_sprite_filename(tr_type) -end - -# @deprecated This alias is slated to be removed in v20. -def pbPlayerSpriteBackFile(tr_type) - Deprecation.warn_method('pbPlayerSpriteBackFile', 'v20', 'GameData::TrainerType.player_back_sprite_filename(trainer_type)') - return GameData::TrainerType.player_back_sprite_filename(tr_type) -end - -# @deprecated This alias is slated to be removed in v20. -def pbTrainerHeadFile(tr_type) - Deprecation.warn_method('pbTrainerHeadFile', 'v20', 'GameData::TrainerType.map_icon_filename(trainer_type)') - return GameData::TrainerType.map_icon_filename(tr_type) -end - -# @deprecated This alias is slated to be removed in v20. -def pbPlayerHeadFile(tr_type) - Deprecation.warn_method('pbPlayerHeadFile', 'v20', 'GameData::TrainerType.player_map_icon_filename(trainer_type)') - return GameData::TrainerType.player_map_icon_filename(tr_type) -end diff --git a/Data/Scripts/010_Data/002_PBS data/013_Trainer.rb b/Data/Scripts/010_Data/002_PBS data/013_Trainer.rb deleted file mode 100644 index 2e76a0f86..000000000 --- a/Data/Scripts/010_Data/002_PBS data/013_Trainer.rb +++ /dev/null @@ -1,387 +0,0 @@ -module GameData - class Trainer - attr_reader :id - attr_reader :id_number - attr_reader :trainer_type - attr_reader :real_name - attr_reader :version - attr_reader :items - attr_reader :real_lose_text - attr_reader :pokemon - - DATA = {} - DATA_FILENAME = "trainers.dat" - - SCHEMA = { - "Items" => [:items, "*e", :Item], - "LoseText" => [:lose_text, "s"], - "Pokemon" => [:pokemon, "ev", :Species], # Species, level - "Form" => [:form, "u"], - "Name" => [:name, "s"], - "Moves" => [:moves, "*e", :Move], - "Ability" => [:ability, "s"], - "AbilityIndex" => [:ability_index, "u"], - "Item" => [:item, "e", :Item], - "Gender" => [:gender, "e", { "M" => 0, "m" => 0, "Male" => 0, "male" => 0, "0" => 0, - "F" => 1, "f" => 1, "Female" => 1, "female" => 1, "1" => 1 }], - "Nature" => [:nature, "e", :Nature], - "IV" => [:iv, "uUUUUU"], - "EV" => [:ev, "uUUUUU"], - "Happiness" => [:happiness, "u"], - "Shiny" => [:shininess, "b"], - "Shadow" => [:shadowness, "b"], - "Ball" => [:poke_ball, "s"], - } - - extend ClassMethods - include InstanceMethods - - # @param tr_type [Symbol, String] - # @param tr_name [String] - # @param tr_version [Integer, nil] - # @return [Boolean] whether the given other is defined as a self - def self.exists?(tr_type, tr_name, tr_version = 0) - validate tr_type => [Symbol, String] - validate tr_name => [String] - key = [tr_type.to_sym, tr_name, tr_version] - return !self::DATA[key].nil? - end - - # @param tr_type [Symbol, String] - # @param tr_name [String] - # @param tr_version [Integer, nil] - # @return [self] - def self.get(tr_type, tr_name, tr_version = 0) - validate tr_type => [Symbol, String] - validate tr_name => [String] - key = [tr_type.to_sym, tr_name, tr_version] - raise "Unknown trainer #{tr_type} #{tr_name} #{tr_version}." unless self::DATA.has_key?(key) - return self::DATA[key] - end - - def list_all - return self::DATA - end - - # @param tr_type [Symbol, String] - # @param tr_name [String] - # @param tr_version [Integer, nil] - # @return [self, nil] - def self.try_get(tr_type, tr_name, tr_version = 0) - validate tr_type => [Symbol, String] - validate tr_name => [String] - key = [tr_type.to_sym, tr_name, tr_version] - return (self::DATA.has_key?(key)) ? self::DATA[key] : nil - end - - def self.list_all() - return self::DATA - end - - def initialize(hash) - @id = hash[:id] - @id_number = hash[:id_number] - @trainer_type = hash[:trainer_type] - @real_name = hash[:name] || "Unnamed" - @version = hash[:version] || 0 - @items = hash[:items] || [] - @real_lose_text = hash[:lose_text] || "..." - @pokemon = hash[:pokemon] || [] - @pokemon.each do |pkmn| - GameData::Stat.each_main do |s| - pkmn[:iv][s.id] ||= 0 if pkmn[:iv] - pkmn[:ev][s.id] ||= 0 if pkmn[:ev] - end - end - end - - # @return [String] the translated name of this trainer - def name - return pbGetMessageFromHash(MessageTypes::TrainerNames, @real_name) - end - - # @return [String] the translated in-battle lose message of this trainer - def lose_text - return pbGetMessageFromHash(MessageTypes::TrainerLoseText, @real_lose_text) - end - - def replace_species_with_placeholder(species) - case species - when Settings::RIVAL_STARTER_PLACEHOLDER_SPECIES - return pbGet(Settings::RIVAL_STARTER_PLACEHOLDER_VARIABLE) - when Settings::VAR_1_PLACEHOLDER_SPECIES - return pbGet(1) - when Settings::VAR_2_PLACEHOLDER_SPECIES - return pbGet(2) - when Settings::VAR_3_PLACEHOLDER_SPECIES - return pbGet(3) - end - end - - def generateRandomChampionSpecies(old_species) - customsList = getCustomSpeciesList() - bst_range = pbGet(VAR_RANDOMIZER_TRAINER_BST) - new_species = $game_switches[SWITCH_RANDOM_GYM_CUSTOMS] ? getSpecies(getNewCustomSpecies(old_species, customsList, bst_range)) : getSpecies(getNewSpecies(old_species, bst_range)) - #every pokemon should be fully evolved - evolved_species_id = getEvolution(new_species) - evolved_species_id = getEvolution(evolved_species_id) - evolved_species_id = getEvolution(evolved_species_id) - evolved_species_id = getEvolution(evolved_species_id) - return getSpecies(evolved_species_id) - end - - def generateRandomGymSpecies(old_species) - gym_index = pbGet(VAR_CURRENT_GYM_TYPE) - return old_species if gym_index == -1 - return generateRandomChampionSpecies(old_species) if gym_index == 999 - type_id = pbGet(VAR_GYM_TYPES_ARRAY)[gym_index] - return old_species if type_id == -1 - - customsList = getCustomSpeciesList() - bst_range = pbGet(VAR_RANDOMIZER_TRAINER_BST) - gym_type = GameData::Type.get(type_id) - while true - new_species = $game_switches[SWITCH_RANDOM_GYM_CUSTOMS] ? getSpecies(getNewCustomSpecies(old_species, customsList, bst_range)) : getSpecies(getNewSpecies(old_species, bst_range)) - if new_species.hasType?(gym_type) - return new_species - end - end - end - - def replace_species_to_randomized_gym(species, trainerId, pokemonIndex) - return if !pokemonIndex - return if !trainerId - return if !species - if $PokemonGlobal.randomGymTrainersHash == nil - $PokemonGlobal.randomGymTrainersHash = {} - end - if $game_switches[SWITCH_RANDOM_GYM_PERSIST_TEAMS] && $PokemonGlobal.randomGymTrainersHash != nil - if $PokemonGlobal.randomGymTrainersHash[trainerId] && $PokemonGlobal.randomGymTrainersHash[trainerId].length >= $PokemonGlobal.randomTrainersHash[trainerId].length - newSpecies = getSpecies($PokemonGlobal.randomGymTrainersHash[trainerId][pokemonIndex]) - return newSpecies if newSpecies - return species - end - end - new_species = generateRandomGymSpecies(species) - if $game_switches[SWITCH_RANDOM_GYM_PERSIST_TEAMS] - add_generated_species_to_gym_array(new_species, trainerId) - end - return new_species - end - - def add_generated_species_to_gym_array(new_species, trainerId) - if (new_species.is_a?(Symbol)) - id = new_species - else - id = new_species.id_number - end - - expected_team_length = 1 - expected_team_length = $PokemonGlobal.randomTrainersHash[trainerId].length if $PokemonGlobal.randomTrainersHash[trainerId] - new_team = [] - if $PokemonGlobal.randomGymTrainersHash[trainerId] - new_team = $PokemonGlobal.randomGymTrainersHash[trainerId] - end - if new_team.length < expected_team_length - new_team << id - end - $PokemonGlobal.randomGymTrainersHash[trainerId] = new_team - end - - def replace_species_to_randomized_regular(species, trainerId, pokemonIndex) - if $PokemonGlobal.randomTrainersHash[trainerId] == nil - Kernel.pbMessage(_INTL("The trainers need to be re-shuffled.")) - Kernel.pbShuffleTrainers() - end - new_species_dex = $PokemonGlobal.randomTrainersHash[trainerId][pokemonIndex] - return getSpecies(new_species_dex) - end - - def isGymBattle - return ($game_switches[SWITCH_RANDOM_TRAINERS] && ($game_variables[VAR_CURRENT_GYM_TYPE] != -1) || ($game_switches[SWITCH_FIRST_RIVAL_BATTLE] && $game_switches[SWITCH_RANDOM_STARTERS])) - end - - def replace_species_to_randomized(species, trainerId, pokemonIndex) - return species if $game_switches[SWITCH_DONT_RANDOMIZE] - return species if $game_switches[SWITCH_FIRST_RIVAL_BATTLE] - return species if getDexNumberForSpecies(species) >= Settings::ZAPMOLCUNO_NB - if isGymBattle() && $game_switches[SWITCH_RANDOMIZE_GYMS_SEPARATELY] - return replace_species_to_randomized_gym(species, trainerId, pokemonIndex) - end - return replace_species_to_randomized_regular(species, trainerId, pokemonIndex) - - end - - def replaceSingleSpeciesModeIfApplicable(species) - return species if getDexNumberForSpecies(species) >= Settings::ZAPMOLCUNO_NB - if $game_switches[SWITCH_SINGLE_POKEMON_MODE] - if $game_switches[SWITCH_SINGLE_POKEMON_MODE_HEAD] - return replaceFusionsHeadWithSpecies(species) - elsif $game_switches[SWITCH_SINGLE_POKEMON_MODE_BODY] - return replaceFusionsBodyWithSpecies(species) - elsif $game_switches[SWITCH_SINGLE_POKEMON_MODE_RANDOM] - if (rand(2) == 0) - return replaceFusionsHeadWithSpecies(species) - else - return replaceFusionsBodyWithSpecies(species) - end - end - end - return species - end - - def replaceFusionsHeadWithSpecies(species) - speciesId = getDexNumberForSpecies(species) - if speciesId > NB_POKEMON - bodyPoke = getBodyID(speciesId) - headPoke = pbGet(VAR_SINGLE_POKEMON_MODE) - newSpecies = bodyPoke * NB_POKEMON + headPoke - return getPokemon(newSpecies) - end - return species - end - - def replaceFusionsBodyWithSpecies(species) - speciesId = getDexNumberForSpecies(species) - if speciesId > NB_POKEMON - bodyPoke = pbGet(VAR_SINGLE_POKEMON_MODE) - headPoke = getHeadID(species) - newSpecies = bodyPoke * NB_POKEMON + headPoke - return getPokemon(newSpecies) - end - return species - end - - def to_trainer - placeholder_species = [Settings::RIVAL_STARTER_PLACEHOLDER_SPECIES, - Settings::VAR_1_PLACEHOLDER_SPECIES, - Settings::VAR_2_PLACEHOLDER_SPECIES, - Settings::VAR_3_PLACEHOLDER_SPECIES] - # Determine trainer's name - tr_name = self.name - Settings::RIVAL_NAMES.each do |rival| - next if rival[0] != @trainer_type || !$game_variables[rival[1]].is_a?(String) - tr_name = $game_variables[rival[1]] - break - end - # Create trainer object - trainer = NPCTrainer.new(tr_name, @trainer_type) - trainer.id = $Trainer.make_foreign_ID - trainer.items = @items.clone - trainer.lose_text = self.lose_text - - isRematch = $game_switches[SWITCH_IS_REMATCH] - isPlayingRandomized = $game_switches[SWITCH_RANDOM_TRAINERS] && !$game_switches[SWITCH_FIRST_RIVAL_BATTLE] - rematchId = getRematchId(trainer.name, trainer.trainer_type) - - # Create each Pokémon owned by the trainer - index = 0 - @pokemon.each do |pkmn_data| - #replace placeholder species infinite fusion edit - species = GameData::Species.get(pkmn_data[:species]).species - original_species = species - if placeholder_species.include?(species) - species = replace_species_with_placeholder(species) - else - species = replace_species_to_randomized(species, self.id, index) if isPlayingRandomized - end - species = replaceSingleSpeciesModeIfApplicable(species) - if $game_switches[SWITCH_REVERSED_MODE] - species = reverseFusionSpecies(species) - end - level = pkmn_data[:level] - if $game_switches[SWITCH_GAME_DIFFICULTY_HARD] - level = (level * Settings::HARD_MODE_LEVEL_MODIFIER).ceil - if level > Settings::MAXIMUM_LEVEL - level = Settings::MAXIMUM_LEVEL - end - end - - if $game_switches[Settings::OVERRIDE_BATTLE_LEVEL_SWITCH] - override_level = $game_variables[Settings::OVERRIDE_BATTLE_LEVEL_VALUE_VAR] - if override_level.is_a?(Integer) - level = override_level - end - end - #### - - #trainer rematch infinite fusion edit - if isRematch - nbRematch = getNumberRematch(rematchId) - level = getRematchLevel(level, nbRematch) - species = getSpecies(evolveRematchPokemon(nbRematch, species)).id - end - pkmn = Pokemon.new(species, level, trainer, false) - - trainer.party.push(pkmn) - # Set Pokémon's properties if defined - if pkmn_data[:form] - pkmn.forced_form = pkmn_data[:form] if MultipleForms.hasFunction?(species, "getForm") - pkmn.form_simple = pkmn_data[:form] - end - - if $game_switches[SWITCH_RANDOM_HELD_ITEMS] - pkmn.item = pbGetRandomHeldItem().id - else - pkmn.item = pkmn_data[:item] - end - if pkmn_data[:moves] && pkmn_data[:moves].length > 0 && original_species == species - pkmn_data[:moves].each { |move| pkmn.learn_move(move) } - else - pkmn.reset_moves - end - pkmn.ability_index = pkmn_data[:ability_index] - pkmn.ability = pkmn_data[:ability] - - if $game_switches[SWITCH_DOUBLE_ABILITIES] && pkmn.isFusion? - secondary_ability_index = pkmn.ability_index == 0 ? 1 : 0 - pkmn.ability2_index = secondary_ability_index - pkmn.ability2 = pkmn.getAbilityList[secondary_ability_index][0] - #print _INTL("Primary: {1}, Secondary: {2}",pkmn.ability.id, pkmn.ability2.id) - end - - pkmn.gender = pkmn_data[:gender] || ((trainer.male?) ? 0 : 1) - pkmn.shiny = (pkmn_data[:shininess]) ? true : false - if pkmn_data[:nature] - pkmn.nature = pkmn_data[:nature] - else - nature = pkmn.species_data.id_number + GameData::TrainerType.get(trainer.trainer_type).id_number - pkmn.nature = nature % (GameData::Nature::DATA.length / 2) - end - GameData::Stat.each_main do |s| - if pkmn_data[:iv] - pkmn.iv[s.id] = pkmn_data[:iv][s.id] - else - pkmn.iv[s.id] = [pkmn_data[:level] / 2, Pokemon::IV_STAT_LIMIT].min - end - if pkmn_data[:ev] - pkmn.ev[s.id] = pkmn_data[:ev][s.id] - else - pkmn.ev[s.id] = [pkmn_data[:level] * 3 / 2, Pokemon::EV_LIMIT / 6].min - end - end - pkmn.happiness = pkmn_data[:happiness] if pkmn_data[:happiness] - pkmn.name = pkmn_data[:name] if pkmn_data[:name] && !pkmn_data[:name].empty? - if pkmn_data[:shadowness] - pkmn.makeShadow - pkmn.update_shadow_moves(true) - pkmn.shiny = false - end - pkmn.poke_ball = pkmn_data[:poke_ball] if pkmn_data[:poke_ball] - pkmn.calc_stats - - index += 1 - end - return trainer - end - end -end - -#=============================================================================== -# Deprecated methods -#=============================================================================== -# @deprecated This alias is slated to be removed in v20. -def pbGetTrainerData(tr_type, tr_name, tr_version = 0) - Deprecation.warn_method('pbGetTrainerData', 'v20', 'GameData::Trainer.get(tr_type, tr_name, tr_version)') - return GameData::Trainer.get(tr_type, tr_name, tr_version) -end diff --git a/Data/Scripts/010_Data/002_PBS data/013_TrainerExpert.rb b/Data/Scripts/010_Data/002_PBS data/013_TrainerExpert.rb deleted file mode 100644 index bb33b3472..000000000 --- a/Data/Scripts/010_Data/002_PBS data/013_TrainerExpert.rb +++ /dev/null @@ -1,14 +0,0 @@ -module GameData - class TrainerExpert < Trainer - DATA_FILENAME = "trainers_expert.dat" - end -end - -#=============================================================================== -# Deprecated methods -#=============================================================================== -# @deprecated This alias is slated to be removed in v20. -def pbGetTrainerData(tr_type, tr_name, tr_version = 0) - Deprecation.warn_method('pbGetTrainerData', 'v20', 'GameData::Trainer.get(tr_type, tr_name, tr_version)') - return GameData::Trainer.get(tr_type, tr_name, tr_version) -end diff --git a/Data/Scripts/010_Data/002_PBS data/013_TrainerModern.rb b/Data/Scripts/010_Data/002_PBS data/013_TrainerModern.rb deleted file mode 100644 index 1b713fae4..000000000 --- a/Data/Scripts/010_Data/002_PBS data/013_TrainerModern.rb +++ /dev/null @@ -1,369 +0,0 @@ -module GameData - class TrainerModern - attr_reader :id - attr_reader :id_number - attr_reader :trainer_type - attr_reader :real_name - attr_reader :version - attr_reader :items - attr_reader :real_lose_text - attr_reader :pokemon - - DATA = {} - DATA_FILENAME = "trainers_remix.dat" - - SCHEMA = { - "Items" => [:items, "*e", :Item], - "LoseText" => [:lose_text, "s"], - "Pokemon" => [:pokemon, "ev", :Species], # Species, level - "Form" => [:form, "u"], - "Name" => [:name, "s"], - "Moves" => [:moves, "*e", :Move], - "Ability" => [:ability, "s"], - "AbilityIndex" => [:ability_index, "u"], - "Item" => [:item, "e", :Item], - "Gender" => [:gender, "e", { "M" => 0, "m" => 0, "Male" => 0, "male" => 0, "0" => 0, - "F" => 1, "f" => 1, "Female" => 1, "female" => 1, "1" => 1 }], - "Nature" => [:nature, "e", :Nature], - "IV" => [:iv, "uUUUUU"], - "EV" => [:ev, "uUUUUU"], - "Happiness" => [:happiness, "u"], - "Shiny" => [:shininess, "b"], - "Shadow" => [:shadowness, "b"], - "Ball" => [:poke_ball, "s"], - } - - extend ClassMethods - include InstanceMethods - - # @param tr_type [Symbol, String] - # @param tr_name [String] - # @param tr_version [Integer, nil] - # @return [Boolean] whether the given other is defined as a self - def self.exists?(tr_type, tr_name, tr_version = 0) - validate tr_type => [Symbol, String] - validate tr_name => [String] - key = [tr_type.to_sym, tr_name, tr_version] - return !self::DATA[key].nil? - end - - # @param tr_type [Symbol, String] - # @param tr_name [String] - # @param tr_version [Integer, nil] - # @return [self] - def self.get(tr_type, tr_name, tr_version = 0) - validate tr_type => [Symbol, String] - validate tr_name => [String] - key = [tr_type.to_sym, tr_name, tr_version] - raise "Unknown trainer #{tr_type} #{tr_name} #{tr_version}." unless self::DATA.has_key?(key) - return self::DATA[key] - end - - # @param tr_type [Symbol, String] - # @param tr_name [String] - # @param tr_version [Integer, nil] - # @return [self, nil] - def self.try_get(tr_type, tr_name, tr_version = 0) - validate tr_type => [Symbol, String] - validate tr_name => [String] - key = [tr_type.to_sym, tr_name, tr_version] - return (self::DATA.has_key?(key)) ? self::DATA[key] : nil - end - - def self.list_all() - return self::DATA - end - - def initialize(hash) - @id = hash[:id] - @id_number = hash[:id_number] - @trainer_type = hash[:trainer_type] - @real_name = hash[:name] || "Unnamed" - @version = hash[:version] || 0 - @items = hash[:items] || [] - @real_lose_text = hash[:lose_text] || "..." - @pokemon = hash[:pokemon] || [] - @pokemon.each do |pkmn| - GameData::Stat.each_main do |s| - pkmn[:iv][s.id] ||= 0 if pkmn[:iv] - pkmn[:ev][s.id] ||= 0 if pkmn[:ev] - end - end - end - - # @return [String] the translated name of this trainer - def name - return pbGetMessageFromHash(MessageTypes::TrainerNames, @real_name) - end - - # @return [String] the translated in-battle lose message of this trainer - def lose_text - return pbGetMessageFromHash(MessageTypes::TrainerLoseText, @real_lose_text) - end - - def replace_species_with_placeholder(species) - case species - when Settings::RIVAL_STARTER_PLACEHOLDER_SPECIES - return pbGet(Settings::RIVAL_STARTER_PLACEHOLDER_VARIABLE) - when Settings::VAR_1_PLACEHOLDER_SPECIES - return pbGet(1) - when Settings::VAR_2_PLACEHOLDER_SPECIES - return pbGet(2) - when Settings::VAR_3_PLACEHOLDER_SPECIES - return pbGet(3) - end - end - - def generateRandomChampionSpecies(old_species) - customsList = getCustomSpeciesList() - bst_range = pbGet(VAR_RANDOMIZER_TRAINER_BST) - new_species = $game_switches[SWITCH_RANDOM_GYM_CUSTOMS] ? getSpecies(getNewCustomSpecies(old_species, customsList, bst_range)) : getSpecies(getNewSpecies(old_species, bst_range)) - #every pokemon should be fully evolved - evolved_species_id = getEvolution(new_species) - evolved_species_id = getEvolution(evolved_species_id) - evolved_species_id = getEvolution(evolved_species_id) - evolved_species_id = getEvolution(evolved_species_id) - return getSpecies(evolved_species_id) - end - - def generateRandomGymSpecies(old_species) - gym_index = pbGet(VAR_CURRENT_GYM_TYPE) - return old_species if gym_index == -1 - return generateRandomChampionSpecies(old_species) if gym_index == 999 - type_id = pbGet(VAR_GYM_TYPES_ARRAY)[gym_index] - return old_species if type_id == -1 - - customsList = getCustomSpeciesList() - bst_range = pbGet(VAR_RANDOMIZER_TRAINER_BST) - gym_type = GameData::Type.get(type_id) - while true - new_species = $game_switches[SWITCH_RANDOM_GYM_CUSTOMS] ? getSpecies(getNewCustomSpecies(old_species, customsList, bst_range)) : getSpecies(getNewSpecies(old_species, bst_range)) - if new_species.hasType?(gym_type) - return new_species - end - end - end - - def replace_species_to_randomized_gym(species, trainerId, pokemonIndex) - if $PokemonGlobal.randomGymTrainersHash == nil - $PokemonGlobal.randomGymTrainersHash = {} - end - if $game_switches[SWITCH_RANDOM_GYM_PERSIST_TEAMS] && $PokemonGlobal.randomGymTrainersHash != nil - if $PokemonGlobal.randomGymTrainersHash[trainerId] != nil && $PokemonGlobal.randomGymTrainersHash[trainerId].length >= $PokemonGlobal.randomTrainersHash[trainerId].length - return getSpecies($PokemonGlobal.randomGymTrainersHash[trainerId][pokemonIndex]) - end - end - new_species = generateRandomGymSpecies(species) - if $game_switches[SWITCH_RANDOM_GYM_PERSIST_TEAMS] - add_generated_species_to_gym_array(new_species, trainerId) - end - return new_species - end - - def add_generated_species_to_gym_array(new_species, trainerId) - if (new_species.is_a?(Symbol)) - id = new_species - else - id = new_species.id_number - end - - expected_team_length = 1 - expected_team_length = $PokemonGlobal.randomTrainersHash[trainerId].length if $PokemonGlobal.randomTrainersHash[trainerId] - new_team = [] - if $PokemonGlobal.randomGymTrainersHash[trainerId] - new_team = $PokemonGlobal.randomGymTrainersHash[trainerId] - end - if new_team.length < expected_team_length - new_team << id - end - $PokemonGlobal.randomGymTrainersHash[trainerId] = new_team - end - - def replace_species_to_randomized_regular(species, trainerId, pokemonIndex) - if $PokemonGlobal.randomTrainersHash[trainerId] == nil - Kernel.pbMessage(_INTL("The trainers need to be re-shuffled.")) - Kernel.pbShuffleTrainers() - end - new_species_dex = $PokemonGlobal.randomTrainersHash[trainerId][pokemonIndex] - return getSpecies(new_species_dex) - end - - def isGymBattle - return ($game_switches[SWITCH_RANDOM_TRAINERS] && ($game_variables[VAR_CURRENT_GYM_TYPE] != -1) || ($game_switches[SWITCH_FIRST_RIVAL_BATTLE] && $game_switches[SWITCH_RANDOM_STARTERS])) - end - - def replace_species_to_randomized(species, trainerId, pokemonIndex) - return species if $game_switches[SWITCH_FIRST_RIVAL_BATTLE] - return species if $game_switches[SWITCH_DONT_RANDOMIZE] - if isGymBattle() && $game_switches[SWITCH_RANDOMIZE_GYMS_SEPARATELY] - return replace_species_to_randomized_gym(species, trainerId, pokemonIndex) - end - return replace_species_to_randomized_regular(species, trainerId, pokemonIndex) - - end - - def replaceSingleSpeciesModeIfApplicable(species) - if $game_switches[SWITCH_SINGLE_POKEMON_MODE] - if $game_switches[SWITCH_SINGLE_POKEMON_MODE_HEAD] - return replaceFusionsHeadWithSpecies(species) - elsif $game_switches[SWITCH_SINGLE_POKEMON_MODE_BODY] - return replaceFusionsBodyWithSpecies(species) - elsif $game_switches[SWITCH_SINGLE_POKEMON_MODE_RANDOM] - if (rand(2) == 0) - return replaceFusionsHeadWithSpecies(species) - else - return replaceFusionsBodyWithSpecies(species) - end - end - end - return species - end - - def replaceFusionsHeadWithSpecies(species) - speciesId = getDexNumberForSpecies(species) - if speciesId > NB_POKEMON - bodyPoke = getBodyID(speciesId) - headPoke = pbGet(VAR_SINGLE_POKEMON_MODE) - newSpecies = bodyPoke * NB_POKEMON + headPoke - return getPokemon(newSpecies) - end - return species - end - - def replaceFusionsBodyWithSpecies(species) - speciesId = getDexNumberForSpecies(species) - if speciesId > NB_POKEMON - bodyPoke = pbGet(VAR_SINGLE_POKEMON_MODE) - headPoke = getHeadID(species) - newSpecies = bodyPoke * NB_POKEMON + headPoke - return getPokemon(newSpecies) - end - return species - end - - def to_trainer - placeholder_species = [Settings::RIVAL_STARTER_PLACEHOLDER_SPECIES, - Settings::VAR_1_PLACEHOLDER_SPECIES, - Settings::VAR_2_PLACEHOLDER_SPECIES, - Settings::VAR_3_PLACEHOLDER_SPECIES] - # Determine trainer's name - tr_name = self.name - Settings::RIVAL_NAMES.each do |rival| - next if rival[0] != @trainer_type || !$game_variables[rival[1]].is_a?(String) - tr_name = $game_variables[rival[1]] - break - end - # Create trainer object - trainer = NPCTrainer.new(tr_name, @trainer_type) - trainer.id = $Trainer.make_foreign_ID - trainer.items = @items.clone - trainer.lose_text = self.lose_text - - isRematch = $game_switches[SWITCH_IS_REMATCH] - isPlayingRandomized = $game_switches[SWITCH_RANDOM_TRAINERS] && !$game_switches[SWITCH_FIRST_RIVAL_BATTLE] - rematchId = getRematchId(trainer.name, trainer.trainer_type) - - # Create each Pokémon owned by the trainer - index = 0 - @pokemon.each do |pkmn_data| - #replace placeholder species infinite fusion edit - species = GameData::Species.get(pkmn_data[:species]).species - original_species = species - if placeholder_species.include?(species) - species = replace_species_with_placeholder(species) - else - species = replace_species_to_randomized(species, self.id, index) if isPlayingRandomized - end - species = replaceSingleSpeciesModeIfApplicable(species) - if $game_switches[SWITCH_REVERSED_MODE] - species = reverseFusionSpecies(species) - end - level = pkmn_data[:level] - if $game_switches[SWITCH_GAME_DIFFICULTY_HARD] - level = (level * Settings::HARD_MODE_LEVEL_MODIFIER).ceil - if level > Settings::MAXIMUM_LEVEL - level = Settings::MAXIMUM_LEVEL - end - end - - if $game_switches[Settings::OVERRIDE_BATTLE_LEVEL_SWITCH] - override_level = $game_variables[Settings::OVERRIDE_BATTLE_LEVEL_VALUE_VAR] - if override_level.is_a?(Integer) - level = override_level - end - end - #### - - #trainer rematch infinite fusion edit - if isRematch - nbRematch = getNumberRematch(rematchId) - level = getRematchLevel(level, nbRematch) - species = evolveRematchPokemon(nbRematch, species) - end - - pkmn = Pokemon.new(species, level, trainer, false) - - trainer.party.push(pkmn) - # Set Pokémon's properties if defined - if pkmn_data[:form] - pkmn.forced_form = pkmn_data[:form] if MultipleForms.hasFunction?(species, "getForm") - pkmn.form_simple = pkmn_data[:form] - end - - if $game_switches[SWITCH_RANDOM_HELD_ITEMS] - pkmn.item = pbGetRandomHeldItem().id - else - pkmn.item = pkmn_data[:item] - end - if pkmn_data[:moves] && pkmn_data[:moves].length > 0 && original_species == species - pkmn_data[:moves].each { |move| pkmn.learn_move(move) } - else - pkmn.reset_moves - end - pkmn.ability_index = pkmn_data[:ability_index] - pkmn.ability = pkmn_data[:ability] - pkmn.gender = pkmn_data[:gender] || ((trainer.male?) ? 0 : 1) - pkmn.shiny = (pkmn_data[:shininess]) ? true : false - if pkmn_data[:nature] - pkmn.nature = pkmn_data[:nature] - else - nature = pkmn.species_data.id_number + GameData::TrainerType.get(trainer.trainer_type).id_number - pkmn.nature = nature % (GameData::Nature::DATA.length / 2) - end - GameData::Stat.each_main do |s| - if pkmn_data[:iv] - pkmn.iv[s.id] = pkmn_data[:iv][s.id] - else - pkmn.iv[s.id] = [pkmn_data[:level] / 2, Pokemon::IV_STAT_LIMIT].min - end - if pkmn_data[:ev] - pkmn.ev[s.id] = pkmn_data[:ev][s.id] - else - pkmn.ev[s.id] = [pkmn_data[:level] * 3 / 2, Pokemon::EV_LIMIT / 6].min - end - end - pkmn.happiness = pkmn_data[:happiness] if pkmn_data[:happiness] - pkmn.name = pkmn_data[:name] if pkmn_data[:name] && !pkmn_data[:name].empty? - if pkmn_data[:shadowness] - pkmn.makeShadow - pkmn.update_shadow_moves(true) - pkmn.shiny = false - end - pkmn.poke_ball = pkmn_data[:poke_ball] if pkmn_data[:poke_ball] - pkmn.calc_stats - - index += 1 - end - return trainer - end - end -end - -#=============================================================================== -# Deprecated methods -#=============================================================================== -# @deprecated This alias is slated to be removed in v20. -def pbGetTrainerData(tr_type, tr_name, tr_version = 0) - Deprecation.warn_method('pbGetTrainerData', 'v20', 'GameData::Trainer.get(tr_type, tr_name, tr_version)') - return GameData::Trainer.get(tr_type, tr_name, tr_version) -end diff --git a/Data/Scripts/010_Data/002_PBS data/014_Metadata.rb b/Data/Scripts/010_Data/002_PBS data/014_Metadata.rb deleted file mode 100644 index 6149254df..000000000 --- a/Data/Scripts/010_Data/002_PBS data/014_Metadata.rb +++ /dev/null @@ -1,147 +0,0 @@ -module GameData - class Metadata - attr_reader :id - attr_reader :home - attr_reader :wild_battle_BGM - attr_reader :trainer_battle_BGM - attr_reader :wild_victory_ME - attr_reader :trainer_victory_ME - attr_reader :wild_capture_ME - attr_reader :surf_BGM - attr_reader :bicycle_BGM - attr_reader :player_A - attr_reader :player_B - attr_reader :player_C - attr_reader :player_D - attr_reader :player_E - attr_reader :player_F - attr_reader :player_G - attr_reader :player_H - - DATA = {} - DATA_FILENAME = "metadata.dat" - - SCHEMA = { - "Home" => [1, "vuuu"], - "WildBattleBGM" => [2, "s"], - "TrainerBattleBGM" => [3, "s"], - "WildVictoryME" => [4, "s"], - "TrainerVictoryME" => [5, "s"], - "WildCaptureME" => [6, "s"], - "SurfBGM" => [7, "s"], - "BicycleBGM" => [8, "s"], - "PlayerA" => [9, "esssssss", :TrainerType], - "PlayerB" => [10, "esssssss", :TrainerType], - "PlayerC" => [11, "esssssss", :TrainerType], - "PlayerD" => [12, "esssssss", :TrainerType], - "PlayerE" => [13, "esssssss", :TrainerType], - "PlayerF" => [14, "esssssss", :TrainerType], - "PlayerG" => [15, "esssssss", :TrainerType], - "PlayerH" => [16, "esssssss", :TrainerType] - } - - extend ClassMethodsIDNumbers - include InstanceMethods - - def self.editor_properties - return [ - ["Home", MapCoordsFacingProperty, _INTL("Map ID and X and Y coordinates of where the player goes if no Pokémon Center was entered after a loss.")], - ["WildBattleBGM", BGMProperty, _INTL("Default BGM for wild Pokémon battles.")], - ["TrainerBattleBGM", BGMProperty, _INTL("Default BGM for Trainer battles.")], - ["WildVictoryME", MEProperty, _INTL("Default ME played after winning a wild Pokémon battle.")], - ["TrainerVictoryME", MEProperty, _INTL("Default ME played after winning a Trainer battle.")], - ["WildCaptureME", MEProperty, _INTL("Default ME played after catching a Pokémon.")], - ["SurfBGM", BGMProperty, _INTL("BGM played while surfing.")], - ["BicycleBGM", BGMProperty, _INTL("BGM played while on a bicycle.")], - ["PlayerA", PlayerProperty, _INTL("Specifies player A.")], - ["PlayerB", PlayerProperty, _INTL("Specifies player B.")], - ["PlayerC", PlayerProperty, _INTL("Specifies player C.")], - ["PlayerD", PlayerProperty, _INTL("Specifies player D.")], - ["PlayerE", PlayerProperty, _INTL("Specifies player E.")], - ["PlayerF", PlayerProperty, _INTL("Specifies player F.")], - ["PlayerG", PlayerProperty, _INTL("Specifies player G.")], - ["PlayerH", PlayerProperty, _INTL("Specifies player H.")] - ] - end - - def self.get - return DATA[0] - end - - def self.get_player(id) - return self.get.player_A - case id - when 0 then return self.get.player_A - when 1 then return self.get.player_B - when 2 then return self.get.player_C - when 3 then return self.get.player_D - when 4 then return self.get.player_E - when 5 then return self.get.player_F - when 6 then return self.get.player_G - when 7 then return self.get.player_H - end - return nil - end - - def initialize(hash) - @id = hash[:id] - @home = hash[:home] - @wild_battle_BGM = hash[:wild_battle_BGM] - @trainer_battle_BGM = hash[:trainer_battle_BGM] - @wild_victory_ME = hash[:wild_victory_ME] - @trainer_victory_ME = hash[:trainer_victory_ME] - @wild_capture_ME = hash[:wild_capture_ME] - @surf_BGM = hash[:surf_BGM] - @bicycle_BGM = hash[:bicycle_BGM] - @player_A = hash[:player_A] - @player_B = hash[:player_B] - @player_C = hash[:player_C] - @player_D = hash[:player_D] - @player_E = hash[:player_E] - @player_F = hash[:player_F] - @player_G = hash[:player_G] - @player_H = hash[:player_H] - end - - def property_from_string(str) - case str - when "Home" then return @home - when "WildBattleBGM" then return @wild_battle_BGM - when "TrainerBattleBGM" then return @trainer_battle_BGM - when "WildVictoryME" then return @wild_victory_ME - when "TrainerVictoryME" then return @trainer_victory_ME - when "WildCaptureME" then return @wild_capture_ME - when "SurfBGM" then return @surf_BGM - when "BicycleBGM" then return @bicycle_BGM - when "PlayerA" then return @player_A - when "PlayerB" then return @player_B - when "PlayerC" then return @player_C - when "PlayerD" then return @player_D - when "PlayerE" then return @player_E - when "PlayerF" then return @player_F - when "PlayerG" then return @player_G - when "PlayerH" then return @player_H - end - return nil - end - end -end - -#=============================================================================== -# Deprecated methods -#=============================================================================== -# @deprecated This alias is slated to be removed in v20. -def pbLoadMetadata - Deprecation.warn_method('pbLoadMetadata', 'v20', 'GameData::Metadata.get or GameData::MapMetadata.get(map_id)') - return nil -end - -# @deprecated This alias is slated to be removed in v20. -def pbGetMetadata(map_id, metadata_type) - if map_id == 0 # Global metadata - Deprecation.warn_method('pbGetMetadata', 'v20', 'GameData::Metadata.get.something') - else # Map metadata - Deprecation.warn_method('pbGetMetadata', 'v20', 'GameData::MapMetadata.get(map_id).something') - end - return nil -end diff --git a/Data/Scripts/010_Data/002_PBS data/015_MapMetadata.rb b/Data/Scripts/010_Data/002_PBS data/015_MapMetadata.rb deleted file mode 100644 index f3dc57946..000000000 --- a/Data/Scripts/010_Data/002_PBS data/015_MapMetadata.rb +++ /dev/null @@ -1,129 +0,0 @@ -module GameData - class MapMetadata - attr_reader :id - attr_reader :outdoor_map - attr_reader :announce_location - attr_reader :can_bicycle - attr_reader :always_bicycle - attr_reader :teleport_destination - attr_reader :weather - attr_reader :town_map_position - attr_reader :dive_map_id - attr_reader :dark_map - attr_reader :safari_map - attr_reader :snap_edges - attr_reader :random_dungeon - attr_reader :battle_background - attr_reader :wild_battle_BGM - attr_reader :trainer_battle_BGM - attr_reader :wild_victory_ME - attr_reader :trainer_victory_ME - attr_reader :wild_capture_ME - attr_reader :town_map_size - attr_reader :battle_environment - - DATA = {} - DATA_FILENAME = "map_metadata.dat" - - SCHEMA = { - "Outdoor" => [1, "b"], - "ShowArea" => [2, "b"], - "Bicycle" => [3, "b"], - "BicycleAlways" => [4, "b"], - "HealingSpot" => [5, "vuu"], - "Weather" => [6, "eu", :Weather], - "MapPosition" => [7, "uuu"], - "DiveMap" => [8, "v"], - "DarkMap" => [9, "b"], - "SafariMap" => [10, "b"], - "SnapEdges" => [11, "b"], - "Dungeon" => [12, "b"], - "BattleBack" => [13, "s"], - "WildBattleBGM" => [14, "s"], - "TrainerBattleBGM" => [15, "s"], - "WildVictoryME" => [16, "s"], - "TrainerVictoryME" => [17, "s"], - "WildCaptureME" => [18, "s"], - "MapSize" => [19, "us"], - "Environment" => [20, "e", :Environment] - } - - extend ClassMethodsIDNumbers - include InstanceMethods - - def self.editor_properties - return [ - ["Outdoor", BooleanProperty, _INTL("If true, this map is an outdoor map and will be tinted according to time of day.")], - ["ShowArea", BooleanProperty, _INTL("If true, the game will display the map's name upon entry.")], - ["Bicycle", BooleanProperty, _INTL("If true, the bicycle can be used on this map.")], - ["BicycleAlways", BooleanProperty, _INTL("If true, the bicycle will be mounted automatically on this map and cannot be dismounted.")], - ["HealingSpot", MapCoordsProperty, _INTL("Map ID of this Pokémon Center's town, and X and Y coordinates of its entrance within that town.")], - ["Weather", WeatherEffectProperty, _INTL("Weather conditions in effect for this map.")], - ["MapPosition", RegionMapCoordsProperty, _INTL("Identifies the point on the regional map for this map.")], - ["DiveMap", MapProperty, _INTL("Specifies the underwater layer of this map. Use only if this map has deep water.")], - ["DarkMap", BooleanProperty, _INTL("If true, this map is dark and a circle of light appears around the player. Flash can be used to expand the circle.")], - ["SafariMap", BooleanProperty, _INTL("If true, this map is part of the Safari Zone (both indoor and outdoor). Not to be used in the reception desk.")], - ["SnapEdges", BooleanProperty, _INTL("If true, when the player goes near this map's edge, the game doesn't center the player as usual.")], - ["Dungeon", BooleanProperty, _INTL("If true, this map has a randomly generated layout. See the wiki for more information.")], - ["BattleBack", StringProperty, _INTL("PNG files named 'XXX_bg', 'XXX_base0', 'XXX_base1', 'XXX_message' in Battlebacks folder, where XXX is this property's value.")], - ["WildBattleBGM", BGMProperty, _INTL("Default BGM for wild Pokémon battles on this map.")], - ["TrainerBattleBGM", BGMProperty, _INTL("Default BGM for trainer battles on this map.")], - ["WildVictoryME", MEProperty, _INTL("Default ME played after winning a wild Pokémon battle on this map.")], - ["TrainerVictoryME", MEProperty, _INTL("Default ME played after winning a Trainer battle on this map.")], - ["WildCaptureME", MEProperty, _INTL("Default ME played after catching a wild Pokémon on this map.")], - ["MapSize", MapSizeProperty, _INTL("The width of the map in Town Map squares, and a string indicating which squares are part of this map.")], - ["Environment", GameDataProperty.new(:Environment), _INTL("The default battle environment for battles on this map.")] - ] - end - - def initialize(hash) - @id = hash[:id] - @outdoor_map = hash[:outdoor_map] - @announce_location = hash[:announce_location] - @can_bicycle = hash[:can_bicycle] - @always_bicycle = hash[:always_bicycle] - @teleport_destination = hash[:teleport_destination] - @weather = hash[:weather] - @town_map_position = hash[:town_map_position] - @dive_map_id = hash[:dive_map_id] - @dark_map = hash[:dark_map] - @safari_map = hash[:safari_map] - @snap_edges = hash[:snap_edges] - @random_dungeon = hash[:random_dungeon] - @battle_background = hash[:battle_background] - @wild_battle_BGM = hash[:wild_battle_BGM] - @trainer_battle_BGM = hash[:trainer_battle_BGM] - @wild_victory_ME = hash[:wild_victory_ME] - @trainer_victory_ME = hash[:trainer_victory_ME] - @wild_capture_ME = hash[:wild_capture_ME] - @town_map_size = hash[:town_map_size] - @battle_environment = hash[:battle_environment] - end - - def property_from_string(str) - case str - when "Outdoor" then return @outdoor_map - when "ShowArea" then return @announce_location - when "Bicycle" then return @can_bicycle - when "BicycleAlways" then return @always_bicycle - when "HealingSpot" then return @teleport_destination - when "Weather" then return @weather - when "MapPosition" then return @town_map_position - when "DiveMap" then return @dive_map_id - when "DarkMap" then return @dark_map - when "SafariMap" then return @safari_map - when "SnapEdges" then return @snap_edges - when "Dungeon" then return @random_dungeon - when "BattleBack" then return @battle_background - when "WildBattleBGM" then return @wild_battle_BGM - when "TrainerBattleBGM" then return @trainer_battle_BGM - when "WildVictoryME" then return @wild_victory_ME - when "TrainerVictoryME" then return @trainer_victory_ME - when "WildCaptureME" then return @wild_capture_ME - when "MapSize" then return @town_map_size - when "Environment" then return @battle_environment - end - return nil - end - end -end diff --git a/Data/Scripts/011_Battle/001_Battler/001_PokeBattle_Battler.rb b/Data/Scripts/011_Battle/001_Battler/001_PokeBattle_Battler.rb deleted file mode 100644 index 20172f0ec..000000000 --- a/Data/Scripts/011_Battle/001_Battler/001_PokeBattle_Battler.rb +++ /dev/null @@ -1,801 +0,0 @@ -class PokeBattle_Battler - # Fundamental to this object - attr_reader :battle - attr_accessor :index - # The Pokémon and its properties - attr_reader :pokemon - attr_accessor :pokemonIndex - attr_accessor :species - attr_accessor :type1 - attr_accessor :type2 - attr_accessor :ability_id - attr_accessor :item_id - attr_accessor :moves - attr_accessor :gender - attr_accessor :iv - attr_accessor :attack - attr_accessor :spatk - attr_accessor :speed - attr_accessor :stages - attr_reader :totalhp - attr_reader :fainted # Boolean to mark whether self has fainted properly - attr_accessor :captured # Boolean to mark whether self was captured - attr_reader :dummy - attr_accessor :effects - # Things the battler has done in battle - attr_accessor :turnCount - attr_accessor :participants - attr_accessor :lastAttacker - attr_accessor :lastFoeAttacker - attr_accessor :lastHPLost - attr_accessor :lastHPLostFromFoe - attr_accessor :lastMoveUsed - attr_accessor :lastMoveUsedType - attr_accessor :lastRegularMoveUsed - attr_accessor :lastRegularMoveTarget # For Instruct - attr_accessor :lastRoundMoved - attr_accessor :lastMoveFailed # For Stomping Tantrum - attr_accessor :lastRoundMoveFailed # For Stomping Tantrum - attr_accessor :movesUsed - attr_accessor :currentMove # ID of multi-turn move currently being used - attr_accessor :tookDamage # Boolean for whether self took damage this round - attr_accessor :tookPhysicalHit - attr_accessor :damageState - attr_accessor :initialHP # Set at the start of each move's usage - - #============================================================================= - # Complex accessors - #============================================================================= - attr_reader :level - - def level=(value) - @level = value - @pokemon.level = value if @pokemon - end - - attr_reader :form - - def form=(value) - @form = value - @pokemon.form = value if @pokemon - end - - def ability - return GameData::Ability.try_get(@ability_id) - end - - def hasHiddenAbility? - return @pokemon.ability_index >= 2 - end - - def ability=(value) - new_ability = GameData::Ability.try_get(value) - @ability_id = (new_ability) ? new_ability.id : nil - end - - def item - return GameData::Item.try_get(@item_id) - end - - def item=(value) - new_item = GameData::Item.try_get(value) - @item_id = (new_item) ? new_item.id : nil - @pokemon.item = @item_id if @pokemon - end - - def defense - return @spdef if @battle.field.effects[PBEffects::WonderRoom] > 0 - return @defense - end - - attr_writer :defense - - def spdef - return @defense if @battle.field.effects[PBEffects::WonderRoom] > 0 - return @spdef - end - - attr_writer :spdef - - attr_reader :hp - - def hp=(value) - checkHPRelatedFormChange(value) #careful, setting @pokemon.hp also calls a method for changing the form on hp change so we should not change the form here, just update the graphics - @hp = value.to_i - @pokemon.hp = value.to_i if @pokemon - end - - def fainted? - return @hp <= 0; - end - - alias isFainted? fainted? - - attr_reader :status - - def status=(value) - @effects[PBEffects::Truant] = false if @status == :SLEEP && value != :SLEEP - @effects[PBEffects::Toxic] = 0 if value != :POISON - @status = value - @pokemon.status = value if @pokemon - self.statusCount = 0 if value != :POISON && value != :SLEEP - @battle.scene.pbRefreshOne(@index) - end - - attr_reader :statusCount - - def statusCount=(value) - @statusCount = value - @pokemon.statusCount = value if @pokemon - @battle.scene.pbRefreshOne(@index) - end - - #============================================================================= - # Properties from Pokémon - #============================================================================= - def happiness - return @pokemon ? @pokemon.happiness : 0; - end - - def nature - return @pokemon ? @pokemon.nature : 0; - end - - def pokerusStage - return @pokemon ? @pokemon.pokerusStage : 0; - end - - #============================================================================= - # Mega Evolution, Primal Reversion, Shadow Pokémon - #============================================================================= - def hasMega? - return false if @effects[PBEffects::Transform] - return @pokemon && @pokemon.hasMegaForm? - end - - def mega? - return @pokemon && @pokemon.mega?; - end - - alias isMega? mega? - - def hasPrimal? - return false if @effects[PBEffects::Transform] - return @pokemon && @pokemon.hasPrimalForm? - end - - def primal? - return @pokemon && @pokemon.primal?; - end - - alias isPrimal? primal? - - def shadowPokemon? - return false; - end - - alias isShadow? shadowPokemon? - - def inHyperMode? - return false; - end - - #============================================================================= - # Display-only properties - #============================================================================= - def name - return @effects[PBEffects::Illusion].name if @effects[PBEffects::Illusion] - return @name - end - - attr_writer :name - - def displayPokemon - return @effects[PBEffects::Illusion] if @effects[PBEffects::Illusion] - return self.pokemon - end - - def displaySpecies - return @effects[PBEffects::Illusion].species if @effects[PBEffects::Illusion] - return self.species - end - - def displayGender - return @effects[PBEffects::Illusion].gender if @effects[PBEffects::Illusion] - return self.gender - end - - def displayForm - return @effects[PBEffects::Illusion].form if @effects[PBEffects::Illusion] - return self.form - end - - def shiny? - return @effects[PBEffects::Illusion].shiny? if @effects[PBEffects::Illusion] - return @pokemon && @pokemon.shiny? - end - - alias isShiny? shiny? - - def glitter? - return @pokemon.glitter - end - - def owned? - return false if !@battle.wildBattle? - return $Trainer.owned?(displaySpecies) - end - - alias owned owned? - - def abilityName - abil = self.ability - return (abil) ? abil.name : "" - end - - def itemName - itm = self.item - return (itm) ? itm.name : "" - end - - def pbThis(lowerCase = false) - if opposes? - if @battle.trainerBattle? - return lowerCase ? _INTL("the opposing {1}", name) : _INTL("The opposing {1}", name) - else - return lowerCase ? _INTL("the wild {1}", name) : _INTL("The wild {1}", name) - end - elsif !pbOwnedByPlayer? - return lowerCase ? _INTL("the ally {1}", name) : _INTL("The ally {1}", name) - end - return name - end - - def pbTeam(lowerCase = false) - if opposes? - return lowerCase ? _INTL("the opposing team") : _INTL("The opposing team") - end - return lowerCase ? _INTL("your team") : _INTL("Your team") - end - - def pbOpposingTeam(lowerCase = false) - if opposes? - return lowerCase ? _INTL("your team") : _INTL("Your team") - end - return lowerCase ? _INTL("the opposing team") : _INTL("The opposing team") - end - - #============================================================================= - # Calculated properties - #============================================================================= - def pbSpeed - return 1 if fainted? - stageMul = [2, 2, 2, 2, 2, 2, 2, 3, 4, 5, 6, 7, 8] - stageDiv = [8, 7, 6, 5, 4, 3, 2, 2, 2, 2, 2, 2, 2] - stage = @stages[:SPEED] + 6 - speed = @speed * stageMul[stage] / stageDiv[stage] - speedMult = 1.0 - # Ability effects that alter calculated Speed - if abilityActive? - speedMult = BattleHandlers.triggerSpeedCalcAbility(self.ability, self, speedMult) - end - # Item effects that alter calculated Speed - if itemActive? - speedMult = BattleHandlers.triggerSpeedCalcItem(self.item, self, speedMult) - end - # Other effects - speedMult *= 2 if pbOwnSide.effects[PBEffects::Tailwind] > 0 - speedMult /= 2 if pbOwnSide.effects[PBEffects::Swamp] > 0 - # Paralysis - if status == :PARALYSIS && !hasActiveAbility?(:QUICKFEET) - speedMult /= (Settings::MECHANICS_GENERATION >= 7) ? 2 : 4 - end - # Badge multiplier - if @battle.internalBattle && pbOwnedByPlayer? && - @battle.pbPlayer.badge_count >= Settings::NUM_BADGES_BOOST_SPEED - speedMult *= 1.1 - end - # Calculation - return [(speed * speedMult).round, 1].max - end - - def pbWeight - ret = (@pokemon) ? @pokemon.weight : 500 - ret += @effects[PBEffects::WeightChange] - ret = 1 if ret < 1 - if abilityActive? && !@battle.moldBreaker - ret = BattleHandlers.triggerWeightCalcAbility(self.ability, self, ret) - end - if itemActive? - ret = BattleHandlers.triggerWeightCalcItem(self.item, self, ret) - end - return [ret, 1].max - end - - #============================================================================= - # Queries about what the battler has - #============================================================================= - def plainStats - ret = {} - ret[:ATTACK] = self.attack - ret[:DEFENSE] = self.defense - ret[:SPECIAL_ATTACK] = self.spatk - ret[:SPECIAL_DEFENSE] = self.spdef - ret[:SPEED] = self.speed - return ret - end - - def isSpecies?(species) - return @pokemon && @pokemon.isSpecies?(species) - end - - def hasBodyOf?(check_species) - return @pokemon.hasBodyOf?(check_species) - end - - def hasHeadOf?(check_species) - return @pokemon.hasHeadOf?(check_species) - end - - def isFusionOf(check_species) - return @pokemon.isFusionOf(check_species) - end - - def isFusion?() - return @pokemon.isFusion?() - end - - # Returns the active types of this Pokémon. The array should not include the - # same type more than once, and should not include any invalid type numbers - # (e.g. -1). - def pbTypes(withType3 = false) - ret = [@type1] - ret.push(@type2) if @type2 != @type1 - # Burn Up erases the Fire-type. - ret.delete(:FIRE) if @effects[PBEffects::BurnUp] - # Roost erases the Flying-type. If there are no types left, adds the Normal- - # type. - if @effects[PBEffects::Roost] - ret.delete(:FLYING) - ret.push(:NORMAL) if ret.length == 0 - end - # Add the third type specially. - if withType3 && @effects[PBEffects::Type3] - ret.push(@effects[PBEffects::Type3]) if !ret.include?(@effects[PBEffects::Type3]) - end - return ret - end - - def pbHasType?(type) - return false if !type - activeTypes = pbTypes(true) - return activeTypes.include?(GameData::Type.get(type).id) - end - - def pbHasOtherType?(type) - return false if !type - activeTypes = pbTypes(true) - activeTypes.delete(GameData::Type.get(type).id) - return activeTypes.length > 0 - end - - # NOTE: Do not create any held item which affects whether a Pokémon's ability - # is active. The ability Klutz affects whether a Pokémon's item is - # active, and the code for the two combined would cause an infinite loop - # (regardless of whether any Pokémon actualy has either the ability or - # the item - the code existing is enough to cause the loop). - def abilityActive?(ignore_fainted = false) - return false if fainted? && !ignore_fainted - return false if @effects[PBEffects::GastroAcid] - return true - end - - def hasActiveAbility?(check_ability, ignore_fainted = false) - return false if !abilityActive?(ignore_fainted) - return check_ability.include?(@ability_id) if check_ability.is_a?(Array) - return self.ability == check_ability - end - - alias hasWorkingAbility hasActiveAbility? - - # Applies to both losing self's ability (i.e. being replaced by another) and - # having self's ability be negated. - def unstoppableAbility?(abil = nil) - abil = @ability_id if !abil - abil = GameData::Ability.try_get(abil) - return false if !abil - ability_blacklist = [ - # Form-changing abilities - :BATTLEBOND, - :DISGUISE, - # :FLOWERGIFT, # This can be stopped - # :FORECAST, # This can be stopped - :MULTITYPE, - :POWERCONSTRUCT, - :SCHOOLING, - :SHIELDSDOWN, - :STANCECHANGE, - :ZENMODE, - # Abilities intended to be inherent properties of a certain species - :COMATOSE, - :RKSSYSTEM - ] - return ability_blacklist.include?(abil.id) - end - - # Applies to gaining the ability. - def ungainableAbility?(abil = nil) - abil = @ability_id if !abil - abil = GameData::Ability.try_get(abil) - return false if !abil - ability_blacklist = [ - # Form-changing abilities - :BATTLEBOND, - :DISGUISE, - :FLOWERGIFT, - :FORECAST, - :MULTITYPE, - :POWERCONSTRUCT, - :SCHOOLING, - :SHIELDSDOWN, - :STANCECHANGE, - :ZENMODE, - # Appearance-changing abilities - :ILLUSION, - :IMPOSTER, - # Abilities intended to be inherent properties of a certain species - :COMATOSE, - :RKSSYSTEM - ] - return ability_blacklist.include?(abil.id) - end - - def itemActive?(ignoreFainted = false) - return false if fainted? && !ignoreFainted - return false if @effects[PBEffects::Embargo] > 0 - return false if @battle.field.effects[PBEffects::MagicRoom] > 0 - return false if hasActiveAbility?(:KLUTZ, ignoreFainted) - return true - end - - def hasActiveItem?(check_item, ignore_fainted = false) - return false if !itemActive?(ignore_fainted) - return check_item.include?(@item_id) if check_item.is_a?(Array) - return self.item == check_item - end - - alias hasWorkingItem hasActiveItem? - - # Returns whether the specified item will be unlosable for this Pokémon. - def unlosableItem?(check_item) - return false if !check_item - return true if GameData::Item.get(check_item).is_mail? - return false if @effects[PBEffects::Transform] - # Items that change a Pokémon's form - if mega? # Check if item was needed for this Mega Evolution - return true if @pokemon.species_data.mega_stone == check_item - else - # Check if item could cause a Mega Evolution - GameData::Species.each do |data| - next if data.species != @species || data.unmega_form != @form - return true if data.mega_stone == check_item - end - end - # Other unlosable items - return GameData::Item.get(check_item).unlosable?(@species, self.ability) - end - - def eachMove - @moves.each { |m| yield m } - end - - def eachMoveWithIndex - @moves.each_with_index { |m, i| yield m, i } - end - - def pbHasMove?(move_id) - return false if !move_id - eachMove { |m| return true if m.id == move_id } - return false - end - - def pbHasMoveType?(check_type) - return false if !check_type - check_type = GameData::Type.get(check_type).id - eachMove { |m| return true if m.type == check_type } - return false - end - - def pbHasMoveFunction?(*arg) - return false if !arg - eachMove do |m| - arg.each { |code| return true if m.function == code } - end - return false - end - - def hasMoldBreaker? - return hasActiveAbility?([:MOLDBREAKER, :TERAVOLT, :TURBOBLAZE]) - end - - def canChangeType? - return ![:MULTITYPE, :RKSSYSTEM].include?(@ability_id) - end - - def airborne? - return false if hasActiveItem?(:IRONBALL) - return false if @effects[PBEffects::Ingrain] - return false if @effects[PBEffects::SmackDown] - return false if @battle.field.effects[PBEffects::Gravity] > 0 - return true if pbHasType?(:FLYING) - return true if hasActiveAbility?(:LEVITATE) && !@battle.moldBreaker - return true if hasActiveItem?(:AIRBALLOON) - return true if @effects[PBEffects::MagnetRise] > 0 - return true if @effects[PBEffects::Telekinesis] > 0 - return false - end - - def affectedByTerrain? - return false if airborne? - return false if semiInvulnerable? - return true - end - - def takesIndirectDamage?(showMsg = false) - return false if fainted? - if hasActiveAbility?(:MAGICGUARD) - if showMsg - @battle.pbShowAbilitySplash(self) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - @battle.pbDisplay(_INTL("{1} is unaffected!", pbThis)) - else - @battle.pbDisplay(_INTL("{1} is unaffected because of its {2}!", pbThis, abilityName)) - end - @battle.pbHideAbilitySplash(self) - end - return false - end - return true - end - - def takesSandstormDamage? - return false if !takesIndirectDamage? - return false if pbHasType?(:GROUND) || pbHasType?(:ROCK) || pbHasType?(:STEEL) - return false if inTwoTurnAttack?("0CA", "0CB") # Dig, Dive - return false if hasActiveAbility?([:OVERCOAT, :SANDFORCE, :SANDRUSH, :SANDVEIL]) - return false if hasActiveItem?(:SAFETYGOGGLES) - return true - end - - def takesHailDamage? - return false if !takesIndirectDamage? - return false if pbHasType?(:ICE) - return false if inTwoTurnAttack?("0CA", "0CB") # Dig, Dive - return false if hasActiveAbility?([:OVERCOAT, :ICEBODY, :SNOWCLOAK]) - return false if hasActiveItem?(:SAFETYGOGGLES) - return true - end - - def takesShadowSkyDamage? - return false if fainted? - return false if shadowPokemon? - return true - end - - def affectedByPowder?(showMsg = false) - return false if fainted? - if pbHasType?(:GRASS) && Settings::MORE_TYPE_EFFECTS - @battle.pbDisplay(_INTL("{1} is unaffected!", pbThis)) if showMsg - return false - end - if Settings::MECHANICS_GENERATION >= 6 - if hasActiveAbility?(:OVERCOAT) && !@battle.moldBreaker - if showMsg - @battle.pbShowAbilitySplash(self) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - @battle.pbDisplay(_INTL("{1} is unaffected!", pbThis)) - else - @battle.pbDisplay(_INTL("{1} is unaffected because of its {2}!", pbThis, abilityName)) - end - @battle.pbHideAbilitySplash(self) - end - return false - end - if hasActiveItem?(:SAFETYGOGGLES) - if showMsg - @battle.pbDisplay(_INTL("{1} is unaffected because of its {2}!", pbThis, itemName)) - end - return false - end - end - return true - end - - def canHeal? - return false if fainted? || @hp >= @totalhp - return false if @effects[PBEffects::HealBlock] > 0 - return true - end - - def affectedByContactEffect?(showMsg = false) - return false if fainted? - if hasActiveItem?(:PROTECTIVEPADS) - @battle.pbDisplay(_INTL("{1} protected itself with the {2}!", pbThis, itemName)) if showMsg - return false - end - return true - end - - def movedThisRound? - return @lastRoundMoved && @lastRoundMoved == @battle.turnCount - end - - def usingMultiTurnAttack? - return true if @effects[PBEffects::TwoTurnAttack] - return true if @effects[PBEffects::HyperBeam] > 0 - return true if @effects[PBEffects::Rollout] > 0 - return true if @effects[PBEffects::Outrage] > 0 - return true if @effects[PBEffects::Uproar] > 0 - return true if @effects[PBEffects::Bide] > 0 - return false - end - - def inTwoTurnAttack?(*arg) - return false if !@effects[PBEffects::TwoTurnAttack] - ttaFunction = GameData::Move.get(@effects[PBEffects::TwoTurnAttack]).function_code - arg.each { |a| return true if a == ttaFunction } - return false - end - - def semiInvulnerable? - return inTwoTurnAttack?("0C9", "0CA", "0CB", "0CC", "0CD", "0CE", "14D") - end - - def pbEncoredMoveIndex - return -1 if @effects[PBEffects::Encore] == 0 || !@effects[PBEffects::EncoreMove] - ret = -1 - eachMoveWithIndex do |m, i| - next if m.id != @effects[PBEffects::EncoreMove] - ret = i - break - end - return ret - end - - def initialItem - return @battle.initialItems[@index & 1][@pokemonIndex] - end - - def setInitialItem(newItem) - @battle.initialItems[@index & 1][@pokemonIndex] = newItem - end - - def recycleItem - return @battle.recycleItems[@index & 1][@pokemonIndex] - end - - def setRecycleItem(newItem) - @battle.recycleItems[@index & 1][@pokemonIndex] = newItem - end - - def belched? - return @battle.belch[@index & 1][@pokemonIndex] - end - - def setBelched - @battle.belch[@index & 1][@pokemonIndex] = true - end - - #============================================================================= - # Methods relating to this battler's position on the battlefield - #============================================================================= - # Returns whether the given position belongs to the opposing Pokémon's side. - def opposes?(i = 0) - i = i.index if i.respond_to?("index") - return (@index & 1) != (i & 1) - end - - # Returns whether the given position/battler is near to self. - def near?(i) - i = i.index if i.respond_to?("index") - return @battle.nearBattlers?(@index, i) - end - - # Returns whether self is owned by the player. - def pbOwnedByPlayer? - return @battle.pbOwnedByPlayer?(@index) - end - - # Returns 0 if self is on the player's side, or 1 if self is on the opposing - # side. - def idxOwnSide - return @index & 1 - end - - # Returns 1 if self is on the player's side, or 0 if self is on the opposing - # side. - def idxOpposingSide - return (@index & 1) ^ 1 - end - - # Returns the data structure for this battler's side. - def pbOwnSide - return @battle.sides[idxOwnSide] - end - - # Returns the data structure for the opposing Pokémon's side. - def pbOpposingSide - return @battle.sides[idxOpposingSide] - end - - # Yields each unfainted ally Pokémon. - def eachAlly - @battle.battlers.each do |b| - yield b if b && !b.fainted? && !b.opposes?(@index) && b.index != @index - end - end - - # Yields each unfainted opposing Pokémon. - def eachOpposing - @battle.battlers.each { |b| yield b if b && !b.fainted? && b.opposes?(@index) } - end - - # Returns the battler that is most directly opposite to self. unfaintedOnly is - # whether it should prefer to return a non-fainted battler. - def pbDirectOpposing(unfaintedOnly = false) - @battle.pbGetOpposingIndicesInOrder(@index).each do |i| - next if !@battle.battlers[i] - break if unfaintedOnly && @battle.battlers[i].fainted? - return @battle.battlers[i] - end - # Wanted an unfainted battler but couldn't find one; make do with a fainted - # battler - @battle.pbGetOpposingIndicesInOrder(@index).each do |i| - return @battle.battlers[i] if @battle.battlers[i] - end - return @battle.battlers[(@index ^ 1)] - end - - #Changes the form VISUALLY in battles. The species is changed in the equivalent method in Pokemon class - def checkHPRelatedFormChange(new_hp) - if @ability_id == :SHIELDSDOWN - if @pokemon.isFusionOf(:MINIOR_M) - if new_hp <= (@totalhp / 2) - changeBattlerForm(:MINIOR_M, :MINIOR_C,nil, :SHELLSMASH) - @battle.pbDisplay(_INTL("{1} changed to the Core Form!", pbThis)) - end - end - if @pokemon.isFusionOf(:MINIOR_C) - if new_hp > (@totalhp / 2) - changeBattlerForm(:MINIOR_C, :MINIOR_M,nil, :SHELLSMASH) - @battle.pbDisplay(_INTL("{1} changed to the Meteor Form!", pbThis)) - end - end - end - end - - - def changeBattlerForm(oldForm, newForm,commonAnimation=nil,moveAnimation=nil) - @pokemon.changeFormSpecies(oldForm, newForm) - if moveAnimation - changeFormSpeciesMoveAnimation(oldForm, newForm,moveAnimation) - else - changeFormSpeciesCommonAnimation(oldForm, newForm, commonAnimation) - end - end - - - #These methods only play the animation and change the graphics. - # To also change the species, call changeFormSpecies() instead - def changeFormSpeciesCommonAnimation(oldForm, newForm, animation = "UltraBurst2") - @battle.scene.pbChangePokemon(self, @pokemon) - @battle.scene.pbCommonAnimation(animation, self) - @battle.scene.pbRefreshOne(@index) - end - - def changeFormSpeciesMoveAnimation(oldForm, newForm, moveID=:REFRESH) - @battle.scene.pbChangePokemon(self, @pokemon) - @battle.scene.pbAnimation(moveID, self,self) - @battle.scene.pbRefreshOne(@index) - end -end diff --git a/Data/Scripts/011_Battle/001_Battler/002_Battler_Initialize.rb b/Data/Scripts/011_Battle/001_Battler/002_Battler_Initialize.rb deleted file mode 100644 index cd05c59e1..000000000 --- a/Data/Scripts/011_Battle/001_Battler/002_Battler_Initialize.rb +++ /dev/null @@ -1,330 +0,0 @@ -class PokeBattle_Battler - #============================================================================= - # Creating a battler - #============================================================================= - def initialize(btl,idxBattler) - @battle = btl - @index = idxBattler - @captured = false - @dummy = false - @stages = {} - @effects = [] - @damageState = PokeBattle_DamageState.new - pbInitBlank - pbInitEffects(false) - end - - def pbInitBlank - @name = "" - @species = 0 - @form = 0 - @level = 0 - @hp = @totalhp = 0 - @type1 = @type2 = nil - @ability_id = nil - @ability2_id = nil - @item_id = nil - @gender = 0 - @attack = @defense = @spatk = @spdef = @speed = 0 - @status = :NONE - @statusCount = 0 - @pokemon = nil - @pokemonIndex = -1 - @participants = [] - @moves = [] - @iv = {} - GameData::Stat.each_main { |s| @iv[s.id] = 0 } - end - - # Used by Future Sight only, when Future Sight's user is no longer in battle. - def pbInitDummyPokemon(pkmn,idxParty) - raise _INTL("An egg can't be an active Pokémon.") if pkmn.egg? - @name = pkmn.name - @species = pkmn.species - @form = pkmn.form - @level = pkmn.level - @hp = pkmn.hp - @totalhp = pkmn.totalhp - @type1 = pkmn.type1 - @type2 = pkmn.type2 - # ability and item intentionally not copied across here - @gender = pkmn.gender - @attack = pkmn.attack - @defense = pkmn.defense - @spatk = pkmn.spatk - @spdef = pkmn.spdef - @speed = pkmn.speed - @status = pkmn.status - @statusCount = pkmn.statusCount - @pokemon = pkmn - @pokemonIndex = idxParty - @participants = [] - # moves intentionally not copied across here - @iv = {} - GameData::Stat.each_main { |s| @iv[s.id] = pkmn.iv[s.id] } - @dummy = true - end - - def pbInitialize(pkmn,idxParty,batonPass=false) - pbInitPokemon(pkmn,idxParty) - pbInitEffects(batonPass) - @damageState.reset - end - - def pbInitPokemon(pkmn,idxParty) - raise _INTL("An egg can't be an active Pokémon.") if pkmn.egg? - @name = pkmn.name - @species = pkmn.species - @form = pkmn.form - @level = pkmn.level - @hp = pkmn.hp - @totalhp = pkmn.totalhp - @type1 = pkmn.type1 - @type2 = pkmn.type2 - @ability_id = pkmn.ability_id - @ability2_id = pkmn.ability2_id - @item_id = pkmn.item_id - @gender = pkmn.gender - @attack = pkmn.attack - @defense = pkmn.defense - @spatk = pkmn.spatk - @spdef = pkmn.spdef - @speed = pkmn.speed - @status = pkmn.status - @statusCount = pkmn.statusCount - @pokemon = pkmn - @pokemonIndex = idxParty - @participants = [] # Participants earn Exp. if this battler is defeated - @moves = [] - pkmn.moves.each_with_index do |m,i| - @moves[i] = PokeBattle_Move.from_pokemon_move(@battle,m) - end - @iv = {} - GameData::Stat.each_main { |s| @iv[s.id] = pkmn.iv[s.id] } - end - - def pbInitEffects(batonPass) - if batonPass - # These effects are passed on if Baton Pass is used, but they need to be - # reapplied - @effects[PBEffects::LaserFocus] = (@effects[PBEffects::LaserFocus]>0) ? 2 : 0 - @effects[PBEffects::LockOn] = (@effects[PBEffects::LockOn]>0) ? 2 : 0 - if @effects[PBEffects::PowerTrick] - @attack,@defense = @defense,@attack - end - # These effects are passed on if Baton Pass is used, but they need to be - # cancelled in certain circumstances anyway - @effects[PBEffects::Telekinesis] = 0 if isSpecies?(:GENGAR) && mega? - @effects[PBEffects::GastroAcid] = false if unstoppableAbility? - else - # These effects are passed on if Baton Pass is used - @stages[:ATTACK] = 0 - @stages[:DEFENSE] = 0 - @stages[:SPEED] = 0 - @stages[:SPECIAL_ATTACK] = 0 - @stages[:SPECIAL_DEFENSE] = 0 - @stages[:ACCURACY] = 0 - @stages[:EVASION] = 0 - @effects[PBEffects::AquaRing] = false - @effects[PBEffects::Confusion] = 0 - @effects[PBEffects::Curse] = false - @effects[PBEffects::Embargo] = 0 - @effects[PBEffects::FocusEnergy] = 0 - @effects[PBEffects::GastroAcid] = false - @effects[PBEffects::HealBlock] = 0 - @effects[PBEffects::Ingrain] = false - @effects[PBEffects::LaserFocus] = 0 - @effects[PBEffects::LeechSeed] = -1 - @effects[PBEffects::LockOn] = 0 - @effects[PBEffects::LockOnPos] = -1 - @effects[PBEffects::MagnetRise] = 0 - @effects[PBEffects::PerishSong] = 0 - @effects[PBEffects::PerishSongUser] = -1 - @effects[PBEffects::PowerTrick] = false - @effects[PBEffects::Substitute] = 0 - @effects[PBEffects::Telekinesis] = 0 - end - @fainted = (@hp==0) - @initialHP = 0 - @lastAttacker = [] - @lastFoeAttacker = [] - @lastHPLost = 0 - @lastHPLostFromFoe = 0 - @tookDamage = false - @tookPhysicalHit = false - @lastMoveUsed = nil - @lastMoveUsedType = nil - @lastRegularMoveUsed = nil - @lastRegularMoveTarget = -1 - @lastRoundMoved = -1 - @lastMoveFailed = false - @lastRoundMoveFailed = false - @movesUsed = [] - @turnCount = 0 - @effects[PBEffects::Attract] = -1 - @battle.eachBattler do |b| # Other battlers no longer attracted to self - b.effects[PBEffects::Attract] = -1 if b.effects[PBEffects::Attract]==@index - end - @effects[PBEffects::BanefulBunker] = false - @effects[PBEffects::BeakBlast] = false - @effects[PBEffects::Bide] = 0 - @effects[PBEffects::BideDamage] = 0 - @effects[PBEffects::BideTarget] = -1 - @effects[PBEffects::BurnUp] = false - @effects[PBEffects::Charge] = 0 - @effects[PBEffects::ChoiceBand] = nil - @effects[PBEffects::Counter] = -1 - @effects[PBEffects::CounterTarget] = -1 - @effects[PBEffects::Dancer] = false - @effects[PBEffects::DefenseCurl] = false - @effects[PBEffects::DestinyBond] = false - @effects[PBEffects::DestinyBondPrevious] = false - @effects[PBEffects::DestinyBondTarget] = -1 - @effects[PBEffects::Disable] = 0 - @effects[PBEffects::DisableMove] = nil - @effects[PBEffects::Electrify] = false - @effects[PBEffects::Encore] = 0 - @effects[PBEffects::EncoreMove] = nil - @effects[PBEffects::Endure] = false - @effects[PBEffects::FirstPledge] = 0 - @effects[PBEffects::FlashFire] = false - @effects[PBEffects::Flinch] = false - @effects[PBEffects::FocusPunch] = false - @effects[PBEffects::FollowMe] = 0 - @effects[PBEffects::Foresight] = false - @effects[PBEffects::FuryCutter] = 0 - @effects[PBEffects::GemConsumed] = nil - @effects[PBEffects::Grudge] = false - @effects[PBEffects::HelpingHand] = false - @effects[PBEffects::HyperBeam] = 0 - @effects[PBEffects::Illusion] = nil - if hasActiveAbility?(:ILLUSION) - idxLastParty = @battle.pbLastInTeam(@index) - if idxLastParty >= 0 && idxLastParty != @pokemonIndex - @effects[PBEffects::Illusion] = @battle.pbParty(@index)[idxLastParty] - end - end - @effects[PBEffects::Imprison] = false - @effects[PBEffects::Instruct] = false - @effects[PBEffects::Instructed] = false - @effects[PBEffects::KingsShield] = false - @battle.eachBattler do |b| # Other battlers lose their lock-on against self - next if b.effects[PBEffects::LockOn]==0 - next if b.effects[PBEffects::LockOnPos]!=@index - b.effects[PBEffects::LockOn] = 0 - b.effects[PBEffects::LockOnPos] = -1 - end - @effects[PBEffects::MagicBounce] = false - @effects[PBEffects::MagicCoat] = false - @effects[PBEffects::MeanLook] = -1 - @battle.eachBattler do |b| # Other battlers no longer blocked by self - b.effects[PBEffects::MeanLook] = -1 if b.effects[PBEffects::MeanLook]==@index - end - @effects[PBEffects::MeFirst] = false - @effects[PBEffects::Metronome] = 0 - @effects[PBEffects::MicleBerry] = false - @effects[PBEffects::Minimize] = false - @effects[PBEffects::MiracleEye] = false - @effects[PBEffects::MirrorCoat] = -1 - @effects[PBEffects::MirrorCoatTarget] = -1 - @effects[PBEffects::MoveNext] = false - @effects[PBEffects::MudSport] = false - @effects[PBEffects::Nightmare] = false - @effects[PBEffects::Outrage] = 0 - @effects[PBEffects::ParentalBond] = 0 - @effects[PBEffects::PickupItem] = nil - @effects[PBEffects::PickupUse] = 0 - @effects[PBEffects::Pinch] = false - @effects[PBEffects::Powder] = false - @effects[PBEffects::Prankster] = false - @effects[PBEffects::PriorityAbility] = false - @effects[PBEffects::PriorityItem] = false - @effects[PBEffects::Protect] = false - @effects[PBEffects::ProtectRate] = 1 - @effects[PBEffects::Pursuit] = false - @effects[PBEffects::Quash] = 0 - @effects[PBEffects::Rage] = false - @effects[PBEffects::RagePowder] = false - @effects[PBEffects::Rollout] = 0 - @effects[PBEffects::Roost] = false - @effects[PBEffects::SkyDrop] = -1 - @battle.eachBattler do |b| # Other battlers no longer Sky Dropped by self - b.effects[PBEffects::SkyDrop] = -1 if b.effects[PBEffects::SkyDrop]==@index - end - @effects[PBEffects::SlowStart] = 0 - @effects[PBEffects::SmackDown] = false - @effects[PBEffects::Snatch] = 0 - @effects[PBEffects::SpikyShield] = false - @effects[PBEffects::Spotlight] = 0 - @effects[PBEffects::Stockpile] = 0 - @effects[PBEffects::StockpileDef] = 0 - @effects[PBEffects::StockpileSpDef] = 0 - @effects[PBEffects::Taunt] = 0 - @effects[PBEffects::ThroatChop] = 0 - @effects[PBEffects::Torment] = false - @effects[PBEffects::Toxic] = 0 - @effects[PBEffects::Transform] = false - @effects[PBEffects::TransformSpecies] = 0 - @effects[PBEffects::Trapping] = 0 - @effects[PBEffects::TrappingMove] = nil - @effects[PBEffects::TrappingUser] = -1 - @battle.eachBattler do |b| # Other battlers no longer trapped by self - next if b.effects[PBEffects::TrappingUser]!=@index - b.effects[PBEffects::Trapping] = 0 - b.effects[PBEffects::TrappingUser] = -1 - end - @effects[PBEffects::Truant] = false - @effects[PBEffects::TwoTurnAttack] = nil - @effects[PBEffects::Type3] = nil - @effects[PBEffects::Unburden] = false - @effects[PBEffects::Uproar] = 0 - @effects[PBEffects::WaterSport] = false - @effects[PBEffects::WeightChange] = 0 - @effects[PBEffects::Yawn] = 0 - end - - #============================================================================= - # Refreshing a battler's properties - #============================================================================= - def pbUpdate(fullChange=false) - return if !@pokemon - @pokemon.calc_stats - @level = @pokemon.level - @hp = @pokemon.hp - @totalhp = @pokemon.totalhp - if !@effects[PBEffects::Transform] - @attack = @pokemon.attack - @defense = @pokemon.defense - @spatk = @pokemon.spatk - @spdef = @pokemon.spdef - @speed = @pokemon.speed - if fullChange - @type1 = @pokemon.type1 - @type2 = @pokemon.type2 - @ability_id = @pokemon.ability_id - end - end - end - - # Used to erase the battler of a Pokémon that has been caught. - def pbReset - @pokemon = nil - @pokemonIndex = -1 - @hp = 0 - pbInitEffects(false) - @participants = [] - # Reset status - @status = :NONE - @statusCount = 0 - # Reset choice - @battle.pbClearChoice(@index) - end - - # Update which Pokémon will gain Exp if this battler is defeated. - def pbUpdateParticipants - return if fainted? || !@battle.opposes?(@index) - eachOpposing do |b| - @participants.push(b.pokemonIndex) if !@participants.include?(b.pokemonIndex) - end - end -end diff --git a/Data/Scripts/011_Battle/001_Battler/003_Battler_ChangeSelf.rb b/Data/Scripts/011_Battle/001_Battler/003_Battler_ChangeSelf.rb deleted file mode 100644 index ba8f420f2..000000000 --- a/Data/Scripts/011_Battle/001_Battler/003_Battler_ChangeSelf.rb +++ /dev/null @@ -1,312 +0,0 @@ -class PokeBattle_Battler - #============================================================================= - # Change HP - #============================================================================= - def pbReduceHP(amt,anim=true,registerDamage=true,anyAnim=true) - amt = amt.round - amt = @hp if amt>@hp - amt = 1 if amt<1 && !fainted? - oldHP = @hp - self.hp -= amt - PBDebug.log("[HP change] #{pbThis} lost #{amt} HP (#{oldHP}=>#{@hp})") if amt>0 - raise _INTL("HP less than 0") if @hp<0 - raise _INTL("HP greater than total HP") if @hp>@totalhp - @battle.scene.pbHPChanged(self,oldHP,anim) if anyAnim && amt>0 - @tookDamage = true if amt>0 && registerDamage - return amt - end - - def pbRecoverHP(amt,anim=true,anyAnim=true) - amt = amt.round - amt = @totalhp-@hp if amt>@totalhp-@hp - amt = 1 if amt<1 && @hp<@totalhp - oldHP = @hp - self.hp += amt - PBDebug.log("[HP change] #{pbThis} gained #{amt} HP (#{oldHP}=>#{@hp})") if amt>0 - raise _INTL("HP less than 0") if @hp<0 - raise _INTL("HP greater than total HP") if @hp>@totalhp - @battle.scene.pbHPChanged(self,oldHP,anim) if anyAnim && amt>0 - return amt - end - - def pbRecoverHPFromDrain(amt,target,msg=nil) - if target.hasActiveAbility?(:LIQUIDOOZE, true) - @battle.pbShowAbilitySplash(target) - pbReduceHP(amt) - @battle.pbDisplay(_INTL("{1} sucked up the liquid ooze!",pbThis)) - @battle.pbHideAbilitySplash(target) - pbItemHPHealCheck - else - msg = _INTL("{1} had its energy drained!",target.pbThis) if nil_or_empty?(msg) - @battle.pbDisplay(msg) - if canHeal? - amt = (amt*1.3).floor if hasActiveItem?(:BIGROOT) - pbRecoverHP(amt) - end - end - end - - def pbFaint(showMessage=true) - if !fainted? - PBDebug.log("!!!***Can't faint with HP greater than 0") - return - end - return if @fainted # Has already fainted properly - @battle.pbDisplayBrief(_INTL("{1} fainted!",pbThis)) if showMessage - updateSpirits() - PBDebug.log("[Pokémon fainted] #{pbThis} (#{@index})") if !showMessage - @battle.scene.pbFaintBattler(self) - pbInitEffects(false) - # Reset status - self.status = :NONE - self.statusCount = 0 - # Lose happiness - if @pokemon && @battle.internalBattle - badLoss = false - @battle.eachOtherSideBattler(@index) do |b| - badLoss = true if b.level>=self.level+30 - end - @pokemon.changeHappiness((badLoss) ? "faintbad" : "faint") - end - # Reset form - @battle.peer.pbOnLeavingBattle(@battle,@pokemon,@battle.usedInBattle[idxOwnSide][@index/2]) - @pokemon.makeUnmega if mega? - @pokemon.makeUnprimal if primal? - # Do other things - @battle.pbClearChoice(@index) # Reset choice - pbOwnSide.effects[PBEffects::LastRoundFainted] = @battle.turnCount - # Check other battlers' abilities that trigger upon a battler fainting - pbAbilitiesOnFainting - # Check for end of primordial weather - @battle.pbEndPrimordialWeather - end - - def updateSpirits() - if $PokemonBag.pbQuantity(:ODDKEYSTONE)>=1 && @pokemon.hasType?(:GHOST) - nbSpirits = pbGet(VAR_ODDKEYSTONE_NB) - if nbSpirits < 108 - pbSet(VAR_ODDKEYSTONE_NB, nbSpirits+1) - end - end - end - - #============================================================================= - # Move PP - #============================================================================= - def pbSetPP(move,pp) - move.pp = pp - # No need to care about @effects[PBEffects::Mimic], since Mimic can't copy - # Mimic - if move.realMove && move.id==move.realMove.id && !@effects[PBEffects::Transform] - move.realMove.pp = pp - end - end - - def pbReducePP(move) - return true if usingMultiTurnAttack? - return true if move.pp<0 # Don't reduce PP for special calls of moves - return true if move.total_pp<=0 # Infinite PP, can always be used - return false if move.pp==0 # Ran out of PP, couldn't reduce - pbSetPP(move,move.pp-1) if move.pp>0 - return true - end - - def pbReducePPOther(move) - pbSetPP(move,move.pp-1) if move.pp>0 - end - - #============================================================================= - # Change type - #============================================================================= - def pbChangeTypes(newType) - if newType.is_a?(PokeBattle_Battler) - newTypes = newType.pbTypes - newTypes.push(:NORMAL) if newTypes.length == 0 - newType3 = newType.effects[PBEffects::Type3] - newType3 = nil if newTypes.include?(newType3) - @type1 = newTypes[0] - @type2 = (newTypes.length == 1) ? newTypes[0] : newTypes[1] - @effects[PBEffects::Type3] = newType3 - else - newType = GameData::Type.get(newType).id - @type1 = newType - @type2 = newType - @effects[PBEffects::Type3] = nil - end - @effects[PBEffects::BurnUp] = false - @effects[PBEffects::Roost] = false - end - - #============================================================================= - # Forms - #============================================================================= - def pbChangeForm(newForm,msg) - return if fainted? || @effects[PBEffects::Transform] || @form==newForm - oldForm = @form - oldDmg = @totalhp-@hp - self.form = newForm - pbUpdate(true) - @hp = @totalhp-oldDmg - @effects[PBEffects::WeightChange] = 0 if Settings::MECHANICS_GENERATION >= 6 - @battle.scene.pbChangePokemon(self,@pokemon) - @battle.scene.pbRefreshOne(@index) - @battle.pbDisplay(msg) if msg && msg!="" - PBDebug.log("[Form changed] #{pbThis} changed from form #{oldForm} to form #{newForm}") - @battle.pbSetSeen(self) - end - - def pbCheckFormOnStatusChange - return if fainted? || @effects[PBEffects::Transform] - # Shaymin - reverts if frozen - if isSpecies?(:SHAYMIN) && frozen? - pbChangeForm(0,_INTL("{1} transformed!",pbThis)) - end - end - - def pbCheckFormOnMovesetChange - return if fainted? || @effects[PBEffects::Transform] - # Keldeo - knowing Secret Sword - if isSpecies?(:KELDEO) - newForm = 0 - newForm = 1 if pbHasMove?(:SECRETSWORD) - pbChangeForm(newForm,_INTL("{1} transformed!",pbThis)) - end - end - - def pbCheckFormOnWeatherChange - return if fainted? || @effects[PBEffects::Transform] - # Castform - Forecast - if isSpecies?(:CASTFORM) - if hasActiveAbility?(:FORECAST) - newForm = 0 - case @battle.pbWeather - when :Sun, :HarshSun then newForm = 1 - when :Rain, :HeavyRain then newForm = 2 - when :Hail then newForm = 3 - end - if @form!=newForm - @battle.pbShowAbilitySplash(self,true) - @battle.pbHideAbilitySplash(self) - pbChangeForm(newForm,_INTL("{1} transformed!",pbThis)) - end - else - pbChangeForm(0,_INTL("{1} transformed!",pbThis)) - end - end - # Cherrim - Flower Gift - if isSpecies?(:CHERRIM) - if hasActiveAbility?(:FLOWERGIFT) - newForm = 0 - newForm = 1 if [:Sun, :HarshSun].include?(@battle.pbWeather) - if @form!=newForm - @battle.pbShowAbilitySplash(self,true) - @battle.pbHideAbilitySplash(self) - pbChangeForm(newForm,_INTL("{1} transformed!",pbThis)) - end - else - pbChangeForm(0,_INTL("{1} transformed!",pbThis)) - end - end - end - - # Checks the Pokémon's form and updates it if necessary. Used for when a - # Pokémon enters battle (endOfRound=false) and at the end of each round - # (endOfRound=true). - def pbCheckForm(endOfRound=false) - return if fainted? || @effects[PBEffects::Transform] - # Form changes upon entering battle and when the weather changes - pbCheckFormOnWeatherChange if !endOfRound - # Darmanitan - Zen Mode - if isSpecies?(:DARMANITAN) && self.ability == :ZENMODE - if @hp<=@totalhp/2 - if @form!=1 - @battle.pbShowAbilitySplash(self,true) - @battle.pbHideAbilitySplash(self) - pbChangeForm(1,_INTL("{1} triggered!",abilityName)) - end - elsif @form!=0 - @battle.pbShowAbilitySplash(self,true) - @battle.pbHideAbilitySplash(self) - pbChangeForm(0,_INTL("{1} triggered!",abilityName)) - end - end - # Minior - Shields Down - if isSpecies?(:MINIOR) && self.ability == :SHIELDSDOWN - if @hp>@totalhp/2 # Turn into Meteor form - newForm = (@form>=7) ? @form-7 : @form - if @form!=newForm - @battle.pbShowAbilitySplash(self,true) - @battle.pbHideAbilitySplash(self) - pbChangeForm(newForm,_INTL("{1} deactivated!",abilityName)) - elsif !endOfRound - @battle.pbDisplay(_INTL("{1} deactivated!",abilityName)) - end - elsif @form<7 # Turn into Core form - @battle.pbShowAbilitySplash(self,true) - @battle.pbHideAbilitySplash(self) - pbChangeForm(@form+7,_INTL("{1} activated!",abilityName)) - end - end - # Wishiwashi - Schooling - if isSpecies?(:WISHIWASHI) && self.ability == :SCHOOLING - if @level>=20 && @hp>@totalhp/4 - if @form!=1 - @battle.pbShowAbilitySplash(self,true) - @battle.pbHideAbilitySplash(self) - pbChangeForm(1,_INTL("{1} formed a school!",pbThis)) - end - elsif @form!=0 - @battle.pbShowAbilitySplash(self,true) - @battle.pbHideAbilitySplash(self) - pbChangeForm(0,_INTL("{1} stopped schooling!",pbThis)) - end - end - # Zygarde - Power Construct - if isSpecies?(:ZYGARDE) && self.ability == :POWERCONSTRUCT && endOfRound - if @hp<=@totalhp/2 && @form<2 # Turn into Complete Forme - newForm = @form+2 - @battle.pbDisplay(_INTL("You sense the presence of many!")) - @battle.pbShowAbilitySplash(self,true) - @battle.pbHideAbilitySplash(self) - pbChangeForm(newForm,_INTL("{1} transformed into its Complete Forme!",pbThis)) - end - end - end - - def pbTransform(target) - if target.is_a?(Integer) - @battle.pbDisplay(_INTL("But it failed...")) - return - end - oldAbil = @ability_id - @effects[PBEffects::Transform] = true - @effects[PBEffects::TransformSpecies] = target.species - pbChangeTypes(target) - self.ability = target.ability - self.ability2 = target.ability2 if target.ability2 - @attack = target.attack - @defense = target.defense - @spatk = target.spatk - @spdef = target.spdef - @speed = target.speed - GameData::Stat.each_battle { |s| @stages[s.id] = target.stages[s.id] } - if Settings::NEW_CRITICAL_HIT_RATE_MECHANICS - @effects[PBEffects::FocusEnergy] = target.effects[PBEffects::FocusEnergy] - @effects[PBEffects::LaserFocus] = target.effects[PBEffects::LaserFocus] - end - @moves.clear - target.moves.each_with_index do |m,i| - @moves[i] = PokeBattle_Move.from_pokemon_move(@battle, Pokemon::Move.new(m.id)) - @moves[i].pp = 5 - @moves[i].total_pp = 5 - end - @effects[PBEffects::Disable] = 0 - @effects[PBEffects::DisableMove] = nil - @effects[PBEffects::WeightChange] = target.effects[PBEffects::WeightChange] - @battle.scene.pbRefreshOne(@index) - @battle.pbDisplay(_INTL("{1} transformed into {2}!",pbThis,target.pbThis(true))) - pbOnAbilityChanged(oldAbil) - end - - def pbHyperMode; end -end diff --git a/Data/Scripts/011_Battle/001_Battler/004_Battler_Statuses.rb b/Data/Scripts/011_Battle/001_Battler/004_Battler_Statuses.rb deleted file mode 100644 index 733192ec3..000000000 --- a/Data/Scripts/011_Battle/001_Battler/004_Battler_Statuses.rb +++ /dev/null @@ -1,576 +0,0 @@ -class PokeBattle_Battler - #============================================================================= - # Generalised checks for whether a status problem can be inflicted - #============================================================================= - # NOTE: Not all "does it have this status?" checks use this method. If the - # check is leading up to curing self of that status condition, then it - # will look at the value of @status directly instead - if it is that - # status condition then it is curable. This method only checks for - # "counts as having that status", which includes Comatose which can't be - # cured. - def pbHasStatus?(checkStatus) - if BattleHandlers.triggerStatusCheckAbilityNonIgnorable(self.ability,self,checkStatus) - return true - end - return @status==checkStatus - end - - def pbHasAnyStatus? - if BattleHandlers.triggerStatusCheckAbilityNonIgnorable(self.ability,self,nil) - return true - end - return @status != :NONE - end - - def pbCanInflictStatus?(newStatus,user,showMessages,move=nil,ignoreStatus=false) - return false if fainted? - selfInflicted = (user && user.index==@index) - # Already have that status problem - if self.status==newStatus && !ignoreStatus - if showMessages - msg = "" - case self.status - when :SLEEP then msg = _INTL("{1} is already asleep!", pbThis) - when :POISON then msg = _INTL("{1} is already poisoned!", pbThis) - when :BURN then msg = _INTL("{1} already has a burn!", pbThis) - when :PARALYSIS then msg = _INTL("{1} is already paralyzed!", pbThis) - when :FROZEN then msg = _INTL("{1} is already frozen solid!", pbThis) - end - @battle.pbDisplay(msg) - end - return false - end - # Trying to replace a status problem with another one - if self.status != :NONE && !ignoreStatus && !selfInflicted - @battle.pbDisplay(_INTL("It doesn't affect {1}...",pbThis(true))) if showMessages - return false - end - # Trying to inflict a status problem on a Pokémon behind a substitute - if @effects[PBEffects::Substitute]>0 && !(move && move.ignoresSubstitute?(user)) && - !selfInflicted - @battle.pbDisplay(_INTL("It doesn't affect {1}...",pbThis(true))) if showMessages - return false - end - # Weather immunity - if newStatus == :FROZEN && [:Sun, :HarshSun].include?(@battle.pbWeather) - @battle.pbDisplay(_INTL("It doesn't affect {1}...",pbThis(true))) if showMessages - return false - end - # Terrains immunity - if affectedByTerrain? - case @battle.field.terrain - when :Electric - if newStatus == :SLEEP - @battle.pbDisplay(_INTL("{1} surrounds itself with electrified terrain!", - pbThis(true))) if showMessages - return false - end - when :Misty - @battle.pbDisplay(_INTL("{1} surrounds itself with misty terrain!",pbThis(true))) if showMessages - return false - end - end - # Uproar immunity - if newStatus == :SLEEP && !(hasActiveAbility?(:SOUNDPROOF) && !@battle.moldBreaker) - @battle.eachBattler do |b| - next if b.effects[PBEffects::Uproar]==0 - @battle.pbDisplay(_INTL("But the uproar kept {1} awake!",pbThis(true))) if showMessages - return false - end - end - # Type immunities - hasImmuneType = false - case newStatus - when :SLEEP - # No type is immune to sleep - when :POISON - if !(user && user.hasActiveAbility?(:CORROSION)) - hasImmuneType |= pbHasType?(:POISON) - hasImmuneType |= pbHasType?(:STEEL) - end - when :BURN - hasImmuneType |= pbHasType?(:FIRE) - when :PARALYSIS - hasImmuneType |= pbHasType?(:ELECTRIC) && Settings::MORE_TYPE_EFFECTS - when :FROZEN - hasImmuneType |= pbHasType?(:ICE) - end - if hasImmuneType - @battle.pbDisplay(_INTL("It doesn't affect {1}...",pbThis(true))) if showMessages - return false - end - # Ability immunity - immuneByAbility = false; immAlly = nil - if BattleHandlers.triggerStatusImmunityAbilityNonIgnorable(self.ability,self,newStatus) - immuneByAbility = true - elsif selfInflicted || !@battle.moldBreaker - if abilityActive? && BattleHandlers.triggerStatusImmunityAbility(self.ability,self,newStatus) - immuneByAbility = true - else - eachAlly do |b| - next if !b.abilityActive? - next if !BattleHandlers.triggerStatusImmunityAllyAbility(b.ability,self,newStatus) - immuneByAbility = true - immAlly = b - break - end - end - end - if immuneByAbility - if showMessages - @battle.pbShowAbilitySplash(immAlly || self) - msg = "" - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - case newStatus - when :SLEEP then msg = _INTL("{1} stays awake!", pbThis) - when :POISON then msg = _INTL("{1} cannot be poisoned!", pbThis) - when :BURN then msg = _INTL("{1} cannot be burned!", pbThis) - when :PARALYSIS then msg = _INTL("{1} cannot be paralyzed!", pbThis) - when :FROZEN then msg = _INTL("{1} cannot be frozen solid!", pbThis) - end - elsif immAlly - case newStatus - when :SLEEP - msg = _INTL("{1} stays awake because of {2}'s {3}!", - pbThis,immAlly.pbThis(true),immAlly.abilityName) - when :POISON - msg = _INTL("{1} cannot be poisoned because of {2}'s {3}!", - pbThis,immAlly.pbThis(true),immAlly.abilityName) - when :BURN - msg = _INTL("{1} cannot be burned because of {2}'s {3}!", - pbThis,immAlly.pbThis(true),immAlly.abilityName) - when :PARALYSIS - msg = _INTL("{1} cannot be paralyzed because of {2}'s {3}!", - pbThis,immAlly.pbThis(true),immAlly.abilityName) - when :FROZEN - msg = _INTL("{1} cannot be frozen solid because of {2}'s {3}!", - pbThis,immAlly.pbThis(true),immAlly.abilityName) - end - else - case newStatus - when :SLEEP then msg = _INTL("{1} stays awake because of its {2}!", pbThis, abilityName) - when :POISON then msg = _INTL("{1}'s {2} prevents poisoning!", pbThis, abilityName) - when :BURN then msg = _INTL("{1}'s {2} prevents burns!", pbThis, abilityName) - when :PARALYSIS then msg = _INTL("{1}'s {2} prevents paralysis!", pbThis, abilityName) - when :FROZEN then msg = _INTL("{1}'s {2} prevents freezing!", pbThis, abilityName) - end - end - @battle.pbDisplay(msg) - @battle.pbHideAbilitySplash(immAlly || self) - end - return false - end - # Safeguard immunity - if pbOwnSide.effects[PBEffects::Safeguard]>0 && !selfInflicted && move && - !(user && user.hasActiveAbility?(:INFILTRATOR)) - @battle.pbDisplay(_INTL("{1}'s team is protected by Safeguard!",pbThis)) if showMessages - return false - end - return true - end - - def pbCanSynchronizeStatus?(newStatus,target) - return false if fainted? - # Trying to replace a status problem with another one - return false if self.status != :NONE - # Terrain immunity - return false if @battle.field.terrain == :Misty && affectedByTerrain? - # Type immunities - hasImmuneType = false - case newStatus - when :POISON - # NOTE: target will have Synchronize, so it can't have Corrosion. - if !(target && target.hasActiveAbility?(:CORROSION)) - hasImmuneType |= pbHasType?(:POISON) - hasImmuneType |= pbHasType?(:STEEL) - end - when :BURN - hasImmuneType |= pbHasType?(:FIRE) - when :PARALYSIS - hasImmuneType |= pbHasType?(:ELECTRIC) && Settings::MORE_TYPE_EFFECTS - end - return false if hasImmuneType - # Ability immunity - if BattleHandlers.triggerStatusImmunityAbilityNonIgnorable(self.ability,self,newStatus) - return false - end - if abilityActive? && BattleHandlers.triggerStatusImmunityAbility(self.ability,self,newStatus) - return false - end - eachAlly do |b| - next if !b.abilityActive? - next if !BattleHandlers.triggerStatusImmunityAllyAbility(b.ability,self,newStatus) - return false - end - # Safeguard immunity - if pbOwnSide.effects[PBEffects::Safeguard]>0 && - !(user && user.hasActiveAbility?(:INFILTRATOR)) - return false - end - return true - end - - #============================================================================= - # Generalised infliction of status problem - #============================================================================= - def pbInflictStatus(newStatus,newStatusCount=0,msg=nil,user=nil) - # Inflict the new status - self.status = newStatus - self.statusCount = newStatusCount - @effects[PBEffects::Toxic] = 0 - # Show animation - if newStatus == :POISON && newStatusCount > 0 - @battle.pbCommonAnimation("Toxic", self) - else - anim_name = GameData::Status.get(newStatus).animation - @battle.pbCommonAnimation(anim_name, self) if anim_name - end - # Show message - if msg && !msg.empty? - @battle.pbDisplay(msg) - else - case newStatus - when :SLEEP - @battle.pbDisplay(_INTL("{1} fell asleep!", pbThis)) - when :POISON - if newStatusCount>0 - @battle.pbDisplay(_INTL("{1} was badly poisoned!", pbThis)) - else - @battle.pbDisplay(_INTL("{1} was poisoned!", pbThis)) - end - when :BURN - @battle.pbDisplay(_INTL("{1} was burned!", pbThis)) - when :PARALYSIS - @battle.pbDisplay(_INTL("{1} is paralyzed! It may be unable to move!", pbThis)) - when :FROZEN - @battle.pbDisplay(_INTL("{1} was frozen solid!", pbThis)) - end - end - PBDebug.log("[Status change] #{pbThis}'s sleep count is #{newStatusCount}") if newStatus == :SLEEP - # Form change check - pbCheckFormOnStatusChange - # Synchronize - if abilityActive? - BattleHandlers.triggerAbilityOnStatusInflicted(self.ability,self,user,newStatus) - end - # Status cures - pbItemStatusCureCheck - pbAbilityStatusCureCheck - # Petal Dance/Outrage/Thrash get cancelled immediately by falling asleep - # NOTE: I don't know why this applies only to Outrage and only to falling - # asleep (i.e. it doesn't cancel Rollout/Uproar/other multi-turn - # moves, and it doesn't cancel any moves if self becomes frozen/ - # disabled/anything else). This behaviour was tested in Gen 5. - if @status == :SLEEP && @effects[PBEffects::Outrage] > 0 - @effects[PBEffects::Outrage] = 0 - @currentMove = nil - end - end - - #============================================================================= - # Sleep - #============================================================================= - def asleep? - return pbHasStatus?(:SLEEP) - end - - def pbCanSleep?(user, showMessages, move = nil, ignoreStatus = false) - return pbCanInflictStatus?(:SLEEP, user, showMessages, move, ignoreStatus) - end - - def pbCanSleepYawn? - return false if self.status != :NONE - if affectedByTerrain? - return false if [:Electric, :Misty].include?(@battle.field.terrain) - end - if !hasActiveAbility?(:SOUNDPROOF) - @battle.eachBattler do |b| - return false if b.effects[PBEffects::Uproar]>0 - end - end - if BattleHandlers.triggerStatusImmunityAbilityNonIgnorable(self.ability, self, :SLEEP) - return false - end - # NOTE: Bulbapedia claims that Flower Veil shouldn't prevent sleep due to - # drowsiness, but I disagree because that makes no sense. Also, the - # comparable Sweet Veil does prevent sleep due to drowsiness. - if abilityActive? && BattleHandlers.triggerStatusImmunityAbility(self.ability, self, :SLEEP) - return false - end - eachAlly do |b| - next if !b.abilityActive? - next if !BattleHandlers.triggerStatusImmunityAllyAbility(b.ability, self, :SLEEP) - return false - end - # NOTE: Bulbapedia claims that Safeguard shouldn't prevent sleep due to - # drowsiness. I disagree with this too. Compare with the other sided - # effects Misty/Electric Terrain, which do prevent it. - return false if pbOwnSide.effects[PBEffects::Safeguard]>0 - return true - end - - def pbSleep(msg = nil) - pbInflictStatus(:SLEEP, pbSleepDuration, msg) - end - - def pbSleepSelf(msg = nil, duration = -1) - pbInflictStatus(:SLEEP, pbSleepDuration(duration), msg) - end - - def pbSleepDuration(duration = -1) - duration = 2 + @battle.pbRandom(3) if duration <= 0 - duration = (duration / 2).floor if hasActiveAbility?(:EARLYBIRD) - return duration - end - - #============================================================================= - # Poison - #============================================================================= - def poisoned? - return pbHasStatus?(:POISON) - end - - def pbCanPoison?(user, showMessages, move = nil) - return pbCanInflictStatus?(:POISON, user, showMessages, move) - end - - def pbCanPoisonSynchronize?(target) - return pbCanSynchronizeStatus?(:POISON, target) - end - - def pbPoison(user = nil, msg = nil, toxic = false) - pbInflictStatus(:POISON, (toxic) ? 1 : 0, msg, user) - end - - #============================================================================= - # Burn - #============================================================================= - def burned? - return pbHasStatus?(:BURN) - end - - def pbCanBurn?(user, showMessages, move = nil) - return pbCanInflictStatus?(:BURN, user, showMessages, move) - end - - def pbCanBurnSynchronize?(target) - return pbCanSynchronizeStatus?(:BURN, target) - end - - def pbBurn(user = nil, msg = nil) - pbInflictStatus(:BURN, 0, msg, user) - end - - #============================================================================= - # Paralyze - #============================================================================= - def paralyzed? - return pbHasStatus?(:PARALYSIS) - end - - def pbCanParalyze?(user, showMessages, move = nil) - return pbCanInflictStatus?(:PARALYSIS, user, showMessages, move) - end - - def pbCanParalyzeSynchronize?(target) - return pbCanSynchronizeStatus?(:PARALYSIS, target) - end - - def pbParalyze(user = nil, msg = nil) - pbInflictStatus(:PARALYSIS, 0, msg, user) - end - - #============================================================================= - # Freeze - #============================================================================= - def frozen? - return pbHasStatus?(:FROZEN) - end - - def pbCanFreeze?(user, showMessages, move = nil) - return pbCanInflictStatus?(:FROZEN, user, showMessages, move) - end - - def pbFreeze(msg = nil) - pbInflictStatus(:FROZEN, 0, msg) - end - - #============================================================================= - # Generalised status displays - #============================================================================= - def pbContinueStatus - if self.status == :POISON && @statusCount > 0 - @battle.pbCommonAnimation("Toxic", self) - else - anim_name = GameData::Status.get(self.status).animation - @battle.pbCommonAnimation(anim_name, self) if anim_name - end - yield if block_given? - case self.status - when :SLEEP - @battle.pbDisplay(_INTL("{1} is fast asleep.", pbThis)) - when :POISON - @battle.pbDisplay(_INTL("{1} was hurt by poison!", pbThis)) - when :BURN - @battle.pbDisplay(_INTL("{1} was hurt by its burn!", pbThis)) - when :PARALYSIS - @battle.pbDisplay(_INTL("{1} is paralyzed! It can't move!", pbThis)) - when :FROZEN - @battle.pbDisplay(_INTL("{1} is frozen solid!", pbThis)) - end - PBDebug.log("[Status continues] #{pbThis}'s sleep count is #{@statusCount}") if self.status == :SLEEP - end - - def pbCureStatus(showMessages=true) - oldStatus = status - self.status = :NONE - if showMessages - case oldStatus - when :SLEEP then @battle.pbDisplay(_INTL("{1} woke up!", pbThis)) - when :POISON then @battle.pbDisplay(_INTL("{1} was cured of its poisoning.", pbThis)) - when :BURN then @battle.pbDisplay(_INTL("{1}'s burn was healed.", pbThis)) - when :PARALYSIS then @battle.pbDisplay(_INTL("{1} was cured of paralysis.", pbThis)) - when :FROZEN then @battle.pbDisplay(_INTL("{1} thawed out!", pbThis)) - end - end - PBDebug.log("[Status change] #{pbThis}'s status was cured") if !showMessages - end - - #============================================================================= - # Confusion - #============================================================================= - def pbCanConfuse?(user=nil,showMessages=true,move=nil,selfInflicted=false) - return false if fainted? - if @effects[PBEffects::Confusion]>0 - @battle.pbDisplay(_INTL("{1} is already confused.",pbThis)) if showMessages - return false - end - if @effects[PBEffects::Substitute]>0 && !(move && move.ignoresSubstitute?(user)) && - !selfInflicted - @battle.pbDisplay(_INTL("But it failed!")) if showMessages - return false - end - # Terrains immunity - if affectedByTerrain? && @battle.field.terrain == :Misty - @battle.pbDisplay(_INTL("{1} surrounds itself with misty terrain!",pbThis(true))) if showMessages - return false - end - if selfInflicted || !@battle.moldBreaker - if hasActiveAbility?(:OWNTEMPO) - if showMessages - @battle.pbShowAbilitySplash(self) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - @battle.pbDisplay(_INTL("{1} doesn't become confused!",pbThis)) - else - @battle.pbDisplay(_INTL("{1}'s {2} prevents confusion!",pbThis,abilityName)) - end - @battle.pbHideAbilitySplash(self) - end - return false - end - end - if pbOwnSide.effects[PBEffects::Safeguard]>0 && !selfInflicted && - !(user && user.hasActiveAbility?(:INFILTRATOR)) - @battle.pbDisplay(_INTL("{1}'s team is protected by Safeguard!",pbThis)) if showMessages - return false - end - return true - end - - def pbCanConfuseSelf?(showMessages) - return pbCanConfuse?(nil,showMessages,nil,true) - end - - def pbConfuse(msg=nil) - @effects[PBEffects::Confusion] = pbConfusionDuration - @battle.pbCommonAnimation("Confusion",self) - msg = _INTL("{1} became confused!",pbThis) if nil_or_empty?(msg) - @battle.pbDisplay(msg) - PBDebug.log("[Lingering effect] #{pbThis}'s confusion count is #{@effects[PBEffects::Confusion]}") - # Confusion cures - pbItemStatusCureCheck - pbAbilityStatusCureCheck - end - - def pbConfusionDuration(duration=-1) - duration = 2+@battle.pbRandom(4) if duration<=0 - return duration - end - - def pbCureConfusion - @effects[PBEffects::Confusion] = 0 - end - - #============================================================================= - # Attraction - #============================================================================= - def pbCanAttract?(user,showMessages=true) - return false if fainted? - return false if !user || user.fainted? - if @effects[PBEffects::Attract]>=0 - @battle.pbDisplay(_INTL("{1} is unaffected!",pbThis)) if showMessages - return false - end - agender = user.gender - ogender = gender - if agender==2 || ogender==2 || agender==ogender - @battle.pbDisplay(_INTL("{1} is unaffected!",pbThis)) if showMessages - return false - end - if !@battle.moldBreaker - if hasActiveAbility?([:AROMAVEIL,:OBLIVIOUS]) - if showMessages - @battle.pbShowAbilitySplash(self) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - @battle.pbDisplay(_INTL("{1} is unaffected!",pbThis)) - else - @battle.pbDisplay(_INTL("{1}'s {2} prevents romance!",pbThis,abilityName)) - end - @battle.pbHideAbilitySplash(self) - end - return false - else - eachAlly do |b| - next if !b.hasActiveAbility?(:AROMAVEIL) - if showMessages - @battle.pbShowAbilitySplash(self) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - @battle.pbDisplay(_INTL("{1} is unaffected!",pbThis)) - else - @battle.pbDisplay(_INTL("{1}'s {2} prevents romance!",b.pbThis,b.abilityName)) - end - @battle.pbHideAbilitySplash(self) - end - return true - end - end - end - return true - end - - def pbAttract(user,msg=nil) - @effects[PBEffects::Attract] = user.index - @battle.pbCommonAnimation("Attract",self) - msg = _INTL("{1} fell in love!",pbThis) if nil_or_empty?(msg) - @battle.pbDisplay(msg) - # Destiny Knot - if hasActiveItem?(:DESTINYKNOT) && user.pbCanAttract?(self,false) - user.pbAttract(self,_INTL("{1} fell in love from the {2}!",user.pbThis(true),itemName)) - end - # Attraction cures - pbItemStatusCureCheck - pbAbilityStatusCureCheck - end - - def pbCureAttract - @effects[PBEffects::Attract] = -1 - end - - #============================================================================= - # Flinching - #============================================================================= - def pbFlinch(_user=nil) - return if hasActiveAbility?(:INNERFOCUS) && !@battle.moldBreaker - @effects[PBEffects::Flinch] = true - end -end diff --git a/Data/Scripts/011_Battle/001_Battler/005_Battler_StatStages.rb b/Data/Scripts/011_Battle/001_Battler/005_Battler_StatStages.rb deleted file mode 100644 index 978728c5f..000000000 --- a/Data/Scripts/011_Battle/001_Battler/005_Battler_StatStages.rb +++ /dev/null @@ -1,308 +0,0 @@ -class PokeBattle_Battler - #============================================================================= - # Increase stat stages - #============================================================================= - def statStageAtMax?(stat) - return @stages[stat]>=6 - end - - def pbCanRaiseStatStage?(stat,user=nil,move=nil,showFailMsg=false,ignoreContrary=false) - return false if fainted? - # Contrary - if hasActiveAbility?(:CONTRARY) && !ignoreContrary && !@battle.moldBreaker - return pbCanLowerStatStage?(stat,user,move,showFailMsg,true) - end - # Check the stat stage - if statStageAtMax?(stat) - @battle.pbDisplay(_INTL("{1}'s {2} won't go any higher!", - pbThis, GameData::Stat.get(stat).name)) if showFailMsg - return false - end - return true - end - - def pbRaiseStatStageBasic(stat,increment,ignoreContrary=false) - if !@battle.moldBreaker - # Contrary - if hasActiveAbility?(:CONTRARY) && !ignoreContrary - return pbLowerStatStageBasic(stat,increment,true) - end - # Simple - increment *= 2 if hasActiveAbility?(:SIMPLE) - end - # Change the stat stage - increment = [increment,6-@stages[stat]].min - if increment>0 - stat_name = GameData::Stat.get(stat).name - new = @stages[stat]+increment - PBDebug.log("[Stat change] #{pbThis}'s #{stat_name}: #{@stages[stat]} -> #{new} (+#{increment})") - @stages[stat] += increment - end - return increment - end - - def pbRaiseStatStage(stat,increment,user,showAnim=true,ignoreContrary=false) - # Contrary - if hasActiveAbility?(:CONTRARY) && !ignoreContrary && !@battle.moldBreaker - return pbLowerStatStage(stat,increment,user,showAnim,true) - end - # Perform the stat stage change - increment = pbRaiseStatStageBasic(stat,increment,ignoreContrary) - return false if increment<=0 - # Stat up animation and message - @battle.pbCommonAnimation("StatUp",self) if showAnim - arrStatTexts = [ - _INTL("{1}'s {2} rose!",pbThis,GameData::Stat.get(stat).name), - _INTL("{1}'s {2} rose sharply!",pbThis,GameData::Stat.get(stat).name), - _INTL("{1}'s {2} rose drastically!",pbThis,GameData::Stat.get(stat).name)] - @battle.pbDisplay(arrStatTexts[[increment-1,2].min]) - # Trigger abilities upon stat gain - if abilityActive? - BattleHandlers.triggerAbilityOnStatGain(self.ability,self,stat,user) - end - return true - end - - def pbRaiseStatStageByCause(stat,increment,user,cause,showAnim=true,ignoreContrary=false) - # Contrary - if hasActiveAbility?(:CONTRARY) && !ignoreContrary && !@battle.moldBreaker - return pbLowerStatStageByCause(stat,increment,user,cause,showAnim,true) - end - # Perform the stat stage change - increment = pbRaiseStatStageBasic(stat,increment,ignoreContrary) - return false if increment<=0 - # Stat up animation and message - @battle.pbCommonAnimation("StatUp",self) if showAnim - if user.index==@index - arrStatTexts = [ - _INTL("{1}'s {2} raised its {3}!",pbThis,cause,GameData::Stat.get(stat).name), - _INTL("{1}'s {2} sharply raised its {3}!",pbThis,cause,GameData::Stat.get(stat).name), - _INTL("{1}'s {2} drastically raised its {3}!",pbThis,cause,GameData::Stat.get(stat).name)] - else - arrStatTexts = [ - _INTL("{1}'s {2} raised {3}'s {4}!",user.pbThis,cause,pbThis(true),GameData::Stat.get(stat).name), - _INTL("{1}'s {2} sharply raised {3}'s {4}!",user.pbThis,cause,pbThis(true),GameData::Stat.get(stat).name), - _INTL("{1}'s {2} drastically raised {3}'s {4}!",user.pbThis,cause,pbThis(true),GameData::Stat.get(stat).name)] - end - @battle.pbDisplay(arrStatTexts[[increment-1,2].min]) - # Trigger abilities upon stat gain - if abilityActive? - BattleHandlers.triggerAbilityOnStatGain(self.ability,self,stat,user) - end - return true - end - - def pbRaiseStatStageByAbility(stat,increment,user,splashAnim=true, abilityName=nil) - return false if fainted? - ret = false - @battle.pbShowAbilitySplash(user,false,true,abilityName) #if splashAnim - if pbCanRaiseStatStage?(stat,user,nil,PokeBattle_SceneConstants::USE_ABILITY_SPLASH) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - ret = pbRaiseStatStage(stat,increment,user) - else - ret = pbRaiseStatStageByCause(stat,increment,user,user.abilityName) - end - end - @battle.pbHideAbilitySplash(user) if splashAnim - return ret - end - - #============================================================================= - # Decrease stat stages - #============================================================================= - def statStageAtMin?(stat) - return @stages[stat]<=-6 - end - - def pbCanLowerStatStage?(stat,user=nil,move=nil,showFailMsg=false,ignoreContrary=false) - return false if fainted? - # Contrary - if hasActiveAbility?(:CONTRARY) && !ignoreContrary && !@battle.moldBreaker - return pbCanRaiseStatStage?(stat,user,move,showFailMsg,true) - end - if !user || user.index!=@index # Not self-inflicted - if @effects[PBEffects::Substitute]>0 && !(move && move.ignoresSubstitute?(user)) - @battle.pbDisplay(_INTL("{1} is protected by its substitute!",pbThis)) if showFailMsg - return false - end - if pbOwnSide.effects[PBEffects::Mist]>0 && - !(user && user.hasActiveAbility?(:INFILTRATOR)) - @battle.pbDisplay(_INTL("{1} is protected by Mist!",pbThis)) if showFailMsg - return false - end - if abilityActive? - return false if BattleHandlers.triggerStatLossImmunityAbility( - self.ability,self,stat,@battle,showFailMsg) if !@battle.moldBreaker - return false if BattleHandlers.triggerStatLossImmunityAbilityNonIgnorable( - self.ability,self,stat,@battle,showFailMsg) - end - if !@battle.moldBreaker - eachAlly do |b| - next if !b.abilityActive? - return false if BattleHandlers.triggerStatLossImmunityAllyAbility( - b.ability,b,self,stat,@battle,showFailMsg) - end - end - end - # Check the stat stage - if statStageAtMin?(stat) - @battle.pbDisplay(_INTL("{1}'s {2} won't go any lower!", - pbThis, GameData::Stat.get(stat).name)) if showFailMsg - return false - end - return true - end - - def pbLowerStatStageBasic(stat,increment,ignoreContrary=false) - if !@battle.moldBreaker - # Contrary - if hasActiveAbility?(:CONTRARY) && !ignoreContrary - return pbRaiseStatStageBasic(stat,increment,true) - end - # Simple - increment *= 2 if hasActiveAbility?(:SIMPLE) - end - # Change the stat stage - increment = [increment,6+@stages[stat]].min - if increment>0 - stat_name = GameData::Stat.get(stat).name - new = @stages[stat]-increment - PBDebug.log("[Stat change] #{pbThis}'s #{stat_name}: #{@stages[stat]} -> #{new} (-#{increment})") - @stages[stat] -= increment - end - return increment - end - - def pbLowerStatStage(stat,increment,user,showAnim=true,ignoreContrary=false) - # Contrary - if hasActiveAbility?(:CONTRARY) && !ignoreContrary && !@battle.moldBreaker - return pbRaiseStatStage(stat,increment,user,showAnim,true) - end - # Perform the stat stage change - increment = pbLowerStatStageBasic(stat,increment,ignoreContrary) - return false if increment<=0 - # Stat down animation and message - @battle.pbCommonAnimation("StatDown",self) if showAnim - arrStatTexts = [ - _INTL("{1}'s {2} fell!",pbThis,GameData::Stat.get(stat).name), - _INTL("{1}'s {2} harshly fell!",pbThis,GameData::Stat.get(stat).name), - _INTL("{1}'s {2} severely fell!",pbThis,GameData::Stat.get(stat).name)] - @battle.pbDisplay(arrStatTexts[[increment-1,2].min]) - # Trigger abilities upon stat loss - if abilityActive? - BattleHandlers.triggerAbilityOnStatLoss(self.ability,self,stat,user) - end - return true - end - - def pbLowerStatStageByCause(stat,increment,user,cause,showAnim=true,ignoreContrary=false) - # Contrary - if hasActiveAbility?(:CONTRARY) && !ignoreContrary && !@battle.moldBreaker - return pbRaiseStatStageByCause(stat,increment,user,cause,showAnim,true) - end - # Perform the stat stage change - increment = pbLowerStatStageBasic(stat,increment,ignoreContrary) - return false if increment<=0 - # Stat down animation and message - @battle.pbCommonAnimation("StatDown",self) if showAnim - if user.index==@index - arrStatTexts = [ - _INTL("{1}'s {2} lowered its {3}!",pbThis,cause,GameData::Stat.get(stat).name), - _INTL("{1}'s {2} harshly lowered its {3}!",pbThis,cause,GameData::Stat.get(stat).name), - _INTL("{1}'s {2} severely lowered its {3}!",pbThis,cause,GameData::Stat.get(stat).name)] - else - arrStatTexts = [ - _INTL("{1}'s {2} lowered {3}'s {4}!",user.pbThis,cause,pbThis(true),GameData::Stat.get(stat).name), - _INTL("{1}'s {2} harshly lowered {3}'s {4}!",user.pbThis,cause,pbThis(true),GameData::Stat.get(stat).name), - _INTL("{1}'s {2} severely lowered {3}'s {4}!",user.pbThis,cause,pbThis(true),GameData::Stat.get(stat).name)] - end - @battle.pbDisplay(arrStatTexts[[increment-1,2].min]) - # Trigger abilities upon stat loss - if abilityActive? - BattleHandlers.triggerAbilityOnStatLoss(self.ability,self,stat,user) - end - return true - end - - def pbLowerStatStageByAbility(stat,increment,user,splashAnim=true,checkContact=false,ability_name=nil) - ret = false - @battle.pbShowAbilitySplash(user,false ,false ,ability_name) if splashAnim - if pbCanLowerStatStage?(stat,user,nil,PokeBattle_SceneConstants::USE_ABILITY_SPLASH) && - (!checkContact || affectedByContactEffect?(PokeBattle_SceneConstants::USE_ABILITY_SPLASH)) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - ret = pbLowerStatStage(stat,increment,user) - else - ret = pbLowerStatStageByCause(stat,increment,user,user.abilityName) - end - end - @battle.pbHideAbilitySplash(user) if splashAnim - return ret - end - - def pbLowerAttackStatStageIntimidate(user) - return false if fainted? - # NOTE: Substitute intentially blocks Intimidate even if self has Contrary. - if @effects[PBEffects::Substitute]>0 - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - @battle.pbDisplay(_INTL("{1} is protected by its substitute!",pbThis)) - else - @battle.pbDisplay(_INTL("{1}'s substitute protected it from {2}'s {3}!", - pbThis,user.pbThis(true),user.abilityName)) - end - return false - end - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - return pbLowerStatStageByAbility(:ATTACK,1,user,false,false ,user.abilityName) - end - # NOTE: These checks exist to ensure appropriate messages are shown if - # Intimidate is blocked somehow (i.e. the messages should mention the - # Intimidate ability by name). - if !hasActiveAbility?(:CONTRARY) - if pbOwnSide.effects[PBEffects::Mist]>0 - @battle.pbDisplay(_INTL("{1} is protected from {2}'s {3} by Mist!", - pbThis,user.pbThis(true),user.abilityName)) - return false - end - if abilityActive? - if BattleHandlers.triggerStatLossImmunityAbility(self.ability,self,:ATTACK,@battle,false) || - BattleHandlers.triggerStatLossImmunityAbilityNonIgnorable(self.ability,self,:ATTACK,@battle,false) - @battle.pbDisplay(_INTL("{1}'s {2} prevented {3}'s {4} from working!", - pbThis,abilityName,user.pbThis(true),user.abilityName)) - return false - end - end - eachAlly do |b| - next if !b.abilityActive? - if BattleHandlers.triggerStatLossImmunityAllyAbility(b.ability,b,self,:ATTACK,@battle,false) - @battle.pbDisplay(_INTL("{1} is protected from {2}'s {3} by {4}'s {5}!", - pbThis,user.pbThis(true),user.abilityName,b.pbThis(true),b.abilityName)) - return false - end - end - end - return false if !pbCanLowerStatStage?(:ATTACK,user) - return pbLowerStatStageByCause(:ATTACK,1,user,user.abilityName) - end - - #============================================================================= - # Reset stat stages - #============================================================================= - def hasAlteredStatStages? - GameData::Stat.each_battle { |s| return true if @stages[s.id] != 0 } - return false - end - - def hasRaisedStatStages? - GameData::Stat.each_battle { |s| return true if @stages[s.id] > 0 } - return false - end - - def hasLoweredStatStages? - GameData::Stat.each_battle { |s| return true if @stages[s.id] < 0 } - return false - end - - def pbResetStatStages - GameData::Stat.each_battle { |s| @stages[s.id] = 0 } - end -end diff --git a/Data/Scripts/011_Battle/001_Battler/006_Battler_AbilityAndItem.rb b/Data/Scripts/011_Battle/001_Battler/006_Battler_AbilityAndItem.rb deleted file mode 100644 index cbb909ecf..000000000 --- a/Data/Scripts/011_Battle/001_Battler/006_Battler_AbilityAndItem.rb +++ /dev/null @@ -1,303 +0,0 @@ -class PokeBattle_Battler - #============================================================================= - # Called when a Pokémon (self) is sent into battle or its ability changes. - #============================================================================= - def pbEffectsOnSwitchIn(switchIn=false) - # Healing Wish/Lunar Dance/entry hazards - @battle.pbOnActiveOne(self) if switchIn - # Primal Revert upon entering battle - @battle.pbPrimalReversion(@index) if !fainted? - # Ending primordial weather, checking Trace - pbContinualAbilityChecks(true) - # Abilities that trigger upon switching in - if (!fainted? && unstoppableAbility?) || abilityActive? - BattleHandlers.triggerAbilityOnSwitchIn(self.ability,self,@battle) - end - # Check for end of primordial weather - @battle.pbEndPrimordialWeather - # Items that trigger upon switching in (Air Balloon message) - if switchIn && itemActive? - BattleHandlers.triggerItemOnSwitchIn(self.item,self,@battle) - end - # Berry check, status-curing ability check - pbHeldItemTriggerCheck if switchIn - pbAbilityStatusCureCheck - end - - #============================================================================= - # Ability effects - #============================================================================= - def pbAbilitiesOnSwitchOut - if abilityActive? - BattleHandlers.triggerAbilityOnSwitchOut(self.ability,self,false) - end - # Reset form - @battle.peer.pbOnLeavingBattle(@battle,@pokemon,@battle.usedInBattle[idxOwnSide][@index/2]) - # Treat self as fainted - @hp = 0 - @fainted = true - # Check for end of primordial weather - @battle.pbEndPrimordialWeather - end - - def pbAbilitiesOnFainting - # Self fainted; check all other battlers to see if their abilities trigger - @battle.pbPriority(true).each do |b| - next if !b || !b.abilityActive? - BattleHandlers.triggerAbilityChangeOnBattlerFainting(b.ability,b,self,@battle) - end - @battle.pbPriority(true).each do |b| - next if !b || !b.abilityActive? - BattleHandlers.triggerAbilityOnBattlerFainting(b.ability,b,self,@battle) - end - end - - # Used for Emergency Exit/Wimp Out. - def pbAbilitiesOnDamageTaken(oldHP,newHP=-1) - return false if !abilityActive? - newHP = @hp if newHP<0 - return false if oldHP<@totalhp/2 || newHP>=@totalhp/2 # Didn't drop below half - ret = BattleHandlers.triggerAbilityOnHPDroppedBelowHalf(self.ability,self,@battle) - return ret # Whether self has switched out - end - - # Called when a Pokémon (self) enters battle, at the end of each move used, - # and at the end of each round. - def pbContinualAbilityChecks(onSwitchIn=false) - # Check for end of primordial weather - @battle.pbEndPrimordialWeather - # Trace - if hasActiveAbility?(:TRACE) - # NOTE: In Gen 5 only, Trace only triggers upon the Trace bearer switching - # in and not at any later times, even if a traceable ability turns - # up later. Essentials ignores this, and allows Trace to trigger - # whenever it can even in the old battle mechanics. - choices = [] - @battle.eachOtherSideBattler(@index) do |b| - next if b.ungainableAbility? || - [:POWEROFALCHEMY, :RECEIVER, :TRACE].include?(b.ability_id) - choices.push(b) - end - if choices.length>0 - choice = choices[@battle.pbRandom(choices.length)] - @battle.pbShowAbilitySplash(self) - self.ability = choice.ability - @battle.pbDisplay(_INTL("{1} traced {2}'s {3}!",pbThis,choice.pbThis(true),choice.abilityName)) - @battle.pbHideAbilitySplash(self) - if !onSwitchIn && (unstoppableAbility? || abilityActive?) - BattleHandlers.triggerAbilityOnSwitchIn(self.ability,self,@battle) - end - end - end - end - - #============================================================================= - # Ability curing - #============================================================================= - # Cures status conditions, confusion and infatuation. - def pbAbilityStatusCureCheck - if abilityActive? - BattleHandlers.triggerStatusCureAbility(self.ability,self) - end - end - - #============================================================================= - # Ability change - #============================================================================= - def pbOnAbilityChanged(oldAbil) - if @effects[PBEffects::Illusion] && oldAbil == :ILLUSION - @effects[PBEffects::Illusion] = nil - if !@effects[PBEffects::Transform] - @battle.scene.pbChangePokemon(self, @pokemon) - @battle.pbDisplay(_INTL("{1}'s {2} wore off!", pbThis, GameData::Ability.get(oldAbil).name)) - @battle.pbSetSeen(self) - end - end - @effects[PBEffects::GastroAcid] = false if unstoppableAbility? - @effects[PBEffects::SlowStart] = 0 if self.ability != :SLOWSTART - # Revert form if Flower Gift/Forecast was lost - pbCheckFormOnWeatherChange - # Check for end of primordial weather - @battle.pbEndPrimordialWeather - end - - #============================================================================= - # Held item consuming/removing - #============================================================================= - def canConsumeBerry? - return false if @battle.pbCheckOpposingAbility(:UNNERVE, @index) - return true - end - - def canConsumePinchBerry?(check_gluttony = true) - return false if !canConsumeBerry? - return true if @hp <= @totalhp / 4 - return true if @hp <= @totalhp / 2 && (!check_gluttony || hasActiveAbility?(:GLUTTONY)) - return false - end - - # permanent is whether the item is lost even after battle. Is false for Knock - # Off. - def pbRemoveItem(permanent = true) - @effects[PBEffects::ChoiceBand] = nil - @effects[PBEffects::Unburden] = true if self.item - - if permanent && self.item == self.initialItem - if $PokemonBag.pbQuantity(self.initialItem)>=1 - $PokemonBag.pbDeleteItem(self.initialItem) - else - setInitialItem(nil) - end - end - self.item = nil - end - - def pbConsumeItem(recoverable=true,symbiosis=true,belch=true) - PBDebug.log("[Item consumed] #{pbThis} consumed its held #{itemName}") - if recoverable - setRecycleItem(@item_id) - @effects[PBEffects::PickupItem] = @item_id - @effects[PBEffects::PickupUse] = @battle.nextPickupUse - end - setBelched if belch && self.item.is_berry? - pbRemoveItem - pbSymbiosis if symbiosis - end - - def pbSymbiosis - return if fainted? - return if !self.item - @battle.pbPriority(true).each do |b| - next if b.opposes? - next if !b.hasActiveAbility?(:SYMBIOSIS) - next if !b.item || b.unlosableItem?(b.item) - next if unlosableItem?(b.item) - @battle.pbShowAbilitySplash(b) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - @battle.pbDisplay(_INTL("{1} shared its {2} with {3}!", - b.pbThis,b.itemName,pbThis(true))) - else - @battle.pbDisplay(_INTL("{1}'s {2} let it share its {3} with {4}!", - b.pbThis,b.abilityName,b.itemName,pbThis(true))) - end - self.item = b.item - b.item = nil - b.effects[PBEffects::Unburden] = true - @battle.pbHideAbilitySplash(b) - pbHeldItemTriggerCheck - break - end - end - - # item_to_use is an item ID or GameData::Item object. own_item is whether the - # item is held by self. fling is for Fling only. - def pbHeldItemTriggered(item_to_use, own_item = true, fling = false) - # Cheek Pouch - if hasActiveAbility?(:CHEEKPOUCH) && GameData::Item.get(item_to_use).is_berry? && canHeal? - @battle.pbShowAbilitySplash(self) - pbRecoverHP(@totalhp / 3) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - @battle.pbDisplay(_INTL("{1}'s HP was restored.", pbThis)) - else - @battle.pbDisplay(_INTL("{1}'s {2} restored its HP.", pbThis, abilityName)) - end - @battle.pbHideAbilitySplash(self) - end - pbConsumeItem if own_item - pbSymbiosis if !own_item && !fling # Bug Bite/Pluck users trigger Symbiosis - end - - #============================================================================= - # Held item trigger checks - #============================================================================= - # NOTE: A Pokémon using Bug Bite/Pluck, and a Pokémon having an item thrown at - # it via Fling, will gain the effect of the item even if the Pokémon is - # affected by item-negating effects. - # item_to_use is an item ID for Bug Bite/Pluck and Fling, and nil otherwise. - # fling is for Fling only. - def pbHeldItemTriggerCheck(item_to_use = nil, fling = false) - return if fainted? - return if !item_to_use && !itemActive? - pbItemHPHealCheck(item_to_use, fling) - pbItemStatusCureCheck(item_to_use, fling) - pbItemEndOfMoveCheck(item_to_use, fling) - # For Enigma Berry, Kee Berry and Maranga Berry, which have their effects - # when forcibly consumed by Pluck/Fling. - if item_to_use - itm = item_to_use || self.item - if BattleHandlers.triggerTargetItemOnHitPositiveBerry(itm, self, @battle, true) - pbHeldItemTriggered(itm, false, fling) - end - end - end - - # item_to_use is an item ID for Bug Bite/Pluck and Fling, and nil otherwise. - # fling is for Fling only. - def pbItemHPHealCheck(item_to_use = nil, fling = false) - return if !item_to_use && !itemActive? - itm = item_to_use || self.item - if BattleHandlers.triggerHPHealItem(itm, self, @battle, !item_to_use.nil?) - pbHeldItemTriggered(itm, item_to_use.nil?, fling) - elsif !item_to_use - pbItemTerrainStatBoostCheck - end - end - - # Cures status conditions, confusion, infatuation and the other effects cured - # by Mental Herb. - # item_to_use is an item ID for Bug Bite/Pluck and Fling, and nil otherwise. - # fling is for Fling only. - def pbItemStatusCureCheck(item_to_use = nil, fling = false) - return if fainted? - return if !item_to_use && !itemActive? - itm = item_to_use || self.item - if BattleHandlers.triggerStatusCureItem(itm, self, @battle, !item_to_use.nil?) - pbHeldItemTriggered(itm, item_to_use.nil?, fling) - end - end - - # Called at the end of using a move. - # item_to_use is an item ID for Bug Bite/Pluck and Fling, and nil otherwise. - # fling is for Fling only. - def pbItemEndOfMoveCheck(item_to_use = nil, fling = false) - return if fainted? - return if !item_to_use && !itemActive? - itm = item_to_use || self.item - if BattleHandlers.triggerEndOfMoveItem(itm, self, @battle, !item_to_use.nil?) - pbHeldItemTriggered(itm, item_to_use.nil?, fling) - elsif BattleHandlers.triggerEndOfMoveStatRestoreItem(itm, self, @battle, !item_to_use.nil?) - pbHeldItemTriggered(itm, item_to_use.nil?, fling) - end - end - - # Used for White Herb (restore lowered stats). Only called by Moody and Sticky - # Web, as all other stat reduction happens because of/during move usage and - # this handler is also called at the end of each move's usage. - # item_to_use is an item ID for Bug Bite/Pluck and Fling, and nil otherwise. - # fling is for Fling only. - def pbItemStatRestoreCheck(item_to_use = nil, fling = false) - return if fainted? - return if !item_to_use && !itemActive? - itm = item_to_use || self.item - if BattleHandlers.triggerEndOfMoveStatRestoreItem(itm, self, @battle, !item_to_use.nil?) - pbHeldItemTriggered(itm, item_to_use.nil?, fling) - end - end - - # Called when the battle terrain changes and when a Pokémon loses HP. - def pbItemTerrainStatBoostCheck - return if !itemActive? - if BattleHandlers.triggerTerrainStatBoostItem(self.item, self, @battle) - pbHeldItemTriggered(self.item) - end - end - - # Used for Adrenaline Orb. Called when Intimidate is triggered (even if - # Intimidate has no effect on the Pokémon). - def pbItemOnIntimidatedCheck - return if !itemActive? - if BattleHandlers.triggerItemOnIntimidated(self.item, self, @battle) - pbHeldItemTriggered(self.item) - end - end -end diff --git a/Data/Scripts/011_Battle/001_Battler/007_Battler_UseMove.rb b/Data/Scripts/011_Battle/001_Battler/007_Battler_UseMove.rb deleted file mode 100644 index 9b5b44903..000000000 --- a/Data/Scripts/011_Battle/001_Battler/007_Battler_UseMove.rb +++ /dev/null @@ -1,809 +0,0 @@ -class PokeBattle_Battler - #============================================================================= - # Turn processing - #============================================================================= - def pbProcessTurn(choice, tryFlee = true) - return false if fainted? - # Wild roaming Pokémon always flee if possible - if tryFlee && @battle.wildBattle? && opposes? && - @battle.rules["alwaysflee"] && @battle.pbCanRun?(@index) - pbBeginTurn(choice) - pbSEPlay("Battle flee") - @battle.pbDisplay(_INTL("{1} fled from battle!", pbThis)) - @battle.decision = 3 - pbEndTurn(choice) - return true - end - # Shift with the battler next to this one - if choice[0] == :Shift - idxOther = -1 - case @battle.pbSideSize(@index) - when 2 - idxOther = (@index + 2) % 4 - when 3 - if @index != 2 && @index != 3 # If not in middle spot already - idxOther = ((@index % 2) == 0) ? 2 : 3 - end - end - if idxOther >= 0 - @battle.pbSwapBattlers(@index, idxOther) - case @battle.pbSideSize(@index) - when 2 - @battle.pbDisplay(_INTL("{1} moved across!", pbThis)) - when 3 - @battle.pbDisplay(_INTL("{1} moved to the center!", pbThis)) - end - end - pbBeginTurn(choice) - pbCancelMoves - @lastRoundMoved = @battle.turnCount # Done something this round - return true - end - # If this battler's action for this round wasn't "use a move" - if choice[0] != :UseMove - # Clean up effects that end at battler's turn - pbBeginTurn(choice) - pbEndTurn(choice) - return false - end - # Turn is skipped if Pursuit was used during switch - if @effects[PBEffects::Pursuit] - @effects[PBEffects::Pursuit] = false - pbCancelMoves - pbEndTurn(choice) - @battle.pbJudge - return false - end - # Use the move - PBDebug.log("[Move usage] #{pbThis} started using #{choice[2].name}") - PBDebug.logonerr { - pbUseMove(choice, choice[2] == @battle.struggle) - } - @battle.pbJudge - # Update priority order - @battle.pbCalculatePriority if Settings::RECALCULATE_TURN_ORDER_AFTER_SPEED_CHANGES - return true - end - - #============================================================================= - # - #============================================================================= - def pbBeginTurn(_choice) - # Cancel some lingering effects which only apply until the user next moves - @effects[PBEffects::BeakBlast] = false - @effects[PBEffects::DestinyBondPrevious] = @effects[PBEffects::DestinyBond] - @effects[PBEffects::DestinyBond] = false - @effects[PBEffects::Grudge] = false - @effects[PBEffects::MoveNext] = false - @effects[PBEffects::Quash] = 0 - # Encore's effect ends if the encored move is no longer available - if @effects[PBEffects::Encore] > 0 && pbEncoredMoveIndex < 0 - @effects[PBEffects::Encore] = 0 - @effects[PBEffects::EncoreMove] = nil - end - end - - # Called when the usage of various multi-turn moves is disrupted due to - # failing pbTryUseMove, being ineffective against all targets, or because - # Pursuit was used specially to intercept a switching foe. - # Cancels the use of multi-turn moves and counters thereof. Note that Hyper - # Beam's effect is NOT cancelled. - def pbCancelMoves(full_cancel = false) - # Outragers get confused anyway if they are disrupted during their final - # turn of using the move - if @effects[PBEffects::Outrage] == 1 && pbCanConfuseSelf?(false) && !full_cancel - pbConfuse(_INTL("{1} became confused due to fatigue!", pbThis)) - end - # Cancel usage of most multi-turn moves - @effects[PBEffects::TwoTurnAttack] = nil - @effects[PBEffects::Rollout] = 0 - @effects[PBEffects::Outrage] = 0 - @effects[PBEffects::Uproar] = 0 - @effects[PBEffects::Bide] = 0 - @currentMove = nil - # Reset counters for moves which increase them when used in succession - @effects[PBEffects::FuryCutter] = 0 - end - - def pbEndTurn(_choice) - @lastRoundMoved = @battle.turnCount # Done something this round - if !@effects[PBEffects::ChoiceBand] && - hasActiveItem?([:CHOICEBAND, :CHOICESPECS, :CHOICESCARF]) - if @lastMoveUsed && pbHasMove?(@lastMoveUsed) - @effects[PBEffects::ChoiceBand] = @lastMoveUsed - elsif @lastRegularMoveUsed && pbHasMove?(@lastRegularMoveUsed) - @effects[PBEffects::ChoiceBand] = @lastRegularMoveUsed - end - end - @effects[PBEffects::BeakBlast] = false - @effects[PBEffects::Charge] = 0 if @effects[PBEffects::Charge] == 1 - @effects[PBEffects::GemConsumed] = nil - @effects[PBEffects::ShellTrap] = false - @battle.eachBattler { |b| b.pbContinualAbilityChecks } # Trace, end primordial weathers - end - - def pbConfusionDamage(msg) - @damageState.reset - @damageState.initialHP = @hp - confusionMove = PokeBattle_Confusion.new(@battle, nil) - confusionMove.calcType = confusionMove.pbCalcType(self) # nil - @damageState.typeMod = confusionMove.pbCalcTypeMod(confusionMove.calcType, self, self) # 8 - confusionMove.pbCheckDamageAbsorption(self, self) - confusionMove.pbCalcDamage(self, self) - confusionMove.pbReduceDamage(self, self) - self.hp -= @damageState.hpLost - confusionMove.pbAnimateHitAndHPLost(self, [self]) - @battle.pbDisplay(msg) # "It hurt itself in its confusion!" - confusionMove.pbRecordDamageLost(self, self) - confusionMove.pbEndureKOMessage(self) - pbFaint if fainted? - pbItemHPHealCheck - end - - #============================================================================= - # Simple "use move" method, used when a move calls another move and for Future - # Sight's attack - #============================================================================= - def pbUseMoveSimple(moveID, target = -1, idxMove = -1, specialUsage = true) - choice = [] - choice[0] = :UseMove # "Use move" - choice[1] = idxMove # Index of move to be used in user's moveset - if idxMove >= 0 - choice[2] = @moves[idxMove] - else - choice[2] = PokeBattle_Move.from_pokemon_move(@battle, Pokemon::Move.new(moveID)) - choice[2].pp = -1 - end - choice[3] = target # Target (-1 means no target yet) - PBDebug.log("[Move usage] #{pbThis} started using the called/simple move #{choice[2].name}") - pbUseMove(choice, specialUsage) - end - - #============================================================================= - # Master "use move" method - #============================================================================= - def pbUseMove(choice, specialUsage = false) - # NOTE: This is intentionally determined before a multi-turn attack can - # set specialUsage to true. - skipAccuracyCheck = (specialUsage && choice[2] != @battle.struggle) - # Start using the move - pbBeginTurn(choice) - # Force the use of certain moves if they're already being used - if usingMultiTurnAttack? - choice[2] = PokeBattle_Move.from_pokemon_move(@battle, Pokemon::Move.new(@currentMove)) - specialUsage = true - elsif @effects[PBEffects::Encore] > 0 && choice[1] >= 0 && - @battle.pbCanShowCommands?(@index) - idxEncoredMove = pbEncoredMoveIndex - if idxEncoredMove >= 0 && @battle.pbCanChooseMove?(@index, idxEncoredMove, false) - if choice[1] != idxEncoredMove # Change move if battler was Encored mid-round - choice[1] = idxEncoredMove - choice[2] = @moves[idxEncoredMove] - choice[3] = -1 # No target chosen - end - end - end - # Labels the move being used as "move" - move = choice[2] - return if !move # if move was not chosen somehow - # Try to use the move (inc. disobedience) - @lastMoveFailed = false - if !pbTryUseMove(choice, move, specialUsage, skipAccuracyCheck) - @lastMoveUsed = nil - @lastMoveUsedType = nil - if !specialUsage - @lastRegularMoveUsed = nil - @lastRegularMoveTarget = -1 - end - @battle.pbGainExp # In case self is KO'd due to confusion - pbCancelMoves - pbEndTurn(choice) - return - end - move = choice[2] # In case disobedience changed the move to be used - return if !move # if move was not chosen somehow - # Subtract PP - if !specialUsage - if !pbReducePP(move) - @battle.pbDisplay(_INTL("{1} used {2}!", pbThis, move.name)) - @battle.pbDisplay(_INTL("But there was no PP left for the move!")) - @lastMoveUsed = nil - @lastMoveUsedType = nil - @lastRegularMoveUsed = nil - @lastRegularMoveTarget = -1 - @lastMoveFailed = true - pbCancelMoves - pbEndTurn(choice) - return - end - end - # Stance Change - if self.ability == :STANCECHANGE - if move.damagingMove? - user = pbFindUser(choice, move) - stanceChangeEffect(user, true) - elsif move.id == :KINGSSHIELD - user = pbFindUser(choice, move) - stanceChangeEffect(user, false) - end - end - # Calculate the move's type during this usage - move.calcType = move.pbCalcType(self) - # Start effect of Mold Breaker - @battle.moldBreaker = hasMoldBreaker? - # Remember that user chose a two-turn move - if move.pbIsChargingTurn?(self) - # Beginning the use of a two-turn attack - @effects[PBEffects::TwoTurnAttack] = move.id - @currentMove = move.id - else - @effects[PBEffects::TwoTurnAttack] = nil # Cancel use of two-turn attack - end - # Add to counters for moves which increase them when used in succession - move.pbChangeUsageCounters(self, specialUsage) - # Charge up Metronome item - if hasActiveItem?(:METRONOME) && !move.callsAnotherMove? - if @lastMoveUsed && @lastMoveUsed == move.id && !@lastMoveFailed - @effects[PBEffects::Metronome] += 1 - else - @effects[PBEffects::Metronome] = 0 - end - end - # Record move as having been used - @lastMoveUsed = move.id - @lastMoveUsedType = move.calcType # For Conversion 2 - if !specialUsage - @lastRegularMoveUsed = move.id # For Disable, Encore, Instruct, Mimic, Mirror Move, Sketch, Spite - @lastRegularMoveTarget = choice[3] # For Instruct (remembering original target is fine) - @movesUsed.push(move.id) if !@movesUsed.include?(move.id) # For Last Resort - end - @battle.lastMoveUsed = move.id # For Copycat - @battle.lastMoveUser = @index # For "self KO" battle clause to avoid draws - @battle.successStates[@index].useState = 1 # Battle Arena - assume failure - # Find the default user (self or Snatcher) and target(s) - user = pbFindUser(choice, move) - user = pbChangeUser(choice, move, user) - targets = pbFindTargets(choice, move, user) - targets = pbChangeTargets(move, user, targets) - # Pressure - if !specialUsage - targets.each do |b| - next unless b.opposes?(user) && b.hasActiveAbility?(:PRESSURE) - PBDebug.log("[Ability triggered] #{b.pbThis}'s #{b.abilityName}") - user.pbReducePP(move) - end - if move.pbTarget(user).affects_foe_side - @battle.eachOtherSideBattler(user) do |b| - next unless b.hasActiveAbility?(:PRESSURE) - PBDebug.log("[Ability triggered] #{b.pbThis}'s #{b.abilityName}") - user.pbReducePP(move) - end - end - end - # Dazzling/Queenly Majesty make the move fail here - @battle.pbPriority(true).each do |b| - next if !b || !b.abilityActive? - if BattleHandlers.triggerMoveBlockingAbility(b.ability, b, user, targets, move, @battle) - @battle.pbDisplayBrief(_INTL("{1} used {2}!", user.pbThis, move.name)) - @battle.pbShowAbilitySplash(b) - @battle.pbDisplay(_INTL("{1} cannot use {2}!", user.pbThis, move.name)) - @battle.pbHideAbilitySplash(b) - user.lastMoveFailed = true - pbCancelMoves - pbEndTurn(choice) - return - end - end - # "X used Y!" message - # Can be different for Bide, Fling, Focus Punch and Future Sight - # NOTE: This intentionally passes self rather than user. The user is always - # self except if Snatched, but this message should state the original - # user (self) even if the move is Snatched. - move.pbDisplayUseMessage(self) - # Snatch's message (user is the new user, self is the original user) - if move.snatched - @lastMoveFailed = true # Intentionally applies to self, not user - @battle.pbDisplay(_INTL("{1} snatched {2}'s move!", user.pbThis, pbThis(true))) - end - # "But it failed!" checks - if move.pbMoveFailed?(user, targets) - PBDebug.log(sprintf("[Move failed] In function code %s's def pbMoveFailed?", move.function)) - user.lastMoveFailed = true - pbCancelMoves - pbEndTurn(choice) - return - end - # Perform set-up actions and display messages - # Messages include Magnitude's number and Pledge moves' "it's a combo!" - move.pbOnStartUse(user, targets) - # Self-thawing due to the move - if user.status == :FROZEN && move.thawsUser? - user.pbCureStatus(false) - @battle.pbDisplay(_INTL("{1} melted the ice!", user.pbThis)) - end - # Powder - if user.effects[PBEffects::Powder] && move.calcType == :FIRE - @battle.pbCommonAnimation("Powder", user) - @battle.pbDisplay(_INTL("When the flame touched the powder on the Pokémon, it exploded!")) - user.lastMoveFailed = true - if ![:Rain, :HeavyRain].include?(@battle.pbWeather) && user.takesIndirectDamage? - oldHP = user.hp - user.pbReduceHP((user.totalhp / 4.0).round, false) - user.pbFaint if user.fainted? - @battle.pbGainExp # In case user is KO'd by this - user.pbItemHPHealCheck - if user.pbAbilitiesOnDamageTaken(oldHP) - user.pbEffectsOnSwitchIn(true) - end - end - pbCancelMoves - pbEndTurn(choice) - return - end - # Primordial Sea, Desolate Land - if move.damagingMove? - case @battle.pbWeather - when :HeavyRain - if move.calcType == :FIRE - @battle.pbDisplay(_INTL("The Fire-type attack fizzled out in the heavy rain!")) - user.lastMoveFailed = true - pbCancelMoves - pbEndTurn(choice) - return - end - when :HarshSun - if move.calcType == :WATER - @battle.pbDisplay(_INTL("The Water-type attack evaporated in the harsh sunlight!")) - user.lastMoveFailed = true - pbCancelMoves - pbEndTurn(choice) - return - end - end - end - # Protean - if user.hasActiveAbility?(:PROTEAN) && !move.callsAnotherMove? && !move.snatched - if user.pbHasOtherType?(move.calcType) && !GameData::Type.get(move.calcType).pseudo_type - @battle.pbShowAbilitySplash(user) - user.pbChangeTypes(move.calcType) - typeName = GameData::Type.get(move.calcType).name - @battle.pbDisplay(_INTL("{1} transformed into the {2} type!", user.pbThis, typeName)) - @battle.pbHideAbilitySplash(user) - # NOTE: The GF games say that if Curse is used by a non-Ghost-type - # Pokémon which becomes Ghost-type because of Protean, it should - # target and curse itself. I think this is silly, so I'm making it - # choose a random opponent to curse instead. - if move.function == "10D" && targets.length == 0 # Curse - choice[3] = -1 - targets = pbFindTargets(choice, move, user) - end - end - end - #--------------------------------------------------------------------------- - magicCoater = -1 - magicBouncer = -1 - if targets.length == 0 && move.pbTarget(user).num_targets > 0 && !move.worksWithNoTargets? - # def pbFindTargets should have found a target(s), but it didn't because - # they were all fainted - # All target types except: None, User, UserSide, FoeSide, BothSides - @battle.pbDisplay(_INTL("But there was no target...")) - user.lastMoveFailed = true - else - # We have targets, or move doesn't use targets - # Reset whole damage state, perform various success checks (not accuracy) - user.initialHP = user.hp - targets.each do |b| - b.damageState.reset - b.damageState.initialHP = b.hp - if !pbSuccessCheckAgainstTarget(move, user, b) - b.damageState.unaffected = true - end - end - # Magic Coat/Magic Bounce checks (for moves which don't target Pokémon) - if targets.length == 0 && move.canMagicCoat? - @battle.pbPriority(true).each do |b| - next if b.fainted? || !b.opposes?(user) - next if b.semiInvulnerable? - if b.effects[PBEffects::MagicCoat] - magicCoater = b.index - b.effects[PBEffects::MagicCoat] = false - break - elsif b.hasActiveAbility?(:MAGICBOUNCE) && !@battle.moldBreaker && - !b.effects[PBEffects::MagicBounce] - magicBouncer = b.index - b.effects[PBEffects::MagicBounce] = true - break - end - end - end - # Get the number of hits - numHits = move.pbNumHits(user, targets) - # Process each hit in turn - realNumHits = 0 - for i in 0...numHits - break if magicCoater >= 0 || magicBouncer >= 0 - success = pbProcessMoveHit(move, user, targets, i, skipAccuracyCheck) - if !success - if i == 0 && targets.length > 0 - hasFailed = false - targets.each do |t| - next if t.damageState.protected - hasFailed = t.damageState.unaffected - break if !t.damageState.unaffected - end - user.lastMoveFailed = hasFailed - end - break - end - realNumHits += 1 - break if user.fainted? - break if [:SLEEP, :FROZEN].include?(user.status) - # NOTE: If a multi-hit move becomes disabled partway through doing those - # hits (e.g. by Cursed Body), the rest of the hits continue as - # normal. - break if !targets.any? { |t| !t.fainted? } # All targets are fainted - end - # Battle Arena only - attack is successful - @battle.successStates[user.index].useState = 2 - if targets.length > 0 - @battle.successStates[user.index].typeMod = 0 - targets.each do |b| - next if b.damageState.unaffected - @battle.successStates[user.index].typeMod += b.damageState.typeMod - end - end - # Effectiveness message for multi-hit moves - # NOTE: No move is both multi-hit and multi-target, and the messages below - # aren't quite right for such a hypothetical move. - if numHits > 1 - if move.damagingMove? - targets.each do |b| - next if b.damageState.unaffected || b.damageState.substitute - move.pbEffectivenessMessage(user, b, targets.length) - end - end - if realNumHits == 1 - @battle.pbDisplay(_INTL("Hit 1 time!")) - elsif realNumHits > 1 - @battle.pbDisplay(_INTL("Hit {1} times!", realNumHits)) - end - end - # Magic Coat's bouncing back (move has targets) - targets.each do |b| - next if b.fainted? - next if !b.damageState.magicCoat && !b.damageState.magicBounce - @battle.pbShowAbilitySplash(b) if b.damageState.magicBounce - @battle.pbDisplay(_INTL("{1} bounced the {2} back!", b.pbThis, move.name)) - @battle.pbHideAbilitySplash(b) if b.damageState.magicBounce - newChoice = choice.clone - newChoice[3] = user.index - newTargets = pbFindTargets(newChoice, move, b) - newTargets = pbChangeTargets(move, b, newTargets) - success = pbProcessMoveHit(move, b, newTargets, 0, false) - b.lastMoveFailed = true if !success - targets.each { |otherB| otherB.pbFaint if otherB && otherB.fainted? } - user.pbFaint if user.fainted? - end - # Magic Coat's bouncing back (move has no targets) - if magicCoater >= 0 || magicBouncer >= 0 - mc = @battle.battlers[(magicCoater >= 0) ? magicCoater : magicBouncer] - if !mc.fainted? - user.lastMoveFailed = true - @battle.pbShowAbilitySplash(mc) if magicBouncer >= 0 - @battle.pbDisplay(_INTL("{1} bounced the {2} back!", mc.pbThis, move.name)) - @battle.pbHideAbilitySplash(mc) if magicBouncer >= 0 - success = pbProcessMoveHit(move, mc, [], 0, false) - mc.lastMoveFailed = true if !success - targets.each { |b| b.pbFaint if b && b.fainted? } - user.pbFaint if user.fainted? - end - end - # Move-specific effects after all hits - targets.each { |b| move.pbEffectAfterAllHits(user, b) } - # Faint if 0 HP - targets.each { |b| b.pbFaint if b && b.fainted? } - user.pbFaint if user.fainted? - # External/general effects after all hits. Eject Button, Shell Bell, etc. - pbEffectsAfterMove(user, targets, move, realNumHits) - end - # End effect of Mold Breaker - @battle.moldBreaker = false - # Gain Exp - @battle.pbGainExp - # Battle Arena only - update skills - @battle.eachBattler { |b| @battle.successStates[b.index].updateSkill } - # Shadow Pokémon triggering Hyper Mode - pbHyperMode if @battle.choices[@index][0] != :None # Not if self is replaced - # End of move usage - pbEndTurn(choice) - # Instruct - @battle.eachBattler do |b| - next if !b.effects[PBEffects::Instruct] || !b.lastMoveUsed - b.effects[PBEffects::Instruct] = false - idxMove = -1 - b.eachMoveWithIndex { |m, i| idxMove = i if m.id == b.lastMoveUsed } - next if idxMove < 0 - oldLastRoundMoved = b.lastRoundMoved - @battle.pbDisplay(_INTL("{1} used the move instructed by {2}!", b.pbThis, user.pbThis(true))) - PBDebug.logonerr { - b.effects[PBEffects::Instructed] = true - b.pbUseMoveSimple(b.lastMoveUsed, b.lastRegularMoveTarget, idxMove, false) - b.effects[PBEffects::Instructed] = false - } - b.lastRoundMoved = oldLastRoundMoved - @battle.pbJudge - return if @battle.decision > 0 - end - # Dancer - if !@effects[PBEffects::Dancer] && !user.lastMoveFailed && realNumHits > 0 && - !move.snatched && magicCoater < 0 && @battle.pbCheckGlobalAbility(:DANCER) && - move.danceMove? - dancers = [] - @battle.pbPriority(true).each do |b| - dancers.push(b) if b.index != user.index && b.hasActiveAbility?(:DANCER) - end - while dancers.length > 0 - nextUser = dancers.pop - oldLastRoundMoved = nextUser.lastRoundMoved - # NOTE: Petal Dance being used because of Dancer shouldn't lock the - # Dancer into using that move, and shouldn't contribute to its - # turn counter if it's already locked into Petal Dance. - oldOutrage = nextUser.effects[PBEffects::Outrage] - nextUser.effects[PBEffects::Outrage] += 1 if nextUser.effects[PBEffects::Outrage] > 0 - oldCurrentMove = nextUser.currentMove - preTarget = choice[3] - preTarget = user.index if nextUser.opposes?(user) || !nextUser.opposes?(preTarget) - @battle.pbShowAbilitySplash(nextUser, true) - @battle.pbHideAbilitySplash(nextUser) - if !PokeBattle_SceneConstants::USE_ABILITY_SPLASH - @battle.pbDisplay(_INTL("{1} kept the dance going with {2}!", - nextUser.pbThis, nextUser.abilityName)) - end - PBDebug.logonerr { - nextUser.effects[PBEffects::Dancer] = true - nextUser.pbUseMoveSimple(move.id, preTarget) - nextUser.effects[PBEffects::Dancer] = false - } - nextUser.lastRoundMoved = oldLastRoundMoved - nextUser.effects[PBEffects::Outrage] = oldOutrage - nextUser.currentMove = oldCurrentMove - @battle.pbJudge - return if @battle.decision > 0 - end - end - end - - def stanceChangeEffect(user, attacking = false) - inSwordForm = user.effects[PBEffects::PowerTrick] - if !inSwordForm && attacking - user.effects[PBEffects::PowerTrick] = true - user.attack, user.defense = user.defense, user.attack - user.spatk, user.spdef = user.spdef, user.spatk - - - #changeForm(1,:AEGISLASH) - - @battle.pbDisplay(_INTL("{1} changed to Sword Mode!", pbThis)) - elsif inSwordForm && !attacking - user.effects[PBEffects::PowerTrick] = false - user.attack, user.defense = user.defense, user.attack - user.spatk, user.spdef = user.spdef, user.spatk - - #user.changeForm(nil,:AEGISLASH) - - @battle.pbDisplay(_INTL("{1} changed to Shield Mode!", pbThis)) - end - end - - def ensure_form_has_sprite(pokemon) - GameData::Species.sprite_filename(pokemon.dexNum) - end - - - def playChangeFormAnimation(animation = "UltraBurst2") - @battle.scene.pbChangePokemon(self, @pokemon) - @battle.scene.pbCommonAnimation(animation, self) - @battle.scene.pbRefreshOne(@index) - end - - def changeSpecies(pokemon, speciesToReplace,newSpecies, animation = "UltraBurst2") - if pokemon.isFusion?() - replaceFusionSpecies(pokemon,speciesToReplace,newSpecies) - else - changeSpeciesSpecific(pokemon,newSpecies) - end - playChangeFormAnimation(animation) - end - - - - # def changeUnfusedSpecies(pokemon, newSpecies, animation = "UltraBurst2") - # - # end - - #For meloetta form change - - def changeFormSpecies(oldForm, newForm,animation = "UltraBurst2") - @pokemon.changeFormSpecies(oldForm,newForm) - playChangeFormAnimation(animation) - end - - - def changeForm(newForm, formChangingSpecies, animation = "UltraBurst2") - spriteform_body = newForm if @pokemon.hasBodyOf?(formChangingSpecies) - spriteform_head = newForm if @pokemon.hasHeadOf?(formChangingSpecies) - - #ensure_form_has_sprite(@pokemon) - - if self.isFusion? - current_form_has_custom = customSpriteExistsSpecies(@pokemon.species) - new_form_has_custom = customSpriteExistsForm(@pokemon.species, spriteform_head, spriteform_body) - should_change_sprite = (current_form_has_custom && new_form_has_custom) || !current_form_has_custom - else - should_change_sprite=true - end - - if should_change_sprite - @pokemon.spriteform_body = spriteform_body - @pokemon.spriteform_head = spriteform_head - end - playChangeFormAnimation(animation) - end - - #============================================================================= - # Attack a single target - #============================================================================= - def pbProcessMoveHit(move, user, targets, hitNum, skipAccuracyCheck) - return false if user.fainted? - # For two-turn attacks being used in a single turn - move.pbInitialEffect(user, targets, hitNum) - numTargets = 0 # Number of targets that are affected by this hit - targets.each { |b| b.damageState.resetPerHit } - # Count a hit for Parental Bond (if it applies) - user.effects[PBEffects::ParentalBond] -= 1 if user.effects[PBEffects::ParentalBond] > 0 - # Accuracy check (accuracy/evasion calc) - if hitNum == 0 || move.successCheckPerHit? - targets.each do |b| - next if b.damageState.unaffected - if pbSuccessCheckPerHit(move, user, b, skipAccuracyCheck) - numTargets += 1 - else - b.damageState.missed = true - b.damageState.unaffected = true - end - end - # If failed against all targets - if targets.length > 0 && numTargets == 0 && !move.worksWithNoTargets? - targets.each do |b| - next if !b.damageState.missed || b.damageState.magicCoat - pbMissMessage(move, user, b) - end - move.pbCrashDamage(user) - user.pbItemHPHealCheck - pbCancelMoves - return false - end - end - # If we get here, this hit will happen and do something - #--------------------------------------------------------------------------- - # Calculate damage to deal - if move.pbDamagingMove? - targets.each do |b| - next if b.damageState.unaffected - # Check whether Substitute/Disguise will absorb the damage - move.pbCheckDamageAbsorption(user, b) - # Calculate the damage against b - # pbCalcDamage shows the "eat berry" animation for SE-weakening - # berries, although the message about it comes after the additional - # effect below - move.pbCalcDamage(user, b, targets.length) # Stored in damageState.calcDamage - # Lessen damage dealt because of False Swipe/Endure/etc. - move.pbReduceDamage(user, b) # Stored in damageState.hpLost - end - end - # Show move animation (for this hit) - move.pbShowAnimation(move.id, user, targets, hitNum) - # Type-boosting Gem consume animation/message - if user.effects[PBEffects::GemConsumed] && hitNum == 0 - # NOTE: The consume animation and message for Gems are shown now, but the - # actual removal of the item happens in def pbEffectsAfterMove. - @battle.pbCommonAnimation("UseItem", user) - @battle.pbDisplay(_INTL("The {1} strengthened {2}'s power!", - GameData::Item.get(user.effects[PBEffects::GemConsumed]).name, move.name)) - end - # Messages about missed target(s) (relevant for multi-target moves only) - targets.each do |b| - next if !b.damageState.missed - pbMissMessage(move, user, b) - end - # Deal the damage (to all allies first simultaneously, then all foes - # simultaneously) - if move.pbDamagingMove? - # This just changes the HP amounts and does nothing else - targets.each do |b| - next if b.damageState.unaffected - move.pbInflictHPDamage(b) - end - # Animate the hit flashing and HP bar changes - move.pbAnimateHitAndHPLost(user, targets) - end - # Self-Destruct/Explosion's damaging and fainting of user - move.pbSelfKO(user) if hitNum == 0 - user.pbFaint if user.fainted? - if move.pbDamagingMove? - targets.each do |b| - next if b.damageState.unaffected - # NOTE: This method is also used for the OKHO special message. - move.pbHitEffectivenessMessages(user, b, targets.length) - # Record data about the hit for various effects' purposes - move.pbRecordDamageLost(user, b) - end - # Close Combat/Superpower's stat-lowering, Flame Burst's splash damage, - # and Incinerate's berry destruction - targets.each do |b| - next if b.damageState.unaffected - move.pbEffectWhenDealingDamage(user, b) - end - # Ability/item effects such as Static/Rocky Helmet, and Grudge, etc. - targets.each do |b| - next if b.damageState.unaffected - pbEffectsOnMakingHit(move, user, b) - end - # Disguise/Endure/Sturdy/Focus Sash/Focus Band messages - targets.each do |b| - next if b.damageState.unaffected - move.pbEndureKOMessage(b) - end - # HP-healing held items (checks all battlers rather than just targets - # because Flame Burst's splash damage affects non-targets) - @battle.pbPriority(true).each { |b| b.pbItemHPHealCheck } - # Animate battlers fainting (checks all battlers rather than just targets - # because Flame Burst's splash damage affects non-targets) - @battle.pbPriority(true).each { |b| b.pbFaint if b && b.fainted? } - end - @battle.pbJudgeCheckpoint(user, move) - # Main effect (recoil/drain, etc.) - targets.each do |b| - next if b.damageState.unaffected - move.pbEffectAgainstTarget(user, b) - end - move.pbEffectGeneral(user) - targets.each { |b| b.pbFaint if b && b.fainted? } - user.pbFaint if user.fainted? - # Additional effect - if !user.hasActiveAbility?(:SHEERFORCE) - targets.each do |b| - next if b.damageState.calcDamage == 0 - chance = move.pbAdditionalEffectChance(user, b) - next if chance <= 0 - if @battle.pbRandom(100) < chance - move.pbAdditionalEffect(user, b) - end - end - end - # Make the target flinch (because of an item/ability) - targets.each do |b| - next if b.fainted? - next if b.damageState.calcDamage == 0 || b.damageState.substitute - chance = move.pbFlinchChance(user, b) - next if chance <= 0 - if @battle.pbRandom(100) < chance - PBDebug.log("[Item/ability triggered] #{user.pbThis}'s King's Rock/Razor Fang or Stench") - b.pbFlinch(user) - end - end - # Message for and consuming of type-weakening berries - # NOTE: The "consume held item" animation for type-weakening berries occurs - # during pbCalcDamage above (before the move's animation), but the - # message about it only shows here. - targets.each do |b| - next if b.damageState.unaffected - next if !b.damageState.berryWeakened - @battle.pbDisplay(_INTL("The {1} weakened the damage to {2}!", b.itemName, b.pbThis(true))) - b.pbConsumeItem - end - targets.each { |b| b.pbFaint if b && b.fainted? } - user.pbFaint if user.fainted? - return true - end -end diff --git a/Data/Scripts/011_Battle/001_Battler/008_Battler_UseMove_Targeting.rb b/Data/Scripts/011_Battle/001_Battler/008_Battler_UseMove_Targeting.rb deleted file mode 100644 index c3cd1a6df..000000000 --- a/Data/Scripts/011_Battle/001_Battler/008_Battler_UseMove_Targeting.rb +++ /dev/null @@ -1,193 +0,0 @@ -class PokeBattle_Battler - #============================================================================= - # Get move's user - #============================================================================= - def pbFindUser(_choice,_move) - return self - end - - def pbChangeUser(choice,move,user) - # Snatch - move.snatched = false - if move.canSnatch? - newUser = nil; strength = 100 - @battle.eachBattler do |b| - next if b.effects[PBEffects::Snatch]==0 || - b.effects[PBEffects::Snatch]>=strength - next if b.effects[PBEffects::SkyDrop]>=0 - newUser = b - strength = b.effects[PBEffects::Snatch] - end - if newUser - user = newUser - user.effects[PBEffects::Snatch] = 0 - move.snatched = true - @battle.moldBreaker = user.hasMoldBreaker? - choice[3] = -1 # Clear pre-chosen target - end - end - return user - end - - #============================================================================= - # Get move's default target(s) - #============================================================================= - def pbFindTargets(choice,move,user) - preTarget = choice[3] # A target that was already chosen - targets = [] - # Get list of targets - case move.pbTarget(user).id # Curse can change its target type - when :NearAlly - targetBattler = (preTarget>=0) ? @battle.battlers[preTarget] : nil - if !pbAddTarget(targets,user,targetBattler,move) - pbAddTargetRandomAlly(targets,user,move) - end - when :UserOrNearAlly - targetBattler = (preTarget>=0) ? @battle.battlers[preTarget] : nil - if !pbAddTarget(targets,user,targetBattler,move,true,true) - pbAddTarget(targets,user,user,move,true,true) - end - when :UserAndAllies - pbAddTarget(targets,user,user,move,true,true) - @battle.eachSameSideBattler(user.index) { |b| pbAddTarget(targets,user,b,move,false,true) } - when :NearFoe, :NearOther - targetBattler = (preTarget>=0) ? @battle.battlers[preTarget] : nil - if !pbAddTarget(targets,user,targetBattler,move) - if preTarget>=0 && !user.opposes?(preTarget) - pbAddTargetRandomAlly(targets,user,move) - else - pbAddTargetRandomFoe(targets,user,move) - end - end - when :RandomNearFoe - pbAddTargetRandomFoe(targets,user,move) - when :AllNearFoes - @battle.eachOtherSideBattler(user.index) { |b| pbAddTarget(targets,user,b,move) } - when :Foe, :Other - targetBattler = (preTarget>=0) ? @battle.battlers[preTarget] : nil - if !pbAddTarget(targets,user,targetBattler,move,false) - if preTarget>=0 && !user.opposes?(preTarget) - pbAddTargetRandomAlly(targets,user,move,false) - else - pbAddTargetRandomFoe(targets,user,move,false) - end - end - when :AllFoes - @battle.eachOtherSideBattler(user.index) { |b| pbAddTarget(targets,user,b,move,false) } - when :AllNearOthers - @battle.eachBattler { |b| pbAddTarget(targets,user,b,move) } - when :AllBattlers - @battle.eachBattler { |b| pbAddTarget(targets,user,b,move,false,true) } - else - # Used by Counter/Mirror Coat/Metal Burst/Bide - move.pbAddTarget(targets,user) # Move-specific pbAddTarget, not the def below - end - return targets - end - - #============================================================================= - # Redirect attack to another target - #============================================================================= - def pbChangeTargets(move,user,targets) - target_data = move.pbTarget(user) - return targets if @battle.switching # For Pursuit interrupting a switch - return targets if move.cannotRedirect? - return targets if !target_data.can_target_one_foe? || targets.length != 1 - priority = @battle.pbPriority(true) - nearOnly = !target_data.can_choose_distant_target? - # Spotlight (takes priority over Follow Me/Rage Powder/Lightning Rod/Storm Drain) - newTarget = nil; strength = 100 # Lower strength takes priority - priority.each do |b| - next if b.fainted? || b.effects[PBEffects::SkyDrop]>=0 - next if b.effects[PBEffects::Spotlight]==0 || - b.effects[PBEffects::Spotlight]>=strength - next if !b.opposes?(user) - next if nearOnly && !b.near?(user) - newTarget = b - strength = b.effects[PBEffects::Spotlight] - end - if newTarget - PBDebug.log("[Move target changed] #{newTarget.pbThis}'s Spotlight made it the target") - targets = [] - pbAddTarget(targets,user,newTarget,move,nearOnly) - return targets - end - # Follow Me/Rage Powder (takes priority over Lightning Rod/Storm Drain) - newTarget = nil; strength = 100 # Lower strength takes priority - priority.each do |b| - next if b.fainted? || b.effects[PBEffects::SkyDrop]>=0 - next if b.effects[PBEffects::RagePowder] && !user.affectedByPowder? - next if b.effects[PBEffects::FollowMe]==0 || - b.effects[PBEffects::FollowMe]>=strength - next if !b.opposes?(user) - next if nearOnly && !b.near?(user) - newTarget = b - strength = b.effects[PBEffects::FollowMe] - end - if newTarget - PBDebug.log("[Move target changed] #{newTarget.pbThis}'s Follow Me/Rage Powder made it the target") - targets = [] - pbAddTarget(targets,user,newTarget,move,nearOnly) - return targets - end - # Lightning Rod - targets = pbChangeTargetByAbility(:LIGHTNINGROD,:ELECTRIC,move,user,targets,priority,nearOnly) - # Storm Drain - targets = pbChangeTargetByAbility(:STORMDRAIN,:WATER,move,user,targets,priority,nearOnly) - return targets - end - - def pbChangeTargetByAbility(drawingAbility,drawnType,move,user,targets,priority,nearOnly) - return targets if move.calcType != drawnType - return targets if targets[0].hasActiveAbility?(drawingAbility) - priority.each do |b| - next if b.index==user.index || b.index==targets[0].index - next if !b.hasActiveAbility?(drawingAbility) - next if nearOnly && !b.near?(user) - @battle.pbShowAbilitySplash(b) - targets.clear - pbAddTarget(targets,user,b,move,nearOnly) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - @battle.pbDisplay(_INTL("{1} took the attack!",b.pbThis)) - else - @battle.pbDisplay(_INTL("{1} took the attack with its {2}!",b.pbThis,b.abilityName)) - end - @battle.pbHideAbilitySplash(b) - break - end - return targets - end - - #============================================================================= - # Register target - #============================================================================= - def pbAddTarget(targets,user,target,move,nearOnly=true,allowUser=false) - return false if !target || (target.fainted? && !move.cannotRedirect?) - return false if !(allowUser && user==target) && nearOnly && !user.near?(target) - targets.each { |b| return true if b.index==target.index } # Already added - targets.push(target) - return true - end - - def pbAddTargetRandomAlly(targets,user,_move,nearOnly=true) - choices = [] - user.eachAlly do |b| - next if nearOnly && !user.near?(b) - pbAddTarget(choices,user,b,nearOnly) - end - if choices.length>0 - pbAddTarget(targets,user,choices[@battle.pbRandom(choices.length)],nearOnly) - end - end - - def pbAddTargetRandomFoe(targets,user,_move,nearOnly=true) - choices = [] - user.eachOpposing do |b| - next if nearOnly && !user.near?(b) - pbAddTarget(choices,user,b,nearOnly) - end - if choices.length>0 - pbAddTarget(targets,user,choices[@battle.pbRandom(choices.length)],nearOnly) - end - end -end diff --git a/Data/Scripts/011_Battle/001_Battler/009_Battler_UseMove_SuccessChecks.rb b/Data/Scripts/011_Battle/001_Battler/009_Battler_UseMove_SuccessChecks.rb deleted file mode 100644 index da2eb5fe2..000000000 --- a/Data/Scripts/011_Battle/001_Battler/009_Battler_UseMove_SuccessChecks.rb +++ /dev/null @@ -1,541 +0,0 @@ -class PokeBattle_Battler - #============================================================================= - # Decide whether the trainer is allowed to tell the Pokémon to use the given - # move. Called when choosing a command for the round. - # Also called when processing the Pokémon's action, because these effects also - # prevent Pokémon action. Relevant because these effects can become active - # earlier in the same round (after choosing the command but before using the - # move) or an unusable move may be called by another move such as Metronome. - #============================================================================= - def pbCanChooseMove?(move,commandPhase,showMessages=true,specialUsage=false) - # Disable - if @effects[PBEffects::DisableMove]==move.id && !specialUsage - if showMessages - msg = _INTL("{1}'s {2} is disabled!",pbThis,move.name) - (commandPhase) ? @battle.pbDisplayPaused(msg) : @battle.pbDisplay(msg) - end - return false - end - # Heal Block - if @effects[PBEffects::HealBlock]>0 && move.healingMove? - if showMessages - msg = _INTL("{1} can't use {2} because of Heal Block!",pbThis,move.name) - (commandPhase) ? @battle.pbDisplayPaused(msg) : @battle.pbDisplay(msg) - end - return false - end - # Gravity - if @battle.field.effects[PBEffects::Gravity]>0 && move.unusableInGravity? - if showMessages - msg = _INTL("{1} can't use {2} because of gravity!",pbThis,move.name) - (commandPhase) ? @battle.pbDisplayPaused(msg) : @battle.pbDisplay(msg) - end - return false - end - # Throat Chop - if @effects[PBEffects::ThroatChop]>0 && move.soundMove? - if showMessages - msg = _INTL("{1} can't use {2} because of Throat Chop!",pbThis,move.name) - (commandPhase) ? @battle.pbDisplayPaused(msg) : @battle.pbDisplay(msg) - end - return false - end - # Choice Band - if @effects[PBEffects::ChoiceBand] - if hasActiveItem?([:CHOICEBAND,:CHOICESPECS,:CHOICESCARF]) && - pbHasMove?(@effects[PBEffects::ChoiceBand]) - if move.id!=@effects[PBEffects::ChoiceBand] - if showMessages - msg = _INTL("{1} allows the use of only {2}!",itemName, - GameData::Move.get(@effects[PBEffects::ChoiceBand]).name) - (commandPhase) ? @battle.pbDisplayPaused(msg) : @battle.pbDisplay(msg) - end - return false - end - else - @effects[PBEffects::ChoiceBand] = nil - end - end - # Taunt - if @effects[PBEffects::Taunt]>0 && move.statusMove? - if showMessages - msg = _INTL("{1} can't use {2} after the taunt!",pbThis,move.name) - (commandPhase) ? @battle.pbDisplayPaused(msg) : @battle.pbDisplay(msg) - end - return false - end - # Torment - if @effects[PBEffects::Torment] && !@effects[PBEffects::Instructed] && - @lastMoveUsed && move.id==@lastMoveUsed && move.id!=@battle.struggle.id - if showMessages - msg = _INTL("{1} can't use the same move twice in a row due to the torment!",pbThis) - (commandPhase) ? @battle.pbDisplayPaused(msg) : @battle.pbDisplay(msg) - end - return false - end - # Imprison - @battle.eachOtherSideBattler(@index) do |b| - next if !b.effects[PBEffects::Imprison] || !b.pbHasMove?(move.id) - if showMessages - msg = _INTL("{1} can't use its sealed {2}!",pbThis,move.name) - (commandPhase) ? @battle.pbDisplayPaused(msg) : @battle.pbDisplay(msg) - end - return false - end - # Assault Vest (prevents choosing status moves but doesn't prevent - # executing them) - if hasActiveItem?(:ASSAULTVEST) && move.statusMove? && commandPhase - if showMessages - msg = _INTL("The effects of the {1} prevent status moves from being used!", - itemName) - (commandPhase) ? @battle.pbDisplayPaused(msg) : @battle.pbDisplay(msg) - end - return false - end - # Belch - return false if !move.pbCanChooseMove?(self,commandPhase,showMessages) - return true - end - - #============================================================================= - # Obedience check - #============================================================================= - # Return true if Pokémon continues attacking (although it may have chosen to - # use a different move in disobedience), or false if attack stops. - def pbObedienceCheck?(choice) - return true if usingMultiTurnAttack? - return true if choice[0]!=:UseMove - return true if !@battle.internalBattle - return true if !@battle.pbOwnedByPlayer?(@index) - disobedient = false - # Pokémon may be disobedient; calculate if it is - badgeLevel = 10 * (@battle.pbPlayer.badge_count + 1) - badgeLevel = GameData::GrowthRate.max_level if @battle.pbPlayer.badge_count >= 8 - if (@pokemon.foreign?(@battle.pbPlayer) && @level>badgeLevel) || @pokemon.force_disobey - a = ((@level+badgeLevel)*@battle.pbRandom(256)/256).floor - disobedient |= (a>=badgeLevel) - end - disobedient |= !pbHyperModeObedience(choice[2]) - return true if !disobedient - # Pokémon is disobedient; make it do something else - return pbDisobey(choice,badgeLevel) - end - - def pbDisobey(choice,badgeLevel) - move = choice[2] - PBDebug.log("[Disobedience] #{pbThis} disobeyed") - @effects[PBEffects::Rage] = false - # Do nothing if using Snore/Sleep Talk - if @status == :SLEEP && move.usableWhenAsleep? - @battle.pbDisplay(_INTL("{1} ignored orders and kept sleeping!",pbThis)) - return false - end - b = ((@level+badgeLevel)*@battle.pbRandom(256)/256).floor - # Use another move - if b=0 # Intentionally no message here - PBDebug.log("[Move failed] #{pbThis} can't use #{move.name} because of being Sky Dropped") - return false - end - if @effects[PBEffects::HyperBeam]>0 # Intentionally before Truant - @battle.pbDisplay(_INTL("{1} must recharge!",pbThis)) - return false - end - if choice[1]==-2 # Battle Palace - @battle.pbDisplay(_INTL("{1} appears incapable of using its power!",pbThis)) - return false - end - # Skip checking all applied effects that could make self fail doing something - return true if skipAccuracyCheck - # Check status problems and continue their effects/cure them - case @status - when :SLEEP - self.statusCount -= 1 - if @statusCount<=0 - pbCureStatus - else - pbContinueStatus - if !move.usableWhenAsleep? # Snore/Sleep Talk - @lastMoveFailed = true - return false - end - end - when :FROZEN - if !move.thawsUser? - if @battle.pbRandom(100)<20 - pbCureStatus - else - pbContinueStatus - @lastMoveFailed = true - return false - end - end - end - # Obedience check - return false if !pbObedienceCheck?(choice) - # Truant - if hasActiveAbility?(:TRUANT) - @effects[PBEffects::Truant] = !@effects[PBEffects::Truant] - if !@effects[PBEffects::Truant] # True means loafing, but was just inverted - @battle.pbShowAbilitySplash(self) - @battle.pbDisplay(_INTL("{1} is loafing around!",pbThis)) - @lastMoveFailed = true - @battle.pbHideAbilitySplash(self) - return false - end - end - # Flinching - if @effects[PBEffects::Flinch] - @battle.pbDisplay(_INTL("{1} flinched and couldn't move!",pbThis)) - if abilityActive? - BattleHandlers.triggerAbilityOnFlinch(self.ability,self,@battle) - end - @lastMoveFailed = true - return false - end - # Confusion - if @effects[PBEffects::Confusion]>0 - @effects[PBEffects::Confusion] -= 1 - if @effects[PBEffects::Confusion]<=0 - pbCureConfusion - @battle.pbDisplay(_INTL("{1} snapped out of its confusion.",pbThis)) - else - @battle.pbCommonAnimation("Confusion",self) - @battle.pbDisplay(_INTL("{1} is confused!",pbThis)) - threshold = (Settings::MECHANICS_GENERATION >= 7) ? 33 : 50 # % chance - if @battle.pbRandom(100)=0 - @battle.pbCommonAnimation("Attract",self) - @battle.pbDisplay(_INTL("{1} is in love with {2}!",pbThis, - @battle.battlers[@effects[PBEffects::Attract]].pbThis(true))) - if @battle.pbRandom(100)<50 - @battle.pbDisplay(_INTL("{1} is immobilized by love!",pbThis)) - @lastMoveFailed = true - return false - end - end - return true - end - - #============================================================================= - # Initial success check against the target. Done once before the first hit. - # Includes move-specific failure conditions, protections and type immunities. - #============================================================================= - def pbSuccessCheckAgainstTarget(move,user,target) - typeMod = move.pbCalcTypeMod(move.calcType,user,target) - target.damageState.typeMod = typeMod - # Two-turn attacks can't fail here in the charging turn - return true if user.effects[PBEffects::TwoTurnAttack] - # Move-specific failures - return false if move.pbFailsAgainstTarget?(user,target) - # Immunity to priority moves because of Psychic Terrain - if @battle.field.terrain == :Psychic && target.affectedByTerrain? && target.opposes?(user) && - @battle.choices[user.index][4]>0 # Move priority saved from pbCalculatePriority - @battle.pbDisplay(_INTL("{1} surrounds itself with psychic terrain!",target.pbThis)) - return false - end - # Crafty Shield - if target.pbOwnSide.effects[PBEffects::CraftyShield] && user.index!=target.index && - move.statusMove? && !move.pbTarget(user).targets_all - @battle.pbCommonAnimation("CraftyShield",target) - @battle.pbDisplay(_INTL("Crafty Shield protected {1}!",target.pbThis(true))) - target.damageState.protected = true - @battle.successStates[user.index].protected = true - return false - end - # Wide Guard - if target.pbOwnSide.effects[PBEffects::WideGuard] && user.index!=target.index && - move.pbTarget(user).num_targets > 1 && - (Settings::MECHANICS_GENERATION >= 7 || move.damagingMove?) - @battle.pbCommonAnimation("WideGuard",target) - @battle.pbDisplay(_INTL("Wide Guard protected {1}!",target.pbThis(true))) - target.damageState.protected = true - @battle.successStates[user.index].protected = true - return false - end - if move.canProtectAgainst? - # Quick Guard - if target.pbOwnSide.effects[PBEffects::QuickGuard] && - @battle.choices[user.index][4]>0 # Move priority saved from pbCalculatePriority - @battle.pbCommonAnimation("QuickGuard",target) - @battle.pbDisplay(_INTL("Quick Guard protected {1}!",target.pbThis(true))) - target.damageState.protected = true - @battle.successStates[user.index].protected = true - return false - end - # Protect - if target.effects[PBEffects::Protect] - @battle.pbCommonAnimation("Protect",target) - @battle.pbDisplay(_INTL("{1} protected itself!",target.pbThis)) - target.damageState.protected = true - @battle.successStates[user.index].protected = true - return false - end - # King's Shield - if target.effects[PBEffects::KingsShield] && move.damagingMove? - @battle.pbCommonAnimation("KingsShield",target) - @battle.pbDisplay(_INTL("{1} protected itself!",target.pbThis)) - target.damageState.protected = true - @battle.successStates[user.index].protected = true - if move.pbContactMove?(user) && user.affectedByContactEffect? - if user.pbCanLowerStatStage?(:ATTACK) - user.pbLowerStatStage(:ATTACK,2,nil) - end - end - return false - end - # Spiky Shield - if target.effects[PBEffects::SpikyShield] - @battle.pbCommonAnimation("SpikyShield",target) - @battle.pbDisplay(_INTL("{1} protected itself!",target.pbThis)) - target.damageState.protected = true - @battle.successStates[user.index].protected = true - if move.pbContactMove?(user) && user.affectedByContactEffect? - @battle.scene.pbDamageAnimation(user) - user.pbReduceHP(user.totalhp/8,false) - @battle.pbDisplay(_INTL("{1} was hurt!",user.pbThis)) - user.pbItemHPHealCheck - end - return false - end - # Baneful Bunker - if target.effects[PBEffects::BanefulBunker] - @battle.pbCommonAnimation("BanefulBunker",target) - @battle.pbDisplay(_INTL("{1} protected itself!",target.pbThis)) - target.damageState.protected = true - @battle.successStates[user.index].protected = true - if move.pbContactMove?(user) && user.affectedByContactEffect? - user.pbPoison(target) if user.pbCanPoison?(target,false) - end - return false - end - # Mat Block - if target.pbOwnSide.effects[PBEffects::MatBlock] && move.damagingMove? - # NOTE: Confirmed no common animation for this effect. - @battle.pbDisplay(_INTL("{1} was blocked by the kicked-up mat!",move.name)) - target.damageState.protected = true - @battle.successStates[user.index].protected = true - return false - end - end - # Magic Coat/Magic Bounce - if move.canMagicCoat? && !target.semiInvulnerable? && target.opposes?(user) - if target.effects[PBEffects::MagicCoat] - target.damageState.magicCoat = true - target.effects[PBEffects::MagicCoat] = false - return false - end - if target.hasActiveAbility?(:MAGICBOUNCE) && !@battle.moldBreaker && - !target.effects[PBEffects::MagicBounce] - target.damageState.magicBounce = true - target.effects[PBEffects::MagicBounce] = true - return false - end - end - # Immunity because of ability (intentionally before type immunity check) - return false if move.pbImmunityByAbility(user,target) - # Type immunity - if move.pbDamagingMove? && Effectiveness.ineffective?(typeMod) - PBDebug.log("[Target immune] #{target.pbThis}'s type immunity") - @battle.pbDisplay(_INTL("It doesn't affect {1}...",target.pbThis(true))) - return false - end - # Dark-type immunity to moves made faster by Prankster - if Settings::MECHANICS_GENERATION >= 7 && user.effects[PBEffects::Prankster] && - target.pbHasType?(:DARK) && target.opposes?(user) - PBDebug.log("[Target immune] #{target.pbThis} is Dark-type and immune to Prankster-boosted moves") - @battle.pbDisplay(_INTL("It doesn't affect {1}...",target.pbThis(true))) - return false - end - # Airborne-based immunity to Ground moves - if move.damagingMove? && move.calcType == :GROUND && - target.airborne? && !move.hitsFlyingTargets? - if target.hasActiveAbility?(:LEVITATE) && !@battle.moldBreaker - @battle.pbShowAbilitySplash(target) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - @battle.pbDisplay(_INTL("{1} avoided the attack!",target.pbThis)) - else - @battle.pbDisplay(_INTL("{1} avoided the attack with {2}!",target.pbThis,target.abilityName)) - end - @battle.pbHideAbilitySplash(target) - return false - end - if target.hasActiveItem?(:AIRBALLOON) - @battle.pbDisplay(_INTL("{1}'s {2} makes Ground moves miss!",target.pbThis,target.itemName)) - return false - end - if target.effects[PBEffects::MagnetRise]>0 - @battle.pbDisplay(_INTL("{1} makes Ground moves miss with Magnet Rise!",target.pbThis)) - return false - end - if target.effects[PBEffects::Telekinesis]>0 - @battle.pbDisplay(_INTL("{1} makes Ground moves miss with Telekinesis!",target.pbThis)) - return false - end - end - # Immunity to powder-based moves - if move.powderMove? - if target.pbHasType?(:GRASS) && Settings::MORE_TYPE_EFFECTS - PBDebug.log("[Target immune] #{target.pbThis} is Grass-type and immune to powder-based moves") - @battle.pbDisplay(_INTL("It doesn't affect {1}...",target.pbThis(true))) - return false - end - if Settings::MECHANICS_GENERATION >= 6 - if target.hasActiveAbility?(:OVERCOAT) && !@battle.moldBreaker - @battle.pbShowAbilitySplash(target) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - @battle.pbDisplay(_INTL("It doesn't affect {1}...",target.pbThis(true))) - else - @battle.pbDisplay(_INTL("It doesn't affect {1} because of its {2}.",target.pbThis(true),target.abilityName)) - end - @battle.pbHideAbilitySplash(target) - return false - end - if target.hasActiveItem?(:SAFETYGOGGLES) - PBDebug.log("[Item triggered] #{target.pbThis} has Safety Goggles and is immune to powder-based moves") - @battle.pbDisplay(_INTL("It doesn't affect {1}...",target.pbThis(true))) - return false - end - end - end - # Substitute - if target.effects[PBEffects::Substitute]>0 && move.statusMove? && - !move.ignoresSubstitute?(user) && user.index!=target.index - PBDebug.log("[Target immune] #{target.pbThis} is protected by its Substitute") - @battle.pbDisplay(_INTL("{1} avoided the attack!",target.pbThis(true))) - return false - end - return true - end - - #============================================================================= - # Per-hit success check against the target. - # Includes semi-invulnerable move use and accuracy calculation. - #============================================================================= - def pbSuccessCheckPerHit(move,user,target,skipAccuracyCheck) - # Two-turn attacks can't fail here in the charging turn - return true if user.effects[PBEffects::TwoTurnAttack] - # Lock-On - return true if user.effects[PBEffects::LockOn]>0 && - user.effects[PBEffects::LockOnPos]==target.index - # Toxic - return true if move.pbOverrideSuccessCheckPerHit(user,target) - miss = false; hitsInvul = false - # No Guard - hitsInvul = true if user.hasActiveAbility?(:NOGUARD) || - target.hasActiveAbility?(:NOGUARD) - # Future Sight - hitsInvul = true if @battle.futureSight - # Helping Hand - hitsInvul = true if move.function=="09C" - if !hitsInvul - # Semi-invulnerable moves - if target.effects[PBEffects::TwoTurnAttack] - if target.inTwoTurnAttack?("0C9","0CC","0CE") # Fly, Bounce, Sky Drop - miss = true if !move.hitsFlyingTargets? - elsif target.inTwoTurnAttack?("0CA") # Dig - miss = true if !move.hitsDiggingTargets? - elsif target.inTwoTurnAttack?("0CB") # Dive - miss = true if !move.hitsDivingTargets? - elsif target.inTwoTurnAttack?("0CD","14D") # Shadow Force, Phantom Force - miss = true - end - end - if target.effects[PBEffects::SkyDrop]>=0 && - target.effects[PBEffects::SkyDrop]!=user.index - miss = true if !move.hitsFlyingTargets? - end - end - if user.hasActiveItem?(:MANKEYPAW) - miss = true if rand(2)==1 - end - if !miss - # Called by another move - return true if skipAccuracyCheck - # Accuracy check - return true if move.pbAccuracyCheck(user,target) # Includes Counter/Mirror Coat - end - # Missed - PBDebug.log("[Move failed] Failed pbAccuracyCheck or target is semi-invulnerable") - return false - end - - #============================================================================= - # Message shown when a move fails the per-hit success check above. - #============================================================================= - def pbMissMessage(move,user,target) - if move.pbTarget(user).num_targets > 1 - @battle.pbDisplay(_INTL("{1} avoided the attack!",target.pbThis)) - elsif target.effects[PBEffects::TwoTurnAttack] - @battle.pbDisplay(_INTL("{1} avoided the attack!",target.pbThis)) - elsif !move.pbMissMessage(user,target) - @battle.pbDisplay(_INTL("{1}'s attack missed!",user.pbThis)) - end - end -end diff --git a/Data/Scripts/011_Battle/001_Battler/010_Battler_UseMove_TriggerEffects.rb b/Data/Scripts/011_Battle/001_Battler/010_Battler_UseMove_TriggerEffects.rb deleted file mode 100644 index dcc21b57c..000000000 --- a/Data/Scripts/011_Battle/001_Battler/010_Battler_UseMove_TriggerEffects.rb +++ /dev/null @@ -1,194 +0,0 @@ -class PokeBattle_Battler - #============================================================================= - # Effect per hit - #============================================================================= - # - - def triggerAbilityEffectsOnHit(move,user,target) - # Target's ability - if target.abilityActive?(true) - oldHP = user.hp - BattleHandlers.triggerTargetAbilityOnHit(target.ability,user,target,move,@battle) - user.pbItemHPHealCheck if user.hp0 && !target.damageState.substitute - triggerAbilityEffectsOnHit(move,user,target) - # Target's item - if target.itemActive?(true) - oldHP = user.hp - BattleHandlers.triggerTargetItemOnHit(target.item,user,target,move,@battle) - user.pbItemHPHealCheck if user.hp0 && !target.damageState.substitute && move.physicalMove? - target.tookPhysicalHit = true - target.effects[PBEffects::MoveNext] = true - target.effects[PBEffects::Quash] = 0 - end - end - # Grudge - if target.effects[PBEffects::Grudge] && target.fainted? - move.pp = 0 - @battle.pbDisplay(_INTL("{1}'s {2} lost all of its PP due to the grudge!", - user.pbThis,move.name)) - end - # Destiny Bond (recording that it should apply) - if target.effects[PBEffects::DestinyBond] && target.fainted? - if user.effects[PBEffects::DestinyBondTarget]<0 - user.effects[PBEffects::DestinyBondTarget] = target.index - end - end - end - end - - #============================================================================= - # Effects after all hits (i.e. at end of move usage) - #============================================================================= - def pbEffectsAfterMove(user,targets,move,numHits) - # Defrost - if move.damagingMove? - targets.each do |b| - next if b.damageState.unaffected || b.damageState.substitute - next if b.status != :FROZEN - # NOTE: Non-Fire-type moves that thaw the user will also thaw the - # target (in Gen 6+). - if move.calcType == :FIRE || (Settings::MECHANICS_GENERATION >= 6 && move.thawsUser?) - b.pbCureStatus - end - end - end - # Destiny Bond - # NOTE: Although Destiny Bond is similar to Grudge, they don't apply at - # the same time (although Destiny Bond does check whether it's going - # to trigger at the same time as Grudge). - if user.effects[PBEffects::DestinyBondTarget]>=0 && !user.fainted? - dbName = @battle.battlers[user.effects[PBEffects::DestinyBondTarget]].pbThis - @battle.pbDisplay(_INTL("{1} took its attacker down with it!",dbName)) - user.pbReduceHP(user.hp,false) - user.pbItemHPHealCheck - user.pbFaint - @battle.pbJudgeCheckpoint(user) - end - # User's ability - if user.abilityActive? - BattleHandlers.triggerUserAbilityEndOfMove(user.ability,user,targets,move,@battle) - BattleHandlers.triggerUserAbilityEndOfMove(user.ability2,user,targets,move,@battle) if user.ability2 - end - # Greninja - Battle Bond - if !user.fainted? && !user.effects[PBEffects::Transform] && - user.isSpecies?(:GRENINJA) && user.ability == :BATTLEBOND - if !@battle.pbAllFainted?(user.idxOpposingSide) && - !@battle.battleBond[user.index&1][user.pokemonIndex] - numFainted = 0 - targets.each { |b| numFainted += 1 if b.damageState.fainted } - if numFainted>0 && user.form==1 - @battle.battleBond[user.index&1][user.pokemonIndex] = true - @battle.pbDisplay(_INTL("{1} became fully charged due to its bond with its Trainer!",user.pbThis)) - @battle.pbShowAbilitySplash(user,true) - @battle.pbHideAbilitySplash(user) - user.pbChangeForm(2,_INTL("{1} became Ash-Greninja!",user.pbThis)) - end - end - end - # Consume user's Gem - if user.effects[PBEffects::GemConsumed] - # NOTE: The consume animation and message for Gems are shown immediately - # after the move's animation, but the item is only consumed now. - user.pbConsumeItem - end - # Pokémon switching caused by Roar, Whirlwind, Circle Throw, Dragon Tail - switchedBattlers = [] - move.pbSwitchOutTargetsEffect(user,targets,numHits,switchedBattlers) - # Target's item, user's item, target's ability (all negated by Sheer Force) - if move.addlEffect==0 || !user.hasActiveAbility?(:SHEERFORCE) - pbEffectsAfterMove2(user,targets,move,numHits,switchedBattlers) - end - # Some move effects that need to happen here, i.e. U-turn/Volt Switch - # switching, Baton Pass switching, Parting Shot switching, Relic Song's form - # changing, Fling/Natural Gift consuming item. - if !switchedBattlers.include?(user.index) - move.pbEndOfMoveUsageEffect(user,targets,numHits,switchedBattlers) - end - if numHits>0 - @battle.eachBattler { |b| b.pbItemEndOfMoveCheck } - end - end - - # Everything in this method is negated by Sheer Force. - def pbEffectsAfterMove2(user,targets,move,numHits,switchedBattlers) - hpNow = user.hp # Intentionally determined now, before Shell Bell - # Target's held item (Eject Button, Red Card) - switchByItem = [] - @battle.pbPriority(true).each do |b| - next if !targets.any? { |targetB| targetB.index==b.index } - next if b.damageState.unaffected || b.damageState.calcDamage==0 || - switchedBattlers.include?(b.index) - next if !b.itemActive? - BattleHandlers.triggerTargetItemAfterMoveUse(b.item,b,user,move,switchByItem,@battle) - end - @battle.moldBreaker = false if switchByItem.include?(user.index) - @battle.pbPriority(true).each do |b| - b.pbEffectsOnSwitchIn(true) if switchByItem.include?(b.index) - end - switchByItem.each { |idxB| switchedBattlers.push(idxB) } - # User's held item (Life Orb, Shell Bell) - if !switchedBattlers.include?(user.index) && user.itemActive? - BattleHandlers.triggerUserItemAfterMoveUse(user.item,user,targets,move,numHits,@battle) - end - # Target's ability (Berserk, Color Change, Emergency Exit, Pickpocket, Wimp Out) - switchWimpOut = [] - @battle.pbPriority(true).each do |b| - next if !targets.any? { |targetB| targetB.index==b.index } - next if b.damageState.unaffected || switchedBattlers.include?(b.index) - next if !b.abilityActive? - BattleHandlers.triggerTargetAbilityAfterMoveUse(b.ability,b,user,move,switchedBattlers,@battle) - BattleHandlers.triggerTargetAbilityAfterMoveUse(b.ability2,b,user,move,switchedBattlers,@battle) if b.ability2 - if !switchedBattlers.include?(b.index) && move.damagingMove? - if b.pbAbilitiesOnDamageTaken(b.damageState.initialHP) # Emergency Exit, Wimp Out - switchWimpOut.push(b.index) - end - end - end - @battle.moldBreaker = false if switchWimpOut.include?(user.index) - @battle.pbPriority(true).each do |b| - next if b.index==user.index - b.pbEffectsOnSwitchIn(true) if switchWimpOut.include?(b.index) - end - switchWimpOut.each { |idxB| switchedBattlers.push(idxB) } - # User's ability (Emergency Exit, Wimp Out) - if !switchedBattlers.include?(user.index) && move.damagingMove? - hpNow = user.hp if user.hp= 7) - itemName = GameData::Item.get(item).name - battle.pbCommonAnimation("EatBerry",battler) if !forced - fraction_to_heal = 8 # Gens 6 and lower - if Settings::MECHANICS_GENERATION == 7; fraction_to_heal = 2 - elsif Settings::MECHANICS_GENERATION >= 8; fraction_to_heal = 3 - end - amt = battler.pbRecoverHP(battler.totalhp / fraction_to_heal) - if amt>0 - if forced - PBDebug.log("[Item triggered] Forced consuming of #{itemName}") - battle.pbDisplay(_INTL("{1}'s HP was restored.",battler.pbThis)) - else - battle.pbDisplay(_INTL("{1} restored its health using its {2}!",battler.pbThis,itemName)) - end - end - flavor_stat = [:ATTACK, :DEFENSE, :SPEED, :SPECIAL_ATTACK, :SPECIAL_DEFENSE][flavor] - battler.nature.stat_changes.each do |change| - next if change[1] > 0 || change[0] != flavor_stat - battle.pbDisplay(confuseMsg) - battler.pbConfuse if battler.pbCanConfuseSelf?(false) - break - end - return true -end - -def pbBattleStatIncreasingBerry(battler,battle,item,forced,stat,increment=1) - return false if !forced && !battler.canConsumePinchBerry? - return false if !battler.pbCanRaiseStatStage?(stat,battler) - itemName = GameData::Item.get(item).name - if forced - PBDebug.log("[Item triggered] Forced consuming of #{itemName}") - return battler.pbRaiseStatStage(stat,increment,battler) - end - battle.pbCommonAnimation("EatBerry",battler) - return battler.pbRaiseStatStageByCause(stat,increment,battler,itemName) -end - -# For abilities that grant immunity to moves of a particular type, and raises -# one of the ability's bearer's stats instead. -def pbBattleMoveImmunityStatAbility(user,target,move,moveType,immuneType,stat,increment,battle) - return false if user.index==target.index - return false if moveType != immuneType - battle.pbShowAbilitySplash(target) - if target.pbCanRaiseStatStage?(stat,target) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - target.pbRaiseStatStage(stat,increment,target) - else - target.pbRaiseStatStageByCause(stat,increment,target,target.abilityName) - end - else - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("It doesn't affect {1}...",target.pbThis(true))) - else - battle.pbDisplay(_INTL("{1}'s {2} made {3} ineffective!", - target.pbThis,target.abilityName,move.name)) - end - end - battle.pbHideAbilitySplash(target) - return true -end - -# For abilities that grant immunity to moves of a particular type, and heals the -# ability's bearer by 1/4 of its total HP instead. -def pbBattleMoveImmunityHealAbility(user,target,move,moveType,immuneType,battle) - return false if user.index==target.index - return false if moveType != immuneType - battle.pbShowAbilitySplash(target) - if target.canHeal? && target.pbRecoverHP(target.totalhp/4)>0 - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("{1}'s HP was restored.",target.pbThis)) - else - battle.pbDisplay(_INTL("{1}'s {2} restored its HP.",target.pbThis,target.abilityName)) - end - else - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("It doesn't affect {1}...",target.pbThis(true))) - else - battle.pbDisplay(_INTL("{1}'s {2} made {3} ineffective!", - target.pbThis,target.abilityName,move.name)) - end - end - battle.pbHideAbilitySplash(target) - return true -end - -def pbBattleGem(user,type,move,mults,moveType) - # Pledge moves never consume Gems - return if move.is_a?(PokeBattle_PledgeMove) - return if moveType != type - user.effects[PBEffects::GemConsumed] = user.item_id - if Settings::MECHANICS_GENERATION >= 6 - mults[:base_damage_multiplier] *= 1.3 - else - mults[:base_damage_multiplier] *= 1.5 - end -end - -def pbBattleTypeWeakingBerry(type,moveType,target,mults) - return if moveType != type - return if Effectiveness.resistant?(target.damageState.typeMod) && moveType != :NORMAL - mults[:final_damage_multiplier] /= 2 - target.damageState.berryWeakened = true - target.battle.pbCommonAnimation("EatBerry",target) -end - -def pbBattleWeatherAbility(weather,battler,battle,ignorePrimal=false) - return if !ignorePrimal && [:HarshSun, :HeavyRain, :StrongWinds].include?(battle.field.weather) - return if battle.field.weather==weather - battle.pbShowAbilitySplash(battler) - if !PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("{1}'s {2} activated!",battler.pbThis,battler.abilityName)) - end - fixedDuration = false - fixedDuration = true if Settings::FIXED_DURATION_WEATHER_FROM_ABILITY && - ![:HarshSun, :HeavyRain, :StrongWinds].include?(weather) - battle.pbStartWeather(battler,weather,fixedDuration) - # NOTE: The ability splash is hidden again in def pbStartWeather. -end diff --git a/Data/Scripts/011_Battle/002_Move/001_PokeBattle_Move.rb b/Data/Scripts/011_Battle/002_Move/001_PokeBattle_Move.rb deleted file mode 100644 index 964c48e06..000000000 --- a/Data/Scripts/011_Battle/002_Move/001_PokeBattle_Move.rb +++ /dev/null @@ -1,141 +0,0 @@ -class PokeBattle_Move - attr_reader :battle - attr_reader :realMove - attr_accessor :id - attr_reader :name - attr_reader :function - attr_reader :baseDamage - attr_reader :type - attr_reader :category - attr_reader :accuracy - attr_accessor :pp - attr_writer :total_pp - attr_reader :addlEffect - attr_reader :target - attr_reader :priority - attr_reader :flags - attr_accessor :calcType - attr_accessor :powerBoost - attr_accessor :snatched - - def to_int; return @id; end - - #============================================================================= - # Creating a move - #============================================================================= - def initialize(battle, move) - @battle = battle - @realMove = move - @id = move.id - @name = move.name # Get the move's name - # Get data on the move - @function = move.function_code - @baseDamage = move.base_damage - @type = move.type - @category = move.category - @accuracy = move.accuracy - @pp = move.pp # Can be changed with Mimic/Transform - @addlEffect = move.effect_chance - @target = move.target - @priority = move.priority - @flags = move.flags - @calcType = nil - @powerBoost = false # For Aerilate, Pixilate, Refrigerate, Galvanize - @snatched = false - end - - # This is the code actually used to generate a PokeBattle_Move object. The - # object generated is a subclass of this one which depends on the move's - # function code (found in the script section PokeBattle_MoveEffect). - def PokeBattle_Move.from_pokemon_move(battle, move) - validate move => Pokemon::Move - moveFunction = move.function_code || "000" - className = sprintf("PokeBattle_Move_%s", moveFunction) - if Object.const_defined?(className) - return Object.const_get(className).new(battle, move) - end - return PokeBattle_UnimplementedMove.new(battle, move) - end - - #============================================================================= - # About the move - #============================================================================= - def pbTarget(_user); return GameData::Target.get(@target); end - - def total_pp - return @total_pp if @total_pp && @total_pp>0 # Usually undefined - return @realMove.total_pp if @realMove - return 0 - end - - # NOTE: This method is only ever called while using a move (and also by the - # AI), so using @calcType here is acceptable. - def physicalMove?(thisType=nil) - return (@category==0) if Settings::MOVE_CATEGORY_PER_MOVE - thisType ||= @calcType - thisType ||= @type - return true if !thisType - return GameData::Type.get(thisType).physical? - end - - # NOTE: This method is only ever called while using a move (and also by the - # AI), so using @calcType here is acceptable. - def specialMove?(thisType=nil) - return (@category==1) if Settings::MOVE_CATEGORY_PER_MOVE - thisType ||= @calcType - thisType ||= @type - return false if !thisType - return GameData::Type.get(thisType).special? - end - - def damagingMove?; return @category!=2; end - def statusMove?; return @category==2; end - - def usableWhenAsleep?; return false; end - def unusableInGravity?; return false; end - def healingMove?; return false; end - def recoilMove?; return false; end - def flinchingMove?; return false; end - def callsAnotherMove?; return false; end - # Whether the move can/will hit more than once in the same turn (including - # Beat Up which may instead hit just once). Not the same as pbNumHits>1. - def multiHitMove?; return false; end - def chargingTurnMove?; return false; end - def successCheckPerHit?; return false; end - def hitsFlyingTargets?; return false; end - def hitsDiggingTargets?; return false; end - def hitsDivingTargets?; return false; end - def ignoresReflect?; return false; end # For Brick Break - def cannotRedirect?; return false; end # For Future Sight/Doom Desire - def worksWithNoTargets?; return false; end # For Explosion - def damageReducedByBurn?; return true; end # For Facade - def triggersHyperMode?; return false; end - - def contactMove?; return @flags[/a/]; end - def canProtectAgainst?; return @flags[/b/]; end - def canMagicCoat?; return @flags[/c/]; end - def canSnatch?; return @flags[/d/]; end - def canMirrorMove?; return @flags[/e/]; end - def canKingsRock?; return @flags[/f/]; end - def thawsUser?; return @flags[/g/]; end - def highCriticalRate?; return @flags[/h/]; end - def bitingMove?; return @flags[/i/]; end - def punchingMove?; return @flags[/j/]; end - def soundMove?; return @flags[/k/]; end - def powderMove?; return @flags[/l/]; end - def pulseMove?; return @flags[/m/]; end - def bombMove?; return @flags[/n/]; end - def danceMove?; return @flags[/o/]; end - - # Causes perfect accuracy (param=1) and double damage (param=2). - def tramplesMinimize?(_param=1); return false; end - def nonLethal?(_user,_target); return false; end # For False Swipe - - def ignoresSubstitute?(user) # user is the Pokémon using this move - if Settings::MECHANICS_GENERATION >= 6 - return true if soundMove? - return true if user && user.hasActiveAbility?(:INFILTRATOR) - end - return false - end -end diff --git a/Data/Scripts/011_Battle/002_Move/002_Move_Usage.rb b/Data/Scripts/011_Battle/002_Move/002_Move_Usage.rb deleted file mode 100644 index 3891acda5..000000000 --- a/Data/Scripts/011_Battle/002_Move/002_Move_Usage.rb +++ /dev/null @@ -1,350 +0,0 @@ -class PokeBattle_Move - #============================================================================= - # Effect methods per move usage - #============================================================================= - def pbCanChooseMove?(user,commandPhase,showMessages); return true; end # For Belch - def pbDisplayChargeMessage(user); end # For Focus Punch/shell Trap/Beak Blast - def pbOnStartUse(user,targets); end - def pbAddTarget(targets,user); end # For Counter, etc. and Bide - - # Reset move usage counters (child classes can increment them). - def pbChangeUsageCounters(user,specialUsage) - user.effects[PBEffects::FuryCutter] = 0 - user.effects[PBEffects::ParentalBond] = 0 - user.effects[PBEffects::ProtectRate] = 1 - @battle.field.effects[PBEffects::FusionBolt] = false - @battle.field.effects[PBEffects::FusionFlare] = false - end - - def pbDisplayUseMessage(user) - @battle.pbDisplayBrief(_INTL("{1} used {2}!",user.pbThis,@name)) - end - - def pbMissMessage(user,target); return false; end - - #============================================================================= - # - #============================================================================= - # Whether the move is currently in the "charging" turn of a two turn attack. - # Is false if Power Herb or another effect lets a two turn move charge and - # attack in the same turn. - # user.effects[PBEffects::TwoTurnAttack] is set to the move's ID during the - # charging turn, and is nil during the attack turn. - def pbIsChargingTurn?(user); return false; end - def pbDamagingMove?; return damagingMove?; end - - def pbContactMove?(user) - return false if user.hasActiveAbility?(:LONGREACH) - return contactMove? - end - - # The maximum number of hits in a round this move will actually perform. This - # can be 1 for Beat Up, and can be 2 for any moves affected by Parental Bond. - def pbNumHits(user,targets) - if user.hasActiveAbility?(:PARENTALBOND) && pbDamagingMove? && - !chargingTurnMove? && targets.length==1 - # Record that Parental Bond applies, to weaken the second attack - user.effects[PBEffects::ParentalBond] = 3 - return 2 - end - return 1 - end - - #============================================================================= - # Effect methods per hit - #============================================================================= - def pbOverrideSuccessCheckPerHit(user,target); return false; end - def pbCrashDamage(user); end - def pbInitialEffect(user,targets,hitNum); end - - def pbShowAnimation(id,user,targets,hitNum=0,showAnimation=true) - return if !showAnimation - if user.effects[PBEffects::ParentalBond]==1 - @battle.pbCommonAnimation("ParentalBond",user,targets) - else - @battle.pbAnimation(id,user,targets,hitNum) - end - end - - def pbSelfKO(user); end - def pbEffectWhenDealingDamage(user,target); end - def pbEffectAgainstTarget(user,target); end - def pbEffectGeneral(user); end - def pbAdditionalEffect(user,target); end - def pbEffectAfterAllHits(user,target); end # Move effects that occur after all hits - def pbSwitchOutTargetsEffect(user,targets,numHits,switchedBattlers); end - def pbEndOfMoveUsageEffect(user,targets,numHits,switchedBattlers); end - - #============================================================================= - # Check if target is immune to the move because of its ability - #============================================================================= - def pbImmunityByAbility(user,target) - return false if @battle.moldBreaker - ret = false - if target.abilityActive? - ret = BattleHandlers.triggerMoveImmunityTargetAbility(target.ability, - user,target,self,@calcType,@battle) - end - return ret - end - - #============================================================================= - # Move failure checks - #============================================================================= - # Check whether the move fails completely due to move-specific requirements. - def pbMoveFailed?(user,targets); return false; end - # Checks whether the move will be ineffective against the target. - def pbFailsAgainstTarget?(user,target); return false; end - - def pbMoveFailedLastInRound?(user) - unmoved = false - @battle.eachBattler do |b| - next if b.index==user.index - next if @battle.choices[b.index][0]!=:UseMove && @battle.choices[b.index][0]!=:Shift - next if b.movedThisRound? - unmoved = true - break - end - if !unmoved - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbMoveFailedTargetAlreadyMoved?(target) - if (@battle.choices[target.index][0]!=:UseMove && - @battle.choices[target.index][0]!=:Shift) || target.movedThisRound? - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbMoveFailedAromaVeil?(user,target,showMessage=true) - return false if @battle.moldBreaker - if target.hasActiveAbility?(:AROMAVEIL) - if showMessage - @battle.pbShowAbilitySplash(target) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - @battle.pbDisplay(_INTL("{1} is unaffected!",target.pbThis)) - else - @battle.pbDisplay(_INTL("{1} is unaffected because of its {2}!", - target.pbThis,target.abilityName)) - end - @battle.pbHideAbilitySplash(target) - end - return true - end - target.eachAlly do |b| - next if !b.hasActiveAbility?(:AROMAVEIL) - if showMessage - @battle.pbShowAbilitySplash(target) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - @battle.pbDisplay(_INTL("{1} is unaffected!",target.pbThis)) - else - @battle.pbDisplay(_INTL("{1} is unaffected because of {2}'s {3}!", - target.pbThis,b.pbThis(true),b.abilityName)) - end - @battle.pbHideAbilitySplash(target) - end - return true - end - return false - end - - #============================================================================= - # Weaken the damage dealt (doesn't actually change a battler's HP) - #============================================================================= - def pbCheckDamageAbsorption(user,target) - # Substitute will take the damage - if target.effects[PBEffects::Substitute]>0 && !ignoresSubstitute?(user) && - (!user || user.index!=target.index) - target.damageState.substitute = true - return - end - # Disguise will take the damage - if !@battle.moldBreaker && target.isFusionOf(:MIMIKYU) && - target.form==0 && target.ability == :DISGUISE - target.damageState.disguise = true - return - end - end - - def pbReduceDamage(user,target) - damage = target.damageState.calcDamage - # Substitute takes the damage - if target.damageState.substitute - damage = target.effects[PBEffects::Substitute] if damage>target.effects[PBEffects::Substitute] - target.damageState.hpLost = damage - target.damageState.totalHPLost += damage - return - end - # Disguise takes the damage - return if target.damageState.disguise - # Target takes the damage - if damage>=target.hp - damage = target.hp - # Survive a lethal hit with 1 HP effects - if nonLethal?(user,target) - damage -= 1 - elsif target.effects[PBEffects::Endure] - target.damageState.endured = true - damage -= 1 - elsif damage==target.totalhp - if target.hasActiveAbility?(:STURDY) && !@battle.moldBreaker - target.damageState.sturdy = true - damage -= 1 - elsif target.hasActiveItem?(:FOCUSSASH) && target.hp==target.totalhp - target.damageState.focusSash = true - damage -= 1 - elsif target.hasActiveItem?(:FOCUSBAND) && @battle.pbRandom(100)<10 - target.damageState.focusBand = true - damage -= 1 - end - end - end - damage = 0 if damage<0 - target.damageState.hpLost = damage - target.damageState.totalHPLost += damage - end - - #============================================================================= - # Change the target's HP by the amount calculated above - #============================================================================= - def pbInflictHPDamage(target) - if target.damageState.substitute - target.effects[PBEffects::Substitute] -= target.damageState.hpLost - else - target.hp -= target.damageState.hpLost - end - end - - #============================================================================= - # Animate the damage dealt, including lowering the HP - #============================================================================= - # Animate being damaged and losing HP (by a move) - def pbAnimateHitAndHPLost(user,targets) - # Animate allies first, then foes - animArray = [] - for side in 0...2 # side here means "allies first, then foes" - targets.each do |b| - next if b.damageState.unaffected || b.damageState.hpLost==0 - next if (side==0 && b.opposes?(user)) || (side==1 && !b.opposes?(user)) - oldHP = b.hp+b.damageState.hpLost - PBDebug.log("[Move damage] #{b.pbThis} lost #{b.damageState.hpLost} HP (#{oldHP}=>#{b.hp})") - effectiveness = 0 - if Effectiveness.resistant?(b.damageState.typeMod); effectiveness = 1 - elsif Effectiveness.super_effective?(b.damageState.typeMod); effectiveness = 2 - end - animArray.push([b,oldHP,effectiveness]) - end - if animArray.length>0 - @battle.scene.pbHitAndHPLossAnimation(animArray) - animArray.clear - end - end - end - - #============================================================================= - # Messages upon being hit - #============================================================================= - def pbEffectivenessMessage(user,target,numTargets=1) - return if target.damageState.disguise - if Effectiveness.super_effective?(target.damageState.typeMod) - if numTargets>1 - @battle.pbDisplay(_INTL("It's super effective on {1}!",target.pbThis(true))) - else - @battle.pbDisplay(_INTL("It's super effective!")) - end - elsif Effectiveness.not_very_effective?(target.damageState.typeMod) - if numTargets>1 - @battle.pbDisplay(_INTL("It's not very effective on {1}...",target.pbThis(true))) - else - @battle.pbDisplay(_INTL("It's not very effective...")) - end - end - end - - def pbHitEffectivenessMessages(user,target,numTargets=1) - return if target.damageState.disguise - if target.damageState.substitute - @battle.pbDisplay(_INTL("The substitute took damage for {1}!",target.pbThis(true))) - end - if target.damageState.critical - if numTargets>1 - @battle.pbDisplay(_INTL("A critical hit on {1}!",target.pbThis(true))) - else - @battle.pbDisplay(_INTL("A critical hit!")) - end - end - # Effectiveness message, for moves with 1 hit - if !multiHitMove? && user.effects[PBEffects::ParentalBond]==0 - pbEffectivenessMessage(user,target,numTargets) - end - if target.damageState.substitute && target.effects[PBEffects::Substitute]==0 - target.effects[PBEffects::Substitute] = 0 - @battle.pbDisplay(_INTL("{1}'s substitute faded!",target.pbThis)) - end - end - - def pbEndureKOMessage(target) - if target.damageState.disguise - @battle.pbShowAbilitySplash(target) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - @battle.pbDisplay(_INTL("Its disguise served it as a decoy!")) - else - @battle.pbDisplay(_INTL("{1}'s disguise served it as a decoy!",target.pbThis)) - end - @battle.pbHideAbilitySplash(target) - target.pbChangeForm(1,_INTL("{1}'s disguise was busted!",target.pbThis)) - elsif target.damageState.endured - @battle.pbDisplay(_INTL("{1} endured the hit!",target.pbThis)) - elsif target.damageState.sturdy - @battle.pbShowAbilitySplash(target) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - @battle.pbDisplay(_INTL("{1} endured the hit!",target.pbThis)) - else - @battle.pbDisplay(_INTL("{1} hung on with Sturdy!",target.pbThis)) - end - @battle.pbHideAbilitySplash(target) - elsif target.damageState.focusSash - @battle.pbCommonAnimation("UseItem",target) - @battle.pbDisplay(_INTL("{1} hung on using its Focus Sash!",target.pbThis)) - target.pbConsumeItem - elsif target.damageState.focusBand - @battle.pbCommonAnimation("UseItem",target) - @battle.pbDisplay(_INTL("{1} hung on using its Focus Band!",target.pbThis)) - end - end - - # Used by Counter/Mirror Coat/Metal Burst/Revenge/Focus Punch/Bide/Assurance. - def pbRecordDamageLost(user,target) - damage = target.damageState.hpLost - # NOTE: In Gen 3 where a move's category depends on its type, Hidden Power - # is for some reason countered by Counter rather than Mirror Coat, - # regardless of its calculated type. Hence the following two lines of - # code. - moveType = nil - moveType = :NORMAL if @function=="090" # Hidden Power - if physicalMove?(moveType) - target.effects[PBEffects::Counter] = damage - target.effects[PBEffects::CounterTarget] = user.index - elsif specialMove?(moveType) - target.effects[PBEffects::MirrorCoat] = damage - target.effects[PBEffects::MirrorCoatTarget] = user.index - end - if target.effects[PBEffects::Bide]>0 - target.effects[PBEffects::BideDamage] += damage - target.effects[PBEffects::BideTarget] = user.index - end - target.damageState.fainted = true if target.fainted? - target.lastHPLost = damage # For Focus Punch - target.tookDamage = true if damage>0 # For Assurance - target.lastAttacker.push(user.index) # For Revenge - if target.opposes?(user) - target.lastHPLostFromFoe = damage # For Metal Burst - target.lastFoeAttacker.push(user.index) # For Metal Burst - end - end -end diff --git a/Data/Scripts/011_Battle/002_Move/003_Move_Usage_Calculations.rb b/Data/Scripts/011_Battle/002_Move/003_Move_Usage_Calculations.rb deleted file mode 100644 index 1ff5f6b13..000000000 --- a/Data/Scripts/011_Battle/002_Move/003_Move_Usage_Calculations.rb +++ /dev/null @@ -1,492 +0,0 @@ -class PokeBattle_Move - #============================================================================= - # Move's type calculation - #============================================================================= - def pbBaseType(user) - ret = @type - if ret && user.abilityActive? - ret = BattleHandlers.triggerMoveBaseTypeModifierAbility(user.ability,user,self,ret) - end - return ret - end - - def pbCalcType(user) - @powerBoost = false - ret = pbBaseType(user) - if ret && GameData::Type.exists?(:ELECTRIC) - if @battle.field.effects[PBEffects::IonDeluge] && ret == :NORMAL - ret = :ELECTRIC - @powerBoost = false - end - if user.effects[PBEffects::Electrify] - ret = :ELECTRIC - @powerBoost = false - end - end - return ret - end - - #============================================================================= - # Type effectiveness calculation - #============================================================================= - def pbCalcTypeModSingle(moveType,defType,user,target) - ret = Effectiveness.calculate_one(moveType, defType) - # Ring Target - if target.hasActiveItem?(:RINGTARGET) - ret = Effectiveness::NORMAL_EFFECTIVE_ONE if Effectiveness.ineffective_type?(moveType, defType) - end - # Foresight - if user.hasActiveAbility?(:SCRAPPY) || target.effects[PBEffects::Foresight] - ret = Effectiveness::NORMAL_EFFECTIVE_ONE if defType == :GHOST && - Effectiveness.ineffective_type?(moveType, defType) - end - # Miracle Eye - if target.effects[PBEffects::MiracleEye] - ret = Effectiveness::NORMAL_EFFECTIVE_ONE if defType == :DARK && - Effectiveness.ineffective_type?(moveType, defType) - end - # Delta Stream's weather - if @battle.pbWeather == :StrongWinds - ret = Effectiveness::NORMAL_EFFECTIVE_ONE if defType == :FLYING && - Effectiveness.super_effective_type?(moveType, defType) - end - # Grounded Flying-type Pokémon become susceptible to Ground moves - if !target.airborne? - ret = Effectiveness::NORMAL_EFFECTIVE_ONE if defType == :FLYING && moveType == :GROUND - end - return ret - end - - def pbCalcTypeMod(moveType,user,target) - return Effectiveness::NORMAL_EFFECTIVE if !moveType - return Effectiveness::NORMAL_EFFECTIVE if moveType == :GROUND && - target.pbHasType?(:FLYING) && target.hasActiveItem?(:IRONBALL) - # Determine types - tTypes = target.pbTypes(true) - # Get effectivenesses - typeMods = [Effectiveness::NORMAL_EFFECTIVE_ONE] * 3 # 3 types max - if moveType == :SHADOW - if target.shadowPokemon? - typeMods[0] = Effectiveness::NOT_VERY_EFFECTIVE_ONE - else - typeMods[0] = Effectiveness::SUPER_EFFECTIVE_ONE - end - else - tTypes.each_with_index do |type,i| - typeMods[i] = pbCalcTypeModSingle(moveType,type,user,target) - end - end - # Multiply all effectivenesses together - ret = 1 - typeMods.each { |m| ret *= m } - return ret - end - - #============================================================================= - # Accuracy check - #============================================================================= - def pbBaseAccuracy(user,target); return @accuracy; end - - # Accuracy calculations for one-hit KO moves and "always hit" moves are - # handled elsewhere. - def pbAccuracyCheck(user,target) - # "Always hit" effects and "always hit" accuracy - return true if target.effects[PBEffects::Telekinesis]>0 - return true if target.effects[PBEffects::Minimize] && tramplesMinimize?(1) - baseAcc = pbBaseAccuracy(user,target) - return true if baseAcc==0 - # Calculate all multiplier effects - modifiers = {} - modifiers[:base_accuracy] = baseAcc - modifiers[:accuracy_stage] = user.stages[:ACCURACY] - modifiers[:evasion_stage] = target.stages[:EVASION] - modifiers[:accuracy_multiplier] = 1.0 - modifiers[:evasion_multiplier] = 1.0 - pbCalcAccuracyModifiers(user,target,modifiers) - # Check if move can't miss - return true if modifiers[:base_accuracy] == 0 - # Calculation - accStage = [[modifiers[:accuracy_stage], -6].max, 6].min + 6 - evaStage = [[modifiers[:evasion_stage], -6].max, 6].min + 6 - stageMul = [3,3,3,3,3,3, 3, 4,5,6,7,8,9] - stageDiv = [9,8,7,6,5,4, 3, 3,3,3,3,3,3] - accuracy = 100.0 * stageMul[accStage] / stageDiv[accStage] - evasion = 100.0 * stageMul[evaStage] / stageDiv[evaStage] - accuracy = (accuracy * modifiers[:accuracy_multiplier]).round - evasion = (evasion * modifiers[:evasion_multiplier]).round - evasion = 1 if evasion < 1 - # Calculation - return @battle.pbRandom(100) < modifiers[:base_accuracy] * accuracy / evasion - end - - def pbCalcAccuracyModifiers(user,target,modifiers) - # Ability effects that alter accuracy calculation - if user.abilityActive? - BattleHandlers.triggerAccuracyCalcUserAbility(user.ability, - modifiers,user,target,self,@calcType) - end - user.eachAlly do |b| - next if !b.abilityActive? - BattleHandlers.triggerAccuracyCalcUserAllyAbility(b.ability, - modifiers,user,target,self,@calcType) - end - if target.abilityActive? && !@battle.moldBreaker - BattleHandlers.triggerAccuracyCalcTargetAbility(target.ability, - modifiers,user,target,self,@calcType) - end - # Item effects that alter accuracy calculation - if user.itemActive? - BattleHandlers.triggerAccuracyCalcUserItem(user.item, - modifiers,user,target,self,@calcType) - end - if target.itemActive? - BattleHandlers.triggerAccuracyCalcTargetItem(target.item, - modifiers,user,target,self,@calcType) - end - # Other effects, inc. ones that set accuracy_multiplier or evasion_stage to - # specific values - if @battle.field.effects[PBEffects::Gravity] > 0 - modifiers[:accuracy_multiplier] *= 5 / 3.0 - end - if user.effects[PBEffects::MicleBerry] - user.effects[PBEffects::MicleBerry] = false - modifiers[:accuracy_multiplier] *= 1.2 - end - modifiers[:evasion_stage] = 0 if target.effects[PBEffects::Foresight] && modifiers[:evasion_stage] > 0 - modifiers[:evasion_stage] = 0 if target.effects[PBEffects::MiracleEye] && modifiers[:evasion_stage] > 0 - end - - #============================================================================= - # Critical hit check - #============================================================================= - # Return values: - # -1: Never a critical hit. - # 0: Calculate normally. - # 1: Always a critical hit. - def pbCritialOverride(user,target); return 0; end - - # Returns whether the move will be a critical hit. - def pbIsCritical?(user,target) - return false if target.pbOwnSide.effects[PBEffects::LuckyChant]>0 - # Set up the critical hit ratios - ratios = (Settings::NEW_CRITICAL_HIT_RATE_MECHANICS) ? [24,8,2,1] : [16,8,4,3,2] - c = 0 - # Ability effects that alter critical hit rate - if c>=0 && user.abilityActive? - c = BattleHandlers.triggerCriticalCalcUserAbility(user.ability,user,target,c) - end - if c>=0 && target.abilityActive? && !@battle.moldBreaker - c = BattleHandlers.triggerCriticalCalcTargetAbility(target.ability,user,target,c) - end - # Item effects that alter critical hit rate - if c>=0 && user.itemActive? - c = BattleHandlers.triggerCriticalCalcUserItem(user.item,user,target,c) - end - if c>=0 && target.itemActive? - c = BattleHandlers.triggerCriticalCalcTargetItem(target.item,user,target,c) - end - return false if c<0 - # Move-specific "always/never a critical hit" effects - case pbCritialOverride(user,target) - when 1 then return true - when -1 then return false - end - # Other effects - return true if user.hasActiveItem?(:MANKEYPAW) - return true if c>50 # Merciless - return true if user.effects[PBEffects::LaserFocus]>0 - c += 1 if highCriticalRate? - c += user.effects[PBEffects::FocusEnergy] - c += 1 if user.inHyperMode? && @type == :SHADOW - c = ratios.length-1 if c>=ratios.length - # Calculation - return @battle.pbRandom(ratios[c])==0 - end - - #============================================================================= - # Damage calculation - #============================================================================= - def pbBaseDamage(baseDmg,user,target); return baseDmg; end - def pbBaseDamageMultiplier(damageMult,user,target); return damageMult; end - def pbModifyDamage(damageMult,user,target); return damageMult; end - - def pbGetAttackStats(user,target) - if specialMove? - return user.spatk, user.stages[:SPECIAL_ATTACK]+6 - end - return user.attack, user.stages[:ATTACK]+6 - end - - def pbGetDefenseStats(user,target) - if specialMove? - return target.spdef, target.stages[:SPECIAL_DEFENSE]+6 - end - return target.defense, target.stages[:DEFENSE]+6 - end - - def pbCalcDamage(user,target,numTargets=1) - return if statusMove? - if target.damageState.disguise - target.damageState.calcDamage = 1 - return - end - stageMul = [2,2,2,2,2,2, 2, 3,4,5,6,7,8] - stageDiv = [8,7,6,5,4,3, 2, 2,2,2,2,2,2] - # Get the move's type - type = @calcType # nil is treated as physical - # Calculate whether this hit deals critical damage - target.damageState.critical = pbIsCritical?(user,target) - # Calcuate base power of move - baseDmg = pbBaseDamage(@baseDamage,user,target) - # Calculate user's attack stat - atk, atkStage = pbGetAttackStats(user,target) - if !target.hasActiveAbility?(:UNAWARE) || @battle.moldBreaker - atkStage = 6 if target.damageState.critical && atkStage<6 - atk = (atk.to_f*stageMul[atkStage]/stageDiv[atkStage]).floor - end - # Calculate target's defense stat - defense, defStage = pbGetDefenseStats(user,target) - if !user.hasActiveAbility?(:UNAWARE) - defStage = 6 if target.damageState.critical && defStage>6 - defense = (defense.to_f*stageMul[defStage]/stageDiv[defStage]).floor - end - # Calculate all multiplier effects - multipliers = { - :base_damage_multiplier => 1.0, - :attack_multiplier => 1.0, - :defense_multiplier => 1.0, - :final_damage_multiplier => 1.0 - } - pbCalcDamageMultipliers(user,target,numTargets,type,baseDmg,multipliers) - # Main damage calculation - baseDmg = [(baseDmg * multipliers[:base_damage_multiplier]).round, 1].max - atk = [(atk * multipliers[:attack_multiplier]).round, 1].max - defense = [(defense * multipliers[:defense_multiplier]).round, 1].max - damage = (((2.0 * user.level / 5 + 2).floor * baseDmg * atk / defense).floor / 50).floor + 2 - damage = [(damage * multipliers[:final_damage_multiplier]).round, 1].max - target.damageState.calcDamage = damage - end - - def pbCalcDamageMultipliers(user,target,numTargets,type,baseDmg,multipliers) - # Global abilities - if (@battle.pbCheckGlobalAbility(:DARKAURA) && type == :DARK) || - (@battle.pbCheckGlobalAbility(:FAIRYAURA) && type == :FAIRY) - if @battle.pbCheckGlobalAbility(:AURABREAK) - multipliers[:base_damage_multiplier] *= 2 / 3.0 - else - multipliers[:base_damage_multiplier] *= 4 / 3.0 - end - end - # Ability effects that alter damage - if user.abilityActive? - BattleHandlers.triggerDamageCalcUserAbility(user.ability, - user,target,self,multipliers,baseDmg,type) - end - if !@battle.moldBreaker - # NOTE: It's odd that the user's Mold Breaker prevents its partner's - # beneficial abilities (i.e. Flower Gift boosting Atk), but that's - # how it works. - user.eachAlly do |b| - next if !b.abilityActive? - BattleHandlers.triggerDamageCalcUserAllyAbility(b.ability, - user,target,self,multipliers,baseDmg,type) - end - if target.abilityActive? - BattleHandlers.triggerDamageCalcTargetAbility(target.ability, - user,target,self,multipliers,baseDmg,type) if !@battle.moldBreaker - BattleHandlers.triggerDamageCalcTargetAbilityNonIgnorable(target.ability, - user,target,self,multipliers,baseDmg,type) - end - target.eachAlly do |b| - next if !b.abilityActive? - BattleHandlers.triggerDamageCalcTargetAllyAbility(b.ability, - user,target,self,multipliers,baseDmg,type) - end - end - # Item effects that alter damage - if user.itemActive? - BattleHandlers.triggerDamageCalcUserItem(user.item, - user,target,self,multipliers,baseDmg,type) - end - if target.itemActive? - BattleHandlers.triggerDamageCalcTargetItem(target.item, - user,target,self,multipliers,baseDmg,type) - end - # Parental Bond's second attack - if user.effects[PBEffects::ParentalBond]==1 - multipliers[:base_damage_multiplier] /= 4 - end - # Other - if user.effects[PBEffects::MeFirst] - multipliers[:base_damage_multiplier] *= 1.5 - end - if user.effects[PBEffects::HelpingHand] && !self.is_a?(PokeBattle_Confusion) - multipliers[:base_damage_multiplier] *= 1.5 - end - if user.effects[PBEffects::Charge]>0 && type == :ELECTRIC - multipliers[:base_damage_multiplier] *= 2 - end - # Mud Sport - if type == :ELECTRIC - @battle.eachBattler do |b| - next if !b.effects[PBEffects::MudSport] - multipliers[:base_damage_multiplier] /= 3 - break - end - if @battle.field.effects[PBEffects::MudSportField]>0 - multipliers[:base_damage_multiplier] /= 3 - end - end - # Water Sport - if type == :FIRE - @battle.eachBattler do |b| - next if !b.effects[PBEffects::WaterSport] - multipliers[:base_damage_multiplier] /= 3 - break - end - if @battle.field.effects[PBEffects::WaterSportField]>0 - multipliers[:base_damage_multiplier] /= 3 - end - end - # Terrain moves - case @battle.field.terrain - when :Electric - multipliers[:base_damage_multiplier] *= 1.5 if type == :ELECTRIC && user.affectedByTerrain? - when :Grassy - multipliers[:base_damage_multiplier] *= 1.5 if type == :GRASS && user.affectedByTerrain? - when :Psychic - multipliers[:base_damage_multiplier] *= 1.5 if type == :PSYCHIC && user.affectedByTerrain? - when :Misty - multipliers[:base_damage_multiplier] /= 2 if type == :DRAGON && target.affectedByTerrain? - end - # Badge multipliers - if @battle.internalBattle - if user.pbOwnedByPlayer? - if physicalMove? && @battle.pbPlayer.badge_count >= Settings::NUM_BADGES_BOOST_ATTACK - multipliers[:attack_multiplier] *= 1.1 - elsif specialMove? && @battle.pbPlayer.badge_count >= Settings::NUM_BADGES_BOOST_SPATK - multipliers[:attack_multiplier] *= 1.1 - end - end - if target.pbOwnedByPlayer? - if physicalMove? && @battle.pbPlayer.badge_count >= Settings::NUM_BADGES_BOOST_DEFENSE - multipliers[:defense_multiplier] *= 1.1 - elsif specialMove? && @battle.pbPlayer.badge_count >= Settings::NUM_BADGES_BOOST_SPDEF - multipliers[:defense_multiplier] *= 1.1 - end - end - end - # Multi-targeting attacks - if numTargets>1 - multipliers[:final_damage_multiplier] *= 0.75 - end - # Weather - case @battle.pbWeather - when :Sun, :HarshSun - if type == :FIRE - multipliers[:final_damage_multiplier] *= 1.5 - elsif type == :WATER - multipliers[:final_damage_multiplier] /= 2 - end - when :Rain, :HeavyRain - if type == :FIRE - multipliers[:final_damage_multiplier] /= 2 - elsif type == :WATER - multipliers[:final_damage_multiplier] *= 1.5 - end - when :Sandstorm - if target.pbHasType?(:ROCK) && specialMove? && @function != "122" # Psyshock - multipliers[:defense_multiplier] *= 1.5 - end - end - # Critical hits - if target.damageState.critical - if Settings::NEW_CRITICAL_HIT_RATE_MECHANICS - multipliers[:final_damage_multiplier] *= 1.5 - else - multipliers[:final_damage_multiplier] *= 2 - end - end - # Random variance - if !self.is_a?(PokeBattle_Confusion) - random = 85+@battle.pbRandom(16) - multipliers[:final_damage_multiplier] *= random / 100.0 - end - # STAB - if type && user.pbHasType?(type) - if user.hasActiveAbility?(:ADAPTABILITY) - multipliers[:final_damage_multiplier] *= 2 - else - multipliers[:final_damage_multiplier] *= 1.5 - end - end - # Type effectiveness - multipliers[:final_damage_multiplier] *= target.damageState.typeMod.to_f / Effectiveness::NORMAL_EFFECTIVE - # Burn - if user.status == :BURN && physicalMove? && damageReducedByBurn? && - !user.hasActiveAbility?(:GUTS) - multipliers[:final_damage_multiplier] /= 2 - end - # Aurora Veil, Reflect, Light Screen - if !ignoresReflect? && !target.damageState.critical && - !user.hasActiveAbility?(:INFILTRATOR) - if target.pbOwnSide.effects[PBEffects::AuroraVeil] > 0 - if @battle.pbSideBattlerCount(target)>1 - multipliers[:final_damage_multiplier] *= 2 / 3.0 - else - multipliers[:final_damage_multiplier] /= 2 - end - elsif target.pbOwnSide.effects[PBEffects::Reflect] > 0 && physicalMove? - if @battle.pbSideBattlerCount(target)>1 - multipliers[:final_damage_multiplier] *= 2 / 3.0 - else - multipliers[:final_damage_multiplier] /= 2 - end - elsif target.pbOwnSide.effects[PBEffects::LightScreen] > 0 && specialMove? - if @battle.pbSideBattlerCount(target) > 1 - multipliers[:final_damage_multiplier] *= 2 / 3.0 - else - multipliers[:final_damage_multiplier] /= 2 - end - end - end - # Minimize - if target.effects[PBEffects::Minimize] && tramplesMinimize?(2) - multipliers[:final_damage_multiplier] *= 2 - end - # Move-specific base damage modifiers - multipliers[:base_damage_multiplier] = pbBaseDamageMultiplier(multipliers[:base_damage_multiplier], user, target) - # Move-specific final damage modifiers - multipliers[:final_damage_multiplier] = pbModifyDamage(multipliers[:final_damage_multiplier], user, target) - end - - #============================================================================= - # Additional effect chance - #============================================================================= - def pbAdditionalEffectChance(user,target,effectChance=0) - return 0 if target.hasActiveAbility?(:SHIELDDUST) && !@battle.moldBreaker - ret = (effectChance>0) ? effectChance : @addlEffect - if Settings::MECHANICS_GENERATION >= 6 || @function != "0A4" # Secret Power - ret *= 2 if user.hasActiveAbility?(:SERENEGRACE) || - user.pbOwnSide.effects[PBEffects::Rainbow]>0 - end - ret = 100 if $DEBUG && Input.press?(Input::CTRL) - return ret - end - - # NOTE: Flinching caused by a move's effect is applied in that move's code, - # not here. - def pbFlinchChance(user,target) - return 0 if flinchingMove? - return 0 if target.hasActiveAbility?(:SHIELDDUST) && !@battle.moldBreaker - ret = 0 - if user.hasActiveAbility?(:STENCH,true) - ret = 10 - elsif user.hasActiveItem?([:KINGSROCK,:RAZORFANG],true) - ret = 10 - end - ret *= 2 if user.hasActiveAbility?(:SERENEGRACE) || - user.pbOwnSide.effects[PBEffects::Rainbow]>0 - return ret - end -end diff --git a/Data/Scripts/011_Battle/002_Move/004_Move_Effects_Generic.rb b/Data/Scripts/011_Battle/002_Move/004_Move_Effects_Generic.rb deleted file mode 100644 index 63c4f21fd..000000000 --- a/Data/Scripts/011_Battle/002_Move/004_Move_Effects_Generic.rb +++ /dev/null @@ -1,716 +0,0 @@ -#=============================================================================== -# Superclass that handles moves using a non-existent function code. -# Damaging moves just do damage with no additional effect. -# Status moves always fail. -#=============================================================================== -class PokeBattle_UnimplementedMove < PokeBattle_Move - def pbMoveFailed?(user,targets) - if statusMove? - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end -end - - - -#=============================================================================== -# Pseudomove for confusion damage. -#=============================================================================== -class PokeBattle_Confusion < PokeBattle_Move - def initialize(battle,move) - @battle = battle - @realMove = move - @id = 0 - @name = "" - @function = "000" - @baseDamage = 40 - @type = nil - @category = 0 - @accuracy = 100 - @pp = -1 - @target = 0 - @priority = 0 - @flags = "" - @addlEffect = 0 - @calcType = nil - @powerBoost = false - @snatched = false - end - - def physicalMove?(thisType=nil); return true; end - def specialMove?(thisType=nil); return false; end - def pbCritialOverride(user,target); return -1; end -end - - - -#=============================================================================== -# Implements the move Struggle. -# For cases where the real move named Struggle is not defined. -#=============================================================================== -class PokeBattle_Struggle < PokeBattle_Move - def initialize(battle,move) - @battle = battle - @realMove = nil # Not associated with a move - @id = (move) ? move.id : :STRUGGLE - @name = (move) ? move.name : _INTL("Struggle") - @function = "002" - @baseDamage = 50 - @type = nil - @category = 0 - @accuracy = 0 - @pp = -1 - @target = 0 - @priority = 0 - @flags = "" - @addlEffect = 0 - @calcType = nil - @powerBoost = false - @snatched = false - end - - def physicalMove?(thisType=nil); return true; end - def specialMove?(thisType=nil); return false; end - - def pbEffectAfterAllHits(user,target) - return if target.damageState.unaffected - user.pbReduceHP((user.totalhp/4.0).round,false) - @battle.pbDisplay(_INTL("{1} is damaged by recoil!",user.pbThis)) - user.pbItemHPHealCheck - end -end - - - -#=============================================================================== -# Generic status problem-inflicting classes. -#=============================================================================== -class PokeBattle_SleepMove < PokeBattle_Move - def pbFailsAgainstTarget?(user,target) - return false if damagingMove? - return !target.pbCanSleep?(user,true,self) - end - - def pbEffectAgainstTarget(user,target) - return if damagingMove? - target.pbSleep - end - - def pbAdditionalEffect(user,target) - return if target.damageState.substitute - target.pbSleep if target.pbCanSleep?(user,false,self) - end -end - - - -class PokeBattle_PoisonMove < PokeBattle_Move - def initialize(battle,move) - super - @toxic = false - end - - def pbFailsAgainstTarget?(user,target) - return false if damagingMove? - return !target.pbCanPoison?(user,true,self) - end - - def pbEffectAgainstTarget(user,target) - return if damagingMove? - target.pbPoison(user,nil,@toxic) - end - - def pbAdditionalEffect(user,target) - return if target.damageState.substitute - target.pbPoison(user,nil,@toxic) if target.pbCanPoison?(user,false,self) - end -end - - - -class PokeBattle_ParalysisMove < PokeBattle_Move - def pbFailsAgainstTarget?(user,target) - return false if damagingMove? - return !target.pbCanParalyze?(user,true,self) - end - - def pbEffectAgainstTarget(user,target) - return if damagingMove? - target.pbParalyze(user) - end - - def pbAdditionalEffect(user,target) - return if target.damageState.substitute - target.pbParalyze(user) if target.pbCanParalyze?(user,false,self) - end -end - - - -class PokeBattle_BurnMove < PokeBattle_Move - def pbFailsAgainstTarget?(user,target) - return false if damagingMove? - return !target.pbCanBurn?(user,true,self) - end - - def pbEffectAgainstTarget(user,target) - return if damagingMove? - target.pbBurn(user) - end - - def pbAdditionalEffect(user,target) - return if target.damageState.substitute - target.pbBurn(user) if target.pbCanBurn?(user,false,self) - end -end - - - -class PokeBattle_FreezeMove < PokeBattle_Move - def pbFailsAgainstTarget?(user,target) - return false if damagingMove? - return !target.pbCanFreeze?(user,true,self) - end - - def pbEffectAgainstTarget(user,target) - return if damagingMove? - target.pbFreeze - end - - def pbAdditionalEffect(user,target) - return if target.damageState.substitute - target.pbFreeze if target.pbCanFreeze?(user,false,self) - end -end - - - -#=============================================================================== -# Other problem-causing classes. -#=============================================================================== -class PokeBattle_FlinchMove < PokeBattle_Move - def flinchingMove?; return true; end - - def pbEffectAgainstTarget(user,target) - return if damagingMove? - target.pbFlinch(user) - end - - def pbAdditionalEffect(user,target) - return if target.damageState.substitute - target.pbFlinch(user) - end -end - - - -class PokeBattle_ConfuseMove < PokeBattle_Move - def pbFailsAgainstTarget?(user,target) - return false if damagingMove? - return !target.pbCanConfuse?(user,true,self) - end - - def pbEffectAgainstTarget(user,target) - return if damagingMove? - target.pbConfuse - end - - def pbAdditionalEffect(user,target) - return if target.damageState.substitute - return if !target.pbCanConfuse?(user,false,self) - target.pbConfuse - end -end - - - -#=============================================================================== -# Generic user's stat increase/decrease classes. -#=============================================================================== -class PokeBattle_StatUpMove < PokeBattle_Move - def pbMoveFailed?(user,targets) - return false if damagingMove? - return !user.pbCanRaiseStatStage?(@statUp[0],user,self,true) - end - - def pbEffectGeneral(user) - return if damagingMove? - user.pbRaiseStatStage(@statUp[0],@statUp[1],user) - end - - def pbAdditionalEffect(user,target) - if user.pbCanRaiseStatStage?(@statUp[0],user,self) - user.pbRaiseStatStage(@statUp[0],@statUp[1],user) - end - end -end - - - -class PokeBattle_MultiStatUpMove < PokeBattle_Move - def pbMoveFailed?(user,targets) - return false if damagingMove? - failed = true - for i in 0...@statUp.length/2 - next if !user.pbCanRaiseStatStage?(@statUp[i*2],user,self) - failed = false - break - end - if failed - @battle.pbDisplay(_INTL("{1}'s stats won't go any higher!",user.pbThis)) - return true - end - return false - end - - def pbEffectGeneral(user) - return if damagingMove? - showAnim = true - for i in 0...@statUp.length/2 - next if !user.pbCanRaiseStatStage?(@statUp[i*2],user,self) - if user.pbRaiseStatStage(@statUp[i*2],@statUp[i*2+1],user,showAnim) - showAnim = false - end - end - end - - def pbAdditionalEffect(user,target) - showAnim = true - for i in 0...@statUp.length/2 - next if !user.pbCanRaiseStatStage?(@statUp[i*2],user,self) - if user.pbRaiseStatStage(@statUp[i*2],@statUp[i*2+1],user,showAnim) - showAnim = false - end - end - end -end - - - -class PokeBattle_StatDownMove < PokeBattle_Move - def pbEffectWhenDealingDamage(user,target) - return if @battle.pbAllFainted?(target.idxOwnSide) - showAnim = true - for i in 0...@statDown.length/2 - next if !user.pbCanLowerStatStage?(@statDown[i*2],user,self) - if user.pbLowerStatStage(@statDown[i*2],@statDown[i*2+1],user,showAnim) - showAnim = false - end - end - end -end - - - -#=============================================================================== -# Generic target's stat increase/decrease classes. -#=============================================================================== -class PokeBattle_TargetStatDownMove < PokeBattle_Move - def pbFailsAgainstTarget?(user,target) - return false if damagingMove? - return !target.pbCanLowerStatStage?(@statDown[0],user,self,true) - end - - def pbEffectAgainstTarget(user,target) - return if damagingMove? - target.pbLowerStatStage(@statDown[0],@statDown[1],user) - end - - def pbAdditionalEffect(user,target) - return if target.damageState.substitute - return if !target.pbCanLowerStatStage?(@statDown[0],user,self) - target.pbLowerStatStage(@statDown[0],@statDown[1],user) - end -end - - - -class PokeBattle_TargetMultiStatDownMove < PokeBattle_Move - def pbFailsAgainstTarget?(user,target) - return false if damagingMove? - failed = true - for i in 0...@statDown.length/2 - next if !target.pbCanLowerStatStage?(@statDown[i*2],user,self) - failed = false - break - end - if failed - # NOTE: It's a bit of a faff to make sure the appropriate failure message - # is shown here, I know. - canLower = false - if target.hasActiveAbility?(:CONTRARY) && !@battle.moldBreaker - for i in 0...@statDown.length/2 - next if target.statStageAtMax?(@statDown[i*2]) - canLower = true - break - end - @battle.pbDisplay(_INTL("{1}'s stats won't go any higher!",user.pbThis)) if !canLower - else - for i in 0...@statDown.length/2 - next if target.statStageAtMin?(@statDown[i*2]) - canLower = true - break - end - @battle.pbDisplay(_INTL("{1}'s stats won't go any lower!",user.pbThis)) if !canLower - end - if canLower - target.pbCanLowerStatStage?(@statDown[0],user,self,true) - end - return true - end - return false - end - - def pbEffectAgainstTarget(user,target) - return if damagingMove? - showAnim = true - for i in 0...@statDown.length/2 - next if !target.pbCanLowerStatStage?(@statDown[i*2],user,self) - if target.pbLowerStatStage(@statDown[i*2],@statDown[i*2+1],user,showAnim) - showAnim = false - end - end - end - - def pbAdditionalEffect(user,target) - return if target.damageState.substitute - showAnim = true - for i in 0...@statDown.length/2 - next if !target.pbCanLowerStatStage?(@statDown[i*2],user,self) - if target.pbLowerStatStage(@statDown[i*2],@statDown[i*2+1],user,showAnim) - showAnim = false - end - end - end -end - - - -#=============================================================================== -# Fixed damage-inflicting move. -#=============================================================================== -class PokeBattle_FixedDamageMove < PokeBattle_Move - def pbFixedDamage(user,target); return 1; end - - def pbCalcDamage(user,target,numTargets=1) - target.damageState.critical = false - target.damageState.calcDamage = pbFixedDamage(user,target) - target.damageState.calcDamage = 1 if target.damageState.calcDamage<1 - end -end - - - -#=============================================================================== -# Two turn move. -#=============================================================================== -class PokeBattle_TwoTurnMove < PokeBattle_Move - def chargingTurnMove?; return true; end - - # user.effects[PBEffects::TwoTurnAttack] is set to the move's ID if this - # method returns true, or nil if false. - # Non-nil means the charging turn. nil means the attacking turn. - def pbIsChargingTurn?(user) - @powerHerb = false - @chargingTurn = false # Assume damaging turn by default - @damagingTurn = true - # 0 at start of charging turn, move's ID at start of damaging turn - if !user.effects[PBEffects::TwoTurnAttack] - @powerHerb = user.hasActiveItem?(:POWERHERB) - @chargingTurn = true - @damagingTurn = @powerHerb - end - return !@damagingTurn # Deliberately not "return @chargingTurn" - end - - def pbDamagingMove? # Stops damage being dealt in the first (charging) turn - return false if !@damagingTurn - return super - end - - def pbAccuracyCheck(user,target) - return true if !@damagingTurn - return super - end - - def pbInitialEffect(user,targets,hitNum) - pbChargingTurnMessage(user,targets) if @chargingTurn - if @chargingTurn && @damagingTurn # Move only takes one turn to use - pbShowAnimation(@id,user,targets,1) # Charging anim - targets.each { |b| pbChargingTurnEffect(user,b) } - if @powerHerb - # Moves that would make the user semi-invulnerable will hide the user - # after the charging animation, so the "UseItem" animation shouldn't show - # for it - if !["0C9","0CA","0CB","0CC","0CD","0CE","14D"].include?(@function) - @battle.pbCommonAnimation("UseItem",user) - end - @battle.pbDisplay(_INTL("{1} became fully charged due to its Power Herb!",user.pbThis)) - user.pbConsumeItem - end - end - pbAttackingTurnMessage(user,targets) if @damagingTurn - end - - def pbChargingTurnMessage(user,targets) - @battle.pbDisplay(_INTL("{1} began charging up!",user.pbThis)) - end - - def pbAttackingTurnMessage(user,targets) - end - - def pbChargingTurnEffect(user,target) - # Skull Bash/Sky Drop are the only two-turn moves with an effect here, and - # the latter just records the target is being Sky Dropped - end - - def pbAttackingTurnEffect(user,target) - end - - def pbEffectAgainstTarget(user,target) - if @damagingTurn; pbAttackingTurnEffect(user,target) - elsif @chargingTurn; pbChargingTurnEffect(user,target) - end - end - - def pbShowAnimation(id,user,targets,hitNum=0,showAnimation=true) - hitNum = 1 if @chargingTurn && !@damagingTurn # Charging anim - super - end -end - - - -#=============================================================================== -# Healing move. -#=============================================================================== -class PokeBattle_HealingMove < PokeBattle_Move - def healingMove?; return true; end - def pbHealAmount(user); return 1; end - - def pbMoveFailed?(user,targets) - if user.hp==user.totalhp - @battle.pbDisplay(_INTL("{1}'s HP is full!",user.pbThis)) - return true - end - return false - end - - def pbEffectGeneral(user) - amt = pbHealAmount(user) - user.pbRecoverHP(amt) - @battle.pbDisplay(_INTL("{1}'s HP was restored.",user.pbThis)) - end -end - - - -#=============================================================================== -# Recoil move. -#=============================================================================== -class PokeBattle_RecoilMove < PokeBattle_Move - def recoilMove?; return true; end - def pbRecoilDamage(user,target); return 1; end - - def pbEffectAfterAllHits(user,target) - return if target.damageState.unaffected - return if !user.takesIndirectDamage? - return if user.hasActiveAbility?(:ROCKHEAD) - amt = pbRecoilDamage(user,target) - amt = 1 if amt<1 - user.pbReduceHP(amt,false) - @battle.pbDisplay(_INTL("{1} is damaged by recoil!",user.pbThis)) - user.pbItemHPHealCheck - end -end - - - -#=============================================================================== -# Protect move. -#=============================================================================== -class PokeBattle_ProtectMove < PokeBattle_Move - def initialize(battle,move) - super - @sidedEffect = false - end - - def pbChangeUsageCounters(user,specialUsage) - oldVal = user.effects[PBEffects::ProtectRate] - super - user.effects[PBEffects::ProtectRate] = oldVal - end - - def pbMoveFailed?(user,targets) - if @sidedEffect - if user.pbOwnSide.effects[@effect] - user.effects[PBEffects::ProtectRate] = 1 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - elsif user.effects[@effect] - user.effects[PBEffects::ProtectRate] = 1 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - if (!@sidedEffect || Settings::MECHANICS_GENERATION <= 5) && - user.effects[PBEffects::ProtectRate]>1 && - @battle.pbRandom(user.effects[PBEffects::ProtectRate])!=0 - user.effects[PBEffects::ProtectRate] = 1 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - if pbMoveFailedLastInRound?(user) - user.effects[PBEffects::ProtectRate] = 1 - return true - end - return false - end - - def pbEffectGeneral(user) - if @sidedEffect - user.pbOwnSide.effects[@effect] = true - else - user.effects[@effect] = true - end - user.effects[PBEffects::ProtectRate] *= (Settings::MECHANICS_GENERATION >= 6) ? 3 : 2 - pbProtectMessage(user) - end - - def pbProtectMessage(user) - if @sidedEffect - @battle.pbDisplay(_INTL("{1} protected {2}!",@name,user.pbTeam(true))) - else - @battle.pbDisplay(_INTL("{1} protected itself!",user.pbThis)) - end - end -end - - - -#=============================================================================== -# Weather-inducing move. -#=============================================================================== -class PokeBattle_WeatherMove < PokeBattle_Move - def initialize(battle,move) - super - @weatherType = :None - end - - def pbMoveFailed?(user,targets) - case @battle.field.weather - when :HarshSun - @battle.pbDisplay(_INTL("The extremely harsh sunlight was not lessened at all!")) - return true - when :HeavyRain - @battle.pbDisplay(_INTL("There is no relief from this heavy rain!")) - return true - when :StrongWinds - @battle.pbDisplay(_INTL("The mysterious air current blows on regardless!")) - return true - when @weatherType - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - @battle.pbStartWeather(user,@weatherType,true,false) - end -end - - - -#=============================================================================== -# Pledge move. -#=============================================================================== -class PokeBattle_PledgeMove < PokeBattle_Move - def pbOnStartUse(user,targets) - @pledgeSetup = false; @pledgeCombo = false; @pledgeOtherUser = nil - @comboEffect = nil; @overrideType = nil; @overrideAnim = nil - # Check whether this is the use of a combo move - @combos.each do |i| - next if i[0]!=user.effects[PBEffects::FirstPledge] - @battle.pbDisplay(_INTL("The two moves have become one! It's a combined move!")) - @pledgeCombo = true - @comboEffect = i[1]; @overrideType = i[2]; @overrideAnim = i[3] - @overrideType = nil if !GameData::Type.exists?(@overrideType) - break - end - return if @pledgeCombo - # Check whether this is the setup of a combo move - user.eachAlly do |b| - next if @battle.choices[b.index][0]!=:UseMove || b.movedThisRound? - move = @battle.choices[b.index][2] - next if !move - @combos.each do |i| - next if i[0]!=move.function - @pledgeSetup = true - @pledgeOtherUser = b - break - end - break if @pledgeSetup - end - end - - def pbDamagingMove? - return false if @pledgeSetup - return super - end - - def pbBaseType(user) - return @overrideType if @overrideType!=nil - return super - end - - def pbBaseDamage(baseDmg,user,target) - baseDmg *= 2 if @pledgeCombo - return baseDmg - end - - def pbEffectGeneral(user) - user.effects[PBEffects::FirstPledge] = 0 - return if !@pledgeSetup - @battle.pbDisplay(_INTL("{1} is waiting for {2}'s move...", - user.pbThis,@pledgeOtherUser.pbThis(true))) - @pledgeOtherUser.effects[PBEffects::FirstPledge] = @function - @pledgeOtherUser.effects[PBEffects::MoveNext] = true - user.lastMoveFailed = true # Treated as a failure for Stomping Tantrum - end - - def pbEffectAfterAllHits(user,target) - return if !@pledgeCombo - msg = nil; animName = nil - case @comboEffect - when :SeaOfFire # Grass + Fire - if user.pbOpposingSide.effects[PBEffects::SeaOfFire]==0 - user.pbOpposingSide.effects[PBEffects::SeaOfFire] = 4 - msg = _INTL("A sea of fire enveloped {1}!",user.pbOpposingTeam(true)) - animName = (user.opposes?) ? "SeaOfFire" : "SeaOfFireOpp" - end - when :Rainbow # Fire + Water - if user.pbOwnSide.effects[PBEffects::Rainbow]==0 - user.pbOwnSide.effects[PBEffects::Rainbow] = 4 - msg = _INTL("A rainbow appeared in the sky on {1}'s side!",user.pbTeam(true)) - animName = (user.opposes?) ? "RainbowOpp" : "Rainbow" - end - when :Swamp # Water + Grass - if user.pbOpposingSide.effects[PBEffects::Swamp]==0 - user.pbOpposingSide.effects[PBEffects::Swamp] = 4 - msg = _INTL("A swamp enveloped {1}!",user.pbOpposingTeam(true)) - animName = (user.opposes?) ? "Swamp" : "SwampOpp" - end - end - @battle.pbDisplay(msg) if msg - @battle.pbCommonAnimation(animName) if animName - end - - def pbShowAnimation(id,user,targets,hitNum=0,showAnimation=true) - return if @pledgeSetup # No animation for setting up - id = @overrideAnim if @overrideAnim - return super - end -end diff --git a/Data/Scripts/011_Battle/002_Move/005_Move_Effects_000-07F.rb b/Data/Scripts/011_Battle/002_Move/005_Move_Effects_000-07F.rb deleted file mode 100644 index ed6194b61..000000000 --- a/Data/Scripts/011_Battle/002_Move/005_Move_Effects_000-07F.rb +++ /dev/null @@ -1,2572 +0,0 @@ -#=============================================================================== -# No additional effect. -#=============================================================================== -class PokeBattle_Move_000 < PokeBattle_Move -end - -#=============================================================================== -# Does absolutely nothing. (Splash) -#=============================================================================== -class PokeBattle_Move_001 < PokeBattle_Move - def unusableInGravity? - return true; - end - - def pbEffectGeneral(user) - @battle.pbDisplay(_INTL("But nothing happened!")) - end -end - -#=============================================================================== -# Struggle, if defined as a move in moves.txt. Typically it won't be. -#=============================================================================== -class PokeBattle_Move_002 < PokeBattle_Struggle -end - -#=============================================================================== -# Puts the target to sleep. -#=============================================================================== -class PokeBattle_Move_003 < PokeBattle_SleepMove - def pbMoveFailed?(user, targets) - if Settings::MECHANICS_GENERATION >= 7 && @id == :DARKVOID - if !user.isSpecies?(:DARKRAI) && user.effects[PBEffects::TransformSpecies] != :DARKRAI - @battle.pbDisplay(_INTL("But {1} can't use the move!", user.pbThis)) - return true - end - end - return false - end - - def pbEndOfMoveUsageEffect(user, targets, numHits, switchedBattlers) - return if numHits == 0 - return if user.fainted? || user.effects[PBEffects::Transform] - return if @id != :RELICSONG - return if !(user.isFusionOf(:MELOETTA_A) || user.isFusionOf(:MELOETTA_P)) - return if user.hasActiveAbility?(:SHEERFORCE) && @addlEffect > 0 - - is_meloetta_A = user.isFusionOf(:MELOETTA_A) - is_meloetta_P = user.isFusionOf(:MELOETTA_P) - #reverse the fusion if it's a meloA and meloP fusion - # There's probably a smarter way to do this but laziness lol - if is_meloetta_A && is_meloetta_P - body_id = user.pokemon.species_data.get_body_species() - body_species = GameData::Species.get(body_id) - if body_species == :MELOETTA_A - changeSpeciesSpecific(user.pokemon,:B467H466) - else - changeSpeciesSpecific(user.pokemon,:B466H467) - end - user.playChangeFormAnimation("Shiny") - else - user.changeSpecies(user.pokemon, :MELOETTA_A, :MELOETTA_P, "Shiny") if is_meloetta_A - user.changeSpecies(user.pokemon, :MELOETTA_P, :MELOETTA_A, "Shiny") if is_meloetta_P - end - end -end - -#=============================================================================== -# Makes the target drowsy; it falls asleep at the end of the next turn. (Yawn) -#=============================================================================== -class PokeBattle_Move_004 < PokeBattle_Move - def pbFailsAgainstTarget?(user, target) - if target.effects[PBEffects::Yawn] > 0 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return true if !target.pbCanSleep?(user, true, self) - return false - end - - def pbEffectAgainstTarget(user, target) - target.effects[PBEffects::Yawn] = 2 - @battle.pbDisplay(_INTL("{1} made {2} drowsy!", user.pbThis, target.pbThis(true))) - end -end - -#=============================================================================== -# Poisons the target. -#=============================================================================== -class PokeBattle_Move_005 < PokeBattle_PoisonMove -end - -#=============================================================================== -# Badly poisons the target. (Poison Fang, Toxic) -#=============================================================================== -class PokeBattle_Move_006 < PokeBattle_PoisonMove - def initialize(battle, move) - super - @toxic = true - end - - def pbOverrideSuccessCheckPerHit(user, target) - return (Settings::MORE_TYPE_EFFECTS && statusMove? && user.pbHasType?(:POISON)) - end -end - -#=============================================================================== -# Paralyzes the target. -# Thunder Wave: Doesn't affect target if move's type has no effect on it. -# Body Slam: Does double damage and has perfect accuracy if target is Minimized. -#=============================================================================== -class PokeBattle_Move_007 < PokeBattle_ParalysisMove - def tramplesMinimize?(param = 1) - # Perfect accuracy and double damage (for Body Slam only) - return Settings::MECHANICS_GENERATION >= 6 if @id == :BODYSLAM - return super - end - - def pbFailsAgainstTarget?(user, target) - if @id == :THUNDERWAVE && Effectiveness.ineffective?(target.damageState.typeMod) - @battle.pbDisplay(_INTL("It doesn't affect {1}...", target.pbThis(true))) - return true - end - return super - end -end - -#=============================================================================== -# Paralyzes the target. Accuracy perfect in rain, 50% in sunshine. Hits some -# semi-invulnerable targets. (Thunder) -#=============================================================================== -class PokeBattle_Move_008 < PokeBattle_ParalysisMove - def hitsFlyingTargets? - return true; - end - - def pbBaseAccuracy(user, target) - case @battle.pbWeather - when :Sun, :HarshSun - return 50 - when :Rain, :HeavyRain - return 0 - end - return super - end -end - -#=============================================================================== -# Paralyzes the target. May cause the target to flinch. (Thunder Fang) -#=============================================================================== -class PokeBattle_Move_009 < PokeBattle_Move - def flinchingMove? - return true; - end - - def pbAdditionalEffect(user, target) - return if target.damageState.substitute - chance = pbAdditionalEffectChance(user, target, 10) - return if chance == 0 - if @battle.pbRandom(100) < chance - target.pbParalyze(user) if target.pbCanParalyze?(user, false, self) - end - target.pbFlinch(user) if @battle.pbRandom(100) < chance - end -end - -#=============================================================================== -# Burns the target. -#=============================================================================== -class PokeBattle_Move_00A < PokeBattle_BurnMove -end - -#=============================================================================== -# Burns the target. May cause the target to flinch. (Fire Fang) -#=============================================================================== -class PokeBattle_Move_00B < PokeBattle_Move - def flinchingMove? - return true; - end - - def pbAdditionalEffect(user, target) - return if target.damageState.substitute - chance = pbAdditionalEffectChance(user, target, 10) - return if chance == 0 - if @battle.pbRandom(100) < chance - target.pbBurn(user) if target.pbCanBurn?(user, false, self) - end - target.pbFlinch(user) if @battle.pbRandom(100) < chance - end -end - -#=============================================================================== -# Freezes the target. -#=============================================================================== -class PokeBattle_Move_00C < PokeBattle_FreezeMove -end - -#=============================================================================== -# Freezes the target. Accuracy perfect in hail. (Blizzard) -#=============================================================================== -class PokeBattle_Move_00D < PokeBattle_FreezeMove - def pbBaseAccuracy(user, target) - return 0 if @battle.pbWeather == :Hail - return super - end -end - -#=============================================================================== -# Freezes the target. May cause the target to flinch. (Ice Fang) -#=============================================================================== -class PokeBattle_Move_00E < PokeBattle_Move - def flinchingMove? - return true; - end - - def pbAdditionalEffect(user, target) - return if target.damageState.substitute - chance = pbAdditionalEffectChance(user, target, 10) - return if chance == 0 - if @battle.pbRandom(100) < chance - target.pbFreeze if target.pbCanFreeze?(user, false, self) - end - target.pbFlinch(user) if @battle.pbRandom(100) < chance - end -end - -#=============================================================================== -# Causes the target to flinch. -#=============================================================================== -class PokeBattle_Move_00F < PokeBattle_FlinchMove -end - -#=============================================================================== -# Causes the target to flinch. Does double damage and has perfect accuracy if -# the target is Minimized. (Dragon Rush, Steamroller, Stomp) -#=============================================================================== -class PokeBattle_Move_010 < PokeBattle_FlinchMove - def tramplesMinimize?(param = 1) - return super if @id == :DRAGONRUSH && Settings::MECHANICS_GENERATION <= 5 - return true if param == 1 && Settings::MECHANICS_GENERATION >= 6 # Perfect accuracy - return true if param == 2 # Double damage - return super - end -end - -#=============================================================================== -# Causes the target to flinch. Fails if the user is not asleep. (Snore) -#=============================================================================== -class PokeBattle_Move_011 < PokeBattle_FlinchMove - def usableWhenAsleep? - return true; - end - - def pbMoveFailed?(user, targets) - if !user.asleep? - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end -end - -#=============================================================================== -# Causes the target to flinch. Fails if this isn't the user's first turn. -# (Fake Out) -#=============================================================================== -class PokeBattle_Move_012 < PokeBattle_FlinchMove - def pbMoveFailed?(user, targets) - if user.turnCount > 1 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end -end - -#=============================================================================== -# Confuses the target. -#=============================================================================== -class PokeBattle_Move_013 < PokeBattle_ConfuseMove -end - -#=============================================================================== -# Confuses the target. (Chatter) -#=============================================================================== -class PokeBattle_Move_014 < PokeBattle_Move_013 -end - -#=============================================================================== -# Confuses the target. Accuracy perfect in rain, 50% in sunshine. Hits some -# semi-invulnerable targets. (Hurricane) -#=============================================================================== -class PokeBattle_Move_015 < PokeBattle_ConfuseMove - def hitsFlyingTargets? - return true; - end - - def pbBaseAccuracy(user, target) - case @battle.pbWeather - when :Sun, :HarshSun - return 50 - when :Rain, :HeavyRain - return 0 - end - return super - end -end - -#=============================================================================== -# Attracts the target. (Attract) -#=============================================================================== -class PokeBattle_Move_016 < PokeBattle_Move - def ignoresSubstitute?(user) - ; return true; - end - - def pbFailsAgainstTarget?(user, target) - return false if damagingMove? - return true if !target.pbCanAttract?(user) - return true if pbMoveFailedAromaVeil?(user, target) - return false - end - - def pbEffectAgainstTarget(user, target) - return if damagingMove? - target.pbAttract(user) - end - - def pbAdditionalEffect(user, target) - return if target.damageState.substitute - target.pbAttract(user) if target.pbCanAttract?(user, false) - end -end - -#=============================================================================== -# Burns, freezes or paralyzes the target. (Tri Attack) -#=============================================================================== -class PokeBattle_Move_017 < PokeBattle_Move - def pbAdditionalEffect(user, target) - return if target.damageState.substitute - case @battle.pbRandom(3) - when 0 then - target.pbBurn(user) if target.pbCanBurn?(user, false, self) - when 1 then - target.pbFreeze if target.pbCanFreeze?(user, false, self) - when 2 then - target.pbParalyze(user) if target.pbCanParalyze?(user, false, self) - end - end -end - -#=============================================================================== -# Cures user of burn, poison and paralysis. (Refresh) -#=============================================================================== -class PokeBattle_Move_018 < PokeBattle_Move - def pbMoveFailed?(user, targets) - if ![:BURN, :POISON, :PARALYSIS].include?(user.status) - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - old_status = user.status - user.pbCureStatus(false) - case old_status - when :BURN - @battle.pbDisplay(_INTL("{1} healed its burn!", user.pbThis)) - when :POISON - @battle.pbDisplay(_INTL("{1} cured its poisoning!", user.pbThis)) - when :PARALYSIS - @battle.pbDisplay(_INTL("{1} cured its paralysis!", user.pbThis)) - end - end -end - -#=============================================================================== -# Cures all party Pokémon of permanent status problems. (Aromatherapy, Heal Bell) -#=============================================================================== -# NOTE: In Gen 5, this move should have a target of UserSide, while in Gen 6+ it -# should have a target of UserAndAllies. This is because, in Gen 5, this -# move shouldn't call def pbSuccessCheckAgainstTarget for each Pokémon -# currently in battle that will be affected by this move (i.e. allies -# aren't protected by their substitute/ability/etc., but they are in Gen -# 6+). We achieve this by not targeting any battlers in Gen 5, since -# pbSuccessCheckAgainstTarget is only called for targeted battlers. -class PokeBattle_Move_019 < PokeBattle_Move - def worksWithNoTargets? - return true; - end - - def pbMoveFailed?(user, targets) - failed = true - @battle.eachSameSideBattler(user) do |b| - next if b.status == :NONE - failed = false - break - end - @battle.pbParty(user.index).each do |pkmn| - next if !pkmn || !pkmn.able? || pkmn.status == :NONE - failed = false - break - end - if failed - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbFailsAgainstTarget?(user, target) - return target.status == :NONE - end - - def pbAromatherapyHeal(pkmn, battler = nil) - oldStatus = (battler) ? battler.status : pkmn.status - curedName = (battler) ? battler.pbThis : pkmn.name - if battler - battler.pbCureStatus(false) - else - pkmn.status = :NONE - pkmn.statusCount = 0 - end - case oldStatus - when :SLEEP - @battle.pbDisplay(_INTL("{1} was woken from sleep.", curedName)) - when :POISON - @battle.pbDisplay(_INTL("{1} was cured of its poisoning.", curedName)) - when :BURN - @battle.pbDisplay(_INTL("{1}'s burn was healed.", curedName)) - when :PARALYSIS - @battle.pbDisplay(_INTL("{1} was cured of paralysis.", curedName)) - when :FROZEN - @battle.pbDisplay(_INTL("{1} was thawed out.", curedName)) - end - end - - def pbEffectAgainstTarget(user, target) - # Cure all Pokémon in battle on the user's side. - pbAromatherapyHeal(target.pokemon, target) - end - - def pbEffectGeneral(user) - # Cure all Pokémon in battle on the user's side. For the benefit of the Gen - # 5 version of this move, to make Pokémon out in battle get cured first. - if pbTarget(user) == :UserSide - @battle.eachSameSideBattler(user) do |b| - next if b.status == :NONE - pbAromatherapyHeal(b.pokemon, b) - end - end - # Cure all Pokémon in the user's and partner trainer's party. - # NOTE: This intentionally affects the partner trainer's inactive Pokémon - # too. - @battle.pbParty(user.index).each_with_index do |pkmn, i| - next if !pkmn || !pkmn.able? || pkmn.status == :NONE - next if @battle.pbFindBattler(i, user) # Skip Pokémon in battle - pbAromatherapyHeal(pkmn) - end - end - - def pbShowAnimation(id, user, targets, hitNum = 0, showAnimation = true) - super - if @id == :AROMATHERAPY - @battle.pbDisplay(_INTL("A soothing aroma wafted through the area!")) - elsif @id == :HEALBELL - @battle.pbDisplay(_INTL("A bell chimed!")) - end - end -end - -#=============================================================================== -# Safeguards the user's side from being inflicted with status problems. -# (Safeguard) -#=============================================================================== -class PokeBattle_Move_01A < PokeBattle_Move - def pbMoveFailed?(user, targets) - if user.pbOwnSide.effects[PBEffects::Safeguard] > 0 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - user.pbOwnSide.effects[PBEffects::Safeguard] = 5 - @battle.pbDisplay(_INTL("{1} became cloaked in a mystical veil!", user.pbTeam)) - end -end - -#=============================================================================== -# User passes its status problem to the target. (Psycho Shift) -#=============================================================================== -class PokeBattle_Move_01B < PokeBattle_Move - def pbMoveFailed?(user, targets) - if user.status == :NONE - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbFailsAgainstTarget?(user, target) - if !target.pbCanInflictStatus?(user.status, user, false, self) - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectAgainstTarget(user, target) - msg = "" - case user.status - when :SLEEP - target.pbSleep - msg = _INTL("{1} woke up.", user.pbThis) - when :POISON - target.pbPoison(user, nil, user.statusCount != 0) - msg = _INTL("{1} was cured of its poisoning.", user.pbThis) - when :BURN - target.pbBurn(user) - msg = _INTL("{1}'s burn was healed.", user.pbThis) - when :PARALYSIS - target.pbParalyze(user) - msg = _INTL("{1} was cured of paralysis.", user.pbThis) - when :FROZEN - target.pbFreeze - msg = _INTL("{1} was thawed out.", user.pbThis) - end - if msg != "" - user.pbCureStatus(false) - @battle.pbDisplay(msg) - end - end -end - -#=============================================================================== -# Increases the user's Attack by 1 stage. -#=============================================================================== -class PokeBattle_Move_01C < PokeBattle_StatUpMove - def initialize(battle, move) - super - @statUp = [:ATTACK, 1] - end -end - -#=============================================================================== -# Increases the user's Defense by 1 stage. (Harden, Steel Wing, Withdraw) -#=============================================================================== -class PokeBattle_Move_01D < PokeBattle_StatUpMove - def initialize(battle, move) - super - @statUp = [:DEFENSE, 1] - end -end - -#=============================================================================== -# Increases the user's Defense by 1 stage. User curls up. (Defense Curl) -#=============================================================================== -class PokeBattle_Move_01E < PokeBattle_StatUpMove - def initialize(battle, move) - super - @statUp = [:DEFENSE, 1] - end - - def pbEffectGeneral(user) - user.effects[PBEffects::DefenseCurl] = true - super - end -end - -#=============================================================================== -# Increases the user's Speed by 1 stage. (Flame Charge) -#=============================================================================== -class PokeBattle_Move_01F < PokeBattle_StatUpMove - def initialize(battle, move) - super - @statUp = [:SPEED, 1] - end -end - -#=============================================================================== -# Increases the user's Special Attack by 1 stage. (Charge Beam, Fiery Dance) -#=============================================================================== -class PokeBattle_Move_020 < PokeBattle_StatUpMove - def initialize(battle, move) - super - @statUp = [:SPECIAL_ATTACK, 1] - end -end - -#=============================================================================== -# Increases the user's Special Defense by 1 stage. -# Charges up user's next attack if it is Electric-type. (Charge) -#=============================================================================== -class PokeBattle_Move_021 < PokeBattle_StatUpMove - def initialize(battle, move) - super - @statUp = [:SPECIAL_DEFENSE, 1] - end - - def pbEffectGeneral(user) - user.effects[PBEffects::Charge] = 2 - @battle.pbDisplay(_INTL("{1} began charging power!", user.pbThis)) - super - end -end - -#=============================================================================== -# Increases the user's evasion by 1 stage. (Double Team) -#=============================================================================== -class PokeBattle_Move_022 < PokeBattle_StatUpMove - def initialize(battle, move) - super - @statUp = [:EVASION, 1] - end -end - -#=============================================================================== -# Increases the user's critical hit rate. (Focus Energy) -#=============================================================================== -class PokeBattle_Move_023 < PokeBattle_Move - def pbMoveFailed?(user, targets) - if user.effects[PBEffects::FocusEnergy] >= 2 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - user.effects[PBEffects::FocusEnergy] = 2 - @battle.pbDisplay(_INTL("{1} is getting pumped!", user.pbThis)) - end -end - -#=============================================================================== -# Increases the user's Attack and Defense by 1 stage each. (Bulk Up) -#=============================================================================== -class PokeBattle_Move_024 < PokeBattle_MultiStatUpMove - def initialize(battle, move) - super - @statUp = [:ATTACK, 1, :DEFENSE, 1] - end -end - -#=============================================================================== -# Increases the user's Attack, Defense and accuracy by 1 stage each. (Coil) -#=============================================================================== -class PokeBattle_Move_025 < PokeBattle_MultiStatUpMove - def initialize(battle, move) - super - @statUp = [:ATTACK, 1, :DEFENSE, 1, :ACCURACY, 1] - end -end - -#=============================================================================== -# Increases the user's Attack and Speed by 1 stage each. (Dragon Dance) -#=============================================================================== -class PokeBattle_Move_026 < PokeBattle_MultiStatUpMove - def initialize(battle, move) - super - @statUp = [:ATTACK, 1, :SPEED, 1] - end -end - -#=============================================================================== -# Increases the user's Attack and Special Attack by 1 stage each. (Work Up) -#=============================================================================== -class PokeBattle_Move_027 < PokeBattle_MultiStatUpMove - def initialize(battle, move) - super - @statUp = [:ATTACK, 1, :SPECIAL_ATTACK, 1] - end -end - -#=============================================================================== -# Increases the user's Attack and Sp. Attack by 1 stage each. -# In sunny weather, increases are 2 stages each instead. (Growth) -#=============================================================================== -class PokeBattle_Move_028 < PokeBattle_MultiStatUpMove - def initialize(battle, move) - super - @statUp = [:ATTACK, 1, :SPECIAL_ATTACK, 1] - end - - def pbOnStartUse(user, targets) - increment = 1 - increment = 2 if [:Sun, :HarshSun].include?(@battle.pbWeather) - @statUp[1] = @statUp[3] = increment - end -end - -#=============================================================================== -# Increases the user's Attack and accuracy by 1 stage each. (Hone Claws) -#=============================================================================== -class PokeBattle_Move_029 < PokeBattle_MultiStatUpMove - def initialize(battle, move) - super - @statUp = [:ATTACK, 1, :ACCURACY, 1] - end -end - -#=============================================================================== -# Increases the user's Defense and Special Defense by 1 stage each. -# (Cosmic Power, Defend Order) -#=============================================================================== -class PokeBattle_Move_02A < PokeBattle_MultiStatUpMove - def initialize(battle, move) - super - @statUp = [:DEFENSE, 1, :SPECIAL_DEFENSE, 1] - end -end - -#=============================================================================== -# Increases the user's Sp. Attack, Sp. Defense and Speed by 1 stage each. -# (Quiver Dance) -#=============================================================================== -class PokeBattle_Move_02B < PokeBattle_MultiStatUpMove - def initialize(battle, move) - super - @statUp = [:SPECIAL_ATTACK, 1, :SPECIAL_DEFENSE, 1, :SPEED, 1] - end -end - -#=============================================================================== -# Increases the user's Sp. Attack and Sp. Defense by 1 stage each. (Calm Mind) -#=============================================================================== -class PokeBattle_Move_02C < PokeBattle_MultiStatUpMove - def initialize(battle, move) - super - @statUp = [:SPECIAL_ATTACK, 1, :SPECIAL_DEFENSE, 1] - end -end - -#=============================================================================== -# Increases the user's Attack, Defense, Speed, Special Attack and Special Defense -# by 1 stage each. (Ancient Power, Ominous Wind, Silver Wind) -#=============================================================================== -class PokeBattle_Move_02D < PokeBattle_MultiStatUpMove - def initialize(battle, move) - super - @statUp = [:ATTACK, 1, :DEFENSE, 1, :SPECIAL_ATTACK, 1, :SPECIAL_DEFENSE, 1, :SPEED, 1] - end -end - -#=============================================================================== -# Increases the user's Attack by 2 stages. (Swords Dance) -#=============================================================================== -class PokeBattle_Move_02E < PokeBattle_StatUpMove - def initialize(battle, move) - super - @statUp = [:ATTACK, 2] - end -end - -#=============================================================================== -# Increases the user's Defense by 2 stages. (Acid Armor, Barrier, Iron Defense) -#=============================================================================== -class PokeBattle_Move_02F < PokeBattle_StatUpMove - def initialize(battle, move) - super - @statUp = [:DEFENSE, 2] - end -end - -#=============================================================================== -# Increases the user's Speed by 2 stages. (Agility, Rock Polish) -#=============================================================================== -class PokeBattle_Move_030 < PokeBattle_StatUpMove - def initialize(battle, move) - super - @statUp = [:SPEED, 2] - end -end - -#=============================================================================== -# Increases the user's Speed by 2 stages. Lowers user's weight by 100kg. -# (Autotomize) -#=============================================================================== -class PokeBattle_Move_031 < PokeBattle_StatUpMove - def initialize(battle, move) - super - @statUp = [:SPEED, 2] - end - - def pbEffectGeneral(user) - if user.pbWeight + user.effects[PBEffects::WeightChange] > 1 - user.effects[PBEffects::WeightChange] -= 1000 - @battle.pbDisplay(_INTL("{1} became nimble!", user.pbThis)) - end - super - end -end - -#=============================================================================== -# Increases the user's Special Attack by 2 stages. (Nasty Plot) -#=============================================================================== -class PokeBattle_Move_032 < PokeBattle_StatUpMove - def initialize(battle, move) - super - @statUp = [:SPECIAL_ATTACK, 2] - end -end - -#=============================================================================== -# Increases the user's Special Defense by 2 stages. (Amnesia) -#=============================================================================== -class PokeBattle_Move_033 < PokeBattle_StatUpMove - def initialize(battle, move) - super - @statUp = [:SPECIAL_DEFENSE, 2] - end -end - -#=============================================================================== -# Increases the user's evasion by 2 stages. Minimizes the user. (Minimize) -#=============================================================================== -class PokeBattle_Move_034 < PokeBattle_StatUpMove - def initialize(battle, move) - super - @statUp = [:EVASION, 2] - end - - def pbEffectGeneral(user) - user.effects[PBEffects::Minimize] = true - super - end -end - -#=============================================================================== -# Decreases the user's Defense and Special Defense by 1 stage each. -# Increases the user's Attack, Speed and Special Attack by 2 stages each. -# (Shell Smash) -#=============================================================================== -class PokeBattle_Move_035 < PokeBattle_Move - def initialize(battle, move) - super - @statUp = [:ATTACK, 2, :SPECIAL_ATTACK, 2, :SPEED, 2] - @statDown = [:DEFENSE, 1, :SPECIAL_DEFENSE, 1] - end - - def pbMoveFailed?(user, targets) - failed = true - for i in 0...@statUp.length / 2 - if user.pbCanRaiseStatStage?(@statUp[i * 2], user, self) - failed = false; break - end - end - for i in 0...@statDown.length / 2 - if user.pbCanLowerStatStage?(@statDown[i * 2], user, self) - failed = false; break - end - end - if failed - @battle.pbDisplay(_INTL("{1}'s stats can't be changed further!", user.pbThis)) - return true - end - return false - end - - def pbEffectGeneral(user) - showAnim = true - for i in 0...@statDown.length / 2 - next if !user.pbCanLowerStatStage?(@statDown[i * 2], user, self) - if user.pbLowerStatStage(@statDown[i * 2], @statDown[i * 2 + 1], user, showAnim) - showAnim = false - end - end - showAnim = true - for i in 0...@statUp.length / 2 - next if !user.pbCanRaiseStatStage?(@statUp[i * 2], user, self) - if user.pbRaiseStatStage(@statUp[i * 2], @statUp[i * 2 + 1], user, showAnim) - showAnim = false - end - end - end -end - -#=============================================================================== -# Increases the user's Speed by 2 stages, and its Attack by 1 stage. (Shift Gear) -#=============================================================================== -class PokeBattle_Move_036 < PokeBattle_MultiStatUpMove - def initialize(battle, move) - super - @statUp = [:SPEED, 2, :ATTACK, 1] - end -end - -#=============================================================================== -# Increases one random stat of the target by 2 stages (except HP). (Acupressure) -#=============================================================================== -class PokeBattle_Move_037 < PokeBattle_Move - def pbFailsAgainstTarget?(user, target) - @statArray = [] - GameData::Stat.each_battle do |s| - @statArray.push(s.id) if target.pbCanRaiseStatStage?(s.id, user, self) - end - if @statArray.length == 0 - @battle.pbDisplay(_INTL("{1}'s stats won't go any higher!", target.pbThis)) - return true - end - return false - end - - def pbEffectAgainstTarget(user, target) - stat = @statArray[@battle.pbRandom(@statArray.length)] - target.pbRaiseStatStage(stat, 2, user) - end -end - -#=============================================================================== -# Increases the user's Defense by 3 stages. (Cotton Guard) -#=============================================================================== -class PokeBattle_Move_038 < PokeBattle_StatUpMove - def initialize(battle, move) - super - @statUp = [:DEFENSE, 3] - end -end - -#=============================================================================== -# Increases the user's Special Attack by 3 stages. (Tail Glow) -#=============================================================================== -class PokeBattle_Move_039 < PokeBattle_StatUpMove - def initialize(battle, move) - super - @statUp = [:SPECIAL_ATTACK, 3] - end -end - -#=============================================================================== -# Reduces the user's HP by half of max, and sets its Attack to maximum. -# (Belly Drum) -#=============================================================================== -class PokeBattle_Move_03A < PokeBattle_Move - def pbMoveFailed?(user, targets) - hpLoss = [user.totalhp / 2, 1].max - if user.hp <= hpLoss - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return true if !user.pbCanRaiseStatStage?(:ATTACK, user, self, true) - return false - end - - def pbEffectGeneral(user) - hpLoss = [user.totalhp / 2, 1].max - user.pbReduceHP(hpLoss, false) - if user.hasActiveAbility?(:CONTRARY) - user.stages[:ATTACK] = -6 - @battle.pbCommonAnimation("StatDown", user) - @battle.pbDisplay(_INTL("{1} cut its own HP and minimized its Attack!", user.pbThis)) - else - user.stages[:ATTACK] = 6 - @battle.pbCommonAnimation("StatUp", user) - @battle.pbDisplay(_INTL("{1} cut its own HP and maximized its Attack!", user.pbThis)) - end - user.pbItemHPHealCheck - end -end - -#=============================================================================== -# Decreases the user's Attack and Defense by 1 stage each. (Superpower) -#=============================================================================== -class PokeBattle_Move_03B < PokeBattle_StatDownMove - def initialize(battle, move) - super - @statDown = [:ATTACK, 1, :DEFENSE, 1] - end -end - -#=============================================================================== -# Decreases the user's Defense and Special Defense by 1 stage each. -# (Close Combat, Dragon Ascent) -#=============================================================================== -class PokeBattle_Move_03C < PokeBattle_StatDownMove - def initialize(battle, move) - super - @statDown = [:DEFENSE, 1, :SPECIAL_DEFENSE, 1] - end -end - -#=============================================================================== -# Decreases the user's Defense, Special Defense and Speed by 1 stage each. -# (V-create) -#=============================================================================== -class PokeBattle_Move_03D < PokeBattle_StatDownMove - def initialize(battle, move) - super - @statDown = [:SPEED, 1, :DEFENSE, 1, :SPECIAL_DEFENSE, 1] - end -end - -#=============================================================================== -# Decreases the user's Speed by 1 stage. (Hammer Arm, Ice Hammer) -#=============================================================================== -class PokeBattle_Move_03E < PokeBattle_StatDownMove - def initialize(battle, move) - super - @statDown = [:SPEED, 1] - end -end - -#=============================================================================== -# Decreases the user's Special Attack by 2 stages. -#=============================================================================== -class PokeBattle_Move_03F < PokeBattle_StatDownMove - def initialize(battle, move) - super - @statDown = [:SPECIAL_ATTACK, 2] - end -end - -#=============================================================================== -# Increases the target's Special Attack by 1 stage. Confuses the target. (Flatter) -#=============================================================================== -class PokeBattle_Move_040 < PokeBattle_Move - def pbMoveFailed?(user, targets) - failed = true - targets.each do |b| - next if !b.pbCanRaiseStatStage?(:SPECIAL_ATTACK, user, self) && - !b.pbCanConfuse?(user, false, self) - failed = false - break - end - if failed - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectAgainstTarget(user, target) - if target.pbCanRaiseStatStage?(:SPECIAL_ATTACK, user, self) - target.pbRaiseStatStage(:SPECIAL_ATTACK, 1, user) - end - target.pbConfuse if target.pbCanConfuse?(user, false, self) - end -end - -#=============================================================================== -# Increases the target's Attack by 2 stages. Confuses the target. (Swagger) -#=============================================================================== -class PokeBattle_Move_041 < PokeBattle_Move - def pbMoveFailed?(user, targets) - failed = true - targets.each do |b| - next if !b.pbCanRaiseStatStage?(:ATTACK, user, self) && - !b.pbCanConfuse?(user, false, self) - failed = false - break - end - if failed - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectAgainstTarget(user, target) - if target.pbCanRaiseStatStage?(:ATTACK, user, self) - target.pbRaiseStatStage(:ATTACK, 2, user) - end - target.pbConfuse if target.pbCanConfuse?(user, false, self) - end -end - -#=============================================================================== -# Decreases the target's Attack by 1 stage. -#=============================================================================== -class PokeBattle_Move_042 < PokeBattle_TargetStatDownMove - def initialize(battle, move) - super - @statDown = [:ATTACK, 1] - end -end - -#=============================================================================== -# Decreases the target's Defense by 1 stage. -#=============================================================================== -class PokeBattle_Move_043 < PokeBattle_TargetStatDownMove - def initialize(battle, move) - super - @statDown = [:DEFENSE, 1] - end -end - -#=============================================================================== -# Decreases the target's Speed by 1 stage. -#=============================================================================== -class PokeBattle_Move_044 < PokeBattle_TargetStatDownMove - def initialize(battle, move) - super - @statDown = [:SPEED, 1] - end - - def pbBaseDamage(baseDmg, user, target) - if @id == :BULLDOZE && @battle.field.terrain == :Grassy - baseDmg = (baseDmg / 2.0).round - end - return baseDmg - end -end - -#=============================================================================== -# Decreases the target's Special Attack by 1 stage. -#=============================================================================== -class PokeBattle_Move_045 < PokeBattle_TargetStatDownMove - def initialize(battle, move) - super - @statDown = [:SPECIAL_ATTACK, 1] - end -end - -#=============================================================================== -# Decreases the target's Special Defense by 1 stage. -#=============================================================================== -class PokeBattle_Move_046 < PokeBattle_TargetStatDownMove - def initialize(battle, move) - super - @statDown = [:SPECIAL_DEFENSE, 1] - end -end - -#=============================================================================== -# Decreases the target's accuracy by 1 stage. -#=============================================================================== -class PokeBattle_Move_047 < PokeBattle_TargetStatDownMove - def initialize(battle, move) - super - @statDown = [:ACCURACY, 1] - end -end - -#=============================================================================== -# Decreases the target's evasion by 1 stage OR 2 stages. (Sweet Scent) -#=============================================================================== -class PokeBattle_Move_048 < PokeBattle_TargetStatDownMove - def initialize(battle, move) - super - @statDown = [:EVASION, (Settings::MECHANICS_GENERATION >= 6) ? 2 : 1] - end -end - -#=============================================================================== -# Decreases the target's evasion by 1 stage. Ends all barriers and entry -# hazards for the target's side OR on both sides. (Defog) -#=============================================================================== -class PokeBattle_Move_049 < PokeBattle_TargetStatDownMove - def ignoresSubstitute?(user) - ; return true; - end - - def initialize(battle, move) - super - @statDown = [:EVASION, 1] - end - - def pbFailsAgainstTarget?(user, target) - targetSide = target.pbOwnSide - targetOpposingSide = target.pbOpposingSide - return false if targetSide.effects[PBEffects::AuroraVeil] > 0 || - targetSide.effects[PBEffects::LightScreen] > 0 || - targetSide.effects[PBEffects::Reflect] > 0 || - targetSide.effects[PBEffects::Mist] > 0 || - targetSide.effects[PBEffects::Safeguard] > 0 - return false if targetSide.effects[PBEffects::StealthRock] || - targetSide.effects[PBEffects::Spikes] > 0 || - targetSide.effects[PBEffects::ToxicSpikes] > 0 || - targetSide.effects[PBEffects::StickyWeb] - return false if Settings::MECHANICS_GENERATION >= 6 && - (targetOpposingSide.effects[PBEffects::StealthRock] || - targetOpposingSide.effects[PBEffects::Spikes] > 0 || - targetOpposingSide.effects[PBEffects::ToxicSpikes] > 0 || - targetOpposingSide.effects[PBEffects::StickyWeb]) - return false if Settings::MECHANICS_GENERATION >= 8 && @battle.field.terrain != :None - return super - end - - def pbEffectAgainstTarget(user, target) - if target.pbCanLowerStatStage?(@statDown[0], user, self) - target.pbLowerStatStage(@statDown[0], @statDown[1], user) - end - if target.pbOwnSide.effects[PBEffects::AuroraVeil] > 0 - target.pbOwnSide.effects[PBEffects::AuroraVeil] = 0 - @battle.pbDisplay(_INTL("{1}'s Aurora Veil wore off!", target.pbTeam)) - end - if target.pbOwnSide.effects[PBEffects::LightScreen] > 0 - target.pbOwnSide.effects[PBEffects::LightScreen] = 0 - @battle.pbDisplay(_INTL("{1}'s Light Screen wore off!", target.pbTeam)) - end - if target.pbOwnSide.effects[PBEffects::Reflect] > 0 - target.pbOwnSide.effects[PBEffects::Reflect] = 0 - @battle.pbDisplay(_INTL("{1}'s Reflect wore off!", target.pbTeam)) - end - if target.pbOwnSide.effects[PBEffects::Mist] > 0 - target.pbOwnSide.effects[PBEffects::Mist] = 0 - @battle.pbDisplay(_INTL("{1}'s Mist faded!", target.pbTeam)) - end - if target.pbOwnSide.effects[PBEffects::Safeguard] > 0 - target.pbOwnSide.effects[PBEffects::Safeguard] = 0 - @battle.pbDisplay(_INTL("{1} is no longer protected by Safeguard!!", target.pbTeam)) - end - if target.pbOwnSide.effects[PBEffects::StealthRock] || - (Settings::MECHANICS_GENERATION >= 6 && - target.pbOpposingSide.effects[PBEffects::StealthRock]) - target.pbOwnSide.effects[PBEffects::StealthRock] = false - target.pbOpposingSide.effects[PBEffects::StealthRock] = false if Settings::MECHANICS_GENERATION >= 6 - @battle.pbDisplay(_INTL("{1} blew away stealth rocks!", user.pbThis)) - end - if target.pbOwnSide.effects[PBEffects::Spikes] > 0 || - (Settings::MECHANICS_GENERATION >= 6 && - target.pbOpposingSide.effects[PBEffects::Spikes] > 0) - target.pbOwnSide.effects[PBEffects::Spikes] = 0 - target.pbOpposingSide.effects[PBEffects::Spikes] = 0 if Settings::MECHANICS_GENERATION >= 6 - @battle.pbDisplay(_INTL("{1} blew away spikes!", user.pbThis)) - end - if target.pbOwnSide.effects[PBEffects::ToxicSpikes] > 0 || - (Settings::MECHANICS_GENERATION >= 6 && - target.pbOpposingSide.effects[PBEffects::ToxicSpikes] > 0) - target.pbOwnSide.effects[PBEffects::ToxicSpikes] = 0 - target.pbOpposingSide.effects[PBEffects::ToxicSpikes] = 0 if Settings::MECHANICS_GENERATION >= 6 - @battle.pbDisplay(_INTL("{1} blew away poison spikes!", user.pbThis)) - end - if target.pbOwnSide.effects[PBEffects::StickyWeb] || - (Settings::MECHANICS_GENERATION >= 6 && - target.pbOpposingSide.effects[PBEffects::StickyWeb]) - target.pbOwnSide.effects[PBEffects::StickyWeb] = false - target.pbOpposingSide.effects[PBEffects::StickyWeb] = false if Settings::MECHANICS_GENERATION >= 6 - @battle.pbDisplay(_INTL("{1} blew away sticky webs!", user.pbThis)) - end - if Settings::MECHANICS_GENERATION >= 8 && @battle.field.terrain != :None - case @battle.field.terrain - when :Electric - @battle.pbDisplay(_INTL("The electricity disappeared from the battlefield.")) - when :Grassy - @battle.pbDisplay(_INTL("The grass disappeared from the battlefield.")) - when :Misty - @battle.pbDisplay(_INTL("The mist disappeared from the battlefield.")) - when :Psychic - @battle.pbDisplay(_INTL("The weirdness disappeared from the battlefield.")) - end - @battle.field.terrain = :None - end - end -end - -#=============================================================================== -# Decreases the target's Attack and Defense by 1 stage each. (Tickle) -#=============================================================================== -class PokeBattle_Move_04A < PokeBattle_TargetMultiStatDownMove - def initialize(battle, move) - super - @statDown = [:ATTACK, 1, :DEFENSE, 1] - end -end - -#=============================================================================== -# Decreases the target's Attack by 2 stages. (Charm, Feather Dance) -#=============================================================================== -class PokeBattle_Move_04B < PokeBattle_TargetStatDownMove - def initialize(battle, move) - super - @statDown = [:ATTACK, 2] - end -end - -#=============================================================================== -# Decreases the target's Defense by 2 stages. (Screech) -#=============================================================================== -class PokeBattle_Move_04C < PokeBattle_TargetStatDownMove - def initialize(battle, move) - super - @statDown = [:DEFENSE, 2] - end -end - -#=============================================================================== -# Decreases the target's Speed by 2 stages. (Cotton Spore, Scary Face, String Shot) -#=============================================================================== -class PokeBattle_Move_04D < PokeBattle_TargetStatDownMove - def initialize(battle, move) - super - inc = 2 - inc = 1 if @id == :STRINGSHOT && Settings::MECHANICS_GENERATION <= 5 - @statDown = [:SPEED, inc] - end -end - -#=============================================================================== -# Decreases the target's Special Attack by 2 stages. Only works on the opposite -# gender. (Captivate) -#=============================================================================== -class PokeBattle_Move_04E < PokeBattle_TargetStatDownMove - def initialize(battle, move) - super - @statDown = [:SPECIAL_ATTACK, 2] - end - - def pbFailsAgainstTarget?(user, target) - return true if super - return false if damagingMove? - if user.gender == 2 || target.gender == 2 || user.gender == target.gender - @battle.pbDisplay(_INTL("{1} is unaffected!", target.pbThis)) - return true - end - if target.hasActiveAbility?(:OBLIVIOUS) && !@battle.moldBreaker - @battle.pbShowAbilitySplash(target) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - @battle.pbDisplay(_INTL("{1} is unaffected!", target.pbThis)) - else - @battle.pbDisplay(_INTL("{1}'s {2} prevents romance!", target.pbThis, target.abilityName)) - end - @battle.pbHideAbilitySplash(target) - return true - end - return false - end - - def pbAdditionalEffect(user, target) - return if user.gender == 2 || target.gender == 2 || user.gender == target.gender - return if target.hasActiveAbility?(:OBLIVIOUS) && !@battle.moldBreaker - super - end -end - -#=============================================================================== -# Decreases the target's Special Defense by 2 stages. -#=============================================================================== -class PokeBattle_Move_04F < PokeBattle_TargetStatDownMove - def initialize(battle, move) - super - @statDown = [:SPECIAL_DEFENSE, 2] - end -end - -#=============================================================================== -# Resets all target's stat stages to 0. (Clear Smog) -#=============================================================================== -class PokeBattle_Move_050 < PokeBattle_Move - def pbEffectAgainstTarget(user, target) - if target.damageState.calcDamage > 0 && !target.damageState.substitute && - target.hasAlteredStatStages? - target.pbResetStatStages - @battle.pbDisplay(_INTL("{1}'s stat changes were removed!", target.pbThis)) - end - end -end - -#=============================================================================== -# Resets all stat stages for all battlers to 0. (Haze) -#=============================================================================== -class PokeBattle_Move_051 < PokeBattle_Move - def pbMoveFailed?(user, targets) - failed = true - @battle.eachBattler do |b| - failed = false if b.hasAlteredStatStages? - break if !failed - end - if failed - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - @battle.eachBattler { |b| b.pbResetStatStages } - @battle.pbDisplay(_INTL("All stat changes were eliminated!")) - end -end - -#=============================================================================== -# User and target swap their Attack and Special Attack stat stages. (Power Swap) -#=============================================================================== -class PokeBattle_Move_052 < PokeBattle_Move - def ignoresSubstitute?(user) - ; return true; - end - - def pbEffectAgainstTarget(user, target) - [:ATTACK, :SPECIAL_ATTACK].each do |s| - user.stages[s], target.stages[s] = target.stages[s], user.stages[s] - end - @battle.pbDisplay(_INTL("{1} switched all changes to its Attack and Sp. Atk with the target!", user.pbThis)) - end -end - -#=============================================================================== -# User and target swap their Defense and Special Defense stat stages. (Guard Swap) -#=============================================================================== -class PokeBattle_Move_053 < PokeBattle_Move - def ignoresSubstitute?(user) - ; return true; - end - - def pbEffectAgainstTarget(user, target) - [:DEFENSE, :SPECIAL_DEFENSE].each do |s| - user.stages[s], target.stages[s] = target.stages[s], user.stages[s] - end - @battle.pbDisplay(_INTL("{1} switched all changes to its Defense and Sp. Def with the target!", user.pbThis)) - end -end - -#=============================================================================== -# User and target swap all their stat stages. (Heart Swap) -#=============================================================================== -class PokeBattle_Move_054 < PokeBattle_Move - def ignoresSubstitute?(user) - ; return true; - end - - def pbEffectAgainstTarget(user, target) - GameData::Stat.each_battle do |s| - user.stages[s.id], target.stages[s.id] = target.stages[s.id], user.stages[s.id] - end - @battle.pbDisplay(_INTL("{1} switched stat changes with the target!", user.pbThis)) - end -end - -#=============================================================================== -# User copies the target's stat stages. (Psych Up) -#=============================================================================== -class PokeBattle_Move_055 < PokeBattle_Move - def ignoresSubstitute?(user) - ; return true; - end - - def pbEffectAgainstTarget(user, target) - GameData::Stat.each_battle { |s| user.stages[s.id] = target.stages[s.id] } - if Settings::NEW_CRITICAL_HIT_RATE_MECHANICS - user.effects[PBEffects::FocusEnergy] = target.effects[PBEffects::FocusEnergy] - user.effects[PBEffects::LaserFocus] = target.effects[PBEffects::LaserFocus] - end - @battle.pbDisplay(_INTL("{1} copied {2}'s stat changes!", user.pbThis, target.pbThis(true))) - end -end - -#=============================================================================== -# For 5 rounds, user's and ally's stat stages cannot be lowered by foes. (Mist) -#=============================================================================== -class PokeBattle_Move_056 < PokeBattle_Move - def pbMoveFailed?(user, targets) - if user.pbOwnSide.effects[PBEffects::Mist] > 0 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - user.pbOwnSide.effects[PBEffects::Mist] = 5 - @battle.pbDisplay(_INTL("{1} became shrouded in mist!", user.pbTeam)) - end -end - -#=============================================================================== -# Swaps the user's Attack and Defense stats. (Power Trick) -#=============================================================================== -class PokeBattle_Move_057 < PokeBattle_Move - def pbEffectGeneral(user) - user.attack, user.defense = user.defense, user.attack - user.effects[PBEffects::PowerTrick] = !user.effects[PBEffects::PowerTrick] - @battle.pbDisplay(_INTL("{1} switched its Attack and Defense!", user.pbThis)) - end -end - -#=============================================================================== -# Averages the user's and target's Attack. -# Averages the user's and target's Special Attack. (Power Split) -#=============================================================================== -class PokeBattle_Move_058 < PokeBattle_Move - def pbEffectAgainstTarget(user, target) - newatk = ((user.attack + target.attack) / 2).floor - newspatk = ((user.spatk + target.spatk) / 2).floor - user.attack = target.attack = newatk - user.spatk = target.spatk = newspatk - @battle.pbDisplay(_INTL("{1} shared its power with the target!", user.pbThis)) - end -end - -#=============================================================================== -# Averages the user's and target's Defense. -# Averages the user's and target's Special Defense. (Guard Split) -#=============================================================================== -class PokeBattle_Move_059 < PokeBattle_Move - def pbEffectAgainstTarget(user, target) - newdef = ((user.defense + target.defense) / 2).floor - newspdef = ((user.spdef + target.spdef) / 2).floor - user.defense = target.defense = newdef - user.spdef = target.spdef = newspdef - @battle.pbDisplay(_INTL("{1} shared its guard with the target!", user.pbThis)) - end -end - -#=============================================================================== -# Averages the user's and target's current HP. (Pain Split) -#=============================================================================== -class PokeBattle_Move_05A < PokeBattle_Move - def pbEffectAgainstTarget(user, target) - newHP = (user.hp + target.hp) / 2 - if user.hp > newHP; - user.pbReduceHP(user.hp - newHP, false, false) - elsif user.hp < newHP; - user.pbRecoverHP(newHP - user.hp, false) - end - if target.hp > newHP; - target.pbReduceHP(target.hp - newHP, false, false) - elsif target.hp < newHP; - target.pbRecoverHP(newHP - target.hp, false) - end - @battle.pbDisplay(_INTL("The battlers shared their pain!")) - user.pbItemHPHealCheck - target.pbItemHPHealCheck - end -end - -#=============================================================================== -# For 4 rounds, doubles the Speed of all battlers on the user's side. (Tailwind) -#=============================================================================== -class PokeBattle_Move_05B < PokeBattle_Move - def pbMoveFailed?(user, targets) - if user.pbOwnSide.effects[PBEffects::Tailwind] > 0 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - user.pbOwnSide.effects[PBEffects::Tailwind] = 4 - @battle.pbDisplay(_INTL("The Tailwind blew from behind {1}!", user.pbTeam(true))) - end -end - -#=============================================================================== -# This move turns into the last move used by the target, until user switches -# out. (Mimic) -#=============================================================================== -class PokeBattle_Move_05C < PokeBattle_Move - def ignoresSubstitute?(user) - ; return true; - end - - def initialize(battle, move) - super - @moveBlacklist = [ - "014", # Chatter - "0B6", # Metronome - # Struggle - "002", # Struggle - # Moves that affect the moveset - "05C", # Mimic - "05D", # Sketch - "069" # Transform - ] - end - - def pbMoveFailed?(user, targets) - if user.effects[PBEffects::Transform] || !user.pbHasMove?(@id) - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbFailsAgainstTarget?(user, target) - lastMoveData = GameData::Move.try_get(target.lastRegularMoveUsed) - if !lastMoveData || - user.pbHasMove?(target.lastRegularMoveUsed) || - @moveBlacklist.include?(lastMoveData.function_code) || - lastMoveData.type == :SHADOW - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectAgainstTarget(user, target) - user.eachMoveWithIndex do |m, i| - next if m.id != @id - newMove = Pokemon::Move.new(target.lastRegularMoveUsed) - user.moves[i] = PokeBattle_Move.from_pokemon_move(@battle, newMove) - @battle.pbDisplay(_INTL("{1} learned {2}!", user.pbThis, newMove.name)) - user.pbCheckFormOnMovesetChange - break - end - end -end - -#=============================================================================== -# This move permanently turns into the last move used by the target. (Sketch) -#=============================================================================== -class PokeBattle_Move_05D < PokeBattle_Move - def ignoresSubstitute?(user) - ; return true; - end - - def initialize(battle, move) - super - @moveBlacklist = [ - "014", # Chatter - "05D", # Sketch (this move) - # Struggle - "002" # Struggle - ] - end - - def pbMoveFailed?(user, targets) - if user.effects[PBEffects::Transform] || !user.pbHasMove?(@id) - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbFailsAgainstTarget?(user, target) - lastMoveData = GameData::Move.try_get(target.lastRegularMoveUsed) - if !lastMoveData || - user.pbHasMove?(target.lastRegularMoveUsed) || - @moveBlacklist.include?(lastMoveData.function_code) || - lastMoveData.type == :SHADOW - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectAgainstTarget(user, target) - user.eachMoveWithIndex do |m, i| - next if m.id != @id - newMove = Pokemon::Move.new(target.lastRegularMoveUsed) - user.pokemon.moves[i] = newMove - user.moves[i] = PokeBattle_Move.from_pokemon_move(@battle, newMove) - @battle.pbDisplay(_INTL("{1} learned {2}!", user.pbThis, newMove.name)) - user.pbCheckFormOnMovesetChange - break - end - end -end - -#=============================================================================== -# Changes user's type to that of a random user's move, except a type the user -# already has (even partially), OR changes to the user's first move's type. -# (Conversion) -#=============================================================================== -class PokeBattle_Move_05E < PokeBattle_Move - def pbMoveFailed?(user, targets) - if !user.canChangeType? - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - userTypes = user.pbTypes(true) - @newTypes = [] - user.eachMoveWithIndex do |m, i| - break if Settings::MECHANICS_GENERATION >= 6 && i > 0 - next if GameData::Type.get(m.type).pseudo_type - next if userTypes.include?(m.type) - @newTypes.push(m.type) if !@newTypes.include?(m.type) - end - if @newTypes.length == 0 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - newType = @newTypes[@battle.pbRandom(@newTypes.length)] - user.pbChangeTypes(newType) - typeName = GameData::Type.get(newType).name - @battle.pbDisplay(_INTL("{1} transformed into the {2} type!", user.pbThis, typeName)) - end -end - -#=============================================================================== -# Changes user's type to a random one that resists/is immune to the last move -# used by the target. (Conversion 2) -#=============================================================================== -class PokeBattle_Move_05F < PokeBattle_Move - def ignoresSubstitute?(user) - ; return true; - end - - def pbMoveFailed?(user, targets) - if !user.canChangeType? - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbFailsAgainstTarget?(user, target) - if !target.lastMoveUsed || !target.lastMoveUsedType || - GameData::Type.get(target.lastMoveUsedType).pseudo_type - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - @newTypes = [] - GameData::Type.each do |t| - next if t.pseudo_type || user.pbHasType?(t.id) || - !Effectiveness.resistant_type?(target.lastMoveUsedType, t.id) - @newTypes.push(t.id) - end - if @newTypes.length == 0 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - newType = @newTypes[@battle.pbRandom(@newTypes.length)] - user.pbChangeTypes(newType) - typeName = GameData::Type.get(newType).name - @battle.pbDisplay(_INTL("{1} transformed into the {2} type!", user.pbThis, typeName)) - end -end - -#=============================================================================== -# Changes user's type depending on the environment. (Camouflage) -#=============================================================================== -class PokeBattle_Move_060 < PokeBattle_Move - def pbMoveFailed?(user, targets) - if !user.canChangeType? - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - @newType = :NORMAL - checkedTerrain = false - case @battle.field.terrain - when :Electric - if GameData::Type.exists?(:ELECTRIC) - @newType = :ELECTRIC - checkedTerrain = true - end - when :Grassy - if GameData::Type.exists?(:GRASS) - @newType = :GRASS - checkedTerrain = true - end - when :Misty - if GameData::Type.exists?(:FAIRY) - @newType = :FAIRY - checkedTerrain = true - end - when :Psychic - if GameData::Type.exists?(:PSYCHIC) - @newType = :PSYCHIC - checkedTerrain = true - end - end - if !checkedTerrain - case @battle.environment - when :Grass, :TallGrass, :Grass_alt1,:Grass_alt2,:Grass_alt3, - @newType = :GRASS - when :MovingWater, :StillWater, :Puddle, :Underwater - @newType = :WATER - when :Cave - @newType = :ROCK - when :Rock, :Sand - @newType = :GROUND - when :Forest, :ForestGrass - @newType = :BUG - when :Snow, :Ice - @newType = :ICE - when :Volcano - @newType = :FIRE - when :Graveyard - @newType = :GHOST - when :Sky - @newType = :FLYING - when :Space - @newType = :DRAGON - when :UltraSpace - @newType = :PSYCHIC - end - end - @newType = :NORMAL if !GameData::Type.exists?(@newType) - if !GameData::Type.exists?(@newType) || !user.pbHasOtherType?(@newType) - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - user.pbChangeTypes(@newType) - typeName = GameData::Type.get(@newType).name - @battle.pbDisplay(_INTL("{1} transformed into the {2} type!", user.pbThis, typeName)) - end -end - -#=============================================================================== -# Target becomes Water type. (Soak) -#=============================================================================== -class PokeBattle_Move_061 < PokeBattle_Move - def pbFailsAgainstTarget?(user, target) - if !target.canChangeType? || !GameData::Type.exists?(:WATER) || - !target.pbHasOtherType?(:WATER) - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectAgainstTarget(user, target) - target.pbChangeTypes(:WATER) - typeName = GameData::Type.get(:WATER).name - @battle.pbDisplay(_INTL("{1} transformed into the {2} type!", target.pbThis, typeName)) - end -end - -#=============================================================================== -# User copes target's types. (Reflect Type) -#=============================================================================== -class PokeBattle_Move_062 < PokeBattle_Move - def ignoresSubstitute?(user) - ; return true; - end - - def pbMoveFailed?(user, targets) - if !user.canChangeType? - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbFailsAgainstTarget?(user, target) - newTypes = target.pbTypes(true) - if newTypes.length == 0 # Target has no type to copy - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - if user.pbTypes == target.pbTypes && - user.effects[PBEffects::Type3] == target.effects[PBEffects::Type3] - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectAgainstTarget(user, target) - user.pbChangeTypes(target) - @battle.pbDisplay(_INTL("{1}'s type changed to match {2}'s!", - user.pbThis, target.pbThis(true))) - end -end - -#=============================================================================== -# Target's ability becomes Simple. (Simple Beam) -#=============================================================================== -class PokeBattle_Move_063 < PokeBattle_Move - def pbMoveFailed?(user, targets) - if !GameData::Ability.exists?(:SIMPLE) - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbFailsAgainstTarget?(user, target) - if target.unstoppableAbility? || [:TRUANT, :SIMPLE].include?(target.ability) - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectAgainstTarget(user, target) - @battle.pbShowAbilitySplash(target, true, false) - oldAbil = target.ability - target.ability = :SIMPLE - @battle.pbReplaceAbilitySplash(target) - @battle.pbDisplay(_INTL("{1} acquired {2}!", target.pbThis, target.abilityName)) - @battle.pbHideAbilitySplash(target) - target.pbOnAbilityChanged(oldAbil) - end -end - -#=============================================================================== -# Target's ability becomes Insomnia. (Worry Seed) -#=============================================================================== -class PokeBattle_Move_064 < PokeBattle_Move - def pbMoveFailed?(user, targets) - if !GameData::Ability.exists?(:INSOMNIA) - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbFailsAgainstTarget?(user, target) - if target.unstoppableAbility? || [:TRUANT, :INSOMNIA].include?(target.ability_id) - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectAgainstTarget(user, target) - @battle.pbShowAbilitySplash(target, true, false) - oldAbil = target.ability - target.ability = :INSOMNIA - @battle.pbReplaceAbilitySplash(target) - @battle.pbDisplay(_INTL("{1} acquired {2}!", target.pbThis, target.abilityName)) - @battle.pbHideAbilitySplash(target) - target.pbOnAbilityChanged(oldAbil) - end -end - -#=============================================================================== -# User copies target's ability. (Role Play) -#=============================================================================== -class PokeBattle_Move_065 < PokeBattle_Move - def ignoresSubstitute?(user) - ; return true; - end - - def pbMoveFailed?(user, targets) - if user.unstoppableAbility? - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbFailsAgainstTarget?(user, target) - if !target.ability || user.ability == target.ability - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - if target.ungainableAbility? || - [:POWEROFALCHEMY, :RECEIVER, :TRACE, :WONDERGUARD].include?(target.ability_id) - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectAgainstTarget(user, target) - @battle.pbShowAbilitySplash(user, true, false) - oldAbil = user.ability - user.ability = target.ability - @battle.pbReplaceAbilitySplash(user) - @battle.pbDisplay(_INTL("{1} copied {2}'s {3}!", - user.pbThis, target.pbThis(true), target.abilityName)) - @battle.pbHideAbilitySplash(user) - user.pbOnAbilityChanged(oldAbil) - user.pbEffectsOnSwitchIn - end -end - -#=============================================================================== -# Target copies user's ability. (Entrainment) -#=============================================================================== -class PokeBattle_Move_066 < PokeBattle_Move - def pbMoveFailed?(user, targets) - if !user.ability - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - if user.ungainableAbility? || - [:POWEROFALCHEMY, :RECEIVER, :TRACE].include?(user.ability_id) - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbFailsAgainstTarget?(user, target) - if target.unstoppableAbility? || target.ability == :TRUANT - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectAgainstTarget(user, target) - @battle.pbShowAbilitySplash(target, true, false) - oldAbil = target.ability - target.ability = user.ability - @battle.pbReplaceAbilitySplash(target) - @battle.pbDisplay(_INTL("{1} acquired {2}!", target.pbThis, target.abilityName)) - @battle.pbHideAbilitySplash(target) - target.pbOnAbilityChanged(oldAbil) - target.pbEffectsOnSwitchIn - end -end - -#=============================================================================== -# User and target swap abilities. (Skill Swap) -#=============================================================================== -class PokeBattle_Move_067 < PokeBattle_Move - def ignoresSubstitute?(user) - ; return true; - end - - def pbMoveFailed?(user, targets) - if !user.ability - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - if user.unstoppableAbility? - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - if user.ungainableAbility? || user.ability == :WONDERGUARD - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbFailsAgainstTarget?(user, target) - if !target.ability || - (user.ability == target.ability && Settings::MECHANICS_GENERATION <= 5) - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - if target.unstoppableAbility? - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - if target.ungainableAbility? || target.ability == :WONDERGUARD - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectAgainstTarget(user, target) - if user.opposes?(target) - @battle.pbShowAbilitySplash(user, false, false) - @battle.pbShowAbilitySplash(target, true, false) - end - oldUserAbil = user.ability - oldTargetAbil = target.ability - user.ability = oldTargetAbil - target.ability = oldUserAbil - if user.opposes?(target) - @battle.pbReplaceAbilitySplash(user) - @battle.pbReplaceAbilitySplash(target) - end - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - @battle.pbDisplay(_INTL("{1} swapped Abilities with its target!", user.pbThis)) - else - @battle.pbDisplay(_INTL("{1} swapped its {2} Ability with its target's {3} Ability!", - user.pbThis, target.abilityName, user.abilityName)) - end - if user.opposes?(target) - @battle.pbHideAbilitySplash(user) - @battle.pbHideAbilitySplash(target) - end - user.pbOnAbilityChanged(oldUserAbil) - target.pbOnAbilityChanged(oldTargetAbil) - user.pbEffectsOnSwitchIn - target.pbEffectsOnSwitchIn - end -end - -#=============================================================================== -# Target's ability is negated. (Gastro Acid) -#=============================================================================== -class PokeBattle_Move_068 < PokeBattle_Move - def pbFailsAgainstTarget?(user, target) - if target.unstoppableAbility? - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectAgainstTarget(user, target) - target.effects[PBEffects::GastroAcid] = true - target.effects[PBEffects::Truant] = false - @battle.pbDisplay(_INTL("{1}'s Ability was suppressed!", target.pbThis)) - target.pbOnAbilityChanged(target.ability) - end -end - -#=============================================================================== -# User transforms into the target. (Transform) -#=============================================================================== -class PokeBattle_Move_069 < PokeBattle_Move - def pbMoveFailed?(user, targets) - if user.effects[PBEffects::Transform] - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbFailsAgainstTarget?(user, target) - if target.effects[PBEffects::Transform] || - target.effects[PBEffects::Illusion] - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectAgainstTarget(user, target) - user.pbTransform(target) - end - - def pbShowAnimation(id, user, targets, hitNum = 0, showAnimation = true) - super - @battle.scene.pbChangePokemon(user, targets[0].pokemon) - end -end - -#=============================================================================== -# Inflicts a fixed 20HP damage. (Sonic Boom) -#=============================================================================== -class PokeBattle_Move_06A < PokeBattle_FixedDamageMove - def pbFixedDamage(user, target) - return 20 - end -end - -#=============================================================================== -# Inflicts a fixed 40HP damage. (Dragon Rage) -#=============================================================================== -class PokeBattle_Move_06B < PokeBattle_FixedDamageMove - def pbFixedDamage(user, target) - return 40 - end -end - -#=============================================================================== -# Halves the target's current HP. (Nature's Madness, Super Fang) -#=============================================================================== -class PokeBattle_Move_06C < PokeBattle_FixedDamageMove - def pbFixedDamage(user, target) - return (target.hp / 2.0).round - end -end - -#=============================================================================== -# Inflicts damage equal to the user's level. (Night Shade, Seismic Toss) -#=============================================================================== -class PokeBattle_Move_06D < PokeBattle_FixedDamageMove - def pbFixedDamage(user, target) - return user.level - end -end - -#=============================================================================== -# Inflicts damage to bring the target's HP down to equal the user's HP. (Endeavor) -#=============================================================================== -class PokeBattle_Move_06E < PokeBattle_FixedDamageMove - def pbFailsAgainstTarget?(user, target) - if user.hp >= target.hp - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbNumHits(user, targets) - ; return 1; - end - - def pbFixedDamage(user, target) - return target.hp - user.hp - end -end - -#=============================================================================== -# Inflicts damage between 0.5 and 1.5 times the user's level. (Psywave) -#=============================================================================== -class PokeBattle_Move_06F < PokeBattle_FixedDamageMove - def pbFixedDamage(user, target) - min = (user.level / 2).floor - max = (user.level * 3 / 2).floor - return min + @battle.pbRandom(max - min + 1) - end -end - -#=============================================================================== -# OHKO. Accuracy increases by difference between levels of user and target. -#=============================================================================== -class PokeBattle_Move_070 < PokeBattle_FixedDamageMove - def hitsDiggingTargets? - return @id == :FISSURE; - end - - def pbFailsAgainstTarget?(user, target) - if target.level > user.level - @battle.pbDisplay(_INTL("{1} is unaffected!", target.pbThis)) - return true - end - if target.hasActiveAbility?(:STURDY) && !@battle.moldBreaker - @battle.pbShowAbilitySplash(target) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - @battle.pbDisplay(_INTL("But it failed to affect {1}!", target.pbThis(true))) - else - @battle.pbDisplay(_INTL("But it failed to affect {1} because of its {2}!", - target.pbThis(true), target.abilityName)) - end - @battle.pbHideAbilitySplash(target) - return true - end - if Settings::MECHANICS_GENERATION >= 7 && @id == :SHEERCOLD && target.pbHasType?(:ICE) - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbAccuracyCheck(user, target) - acc = @accuracy + user.level - target.level - acc -= 10 if Settings::MECHANICS_GENERATION >= 7 && @id == :SHEERCOLD && !user.pbHasType?(:ICE) - return @battle.pbRandom(100) < acc - end - - def pbFixedDamage(user, target) - return target.totalhp - end - - def pbHitEffectivenessMessages(user, target, numTargets = 1) - super - if target.fainted? - @battle.pbDisplay(_INTL("It's a one-hit KO!")) - end - end -end - -#=============================================================================== -# Counters a physical move used against the user this round, with 2x the power. -# (Counter) -#=============================================================================== -class PokeBattle_Move_071 < PokeBattle_FixedDamageMove - def pbAddTarget(targets, user) - t = user.effects[PBEffects::CounterTarget] - return if t < 0 || !user.opposes?(t) - user.pbAddTarget(targets, user, @battle.battlers[t], self, false) - end - - def pbMoveFailed?(user, targets) - if targets.length == 0 - @battle.pbDisplay(_INTL("But there was no target...")) - return true - end - return false - end - - def pbFixedDamage(user, target) - dmg = user.effects[PBEffects::Counter] * 2 - dmg = 1 if dmg == 0 - return dmg - end -end - -#=============================================================================== -# Counters a specical move used against the user this round, with 2x the power. -# (Mirror Coat) -#=============================================================================== -class PokeBattle_Move_072 < PokeBattle_FixedDamageMove - def pbAddTarget(targets, user) - t = user.effects[PBEffects::MirrorCoatTarget] - return if t < 0 || !user.opposes?(t) - user.pbAddTarget(targets, user, @battle.battlers[t], self, false) - end - - def pbMoveFailed?(user, targets) - if targets.length == 0 - @battle.pbDisplay(_INTL("But there was no target...")) - return true - end - return false - end - - def pbFixedDamage(user, target) - dmg = user.effects[PBEffects::MirrorCoat] * 2 - dmg = 1 if dmg == 0 - return dmg - end -end - -#=============================================================================== -# Counters the last damaging move used against the user this round, with 1.5x -# the power. (Metal Burst) -#=============================================================================== -class PokeBattle_Move_073 < PokeBattle_FixedDamageMove - def pbAddTarget(targets, user) - return if user.lastFoeAttacker.length == 0 - lastAttacker = user.lastFoeAttacker.last - return if lastAttacker < 0 || !user.opposes?(lastAttacker) - user.pbAddTarget(targets, user, @battle.battlers[lastAttacker], self, false) - end - - def pbMoveFailed?(user, targets) - if targets.length == 0 - @battle.pbDisplay(_INTL("But there was no target...")) - return true - end - return false - end - - def pbFixedDamage(user, target) - dmg = (user.lastHPLostFromFoe * 1.5).floor - dmg = 1 if dmg == 0 - return dmg - end -end - -#=============================================================================== -# The target's ally loses 1/16 of its max HP. (Flame Burst) -#=============================================================================== -class PokeBattle_Move_074 < PokeBattle_Move - def pbEffectWhenDealingDamage(user, target) - hitAlly = [] - target.eachAlly do |b| - next if !b.near?(target.index) - next if !b.takesIndirectDamage? - hitAlly.push([b.index, b.hp]) - b.pbReduceHP(b.totalhp / 16, false) - end - if hitAlly.length == 2 - @battle.pbDisplay(_INTL("The bursting flame hit {1} and {2}!", - @battle.battlers[hitAlly[0][0]].pbThis(true), - @battle.battlers[hitAlly[1][0]].pbThis(true))) - elsif hitAlly.length > 0 - hitAlly.each do |b| - @battle.pbDisplay(_INTL("The bursting flame hit {1}!", - @battle.battlers[b[0]].pbThis(true))) - end - end - switchedAlly = [] - hitAlly.each do |b| - @battle.battlers[b[0]].pbItemHPHealCheck - if @battle.battlers[b[0]].pbAbilitiesOnDamageTaken(b[1]) - switchedAlly.push(@battle.battlers[b[0]]) - end - end - switchedAlly.each { |b| b.pbEffectsOnSwitchIn(true) } - end -end - -#=============================================================================== -# Power is doubled if the target is using Dive. Hits some semi-invulnerable -# targets. (Surf) -#=============================================================================== -class PokeBattle_Move_075 < PokeBattle_Move - def hitsDivingTargets? - return true; - end - - def pbModifyDamage(damageMult, user, target) - damageMult *= 2 if target.inTwoTurnAttack?("0CB") # Dive - return damageMult - end -end - -#=============================================================================== -# Power is doubled if the target is using Dig. Power is halved if Grassy Terrain -# is in effect. Hits some semi-invulnerable targets. (Earthquake) -#=============================================================================== -class PokeBattle_Move_076 < PokeBattle_Move - def hitsDiggingTargets? - return true; - end - - def pbModifyDamage(damageMult, user, target) - damageMult *= 2 if target.inTwoTurnAttack?("0CA") # Dig - damageMult /= 2 if @battle.field.terrain == :Grassy - return damageMult - end -end - -#=============================================================================== -# Power is doubled if the target is using Bounce, Fly or Sky Drop. Hits some -# semi-invulnerable targets. (Gust) -#=============================================================================== -class PokeBattle_Move_077 < PokeBattle_Move - def hitsFlyingTargets? - return true; - end - - def pbBaseDamage(baseDmg, user, target) - baseDmg *= 2 if target.inTwoTurnAttack?("0C9", "0CC", "0CE") || # Fly/Bounce/Sky Drop - target.effects[PBEffects::SkyDrop] >= 0 - return baseDmg - end -end - -#=============================================================================== -# Power is doubled if the target is using Bounce, Fly or Sky Drop. Hits some -# semi-invulnerable targets. May make the target flinch. (Twister) -#=============================================================================== -class PokeBattle_Move_078 < PokeBattle_FlinchMove - def hitsFlyingTargets? - return true; - end - - def pbBaseDamage(baseDmg, user, target) - baseDmg *= 2 if target.inTwoTurnAttack?("0C9", "0CC", "0CE") || # Fly/Bounce/Sky Drop - target.effects[PBEffects::SkyDrop] >= 0 - return baseDmg - end -end - -#=============================================================================== -# Power is doubled if Fusion Flare has already been used this round. (Fusion Bolt) -#=============================================================================== -class PokeBattle_Move_079 < PokeBattle_Move - def pbChangeUsageCounters(user, specialUsage) - @doublePower = @battle.field.effects[PBEffects::FusionFlare] - super - end - - def pbBaseDamageMultiplier(damageMult, user, target) - damageMult *= 2 if @doublePower - return damageMult - end - - def pbEffectGeneral(user) - @battle.field.effects[PBEffects::FusionBolt] = true - end - - def pbShowAnimation(id, user, targets, hitNum = 0, showAnimation = true) - hitNum = 1 if (targets.length > 0 && targets[0].damageState.critical) || - @doublePower # Charged anim - super - end -end - -#=============================================================================== -# Power is doubled if Fusion Bolt has already been used this round. (Fusion Flare) -#=============================================================================== -class PokeBattle_Move_07A < PokeBattle_Move - def pbChangeUsageCounters(user, specialUsage) - @doublePower = @battle.field.effects[PBEffects::FusionBolt] - super - end - - def pbBaseDamageMultiplier(damageMult, user, target) - damageMult *= 2 if @doublePower - return damageMult - end - - def pbEffectGeneral(user) - @battle.field.effects[PBEffects::FusionFlare] = true - end - - def pbShowAnimation(id, user, targets, hitNum = 0, showAnimation = true) - hitNum = 1 if (targets.length > 0 && targets[0].damageState.critical) || - @doublePower # Charged anim - super - end -end - -#=============================================================================== -# Power is doubled if the target is poisoned. (Venoshock) -#=============================================================================== -class PokeBattle_Move_07B < PokeBattle_Move - def pbBaseDamage(baseDmg, user, target) - if target.poisoned? && - (target.effects[PBEffects::Substitute] == 0 || ignoresSubstitute?(user)) - baseDmg *= 2 - end - return baseDmg - end -end - -#=============================================================================== -# Power is doubled if the target is paralyzed. Cures the target of paralysis. -# (Smelling Salts) -#=============================================================================== -class PokeBattle_Move_07C < PokeBattle_Move - def pbBaseDamage(baseDmg, user, target) - if target.paralyzed? && - (target.effects[PBEffects::Substitute] == 0 || ignoresSubstitute?(user)) - baseDmg *= 2 - end - return baseDmg - end - - def pbEffectAfterAllHits(user, target) - return if target.fainted? - return if target.damageState.unaffected || target.damageState.substitute - return if target.status != :PARALYSIS - target.pbCureStatus - end -end - -#=============================================================================== -# Power is doubled if the target is asleep. Wakes the target up. (Wake-Up Slap) -#=============================================================================== -class PokeBattle_Move_07D < PokeBattle_Move - def pbBaseDamage(baseDmg, user, target) - if target.asleep? && - (target.effects[PBEffects::Substitute] == 0 || ignoresSubstitute?(user)) - baseDmg *= 2 - end - return baseDmg - end - - def pbEffectAfterAllHits(user, target) - return if target.fainted? - return if target.damageState.unaffected || target.damageState.substitute - return if target.status != :SLEEP - target.pbCureStatus - end -end - -#=============================================================================== -# Power is doubled if the user is burned, poisoned or paralyzed. (Facade) -# Burn's halving of Attack is negated (new mechanics). -#=============================================================================== -class PokeBattle_Move_07E < PokeBattle_Move - def damageReducedByBurn? - return Settings::MECHANICS_GENERATION <= 5; - end - - def pbBaseDamage(baseDmg, user, target) - baseDmg *= 2 if user.poisoned? || user.burned? || user.paralyzed? - return baseDmg - end -end - -#=============================================================================== -# Power is doubled if the target has a status problem. (Hex) -#=============================================================================== -class PokeBattle_Move_07F < PokeBattle_Move - def pbBaseDamage(baseDmg, user, target) - if target.pbHasAnyStatus? && - (target.effects[PBEffects::Substitute] == 0 || ignoresSubstitute?(user)) - baseDmg *= 2 - end - return baseDmg - end -end - -################# -# Fusion Swap -# ############### -# class PokeBattle_Move_XXX < PokeBattle_Move -# def pbMoveFailed?(user,targets) -# if targets[0].effects[PBEffects::Transform] -# @battle.pbDisplay(_INTL("But it failed!")) -# return true -# end -# return false -# end -# -# def pbFailsAgainstTarget?(user,target) -# if target.effects[PBEffects::Transform] || -# target.effects[PBEffects::Illusion] || -# !target.pokemon.isFusion? -# @battle.pbDisplay(_INTL("But it failed!")) -# return true -# end -# return false -# end -# -# def pbEffectAgainstTarget(user,target) -# body = getBasePokemonID(target.pokemon.species, true) -# head = getBasePokemonID(target.pokemon.species, false) -# newspecies = (head) * Settings::NB_POKEMON + body -# target.pbTransform(newspecies) -# end -# -# def pbShowAnimation(id,user,targets,hitNum=0,showAnimation=true) -# super -# @battle.scene.pbChangePokemon(user,targets[0].pokemon) -# end -# end diff --git a/Data/Scripts/011_Battle/002_Move/006_Move_Effects_080-0FF.rb b/Data/Scripts/011_Battle/002_Move/006_Move_Effects_080-0FF.rb deleted file mode 100644 index 1dca76cc8..000000000 --- a/Data/Scripts/011_Battle/002_Move/006_Move_Effects_080-0FF.rb +++ /dev/null @@ -1,3723 +0,0 @@ -#=============================================================================== -# Power is doubled if the target's HP is down to 1/2 or less. (Brine) -#=============================================================================== -class PokeBattle_Move_080 < PokeBattle_Move - def pbBaseDamage(baseDmg,user,target) - baseDmg *= 2 if target.hp<=target.totalhp/2 - return baseDmg - end -end - - - -#=============================================================================== -# Power is doubled if the user has lost HP due to the target's move this round. -# (Avalanche, Revenge) -#=============================================================================== -class PokeBattle_Move_081 < PokeBattle_Move - def pbBaseDamage(baseDmg,user,target) - baseDmg *= 2 if user.lastAttacker.include?(target.index) - return baseDmg - end -end - - - -#=============================================================================== -# Power is doubled if the target has already lost HP this round. (Assurance) -#=============================================================================== -class PokeBattle_Move_082 < PokeBattle_Move - def pbBaseDamage(baseDmg,user,target) - baseDmg *= 2 if target.tookDamage - return baseDmg - end -end - - - -#=============================================================================== -# Power is doubled if a user's ally has already used this move this round. (Round) -# If an ally is about to use the same move, make it go next, ignoring priority. -#=============================================================================== -class PokeBattle_Move_083 < PokeBattle_Move - def pbBaseDamage(baseDmg,user,target) - baseDmg *= 2 if user.pbOwnSide.effects[PBEffects::Round] - return baseDmg - end - - def pbEffectGeneral(user) - user.pbOwnSide.effects[PBEffects::Round] = true - user.eachAlly do |b| - next if @battle.choices[b.index][0]!=:UseMove || b.movedThisRound? - next if @battle.choices[b.index][2].function!=@function - b.effects[PBEffects::MoveNext] = true - b.effects[PBEffects::Quash] = 0 - break - end - end -end - - - -#=============================================================================== -# Power is doubled if the target has already moved this round. (Payback) -#=============================================================================== -class PokeBattle_Move_084 < PokeBattle_Move - def pbBaseDamage(baseDmg,user,target) - if @battle.choices[target.index][0]!=:None && - ((@battle.choices[target.index][0]!=:UseMove && - @battle.choices[target.index][0]!=:Shift) || target.movedThisRound?) - baseDmg *= 2 - end - return baseDmg - end -end - - - -#=============================================================================== -# Power is doubled if a user's teammate fainted last round. (Retaliate) -#=============================================================================== -class PokeBattle_Move_085 < PokeBattle_Move - def pbBaseDamage(baseDmg,user,target) - lrf = user.pbOwnSide.effects[PBEffects::LastRoundFainted] - baseDmg *= 2 if lrf>=0 && lrf==@battle.turnCount-1 - return baseDmg - end -end - - - -#=============================================================================== -# Power is doubled if the user has no held item. (Acrobatics) -#=============================================================================== -class PokeBattle_Move_086 < PokeBattle_Move - def pbBaseDamageMultiplier(damageMult,user,target) - damageMult *= 2 if !user.item - return damageMult - end -end - - - -#=============================================================================== -# Power is doubled in weather. Type changes depending on the weather. (Weather Ball) -#=============================================================================== -class PokeBattle_Move_087 < PokeBattle_Move - def pbBaseDamage(baseDmg,user,target) - baseDmg *= 2 if @battle.pbWeather != :None - return baseDmg - end - - def pbBaseType(user) - ret = :NORMAL - case @battle.pbWeather - when :Sun, :HarshSun - ret = :FIRE if GameData::Type.exists?(:FIRE) - when :Rain, :HeavyRain - ret = :WATER if GameData::Type.exists?(:WATER) - when :Sandstorm - ret = :ROCK if GameData::Type.exists?(:ROCK) - when :Hail - ret = :ICE if GameData::Type.exists?(:ICE) - end - return ret - end - - def pbShowAnimation(id,user,targets,hitNum=0,showAnimation=true) - t = pbBaseType(user) - hitNum = 1 if t == :FIRE # Type-specific anims - hitNum = 2 if t == :WATER - hitNum = 3 if t == :ROCK - hitNum = 4 if t == :ICE - super - end -end - - - -#=============================================================================== -# Interrupts a foe switching out or using U-turn/Volt Switch/Parting Shot. Power -# is doubled in that case. (Pursuit) -# (Handled in Battle's pbAttackPhase): Makes this attack happen before switching. -#=============================================================================== -class PokeBattle_Move_088 < PokeBattle_Move - def pbAccuracyCheck(user,target) - return true if @battle.switching - return super - end - - def pbBaseDamage(baseDmg,user,target) - baseDmg *= 2 if @battle.switching - return baseDmg - end -end - - - -#=============================================================================== -# Power increases with the user's happiness. (Return) -#=============================================================================== -class PokeBattle_Move_089 < PokeBattle_Move - def pbBaseDamage(baseDmg,user,target) - return [(user.happiness*2/5).floor,1].max - end -end - - - -#=============================================================================== -# Power decreases with the user's happiness. (Frustration) -#=============================================================================== -class PokeBattle_Move_08A < PokeBattle_Move - def pbBaseDamage(baseDmg,user,target) - return [((255-user.happiness)*2/5).floor,1].max - end -end - - - -#=============================================================================== -# Power increases with the user's HP. (Eruption, Water Spout) -#=============================================================================== -class PokeBattle_Move_08B < PokeBattle_Move - def pbBaseDamage(baseDmg,user,target) - return [150*user.hp/user.totalhp,1].max - end -end - - - -#=============================================================================== -# Power increases with the target's HP. (Crush Grip, Wring Out) -#=============================================================================== -class PokeBattle_Move_08C < PokeBattle_Move - def pbBaseDamage(baseDmg,user,target) - return [120*target.hp/target.totalhp,1].max - end -end - - - -#=============================================================================== -# Power increases the quicker the target is than the user. (Gyro Ball) -#=============================================================================== -class PokeBattle_Move_08D < PokeBattle_Move - def pbBaseDamage(baseDmg,user,target) - return [[(25*target.pbSpeed/user.pbSpeed).floor,150].min,1].max - end -end - - - -#=============================================================================== -# Power increases with the user's positive stat changes (ignores negative ones). -# (Power Trip, Stored Power) -#=============================================================================== -class PokeBattle_Move_08E < PokeBattle_Move - def pbBaseDamage(baseDmg,user,target) - mult = 1 - GameData::Stat.each_battle { |s| mult += user.stages[s.id] if user.stages[s.id] > 0 } - return 20 * mult - end -end - - - -#=============================================================================== -# Power increases with the target's positive stat changes (ignores negative ones). -# (Punishment) -#=============================================================================== -class PokeBattle_Move_08F < PokeBattle_Move - def pbBaseDamage(baseDmg,user,target) - mult = 3 - GameData::Stat.each_battle { |s| mult += target.stages[s.id] if target.stages[s.id] > 0 } - return [20 * mult, 200].min - end -end - - - -#=============================================================================== -# Power and type depends on the user's IVs. (Hidden Power) -#=============================================================================== -class PokeBattle_Move_090 < PokeBattle_Move - def pbBaseType(user) - hp = pbHiddenPower(user,user.pokemon.hiddenPowerType) - return hp[0] - end - - def pbBaseDamage(baseDmg,user,target) - return super if Settings::MECHANICS_GENERATION >= 6 - hp = pbHiddenPower(user,user.pokemon.hiddenPowerType) - return hp[1] - end -end - - - -def pbHiddenPower(pkmn,forcedType=nil) - # NOTE: This allows Hidden Power to be Fairy-type (if you have that type in - # your game). I don't care that the official games don't work like that. - iv = pkmn.iv - idxType = 0; power = 60 - types = [] - GameData::Type.each { |t| types.push(t.id) if !t.pseudo_type && ![:NORMAL, :SHADOW].include?(t.id)} - types.sort! { |a, b| GameData::Type.get(a).id_number <=> GameData::Type.get(b).id_number } - idxType |= (iv[:HP]&1) - idxType |= (iv[:ATTACK]&1)<<1 - idxType |= (iv[:DEFENSE]&1)<<2 - idxType |= (iv[:SPEED]&1)<<3 - idxType |= (iv[:SPECIAL_ATTACK]&1)<<4 - idxType |= (iv[:SPECIAL_DEFENSE]&1)<<5 - idxType = (types.length-1)*idxType/63 - type = types[idxType] - if Settings::MECHANICS_GENERATION <= 5 - powerMin = 30 - powerMax = 70 - power |= (iv[:HP]&2)>>1 - power |= (iv[:ATTACK]&2) - power |= (iv[:DEFENSE]&2)<<1 - power |= (iv[:SPEED]&2)<<2 - power |= (iv[:SPECIAL_ATTACK]&2)<<3 - power |= (iv[:SPECIAL_DEFENSE]&2)<<4 - power = powerMin+(powerMax-powerMin)*power/63 - end - if forcedType != nil - return [forcedType,power] - end - return [type,power] -end - - - -#=============================================================================== -# Power doubles for each consecutive use. (Fury Cutter) -#=============================================================================== -class PokeBattle_Move_091 < PokeBattle_Move - def pbChangeUsageCounters(user,specialUsage) - oldVal = user.effects[PBEffects::FuryCutter] - super - maxMult = 1 - while (@baseDamage<<(maxMult-1))<160 - maxMult += 1 # 1-4 for base damage of 20, 1-3 for base damage of 40 - end - user.effects[PBEffects::FuryCutter] = (oldVal>=maxMult) ? maxMult : oldVal+1 - end - - def pbBaseDamage(baseDmg,user,target) - return baseDmg<<(user.effects[PBEffects::FuryCutter]-1) - end -end - - - -#=============================================================================== -# Power is multiplied by the number of consecutive rounds in which this move was -# used by any Pokémon on the user's side. (Echoed Voice) -#=============================================================================== -class PokeBattle_Move_092 < PokeBattle_Move - def pbChangeUsageCounters(user,specialUsage) - oldVal = user.pbOwnSide.effects[PBEffects::EchoedVoiceCounter] - super - if !user.pbOwnSide.effects[PBEffects::EchoedVoiceUsed] - user.pbOwnSide.effects[PBEffects::EchoedVoiceCounter] = (oldVal>=5) ? 5 : oldVal+1 - end - user.pbOwnSide.effects[PBEffects::EchoedVoiceUsed] = true - end - - def pbBaseDamage(baseDmg,user,target) - return baseDmg*user.pbOwnSide.effects[PBEffects::EchoedVoiceCounter] # 1-5 - end -end - - - -#=============================================================================== -# User rages until the start of a round in which they don't use this move. (Rage) -# (Handled in Battler's pbProcessMoveAgainstTarget): Ups rager's Attack by 1 -# stage each time it loses HP due to a move. -#=============================================================================== -class PokeBattle_Move_093 < PokeBattle_Move - def pbEffectGeneral(user) - user.effects[PBEffects::Rage] = true - end -end - - - -#=============================================================================== -# Randomly damages or heals the target. (Present) -# NOTE: Apparently a Normal Gem should be consumed even if this move will heal, -# but I think that's silly so I've omitted that effect. -#=============================================================================== -class PokeBattle_Move_094 < PokeBattle_Move - def pbOnStartUse(user,targets) - @presentDmg = 0 # 0 = heal, >0 = damage - r = @battle.pbRandom(100) - if r<40; @presentDmg = 40 - elsif r<70; @presentDmg = 80 - elsif r<80; @presentDmg = 120 - end - end - - def pbFailsAgainstTarget?(user,target) - return false if @presentDmg>0 - if !target.canHeal? - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbDamagingMove? - return false if @presentDmg==0 - return super - end - - def pbBaseDamage(baseDmg,user,target) - return @presentDmg - end - - def pbEffectAgainstTarget(user,target) - return if @presentDmg>0 - target.pbRecoverHP(target.totalhp/4) - @battle.pbDisplay(_INTL("{1}'s HP was restored.",target.pbThis)) - end - - def pbShowAnimation(id,user,targets,hitNum=0,showAnimation=true) - hitNum = 1 if @presentDmg==0 # Healing anim - super - end -end - - - -#=============================================================================== -# Power is chosen at random. Power is doubled if the target is using Dig. Hits -# some semi-invulnerable targets. (Magnitude) -#=============================================================================== -class PokeBattle_Move_095 < PokeBattle_Move - def hitsDiggingTargets?; return true; end - - def pbOnStartUse(user,targets) - baseDmg = [10,30,50,70,90,110,150] - magnitudes = [ - 4, - 5,5, - 6,6,6,6, - 7,7,7,7,7,7, - 8,8,8,8, - 9,9, - 10 - ] - magni = magnitudes[@battle.pbRandom(magnitudes.length)] - @magnitudeDmg = baseDmg[magni-4] - @battle.pbDisplay(_INTL("Magnitude {1}!",magni)) - end - - def pbBaseDamage(baseDmg,user,target) - return @magnitudeDmg - end - - def pbModifyDamage(damageMult,user,target) - damageMult *= 2 if target.inTwoTurnAttack?("0CA") # Dig - damageMult /= 2 if @battle.field.terrain == :Grassy - return damageMult - end -end - - - -#=============================================================================== -# Power and type depend on the user's held berry. Destroys the berry. -# (Natural Gift) -#=============================================================================== -class PokeBattle_Move_096 < PokeBattle_Move - def initialize(battle,move) - super - @typeArray = { - :NORMAL => [:CHILANBERRY], - :FIRE => [:CHERIBERRY, :BLUKBERRY, :WATMELBERRY, :OCCABERRY], - :WATER => [:CHESTOBERRY, :NANABBERRY, :DURINBERRY, :PASSHOBERRY], - :ELECTRIC => [:PECHABERRY, :WEPEARBERRY, :BELUEBERRY, :WACANBERRY], - :GRASS => [:RAWSTBERRY, :PINAPBERRY, :RINDOBERRY, :LIECHIBERRY], - :ICE => [:ASPEARBERRY, :POMEGBERRY, :YACHEBERRY, :GANLONBERRY], - :FIGHTING => [:LEPPABERRY, :KELPSYBERRY, :CHOPLEBERRY, :SALACBERRY], - :POISON => [:ORANBERRY, :QUALOTBERRY, :KEBIABERRY, :PETAYABERRY], - :GROUND => [:PERSIMBERRY, :HONDEWBERRY, :SHUCABERRY, :APICOTBERRY], - :FLYING => [:LUMBERRY, :GREPABERRY, :COBABERRY, :LANSATBERRY], - :PSYCHIC => [:SITRUSBERRY, :TAMATOBERRY, :PAYAPABERRY, :STARFBERRY], - :BUG => [:FIGYBERRY, :CORNNBERRY, :TANGABERRY, :ENIGMABERRY], - :ROCK => [:WIKIBERRY, :MAGOSTBERRY, :CHARTIBERRY, :MICLEBERRY], - :GHOST => [:MAGOBERRY, :RABUTABERRY, :KASIBBERRY, :CUSTAPBERRY], - :DRAGON => [:AGUAVBERRY, :NOMELBERRY, :HABANBERRY, :JABOCABERRY], - :DARK => [:IAPAPABERRY, :SPELONBERRY, :COLBURBERRY, :ROWAPBERRY, :MARANGABERRY], - :STEEL => [:RAZZBERRY, :PAMTREBERRY, :BABIRIBERRY], - :FAIRY => [:ROSELIBERRY, :KEEBERRY] - } - @damageArray = { - 60 => [:CHERIBERRY, :CHESTOBERRY, :PECHABERRY, :RAWSTBERRY, :ASPEARBERRY, - :LEPPABERRY, :ORANBERRY, :PERSIMBERRY, :LUMBERRY, :SITRUSBERRY, - :FIGYBERRY, :WIKIBERRY, :MAGOBERRY, :AGUAVBERRY, :IAPAPABERRY, - :RAZZBERRY, :OCCABERRY, :PASSHOBERRY, :WACANBERRY, :RINDOBERRY, - :YACHEBERRY, :CHOPLEBERRY, :KEBIABERRY, :SHUCABERRY, :COBABERRY, - :PAYAPABERRY, :TANGABERRY, :CHARTIBERRY, :KASIBBERRY, :HABANBERRY, - :COLBURBERRY, :BABIRIBERRY, :CHILANBERRY, :ROSELIBERRY], - 70 => [:BLUKBERRY, :NANABBERRY, :WEPEARBERRY, :PINAPBERRY, :POMEGBERRY, - :KELPSYBERRY, :QUALOTBERRY, :HONDEWBERRY, :GREPABERRY, :TAMATOBERRY, - :CORNNBERRY, :MAGOSTBERRY, :RABUTABERRY, :NOMELBERRY, :SPELONBERRY, - :PAMTREBERRY], - 80 => [:WATMELBERRY, :DURINBERRY, :BELUEBERRY, :LIECHIBERRY, :GANLONBERRY, - :SALACBERRY, :PETAYABERRY, :APICOTBERRY, :LANSATBERRY, :STARFBERRY, - :ENIGMABERRY, :MICLEBERRY, :CUSTAPBERRY, :JABOCABERRY, :ROWAPBERRY, - :KEEBERRY, :MARANGABERRY] - } - end - - def pbMoveFailed?(user,targets) - # NOTE: Unnerve does not stop a Pokémon using this move. - item = user.item - if !item || !item.is_berry? || !user.itemActive? - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - # NOTE: The AI calls this method via pbCalcType, but it involves user.item - # which here is assumed to be not nil (because item.id is called). Since - # the AI won't want to use it if the user has no item anyway, perhaps - # this is good enough. - def pbBaseType(user) - item = user.item - ret = :NORMAL - if item - @typeArray.each do |type, items| - next if !items.include?(item.id) - ret = type if GameData::Type.exists?(type) - break - end - end - return ret - end - - # This is a separate method so that the AI can use it as well - def pbNaturalGiftBaseDamage(heldItem) - ret = 1 - @damageArray.each do |dmg, items| - next if !items.include?(heldItem) - ret = dmg - ret += 20 if Settings::MECHANICS_GENERATION >= 6 - break - end - return ret - end - - def pbBaseDamage(baseDmg,user,target) - return pbNaturalGiftBaseDamage(user.item.id) - end - - def pbEndOfMoveUsageEffect(user,targets,numHits,switchedBattlers) - # NOTE: The item is consumed even if this move was Protected against or it - # missed. The item is not consumed if the target was switched out by - # an effect like a target's Red Card. - # NOTE: There is no item consumption animation. - user.pbConsumeItem(true,true,false) if user.item - end -end - - - -#=============================================================================== -# Power increases the less PP this move has. (Trump Card) -#=============================================================================== -class PokeBattle_Move_097 < PokeBattle_Move - def pbBaseDamage(baseDmg,user,target) - dmgs = [200,80,60,50,40] - ppLeft = [@pp,dmgs.length-1].min # PP is reduced before the move is used - return dmgs[ppLeft] - end -end - - - -#=============================================================================== -# Power increases the less HP the user has. (Flail, Reversal) -#=============================================================================== -class PokeBattle_Move_098 < PokeBattle_Move - def pbBaseDamage(baseDmg,user,target) - ret = 20 - n = 48*user.hp/user.totalhp - if n<2; ret = 200 - elsif n<5; ret = 150 - elsif n<10; ret = 100 - elsif n<17; ret = 80 - elsif n<33; ret = 40 - end - return ret - end -end - - - -#=============================================================================== -# Power increases the quicker the user is than the target. (Electro Ball) -#=============================================================================== -class PokeBattle_Move_099 < PokeBattle_Move - def pbBaseDamage(baseDmg,user,target) - ret = 40 - n = user.pbSpeed/target.pbSpeed - if n>=4; ret = 150 - elsif n>=3; ret = 120 - elsif n>=2; ret = 80 - elsif n>=1; ret = 60 - end - return ret - end -end - - - -#=============================================================================== -# Power increases the heavier the target is. (Grass Knot, Low Kick) -#=============================================================================== -class PokeBattle_Move_09A < PokeBattle_Move - def pbBaseDamage(baseDmg,user,target) - ret = 20 - weight = target.pbWeight - if weight>=2000; ret = 120 - elsif weight>=1000; ret = 100 - elsif weight>=500; ret = 80 - elsif weight>=250; ret = 60 - elsif weight>=100; ret = 40 - end - return ret - end -end - - - -#=============================================================================== -# Power increases the heavier the user is than the target. (Heat Crash, Heavy Slam) -# Does double damage and has perfect accuracy if the target is Minimized. -#=============================================================================== -class PokeBattle_Move_09B < PokeBattle_Move - def tramplesMinimize?(param=1) - return true if Settings::MECHANICS_GENERATION >= 7 # Perfect accuracy and double damage - return super - end - - def pbBaseDamage(baseDmg,user,target) - ret = 40 - n = (user.pbWeight/target.pbWeight).floor - if n>=5; ret = 120 - elsif n>=4; ret = 100 - elsif n>=3; ret = 80 - elsif n>=2; ret = 60 - end - return ret - end -end - - - -#=============================================================================== -# Powers up the ally's attack this round by 1.5. (Helping Hand) -#=============================================================================== -class PokeBattle_Move_09C < PokeBattle_Move - def ignoresSubstitute?(user); return true; end - - def pbFailsAgainstTarget?(user,target) - if target.fainted? || target.effects[PBEffects::HelpingHand] - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return true if pbMoveFailedTargetAlreadyMoved?(target) - return false - end - - def pbEffectAgainstTarget(user,target) - target.effects[PBEffects::HelpingHand] = true - @battle.pbDisplay(_INTL("{1} is ready to help {2}!",user.pbThis,target.pbThis(true))) - end -end - - - -#=============================================================================== -# Weakens Electric attacks. (Mud Sport) -#=============================================================================== -class PokeBattle_Move_09D < PokeBattle_Move - def pbMoveFailed?(user,targets) - if Settings::MECHANICS_GENERATION >= 6 - if @battle.field.effects[PBEffects::MudSportField]>0 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - else - @battle.eachBattler do |b| - next if !b.effects[PBEffects::MudSport] - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - end - return false - end - - def pbEffectGeneral(user) - if Settings::MECHANICS_GENERATION >= 6 - @battle.field.effects[PBEffects::MudSportField] = 5 - else - user.effects[PBEffects::MudSport] = true - end - @battle.pbDisplay(_INTL("Electricity's power was weakened!")) - end -end - - - -#=============================================================================== -# Weakens Fire attacks. (Water Sport) -#=============================================================================== -class PokeBattle_Move_09E < PokeBattle_Move - def pbMoveFailed?(user,targets) - if Settings::MECHANICS_GENERATION >= 6 - if @battle.field.effects[PBEffects::WaterSportField]>0 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - else - @battle.eachBattler do |b| - next if !b.effects[PBEffects::WaterSport] - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - end - return false - end - - def pbEffectGeneral(user) - if Settings::MECHANICS_GENERATION >= 6 - @battle.field.effects[PBEffects::WaterSportField] = 5 - else - user.effects[PBEffects::WaterSport] = true - end - @battle.pbDisplay(_INTL("Fire's power was weakened!")) - end -end - - - -#=============================================================================== -# Type depends on the user's held item. (Judgment, Multi-Attack, Techno Blast) -#=============================================================================== -class PokeBattle_Move_09F < PokeBattle_Move - def initialize(battle,move) - super - if @id == :JUDGMENT - @itemTypes = { - :FISTPLATE => :FIGHTING, - :SKYPLATE => :FLYING, - :TOXICPLATE => :POISON, - :EARTHPLATE => :GROUND, - :STONEPLATE => :ROCK, - :INSECTPLATE => :BUG, - :SPOOKYPLATE => :GHOST, - :IRONPLATE => :STEEL, - :FLAMEPLATE => :FIRE, - :SPLASHPLATE => :WATER, - :MEADOWPLATE => :GRASS, - :ZAPPLATE => :ELECTRIC, - :MINDPLATE => :PSYCHIC, - :ICICLEPLATE => :ICE, - :DRACOPLATE => :DRAGON, - :DREADPLATE => :DARK, - :PIXIEPLATE => :FAIRY - } - elsif @id == :TECHNOBLAST - @itemTypes = { - :SHOCKDRIVE => :ELECTRIC, - :BURNDRIVE => :FIRE, - :CHILLDRIVE => :ICE, - :DOUSEDRIVE => :WATER - } - elsif @id == :MULTIATTACK - @itemTypes = { - :FIGHTINGMEMORY => :FIGHTING, - :FLYINGMEMORY => :FLYING, - :POISONMEMORY => :POISON, - :GROUNDMEMORY => :GROUND, - :ROCKMEMORY => :ROCK, - :BUGMEMORY => :BUG, - :GHOSTMEMORY => :GHOST, - :STEELMEMORY => :STEEL, - :FIREMEMORY => :FIRE, - :WATERMEMORY => :WATER, - :GRASSMEMORY => :GRASS, - :ELECTRICMEMORY => :ELECTRIC, - :PSYCHICMEMORY => :PSYCHIC, - :ICEMEMORY => :ICE, - :DRAGONMEMORY => :DRAGON, - :DARKMEMORY => :DARK, - :FAIRYMEMORY => :FAIRY - } - end - end - - def pbBaseType(user) - ret = :NORMAL - if user.itemActive? - @itemTypes.each do |item, itemType| - next if user.item != item - ret = itemType if GameData::Type.exists?(itemType) - break - end - end - return ret - end - - def pbShowAnimation(id,user,targets,hitNum=0,showAnimation=true) - if @id == :TECHNOBLAST # Type-specific anim - t = pbBaseType(user) - hitNum = 0 - hitNum = 1 if t == :ELECTRIC - hitNum = 2 if t == :FIRE - hitNum = 3 if t == :ICE - hitNum = 4 if t == :WATER - end - super - end -end - - - -#=============================================================================== -# This attack is always a critical hit. (Frost Breath, Storm Throw) -#=============================================================================== -class PokeBattle_Move_0A0 < PokeBattle_Move - def pbCritialOverride(user,target); return 1; end -end - - - -#=============================================================================== -# For 5 rounds, foes' attacks cannot become critical hits. (Lucky Chant) -#=============================================================================== -class PokeBattle_Move_0A1 < PokeBattle_Move - def pbMoveFailed?(user,targets) - if user.pbOwnSide.effects[PBEffects::LuckyChant]>0 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - user.pbOwnSide.effects[PBEffects::LuckyChant] = 5 - @battle.pbDisplay(_INTL("The Lucky Chant shielded {1} from critical hits!",user.pbTeam(true))) - end -end - - - -#=============================================================================== -# For 5 rounds, lowers power of physical attacks against the user's side. -# (Reflect) -#=============================================================================== -class PokeBattle_Move_0A2 < PokeBattle_Move - def pbMoveFailed?(user,targets) - if user.pbOwnSide.effects[PBEffects::Reflect]>0 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - user.pbOwnSide.effects[PBEffects::Reflect] = 5 - user.pbOwnSide.effects[PBEffects::Reflect] = 8 if user.hasActiveItem?(:LIGHTCLAY) - @battle.pbDisplay(_INTL("{1} raised {2}'s Defense!",@name,user.pbTeam(true))) - end -end - - - -#=============================================================================== -# For 5 rounds, lowers power of special attacks against the user's side. (Light Screen) -#=============================================================================== -class PokeBattle_Move_0A3 < PokeBattle_Move - def pbMoveFailed?(user,targets) - if user.pbOwnSide.effects[PBEffects::LightScreen]>0 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - user.pbOwnSide.effects[PBEffects::LightScreen] = 5 - user.pbOwnSide.effects[PBEffects::LightScreen] = 8 if user.hasActiveItem?(:LIGHTCLAY) - @battle.pbDisplay(_INTL("{1} raised {2}'s Special Defense!",@name,user.pbTeam(true))) - end -end - - - -#=============================================================================== -# Effect depends on the environment. (Secret Power) -#=============================================================================== -class PokeBattle_Move_0A4 < PokeBattle_Move - def flinchingMove?; return [6,10,12].include?(@secretPower); end - - def pbOnStartUse(user,targets) - # NOTE: This is Gen 7's list plus some of Gen 6 plus a bit of my own. - @secretPower = 0 # Body Slam, paralysis - case @battle.field.terrain - when :Electric - @secretPower = 1 # Thunder Shock, paralysis - when :Grassy - @secretPower = 2 # Vine Whip, sleep - when :Misty - @secretPower = 3 # Fairy Wind, lower Sp. Atk by 1 - when :Psychic - @secretPower = 4 # Confusion, lower Speed by 1 - else - case @battle.environment - when :Grass, :TallGrass, :Forest, :ForestGrass - @secretPower = 2 # (Same as Grassy Terrain) - when :MovingWater, :StillWater, :Underwater - @secretPower = 5 # Water Pulse, lower Attack by 1 - when :Puddle - @secretPower = 6 # Mud Shot, lower Speed by 1 - when :Cave - @secretPower = 7 # Rock Throw, flinch - when :Rock, :Sand - @secretPower = 8 # Mud-Slap, lower Acc by 1 - when :Snow, :Ice - @secretPower = 9 # Ice Shard, freeze - when :Volcano - @secretPower = 10 # Incinerate, burn - when :Graveyard - @secretPower = 11 # Shadow Sneak, flinch - when :Sky - @secretPower = 12 # Gust, lower Speed by 1 - when :Space - @secretPower = 13 # Swift, flinch - when :UltraSpace - @secretPower = 14 # Psywave, lower Defense by 1 - end - end - end - - # NOTE: This intentionally doesn't use def pbAdditionalEffect, because that - # method is called per hit and this move's additional effect only occurs - # once per use, after all the hits have happened (two hits are possible - # via Parental Bond). - def pbEffectAfterAllHits(user,target) - return if target.fainted? - return if target.damageState.unaffected || target.damageState.substitute - chance = pbAdditionalEffectChance(user,target) - return if @battle.pbRandom(100)>=chance - case @secretPower - when 2 - target.pbSleep if target.pbCanSleep?(user,false,self) - when 10 - target.pbBurn(user) if target.pbCanBurn?(user,false,self) - when 0, 1 - target.pbParalyze(user) if target.pbCanParalyze?(user,false,self) - when 9 - target.pbFreeze if target.pbCanFreeze?(user,false,self) - when 5 - if target.pbCanLowerStatStage?(:ATTACK,user,self) - target.pbLowerStatStage(:ATTACK,1,user) - end - when 14 - if target.pbCanLowerStatStage?(:DEFENSE,user,self) - target.pbLowerStatStage(:DEFENSE,1,user) - end - when 3 - if target.pbCanLowerStatStage?(:SPECIAL_ATTACK,user,self) - target.pbLowerStatStage(:SPECIAL_ATTACK,1,user) - end - when 4, 6, 12 - if target.pbCanLowerStatStage?(:SPEED,user,self) - target.pbLowerStatStage(:SPEED,1,user) - end - when 8 - if target.pbCanLowerStatStage?(:ACCURACY,user,self) - target.pbLowerStatStage(:ACCURACY,1,user) - end - when 7, 11, 13 - target.pbFlinch(user) - end - end - - def pbShowAnimation(id,user,targets,hitNum=0,showAnimation=true) - id = :BODYSLAM # Environment-specific anim - case @secretPower - when 1 then id = :THUNDERSHOCK if GameData::Move.exists?(:THUNDERSHOCK) - when 2 then id = :VINEWHIP if GameData::Move.exists?(:VINEWHIP) - when 3 then id = :FAIRYWIND if GameData::Move.exists?(:FAIRYWIND) - when 4 then id = :CONFUSIO if GameData::Move.exists?(:CONFUSION) - when 5 then id = :WATERPULSE if GameData::Move.exists?(:WATERPULSE) - when 6 then id = :MUDSHOT if GameData::Move.exists?(:MUDSHOT) - when 7 then id = :ROCKTHROW if GameData::Move.exists?(:ROCKTHROW) - when 8 then id = :MUDSLAP if GameData::Move.exists?(:MUDSLAP) - when 9 then id = :ICESHARD if GameData::Move.exists?(:ICESHARD) - when 10 then id = :INCINERATE if GameData::Move.exists?(:INCINERATE) - when 11 then id = :SHADOWSNEAK if GameData::Move.exists?(:SHADOWSNEAK) - when 12 then id = :GUST if GameData::Move.exists?(:GUST) - when 13 then id = :SWIFT if GameData::Move.exists?(:SWIFT) - when 14 then id = :PSYWAVE if GameData::Move.exists?(:PSYWAVE) - end - super - end -end - - - -#=============================================================================== -# Always hits. -#=============================================================================== -class PokeBattle_Move_0A5 < PokeBattle_Move - def pbAccuracyCheck(user,target); return true; end -end - - - -#=============================================================================== -# User's attack next round against the target will definitely hit. -# (Lock-On, Mind Reader) -#=============================================================================== -class PokeBattle_Move_0A6 < PokeBattle_Move - def pbEffectAgainstTarget(user,target) - user.effects[PBEffects::LockOn] = 2 - user.effects[PBEffects::LockOnPos] = target.index - @battle.pbDisplay(_INTL("{1} took aim at {2}!",user.pbThis,target.pbThis(true))) - end -end - - - -#=============================================================================== -# Target's evasion stat changes are ignored from now on. (Foresight, Odor Sleuth) -# Normal and Fighting moves have normal effectiveness against the Ghost-type target. -#=============================================================================== -class PokeBattle_Move_0A7 < PokeBattle_Move - def ignoresSubstitute?(user); return true; end - - def pbEffectAgainstTarget(user,target) - target.effects[PBEffects::Foresight] = true - @battle.pbDisplay(_INTL("{1} was identified!",target.pbThis)) - end -end - - - -#=============================================================================== -# Target's evasion stat changes are ignored from now on. (Miracle Eye) -# Psychic moves have normal effectiveness against the Dark-type target. -#=============================================================================== -class PokeBattle_Move_0A8 < PokeBattle_Move - def ignoresSubstitute?(user); return true; end - - def pbEffectAgainstTarget(user,target) - target.effects[PBEffects::MiracleEye] = true - @battle.pbDisplay(_INTL("{1} was identified!",target.pbThis)) - end -end - - - -#=============================================================================== -# This move ignores target's Defense, Special Defense and evasion stat changes. -# (Chip Away, Darkest Lariat, Sacred Sword) -#=============================================================================== -class PokeBattle_Move_0A9 < PokeBattle_Move - def pbCalcAccuracyMultipliers(user,target,multipliers) - super - modifiers[:evasion_stage] = 0 - end - - def pbGetDefenseStats(user,target) - ret1, _ret2 = super - return ret1, 6 # Def/SpDef stat stage - end -end - - - -#=============================================================================== -# User is protected against moves with the "B" flag this round. (Detect, Protect) -#=============================================================================== -class PokeBattle_Move_0AA < PokeBattle_ProtectMove - def initialize(battle,move) - super - @effect = PBEffects::Protect - end -end - - - -#=============================================================================== -# User's side is protected against moves with priority greater than 0 this round. -# (Quick Guard) -#=============================================================================== -class PokeBattle_Move_0AB < PokeBattle_ProtectMove - def initialize(battle,move) - super - @effect = PBEffects::QuickGuard - @sidedEffect = true - end -end - - - -#=============================================================================== -# User's side is protected against moves that target multiple battlers this round. -# (Wide Guard) -#=============================================================================== -class PokeBattle_Move_0AC < PokeBattle_ProtectMove - def initialize(battle,move) - super - @effect = PBEffects::WideGuard - @sidedEffect = true - end -end - - - -#=============================================================================== -# Ends target's protections immediately. (Feint) -#=============================================================================== -class PokeBattle_Move_0AD < PokeBattle_Move - def pbEffectAgainstTarget(user,target) - target.effects[PBEffects::BanefulBunker] = false - target.effects[PBEffects::KingsShield] = false - target.effects[PBEffects::Protect] = false - target.effects[PBEffects::SpikyShield] = false - target.pbOwnSide.effects[PBEffects::CraftyShield] = false - target.pbOwnSide.effects[PBEffects::MatBlock] = false - target.pbOwnSide.effects[PBEffects::QuickGuard] = false - target.pbOwnSide.effects[PBEffects::WideGuard] = false - end -end - - - -#=============================================================================== -# Uses the last move that the target used. (Mirror Move) -#=============================================================================== -class PokeBattle_Move_0AE < PokeBattle_Move - def ignoresSubstitute?(user); return true; end - def callsAnotherMove?; return true; end - - def pbFailsAgainstTarget?(user,target) - if !target.lastRegularMoveUsed || - !GameData::Move.get(target.lastRegularMoveUsed).flags[/e/] # Not copyable by Mirror Move - @battle.pbDisplay(_INTL("The mirror move failed!")) - return true - end - return false - end - - def pbEffectAgainstTarget(user,target) - user.pbUseMoveSimple(target.lastRegularMoveUsed,target.index) - end - - def pbShowAnimation(id,user,targets,hitNum=0,showAnimation=true) - # No animation - end -end - - - -#=============================================================================== -# Uses the last move that was used. (Copycat) -#=============================================================================== -class PokeBattle_Move_0AF < PokeBattle_Move - def callsAnotherMove?; return true; end - - def initialize(battle,move) - super - @moveBlacklist = [ - # Struggle, Chatter, Belch - "002", # Struggle - "014", # Chatter - "158", # Belch # Not listed on Bulbapedia - # Moves that affect the moveset - "05C", # Mimic - "05D", # Sketch - "069", # Transform - # Counter moves - "071", # Counter - "072", # Mirror Coat - "073", # Metal Burst # Not listed on Bulbapedia - # Helping Hand, Feint (always blacklisted together, don't know why) - "09C", # Helping Hand - "0AD", # Feint - # Protection moves - "0AA", # Detect, Protect - "0AB", # Quick Guard # Not listed on Bulbapedia - "0AC", # Wide Guard # Not listed on Bulbapedia - "0E8", # Endure - "149", # Mat Block - "14A", # Crafty Shield # Not listed on Bulbapedia - "14B", # King's Shield - "14C", # Spiky Shield - "168", # Baneful Bunker - # Moves that call other moves - "0AE", # Mirror Move - "0AF", # Copycat (this move) - "0B0", # Me First - "0B3", # Nature Power # Not listed on Bulbapedia - "0B4", # Sleep Talk - "0B5", # Assist - "0B6", # Metronome - # Move-redirecting and stealing moves - "0B1", # Magic Coat # Not listed on Bulbapedia - "0B2", # Snatch - "117", # Follow Me, Rage Powder - "16A", # Spotlight - # Set up effects that trigger upon KO - "0E6", # Grudge # Not listed on Bulbapedia - "0E7", # Destiny Bond - # Held item-moving moves - "0F1", # Covet, Thief - "0F2", # Switcheroo, Trick - "0F3", # Bestow - # Moves that start focussing at the start of the round - "115", # Focus Punch - "171", # Shell Trap - "172", # Beak Blast - # Event moves that do nothing - "133", # Hold Hands - "134" # Celebrate - ] - if Settings::MECHANICS_GENERATION >= 6 - @moveBlacklist += [ - # Target-switching moves - "0EB", # Roar, Whirlwind - "0EC" # Circle Throw, Dragon Tail - ] - end - end - - def pbChangeUsageCounters(user,specialUsage) - super - @copied_move = @battle.lastMoveUsed - end - - def pbMoveFailed?(user,targets) - if !@copied_move || - @moveBlacklist.include?(GameData::Move.get(@copied_move).function_code) - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - user.pbUseMoveSimple(@copied_move) - end -end - - - -#=============================================================================== -# Uses the move the target was about to use this round, with 1.5x power. -# (Me First) -#=============================================================================== -class PokeBattle_Move_0B0 < PokeBattle_Move - def ignoresSubstitute?(user); return true; end - def callsAnotherMove?; return true; end - - def initialize(battle,move) - super - @moveBlacklist = [ - "0F1", # Covet, Thief - # Struggle, Chatter, Belch - "002", # Struggle - "014", # Chatter - "158", # Belch - # Counter moves - "071", # Counter - "072", # Mirror Coat - "073", # Metal Burst - # Moves that start focussing at the start of the round - "115", # Focus Punch - "171", # Shell Trap - "172" # Beak Blast - ] - end - - def pbFailsAgainstTarget?(user,target) - return true if pbMoveFailedTargetAlreadyMoved?(target) - oppMove = @battle.choices[target.index][2] - if !oppMove || oppMove.statusMove? || @moveBlacklist.include?(oppMove.function) - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectAgainstTarget(user,target) - user.effects[PBEffects::MeFirst] = true - user.pbUseMoveSimple(@battle.choices[target.index][2].id) - user.effects[PBEffects::MeFirst] = false - end -end - - - -#=============================================================================== -# This round, reflects all moves with the "C" flag targeting the user back at -# their origin. (Magic Coat) -#=============================================================================== -class PokeBattle_Move_0B1 < PokeBattle_Move - def pbEffectGeneral(user) - user.effects[PBEffects::MagicCoat] = true - @battle.pbDisplay(_INTL("{1} shrouded itself with Magic Coat!",user.pbThis)) - end -end - - - -#=============================================================================== -# This round, snatches all used moves with the "D" flag. (Snatch) -#=============================================================================== -class PokeBattle_Move_0B2 < PokeBattle_Move - def pbEffectGeneral(user) - user.effects[PBEffects::Snatch] = 1 - @battle.eachBattler do |b| - next if b.effects[PBEffects::Snatch]= 6 - @npMove = :ENERGYBALL if GameData::Move.exists?(:ENERGYBALL) - else - @npMove = :SEEDBOMB if GameData::Move.exists?(:SEEDBOMB) - end - when :MovingWater, :StillWater, :Underwater - @npMove = :HYDROPUMP if GameData::Move.exists?(:HYDROPUMP) - when :Puddle - @npMove = :MUDBOMB if GameData::Move.exists?(:MUDBOMB) - when :Cave - if Settings::MECHANICS_GENERATION >= 6 - @npMove = :POWERGEM if GameData::Move.exists?(:POWERGEM) - else - @npMove = :ROCKSLIDE if GameData::Move.exists?(:ROCKSLIDE) - end - when :Rock - if Settings::MECHANICS_GENERATION >= 6 - @npMove = :EARTHPOWER if GameData::Move.exists?(:EARTHPOWER) - else - @npMove = :ROCKSLIDE if GameData::Move.exists?(:ROCKSLIDE) - end - when :Sand - if Settings::MECHANICS_GENERATION >= 6 - @npMove = :EARTHPOWER if GameData::Move.exists?(:EARTHPOWER) - else - @npMove = :EARTHQUAKE if GameData::Move.exists?(:EARTHQUAKE) - end - when :Snow - if Settings::MECHANICS_GENERATION >= 6 - @npMove = :FROSTBREATH if GameData::Move.exists?(:FROSTBREATH) - else - @npMove = :BLIZZARD if GameData::Move.exists?(:BLIZZARD) - end - when :Ice - @npMove = :ICEBEAM if GameData::Move.exists?(:ICEBEAM) - when :Volcano - @npMove = :LAVAPLUME if GameData::Move.exists?(:LAVAPLUME) - when :Graveyard - @npMove = :SHADOWBALL if GameData::Move.exists?(:SHADOWBALL) - when :Sky - @npMove = :AIRSLASH if GameData::Move.exists?(:AIRSLASH) - when :Space - @npMove = :DRACOMETEOR if GameData::Move.exists?(:DRACOMETEOR) - when :UltraSpace - @npMove = :PSYSHOCK if GameData::Move.exists?(:PSYSHOCK) - end - end - end - - def pbEffectAgainstTarget(user,target) - @battle.pbDisplay(_INTL("{1} turned into {2}!", @name, GameData::Move.get(@npMove).name)) - user.pbUseMoveSimple(@npMove, target.index) - end -end - - - -#=============================================================================== -# Uses a random move the user knows. Fails if user is not asleep. (Sleep Talk) -#=============================================================================== -class PokeBattle_Move_0B4 < PokeBattle_Move - def usableWhenAsleep?; return true; end - def callsAnotherMove?; return true; end - - def initialize(battle,move) - super - @moveBlacklist = [ - "0D1", # Uproar - "0D4", # Bide - # Struggle, Chatter, Belch - "002", # Struggle # Not listed on Bulbapedia - "014", # Chatter # Not listed on Bulbapedia - "158", # Belch - # Moves that affect the moveset (except Transform) - "05C", # Mimic - "05D", # Sketch - # Moves that call other moves - "0AE", # Mirror Move - "0AF", # Copycat - "0B0", # Me First - "0B3", # Nature Power # Not listed on Bulbapedia - "0B4", # Sleep Talk - "0B5", # Assist - "0B6", # Metronome - # Two-turn attacks - "0C3", # Razor Wind - "0C4", # Solar Beam, Solar Blade - "0C5", # Freeze Shock - "0C6", # Ice Burn - "0C7", # Sky Attack - "0C8", # Skull Bash - "0C9", # Fly - "0CA", # Dig - "0CB", # Dive - "0CC", # Bounce - "0CD", # Shadow Force - "0CE", # Sky Drop - "12E", # Shadow Half - "14D", # Phantom Force - "14E", # Geomancy - # Moves that start focussing at the start of the round - "115", # Focus Punch - "171", # Shell Trap - "172" # Beak Blast - ] - end - - def pbMoveFailed?(user,targets) - @sleepTalkMoves = [] - user.eachMoveWithIndex do |m,i| - next if @moveBlacklist.include?(m.function) - next if !@battle.pbCanChooseMove?(user.index,i,false,true) - @sleepTalkMoves.push(i) - end - if !user.asleep? || @sleepTalkMoves.length==0 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - choice = @sleepTalkMoves[@battle.pbRandom(@sleepTalkMoves.length)] - user.pbUseMoveSimple(user.moves[choice].id,user.pbDirectOpposing.index) - end -end - - - -#=============================================================================== -# Uses a random move known by any non-user Pokémon in the user's party. (Assist) -#=============================================================================== -class PokeBattle_Move_0B5 < PokeBattle_Move - def callsAnotherMove?; return true; end - - def initialize(battle,move) - super - @moveBlacklist = [ - # Struggle, Chatter, Belch - "002", # Struggle - "014", # Chatter - "158", # Belch - # Moves that affect the moveset - "05C", # Mimic - "05D", # Sketch - "069", # Transform - # Counter moves - "071", # Counter - "072", # Mirror Coat - "073", # Metal Burst # Not listed on Bulbapedia - # Helping Hand, Feint (always blacklisted together, don't know why) - "09C", # Helping Hand - "0AD", # Feint - # Protection moves - "0AA", # Detect, Protect - "0AB", # Quick Guard # Not listed on Bulbapedia - "0AC", # Wide Guard # Not listed on Bulbapedia - "0E8", # Endure - "149", # Mat Block - "14A", # Crafty Shield # Not listed on Bulbapedia - "14B", # King's Shield - "14C", # Spiky Shield - "168", # Baneful Bunker - # Moves that call other moves - "0AE", # Mirror Move - "0AF", # Copycat - "0B0", # Me First -# "0B3", # Nature Power # See below - "0B4", # Sleep Talk - "0B5", # Assist - "0B6", # Metronome - # Move-redirecting and stealing moves - "0B1", # Magic Coat # Not listed on Bulbapedia - "0B2", # Snatch - "117", # Follow Me, Rage Powder - "16A", # Spotlight - # Set up effects that trigger upon KO - "0E6", # Grudge # Not listed on Bulbapedia - "0E7", # Destiny Bond - # Target-switching moves -# "0EB", # Roar, Whirlwind # See below - "0EC", # Circle Throw, Dragon Tail - # Held item-moving moves - "0F1", # Covet, Thief - "0F2", # Switcheroo, Trick - "0F3", # Bestow - # Moves that start focussing at the start of the round - "115", # Focus Punch - "171", # Shell Trap - "172", # Beak Blast - # Event moves that do nothing - "133", # Hold Hands - "134" # Celebrate - ] - if Settings::MECHANICS_GENERATION >= 6 - @moveBlacklist += [ - # Moves that call other moves - "0B3", # Nature Power - # Two-turn attacks - "0C3", # Razor Wind # Not listed on Bulbapedia - "0C4", # Solar Beam, Solar Blade # Not listed on Bulbapedia - "0C5", # Freeze Shock # Not listed on Bulbapedia - "0C6", # Ice Burn # Not listed on Bulbapedia - "0C7", # Sky Attack # Not listed on Bulbapedia - "0C8", # Skull Bash # Not listed on Bulbapedia - "0C9", # Fly - "0CA", # Dig - "0CB", # Dive - "0CC", # Bounce - "0CD", # Shadow Force - "0CE", # Sky Drop - "12E", # Shadow Half - "14D", # Phantom Force - "14E", # Geomancy # Not listed on Bulbapedia - # Target-switching moves - "0EB" # Roar, Whirlwind - ] - end - end - - def pbMoveFailed?(user,targets) - @assistMoves = [] - # NOTE: This includes the Pokémon of ally trainers in multi battles. - @battle.pbParty(user.index).each_with_index do |pkmn,i| - next if !pkmn || i==user.pokemonIndex - next if Settings::MECHANICS_GENERATION >= 6 && pkmn.egg? - pkmn.moves.each do |move| - next if @moveBlacklist.include?(move.function_code) - next if move.type == :SHADOW - @assistMoves.push(move.id) - end - end - if @assistMoves.length==0 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - move = @assistMoves[@battle.pbRandom(@assistMoves.length)] - user.pbUseMoveSimple(move) - end -end - - - -#=============================================================================== -# Uses a random move that exists. (Metronome) -#=============================================================================== -class PokeBattle_Move_0B6 < PokeBattle_Move - def callsAnotherMove?; return true; end - - def initialize(battle,move) - super - @moveBlacklist = [ - "011", # Snore - "11D", # After You - "11E", # Quash - "16C", # Instruct - # Struggle, Chatter, Belch - "002", # Struggle - "014", # Chatter - "158", # Belch - # Moves that affect the moveset - "05C", # Mimic - "05D", # Sketch - "069", # Transform - # Counter moves - "071", # Counter - "072", # Mirror Coat - "073", # Metal Burst # Not listed on Bulbapedia - # Helping Hand, Feint (always blacklisted together, don't know why) - "09C", # Helping Hand - "0AD", # Feint - # Protection moves - "0AA", # Detect, Protect - "0AB", # Quick Guard - "0AC", # Wide Guard - "0E8", # Endure - "149", # Mat Block - "14A", # Crafty Shield - "14B", # King's Shield - "14C", # Spiky Shield - "168", # Baneful Bunker - # Moves that call other moves - "0AE", # Mirror Move - "0AF", # Copycat - "0B0", # Me First - "0B3", # Nature Power - "0B4", # Sleep Talk - "0B5", # Assist - "0B6", # Metronome - # Move-redirecting and stealing moves - "0B1", # Magic Coat # Not listed on Bulbapedia - "0B2", # Snatch - "117", # Follow Me, Rage Powder - "16A", # Spotlight - # Set up effects that trigger upon KO - "0E6", # Grudge # Not listed on Bulbapedia - "0E7", # Destiny Bond - # Held item-moving moves - "0F1", # Covet, Thief - "0F2", # Switcheroo, Trick - "0F3", # Bestow - # Moves that start focussing at the start of the round - "115", # Focus Punch - "171", # Shell Trap - "172", # Beak Blast - # Event moves that do nothing - "133", # Hold Hands - "134" # Celebrate - ] - @moveBlacklistSignatures = [ - :SNARL, - # Signature moves - :DIAMONDSTORM, # Diancie (Gen 6) - :FLEURCANNON, # Magearna (Gen 7) - :FREEZESHOCK, # Black Kyurem (Gen 5) - :HYPERSPACEFURY, # Hoopa Unbound (Gen 6) - :HYPERSPACEHOLE, # Hoopa Confined (Gen 6) - :ICEBURN, # White Kyurem (Gen 5) - :LIGHTOFRUIN, # Eternal Flower Floette (Gen 6) - :MINDBLOWN, # Blacephalon (Gen 7) - :PHOTONGEYSER, # Necrozma (Gen 7) - :PLASMAFISTS, # Zeraora (Gen 7) - :RELICSONG, # Meloetta (Gen 5) - :SECRETSWORD, # Keldeo (Gen 5) - :SPECTRALTHIEF, # Marshadow (Gen 7) - :STEAMERUPTION, # Volcanion (Gen 6) - :TECHNOBLAST, # Genesect (Gen 5) - :THOUSANDARROWS, # Zygarde (Gen 6) - :THOUSANDWAVES, # Zygarde (Gen 6) - :VCREATE, # Victini (Gen 5) - :FAKEMOVE #not a real move - ] - end - - def pbMoveFailed?(user,targets) - @metronomeMove = nil - move_keys = GameData::Move::DATA.keys - # NOTE: You could be really unlucky and roll blacklisted moves 1000 times in - # a row. This is too unlikely to care about, though. - 1000.times do - move_id = move_keys[@battle.pbRandom(move_keys.length)] - move_data = GameData::Move.get(move_id) - next if @moveBlacklist.include?(move_data.function_code) - next if @moveBlacklistSignatures.include?(move_data.id) - next if move_data.type == :SHADOW - @metronomeMove = move_data.id - break - end - if !@metronomeMove - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - user.pbUseMoveSimple(@metronomeMove) - end -end - - - -#=============================================================================== -# The target can no longer use the same move twice in a row. (Torment) -#=============================================================================== -class PokeBattle_Move_0B7 < PokeBattle_Move - def ignoresSubstitute?(user); return true; end - - def pbFailsAgainstTarget?(user,target) - if target.effects[PBEffects::Torment] - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return true if pbMoveFailedAromaVeil?(user,target) - return false - end - - def pbEffectAgainstTarget(user,target) - target.effects[PBEffects::Torment] = true - @battle.pbDisplay(_INTL("{1} was subjected to torment!",target.pbThis)) - target.pbItemStatusCureCheck - end -end - - - -#=============================================================================== -# Disables all target's moves that the user also knows. (Imprison) -#=============================================================================== -class PokeBattle_Move_0B8 < PokeBattle_Move - def pbMoveFailed?(user,targets) - if user.effects[PBEffects::Imprison] - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - user.effects[PBEffects::Imprison] = true - @battle.pbDisplay(_INTL("{1} sealed any moves its target shares with it!",user.pbThis)) - end -end - - - -#=============================================================================== -# For 5 rounds, disables the last move the target used. (Disable) -#=============================================================================== -class PokeBattle_Move_0B9 < PokeBattle_Move - def ignoresSubstitute?(user); return true; end - - def pbFailsAgainstTarget?(user,target) - if target.effects[PBEffects::Disable]>0 || !target.lastRegularMoveUsed - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return true if pbMoveFailedAromaVeil?(user,target) - canDisable = false - target.eachMove do |m| - next if m.id!=target.lastRegularMoveUsed - next if m.pp==0 && m.total_pp>0 - canDisable = true - break - end - if !canDisable - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectAgainstTarget(user,target) - target.effects[PBEffects::Disable] = 5 - target.effects[PBEffects::DisableMove] = target.lastRegularMoveUsed - @battle.pbDisplay(_INTL("{1}'s {2} was disabled!",target.pbThis, - GameData::Move.get(target.lastRegularMoveUsed).name)) - target.pbItemStatusCureCheck - end -end - - - -#=============================================================================== -# For 4 rounds, disables the target's non-damaging moves. (Taunt) -#=============================================================================== -class PokeBattle_Move_0BA < PokeBattle_Move - def ignoresSubstitute?(user); return true; end - - def pbFailsAgainstTarget?(user,target) - if target.effects[PBEffects::Taunt]>0 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return true if pbMoveFailedAromaVeil?(user,target) - if Settings::MECHANICS_GENERATION >= 6 && target.hasActiveAbility?(:OBLIVIOUS) && - !@battle.moldBreaker - @battle.pbShowAbilitySplash(target) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - @battle.pbDisplay(_INTL("But it failed!")) - else - @battle.pbDisplay(_INTL("But it failed because of {1}'s {2}!", - target.pbThis(true),target.abilityName)) - end - @battle.pbHideAbilitySplash(target) - return true - end - return false - end - - def pbEffectAgainstTarget(user,target) - target.effects[PBEffects::Taunt] = 4 - @battle.pbDisplay(_INTL("{1} fell for the taunt!",target.pbThis)) - target.pbItemStatusCureCheck - end -end - - - -#=============================================================================== -# For 5 rounds, disables the target's healing moves. (Heal Block) -#=============================================================================== -class PokeBattle_Move_0BB < PokeBattle_Move - def pbFailsAgainstTarget?(user,target) - if target.effects[PBEffects::HealBlock]>0 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return true if pbMoveFailedAromaVeil?(user,target) - return false - end - - def pbEffectAgainstTarget(user,target) - target.effects[PBEffects::HealBlock] = 5 - @battle.pbDisplay(_INTL("{1} was prevented from healing!",target.pbThis)) - target.pbItemStatusCureCheck - end -end - - - -#=============================================================================== -# For 4 rounds, the target must use the same move each round. (Encore) -#=============================================================================== -class PokeBattle_Move_0BC < PokeBattle_Move - def ignoresSubstitute?(user); return true; end - - def initialize(battle,move) - super - @moveBlacklist = [ - "0BC", # Encore - # Struggle - "002", # Struggle - # Moves that affect the moveset - "05C", # Mimic - "05D", # Sketch - "069", # Transform - # Moves that call other moves (see also below) - "0AE" # Mirror Move - ] - if Settings::MECHANICS_GENERATION >= 7 - @moveBlacklist += [ - # Moves that call other moves -# "0AE", # Mirror Move # See above - "0AF", # Copycat - "0B0", # Me First - "0B3", # Nature Power - "0B4", # Sleep Talk - "0B5", # Assist - "0B6" # Metronome - ] - end - end - - def pbFailsAgainstTarget?(user,target) - if target.effects[PBEffects::Encore]>0 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - if !target.lastRegularMoveUsed || - @moveBlacklist.include?(GameData::Move.get(target.lastRegularMoveUsed).function_code) - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - if target.effects[PBEffects::ShellTrap] - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return true if pbMoveFailedAromaVeil?(user,target) - canEncore = false - target.eachMove do |m| - next if m.id!=target.lastRegularMoveUsed - next if m.pp==0 && m.total_pp>0 - canEncore = true - break - end - if !canEncore - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectAgainstTarget(user,target) - target.effects[PBEffects::Encore] = 4 - target.effects[PBEffects::EncoreMove] = target.lastRegularMoveUsed - @battle.pbDisplay(_INTL("{1} received an encore!",target.pbThis)) - target.pbItemStatusCureCheck - end -end - - - -#=============================================================================== -# Hits twice. -#=============================================================================== -class PokeBattle_Move_0BD < PokeBattle_Move - def multiHitMove?; return true; end - def pbNumHits(user,targets); return 2; end -end - - - -#=============================================================================== -# Hits twice. May poison the target on each hit. (Twineedle) -#=============================================================================== -class PokeBattle_Move_0BE < PokeBattle_PoisonMove - def multiHitMove?; return true; end - def pbNumHits(user,targets); return 2; end -end - - - -#=============================================================================== -# Hits 3 times. Power is multiplied by the hit number. (Triple Kick) -# An accuracy check is performed for each hit. -#=============================================================================== -class PokeBattle_Move_0BF < PokeBattle_Move - def multiHitMove?; return true; end - def pbNumHits(user,targets); return 3; end - - def successCheckPerHit? - return @accCheckPerHit - end - - def pbOnStartUse(user,targets) - @calcBaseDmg = 0 - @accCheckPerHit = !user.hasActiveAbility?(:SKILLLINK) - end - - def pbBaseDamage(baseDmg,user,target) - @calcBaseDmg += baseDmg - return @calcBaseDmg - end -end - - - -#=============================================================================== -# Hits 2-5 times. -#=============================================================================== -class PokeBattle_Move_0C0 < PokeBattle_Move - def multiHitMove?; return true; end - - def pbNumHits(user,targets) - if @id == :WATERSHURIKEN && user.isSpecies?(:GRENINJA) && user.form == 2 - return 3 - end - hitChances = [2,2,3,3,4,5] - r = @battle.pbRandom(hitChances.length) - r = hitChances.length-1 if user.hasActiveAbility?(:SKILLLINK) - return hitChances[r] - end - - def pbBaseDamage(baseDmg,user,target) - if @id == :WATERSHURIKEN && user.isSpecies?(:GRENINJA) && user.form == 2 - return 20 - end - return super - end -end - - - -#=============================================================================== -# Hits X times, where X is the number of non-user unfainted status-free Pokémon -# in the user's party (not including partner trainers). Fails if X is 0. -# Base power of each hit depends on the base Attack stat for the species of that -# hit's participant. (Beat Up) -#=============================================================================== -class PokeBattle_Move_0C1 < PokeBattle_Move - def multiHitMove?; return true; end - - def pbMoveFailed?(user,targets) - @beatUpList = [] - @battle.eachInTeamFromBattlerIndex(user.index) do |pkmn,i| - next if !pkmn.able? || pkmn.status != :NONE - @beatUpList.push(i) - end - if @beatUpList.length==0 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbNumHits(user,targets) - return @beatUpList.length - end - - def pbBaseDamage(baseDmg,user,target) - i = @beatUpList.shift # First element in array, and removes it from array - atk = @battle.pbParty(user.index)[i].baseStats[:ATTACK] - return 5+(atk/10) - end -end - - - -#=============================================================================== -# Two turn attack. Attacks first turn, skips second turn (if successful). -#=============================================================================== -class PokeBattle_Move_0C2 < PokeBattle_Move - def pbEffectGeneral(user) - user.effects[PBEffects::HyperBeam] = 2 - user.currentMove = @id - end -end - - - -#=============================================================================== -# Two turn attack. Skips first turn, attacks second turn. (Razor Wind) -#=============================================================================== -class PokeBattle_Move_0C3 < PokeBattle_TwoTurnMove - def pbChargingTurnMessage(user,targets) - @battle.pbDisplay(_INTL("{1} whipped up a whirlwind!",user.pbThis)) - end -end - - - -#=============================================================================== -# Two turn attack. Skips first turn, attacks second turn. (Solar Beam, Solar Blade) -# Power halved in all weather except sunshine. In sunshine, takes 1 turn instead. -#=============================================================================== -class PokeBattle_Move_0C4 < PokeBattle_TwoTurnMove - def pbIsChargingTurn?(user) - ret = super - if !user.effects[PBEffects::TwoTurnAttack] - if [:Sun, :HarshSun].include?(@battle.pbWeather) - @powerHerb = false - @chargingTurn = true - @damagingTurn = true - return false - end - end - return ret - end - - def pbChargingTurnMessage(user,targets) - @battle.pbDisplay(_INTL("{1} took in sunlight!",user.pbThis)) - end - - def pbBaseDamageMultiplier(damageMult,user,target) - damageMult /= 2 if ![:None, :Sun, :HarshSun].include?(@battle.pbWeather) - return damageMult - end -end - - - -#=============================================================================== -# Two turn attack. Skips first turn, attacks second turn. (Freeze Shock) -# May paralyze the target. -#=============================================================================== -class PokeBattle_Move_0C5 < PokeBattle_TwoTurnMove - def pbChargingTurnMessage(user,targets) - @battle.pbDisplay(_INTL("{1} became cloaked in a freezing light!",user.pbThis)) - end - - def pbAdditionalEffect(user,target) - return if target.damageState.substitute - target.pbParalyze(user) if target.pbCanParalyze?(user,false,self) - end -end - - - -#=============================================================================== -# Two turn attack. Skips first turn, attacks second turn. (Ice Burn) -# May burn the target. -#=============================================================================== -class PokeBattle_Move_0C6 < PokeBattle_TwoTurnMove - def pbChargingTurnMessage(user,targets) - @battle.pbDisplay(_INTL("{1} became cloaked in freezing air!",user.pbThis)) - end - - def pbAdditionalEffect(user,target) - return if target.damageState.substitute - target.pbBurn(user) if target.pbCanBurn?(user,false,self) - end -end - - - -#=============================================================================== -# Two turn attack. Skips first turn, attacks second turn. (Sky Attack) -# May make the target flinch. -#=============================================================================== -class PokeBattle_Move_0C7 < PokeBattle_TwoTurnMove - def flinchingMove?; return true; end - - def pbChargingTurnMessage(user,targets) - @battle.pbDisplay(_INTL("{1} became cloaked in a harsh light!",user.pbThis)) - end - - def pbAdditionalEffect(user,target) - return if target.damageState.substitute - target.pbFlinch(user) - end -end - - - -#=============================================================================== -# Two turn attack. Ups user's Defense by 1 stage first turn, attacks second turn. -# (Skull Bash) -#=============================================================================== -class PokeBattle_Move_0C8 < PokeBattle_TwoTurnMove - def pbChargingTurnMessage(user,targets) - @battle.pbDisplay(_INTL("{1} tucked in its head!",user.pbThis)) - end - - def pbChargingTurnEffect(user,target) - if user.pbCanRaiseStatStage?(:DEFENSE,user,self) - user.pbRaiseStatStage(:DEFENSE,1,user) - end - end -end - - - -#=============================================================================== -# Two turn attack. Skips first turn, attacks second turn. (Fly) -# (Handled in Battler's pbSuccessCheckPerHit): Is semi-invulnerable during use. -#=============================================================================== -class PokeBattle_Move_0C9 < PokeBattle_TwoTurnMove - def unusableInGravity?; return true; end - - def pbChargingTurnMessage(user,targets) - @battle.pbDisplay(_INTL("{1} flew up high!",user.pbThis)) - end -end - - - -#=============================================================================== -# Two turn attack. Skips first turn, attacks second turn. (Dig) -# (Handled in Battler's pbSuccessCheckPerHit): Is semi-invulnerable during use. -#=============================================================================== -class PokeBattle_Move_0CA < PokeBattle_TwoTurnMove - def pbChargingTurnMessage(user,targets) - @battle.pbDisplay(_INTL("{1} burrowed its way under the ground!",user.pbThis)) - end -end - - - -#=============================================================================== -# Two turn attack. Skips first turn, attacks second turn. (Dive) -# (Handled in Battler's pbSuccessCheckPerHit): Is semi-invulnerable during use. -#=============================================================================== -class PokeBattle_Move_0CB < PokeBattle_TwoTurnMove - def pbChargingTurnMessage(user,targets) - @battle.pbDisplay(_INTL("{1} hid underwater!",user.pbThis)) - end -end - - - -#=============================================================================== -# Two turn attack. Skips first turn, attacks second turn. (Bounce) -# May paralyze the target. -# (Handled in Battler's pbSuccessCheckPerHit): Is semi-invulnerable during use. -#=============================================================================== -class PokeBattle_Move_0CC < PokeBattle_TwoTurnMove - def unusableInGravity?; return true; end - - def pbChargingTurnMessage(user,targets) - @battle.pbDisplay(_INTL("{1} sprang up!",user.pbThis)) - end - - def pbAdditionalEffect(user,target) - return if target.damageState.substitute - target.pbParalyze(user) if target.pbCanParalyze?(user,false,self) - end -end - - - -#=============================================================================== -# Two turn attack. Skips first turn, attacks second turn. (Shadow Force) -# Is invulnerable during use. Ends target's protections upon hit. -#=============================================================================== -class PokeBattle_Move_0CD < PokeBattle_TwoTurnMove - def pbChargingTurnMessage(user,targets) - @battle.pbDisplay(_INTL("{1} vanished instantly!",user.pbThis)) - end - - def pbAttackingTurnEffect(user,target) - target.effects[PBEffects::BanefulBunker] = false - target.effects[PBEffects::KingsShield] = false - target.effects[PBEffects::Protect] = false - target.effects[PBEffects::SpikyShield] = false - target.pbOwnSide.effects[PBEffects::CraftyShield] = false - target.pbOwnSide.effects[PBEffects::MatBlock] = false - target.pbOwnSide.effects[PBEffects::QuickGuard] = false - target.pbOwnSide.effects[PBEffects::WideGuard] = false - end -end - - - -#=============================================================================== -# Two turn attack. Skips first turn, attacks second turn. (Sky Drop) -# (Handled in Battler's pbSuccessCheckPerHit): Is semi-invulnerable during use. -# Target is also semi-invulnerable during use, and can't take any action. -# Doesn't damage airborne Pokémon (but still makes them unable to move during). -#=============================================================================== -class PokeBattle_Move_0CE < PokeBattle_TwoTurnMove - def unusableInGravity?; return true; end - - def pbIsChargingTurn?(user) - # NOTE: Sky Drop doesn't benefit from Power Herb, probably because it works - # differently (i.e. immobilises the target during use too). - @powerHerb = false - @chargingTurn = (user.effects[PBEffects::TwoTurnAttack].nil?) - @damagingTurn = (!user.effects[PBEffects::TwoTurnAttack].nil?) - return !@damagingTurn - end - - def pbFailsAgainstTarget?(user,target) - if !target.opposes?(user) - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - if target.effects[PBEffects::Substitute]>0 && !ignoresSubstitute?(user) - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - if Settings::MECHANICS_GENERATION >= 6 && target.pbWeight>=2000 # 200.0kg - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - if target.semiInvulnerable? || - (target.effects[PBEffects::SkyDrop]>=0 && @chargingTurn) - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - if target.effects[PBEffects::SkyDrop]!=user.index && @damagingTurn - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbCalcTypeMod(movetype,user,target) - return Effectiveness::INEFFECTIVE if target.pbHasType?(:FLYING) - return super - end - - def pbChargingTurnMessage(user,targets) - @battle.pbDisplay(_INTL("{1} took {2} into the sky!",user.pbThis,targets[0].pbThis(true))) - end - - def pbAttackingTurnMessage(user,targets) - @battle.pbDisplay(_INTL("{1} was freed from the Sky Drop!",targets[0].pbThis)) - end - - def pbChargingTurnEffect(user,target) - target.effects[PBEffects::SkyDrop] = user.index - end - - def pbAttackingTurnEffect(user,target) - target.effects[PBEffects::SkyDrop] = -1 - end -end - - - -#=============================================================================== -# Trapping move. Traps for 5 or 6 rounds. Trapped Pokémon lose 1/16 of max HP -# at end of each round. -#=============================================================================== -class PokeBattle_Move_0CF < PokeBattle_Move - def pbEffectAgainstTarget(user,target) - return if target.fainted? || target.damageState.substitute - return if target.effects[PBEffects::Trapping]>0 - # Set trapping effect duration and info - if user.hasActiveItem?(:GRIPCLAW) - target.effects[PBEffects::Trapping] = (Settings::MECHANICS_GENERATION >= 5) ? 8 : 6 - else - target.effects[PBEffects::Trapping] = 5+@battle.pbRandom(2) - end - target.effects[PBEffects::TrappingMove] = @id - target.effects[PBEffects::TrappingUser] = user.index - # Message - msg = _INTL("{1} was trapped in the vortex!",target.pbThis) - case @id - when :BIND - msg = _INTL("{1} was squeezed by {2}!",target.pbThis,user.pbThis(true)) - when :CLAMP - msg = _INTL("{1} clamped {2}!",user.pbThis,target.pbThis(true)) - when :FIRESPIN - msg = _INTL("{1} was trapped in the fiery vortex!",target.pbThis) - when :INFESTATION - msg = _INTL("{1} has been afflicted with an infestation by {2}!",target.pbThis,user.pbThis(true)) - when :MAGMASTORM - msg = _INTL("{1} became trapped by Magma Storm!",target.pbThis) - when :SANDTOMB - msg = _INTL("{1} became trapped by Sand Tomb!",target.pbThis) - when :WHIRLPOOL - msg = _INTL("{1} became trapped in the vortex!",target.pbThis) - when :WRAP - msg = _INTL("{1} was wrapped by {2}!",target.pbThis,user.pbThis(true)) - end - @battle.pbDisplay(msg) - end -end - - - -#=============================================================================== -# Trapping move. Traps for 5 or 6 rounds. Trapped Pokémon lose 1/16 of max HP -# at end of each round. (Whirlpool) -# Power is doubled if target is using Dive. Hits some semi-invulnerable targets. -#=============================================================================== -class PokeBattle_Move_0D0 < PokeBattle_Move_0CF - def hitsDivingTargets?; return true; end - - def pbModifyDamage(damageMult,user,target) - damageMult *= 2 if target.inTwoTurnAttack?("0CB") # Dive - return damageMult - end -end - - - -#=============================================================================== -# User must use this move for 2 more rounds. No battlers can sleep. (Uproar) -# NOTE: Bulbapedia claims that an uproar will wake up Pokémon even if they have -# Soundproof, and will not allow Pokémon to fall asleep even if they have -# Soundproof. I think this is an oversight, so I've let Soundproof Pokémon -# be unaffected by Uproar waking/non-sleeping effects. -#=============================================================================== -class PokeBattle_Move_0D1 < PokeBattle_Move - def pbEffectGeneral(user) - return if user.effects[PBEffects::Uproar]>0 - user.effects[PBEffects::Uproar] = 3 - user.currentMove = @id - @battle.pbDisplay(_INTL("{1} caused an uproar!",user.pbThis)) - @battle.pbPriority(true).each do |b| - next if b.fainted? || b.status != :SLEEP - next if b.hasActiveAbility?(:SOUNDPROOF) - b.pbCureStatus - end - end -end - - - -#=============================================================================== -# User must use this move for 1 or 2 more rounds. At end, user becomes confused. -# (Outrage, Petal Dange, Thrash) -#=============================================================================== -class PokeBattle_Move_0D2 < PokeBattle_Move - def pbEffectAfterAllHits(user,target) - if !target.damageState.unaffected && user.effects[PBEffects::Outrage]==0 - user.effects[PBEffects::Outrage] = 2+@battle.pbRandom(2) - user.currentMove = @id - end - if user.effects[PBEffects::Outrage]>0 - user.effects[PBEffects::Outrage] -= 1 - if user.effects[PBEffects::Outrage]==0 && user.pbCanConfuseSelf?(false) - user.pbConfuse(_INTL("{1} became confused due to fatigue!",user.pbThis)) - end - end - end -end - - - -#=============================================================================== -# User must use this move for 4 more rounds. Power doubles each round. -# Power is also doubled if user has curled up. (Ice Ball, Rollout) -#=============================================================================== -class PokeBattle_Move_0D3 < PokeBattle_Move - def pbBaseDamage(baseDmg,user,target) - shift = (5 - user.effects[PBEffects::Rollout]) # 0-4, where 0 is most powerful - shift = 0 if user.effects[PBEffects::Rollout] == 0 # For first turn - shift += 1 if user.effects[PBEffects::DefenseCurl] - baseDmg *= 2**shift - return baseDmg - end - - def pbEffectAfterAllHits(user,target) - if !target.damageState.unaffected && user.effects[PBEffects::Rollout] == 0 - user.effects[PBEffects::Rollout] = 5 - user.currentMove = @id - end - user.effects[PBEffects::Rollout] -= 1 if user.effects[PBEffects::Rollout] > 0 - end -end - - - -#=============================================================================== -# User bides its time this round and next round. The round after, deals 2x the -# total direct damage it took while biding to the last battler that damaged it. -# (Bide) -#=============================================================================== -class PokeBattle_Move_0D4 < PokeBattle_FixedDamageMove - def pbAddTarget(targets,user) - return if user.effects[PBEffects::Bide]!=1 # Not the attack turn - idxTarget = user.effects[PBEffects::BideTarget] - t = (idxTarget>=0) ? @battle.battlers[idxTarget] : nil - if !user.pbAddTarget(targets,user,t,self,false) - user.pbAddTargetRandomFoe(targets,user,self,false) - end - end - - def pbMoveFailed?(user,targets) - return false if user.effects[PBEffects::Bide]!=1 # Not the attack turn - if user.effects[PBEffects::BideDamage]==0 - @battle.pbDisplay(_INTL("But it failed!")) - user.effects[PBEffects::Bide] = 0 # No need to reset other Bide variables - return true - end - if targets.length==0 - @battle.pbDisplay(_INTL("But there was no target...")) - user.effects[PBEffects::Bide] = 0 # No need to reset other Bide variables - return true - end - return false - end - - def pbOnStartUse(user,targets) - @damagingTurn = (user.effects[PBEffects::Bide]==1) # If attack turn - end - - def pbDisplayUseMessage(user) - if @damagingTurn # Attack turn - @battle.pbDisplayBrief(_INTL("{1} unleashed energy!",user.pbThis)) - elsif user.effects[PBEffects::Bide]>1 # Charging turns - @battle.pbDisplayBrief(_INTL("{1} is storing energy!",user.pbThis)) - else - super # Start using Bide - end - end - - def pbDamagingMove? # Stops damage being dealt in the charging turns - return false if !@damagingTurn - return super - end - - def pbFixedDamage(user,target) - return user.effects[PBEffects::BideDamage]*2 - end - - def pbEffectGeneral(user) - if user.effects[PBEffects::Bide]==0 # Starting using Bide - user.effects[PBEffects::Bide] = 3 - user.effects[PBEffects::BideDamage] = 0 - user.effects[PBEffects::BideTarget] = -1 - user.currentMove = @id - end - user.effects[PBEffects::Bide] -= 1 - end - - def pbShowAnimation(id,user,targets,hitNum=0,showAnimation=true) - hitNum = 1 if !@damagingTurn # Charging anim - super - end -end - - - -#=============================================================================== -# Heals user by 1/2 of its max HP. -#=============================================================================== -class PokeBattle_Move_0D5 < PokeBattle_HealingMove - def pbHealAmount(user) - return (user.totalhp/2.0).round - end -end - - - -#=============================================================================== -# Heals user by 1/2 of its max HP. (Roost) -# User roosts, and its Flying type is ignored for attacks used against it. -#=============================================================================== -class PokeBattle_Move_0D6 < PokeBattle_HealingMove - def pbHealAmount(user) - return (user.totalhp/2.0).round - end - - def pbEffectAfterAllHits(user,target) - user.effects[PBEffects::Roost] = true - end -end - - - -#=============================================================================== -# Battler in user's position is healed by 1/2 of its max HP, at the end of the -# next round. (Wish) -#=============================================================================== -class PokeBattle_Move_0D7 < PokeBattle_Move - def healingMove?; return true; end - - def pbMoveFailed?(user,targets) - if @battle.positions[user.index].effects[PBEffects::Wish]>0 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - @battle.positions[user.index].effects[PBEffects::Wish] = 2 - @battle.positions[user.index].effects[PBEffects::WishAmount] = (user.totalhp/2.0).round - @battle.positions[user.index].effects[PBEffects::WishMaker] = user.pokemonIndex - end -end - - - -#=============================================================================== -# Heals user by an amount depending on the weather. (Moonlight, Morning Sun, -# Synthesis) -#=============================================================================== -class PokeBattle_Move_0D8 < PokeBattle_HealingMove - def pbOnStartUse(user,targets) - case @battle.pbWeather - when :Sun, :HarshSun - @healAmount = (user.totalhp*2/3.0).round - when :None, :StrongWinds - @healAmount = (user.totalhp/2.0).round - else - @healAmount = (user.totalhp/4.0).round - end - end - - def pbHealAmount(user) - return @healAmount - end -end - - - -#=============================================================================== -# Heals user to full HP. User falls asleep for 2 more rounds. (Rest) -#=============================================================================== -class PokeBattle_Move_0D9 < PokeBattle_HealingMove - def pbMoveFailed?(user,targets) - if user.asleep? - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return true if !user.pbCanSleep?(user,true,self,true) - return true if super - return false - end - - def pbHealAmount(user) - return user.totalhp-user.hp - end - - def pbEffectGeneral(user) - user.pbSleepSelf(_INTL("{1} slept and became healthy!",user.pbThis),3) - super - end -end - - - -#=============================================================================== -# Rings the user. Ringed Pokémon gain 1/16 of max HP at the end of each round. -# (Aqua Ring) -#=============================================================================== -class PokeBattle_Move_0DA < PokeBattle_Move - def pbMoveFailed?(user,targets) - if user.effects[PBEffects::AquaRing] - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - user.effects[PBEffects::AquaRing] = true - @battle.pbDisplay(_INTL("{1} surrounded itself with a veil of water!",user.pbThis)) - end -end - - - -#=============================================================================== -# Ingrains the user. Ingrained Pokémon gain 1/16 of max HP at the end of each -# round, and cannot flee or switch out. (Ingrain) -#=============================================================================== -class PokeBattle_Move_0DB < PokeBattle_Move - def pbMoveFailed?(user,targets) - if user.effects[PBEffects::Ingrain] - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - user.effects[PBEffects::Ingrain] = true - @battle.pbDisplay(_INTL("{1} planted its roots!",user.pbThis)) - end -end - - - -#=============================================================================== -# Seeds the target. Seeded Pokémon lose 1/8 of max HP at the end of each round, -# and the Pokémon in the user's position gains the same amount. (Leech Seed) -#=============================================================================== -class PokeBattle_Move_0DC < PokeBattle_Move - def pbFailsAgainstTarget?(user,target) - if target.effects[PBEffects::LeechSeed]>=0 - @battle.pbDisplay(_INTL("{1} evaded the attack!",target.pbThis)) - return true - end - if target.pbHasType?(:GRASS) - @battle.pbDisplay(_INTL("It doesn't affect {1}...",target.pbThis(true))) - return true - end - return false - end - - def pbMissMessage(user,target) - @battle.pbDisplay(_INTL("{1} evaded the attack!",target.pbThis)) - return true - end - - def pbEffectAgainstTarget(user,target) - target.effects[PBEffects::LeechSeed] = user.index - @battle.pbDisplay(_INTL("{1} was seeded!",target.pbThis)) - end -end - - - -#=============================================================================== -# User gains half the HP it inflicts as damage. -#=============================================================================== -class PokeBattle_Move_0DD < PokeBattle_Move - def healingMove?; return Settings::MECHANICS_GENERATION >= 6; end - - def pbEffectAgainstTarget(user,target) - return if target.damageState.hpLost<=0 - hpGain = (target.damageState.hpLost/2.0).round - user.pbRecoverHPFromDrain(hpGain,target) - end -end - - - -#=============================================================================== -# User gains half the HP it inflicts as damage. Fails if target is not asleep. -# (Dream Eater) -#=============================================================================== -class PokeBattle_Move_0DE < PokeBattle_Move - def healingMove?; return Settings::MECHANICS_GENERATION >= 6; end - - def pbFailsAgainstTarget?(user,target) - if !target.asleep? - @battle.pbDisplay(_INTL("{1} wasn't affected!",target.pbThis)) - return true - end - return false - end - - def pbEffectAgainstTarget(user,target) - return if target.damageState.hpLost<=0 - hpGain = (target.damageState.hpLost/2.0).round - user.pbRecoverHPFromDrain(hpGain,target) - end -end - - - -#=============================================================================== -# Heals target by 1/2 of its max HP. (Heal Pulse) -#=============================================================================== -class PokeBattle_Move_0DF < PokeBattle_Move - def healingMove?; return true; end - - def pbFailsAgainstTarget?(user,target) - if target.hp==target.totalhp - @battle.pbDisplay(_INTL("{1}'s HP is full!",target.pbThis)) - return true - elsif !target.canHeal? - @battle.pbDisplay(_INTL("{1} is unaffected!",target.pbThis)) - return true - end - return false - end - - def pbEffectAgainstTarget(user,target) - hpGain = (target.totalhp/2.0).round - if pulseMove? && user.hasActiveAbility?(:MEGALAUNCHER) - hpGain = (target.totalhp*3/4.0).round - end - target.pbRecoverHP(hpGain) - @battle.pbDisplay(_INTL("{1}'s HP was restored.",target.pbThis)) - end -end - - - -#=============================================================================== -# User faints, even if the move does nothing else. (Explosion, Self-Destruct) -#=============================================================================== -class PokeBattle_Move_0E0 < PokeBattle_Move - def worksWithNoTargets?; return true; end - def pbNumHits(user,targets); return 1; end - - def pbMoveFailed?(user,targets) - if !@battle.moldBreaker - bearer = @battle.pbCheckGlobalAbility(:DAMP) - if bearer!=nil - @battle.pbShowAbilitySplash(bearer) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - @battle.pbDisplay(_INTL("{1} cannot use {2}!",user.pbThis,@name)) - else - @battle.pbDisplay(_INTL("{1} cannot use {2} because of {3}'s {4}!", - user.pbThis,@name,bearer.pbThis(true),bearer.abilityName)) - end - @battle.pbHideAbilitySplash(bearer) - return true - end - end - return false - end - - def pbSelfKO(user) - return if user.fainted? - user.pbReduceHP(user.hp,false) - user.pbItemHPHealCheck - end -end - - - -#=============================================================================== -# Inflicts fixed damage equal to user's current HP. (Final Gambit) -# User faints (if successful). -#=============================================================================== -class PokeBattle_Move_0E1 < PokeBattle_FixedDamageMove - def pbNumHits(user,targets); return 1; end - - def pbOnStartUse(user,targets) - @finalGambitDamage = user.hp - end - - def pbFixedDamage(user,target) - return @finalGambitDamage - end - - def pbSelfKO(user) - return if user.fainted? - user.pbReduceHP(user.hp,false) - user.pbItemHPHealCheck - end -end - - - -#=============================================================================== -# Decreases the target's Attack and Special Attack by 2 stages each. (Memento) -# User faints (if successful). -#=============================================================================== -class PokeBattle_Move_0E2 < PokeBattle_TargetMultiStatDownMove - def initialize(battle,move) - super - @statDown = [:ATTACK,2,:SPECIAL_ATTACK,2] - end - - # NOTE: The user faints even if the target's stats cannot be changed, so this - # method must always return false to allow the move's usage to continue. - def pbFailsAgainstTarget?(user,target) - return false - end - - def pbSelfKO(user) - return if user.fainted? - user.pbReduceHP(user.hp,false) - user.pbItemHPHealCheck - end -end - - - -#=============================================================================== -# User faints. The Pokémon that replaces the user is fully healed (HP and -# status). Fails if user won't be replaced. (Healing Wish) -#=============================================================================== -class PokeBattle_Move_0E3 < PokeBattle_Move - def healingMove?; return true; end - - def pbMoveFailed?(user,targets) - if !@battle.pbCanChooseNonActive?(user.index) - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbSelfKO(user) - return if user.fainted? - user.pbReduceHP(user.hp,false) - user.pbItemHPHealCheck - @battle.positions[user.index].effects[PBEffects::HealingWish] = true - end -end - - - -#=============================================================================== -# User faints. The Pokémon that replaces the user is fully healed (HP, PP and -# status). Fails if user won't be replaced. (Lunar Dance) -#=============================================================================== -class PokeBattle_Move_0E4 < PokeBattle_Move - def healingMove?; return true; end - - def pbMoveFailed?(user,targets) - if !@battle.pbCanChooseNonActive?(user.index) - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbSelfKO(user) - return if user.fainted? - user.pbReduceHP(user.hp,false) - user.pbItemHPHealCheck - @battle.positions[user.index].effects[PBEffects::LunarDance] = true - end -end - - - -#=============================================================================== -# All current battlers will perish after 3 more rounds. (Perish Song) -#=============================================================================== -class PokeBattle_Move_0E5 < PokeBattle_Move - def pbMoveFailed?(user,targets) - failed = true - targets.each do |b| - next if b.effects[PBEffects::PerishSong]>0 # Heard it before - failed = false - break - end - if failed - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbFailsAgainstTarget?(user,target) - return target.effects[PBEffects::PerishSong]>0 # Heard it before - end - - def pbEffectAgainstTarget(user,target) - target.effects[PBEffects::PerishSong] = 4 - target.effects[PBEffects::PerishSongUser] = user.index - end - - def pbShowAnimation(id,user,targets,hitNum=0,showAnimation=true) - super - @battle.pbDisplay(_INTL("All Pokémon that hear the song will faint in three turns!")) - end -end - - - -#=============================================================================== -# If user is KO'd before it next moves, the attack that caused it loses all PP. -# (Grudge) -#=============================================================================== -class PokeBattle_Move_0E6 < PokeBattle_Move - def pbEffectGeneral(user) - user.effects[PBEffects::Grudge] = true - @battle.pbDisplay(_INTL("{1} wants its target to bear a grudge!",user.pbThis)) - end -end - - - -#=============================================================================== -# If user is KO'd before it next moves, the battler that caused it also faints. -# (Destiny Bond) -#=============================================================================== -class PokeBattle_Move_0E7 < PokeBattle_Move - def pbMoveFailed?(user,targets) - if Settings::MECHANICS_GENERATION >= 7 && user.effects[PBEffects::DestinyBondPrevious] - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - user.effects[PBEffects::DestinyBond] = true - @battle.pbDisplay(_INTL("{1} is hoping to take its attacker down with it!",user.pbThis)) - end -end - - - -#=============================================================================== -# If user would be KO'd this round, it survives with 1HP instead. (Endure) -#=============================================================================== -class PokeBattle_Move_0E8 < PokeBattle_ProtectMove - def initialize(battle,move) - super - @effect = PBEffects::Endure - end - - def pbProtectMessage(user) - @battle.pbDisplay(_INTL("{1} braced itself!",user.pbThis)) - end -end - - - -#=============================================================================== -# If target would be KO'd by this attack, it survives with 1HP instead. -# (False Swipe, Hold Back) -#=============================================================================== -class PokeBattle_Move_0E9 < PokeBattle_Move - def nonLethal?(user,target); return true; end -end - - - -#=============================================================================== -# User flees from battle. Fails in trainer battles. (Teleport) -#=============================================================================== -class PokeBattle_Move_0EA < PokeBattle_Move - def pbMoveFailed?(user,targets) - if !@battle.pbCanRun?(user.index) - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - @battle.pbDisplay(_INTL("{1} fled from battle!",user.pbThis)) - @battle.decision = 3 # Escaped - end -end - - - -#=============================================================================== -# In wild battles, makes target flee. Fails if target is a higher level than the -# user. -# In trainer battles, target switches out. -# For status moves. (Roar, Whirlwind) -#=============================================================================== -class PokeBattle_Move_0EB < PokeBattle_Move - def ignoresSubstitute?(user); return true; end - - def pbFailsAgainstTarget?(user,target) - if target.hasActiveAbility?(:SUCTIONCUPS) && !@battle.moldBreaker - @battle.pbShowAbilitySplash(target) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - @battle.pbDisplay(_INTL("{1} anchors itself!",target.pbThis)) - else - @battle.pbDisplay(_INTL("{1} anchors itself with {2}!",target.pbThis,target.abilityName)) - end - @battle.pbHideAbilitySplash(target) - return true - end - if target.effects[PBEffects::Ingrain] - @battle.pbDisplay(_INTL("{1} anchored itself with its roots!",target.pbThis)) - return true - end - if !@battle.canRun - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - # if @battle.wildBattle? && target.level>user.level - # @battle.pbDisplay(_INTL("But it failed!")) - # return true - # end - if @battle.trainerBattle? - canSwitch = false - @battle.eachInTeamFromBattlerIndex(target.index) do |_pkmn,i| - next if !@battle.pbCanSwitchLax?(target.index,i) - canSwitch = true - break - end - if !canSwitch - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - end - return false - end - - def pbEffectGeneral(user) - @battle.decision = 3 if @battle.wildBattle? # Escaped from battle - end - - def pbSwitchOutTargetsEffect(user,targets,numHits,switchedBattlers) - return if @battle.wildBattle? - return if user.fainted? || numHits==0 - roarSwitched = [] - targets.each do |b| - next if b.fainted? || b.damageState.unaffected || switchedBattlers.include?(b.index) - newPkmn = @battle.pbGetReplacementPokemonIndex(b.index,true) # Random - next if newPkmn<0 - @battle.pbRecallAndReplace(b.index, newPkmn, true) - @battle.pbDisplay(_INTL("{1} was dragged out!",b.pbThis)) - @battle.pbClearChoice(b.index) # Replacement Pokémon does nothing this round - switchedBattlers.push(b.index) - roarSwitched.push(b.index) - end - if roarSwitched.length>0 - @battle.moldBreaker = false if roarSwitched.include?(user.index) - @battle.pbPriority(true).each do |b| - b.pbEffectsOnSwitchIn(true) if roarSwitched.include?(b.index) - end - end - end -end - - - -#=============================================================================== -# In wild battles, makes target flee. Fails if target is a higher level than the -# user. -# In trainer battles, target switches out. -# For damaging moves. (Circle Throw, Dragon Tail) -#=============================================================================== -class PokeBattle_Move_0EC < PokeBattle_Move - def pbEffectAgainstTarget(user,target) - if @battle.wildBattle? && target.level<=user.level && @battle.canRun && - (target.effects[PBEffects::Substitute]==0 || ignoresSubstitute?(user)) - @battle.decision = 3 - end - end - - def pbSwitchOutTargetsEffect(user,targets,numHits,switchedBattlers) - return if @battle.wildBattle? - return if user.fainted? || numHits==0 - roarSwitched = [] - targets.each do |b| - next if b.fainted? || b.damageState.unaffected || b.damageState.substitute - next if switchedBattlers.include?(b.index) - next if b.effects[PBEffects::Ingrain] - next if b.hasActiveAbility?(:SUCTIONCUPS) && !@battle.moldBreaker - newPkmn = @battle.pbGetReplacementPokemonIndex(b.index,true) # Random - next if newPkmn<0 - @battle.pbRecallAndReplace(b.index, newPkmn, true) - @battle.pbDisplay(_INTL("{1} was dragged out!",b.pbThis)) - @battle.pbClearChoice(b.index) # Replacement Pokémon does nothing this round - switchedBattlers.push(b.index) - roarSwitched.push(b.index) - end - if roarSwitched.length>0 - @battle.moldBreaker = false if roarSwitched.include?(user.index) - @battle.pbPriority(true).each do |b| - b.pbEffectsOnSwitchIn(true) if roarSwitched.include?(b.index) - end - end - end -end - - - -#=============================================================================== -# User switches out. Various effects affecting the user are passed to the -# replacement. (Baton Pass) -#=============================================================================== -class PokeBattle_Move_0ED < PokeBattle_Move - def pbMoveFailed?(user,targets) - if !@battle.pbCanChooseNonActive?(user.index) - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEndOfMoveUsageEffect(user,targets,numHits,switchedBattlers) - return if user.fainted? || numHits==0 - return if !@battle.pbCanChooseNonActive?(user.index) - @battle.pbPursuit(user.index) - return if user.fainted? - newPkmn = @battle.pbGetReplacementPokemonIndex(user.index) # Owner chooses - return if newPkmn<0 - @battle.pbRecallAndReplace(user.index, newPkmn, false, true) - @battle.pbClearChoice(user.index) # Replacement Pokémon does nothing this round - @battle.moldBreaker = false - switchedBattlers.push(user.index) - user.pbEffectsOnSwitchIn(true) - end -end - - - -#=============================================================================== -# After inflicting damage, user switches out. Ignores trapping moves. -# (U-turn, Volt Switch) -#=============================================================================== -class PokeBattle_Move_0EE < PokeBattle_Move - def pbEndOfMoveUsageEffect(user,targets,numHits,switchedBattlers) - return if user.fainted? || numHits==0 - targetSwitched = true - targets.each do |b| - targetSwitched = false if !switchedBattlers.include?(b.index) - end - return if targetSwitched - return if !@battle.pbCanChooseNonActive?(user.index) - @battle.pbDisplay(_INTL("{1} went back to {2}!",user.pbThis, - @battle.pbGetOwnerName(user.index))) - @battle.pbPursuit(user.index) - return if user.fainted? - newPkmn = @battle.pbGetReplacementPokemonIndex(user.index) # Owner chooses - return if newPkmn<0 - @battle.pbRecallAndReplace(user.index,newPkmn) - @battle.pbClearChoice(user.index) # Replacement Pokémon does nothing this round - @battle.moldBreaker = false - switchedBattlers.push(user.index) - user.pbEffectsOnSwitchIn(true) - end -end - - - -#=============================================================================== -# Target can no longer switch out or flee, as long as the user remains active. -# (Anchor Shot, Block, Mean Look, Spider Web, Spirit Shackle, Thousand Waves) -#=============================================================================== -class PokeBattle_Move_0EF < PokeBattle_Move - def pbFailsAgainstTarget?(user,target) - return false if damagingMove? - if target.effects[PBEffects::MeanLook]>=0 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - if Settings::MORE_TYPE_EFFECTS && target.pbHasType?(:GHOST) - @battle.pbDisplay(_INTL("It doesn't affect {1}...",target.pbThis(true))) - return true - end - return false - end - - def pbEffectAgainstTarget(user,target) - return if damagingMove? - target.effects[PBEffects::MeanLook] = user.index - @battle.pbDisplay(_INTL("{1} can no longer escape!",target.pbThis)) - end - - def pbAdditionalEffect(user,target) - return if target.fainted? || target.damageState.substitute - return if target.effects[PBEffects::MeanLook]>=0 - return if Settings::MORE_TYPE_EFFECTS && target.pbHasType?(:GHOST) - target.effects[PBEffects::MeanLook] = user.index - @battle.pbDisplay(_INTL("{1} can no longer escape!",target.pbThis)) - end -end - - - -#=============================================================================== -# Target drops its item. It regains the item at the end of the battle. (Knock Off) -# If target has a losable item, damage is multiplied by 1.5. -#=============================================================================== -class PokeBattle_Move_0F0 < PokeBattle_Move - def pbBaseDamage(baseDmg,user,target) - if Settings::MECHANICS_GENERATION >= 6 && - target.item && !target.unlosableItem?(target.item) - # NOTE: Damage is still boosted even if target has Sticky Hold or a - # substitute. - baseDmg = (baseDmg*1.5).round - end - return baseDmg - end - - def pbEffectAfterAllHits(user,target) - return if @battle.wildBattle? && user.opposes? # Wild Pokémon can't knock off - return if user.fainted? - return if target.damageState.unaffected || target.damageState.substitute - return if !target.item || target.unlosableItem?(target.item) - return if target.hasActiveAbility?(:STICKYHOLD) && !@battle.moldBreaker - itemName = target.itemName - target.pbRemoveItem(false) - @battle.pbDisplay(_INTL("{1} dropped its {2}!",target.pbThis,itemName)) - end -end - - - -#=============================================================================== -# User steals the target's item, if the user has none itself. (Covet, Thief) -# Items stolen from wild Pokémon are kept after the battle. -#=============================================================================== -class PokeBattle_Move_0F1 < PokeBattle_Move - def pbEffectAfterAllHits(user,target) - return if @battle.wildBattle? && user.opposes? # Wild Pokémon can't thieve - return if user.fainted? - return if target.damageState.unaffected || target.damageState.substitute - return if !target.item || user.item - return if target.unlosableItem?(target.item) - return if user.unlosableItem?(target.item) - return if target.hasActiveAbility?(:STICKYHOLD) && !@battle.moldBreaker - itemName = target.itemName - user.item = target.item - # Permanently steal the item from wild Pokémon - # removed target.item == target.initialItem, this may cause bugs. - if @battle.wildBattle? && target.opposes? && !user.initialItem - user.setInitialItem(target.item) - end - target.pbRemoveItem(false) - @battle.pbDisplay(_INTL("{1} stole {2}'s {3}!",user.pbThis,target.pbThis(true),itemName)) - user.pbHeldItemTriggerCheck - end -end - - - -#=============================================================================== -# User and target swap items. They remain swapped after wild battles. -# (Switcheroo, Trick) -#=============================================================================== -class PokeBattle_Move_0F2 < PokeBattle_Move - def pbMoveFailed?(user,targets) - if @battle.wildBattle? && user.opposes? - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbFailsAgainstTarget?(user,target) - if !user.item && !target.item - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - if target.unlosableItem?(target.item) || - target.unlosableItem?(user.item) || - user.unlosableItem?(user.item) || - user.unlosableItem?(target.item) - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - if target.hasActiveAbility?(:STICKYHOLD) && !@battle.moldBreaker - @battle.pbShowAbilitySplash(target) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - @battle.pbDisplay(_INTL("But it failed to affect {1}!",target.pbThis(true))) - else - @battle.pbDisplay(_INTL("But it failed to affect {1} because of its {2}!", - target.pbThis(true),target.abilityName)) - end - @battle.pbHideAbilitySplash(target) - return true - end - return false - end - - def pbEffectAgainstTarget(user,target) - oldUserItem = user.item; oldUserItemName = user.itemName - oldTargetItem = target.item; oldTargetItemName = target.itemName - user.item = oldTargetItem - user.effects[PBEffects::ChoiceBand] = nil - user.effects[PBEffects::Unburden] = (!user.item && oldUserItem) - target.item = oldUserItem - target.effects[PBEffects::ChoiceBand] = nil - target.effects[PBEffects::Unburden] = (!target.item && oldTargetItem) - # Permanently steal the item from wild Pokémon - if @battle.wildBattle? && target.opposes? && - target.initialItem==oldTargetItem && !user.initialItem - user.setInitialItem(oldTargetItem) - end - @battle.pbDisplay(_INTL("{1} switched items with its opponent!",user.pbThis)) - @battle.pbDisplay(_INTL("{1} obtained {2}.",user.pbThis,oldTargetItemName)) if oldTargetItem - @battle.pbDisplay(_INTL("{1} obtained {2}.",target.pbThis,oldUserItemName)) if oldUserItem - user.pbHeldItemTriggerCheck - target.pbHeldItemTriggerCheck - end -end - - - -#=============================================================================== -# User gives its item to the target. The item remains given after wild battles. -# (Bestow) -#=============================================================================== -class PokeBattle_Move_0F3 < PokeBattle_Move - def ignoresSubstitute?(user) - return true if Settings::MECHANICS_GENERATION >= 6 - return super - end - - def pbMoveFailed?(user,targets) - if !user.item || user.unlosableItem?(user.item) - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbFailsAgainstTarget?(user,target) - if target.item || target.unlosableItem?(user.item) - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectAgainstTarget(user,target) - itemName = user.itemName - target.item = user.item - # Permanently steal the item from wild Pokémon - if @battle.wildBattle? && user.opposes? && - user.initialItem==user.item && !target.initialItem - target.setInitialItem(user.item) - user.pbRemoveItem - else - user.pbRemoveItem(false) - end - @battle.pbDisplay(_INTL("{1} received {2} from {3}!",target.pbThis,itemName,user.pbThis(true))) - target.pbHeldItemTriggerCheck - end -end - - - -#=============================================================================== -# User consumes target's berry and gains its effect. (Bug Bite, Pluck) -#=============================================================================== -class PokeBattle_Move_0F4 < PokeBattle_Move - def pbEffectAfterAllHits(user,target) - return if user.fainted? || target.fainted? - return if target.damageState.unaffected || target.damageState.substitute - return if !target.item || !target.item.is_berry? - return if target.hasActiveAbility?(:STICKYHOLD) && !@battle.moldBreaker - item = target.item - itemName = target.itemName - target.pbRemoveItem - @battle.pbDisplay(_INTL("{1} stole and ate its target's {2}!",user.pbThis,itemName)) - user.pbHeldItemTriggerCheck(item,false) - end -end - - - -#=============================================================================== -# Target's berry/Gem is destroyed. (Incinerate) -#=============================================================================== -class PokeBattle_Move_0F5 < PokeBattle_Move - def pbEffectWhenDealingDamage(user,target) - return if target.damageState.substitute || target.damageState.berryWeakened - return if !target.item || (!target.item.is_berry? && - !(Settings::MECHANICS_GENERATION >= 6 && target.item.is_gem?)) - target.pbRemoveItem - @battle.pbDisplay(_INTL("{1}'s {2} was incinerated!",target.pbThis,target.itemName)) - end -end - - - -#=============================================================================== -# User recovers the last item it held and consumed. (Recycle) -#=============================================================================== -class PokeBattle_Move_0F6 < PokeBattle_Move - def pbMoveFailed?(user,targets) - if !user.recycleItem - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - item = user.recycleItem - user.item = item - user.setInitialItem(item) if @battle.wildBattle? && !user.initialItem - user.setRecycleItem(nil) - user.effects[PBEffects::PickupItem] = nil - user.effects[PBEffects::PickupUse] = 0 - itemName = GameData::Item.get(item).name - if itemName.starts_with_vowel? - @battle.pbDisplay(_INTL("{1} found an {2}!",user.pbThis,itemName)) - else - @battle.pbDisplay(_INTL("{1} found a {2}!",user.pbThis,itemName)) - end - user.pbHeldItemTriggerCheck - end -end - - - -#=============================================================================== -# User flings its item at the target. Power/effect depend on the item. (Fling) -#=============================================================================== -class PokeBattle_Move_0F7 < PokeBattle_Move - def initialize(battle,move) - super - # 80 => all Mega Stones - # 10 => all Berries - @flingPowers = { - 130 => [:IRONBALL - ], - 100 => [:HARDSTONE,:RAREBONE, - # Fossils - :ARMORFOSSIL,:CLAWFOSSIL,:COVERFOSSIL,:DOMEFOSSIL,:HELIXFOSSIL, - :JAWFOSSIL,:OLDAMBER,:PLUMEFOSSIL,:ROOTFOSSIL,:SAILFOSSIL, - :SKULLFOSSIL - ], - 90 => [:DEEPSEATOOTH,:GRIPCLAW,:THICKCLUB, - # Plates - :DRACOPLATE,:DREADPLATE,:EARTHPLATE,:FISTPLATE,:FLAMEPLATE, - :ICICLEPLATE,:INSECTPLATE,:IRONPLATE,:MEADOWPLATE,:MINDPLATE, - :PIXIEPLATE,:SKYPLATE,:SPLASHPLATE,:SPOOKYPLATE,:STONEPLATE, - :TOXICPLATE,:ZAPPLATE - ], - 80 => [:ASSAULTVEST,:DAWNSTONE,:DUSKSTONE,:ELECTIRIZER,:MAGMARIZER, - :ODDKEYSTONE,:OVALSTONE,:PROTECTOR,:QUICKCLAW,:RAZORCLAW,:SACHET, - :SAFETYGOGGLES,:SHINYSTONE,:STICKYBARB,:WEAKNESSPOLICY, - :WHIPPEDDREAM - ], - 70 => [:DRAGONFANG,:POISONBARB, - # EV-training items (Macho Brace is 60) - :POWERANKLET,:POWERBAND,:POWERBELT,:POWERBRACER,:POWERLENS, - :POWERWEIGHT, - # Drives - :BURNDRIVE,:CHILLDRIVE,:DOUSEDRIVE,:SHOCKDRIVE - ], - 60 => [:ADAMANTORB,:DAMPROCK,:GRISEOUSORB,:HEATROCK,:LUSTROUSORB, - :MACHOBRACE,:ROCKYHELMET,:STICK,:TERRAINEXTENDER - ], - 50 => [:DUBIOUSDISC,:SHARPBEAK, - # Memories - :BUGMEMORY,:DARKMEMORY,:DRAGONMEMORY,:ELECTRICMEMORY,:FAIRYMEMORY, - :FIGHTINGMEMORY,:FIREMEMORY,:FLYINGMEMORY,:GHOSTMEMORY, - :GRASSMEMORY,:GROUNDMEMORY,:ICEMEMORY,:POISONMEMORY, - :PSYCHICMEMORY,:ROCKMEMORY,:STEELMEMORY,:WATERMEMORY - ], - 40 => [:EVIOLITE,:ICYROCK,:LUCKYPUNCH - ], - 30 => [:ABSORBBULB,:ADRENALINEORB,:AMULETCOIN,:BINDINGBAND,:BLACKBELT, - :BLACKGLASSES,:BLACKSLUDGE,:BOTTLECAP,:CELLBATTERY,:CHARCOAL, - :CLEANSETAG,:DEEPSEASCALE,:DRAGONSCALE,:EJECTBUTTON,:ESCAPEROPE, - :EXPSHARE,:FLAMEORB,:FLOATSTONE,:FLUFFYTAIL,:GOLDBOTTLECAP, - :HEARTSCALE,:HONEY,:KINGSROCK,:LIFEORB,:LIGHTBALL,:LIGHTCLAY, - :LUCKYEGG,:LUMINOUSMOSS,:MAGNET,:METALCOAT,:METRONOME, - :MIRACLESEED,:MYSTICWATER,:NEVERMELTICE,:PASSORB,:POKEDOLL, - :POKETOY,:PRISMSCALE,:PROTECTIVEPADS,:RAZORFANG,:SACREDASH, - :SCOPELENS,:SHELLBELL,:SHOALSALT,:SHOALSHELL,:SMOKEBALL,:SNOWBALL, - :SOULDEW,:SPELLTAG,:TOXICORB,:TWISTEDSPOON,:UPGRADE, - # Healing items - :ANTIDOTE,:AWAKENING,:BERRYJUICE,:BIGMALASADA,:BLUEFLUTE, - :BURNHEAL,:CASTELIACONE,:ELIXIR,:ENERGYPOWDER,:ENERGYROOT,:ETHER, - :FRESHWATER,:FULLHEAL,:FULLRESTORE,:HEALPOWDER,:HYPERPOTION, - :ICEHEAL,:LAVACOOKIE,:LEMONADE,:LUMIOSEGALETTE,:MAXELIXIR, - :MAXETHER,:MAXPOTION,:MAXREVIVE,:MOOMOOMILK,:OLDGATEAU, - :PARALYZEHEAL,:PARLYZHEAL,:PEWTERCRUNCHIES,:POTION,:RAGECANDYBAR, - :REDFLUTE,:REVIVALHERB,:REVIVE,:SHALOURSABLE,:SODAPOP, - :SUPERPOTION,:SWEETHEART,:YELLOWFLUTE, - # Battle items - :XACCURACY,:XACCURACY2,:XACCURACY3,:XACCURACY6, - :XATTACK,:XATTACK2,:XATTACK3,:XATTACK6, - :XDEFEND,:XDEFEND2,:XDEFEND3,:XDEFEND6, - :XDEFENSE,:XDEFENSE2,:XDEFENSE3,:XDEFENSE6, - :XSPATK,:XSPATK2,:XSPATK3,:XSPATK6, - :XSPECIAL,:XSPECIAL2,:XSPECIAL3,:XSPECIAL6, - :XSPDEF,:XSPDEF2,:XSPDEF3,:XSPDEF6, - :XSPEED,:XSPEED2,:XSPEED3,:XSPEED6, - :DIREHIT,:DIREHIT2,:DIREHIT3, - :ABILITYURGE,:GUARDSPEC,:ITEMDROP,:ITEMURGE,:RESETURGE, - # Vitamins - :CALCIUM,:CARBOS,:HPUP,:IRON,:PPUP,:PPMAX,:PROTEIN,:ZINC, - :RARECANDY, - # Most evolution stones (see also 80) - :EVERSTONE,:FIRESTONE,:ICESTONE,:LEAFSTONE,:MOONSTONE,:SUNSTONE, - :THUNDERSTONE,:WATERSTONE, - # Repels - :MAXREPEL,:REPEL,:SUPERREPEL, - # Mulches - :AMAZEMULCH,:BOOSTMULCH,:DAMPMULCH,:GOOEYMULCH,:GROWTHMULCH, - :RICHMULCH,:STABLEMULCH,:SURPRISEMULCH, - # Shards - :BLUESHARD,:GREENSHARD,:REDSHARD,:YELLOWSHARD, - # Valuables - :BALMMUSHROOM,:BIGMUSHROOM,:BIGNUGGET,:BIGPEARL,:COMETSHARD, - :NUGGET,:PEARL,:PEARLSTRING,:RELICBAND,:RELICCOPPER,:RELICCROWN, - :RELICGOLD,:RELICSILVER,:RELICSTATUE,:RELICVASE,:STARDUST, - :STARPIECE,:STRANGESOUVENIR,:TINYMUSHROOM - ], - 20 => [# Wings - :CLEVERWING,:GENIUSWING,:HEALTHWING,:MUSCLEWING,:PRETTYWING, - :RESISTWING,:SWIFTWING - ], - 10 => [:AIRBALLOON,:BIGROOT,:BRIGHTPOWDER,:CHOICEBAND,:CHOICESCARF, - :CHOICESPECS,:DESTINYKNOT,:DISCOUNTCOUPON,:EXPERTBELT,:FOCUSBAND, - :FOCUSSASH,:LAGGINGTAIL,:LEFTOVERS,:MENTALHERB,:METALPOWDER, - :MUSCLEBAND,:POWERHERB,:QUICKPOWDER,:REAPERCLOTH,:REDCARD, - :RINGTARGET,:SHEDSHELL,:SILKSCARF,:SILVERPOWDER,:SMOOTHROCK, - :SOFTSAND,:SOOTHEBELL,:WHITEHERB,:WIDELENS,:WISEGLASSES,:ZOOMLENS, - # Terrain seeds - :ELECTRICSEED,:GRASSYSEED,:MISTYSEED,:PSYCHICSEED, - # Nectar - :PINKNECTAR,:PURPLENECTAR,:REDNECTAR,:YELLOWNECTAR, - # Incenses - :FULLINCENSE,:LAXINCENSE,:LUCKINCENSE,:ODDINCENSE,:PUREINCENSE, - :ROCKINCENSE,:ROSEINCENSE,:SEAINCENSE,:WAVEINCENSE, - # Scarves - :BLUESCARF,:GREENSCARF,:PINKSCARF,:REDSCARF,:YELLOWSCARF - ] - } - end - - def pbCheckFlingSuccess(user) - @willFail = false - @willFail = true if !user.item || !user.itemActive? || user.unlosableItem?(user.item) - return if @willFail - @willFail = true if user.item.is_berry? && !user.canConsumeBerry? - return if @willFail - return if user.item.is_mega_stone? - flingableItem = false - @flingPowers.each do |_power, items| - next if !items.include?(user.item_id) - flingableItem = true - break - end - @willFail = true if !flingableItem - end - - def pbMoveFailed?(user,targets) - if @willFail - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbDisplayUseMessage(user) - super - pbCheckFlingSuccess(user) - if !@willFail - @battle.pbDisplay(_INTL("{1} flung its {2}!",user.pbThis,user.itemName)) - end - end - - def pbNumHits(user,targets); return 1; end - - def pbBaseDamage(baseDmg,user,target) - return 10 if user.item && user.item.is_berry? - return 80 if user.item && user.item.is_mega_stone? - @flingPowers.each do |power,items| - return power if items.include?(user.item_id) - end - return 10 - end - - def pbEffectAgainstTarget(user,target) - return if target.damageState.substitute - return if target.hasActiveAbility?(:SHIELDDUST) && !@battle.moldBreaker - case user.item_id - when :POISONBARB - target.pbPoison(user) if target.pbCanPoison?(user,false,self) - when :TOXICORB - target.pbPoison(user,nil,true) if target.pbCanPoison?(user,false,self) - when :FLAMEORB - target.pbBurn(user) if target.pbCanBurn?(user,false,self) - when :LIGHTBALL - target.pbParalyze(user) if target.pbCanParalyze?(user,false,self) - when :KINGSROCK, :RAZORFANG - target.pbFlinch(user) - else - target.pbHeldItemTriggerCheck(user.item,true) - end - end - - def pbEndOfMoveUsageEffect(user,targets,numHits,switchedBattlers) - # NOTE: The item is consumed even if this move was Protected against or it - # missed. The item is not consumed if the target was switched out by - # an effect like a target's Red Card. - # NOTE: There is no item consumption animation. - user.pbConsumeItem(true,true,false) if user.item - end -end - - - -#=============================================================================== -# For 5 rounds, the target cannnot use its held item, its held item has no -# effect, and no items can be used on it. (Embargo) -#=============================================================================== -class PokeBattle_Move_0F8 < PokeBattle_Move - def pbFailsAgainstTarget?(user,target) - if target.effects[PBEffects::Embargo]>0 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectAgainstTarget(user,target) - target.effects[PBEffects::Embargo] = 5 - @battle.pbDisplay(_INTL("{1} can't use items anymore!",target.pbThis)) - end -end - - - -#=============================================================================== -# For 5 rounds, all held items cannot be used in any way and have no effect. -# Held items can still change hands, but can't be thrown. (Magic Room) -#=============================================================================== -class PokeBattle_Move_0F9 < PokeBattle_Move - def pbEffectGeneral(user) - if @battle.field.effects[PBEffects::MagicRoom]>0 - @battle.field.effects[PBEffects::MagicRoom] = 0 - @battle.pbDisplay(_INTL("The area returned to normal!")) - else - @battle.field.effects[PBEffects::MagicRoom] = 5 - @battle.pbDisplay(_INTL("It created a bizarre area in which Pokémon's held items lose their effects!")) - end - end - - def pbShowAnimation(id,user,targets,hitNum=0,showAnimation=true) - return if @battle.field.effects[PBEffects::MagicRoom]>0 # No animation - super - end -end - - - -#=============================================================================== -# User takes recoil damage equal to 1/4 of the damage this move dealt. -#=============================================================================== -class PokeBattle_Move_0FA < PokeBattle_RecoilMove - def pbRecoilDamage(user,target) - return (target.damageState.totalHPLost/4.0).round - end -end - - - -#=============================================================================== -# User takes recoil damage equal to 1/3 of the damage this move dealt. -#=============================================================================== -class PokeBattle_Move_0FB < PokeBattle_RecoilMove - def pbRecoilDamage(user,target) - return (target.damageState.totalHPLost/3.0).round - end -end - - - -#=============================================================================== -# User takes recoil damage equal to 1/2 of the damage this move dealt. -# (Head Smash, Light of Ruin) -#=============================================================================== -class PokeBattle_Move_0FC < PokeBattle_RecoilMove - def pbRecoilDamage(user,target) - return (target.damageState.totalHPLost/2.0).round - end -end - - - -#=============================================================================== -# User takes recoil damage equal to 1/3 of the damage this move dealt. -# May paralyze the target. (Volt Tackle) -#=============================================================================== -class PokeBattle_Move_0FD < PokeBattle_RecoilMove - def pbRecoilDamage(user,target) - return (target.damageState.totalHPLost/3.0).round - end - - def pbAdditionalEffect(user,target) - return if target.damageState.substitute - target.pbParalyze(user) if target.pbCanParalyze?(user,false,self) - end -end - - - -#=============================================================================== -# User takes recoil damage equal to 1/3 of the damage this move dealt. -# May burn the target. (Flare Blitz) -#=============================================================================== -class PokeBattle_Move_0FE < PokeBattle_RecoilMove - def pbRecoilDamage(user,target) - return (target.damageState.totalHPLost/3.0).round - end - - def pbAdditionalEffect(user,target) - return if target.damageState.substitute - target.pbBurn(user) if target.pbCanBurn?(user,false,self) - end -end - - - -#=============================================================================== -# Starts sunny weather. (Sunny Day) -#=============================================================================== -class PokeBattle_Move_0FF < PokeBattle_WeatherMove - def initialize(battle,move) - super - @weatherType = :Sun - end -end diff --git a/Data/Scripts/011_Battle/002_Move/007_Move_Effects_100-17F.rb b/Data/Scripts/011_Battle/002_Move/007_Move_Effects_100-17F.rb deleted file mode 100644 index 712505f73..000000000 --- a/Data/Scripts/011_Battle/002_Move/007_Move_Effects_100-17F.rb +++ /dev/null @@ -1,2493 +0,0 @@ -#=============================================================================== -# Starts rainy weather. (Rain Dance) -#=============================================================================== -class PokeBattle_Move_100 < PokeBattle_WeatherMove - def initialize(battle, move) - super - @weatherType = :Rain - end -end - -#=============================================================================== -# Starts sandstorm weather. (Sandstorm) -#=============================================================================== -class PokeBattle_Move_101 < PokeBattle_WeatherMove - def initialize(battle, move) - super - @weatherType = :Sandstorm - end -end - -#=============================================================================== -# Starts hail weather. (Hail) -#=============================================================================== -class PokeBattle_Move_102 < PokeBattle_WeatherMove - def initialize(battle, move) - super - @weatherType = :Hail - end -end - -#=============================================================================== -# Entry hazard. Lays spikes on the opposing side (max. 3 layers). (Spikes) -#=============================================================================== -class PokeBattle_Move_103 < PokeBattle_Move - def pbMoveFailed?(user, targets) - if user.pbOpposingSide.effects[PBEffects::Spikes] >= 3 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - user.pbOpposingSide.effects[PBEffects::Spikes] += 1 - @battle.pbDisplay(_INTL("Spikes were scattered all around {1}'s feet!", - user.pbOpposingTeam(true))) - end -end - -#=============================================================================== -# Entry hazard. Lays poison spikes on the opposing side (max. 2 layers). -# (Toxic Spikes) -#=============================================================================== -class PokeBattle_Move_104 < PokeBattle_Move - def pbMoveFailed?(user, targets) - if user.pbOpposingSide.effects[PBEffects::ToxicSpikes] >= 2 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - user.pbOpposingSide.effects[PBEffects::ToxicSpikes] += 1 - @battle.pbDisplay(_INTL("Poison spikes were scattered all around {1}'s feet!", - user.pbOpposingTeam(true))) - end -end - -#=============================================================================== -# Entry hazard. Lays stealth rocks on the opposing side. (Stealth Rock) -#=============================================================================== -class PokeBattle_Move_105 < PokeBattle_Move - def pbMoveFailed?(user, targets) - if user.pbOpposingSide.effects[PBEffects::StealthRock] - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - user.pbOpposingSide.effects[PBEffects::StealthRock] = true - @battle.pbDisplay(_INTL("Pointed stones float in the air around {1}!", - user.pbOpposingTeam(true))) - end -end - -#=============================================================================== -# Combos with another Pledge move used by the ally. (Grass Pledge) -# If the move is a combo, power is doubled and causes either a sea of fire or a -# swamp on the opposing side. -#=============================================================================== -class PokeBattle_Move_106 < PokeBattle_PledgeMove - def initialize(battle, move) - super - # [Function code to combo with, effect, override type, override animation] - @combos = [["107", :SeaOfFire, :FIRE, :FIREPLEDGE], - ["108", :Swamp, nil, nil]] - end -end - -#=============================================================================== -# Combos with another Pledge move used by the ally. (Fire Pledge) -# If the move is a combo, power is doubled and causes either a rainbow on the -# user's side or a sea of fire on the opposing side. -#=============================================================================== -class PokeBattle_Move_107 < PokeBattle_PledgeMove - def initialize(battle, move) - super - # [Function code to combo with, effect, override type, override animation] - @combos = [["108", :Rainbow, :WATER, :WATERPLEDGE], - ["106", :SeaOfFire, nil, nil]] - end -end - -#=============================================================================== -# Combos with another Pledge move used by the ally. (Water Pledge) -# If the move is a combo, power is doubled and causes either a swamp on the -# opposing side or a rainbow on the user's side. -#=============================================================================== -class PokeBattle_Move_108 < PokeBattle_PledgeMove - def initialize(battle, move) - super - # [Function code to combo with, effect, override type, override animation] - @combos = [["106", :Swamp, :GRASS, :GRASSPLEDGE], - ["107", :Rainbow, nil, nil]] - end -end - -#=============================================================================== -# Scatters coins that the player picks up after winning the battle. (Pay Day) -# NOTE: In Gen 6+, if the user levels up after this move is used, the amount of -# money picked up depends on the user's new level rather than its level -# when it used the move. I think this is sill -# y, so I haven't coded this -# effect. -#=============================================================================== -class PokeBattle_Move_109 < PokeBattle_Move - def pbEffectGeneral(user) - if user.pbOwnedByPlayer? - @battle.field.effects[PBEffects::PayDay] += 5 * user.level - end - @battle.pbDisplay(_INTL("Coins were scattered everywhere!")) - end -end - -#=============================================================================== -# Ends the opposing side's Light Screen, Reflect and Aurora Break. (Brick Break, -# Psychic Fangs) -#=============================================================================== -class PokeBattle_Move_10A < PokeBattle_Move - def ignoresReflect? - return true; - end - - def pbEffectGeneral(user) - if user.pbOpposingSide.effects[PBEffects::LightScreen] > 0 - user.pbOpposingSide.effects[PBEffects::LightScreen] = 0 - @battle.pbDisplay(_INTL("{1}'s Light Screen wore off!", user.pbOpposingTeam)) - end - if user.pbOpposingSide.effects[PBEffects::Reflect] > 0 - user.pbOpposingSide.effects[PBEffects::Reflect] = 0 - @battle.pbDisplay(_INTL("{1}'s Reflect wore off!", user.pbOpposingTeam)) - end - if user.pbOpposingSide.effects[PBEffects::AuroraVeil] > 0 - user.pbOpposingSide.effects[PBEffects::AuroraVeil] = 0 - @battle.pbDisplay(_INTL("{1}'s Aurora Veil wore off!", user.pbOpposingTeam)) - end - end - - def pbShowAnimation(id, user, targets, hitNum = 0, showAnimation = true) - if user.pbOpposingSide.effects[PBEffects::LightScreen] > 0 || - user.pbOpposingSide.effects[PBEffects::Reflect] > 0 || - user.pbOpposingSide.effects[PBEffects::AuroraVeil] > 0 - hitNum = 1 # Wall-breaking anim - end - super - end -end - -#=============================================================================== -# If attack misses, user takes crash damage of 1/2 of max HP. -# (High Jump Kick, Jump Kick) -#=============================================================================== -class PokeBattle_Move_10B < PokeBattle_Move - def recoilMove? - return true; - end - - def unusableInGravity? - return true; - end - - def pbCrashDamage(user) - return if !user.takesIndirectDamage? - @battle.pbDisplay(_INTL("{1} kept going and crashed!", user.pbThis)) - @battle.scene.pbDamageAnimation(user) - user.pbReduceHP(user.totalhp / 2, false) - user.pbItemHPHealCheck - user.pbFaint if user.fainted? - end -end - -#=============================================================================== -# User turns 1/4 of max HP into a substitute. (Substitute) -#=============================================================================== -class PokeBattle_Move_10C < PokeBattle_Move - def pbMoveFailed?(user, targets) - if user.effects[PBEffects::Substitute] > 0 - @battle.pbDisplay(_INTL("{1} already has a substitute!", user.pbThis)) - return true - end - @subLife = user.totalhp / 4 - @subLife = 1 if @subLife < 1 - if user.hp <= @subLife - @battle.pbDisplay(_INTL("But it does not have enough HP left to make a substitute!")) - return true - end - return false - end - - def pbOnStartUse(user, targets) - user.pbReduceHP(@subLife, false, false) - user.pbItemHPHealCheck - end - - def pbEffectGeneral(user) - user.effects[PBEffects::Trapping] = 0 - user.effects[PBEffects::TrappingMove] = nil - user.effects[PBEffects::Substitute] = @subLife - @battle.pbDisplay(_INTL("{1} put in a substitute!", user.pbThis)) - end -end - -#=============================================================================== -# User is Ghost: User loses 1/2 of max HP, and curses the target. -# Cursed Pokémon lose 1/4 of their max HP at the end of each round. -# User is not Ghost: Decreases the user's Speed by 1 stage, and increases the -# user's Attack and Defense by 1 stage each. (Curse) -#=============================================================================== -class PokeBattle_Move_10D < PokeBattle_Move - def ignoresSubstitute?(user) - ; return true; - end - - def pbTarget(user) - return GameData::Target.get(:NearFoe) if user.pbHasType?(:GHOST) - return super - end - - def pbMoveFailed?(user, targets) - return false if user.pbHasType?(:GHOST) - if !user.pbCanLowerStatStage?(:SPEED, user, self) && - !user.pbCanRaiseStatStage?(:ATTACK, user, self) && - !user.pbCanRaiseStatStage?(:DEFENSE, user, self) - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbFailsAgainstTarget?(user, target) - if user.pbHasType?(:GHOST) && target.effects[PBEffects::Curse] - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - return if user.pbHasType?(:GHOST) - # Non-Ghost effect - if user.pbCanLowerStatStage?(:SPEED, user, self) - user.pbLowerStatStage(:SPEED, 1, user) - end - showAnim = true - if user.pbCanRaiseStatStage?(:ATTACK, user, self) - if user.pbRaiseStatStage(:ATTACK, 1, user, showAnim) - showAnim = false - end - end - if user.pbCanRaiseStatStage?(:DEFENSE, user, self) - user.pbRaiseStatStage(:DEFENSE, 1, user, showAnim) - end - end - - def pbEffectAgainstTarget(user, target) - return if !user.pbHasType?(:GHOST) - # Ghost effect - @battle.pbDisplay(_INTL("{1} cut its own HP and laid a curse on {2}!", user.pbThis, target.pbThis(true))) - target.effects[PBEffects::Curse] = true - user.pbReduceHP(user.totalhp / 2, false) - user.pbItemHPHealCheck - end - - def pbShowAnimation(id, user, targets, hitNum = 0, showAnimation = true) - hitNum = 1 if !user.pbHasType?(:GHOST) # Non-Ghost anim - super - end -end - -#=============================================================================== -# Target's last move used loses 4 PP. (Spite) -#=============================================================================== -class PokeBattle_Move_10E < PokeBattle_Move - def ignoresSubstitute?(user) - ; return true; - end - - def pbFailsAgainstTarget?(user, target) - failed = true - if target.lastRegularMoveUsed - target.eachMove do |m| - next if m.id != target.lastRegularMoveUsed || m.pp == 0 || m.total_pp <= 0 - failed = false; break - end - end - if failed - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectAgainstTarget(user, target) - target.eachMove do |m| - next if m.id != target.lastRegularMoveUsed - reduction = [4, m.pp].min - target.pbSetPP(m, m.pp - reduction) - @battle.pbDisplay(_INTL("It reduced the PP of {1}'s {2} by {3}!", - target.pbThis(true), m.name, reduction)) - break - end - end -end - -#=============================================================================== -# Target will lose 1/4 of max HP at end of each round, while asleep. (Nightmare) -#=============================================================================== -class PokeBattle_Move_10F < PokeBattle_Move - def pbFailsAgainstTarget?(user, target) - if !target.asleep? || target.effects[PBEffects::Nightmare] - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectAgainstTarget(user, target) - target.effects[PBEffects::Nightmare] = true - @battle.pbDisplay(_INTL("{1} began having a nightmare!", target.pbThis)) - end -end - -#=============================================================================== -# Removes trapping moves, entry hazards and Leech Seed on user/user's side. -# (Rapid Spin) -#=============================================================================== -class PokeBattle_Move_110 < PokeBattle_Move - def pbEffectAfterAllHits(user, target) - return if user.fainted? || target.damageState.unaffected - if user.effects[PBEffects::Trapping] > 0 - trapMove = GameData::Move.get(user.effects[PBEffects::TrappingMove]).name - trapUser = @battle.battlers[user.effects[PBEffects::TrappingUser]] - @battle.pbDisplay(_INTL("{1} got free of {2}'s {3}!", user.pbThis, trapUser.pbThis(true), trapMove)) - user.effects[PBEffects::Trapping] = 0 - user.effects[PBEffects::TrappingMove] = nil - user.effects[PBEffects::TrappingUser] = -1 - end - if user.effects[PBEffects::LeechSeed] >= 0 - user.effects[PBEffects::LeechSeed] = -1 - @battle.pbDisplay(_INTL("{1} shed Leech Seed!", user.pbThis)) - end - if user.pbOwnSide.effects[PBEffects::StealthRock] - user.pbOwnSide.effects[PBEffects::StealthRock] = false - @battle.pbDisplay(_INTL("{1} blew away stealth rocks!", user.pbThis)) - end - if user.pbOwnSide.effects[PBEffects::Spikes] > 0 - user.pbOwnSide.effects[PBEffects::Spikes] = 0 - @battle.pbDisplay(_INTL("{1} blew away spikes!", user.pbThis)) - end - if user.pbOwnSide.effects[PBEffects::ToxicSpikes] > 0 - user.pbOwnSide.effects[PBEffects::ToxicSpikes] = 0 - @battle.pbDisplay(_INTL("{1} blew away poison spikes!", user.pbThis)) - end - if user.pbOwnSide.effects[PBEffects::StickyWeb] - user.pbOwnSide.effects[PBEffects::StickyWeb] = false - @battle.pbDisplay(_INTL("{1} blew away sticky webs!", user.pbThis)) - end - end -end - -#=============================================================================== -# Attacks 2 rounds in the future. (Doom Desire, Future Sight) -#=============================================================================== -class PokeBattle_Move_111 < PokeBattle_Move - def cannotRedirect? - return true; - end - - def pbDamagingMove? # Stops damage being dealt in the setting-up turn - return false if !@battle.futureSight - return super - end - - def pbAccuracyCheck(user, target) - return true if !@battle.futureSight - return super - end - - def pbDisplayUseMessage(user) - super if !@battle.futureSight - end - - def pbFailsAgainstTarget?(user, target) - if !@battle.futureSight && - @battle.positions[target.index].effects[PBEffects::FutureSightCounter] > 0 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectAgainstTarget(user, target) - return if @battle.futureSight # Attack is hitting - effects = @battle.positions[target.index].effects - effects[PBEffects::FutureSightCounter] = 3 - effects[PBEffects::FutureSightMove] = @id - effects[PBEffects::FutureSightUserIndex] = user.index - effects[PBEffects::FutureSightUserPartyIndex] = user.pokemonIndex - if @id == :DOOMDESIRE - @battle.pbDisplay(_INTL("{1} chose Doom Desire as its destiny!", user.pbThis)) - else - @battle.pbDisplay(_INTL("{1} foresaw an attack!", user.pbThis)) - end - end - - def pbShowAnimation(id, user, targets, hitNum = 0, showAnimation = true) - hitNum = 1 if !@battle.futureSight # Charging anim - super - end -end - -#=============================================================================== -# Increases the user's Defense and Special Defense by 1 stage each. Ups the -# user's stockpile by 1 (max. 3). (Stockpile) -#=============================================================================== -class PokeBattle_Move_112 < PokeBattle_Move - def pbMoveFailed?(user, targets) - if user.effects[PBEffects::Stockpile] >= 3 - @battle.pbDisplay(_INTL("{1} can't stockpile any more!", user.pbThis)) - return true - end - return false - end - - def pbEffectGeneral(user) - user.effects[PBEffects::Stockpile] += 1 - @battle.pbDisplay(_INTL("{1} stockpiled {2}!", - user.pbThis, user.effects[PBEffects::Stockpile])) - showAnim = true - if user.pbCanRaiseStatStage?(:DEFENSE, user, self) - if user.pbRaiseStatStage(:DEFENSE, 1, user, showAnim) - user.effects[PBEffects::StockpileDef] += 1 - showAnim = false - end - end - if user.pbCanRaiseStatStage?(:SPECIAL_DEFENSE, user, self) - if user.pbRaiseStatStage(:SPECIAL_DEFENSE, 1, user, showAnim) - user.effects[PBEffects::StockpileSpDef] += 1 - end - end - end -end - -#=============================================================================== -# Power is 100 multiplied by the user's stockpile (X). Resets the stockpile to -# 0. Decreases the user's Defense and Special Defense by X stages each. (Spit Up) -#=============================================================================== -class PokeBattle_Move_113 < PokeBattle_Move - def pbMoveFailed?(user, targets) - if user.effects[PBEffects::Stockpile] == 0 - @battle.pbDisplay(_INTL("But it failed to spit up a thing!")) - return true - end - return false - end - - def pbBaseDamage(baseDmg, user, target) - return 100 * user.effects[PBEffects::Stockpile] - end - - def pbEffectAfterAllHits(user, target) - return if user.fainted? || user.effects[PBEffects::Stockpile] == 0 - return if target.damageState.unaffected - @battle.pbDisplay(_INTL("{1}'s stockpiled effect wore off!", user.pbThis)) - return if @battle.pbAllFainted?(target.idxOwnSide) - showAnim = true - if user.effects[PBEffects::StockpileDef] > 0 && - user.pbCanLowerStatStage?(:DEFENSE, user, self) - if user.pbLowerStatStage(:DEFENSE, user.effects[PBEffects::StockpileDef], user, showAnim) - showAnim = false - end - end - if user.effects[PBEffects::StockpileSpDef] > 0 && - user.pbCanLowerStatStage?(:SPECIAL_DEFENSE, user, self) - user.pbLowerStatStage(:SPECIAL_DEFENSE, user.effects[PBEffects::StockpileSpDef], user, showAnim) - end - user.effects[PBEffects::Stockpile] = 0 - user.effects[PBEffects::StockpileDef] = 0 - user.effects[PBEffects::StockpileSpDef] = 0 - end -end - -#=============================================================================== -# Heals user depending on the user's stockpile (X). Resets the stockpile to 0. -# Decreases the user's Defense and Special Defense by X stages each. (Swallow) -#=============================================================================== -class PokeBattle_Move_114 < PokeBattle_Move - def healingMove? - return true; - end - - def pbMoveFailed?(user, targets) - if user.effects[PBEffects::Stockpile] == 0 - @battle.pbDisplay(_INTL("But it failed to swallow a thing!")) - return true - end - if !user.canHeal? && - user.effects[PBEffects::StockpileDef] == 0 && - user.effects[PBEffects::StockpileSpDef] == 0 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - hpGain = 0 - case [user.effects[PBEffects::Stockpile], 1].max - when 1 then - hpGain = user.totalhp / 4 - when 2 then - hpGain = user.totalhp / 2 - when 3 then - hpGain = user.totalhp - end - if user.pbRecoverHP(hpGain) > 0 - @battle.pbDisplay(_INTL("{1}'s HP was restored.", user.pbThis)) - end - @battle.pbDisplay(_INTL("{1}'s stockpiled effect wore off!", user.pbThis)) - showAnim = true - if user.effects[PBEffects::StockpileDef] > 0 && - user.pbCanLowerStatStage?(:DEFENSE, user, self) - if user.pbLowerStatStage(:DEFENSE, user.effects[PBEffects::StockpileDef], user, showAnim) - showAnim = false - end - end - if user.effects[PBEffects::StockpileSpDef] > 0 && - user.pbCanLowerStatStage?(:SPECIAL_DEFENSE, user, self) - user.pbLowerStatStage(:SPECIAL_DEFENSE, user.effects[PBEffects::StockpileSpDef], user, showAnim) - end - user.effects[PBEffects::Stockpile] = 0 - user.effects[PBEffects::StockpileDef] = 0 - user.effects[PBEffects::StockpileSpDef] = 0 - end -end - -#=============================================================================== -# Fails if user was hit by a damaging move this round. (Focus Punch) -#=============================================================================== -class PokeBattle_Move_115 < PokeBattle_Move - def pbDisplayChargeMessage(user) - user.effects[PBEffects::FocusPunch] = true - @battle.pbCommonAnimation("FocusPunch", user) - @battle.pbDisplay(_INTL("{1} is tightening its focus!", user.pbThis)) - end - - def pbDisplayUseMessage(user) - super if !user.effects[PBEffects::FocusPunch] || user.lastHPLost == 0 - end - - def pbMoveFailed?(user, targets) - if user.effects[PBEffects::FocusPunch] && user.lastHPLost > 0 - @battle.pbDisplay(_INTL("{1} lost its focus and couldn't move!", user.pbThis)) - return true - end - return false - end -end - -#=============================================================================== -# Fails if the target didn't chose a damaging move to use this round, or has -# already moved. (Sucker Punch) -#=============================================================================== -class PokeBattle_Move_116 < PokeBattle_Move - def pbFailsAgainstTarget?(user, target) - if @battle.choices[target.index][0] != :UseMove - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - oppMove = @battle.choices[target.index][2] - if !oppMove || - (oppMove.function != "0B0" && # Me First - (target.movedThisRound? || oppMove.statusMove?)) - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end -end - -#=============================================================================== -# This round, user becomes the target of attacks that have single targets. -# (Follow Me, Rage Powder) -#=============================================================================== -class PokeBattle_Move_117 < PokeBattle_Move - def pbEffectGeneral(user) - user.effects[PBEffects::FollowMe] = 1 - user.eachAlly do |b| - next if b.effects[PBEffects::FollowMe] < user.effects[PBEffects::FollowMe] - user.effects[PBEffects::FollowMe] = b.effects[PBEffects::FollowMe] + 1 - end - user.effects[PBEffects::RagePowder] = true if @id == :RAGEPOWDER - @battle.pbDisplay(_INTL("{1} became the center of attention!", user.pbThis)) - end -end - -#=============================================================================== -# For 5 rounds, increases gravity on the field. Pokémon cannot become airborne. -# (Gravity) -#=============================================================================== -class PokeBattle_Move_118 < PokeBattle_Move - def pbMoveFailed?(user, targets) - if @battle.field.effects[PBEffects::Gravity] > 0 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - @battle.field.effects[PBEffects::Gravity] = 5 - @battle.pbDisplay(_INTL("Gravity intensified!")) - @battle.eachBattler do |b| - showMessage = false - if b.inTwoTurnAttack?("0C9", "0CC", "0CE") # Fly/Bounce/Sky Drop - b.effects[PBEffects::TwoTurnAttack] = nil - @battle.pbClearChoice(b.index) if !b.movedThisRound? - showMessage = true - end - if b.effects[PBEffects::MagnetRise] > 0 || - b.effects[PBEffects::Telekinesis] > 0 || - b.effects[PBEffects::SkyDrop] >= 0 - b.effects[PBEffects::MagnetRise] = 0 - b.effects[PBEffects::Telekinesis] = 0 - b.effects[PBEffects::SkyDrop] = -1 - showMessage = true - end - @battle.pbDisplay(_INTL("{1} couldn't stay airborne because of gravity!", - b.pbThis)) if showMessage - end - end -end - -#=============================================================================== -# For 5 rounds, user becomes airborne. (Magnet Rise) -#=============================================================================== -class PokeBattle_Move_119 < PokeBattle_Move - def unusableInGravity? - return true; - end - - def pbMoveFailed?(user, targets) - if user.effects[PBEffects::Ingrain] || - user.effects[PBEffects::SmackDown] || - user.effects[PBEffects::MagnetRise] > 0 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - user.effects[PBEffects::MagnetRise] = 5 - @battle.pbDisplay(_INTL("{1} levitated with electromagnetism!", user.pbThis)) - end -end - -#=============================================================================== -# For 3 rounds, target becomes airborne and can always be hit. (Telekinesis) -#=============================================================================== -class PokeBattle_Move_11A < PokeBattle_Move - def unusableInGravity? - return true; - end - - def pbFailsAgainstTarget?(user, target) - if target.effects[PBEffects::Ingrain] || - target.effects[PBEffects::SmackDown] || - target.effects[PBEffects::Telekinesis] > 0 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - if target.isSpecies?(:DIGLETT) || - target.isSpecies?(:DUGTRIO) || - target.isSpecies?(:SANDYGAST) || - target.isSpecies?(:PALOSSAND) || - (target.isSpecies?(:GENGAR) && target.mega?) - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectAgainstTarget(user, target) - target.effects[PBEffects::Telekinesis] = 3 - @battle.pbDisplay(_INTL("{1} was hurled into the air!", target.pbThis)) - end -end - -#=============================================================================== -# Hits airborne semi-invulnerable targets. (Sky Uppercut) -#=============================================================================== -class PokeBattle_Move_11B < PokeBattle_Move - def hitsFlyingTargets? - return true; - end -end - -#=============================================================================== -# Grounds the target while it remains active. Hits some semi-invulnerable -# targets. (Smack Down, Thousand Arrows) -#=============================================================================== -class PokeBattle_Move_11C < PokeBattle_Move - def hitsFlyingTargets? - return true; - end - - def pbCalcTypeModSingle(moveType, defType, user, target) - return Effectiveness::NORMAL_EFFECTIVE_ONE if moveType == :GROUND && defType == :FLYING - return super - end - - def pbEffectAfterAllHits(user, target) - return if target.fainted? - return if target.damageState.unaffected || target.damageState.substitute - return if target.inTwoTurnAttack?("0CE") || target.effects[PBEffects::SkyDrop] >= 0 # Sky Drop - return if !target.airborne? && !target.inTwoTurnAttack?("0C9", "0CC") # Fly/Bounce - target.effects[PBEffects::SmackDown] = true - if target.inTwoTurnAttack?("0C9", "0CC") # Fly/Bounce. NOTE: Not Sky Drop. - target.effects[PBEffects::TwoTurnAttack] = nil - @battle.pbClearChoice(target.index) if !target.movedThisRound? - end - target.effects[PBEffects::MagnetRise] = 0 - target.effects[PBEffects::Telekinesis] = 0 - @battle.pbDisplay(_INTL("{1} fell straight down!", target.pbThis)) - end -end - -#=============================================================================== -# Target moves immediately after the user, ignoring priority/speed. (After You) -#=============================================================================== -class PokeBattle_Move_11D < PokeBattle_Move - def ignoresSubstitute?(user) - ; return true; - end - - def pbFailsAgainstTarget?(user, target) - # Target has already moved this round - return true if pbMoveFailedTargetAlreadyMoved?(target) - # Target was going to move next anyway (somehow) - if target.effects[PBEffects::MoveNext] - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - # Target didn't choose to use a move this round - oppMove = @battle.choices[target.index][2] - if !oppMove - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectAgainstTarget(user, target) - target.effects[PBEffects::MoveNext] = true - target.effects[PBEffects::Quash] = 0 - @battle.pbDisplay(_INTL("{1} took the kind offer!", target.pbThis)) - end -end - -#=============================================================================== -# Target moves last this round, ignoring priority/speed. (Quash) -#=============================================================================== -class PokeBattle_Move_11E < PokeBattle_Move - def pbFailsAgainstTarget?(user, target) - return true if pbMoveFailedTargetAlreadyMoved?(target) - # Target isn't going to use a move - oppMove = @battle.choices[target.index][2] - if !oppMove - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - # Target is already maximally Quashed and will move last anyway - highestQuash = 0 - @battle.battlers.each do |b| - next if b.effects[PBEffects::Quash] <= highestQuash - highestQuash = b.effects[PBEffects::Quash] - end - if highestQuash > 0 && target.effects[PBEffects::Quash] == highestQuash - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - # Target was already going to move last - if highestQuash == 0 && @battle.pbPriority.last.index == target.index - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectAgainstTarget(user, target) - highestQuash = 0 - @battle.battlers.each do |b| - next if b.effects[PBEffects::Quash] <= highestQuash - highestQuash = b.effects[PBEffects::Quash] - end - target.effects[PBEffects::Quash] = highestQuash + 1 - target.effects[PBEffects::MoveNext] = false - @battle.pbDisplay(_INTL("{1}'s move was postponed!", target.pbThis)) - end -end - -#=============================================================================== -# For 5 rounds, for each priority bracket, slow Pokémon move before fast ones. -# (Trick Room) -#=============================================================================== -class PokeBattle_Move_11F < PokeBattle_Move - def pbEffectGeneral(user) - if @battle.field.effects[PBEffects::TrickRoom] > 0 - @battle.field.effects[PBEffects::TrickRoom] = 0 - @battle.pbDisplay(_INTL("{1} reverted the dimensions!", user.pbThis)) - else - @battle.field.effects[PBEffects::TrickRoom] = 5 - @battle.pbDisplay(_INTL("{1} twisted the dimensions!", user.pbThis)) - end - end - - def pbShowAnimation(id, user, targets, hitNum = 0, showAnimation = true) - return if @battle.field.effects[PBEffects::TrickRoom] > 0 # No animation - super - end -end - -#=============================================================================== -# User switches places with its ally. (Ally Switch) -#=============================================================================== -class PokeBattle_Move_120 < PokeBattle_Move - def pbMoveFailed?(user, targets) - numTargets = 0 - @idxAlly = -1 - idxUserOwner = @battle.pbGetOwnerIndexFromBattlerIndex(user.index) - user.eachAlly do |b| - next if @battle.pbGetOwnerIndexFromBattlerIndex(b.index) != idxUserOwner - next if !b.near?(user) - numTargets += 1 - @idxAlly = b.index - end - if numTargets != 1 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - idxA = user.index - idxB = @idxAlly - if @battle.pbSwapBattlers(idxA, idxB) - @battle.pbDisplay(_INTL("{1} and {2} switched places!", - @battle.battlers[idxB].pbThis, @battle.battlers[idxA].pbThis(true))) - end - end -end - -#=============================================================================== -# Target's Attack is used instead of user's Attack for this move's calculations. -# (Foul Play) -#=============================================================================== -class PokeBattle_Move_121 < PokeBattle_Move - def pbGetAttackStats(user, target) - if specialMove? - return target.spatk, target.stages[:SPECIAL_ATTACK] + 6 - end - return target.attack, target.stages[:ATTACK] + 6 - end -end - -#=============================================================================== -# Target's Defense is used instead of its Special Defense for this move's -# calculations. (Psyshock, Psystrike, Secret Sword) -#=============================================================================== -class PokeBattle_Move_122 < PokeBattle_Move - def pbGetDefenseStats(user, target) - return target.defense, target.stages[:DEFENSE] + 6 - end -end - -#=============================================================================== -# Only damages Pokémon that share a type with the user. (Synchronoise) -#=============================================================================== -class PokeBattle_Move_123 < PokeBattle_Move - def pbFailsAgainstTarget?(user, target) - userTypes = user.pbTypes(true) - targetTypes = target.pbTypes(true) - sharesType = false - userTypes.each do |t| - next if !targetTypes.include?(t) - sharesType = true - break - end - if !sharesType - @battle.pbDisplay(_INTL("{1} is unaffected!", target.pbThis)) - return true - end - return false - end -end - -#=============================================================================== -# For 5 rounds, swaps all battlers' base Defense with base Special Defense. -# (Wonder Room) -#=============================================================================== -class PokeBattle_Move_124 < PokeBattle_Move - def pbEffectGeneral(user) - if @battle.field.effects[PBEffects::WonderRoom] > 0 - @battle.field.effects[PBEffects::WonderRoom] = 0 - @battle.pbDisplay(_INTL("Wonder Room wore off, and the Defense and Sp. Def stats returned to normal!")) - else - @battle.field.effects[PBEffects::WonderRoom] = 5 - @battle.pbDisplay(_INTL("It created a bizarre area in which the Defense and Sp. Def stats are swapped!")) - end - end - - def pbShowAnimation(id, user, targets, hitNum = 0, showAnimation = true) - return if @battle.field.effects[PBEffects::WonderRoom] > 0 # No animation - super - end -end - -#=============================================================================== -# Fails unless user has already used all other moves it knows. (Last Resort) -#=============================================================================== -class PokeBattle_Move_125 < PokeBattle_Move - def pbFailsAgainstTarget?(user, target) - hasThisMove = false; hasOtherMoves = false; hasUnusedMoves = false - user.eachMove do |m| - hasThisMove = true if m.id == @id - hasOtherMoves = true if m.id != @id - hasUnusedMoves = true if m.id != @id && !user.movesUsed.include?(m.id) - end - if !hasThisMove || !hasOtherMoves || hasUnusedMoves - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end -end - -#=============================================================================== -# NOTE: Shadow moves use function codes 126-132 inclusive. -#=============================================================================== - -#=============================================================================== -# Does absolutely nothing. (Hold Hands) -#=============================================================================== -class PokeBattle_Move_133 < PokeBattle_Move - def ignoresSubstitute?(user) - ; return true; - end - - def pbMoveFailed?(user, targets) - hasAlly = false - user.eachAlly do |_b| - hasAlly = true - break - end - if !hasAlly - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end -end - -#=============================================================================== -# Does absolutely nothing. Shows a special message. (Celebrate) -#=============================================================================== -class PokeBattle_Move_134 < PokeBattle_Move - def pbEffectGeneral(user) - if @battle.wildBattle? && user.opposes? - @battle.pbDisplay(_INTL("Congratulations from {1}!", user.pbThis(true))) - else - @battle.pbDisplay(_INTL("Congratulations, {1}!", @battle.pbGetOwnerName(user.index))) - end - end -end - -#=============================================================================== -# Freezes the target. Effectiveness against Water-type is 2x. (Freeze-Dry) -#=============================================================================== -class PokeBattle_Move_135 < PokeBattle_FreezeMove - def pbCalcTypeModSingle(moveType, defType, user, target) - return Effectiveness::SUPER_EFFECTIVE_ONE if defType == :WATER - return super - end -end - -#=============================================================================== -# Increases the user's Defense by 2 stages. (Diamond Storm) -#=============================================================================== -class PokeBattle_Move_136 < PokeBattle_Move_02F - # NOTE: In Gen 6, this move increased the user's Defense by 1 stage for each - # target it hit. This effect changed in Gen 7 and is now identical to - # function code 02F. -end - -#=============================================================================== -# Increases the user's and its ally's Defense and Special Defense by 1 stage -# each, if they have Plus or Minus. (Magnetic Flux) -#=============================================================================== -# NOTE: In Gen 5, this move should have a target of UserSide, while in Gen 6+ it -# should have a target of UserAndAllies. This is because, in Gen 5, this -# move shouldn't call def pbSuccessCheckAgainstTarget for each Pokémon -# currently in battle that will be affected by this move (i.e. allies -# aren't protected by their substitute/ability/etc., but they are in Gen -# 6+). We achieve this by not targeting any battlers in Gen 5, since -# pbSuccessCheckAgainstTarget is only called for targeted battlers. -class PokeBattle_Move_137 < PokeBattle_Move - def ignoresSubstitute?(user) - ; return true; - end - - def pbMoveFailed?(user, targets) - @validTargets = [] - @battle.eachSameSideBattler(user) do |b| - next if !b.hasActiveAbility?([:MINUS, :PLUS]) - next if !b.pbCanRaiseStatStage?(:DEFENSE, user, self) && - !b.pbCanRaiseStatStage?(:SPECIAL_DEFENSE, user, self) - @validTargets.push(b) - end - if @validTargets.length == 0 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbFailsAgainstTarget?(user, target) - return false if @validTargets.any? { |b| b.index == target.index } - return true if !target.hasActiveAbility?([:MINUS, :PLUS]) - @battle.pbDisplay(_INTL("{1}'s stats can't be raised further!", target.pbThis)) - return true - end - - def pbEffectAgainstTarget(user, target) - showAnim = true - if target.pbCanRaiseStatStage?(:DEFENSE, user, self) - if target.pbRaiseStatStage(:DEFENSE, 1, user, showAnim) - showAnim = false - end - end - if target.pbCanRaiseStatStage?(:SPECIAL_DEFENSE, user, self) - target.pbRaiseStatStage(:SPECIAL_DEFENSE, 1, user, showAnim) - end - end - - def pbEffectGeneral(user) - return if pbTarget(user) != :UserSide - @validTargets.each { |b| pbEffectAgainstTarget(user, b) } - end -end - -#=============================================================================== -# Increases target's Special Defense by 1 stage. (Aromatic Mist) -#=============================================================================== -class PokeBattle_Move_138 < PokeBattle_Move - def ignoresSubstitute?(user) - ; return true; - end - - def pbFailsAgainstTarget?(user, target) - return true if !target.pbCanRaiseStatStage?(:SPECIAL_DEFENSE, user, self, true) - return false - end - - def pbEffectAgainstTarget(user, target) - target.pbRaiseStatStage(:SPECIAL_DEFENSE, 1, user) - end -end - -#=============================================================================== -# Decreases the target's Attack by 1 stage. Always hits. (Play Nice) -#=============================================================================== -class PokeBattle_Move_139 < PokeBattle_TargetStatDownMove - def ignoresSubstitute?(user) - ; return true; - end - - def initialize(battle, move) - super - @statDown = [:ATTACK, 1] - end - - def pbAccuracyCheck(user, target) - ; return true; - end -end - -#=============================================================================== -# Decreases the target's Attack and Special Attack by 1 stage each. Always hits. -# (Noble Roar) -#=============================================================================== -class PokeBattle_Move_13A < PokeBattle_TargetMultiStatDownMove - def ignoresSubstitute?(user) - ; return true; - end - - def initialize(battle, move) - super - @statDown = [:ATTACK, 1, :SPECIAL_ATTACK, 1] - end - - def pbAccuracyCheck(user, target) - ; return true; - end -end - -#=============================================================================== -# Decreases the user's Defense by 1 stage. Always hits. Ends target's -# protections immediately. (Hyperspace Fury) -#=============================================================================== -class PokeBattle_Move_13B < PokeBattle_StatDownMove - def ignoresSubstitute?(user) - ; return true; - end - - def initialize(battle, move) - super - @statDown = [:DEFENSE, 1] - end - - def pbMoveFailed?(user, targets) - if !user.isSpecies?(:HOOPA) - @battle.pbDisplay(_INTL("But {1} can't use the move!", user.pbThis(true))) - return true - elsif user.form != 1 - @battle.pbDisplay(_INTL("But {1} can't use it the way it is now!", user.pbThis(true))) - return true - end - return false - end - - def pbAccuracyCheck(user, target) - ; return true; - end - - def pbEffectAgainstTarget(user, target) - target.effects[PBEffects::BanefulBunker] = false - target.effects[PBEffects::KingsShield] = false - target.effects[PBEffects::Protect] = false - target.effects[PBEffects::SpikyShield] = false - target.pbOwnSide.effects[PBEffects::CraftyShield] = false - target.pbOwnSide.effects[PBEffects::MatBlock] = false - target.pbOwnSide.effects[PBEffects::QuickGuard] = false - target.pbOwnSide.effects[PBEffects::WideGuard] = false - end -end - -#=============================================================================== -# Decreases the target's Special Attack by 1 stage. Always hits. (Confide) -#=============================================================================== -class PokeBattle_Move_13C < PokeBattle_TargetStatDownMove - def ignoresSubstitute?(user) - ; return true; - end - - def initialize(battle, move) - super - @statDown = [:SPECIAL_ATTACK, 1] - end - - def pbAccuracyCheck(user, target) - ; return true; - end -end - -#=============================================================================== -# Decreases the target's Special Attack by 2 stages. (Eerie Impulse) -#=============================================================================== -class PokeBattle_Move_13D < PokeBattle_TargetStatDownMove - def initialize(battle, move) - super - @statDown = [:SPECIAL_ATTACK, 2] - end -end - -#=============================================================================== -# Increases the Attack and Special Attack of all Grass-type Pokémon in battle by -# 1 stage each. Doesn't affect airborne Pokémon. (Rototiller) -#=============================================================================== -class PokeBattle_Move_13E < PokeBattle_Move - def pbMoveFailed?(user, targets) - @validTargets = [] - @battle.eachBattler do |b| - next if !b.pbHasType?(:GRASS) - next if b.airborne? || b.semiInvulnerable? - next if !b.pbCanRaiseStatStage?(:ATTACK, user, self) && - !b.pbCanRaiseStatStage?(:SPECIAL_ATTACK, user, self) - @validTargets.push(b.index) - end - if @validTargets.length == 0 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbFailsAgainstTarget?(user, target) - return false if @validTargets.include?(target.index) - return true if !target.pbHasType?(:GRASS) - return true if target.airborne? || target.semiInvulnerable? - @battle.pbDisplay(_INTL("{1}'s stats can't be raised further!", target.pbThis)) - return true - end - - def pbEffectAgainstTarget(user, target) - showAnim = true - if target.pbCanRaiseStatStage?(:ATTACK, user, self) - if target.pbRaiseStatStage(:ATTACK, 1, user, showAnim) - showAnim = false - end - end - if target.pbCanRaiseStatStage?(:SPECIAL_ATTACK, user, self) - target.pbRaiseStatStage(:SPECIAL_ATTACK, 1, user, showAnim) - end - end -end - -#=============================================================================== -# Increases the Defense of all Grass-type Pokémon on the field by 1 stage each. -# (Flower Shield) -#=============================================================================== -class PokeBattle_Move_13F < PokeBattle_Move - def pbMoveFailed?(user, targets) - @validTargets = [] - @battle.eachBattler do |b| - next if !b.pbHasType?(:GRASS) - next if b.semiInvulnerable? - next if !b.pbCanRaiseStatStage?(:DEFENSE, user, self) - @validTargets.push(b.index) - end - if @validTargets.length == 0 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbFailsAgainstTarget?(user, target) - return false if @validTargets.include?(target.index) - return true if !target.pbHasType?(:GRASS) || target.semiInvulnerable? - return !target.pbCanRaiseStatStage?(:DEFENSE, user, self, true) - end - - def pbEffectAgainstTarget(user, target) - target.pbRaiseStatStage(:DEFENSE, 1, user) - end -end - -#=============================================================================== -# Decreases the Attack, Special Attack and Speed of all poisoned targets by 1 -# stage each. (Venom Drench) -#=============================================================================== -class PokeBattle_Move_140 < PokeBattle_Move - def pbMoveFailed?(user, targets) - @validTargets = [] - targets.each do |b| - next if !b || b.fainted? - next if !b.poisoned? - next if !b.pbCanLowerStatStage?(:ATTACK, user, self) && - !b.pbCanLowerStatStage?(:SPECIAL_ATTACK, user, self) && - !b.pbCanLowerStatStage?(:SPEED, user, self) - @validTargets.push(b.index) - end - if @validTargets.length == 0 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectAgainstTarget(user, target) - return if !@validTargets.include?(target.index) - showAnim = true - [:ATTACK, :SPECIAL_ATTACK, :SPEED].each do |s| - next if !target.pbCanLowerStatStage?(s, user, self) - if target.pbLowerStatStage(s, 1, user, showAnim) - showAnim = false - end - end - end -end - -#=============================================================================== -# Reverses all stat changes of the target. (Topsy-Turvy) -#=============================================================================== -class PokeBattle_Move_141 < PokeBattle_Move - def pbFailsAgainstTarget?(user, target) - failed = true - GameData::Stat.each_battle do |s| - next if target.stages[s.id] == 0 - failed = false - break - end - if failed - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectAgainstTarget(user, target) - GameData::Stat.each_battle { |s| target.stages[s.id] *= -1 } - @battle.pbDisplay(_INTL("{1}'s stats were reversed!", target.pbThis)) - end -end - -#=============================================================================== -# Gives target the Ghost type. (Trick-or-Treat) -#=============================================================================== -class PokeBattle_Move_142 < PokeBattle_Move - def pbFailsAgainstTarget?(user, target) - if !GameData::Type.exists?(:GHOST) || target.pbHasType?(:GHOST) || !target.canChangeType? - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectAgainstTarget(user, target) - target.effects[PBEffects::Type3] = :GHOST - typeName = GameData::Type.get(:GHOST).name - @battle.pbDisplay(_INTL("{1} transformed into the {2} type!", target.pbThis, typeName)) - end -end - -#=============================================================================== -# Gives target the Grass type. (Forest's Curse) -#=============================================================================== -class PokeBattle_Move_143 < PokeBattle_Move - def pbFailsAgainstTarget?(user, target) - if !GameData::Type.exists?(:GRASS) || target.pbHasType?(:GRASS) || !target.canChangeType? - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectAgainstTarget(user, target) - target.effects[PBEffects::Type3] = :GRASS - typeName = GameData::Type.get(:GRASS).name - @battle.pbDisplay(_INTL("{1} transformed into the {2} type!", target.pbThis, typeName)) - end -end - -#=============================================================================== -# Type effectiveness is multiplied by the Flying-type's effectiveness against -# the target. Does double damage and has perfect accuracy if the target is -# Minimized. (Flying Press) -#=============================================================================== -class PokeBattle_Move_144 < PokeBattle_Move - def tramplesMinimize?(param = 1) - return true if param == 1 && Settings::MECHANICS_GENERATION >= 6 # Perfect accuracy - return true if param == 2 # Double damage - return super - end - - def pbCalcTypeModSingle(moveType, defType, user, target) - ret = super - if GameData::Type.exists?(:FLYING) - flyingEff = Effectiveness.calculate_one(:FLYING, defType) - ret *= flyingEff.to_f / Effectiveness::NORMAL_EFFECTIVE_ONE - end - return ret - end -end - -#=============================================================================== -# Target's moves become Electric-type for the rest of the round. (Electrify) -#=============================================================================== -class PokeBattle_Move_145 < PokeBattle_Move - def pbFailsAgainstTarget?(user, target) - if target.effects[PBEffects::Electrify] - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return true if pbMoveFailedTargetAlreadyMoved?(target) - return false - end - - def pbEffectAgainstTarget(user, target) - target.effects[PBEffects::Electrify] = true - @battle.pbDisplay(_INTL("{1}'s moves have been electrified!", target.pbThis)) - end -end - -#=============================================================================== -# All Normal-type moves become Electric-type for the rest of the round. -# (Ion Deluge, Plasma Fists) -#=============================================================================== -class PokeBattle_Move_146 < PokeBattle_Move - def pbMoveFailed?(user, targets) - return false if damagingMove? - if @battle.field.effects[PBEffects::IonDeluge] - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return true if pbMoveFailedLastInRound?(user) - return false - end - - def pbEffectGeneral(user) - return if @battle.field.effects[PBEffects::IonDeluge] - @battle.field.effects[PBEffects::IonDeluge] = true - @battle.pbDisplay(_INTL("A deluge of ions showers the battlefield!")) - end -end - -#=============================================================================== -# Always hits. Ends target's protections immediately. (Hyperspace Hole) -#=============================================================================== -class PokeBattle_Move_147 < PokeBattle_Move - def ignoresSubstitute?(user) - ; return true; - end - - def pbAccuracyCheck(user, target) - ; return true; - end - - def pbEffectAgainstTarget(user, target) - target.effects[PBEffects::BanefulBunker] = false - target.effects[PBEffects::KingsShield] = false - target.effects[PBEffects::Protect] = false - target.effects[PBEffects::SpikyShield] = false - target.pbOwnSide.effects[PBEffects::CraftyShield] = false - target.pbOwnSide.effects[PBEffects::MatBlock] = false - target.pbOwnSide.effects[PBEffects::QuickGuard] = false - target.pbOwnSide.effects[PBEffects::WideGuard] = false - end -end - -#=============================================================================== -# Powders the foe. This round, if it uses a Fire move, it loses 1/4 of its max -# HP instead. (Powder) -#=============================================================================== -class PokeBattle_Move_148 < PokeBattle_Move - def ignoresSubstitute?(user) - ; return true; - end - - def pbFailsAgainstTarget?(user, target) - if target.effects[PBEffects::Powder] - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectAgainstTarget(user, target) - target.effects[PBEffects::Powder] = true - @battle.pbDisplay(_INTL("{1} is covered in powder!", user.pbThis)) - end -end - -#=============================================================================== -# This round, the user's side is unaffected by damaging moves. (Mat Block) -#=============================================================================== -class PokeBattle_Move_149 < PokeBattle_Move - def pbMoveFailed?(user, targets) - if user.turnCount > 1 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return true if pbMoveFailedLastInRound?(user) - return false - end - - def pbEffectGeneral(user) - user.pbOwnSide.effects[PBEffects::MatBlock] = true - @battle.pbDisplay(_INTL("{1} intends to flip up a mat and block incoming attacks!", user.pbThis)) - end -end - -#=============================================================================== -# User's side is protected against status moves this round. (Crafty Shield) -#=============================================================================== -class PokeBattle_Move_14A < PokeBattle_Move - def pbMoveFailed?(user, targets) - if user.pbOwnSide.effects[PBEffects::CraftyShield] - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return true if pbMoveFailedLastInRound?(user) - return false - end - - def pbEffectGeneral(user) - user.pbOwnSide.effects[PBEffects::CraftyShield] = true - @battle.pbDisplay(_INTL("Crafty Shield protected {1}!", user.pbTeam(true))) - end -end - -#=============================================================================== -# User is protected against damaging moves this round. Decreases the Attack of -# the user of a stopped contact move by 2 stages. (King's Shield) -#=============================================================================== -class PokeBattle_Move_14B < PokeBattle_ProtectMove - def initialize(battle, move) - super - @effect = PBEffects::KingsShield - end -end - -#=============================================================================== -# User is protected against moves that target it this round. Damages the user of -# a stopped contact move by 1/8 of its max HP. (Spiky Shield) -#=============================================================================== -class PokeBattle_Move_14C < PokeBattle_ProtectMove - def initialize(battle, move) - super - @effect = PBEffects::SpikyShield - end -end - -#=============================================================================== -# Two turn attack. Skips first turn, attacks second turn. (Phantom Force) -# Is invulnerable during use. Ends target's protections upon hit. -#=============================================================================== -class PokeBattle_Move_14D < PokeBattle_Move_0CD - # NOTE: This move is identical to function code 0CD (Shadow Force). -end - -#=============================================================================== -# Two turn attack. Skips first turn, and increases the user's Special Attack, -# Special Defense and Speed by 2 stages each in the second turn. (Geomancy) -#=============================================================================== -class PokeBattle_Move_14E < PokeBattle_TwoTurnMove - def pbMoveFailed?(user, targets) - return false if user.effects[PBEffects::TwoTurnAttack] # Charging turn - if !user.pbCanRaiseStatStage?(:SPECIAL_ATTACK, user, self) && - !user.pbCanRaiseStatStage?(:SPECIAL_DEFENSE, user, self) && - !user.pbCanRaiseStatStage?(:SPEED, user, self) - @battle.pbDisplay(_INTL("{1}'s stats won't go any higher!", user.pbThis)) - return true - end - return false - end - - def pbChargingTurnMessage(user, targets) - @battle.pbDisplay(_INTL("{1} is absorbing power!", user.pbThis)) - end - - def pbEffectGeneral(user) - return if !@damagingTurn - showAnim = true - [:SPECIAL_ATTACK, :SPECIAL_DEFENSE, :SPEED].each do |s| - next if !user.pbCanRaiseStatStage?(s, user, self) - if user.pbRaiseStatStage(s, 2, user, showAnim) - showAnim = false - end - end - end -end - -#=============================================================================== -# User gains 3/4 the HP it inflicts as damage. (Draining Kiss, Oblivion Wing) -#=============================================================================== -class PokeBattle_Move_14F < PokeBattle_Move - def healingMove? - return Settings::MECHANICS_GENERATION >= 6; - end - - def pbEffectAgainstTarget(user, target) - return if target.damageState.hpLost <= 0 - hpGain = (target.damageState.hpLost * 0.75).round - user.pbRecoverHPFromDrain(hpGain, target) - end -end - -#=============================================================================== -# If this move KO's the target, increases the user's Attack by 3 stages. -# (Fell Stinger) -#=============================================================================== -class PokeBattle_Move_150 < PokeBattle_Move - def pbEffectAfterAllHits(user, target) - return if !target.damageState.fainted - return if !user.pbCanRaiseStatStage?(:ATTACK, user, self) - user.pbRaiseStatStage(:ATTACK, 3, user) - end -end - -#=============================================================================== -# Decreases the target's Attack and Special Attack by 1 stage each. Then, user -# switches out. Ignores trapping moves. (Parting Shot) -#=============================================================================== -class PokeBattle_Move_151 < PokeBattle_TargetMultiStatDownMove - def initialize(battle, move) - super - @statDown = [:ATTACK, 1, :SPECIAL_ATTACK, 1] - end - - def pbEndOfMoveUsageEffect(user, targets, numHits, switchedBattlers) - switcher = user - targets.each do |b| - next if switchedBattlers.include?(b.index) - switcher = b if b.effects[PBEffects::MagicCoat] || b.effects[PBEffects::MagicBounce] - end - return if switcher.fainted? || numHits == 0 - return if !@battle.pbCanChooseNonActive?(switcher.index) - @battle.pbDisplay(_INTL("{1} went back to {2}!", switcher.pbThis, - @battle.pbGetOwnerName(switcher.index))) - @battle.pbPursuit(switcher.index) - return if switcher.fainted? - newPkmn = @battle.pbGetReplacementPokemonIndex(switcher.index) # Owner chooses - return if newPkmn < 0 - @battle.pbRecallAndReplace(switcher.index, newPkmn) - @battle.pbClearChoice(switcher.index) # Replacement Pokémon does nothing this round - @battle.moldBreaker = false if switcher.index == user.index - switchedBattlers.push(switcher.index) - switcher.pbEffectsOnSwitchIn(true) - end -end - -#=============================================================================== -# No Pokémon can switch out or flee until the end of the next round, as long as -# the user remains active. (Fairy Lock) -#=============================================================================== -class PokeBattle_Move_152 < PokeBattle_Move - def pbMoveFailed?(user, targets) - if @battle.field.effects[PBEffects::FairyLock] > 0 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - @battle.field.effects[PBEffects::FairyLock] = 2 - @battle.pbDisplay(_INTL("No one will be able to run away during the next turn!")) - end -end - -#=============================================================================== -# Entry hazard. Lays stealth rocks on the opposing side. (Sticky Web) -#=============================================================================== -class PokeBattle_Move_153 < PokeBattle_Move - def pbMoveFailed?(user, targets) - if user.pbOpposingSide.effects[PBEffects::StickyWeb] - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - user.pbOpposingSide.effects[PBEffects::StickyWeb] = true - @battle.pbDisplay(_INTL("A sticky web has been laid out beneath {1}'s feet!", - user.pbOpposingTeam(true))) - end -end - -#=============================================================================== -# For 5 rounds, creates an electric terrain which boosts Electric-type moves and -# prevents Pokémon from falling asleep. Affects non-airborne Pokémon only. -# (Electric Terrain) -#=============================================================================== -class PokeBattle_Move_154 < PokeBattle_Move - def pbMoveFailed?(user, targets) - if @battle.field.terrain == :Electric - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - @battle.pbStartTerrain(user, :Electric) - end -end - -#=============================================================================== -# For 5 rounds, creates a grassy terrain which boosts Grass-type moves and heals -# Pokémon at the end of each round. Affects non-airborne Pokémon only. -# (Grassy Terrain) -#=============================================================================== -class PokeBattle_Move_155 < PokeBattle_Move - def pbMoveFailed?(user, targets) - if @battle.field.terrain == :Grassy - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - @battle.pbStartTerrain(user, :Grassy) - end -end - -#=============================================================================== -# For 5 rounds, creates a misty terrain which weakens Dragon-type moves and -# protects Pokémon from status problems. Affects non-airborne Pokémon only. -# (Misty Terrain) -#=============================================================================== -class PokeBattle_Move_156 < PokeBattle_Move - def pbMoveFailed?(user, targets) - if @battle.field.terrain == :Misty - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - @battle.pbStartTerrain(user, :Misty) - end -end - -#=============================================================================== -# Doubles the prize money the player gets after winning the battle. (Happy Hour) -#=============================================================================== -class PokeBattle_Move_157 < PokeBattle_Move - def pbEffectGeneral(user) - @battle.field.effects[PBEffects::HappyHour] = true if !user.opposes? - @battle.pbDisplay(_INTL("Everyone is caught up in the happy atmosphere!")) - end -end - -#=============================================================================== -# Fails unless user has consumed a berry at some point. (Belch) -#=============================================================================== -class PokeBattle_Move_158 < PokeBattle_Move - def pbCanChooseMove?(user, commandPhase, showMessages) - if !user.belched? - if showMessages - msg = _INTL("{1} hasn't eaten any held berry, so it can't possibly belch!", user.pbThis) - (commandPhase) ? @battle.pbDisplayPaused(msg) : @battle.pbDisplay(msg) - end - return false - end - return true - end - - def pbMoveFailed?(user, targets) - if !user.belched? - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end -end - -#=============================================================================== -# Poisons the target and decreases its Speed by 1 stage. (Toxic Thread) -#=============================================================================== -class PokeBattle_Move_159 < PokeBattle_Move - def pbFailsAgainstTarget?(user, target) - if !target.pbCanPoison?(user, false, self) && - !target.pbCanLowerStatStage?(:SPEED, user, self) - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectAgainstTarget(user, target) - target.pbPoison(user) if target.pbCanPoison?(user, false, self) - if target.pbCanLowerStatStage?(:SPEED, user, self) - target.pbLowerStatStage(:SPEED, 1, user) - end - end -end - -#=============================================================================== -# Cures the target's burn. (Sparkling Aria) -#=============================================================================== -class PokeBattle_Move_15A < PokeBattle_Move - def pbAdditionalEffect(user, target) - return if target.fainted? || target.damageState.substitute - return if target.status != :BURN - target.pbCureStatus - end -end - -#=============================================================================== -# Cures the target's permanent status problems. Heals user by 1/2 of its max HP. -# (Purify) -#=============================================================================== -class PokeBattle_Move_15B < PokeBattle_HealingMove - def pbFailsAgainstTarget?(user, target) - if target.status == :NONE - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbHealAmount(user) - return (user.totalhp / 2.0).round - end - - def pbEffectAgainstTarget(user, target) - target.pbCureStatus - super - end -end - -#=============================================================================== -# Increases the user's and its ally's Attack and Special Attack by 1 stage each, -# if they have Plus or Minus. (Gear Up) -#=============================================================================== -# NOTE: In Gen 5, this move should have a target of UserSide, while in Gen 6+ it -# should have a target of UserAndAllies. This is because, in Gen 5, this -# move shouldn't call def pbSuccessCheckAgainstTarget for each Pokémon -# currently in battle that will be affected by this move (i.e. allies -# aren't protected by their substitute/ability/etc., but they are in Gen -# 6+). We achieve this by not targeting any battlers in Gen 5, since -# pbSuccessCheckAgainstTarget is only called for targeted battlers. -class PokeBattle_Move_15C < PokeBattle_Move - def ignoresSubstitute?(user) - ; return true; - end - - def pbMoveFailed?(user, targets) - @validTargets = [] - @battle.eachSameSideBattler(user) do |b| - next if !b.hasActiveAbility?([:MINUS, :PLUS]) - next if !b.pbCanRaiseStatStage?(:ATTACK, user, self) && - !b.pbCanRaiseStatStage?(:SPECIAL_ATTACK, user, self) - @validTargets.push(b) - end - if @validTargets.length == 0 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbFailsAgainstTarget?(user, target) - return false if @validTargets.any? { |b| b.index == target.index } - return true if !target.hasActiveAbility?([:MINUS, :PLUS]) - @battle.pbDisplay(_INTL("{1}'s stats can't be raised further!", target.pbThis)) - return true - end - - def pbEffectAgainstTarget(user, target) - showAnim = true - if target.pbCanRaiseStatStage?(:ATTACK, user, self) - if target.pbRaiseStatStage(:ATTACK, 1, user, showAnim) - showAnim = false - end - end - if target.pbCanRaiseStatStage?(:SPECIAL_ATTACK, user, self) - target.pbRaiseStatStage(:SPECIAL_ATTACK, 1, user, showAnim) - end - end - - def pbEffectGeneral(user) - return if pbTarget(user) != :UserSide - @validTargets.each { |b| pbEffectAgainstTarget(user, b) } - end -end - -#=============================================================================== -# User gains stat stages equal to each of the target's positive stat stages, -# and target's positive stat stages become 0, before damage calculation. -# (Spectral Thief) -#=============================================================================== -class PokeBattle_Move_15D < PokeBattle_Move - def ignoresSubstitute?(user) - ; return true; - end - - def pbCalcDamage(user, target, numTargets = 1) - if target.hasRaisedStatStages? - pbShowAnimation(@id, user, target, 1) # Stat stage-draining animation - @battle.pbDisplay(_INTL("{1} stole the target's boosted stats!", user.pbThis)) - showAnim = true - GameData::Stat.each_battle do |s| - next if target.stages[s.id] <= 0 - if user.pbCanRaiseStatStage?(s.id, user, self) - if user.pbRaiseStatStage(s.id, target.stages[s.id], user, showAnim) - showAnim = false - end - end - target.stages[s.id] = 0 - end - end - super - end -end - -#=============================================================================== -# Until the end of the next round, the user's moves will always be critical hits. -# (Laser Focus) -#=============================================================================== -class PokeBattle_Move_15E < PokeBattle_Move - def pbEffectGeneral(user) - user.effects[PBEffects::LaserFocus] = 2 - @battle.pbDisplay(_INTL("{1} concentrated intensely!", user.pbThis)) - end -end - -#=============================================================================== -# Decreases the user's Defense by 1 stage. (Clanging Scales) -#=============================================================================== -class PokeBattle_Move_15F < PokeBattle_StatDownMove - def initialize(battle, move) - super - @statDown = [:DEFENSE, 1] - end -end - -#=============================================================================== -# Decreases the target's Attack by 1 stage. Heals user by an amount equal to the -# target's Attack stat (after applying stat stages, before this move decreases -# it). (Strength Sap) -#=============================================================================== -class PokeBattle_Move_160 < PokeBattle_Move - def healingMove? - return true; - end - - def pbFailsAgainstTarget?(user, target) - # NOTE: The official games appear to just check whether the target's Attack - # stat stage is -6 and fail if so, but I've added the "fail if target - # has Contrary and is at +6" check too for symmetry. This move still - # works even if the stat stage cannot be changed due to an ability or - # other effect. - if !@battle.moldBreaker && target.hasActiveAbility?(:CONTRARY) && - target.statStageAtMax?(:ATTACK) - @battle.pbDisplay(_INTL("But it failed!")) - return true - elsif target.statStageAtMin?(:ATTACK) - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectAgainstTarget(user, target) - # Calculate target's effective attack value - stageMul = [2, 2, 2, 2, 2, 2, 2, 3, 4, 5, 6, 7, 8] - stageDiv = [8, 7, 6, 5, 4, 3, 2, 2, 2, 2, 2, 2, 2] - atk = target.attack - atkStage = target.stages[:ATTACK] + 6 - healAmt = (atk.to_f * stageMul[atkStage] / stageDiv[atkStage]).floor - # Reduce target's Attack stat - if target.pbCanLowerStatStage?(:ATTACK, user, self) - target.pbLowerStatStage(:ATTACK, 1, user) - end - # Heal user - if target.hasActiveAbility?(:LIQUIDOOZE) - @battle.pbShowAbilitySplash(target) - user.pbReduceHP(healAmt) - @battle.pbDisplay(_INTL("{1} sucked up the liquid ooze!", user.pbThis)) - @battle.pbHideAbilitySplash(target) - user.pbItemHPHealCheck - elsif user.canHeal? - healAmt = (healAmt * 1.3).floor if user.hasActiveItem?(:BIGROOT) - user.pbRecoverHP(healAmt) - @battle.pbDisplay(_INTL("{1}'s HP was restored.", user.pbThis)) - end - end -end - -#=============================================================================== -# User and target swap their Speed stats (not their stat stages). (Speed Swap) -#=============================================================================== -class PokeBattle_Move_161 < PokeBattle_Move - def ignoresSubstitute?(user) - ; return true; - end - - def pbEffectAgainstTarget(user, target) - user.speed, target.speed = target.speed, user.speed - @battle.pbDisplay(_INTL("{1} switched Speed with its target!", user.pbThis)) - end -end - -#=============================================================================== -# User loses their Fire type. Fails if user is not Fire-type. (Burn Up) -#=============================================================================== -class PokeBattle_Move_162 < PokeBattle_Move - def pbMoveFailed?(user, targets) - if !user.pbHasType?(:FIRE) - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectAfterAllHits(user, target) - if !user.effects[PBEffects::BurnUp] - user.effects[PBEffects::BurnUp] = true - @battle.pbDisplay(_INTL("{1} burned itself out!", user.pbThis)) - end - end -end - -#=============================================================================== -# Ignores all abilities that alter this move's success or damage. -# (Moongeist Beam, Sunsteel Strike) -#=============================================================================== -class PokeBattle_Move_163 < PokeBattle_Move - def pbChangeUsageCounters(user, specialUsage) - super - @battle.moldBreaker = true if !specialUsage - end -end - -#=============================================================================== -# Ignores all abilities that alter this move's success or damage. This move is -# physical if user's Attack is higher than its Special Attack (after applying -# stat stages), and special otherwise. (Photon Geyser) -#=============================================================================== -class PokeBattle_Move_164 < PokeBattle_Move_163 - def initialize(battle, move) - super - @calcCategory = 1 - end - - def physicalMove?(thisType = nil) - ; return (@calcCategory == 0); - end - - def specialMove?(thisType = nil) - ; return (@calcCategory == 1); - end - - def pbOnStartUse(user, targets) - echoln _INTL("type1={1}",user.type1) - echoln _INTL("type2={1}",user.type2) - - # Calculate user's effective attacking value - stageMul = [2, 2, 2, 2, 2, 2, 2, 3, 4, 5, 6, 7, 8] - stageDiv = [8, 7, 6, 5, 4, 3, 2, 2, 2, 2, 2, 2, 2] - atk = user.attack - atkStage = user.stages[:ATTACK] + 6 - realAtk = (atk.to_f * stageMul[atkStage] / stageDiv[atkStage]).floor - spAtk = user.spatk - spAtkStage = user.stages[:SPECIAL_ATTACK] + 6 - realSpAtk = (spAtk.to_f * stageMul[spAtkStage] / stageDiv[spAtkStage]).floor - # Determine move's category - @calcCategory = (realAtk > realSpAtk) ? 0 : 1 - - if user.hasActiveItem?(:NECROZIUM) && (user.isFusionOf(:NECROZMA) && !user.pokemon.spriteform_body && !user.pokemon.spriteform_head) - # user.type2 = :DRAGON if user.pokemon.hasBodyOf?(:NECROZMA) - # user.attack*=1.3 - # user.spatk*=1.3 - # user.defense*=0.5 - # user.spdef*=0.5 - # user.speed*=1.5 - - user.changeFormSpecies(:NECROZMA,:U_NECROZMA,"UltraBurst2") - #user.changeForm(1,:NECROZMA) - end - end -end - -#change back at the end of battle -Events.onEndBattle += proc { |_sender,_e| - $Trainer.party.each_with_index do |value, i| - pokemon = $Trainer.party[i] - pokemon.changeFormSpecies(:U_NECROZMA,:NECROZMA) if pokemon.isFusionOf(:U_NECROZMA) - end -} - -#=============================================================================== -# Negates the target's ability while it remains on the field, if it has already -# performed its action this round. (Core Enforcer) -#=============================================================================== -class PokeBattle_Move_165 < PokeBattle_Move - def pbEffectAgainstTarget(user, target) - return if target.damageState.substitute || target.effects[PBEffects::GastroAcid] - return if target.unstoppableAbility? - return if @battle.choices[target.index][0] != :UseItem && - !((@battle.choices[target.index][0] == :UseMove || - @battle.choices[target.index][0] == :Shift) && target.movedThisRound?) - target.effects[PBEffects::GastroAcid] = true - target.effects[PBEffects::Truant] = false - @battle.pbDisplay(_INTL("{1}'s Ability was suppressed!", target.pbThis)) - target.pbOnAbilityChanged(target.ability) - end -end - -#=============================================================================== -# Power is doubled if the user's last move failed. (Stomping Tantrum) -#=============================================================================== -class PokeBattle_Move_166 < PokeBattle_Move - def pbBaseDamage(baseDmg, user, target) - baseDmg *= 2 if user.lastRoundMoveFailed - return baseDmg - end -end - -#=============================================================================== -# For 5 rounds, lowers power of attacks against the user's side. Fails if -# weather is not hail. (Aurora Veil) -#=============================================================================== -class PokeBattle_Move_167 < PokeBattle_Move - def pbMoveFailed?(user, targets) - if @battle.pbWeather != :Hail - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - if user.pbOwnSide.effects[PBEffects::AuroraVeil] > 0 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - user.pbOwnSide.effects[PBEffects::AuroraVeil] = 5 - user.pbOwnSide.effects[PBEffects::AuroraVeil] = 8 if user.hasActiveItem?(:LIGHTCLAY) - @battle.pbDisplay(_INTL("{1} made {2} stronger against physical and special moves!", - @name, user.pbTeam(true))) - end -end - -#=============================================================================== -# User is protected against moves with the "B" flag this round. If a Pokémon -# makes contact with the user while this effect applies, that Pokémon is -# poisoned. (Baneful Bunker) -#=============================================================================== -class PokeBattle_Move_168 < PokeBattle_ProtectMove - def initialize(battle, move) - super - @effect = PBEffects::BanefulBunker - end -end - -#=============================================================================== -# This move's type is the same as the user's first type. (Revelation Dance) -#=============================================================================== -class PokeBattle_Move_169 < PokeBattle_Move - def pbBaseType(user) - userTypes = user.pbTypes(true) - return userTypes[0] - end -end - -#=============================================================================== -# This round, target becomes the target of attacks that have single targets. -# (Spotlight) -#=============================================================================== -class PokeBattle_Move_16A < PokeBattle_Move - def pbEffectAgainstTarget(user, target) - target.effects[PBEffects::Spotlight] = 1 - target.eachAlly do |b| - next if b.effects[PBEffects::Spotlight] < target.effects[PBEffects::Spotlight] - target.effects[PBEffects::Spotlight] = b.effects[PBEffects::Spotlight] + 1 - end - @battle.pbDisplay(_INTL("{1} became the center of attention!", target.pbThis)) - end -end - -#=============================================================================== -# The target uses its most recent move again. (Instruct) -#=============================================================================== -class PokeBattle_Move_16B < PokeBattle_Move - def ignoresSubstitute?(user) - ; return true; - end - - def initialize(battle, move) - super - @moveBlacklist = [ - "0D4", # Bide - "14B", # King's Shield - "16B", # Instruct (this move) - # Struggle - "002", # Struggle - # Moves that affect the moveset - "05C", # Mimic - "05D", # Sketch - "069", # Transform - # Moves that call other moves - "0AE", # Mirror Move - "0AF", # Copycat - "0B0", # Me First - "0B3", # Nature Power - "0B4", # Sleep Talk - "0B5", # Assist - "0B6", # Metronome - # Moves that require a recharge turn - "0C2", # Hyper Beam - # Two-turn attacks - "0C3", # Razor Wind - "0C4", # Solar Beam, Solar Blade - "0C5", # Freeze Shock - "0C6", # Ice Burn - "0C7", # Sky Attack - "0C8", # Skull Bash - "0C9", # Fly - "0CA", # Dig - "0CB", # Dive - "0CC", # Bounce - "0CD", # Shadow Force - "0CE", # Sky Drop - "12E", # Shadow Half - "14D", # Phantom Force - "14E", # Geomancy - # Moves that start focussing at the start of the round - "115", # Focus Punch - "171", # Shell Trap - "172" # Beak Blast - ] - end - - def pbFailsAgainstTarget?(user, target) - if !target.lastRegularMoveUsed || !target.pbHasMove?(target.lastRegularMoveUsed) - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - if target.usingMultiTurnAttack? - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - targetMove = @battle.choices[target.index][2] - if targetMove && (targetMove.function == "115" || # Focus Punch - targetMove.function == "171" || # Shell Trap - targetMove.function == "172") # Beak Blast - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - if @moveBlacklist.include?(GameData::Move.get(target.lastRegularMoveUsed).function_code) - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - idxMove = -1 - target.eachMoveWithIndex do |m, i| - idxMove = i if m.id == target.lastRegularMoveUsed - end - if target.moves[idxMove].pp == 0 && target.moves[idxMove].total_pp > 0 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectAgainstTarget(user, target) - target.effects[PBEffects::Instruct] = true - end -end - -#=============================================================================== -# Target cannot use sound-based moves for 2 more rounds. (Throat Chop) -#=============================================================================== -class PokeBattle_Move_16C < PokeBattle_Move - def pbAdditionalEffect(user, target) - return if target.fainted? || target.damageState.substitute - @battle.pbDisplay(_INTL("The effects of {1} prevent {2} from using certain moves!", - @name, target.pbThis(true))) if target.effects[PBEffects::ThroatChop] == 0 - target.effects[PBEffects::ThroatChop] = 3 - end -end - -#=============================================================================== -# Heals user by 1/2 of its max HP, or 2/3 of its max HP in a sandstorm. (Shore Up) -#=============================================================================== -class PokeBattle_Move_16D < PokeBattle_HealingMove - def pbHealAmount(user) - return (user.totalhp * 2 / 3.0).round if @battle.pbWeather == :Sandstorm - return (user.totalhp / 2.0).round - end -end - -#=============================================================================== -# Heals target by 1/2 of its max HP, or 2/3 of its max HP in Grassy Terrain. -# (Floral Healing) -#=============================================================================== -class PokeBattle_Move_16E < PokeBattle_Move - def healingMove? - return true; - end - - def pbFailsAgainstTarget?(user, target) - if target.hp == target.totalhp - @battle.pbDisplay(_INTL("{1}'s HP is full!", target.pbThis)) - return true - elsif !target.canHeal? - @battle.pbDisplay(_INTL("{1} is unaffected!", target.pbThis)) - return true - end - return false - end - - def pbEffectAgainstTarget(user, target) - hpGain = (target.totalhp / 2.0).round - hpGain = (target.totalhp * 2 / 3.0).round if @battle.field.terrain == :Grassy - target.pbRecoverHP(hpGain) - @battle.pbDisplay(_INTL("{1}'s HP was restored.", target.pbThis)) - end -end - -#=============================================================================== -# Damages target if target is a foe, or heals target by 1/2 of its max HP if -# target is an ally. (Pollen Puff) -#=============================================================================== -class PokeBattle_Move_16F < PokeBattle_Move - def pbTarget(user) - return GameData::Target.get(:NearFoe) if user.effects[PBEffects::HealBlock] > 0 - return super - end - - def pbOnStartUse(user, targets) - @healing = false - @healing = !user.opposes?(targets[0]) if targets.length > 0 - end - - def pbFailsAgainstTarget?(user, target) - return false if !@healing - if target.effects[PBEffects::Substitute] > 0 && !ignoresSubstitute?(user) - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - if !target.canHeal? - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbDamagingMove? - return false if @healing - return super - end - - def pbEffectAgainstTarget(user, target) - return if !@healing - target.pbRecoverHP(target.totalhp / 2) - @battle.pbDisplay(_INTL("{1}'s HP was restored.", target.pbThis)) - end - - def pbShowAnimation(id, user, targets, hitNum = 0, showAnimation = true) - hitNum = 1 if @healing # Healing anim - super - end -end - -#=============================================================================== -# Damages user by 1/2 of its max HP, even if this move misses. (Mind Blown) -#=============================================================================== -class PokeBattle_Move_170 < PokeBattle_Move - def worksWithNoTargets? - return true; - end - - def pbMoveFailed?(user, targets) - if !@battle.moldBreaker - bearer = @battle.pbCheckGlobalAbility(:DAMP) - if bearer != nil - @battle.pbShowAbilitySplash(bearer) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - @battle.pbDisplay(_INTL("{1} cannot use {2}!", user.pbThis, @name)) - else - @battle.pbDisplay(_INTL("{1} cannot use {2} because of {3}'s {4}!", - user.pbThis, @name, bearer.pbThis(true), bearer.abilityName)) - end - @battle.pbHideAbilitySplash(bearer) - return true - end - end - return false - end - - def pbSelfKO(user) - return if !user.takesIndirectDamage? - user.pbReduceHP((user.totalhp / 2.0).round, false) - user.pbItemHPHealCheck - end -end - -#=============================================================================== -# Fails if user has not been hit by an opponent's physical move this round. -# (Shell Trap) -#=============================================================================== -class PokeBattle_Move_171 < PokeBattle_Move - def pbDisplayChargeMessage(user) - user.effects[PBEffects::ShellTrap] = true - @battle.pbCommonAnimation("ShellTrap", user) - @battle.pbDisplay(_INTL("{1} set a shell trap!", user.pbThis)) - end - - def pbDisplayUseMessage(user) - super if user.tookPhysicalHit - end - - def pbMoveFailed?(user, targets) - if !user.effects[PBEffects::ShellTrap] - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - if !user.tookPhysicalHit - @battle.pbDisplay(_INTL("{1}'s shell trap didn't work!", user.pbThis)) - return true - end - return false - end -end - -#=============================================================================== -# If a Pokémon makes contact with the user before it uses this move, the -# attacker is burned. (Beak Blast) -#=============================================================================== -class PokeBattle_Move_172 < PokeBattle_Move - def pbDisplayChargeMessage(user) - user.effects[PBEffects::BeakBlast] = true - @battle.pbCommonAnimation("BeakBlast", user) - @battle.pbDisplay(_INTL("{1} started heating up its beak!", user.pbThis)) - end -end - -#=============================================================================== -# For 5 rounds, creates a psychic terrain which boosts Psychic-type moves and -# prevents Pokémon from being hit by >0 priority moves. Affects non-airborne -# Pokémon only. (Psychic Terrain) -#=============================================================================== -class PokeBattle_Move_173 < PokeBattle_Move - def pbMoveFailed?(user, targets) - if @battle.field.terrain == :Psychic - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end - - def pbEffectGeneral(user) - @battle.pbStartTerrain(user, :Psychic) - end -end - -#=============================================================================== -# Fails if this isn't the user's first turn. (First Impression) -#=============================================================================== -class PokeBattle_Move_174 < PokeBattle_Move - def pbMoveFailed?(user, targets) - if user.turnCount > 1 - @battle.pbDisplay(_INTL("But it failed!")) - return true - end - return false - end -end - -#=============================================================================== -# Hits twice. Causes the target to flinch. Does double damage and has perfect -# accuracy if the target is Minimized. (Double Iron Bash) -#=============================================================================== -class PokeBattle_Move_175 < PokeBattle_FlinchMove - def multiHitMove? - return true; - end - - def pbNumHits(user, targets) - ; return 2; - end - - def tramplesMinimize?(param = 1) - ; return true; - end -end - -# NOTE: If you're inventing new move effects, use function code 176 and onwards. -# Actually, you might as well use high numbers like 500+ (up to FFFF), -# just to make sure later additions to Essentials don't clash with your -# new effects. diff --git a/Data/Scripts/011_Battle/003_Battle/001_PokeBattle_BattleCommon.rb b/Data/Scripts/011_Battle/003_Battle/001_PokeBattle_BattleCommon.rb deleted file mode 100644 index 1fc2b4994..000000000 --- a/Data/Scripts/011_Battle/003_Battle/001_PokeBattle_BattleCommon.rb +++ /dev/null @@ -1,264 +0,0 @@ -module PokeBattle_BattleCommon - #============================================================================= - # Store caught Pokémon - #============================================================================= - def pbStorePokemon(pkmn) - # Nickname the Pokémon (unless it's a Shadow Pokémon) - if !pkmn.shadowPokemon? - if pbDisplayConfirm(_INTL("Would you like to give a nickname to {1}?", pkmn.name)) - nickname = @scene.pbNameEntry(_INTL("{1}'s nickname?", pkmn.speciesName), pkmn) - pkmn.name = nickname - end - end - # Store the Pokémon - currentBox = @peer.pbCurrentBox - storedBox = @peer.pbStorePokemon(pbPlayer, pkmn) - if storedBox < 0 - pbDisplayPaused(_INTL("{1} has been added to your party.", pkmn.name)) - @initialItems[0][pbPlayer.party.length - 1] = pkmn.item_id if @initialItems - return - end - # Messages saying the Pokémon was stored in a PC box - creator = @peer.pbGetStorageCreatorName - curBoxName = @peer.pbBoxName(currentBox) - boxName = @peer.pbBoxName(storedBox) - if storedBox != currentBox - if creator - pbDisplayPaused(_INTL("Box \"{1}\" on {2}'s PC was full.", curBoxName, creator)) - else - pbDisplayPaused(_INTL("Box \"{1}\" on someone's PC was full.", curBoxName)) - end - pbDisplayPaused(_INTL("{1} was transferred to box \"{2}\".", pkmn.name, boxName)) - else - if creator - pbDisplayPaused(_INTL("{1} was transferred to {2}'s PC.", pkmn.name, creator)) - else - pbDisplayPaused(_INTL("{1} was transferred to someone's PC.", pkmn.name)) - end - pbDisplayPaused(_INTL("It was stored in box \"{1}\".", boxName)) - end - end - - #def pbChoosePokemon(variableNumber, nameVarNumber, ableProc = nil, allowIneligible = false) - # def swapCaughtPokemon(caughtPokemon) - # pbChoosePokemon(1,2, - # proc {|poke| - # !poke.egg? && - # !(poke.isShadow? rescue false) - # }) - # index = pbGet(1) - # return false if index == -1 - # $PokemonStorage.pbStoreCaught($Trainer.party[index]) - # pbRemovePokemonAt(index) - # pbStorePokemon(caughtPokemon) - # return true - # end - - # Register all caught Pokémon in the Pokédex, and store them. - def pbRecordAndStoreCaughtPokemon - @caughtPokemon.each do |pkmn| - pbPlayer.pokedex.register(pkmn) # In case the form changed upon leaving battle - # Record the Pokémon's species as owned in the Pokédex - if !pbPlayer.owned?(pkmn.species) - pbPlayer.pokedex.set_owned(pkmn.species) - if $Trainer.has_pokedex - pbDisplayPaused(_INTL("{1}'s data was added to the Pokédex.", pkmn.name)) - pbPlayer.pokedex.register_last_seen(pkmn) - @scene.pbShowPokedex(pkmn.species) - end - end - # Record a Shadow Pokémon's species as having been caught - pbPlayer.pokedex.set_shadow_pokemon_owned(pkmn.species) if pkmn.shadowPokemon? - # Store caught Pokémon - promptCaughtPokemonAction(pkmn) - if $game_switches[AUTOSAVE_CATCH_SWITCH] - Kernel.tryAutosave() - end - - end - @caughtPokemon.clear - end - - # def promptCaughtPokemonAction(pokemon) - # pickedOption = false - # return pbStorePokemon(pokemon) if !$Trainer.party_full? - # - # while !pickedOption - # command = pbMessage(_INTL("\\ts[]Your team is full!"), - # [_INTL("Add to your party"), _INTL("Store to PC"),], 2) - # echoln ("command " + command.to_s) - # case command - # when 0 #SWAP - # if swapCaughtPokemon(pokemon) - # echoln pickedOption - # pickedOption = true - # end - # else - # #STORE - # pbStorePokemon(pokemon) - # echoln pickedOption - # pickedOption = true - # end - # end - # - # end - - #============================================================================= - # Throw a Poké Ball - #============================================================================= - def pbThrowPokeBall(idxBattler, ball, catch_rate = nil, showPlayer = false) - # Determine which Pokémon you're throwing the Poké Ball at - battler = nil - if opposes?(idxBattler) - battler = @battlers[idxBattler] - else - battler = @battlers[idxBattler].pbDirectOpposing(true) - end - if battler.fainted? - battler.eachAlly do |b| - battler = b - break - end - end - # Messages - itemName = GameData::Item.get(ball).name - if battler.fainted? - if itemName.starts_with_vowel? - pbDisplay(_INTL("{1} threw an {2}!", pbPlayer.name, itemName)) - else - pbDisplay(_INTL("{1} threw a {2}!", pbPlayer.name, itemName)) - end - pbDisplay(_INTL("But there was no target...")) - return - end - if itemName.starts_with_vowel? - pbDisplayBrief(_INTL("{1} threw an {2}!", pbPlayer.name, itemName)) - else - pbDisplayBrief(_INTL("{1} threw a {2}!", pbPlayer.name, itemName)) - end - # Animation of opposing trainer blocking Poké Balls (unless it's a Snag Ball - # at a Shadow Pokémon) - if trainerBattle? && !(GameData::Item.get(ball).is_snag_ball? && battler.shadowPokemon?) - @scene.pbThrowAndDeflect(ball, 1) - pbDisplay(_INTL("The Trainer blocked your Poké Ball! Don't be a thief!")) - return - elsif $game_switches[SWITCH_CANNOT_CATCH_POKEMON] - @scene.pbThrowAndDeflect(ball, 1) - pbDisplay(_INTL("The Pokémon is impossible to catch!")) - return - end - # Calculate the number of shakes (4=capture) - pkmn = battler.pokemon - @criticalCapture = false - numShakes = pbCaptureCalc(pkmn, battler, catch_rate, ball) - PBDebug.log("[Threw Poké Ball] #{itemName}, #{numShakes} shakes (4=capture)") - # Animation of Ball throw, absorb, shake and capture/burst out - @scene.pbThrow(ball, numShakes, @criticalCapture, battler.index, showPlayer) - # Outcome message - case numShakes - when 0 - pbDisplay(_INTL("Oh no! The Pokémon broke free!")) - BallHandlers.onFailCatch(ball, self, battler) - when 1 - pbDisplay(_INTL("Aww! It appeared to be caught!")) - BallHandlers.onFailCatch(ball, self, battler) - when 2 - pbDisplay(_INTL("Aargh! Almost had it!")) - BallHandlers.onFailCatch(ball, self, battler) - when 3 - pbDisplay(_INTL("Gah! It was so close, too!")) - BallHandlers.onFailCatch(ball, self, battler) - when 4 - if $game_switches[SWITCH_SILVERBOSS_BATTLE] - pkmn.species = :PALDIATINA - pkmn.name = "Paldiatina" - end - pbDisplayBrief(_INTL("Gotcha! {1} was caught!", pkmn.name)) - @scene.pbThrowSuccess # Play capture success jingle - pbRemoveFromParty(battler.index, battler.pokemonIndex) - # Gain Exp - if Settings::GAIN_EXP_FOR_CAPTURE - battler.captured = true - pbGainExp - battler.captured = false - end - battler.pbReset - if pbAllFainted?(battler.index) - @decision = (trainerBattle?) ? 1 : 4 # Battle ended by win/capture - end - # Modify the Pokémon's properties because of the capture - if GameData::Item.get(ball).is_snag_ball? - pkmn.owner = Pokemon::Owner.new_from_trainer(pbPlayer) - end - BallHandlers.onCatch(ball, self, pkmn) - pkmn.poke_ball = ball - pkmn.makeUnmega if pkmn.mega? - pkmn.makeUnprimal - pkmn.update_shadow_moves if pkmn.shadowPokemon? - pkmn.record_first_moves - # Reset form - pkmn.forced_form = nil if MultipleForms.hasFunction?(pkmn.species, "getForm") - @peer.pbOnLeavingBattle(self, pkmn, true, true) - # Make the Poké Ball and data box disappear - @scene.pbHideCaptureBall(idxBattler) - # Save the Pokémon for storage at the end of battle - @caughtPokemon.push(pkmn) - end - end - - #============================================================================= - # Calculate how many shakes a thrown Poké Ball will make (4 = capture) - #============================================================================= - def pbCaptureCalc(pkmn, battler, catch_rate, ball) - return 4 if $DEBUG && Input.press?(Input::CTRL) - # Get a catch rate if one wasn't provided - catch_rate = pkmn.species_data.catch_rate if !catch_rate - # Modify catch_rate depending on the Poké Ball's effect - ultraBeast = [:NIHILEGO, :BUZZWOLE, :PHEROMOSA, :XURKITREE, :CELESTEELA, - :KARTANA, :GUZZLORD, :POIPOLE, :NAGANADEL, :STAKATAKA, - :BLACEPHALON].include?(pkmn.species) - if !ultraBeast || ball == :BEASTBALL - catch_rate = BallHandlers.modifyCatchRate(ball, catch_rate, self, battler, ultraBeast) - else - catch_rate /= 10 - end - - - - # First half of the shakes calculation - a = battler.totalhp - b = battler.hp - x = ((3 * a - 2 * b) * catch_rate.to_f) / (3 * a) - # Calculation modifiers - if battler.status == :SLEEP || battler.status == :FROZEN - x *= 2.5 - elsif battler.status != :NONE - x *= 1.5 - end - x = x.floor - x = 1 if x < 1 - # Definite capture, no need to perform randomness checks - return 4 if x >= 255 || BallHandlers.isUnconditional?(ball, self, battler) - # Second half of the shakes calculation - y = (65536 / ((255.0 / x) ** 0.1875)).floor - - #Increased chances of catching if is on last ball - isOnLastBall = !$PokemonBag.pbHasItem?(ball) - echoln isOnLastBall - # Critical capture check - if isOnLastBall - c = x * 6 / 12 - if c > 0 && pbRandom(256) < c - @criticalCapture = true - return 4 - end - end - # Calculate the number of shakes - numShakes = 0 - for i in 0...4 - break if numShakes < i - numShakes += 1 if pbRandom(65536) < y - end - return numShakes - end -end diff --git a/Data/Scripts/011_Battle/003_Battle/002_PokeBattle_Battle.rb b/Data/Scripts/011_Battle/003_Battle/002_PokeBattle_Battle.rb deleted file mode 100644 index 56708268b..000000000 --- a/Data/Scripts/011_Battle/003_Battle/002_PokeBattle_Battle.rb +++ /dev/null @@ -1,799 +0,0 @@ -# Results of battle: -# 0 - Undecided or aborted -# 1 - Player won -# 2 - Player lost -# 3 - Player or wild Pokémon ran from battle, or player forfeited the match -# 4 - Wild Pokémon was caught -# 5 - Draw -# Possible actions a battler can take in a round: -# :None -# :UseMove -# :SwitchOut -# :UseItem -# :Call -# :Run -# :Shift -# NOTE: If you want to have more than 3 Pokémon on a side at once, you will need -# to edit some code. Mainly this is to change/add coordinates for the -# sprites, describe the relationships between Pokémon and trainers, and to -# change messages. The methods that will need editing are as follows: -# class PokeBattle_Battle -# def setBattleMode -# def pbGetOwnerIndexFromBattlerIndex -# def pbGetOpposingIndicesInOrder -# def nearBattlers? -# def pbStartBattleSendOut -# def pbEORShiftDistantBattlers -# def pbCanShift? -# def pbEndOfRoundPhase -# class TargetMenuDisplay -# def initialize -# class PokemonDataBox -# def initializeDataBoxGraphic -# module PokeBattle_SceneConstants -# def self.pbBattlerPosition -# def self.pbTrainerPosition -# class PokemonTemp -# def recordBattleRule -# (There is no guarantee that this list is complete.) - -class PokeBattle_Battle - attr_reader :scene # Scene object for this battle - attr_reader :peer - attr_reader :field # Effects common to the whole of a battle - attr_reader :sides # Effects common to each side of a battle - attr_reader :positions # Effects that apply to a battler position - attr_reader :battlers # Currently active Pokémon - attr_reader :sideSizes # Array of number of battlers per side - attr_accessor :backdrop # Filename fragment used for background graphics - attr_accessor :backdropBase # Filename fragment used for base graphics - attr_accessor :time # Time of day (0=day, 1=eve, 2=night) - attr_accessor :environment # Battle surroundings (for mechanics purposes) - attr_reader :turnCount - attr_accessor :decision # Decision: 0=undecided; 1=win; 2=loss; 3=escaped; 4=caught - attr_reader :player # Player trainer (or array of trainers) - attr_reader :opponent # Opponent trainer (or array of trainers) - attr_accessor :items # Items held by opponents - attr_accessor :endSpeeches - attr_accessor :endSpeechesWin - attr_accessor :party1starts # Array of start indexes for each player-side trainer's party - attr_accessor :party2starts # Array of start indexes for each opponent-side trainer's party - attr_accessor :internalBattle # Internal battle flag - attr_accessor :debug # Debug flag - attr_accessor :canRun # True if player can run from battle - attr_accessor :canLose # True if player won't black out if they lose - attr_accessor :switchStyle # Switch/Set "battle style" option - attr_accessor :showAnims # "Battle Effects" option - attr_accessor :controlPlayer # Whether player's Pokémon are AI controlled - attr_accessor :expGain # Whether Pokémon can gain Exp/EVs - attr_accessor :moneyGain # Whether the player can gain/lose money - attr_accessor :rules - attr_accessor :choices # Choices made by each Pokémon this round - attr_accessor :megaEvolution # Battle index of each trainer's Pokémon to Mega Evolve - attr_reader :initialItems - attr_reader :recycleItems - attr_reader :belch - attr_reader :battleBond - attr_reader :usedInBattle # Whether each Pokémon was used in battle (for Burmy) - attr_reader :successStates # Success states - attr_accessor :lastMoveUsed # Last move used - attr_accessor :lastMoveUser # Last move user - attr_reader :switching # True if during the switching phase of the round - attr_reader :futureSight # True if Future Sight is hitting - attr_reader :endOfRound # True during the end of round - attr_accessor :moldBreaker # True if Mold Breaker applies - attr_reader :struggle # The Struggle move - - include PokeBattle_BattleCommon - - def pbRandom(x); return rand(x); end - - #============================================================================= - # Creating the battle class - #============================================================================= - def initialize(scene,p1,p2,player,opponent) - if p1.length==0 - raise ArgumentError.new(_INTL("Party 1 has no Pokémon.")) - elsif p2.length==0 - raise ArgumentError.new(_INTL("Party 2 has no Pokémon.")) - end - @scene = scene - @peer = PokeBattle_BattlePeer.create - @battleAI = PokeBattle_AI.new(self) - @field = PokeBattle_ActiveField.new # Whole field (gravity/rooms) - @sides = [PokeBattle_ActiveSide.new, # Player's side - PokeBattle_ActiveSide.new] # Foe's side - @positions = [] # Battler positions - @battlers = [] - @sideSizes = [1,1] # Single battle, 1v1 - @backdrop = "" - @backdropBase = nil - @time = 0 - @environment = :None # e.g. Tall grass, cave, still water - @turnCount = 0 - @decision = 0 - @caughtPokemon = [] - player = [player] if !player.nil? && !player.is_a?(Array) - opponent = [opponent] if !opponent.nil? && !opponent.is_a?(Array) - @player = player # Array of Player/NPCTrainer objects, or nil - @opponent = opponent # Array of NPCTrainer objects, or nil - @items = nil - @endSpeeches = [] - @endSpeechesWin = [] - @party1 = p1 - @party2 = p2 - @party1order = Array.new(@party1.length) { |i| i } - @party2order = Array.new(@party2.length) { |i| i } - @party1starts = [0] - @party2starts = [0] - @internalBattle = true - @debug = false - @canRun = true - @canLose = false - @switchStyle = true - @showAnims = true - @controlPlayer = false - @expGain = true - @moneyGain = true - @rules = {} - @priority = [] - @priorityTrickRoom = false - @choices = [] - @megaEvolution = [ - [-1] * (@player ? @player.length : 1), - [-1] * (@opponent ? @opponent.length : 1) - ] - @initialItems = [ - Array.new(@party1.length) { |i| (@party1[i]) ? @party1[i].item_id : nil }, - Array.new(@party2.length) { |i| (@party2[i]) ? @party2[i].item_id : nil } - ] - @recycleItems = [Array.new(@party1.length, nil), Array.new(@party2.length, nil)] - @belch = [Array.new(@party1.length, false), Array.new(@party2.length, false)] - @battleBond = [Array.new(@party1.length, false), Array.new(@party2.length, false)] - @usedInBattle = [Array.new(@party1.length, false), Array.new(@party2.length, false)] - @successStates = [] - @lastMoveUsed = nil - @lastMoveUser = -1 - @switching = false - @futureSight = false - @endOfRound = false - @moldBreaker = false - @runCommand = 0 - @nextPickupUse = 0 - if GameData::Move.exists?(:STRUGGLE) - @struggle = PokeBattle_Move.from_pokemon_move(self, Pokemon::Move.new(:STRUGGLE)) - else - @struggle = PokeBattle_Struggle.new(self, nil) - end - end - - #============================================================================= - # Information about the type and size of the battle - #============================================================================= - def wildBattle?; return @opponent.nil?; end - def trainerBattle?; return !@opponent.nil?; end - - def get_default_battle_format() - case $PokemonSystem.battle_type - when 0 then return [1, 1] - when 1 then return [2, 2] - when 2 then return [3, 3] - end - return [1,1] - end - - # Sets the number of battler slots on each side of the field independently. - # For "1v2" names, the first number is for the player's side and the second - # number is for the opposing side. - def setBattleMode(mode) - default = get_default_battle_format() - @sideSizes = - case mode - when "triple", "3v3" then [3, 3] - when "3v2" then [3, 2] - when "3v1" then [3, 1] - when "2v3" then [2, 3] - when "double", "2v2" then [2, 2] - when "2v1" then [2, 1] - when "1v3" then [1, 3] - when "1v2" then [1, 2] - when "single" then [1, 1] - when "1v1" then [1, 1] - else default # Single, 1v1 (default) - end - end - - def singleBattle? - return pbSideSize(0)==1 && pbSideSize(1)==1 - end - - def pbSideSize(index) - return @sideSizes[index%2] - end - - def maxBattlerIndex - return (pbSideSize(0)>pbSideSize(1)) ? (pbSideSize(0)-1)*2 : pbSideSize(1)*2-1 - end - - #============================================================================= - # Trainers and owner-related methods - #============================================================================= - def pbPlayer; return @player[0]; end - - # Given a battler index, returns the index within @player/@opponent of the - # trainer that controls that battler index. - # NOTE: You shouldn't ever have more trainers on a side than there are battler - # positions on that side. This method doesn't account for if you do. - def pbGetOwnerIndexFromBattlerIndex(idxBattler) - trainer = (opposes?(idxBattler)) ? @opponent : @player - return 0 if !trainer - case trainer.length - when 2 - n = pbSideSize(idxBattler%2) - return [0,0,1][idxBattler/2] if n==3 - return idxBattler/2 # Same as [0,1][idxBattler/2], i.e. 2 battler slots - when 3 - return idxBattler/2 - end - return 0 - end - - def pbGetOwnerFromBattlerIndex(idxBattler) - idxTrainer = pbGetOwnerIndexFromBattlerIndex(idxBattler) - return (opposes?(idxBattler)) ? @opponent[idxTrainer] : @player[idxTrainer] - end - - def pbGetOwnerIndexFromPartyIndex(idxBattler,idxParty) - ret = -1 - pbPartyStarts(idxBattler).each_with_index do |start,i| - break if start>idxParty - ret = i - end - return ret - end - - # Only used for the purpose of an error message when one trainer tries to - # switch another trainer's Pokémon. - def pbGetOwnerFromPartyIndex(idxBattler,idxParty) - idxTrainer = pbGetOwnerIndexFromPartyIndex(idxBattler,idxParty) - return (opposes?(idxBattler)) ? @opponent[idxTrainer] : @player[idxTrainer] - end - - def pbGetOwnerName(idxBattler) - idxTrainer = pbGetOwnerIndexFromBattlerIndex(idxBattler) - return @opponent[idxTrainer].full_name if opposes?(idxBattler) # Opponent - return @player[idxTrainer].full_name if idxTrainer>0 # Ally trainer - return @player[idxTrainer].name # Player - end - - def pbGetOwnerItems(idxBattler) - return [] if !@items || !opposes?(idxBattler) - return @items[pbGetOwnerIndexFromBattlerIndex(idxBattler)] - end - - # Returns whether the battler in position idxBattler is owned by the same - # trainer that owns the Pokémon in party slot idxParty. This assumes that - # both the battler position and the party slot are from the same side. - def pbIsOwner?(idxBattler,idxParty) - idxTrainer1 = pbGetOwnerIndexFromBattlerIndex(idxBattler) - idxTrainer2 = pbGetOwnerIndexFromPartyIndex(idxBattler,idxParty) - return idxTrainer1==idxTrainer2 - end - - def pbOwnedByPlayer?(idxBattler) - return false if opposes?(idxBattler) - return pbGetOwnerIndexFromBattlerIndex(idxBattler)==0 - end - - # Returns the number of Pokémon positions controlled by the given trainerIndex - # on the given side of battle. - def pbNumPositions(side,idxTrainer) - ret = 0 - for i in 0...pbSideSize(side) - t = pbGetOwnerIndexFromBattlerIndex(i*2+side) - next if t!=idxTrainer - ret += 1 - end - return ret - end - - #============================================================================= - # Get party information (counts all teams on the same side) - #============================================================================= - def pbParty(idxBattler) - return (opposes?(idxBattler)) ? @party2 : @party1 - end - - def pbOpposingParty(idxBattler) - return (opposes?(idxBattler)) ? @party1 : @party2 - end - - def pbPartyOrder(idxBattler) - return (opposes?(idxBattler)) ? @party2order : @party1order - end - - def pbPartyStarts(idxBattler) - return (opposes?(idxBattler)) ? @party2starts : @party1starts - end - - # Returns the player's team in its display order. Used when showing the party - # screen. - def pbPlayerDisplayParty(idxBattler=0) - partyOrders = pbPartyOrder(idxBattler) - idxStart, _idxEnd = pbTeamIndexRangeFromBattlerIndex(idxBattler) - ret = [] - eachInTeamFromBattlerIndex(idxBattler) { |pkmn,i| ret[partyOrders[i]-idxStart] = pkmn } - return ret - end - - def pbAbleCount(idxBattler=0) - party = pbParty(idxBattler) - count = 0 - party.each { |pkmn| count += 1 if pkmn && pkmn.able? } - return count - end - - def pbAbleNonActiveCount(idxBattler=0) - party = pbParty(idxBattler) - inBattleIndices = [] - eachSameSideBattler(idxBattler) { |b| inBattleIndices.push(b.pokemonIndex) } - count = 0 - party.each_with_index do |pkmn,idxParty| - next if !pkmn || !pkmn.able? - next if inBattleIndices.include?(idxParty) - count += 1 - end - return count - end - - def pbAllFainted?(idxBattler=0) - return pbAbleCount(idxBattler)==0 - end - - # For the given side of the field (0=player's, 1=opponent's), returns an array - # containing the number of able Pokémon in each team. - def pbAbleTeamCounts(side) - party = pbParty(side) - partyStarts = pbPartyStarts(side) - ret = [] - idxTeam = -1 - nextStart = 0 - party.each_with_index do |pkmn,i| - if i>=nextStart - idxTeam += 1 - nextStart = (idxTeam=idxPartyStart && i=idxPartyStart && i=idxPartyEnd # Check the team only - next if !pkmn || !pkmn.able? # Can't copy a non-fainted Pokémon or egg - ret = i if ret < 0 || partyOrders[i] > partyOrders[ret] - end - return ret - end - - # Used to calculate money gained/lost after winning/losing a battle. - def pbMaxLevelInTeam(side,idxTrainer) - ret = 1 - eachInTeam(side,idxTrainer) do |pkmn,_i| - ret = pkmn.level if pkmn.level>ret - end - return ret - end - - #============================================================================= - # Iterate through battlers - #============================================================================= - def eachBattler - @battlers.each { |b| yield b if b && !b.fainted? } - end - - def eachSameSideBattler(idxBattler=0) - idxBattler = idxBattler.index if idxBattler.respond_to?("index") - @battlers.each { |b| yield b if b && !b.fainted? && !b.opposes?(idxBattler) } - end - - def eachOtherSideBattler(idxBattler=0) - idxBattler = idxBattler.index if idxBattler.respond_to?("index") - @battlers.each { |b| yield b if b && !b.fainted? && b.opposes?(idxBattler) } - end - - def pbSideBattlerCount(idxBattler=0) - ret = 0 - eachSameSideBattler(idxBattler) { |_b| ret += 1 } - return ret - end - - def pbOpposingBattlerCount(idxBattler=0) - ret = 0 - eachOtherSideBattler(idxBattler) { |_b| ret += 1 } - return ret - end - - # This method only counts the player's Pokémon, not a partner trainer's. - def pbPlayerBattlerCount - ret = 0 - eachSameSideBattler { |b| ret += 1 if b.pbOwnedByPlayer? } - return ret - end - - def pbCheckGlobalAbility(abil) - eachBattler { |b| return b if b.hasActiveAbility?(abil) } - return nil - end - - def pbCheckOpposingAbility(abil,idxBattler=0,nearOnly=false) - eachOtherSideBattler(idxBattler) do |b| - next if nearOnly && !b.near?(idxBattler) - return b if b.hasActiveAbility?(abil) - end - return nil - end - - # Given a battler index, and using battle side sizes, returns an array of - # battler indices from the opposing side that are in order of most "opposite". - # Used when choosing a target and pressing up/down to move the cursor to the - # opposite side, and also when deciding which target to select first for some - # moves. - def pbGetOpposingIndicesInOrder(idxBattler) - case pbSideSize(0) - when 1 - case pbSideSize(1) - when 1 # 1v1 single - return [0] if opposes?(idxBattler) - return [1] - when 2 # 1v2 - return [0] if opposes?(idxBattler) - return [3,1] - when 3 # 1v3 - return [0] if opposes?(idxBattler) - return [3,5,1] - end - when 2 - case pbSideSize(1) - when 1 # 2v1 - return [0,2] if opposes?(idxBattler) - return [1] - when 2 # 2v2 double - return [[3,1],[2,0],[1,3],[0,2]][idxBattler] - when 3 # 2v3 - return [[5,3,1],[2,0],[3,1,5]][idxBattler] if idxBattler<3 - return [0,2] - end - when 3 - case pbSideSize(1) - when 1 # 3v1 - return [2,0,4] if opposes?(idxBattler) - return [1] - when 2 # 3v2 - return [[3,1],[2,4,0],[3,1],[2,0,4],[1,3]][idxBattler] - when 3 # 3v3 triple - return [[5,3,1],[4,2,0],[3,5,1],[2,0,4],[1,3,5],[0,2,4]][idxBattler] - end - end - return [idxBattler] - end - - #============================================================================= - # Comparing the positions of two battlers - #============================================================================= - def opposes?(idxBattler1,idxBattler2=0) - idxBattler1 = idxBattler1.index if idxBattler1.respond_to?("index") - idxBattler2 = idxBattler2.index if idxBattler2.respond_to?("index") - return (idxBattler1&1)!=(idxBattler2&1) - end - - def nearBattlers?(idxBattler1,idxBattler2) - return false if idxBattler1==idxBattler2 - return true if pbSideSize(0)<=2 && pbSideSize(1)<=2 - # Get all pairs of battler positions that are not close to each other - pairsArray = [[0,4],[1,5]] # Covers 3v1 and 1v3 - case pbSideSize(0) - when 3 - case pbSideSize(1) - when 3 # 3v3 (triple) - pairsArray.push([0,1]) - pairsArray.push([4,5]) - when 2 # 3v2 - pairsArray.push([0,1]) - pairsArray.push([3,4]) - end - when 2 # 2v3 - pairsArray.push([0,1]) - pairsArray.push([2,5]) - end - # See if any pair matches the two battlers being assessed - pairsArray.each do |pair| - return false if pair.include?(idxBattler1) && pair.include?(idxBattler2) - end - return true - end - - #============================================================================= - # Altering a party or rearranging battlers - #============================================================================= - def pbRemoveFromParty(idxBattler,idxParty) - party = pbParty(idxBattler) - # Erase the Pokémon from the party - party[idxParty] = nil - # Rearrange the display order of the team to place the erased Pokémon last - # in it (to avoid gaps) - partyOrders = pbPartyOrder(idxBattler) - partyStarts = pbPartyStarts(idxBattler) - idxTrainer = pbGetOwnerIndexFromPartyIndex(idxBattler,idxParty) - idxPartyStart = partyStarts[idxTrainer] - idxPartyEnd = (idxTrainer=idxPartyEnd # Only check the team - next if partyOrders[i]0 && user && user.itemActive? - duration = BattleHandlers.triggerWeatherExtenderItem(user.item, - @field.weather,duration,user,self) - end - @field.weatherDuration = duration - weather_data = GameData::BattleWeather.try_get(@field.weather) - pbCommonAnimation(weather_data.animation) if showAnim && weather_data - pbHideAbilitySplash(user) if user - case @field.weather - when :Sun then pbDisplay(_INTL("The sunlight turned harsh!")) - when :Rain then pbDisplay(_INTL("It started to rain!")) - when :Sandstorm then pbDisplay(_INTL("A sandstorm brewed!")) - when :Hail then pbDisplay(_INTL("It started to hail!")) - when :HarshSun then pbDisplay(_INTL("The sunlight turned extremely harsh!")) - when :HeavyRain then pbDisplay(_INTL("A heavy rain began to fall!")) - when :StrongWinds then pbDisplay(_INTL("Mysterious strong winds are protecting Flying-type Pokémon!")) - when :ShadowSky then pbDisplay(_INTL("A shadow sky appeared!")) - end - # Check for end of primordial weather, and weather-triggered form changes - eachBattler { |b| b.pbCheckFormOnWeatherChange } - pbEndPrimordialWeather - end - - def pbEndPrimordialWeather - oldWeather = @field.weather - # End Primordial Sea, Desolate Land, Delta Stream - case @field.weather - when :HarshSun - if !pbCheckGlobalAbility(:DESOLATELAND) - @field.weather = :None - pbDisplay("The harsh sunlight faded!") - end - when :HeavyRain - if !pbCheckGlobalAbility(:PRIMORDIALSEA) - @field.weather = :None - pbDisplay("The heavy rain has lifted!") - end - # when :StrongWinds - # if !pbCheckGlobalAbility(:DELTASTREAM) - # @field.weather = :None - # pbDisplay("The mysterious air current has dissipated!") - # end - end - if @field.weather!=oldWeather - # Check for form changes caused by the weather changing - eachBattler { |b| b.pbCheckFormOnWeatherChange } - # Start up the default weather - pbStartWeather(nil,@field.defaultWeather) if @field.defaultWeather != :None - end - end - - def defaultTerrain=(value) - @field.defaultTerrain = value - @field.terrain = value - @field.terrainDuration = -1 - end - - def pbStartTerrain(user,newTerrain,fixedDuration=true) - return if @field.terrain==newTerrain - @field.terrain = newTerrain - duration = (fixedDuration) ? 5 : -1 - if duration>0 && user && user.itemActive? - duration = BattleHandlers.triggerTerrainExtenderItem(user.item, - newTerrain,duration,user,self) - end - @field.terrainDuration = duration - terrain_data = GameData::BattleTerrain.try_get(@field.terrain) - pbCommonAnimation(terrain_data.animation) if terrain_data - pbHideAbilitySplash(user) if user - case @field.terrain - when :Electric - pbDisplay(_INTL("An electric current runs across the battlefield!")) - when :Grassy - pbDisplay(_INTL("Grass grew to cover the battlefield!")) - when :Misty - pbDisplay(_INTL("Mist swirled about the battlefield!")) - when :Psychic - pbDisplay(_INTL("The battlefield got weird!")) - end - # Check for terrain seeds that boost stats in a terrain - eachBattler { |b| b.pbItemTerrainStatBoostCheck } - end - - #============================================================================= - # Messages and animations - #============================================================================= - def pbDisplay(msg,&block) - @scene.pbDisplayMessage(msg,&block) - end - - def pbDisplayBrief(msg) - @scene.pbDisplayMessage(msg,true) - end - - def pbDisplayPaused(msg,&block) - @scene.pbDisplayPausedMessage(msg,&block) - end - - def pbDisplayConfirm(msg) - return @scene.pbDisplayConfirmMessage(msg) - end - - def pbShowCommands(msg,commands,canCancel=true) - @scene.pbShowCommands(msg,commands,canCancel) - end - - def pbAnimation(move,user,targets,hitNum=0) - @scene.pbAnimation(move,user,targets,hitNum) if @showAnims - end - - def pbCommonAnimation(name,user=nil,targets=nil) - @scene.pbCommonAnimation(name,user,targets) if @showAnims - end - - - - def pbShowAbilitySplash(battler,delay=false,logTrigger=true,abilityName=nil) - PBDebug.log("[Ability triggered] #{battler.pbThis}'s #{battler.abilityName}") if logTrigger - return if !PokeBattle_SceneConstants::USE_ABILITY_SPLASH - @scene.pbShowAbilitySplash(battler,false ,abilityName) - if delay - Graphics.frame_rate.times { @scene.pbUpdate } # 1 second - end - end - - def pbHideAbilitySplash(battler) - return if !PokeBattle_SceneConstants::USE_ABILITY_SPLASH - @scene.pbHideAbilitySplash(battler) - end - - def pbReplaceAbilitySplash(battler) - return if !PokeBattle_SceneConstants::USE_ABILITY_SPLASH - @scene.pbReplaceAbilitySplash(battler) - end -end diff --git a/Data/Scripts/011_Battle/003_Battle/003_Battle_StartAndEnd.rb b/Data/Scripts/011_Battle/003_Battle/003_Battle_StartAndEnd.rb deleted file mode 100644 index ed0b944e7..000000000 --- a/Data/Scripts/011_Battle/003_Battle/003_Battle_StartAndEnd.rb +++ /dev/null @@ -1,581 +0,0 @@ -class PokeBattle_Battle - class BattleAbortedException < Exception; end - - def pbAbort - raise BattleAbortedException.new("Battle aborted") - end - - #============================================================================= - # Makes sure all Pokémon exist that need to. Alter the type of battle if - # Makes sure all Pokémon exist that need to. Alter the type of battle if - # necessary. Will never try to create battler positions, only delete them - # (except for wild Pokémon whose number of positions are fixed). Reduces the - # size of each side by 1 and tries again. If the side sizes are uneven, only - # the larger side's size will be reduced by 1 each time, until both sides are - # an equal size (then both sides will be reduced equally). - #============================================================================= - def pbEnsureParticipants - # Prevent battles larger than 2v2 if both sides have multiple trainers - # NOTE: This is necessary to ensure that battlers can never become unable to - # hit each other due to being too far away. In such situations, - # battlers will move to the centre position at the end of a round, but - # because they cannot move into a position owned by a different - # trainer, it's possible that battlers will be unable to move close - # enough to hit each other if there are multiple trainers on each - # side. - if trainerBattle? && (@sideSizes[0]>2 || @sideSizes[1]>2) && - @player.length>1 && @opponent.length>1 - raise _INTL("Can't have battles larger than 2v2 where both sides have multiple trainers") - end - # Find out how many Pokémon each trainer has - side1counts = pbAbleTeamCounts(0) - side2counts = pbAbleTeamCounts(1) - # Change the size of the battle depending on how many wild Pokémon there are - if wildBattle? && side2counts[0]!=@sideSizes[1] - if @sideSizes[0]==@sideSizes[1] - # Even number of battlers per side, change both equally - @sideSizes = [side2counts[0],side2counts[0]] - else - # Uneven number of battlers per side, just change wild side's size - @sideSizes[1] = side2counts[0] - end - end - # Check if battle is possible, including changing the number of battlers per - # side if necessary - loop do - needsChanging = false - for side in 0...2 # Each side in turn - next if side==1 && wildBattle? # Wild side's size already checked above - sideCounts = (side==0) ? side1counts : side2counts - requireds = [] - # Find out how many Pokémon each trainer on side needs to have - for i in 0...@sideSizes[side] - idxTrainer = pbGetOwnerIndexFromBattlerIndex(i*2+side) - requireds[idxTrainer] = 0 if requireds[idxTrainer].nil? - requireds[idxTrainer] += 1 - end - # Compare the have values with the need values - if requireds.length>sideCounts.length - raise _INTL("Error: def pbGetOwnerIndexFromBattlerIndex gives invalid owner index ({1} for battle type {2}v{3}, trainers {4}v{5})", - requireds.length-1,@sideSizes[0],@sideSizes[1],side1counts.length,side2counts.length) - end - sideCounts.each_with_index do |_count,i| - if !requireds[i] || requireds[i]==0 - raise _INTL("Player-side trainer {1} has no battler position for their Pokémon to go (trying {2}v{3} battle)", - i+1,@sideSizes[0],@sideSizes[1]) if side==0 - raise _INTL("Opposing trainer {1} has no battler position for their Pokémon to go (trying {2}v{3} battle)", - i+1,@sideSizes[0],@sideSizes[1]) if side==1 - end - next if requireds[i]<=sideCounts[i] # Trainer has enough Pokémon to fill their positions - if requireds[i]==1 - raise _INTL("Player-side trainer {1} has no able Pokémon",i+1) if side==0 - raise _INTL("Opposing trainer {1} has no able Pokémon",i+1) if side==1 - end - # Not enough Pokémon, try lowering the number of battler positions - needsChanging = true - break - end - break if needsChanging - end - break if !needsChanging - # Reduce one or both side's sizes by 1 and try again - if wildBattle? - PBDebug.log("#{@sideSizes[0]}v#{@sideSizes[1]} battle isn't possible " + - "(#{side1counts} player-side teams versus #{side2counts[0]} wild Pokémon)") - newSize = @sideSizes[0]-1 - else - PBDebug.log("#{@sideSizes[0]}v#{@sideSizes[1]} battle isn't possible " + - "(#{side1counts} player-side teams versus #{side2counts} opposing teams)") - newSize = @sideSizes.max-1 - end - if newSize==0 - raise _INTL("Couldn't lower either side's size any further, battle isn't possible") - end - for side in 0...2 - next if side==1 && wildBattle? # Wild Pokémon's side size is fixed - next if @sideSizes[side]==1 || newSize>@sideSizes[side] - @sideSizes[side] = newSize - end - PBDebug.log("Trying #{@sideSizes[0]}v#{@sideSizes[1]} battle instead") - end - end - - #============================================================================= - # Set up all battlers - #============================================================================= - def pbCreateBattler(idxBattler,pkmn,idxParty) - if !@battlers[idxBattler].nil? - raise _INTL("Battler index {1} already exists",idxBattler) - end - @battlers[idxBattler] = PokeBattle_Battler.new(self,idxBattler) - @positions[idxBattler] = PokeBattle_ActivePosition.new - pbClearChoice(idxBattler) - @successStates[idxBattler] = PokeBattle_SuccessState.new - @battlers[idxBattler].pbInitialize(pkmn,idxParty) - end - - def pbSetUpSides - ret = [[],[]] - for side in 0...2 - # Set up wild Pokémon - if side==1 && wildBattle? - pbParty(1).each_with_index do |pkmn,idxPkmn| - pbCreateBattler(2*idxPkmn+side,pkmn,idxPkmn) - # Changes the Pokémon's form upon entering battle (if it should) - @peer.pbOnEnteringBattle(self,pkmn,true) - pbSetSeen(@battlers[2*idxPkmn+side]) - @usedInBattle[side][idxPkmn] = true - end - next - end - # Set up player's Pokémon and trainers' Pokémon - trainer = (side==0) ? @player : @opponent - requireds = [] - # Find out how many Pokémon each trainer on side needs to have - for i in 0...@sideSizes[side] - idxTrainer = pbGetOwnerIndexFromBattlerIndex(i*2+side) - requireds[idxTrainer] = 0 if requireds[idxTrainer].nil? - requireds[idxTrainer] += 1 - end - # For each trainer in turn, find the needed number of Pokémon for them to - # send out, and initialize them - battlerNumber = 0 - trainer.each_with_index do |_t,idxTrainer| - ret[side][idxTrainer] = [] - eachInTeam(side,idxTrainer) do |pkmn,idxPkmn| - next if !pkmn.able? - idxBattler = 2*battlerNumber+side - pbCreateBattler(idxBattler,pkmn,idxPkmn) - ret[side][idxTrainer].push(idxBattler) - battlerNumber += 1 - break if ret[side][idxTrainer].length>=requireds[idxTrainer] - end - end - end - return ret - end - - #============================================================================= - # Send out all battlers at the start of battle - #============================================================================= - def pbStartBattleSendOut(sendOuts) - # "Want to battle" messages - if wildBattle? - foeParty = pbParty(1) - case foeParty.length - when 1 - pbDisplayPaused(_INTL("Oh! A wild {1} appeared!",foeParty[0].name)) - when 2 - pbDisplayPaused(_INTL("Oh! A wild {1} and {2} appeared!",foeParty[0].name, - foeParty[1].name)) - when 3 - pbDisplayPaused(_INTL("Oh! A wild {1}, {2} and {3} appeared!",foeParty[0].name, - foeParty[1].name,foeParty[2].name)) - end - else # Trainer battle - case @opponent.length - when 1 - pbDisplayPaused(_INTL("You are challenged by {1}!",@opponent[0].full_name)) - when 2 - pbDisplayPaused(_INTL("You are challenged by {1} and {2}!",@opponent[0].full_name, - @opponent[1].full_name)) - when 3 - pbDisplayPaused(_INTL("You are challenged by {1}, {2} and {3}!", - @opponent[0].full_name,@opponent[1].full_name,@opponent[2].full_name)) - end - end - # Send out Pokémon (opposing trainers first) - for side in [1,0] - next if side==1 && wildBattle? - msg = "" - toSendOut = [] - trainers = (side==0) ? @player : @opponent - # Opposing trainers and partner trainers's messages about sending out Pokémon - trainers.each_with_index do |t,i| - next if side==0 && i==0 # The player's message is shown last - msg += "\r\n" if msg.length>0 - sent = sendOuts[side][i] - case sent.length - when 1 - msg += _INTL("{1} sent out {2}!",t.full_name,@battlers[sent[0]].name) - when 2 - msg += _INTL("{1} sent out {2} and {3}!",t.full_name, - @battlers[sent[0]].name,@battlers[sent[1]].name) - when 3 - if $game_switches[SWITCH_TRIPLE_BOSS_BATTLE] - if $game_switches[SWITCH_SILVERBOSS_BATTLE] - msg += _INTL("A wild Paldiatina appeared!",t.full_name) - else - msg += _INTL("{1} sent out Zapmolcuno!",t.full_name) - end - else - msg += _INTL("{1} sent out {2}, {3} and {4}!",t.full_name, - @battlers[sent[0]].name,@battlers[sent[1]].name,@battlers[sent[2]].name) - end - - end - toSendOut.concat(sent) - end - # The player's message about sending out Pokémon - if side==0 - msg += "\r\n" if msg.length>0 - sent = sendOuts[side][0] - case sent.length - when 1 - msg += _INTL("Go! {1}!",@battlers[sent[0]].name) - when 2 - msg += _INTL("Go! {1} and {2}!",@battlers[sent[0]].name,@battlers[sent[1]].name) - when 3 - msg += _INTL("Go! {1}, {2} and {3}!",@battlers[sent[0]].name, - @battlers[sent[1]].name,@battlers[sent[2]].name) - end - toSendOut.concat(sent) - end - pbDisplayBrief(msg) if msg.length>0 - # The actual sending out of Pokémon - animSendOuts = [] - toSendOut.each do |idxBattler| - animSendOuts.push([idxBattler,@battlers[idxBattler].pokemon]) - end - pbSendOut(animSendOuts,true) - end - end - - #============================================================================= - # Start a battle - #============================================================================= - def pbStartBattle - PBDebug.log("") - PBDebug.log("******************************************") - logMsg = "[Started battle] " - if @sideSizes[0]==1 && @sideSizes[1]==1 - logMsg += "Single " - elsif @sideSizes[0]==2 && @sideSizes[1]==2 - logMsg += "Double " - elsif @sideSizes[0]==3 && @sideSizes[1]==3 - logMsg += "Triple " - else - logMsg += "#{@sideSizes[0]}v#{@sideSizes[1]} " - end - logMsg += "wild " if wildBattle? - logMsg += "trainer " if trainerBattle? - logMsg += "battle (#{@player.length} trainer(s) vs. " - logMsg += "#{pbParty(1).length} wild Pokémon)" if wildBattle? - logMsg += "#{@opponent.length} trainer(s))" if trainerBattle? - PBDebug.log(logMsg) - pbEnsureParticipants - begin - pbStartBattleCore - rescue BattleAbortedException - @decision = 0 - @scene.pbEndBattle(@decision) - end - return @decision - end - - def pbStartBattleCore - # Set up the battlers on each side - sendOuts = pbSetUpSides - # Create all the sprites and play the battle intro animation - @scene.pbStartBattle(self) - # Show trainers on both sides sending out Pokémon - pbStartBattleSendOut(sendOuts) - # Weather announcement - weather_data = GameData::BattleWeather.try_get(@field.weather) - echoln "Current weather: #{@field.weather}" - - pbCommonAnimation(weather_data.animation) if weather_data - case @field.weather - when :Sun then pbDisplay(_INTL("The sunlight is strong.")) - when :Rain then pbDisplay(_INTL("It is raining.")) - when :Sandstorm then pbDisplay(_INTL("A sandstorm is raging.")) - when :Hail then pbDisplay(_INTL("Hail is falling.")) - when :HarshSun then pbDisplay(_INTL("The sunlight is extremely harsh.")) - when :HeavyRain then pbDisplay(_INTL("It is raining heavily.")) - when :StrongWinds then pbDisplay(_INTL("The wind is strong.")) - when :ShadowSky then pbDisplay(_INTL("The sky is shadowy.")) - end - # Terrain announcement - terrain_data = GameData::BattleTerrain.try_get(@field.terrain) - pbCommonAnimation(terrain_data.animation) if terrain_data - case @field.terrain - when :Electric - pbDisplay(_INTL("An electric current runs across the battlefield!")) - when :Grassy - pbDisplay(_INTL("Grass is covering the battlefield!")) - when :Misty - pbDisplay(_INTL("Mist swirls about the battlefield!")) - when :Psychic - pbDisplay(_INTL("The battlefield is weird!")) - end - # Abilities upon entering battle - pbOnActiveAll - # Main battle loop - pbBattleLoop - end - - #============================================================================= - # Main battle loop - #============================================================================= - def pbBattleLoop - @turnCount = 0 - loop do # Now begin the battle loop - PBDebug.log("") - PBDebug.log("***Round #{@turnCount+1}***") - if @debug && @turnCount>=100 - @decision = pbDecisionOnTime - PBDebug.log("") - PBDebug.log("***Undecided after 100 rounds, aborting***") - pbAbort - break - end - PBDebug.log("") - # Command phase - PBDebug.logonerr { pbCommandPhase } - break if @decision>0 - # Attack phase - PBDebug.logonerr { pbAttackPhase } - break if @decision>0 - # End of round phase - PBDebug.logonerr { pbEndOfRoundPhase } - break if @decision>0 - @turnCount += 1 - end - pbEndOfBattle - end - - #============================================================================= - # End of battle - #============================================================================= - def pbGainMoney - return if $game_switches[SWITCH_IS_REMATCH] #is rematch - return if !@internalBattle || !@moneyGain - # Money rewarded from opposing trainers - if trainerBattle? - tMoney = 0 - @opponent.each_with_index do |t,i| - tMoney += pbMaxLevelInTeam(1, i) * t.base_money - end - tMoney *= 2 if @field.effects[PBEffects::AmuletCoin] - tMoney *= 2 if @field.effects[PBEffects::HappyHour] - oldMoney = pbPlayer.money - pbPlayer.money += tMoney - moneyGained = pbPlayer.money-oldMoney - if moneyGained>0 - pbDisplayPaused(_INTL("You got ${1} for winning!",moneyGained.to_s_formatted)) - end - end - # Pick up money scattered by Pay Day - if @field.effects[PBEffects::PayDay]>0 - @field.effects[PBEffects::PayDay] *= 2 if @field.effects[PBEffects::AmuletCoin] - @field.effects[PBEffects::PayDay] *= 2 if @field.effects[PBEffects::HappyHour] - oldMoney = pbPlayer.money - pbPlayer.money += @field.effects[PBEffects::PayDay] - moneyGained = pbPlayer.money-oldMoney - if moneyGained>0 - pbDisplayPaused(_INTL("You picked up ${1}!",moneyGained.to_s_formatted)) - end - end - end - - def pbLoseMoney - return if !@internalBattle || !@moneyGain - return if $game_switches[Settings::NO_MONEY_LOSS] - maxLevel = pbMaxLevelInTeam(0,0) # Player's Pokémon only, not partner's - multiplier = [8,16,24,36,48,64,80,100,120] - idxMultiplier = [pbPlayer.badge_count, multiplier.length - 1].min - tMoney = maxLevel*multiplier[idxMultiplier] - tMoney = pbPlayer.money if tMoney>pbPlayer.money - oldMoney = pbPlayer.money - pbPlayer.money -= tMoney - moneyLost = oldMoney-pbPlayer.money - if moneyLost>0 - if trainerBattle? - pbDisplayPaused(_INTL("You gave ${1} to the winner...",moneyLost.to_s_formatted)) - else - pbDisplayPaused(_INTL("You panicked and dropped ${1}...",moneyLost.to_s_formatted)) - end - end - end - - def pbEndOfBattle - oldDecision = @decision - @decision = 4 if @decision==1 && wildBattle? && @caughtPokemon.length>0 - case oldDecision - ##### WIN ##### - when 1 - PBDebug.log("") - PBDebug.log("***Player won***") - if trainerBattle? - @scene.pbTrainerBattleSuccess - case @opponent.length - when 1 - pbDisplayPaused(_INTL("You defeated {1}!",@opponent[0].full_name)) - when 2 - pbDisplayPaused(_INTL("You defeated {1} and {2}!",@opponent[0].full_name, - @opponent[1].full_name)) - when 3 - pbDisplayPaused(_INTL("You defeated {1}, {2} and {3}!",@opponent[0].full_name, - @opponent[1].full_name,@opponent[2].full_name)) - end - @opponent.each_with_index do |_t,i| - @scene.pbShowOpponent(i) - msg = (@endSpeeches[i] && @endSpeeches[i]!="") ? @endSpeeches[i] : "..." - pbDisplayPaused(msg.gsub(/\\[Pp][Nn]/,pbPlayer.name)) - end - end - # Gain money from winning a trainer battle, and from Pay Day - pbGainMoney if @decision!=4 - # Hide remaining trainer - @scene.pbShowOpponent(@opponent.length) if trainerBattle? && @caughtPokemon.length>0 - if $game_switches[AUTOSAVE_WIN_SWITCH] - Kernel.tryAutosave() - end - - ##### LOSE, DRAW ##### - when 2, 5 - PBDebug.log("") - PBDebug.log("***Player lost***") if @decision==2 - PBDebug.log("***Player drew with opponent***") if @decision==5 - if @internalBattle - pbDisplayPaused(_INTL("You have no more Pokémon that can fight!")) - if trainerBattle? - case @opponent.length - when 1 - pbDisplayPaused(_INTL("You lost against {1}!",@opponent[0].full_name)) - when 2 - pbDisplayPaused(_INTL("You lost against {1} and {2}!", - @opponent[0].full_name,@opponent[1].full_name)) - when 3 - pbDisplayPaused(_INTL("You lost against {1}, {2} and {3}!", - @opponent[0].full_name,@opponent[1].full_name,@opponent[2].full_name)) - end - end - # Lose money from losing a battle - pbLoseMoney - pbDisplayPaused(_INTL("You blacked out!")) if !@canLose - elsif @decision==2 - if @opponent - @opponent.each_with_index do |_t,i| - @scene.pbShowOpponent(i) - msg = (@endSpeechesWin[i] && @endSpeechesWin[i]!="") ? @endSpeechesWin[i] : "..." - pbDisplayPaused(msg.gsub(/\\[Pp][Nn]/,pbPlayer.name)) - end - end - end - ##### CAUGHT WILD POKÉMON ##### - when 4 - @scene.pbWildBattleSuccess if !Settings::GAIN_EXP_FOR_CAPTURE - end - # Register captured Pokémon in the Pokédex, and store them - #pbRecordAndStoreCaughtPokemon - - isRematch = $game_switches[SWITCH_IS_REMATCH] - begin - if isRematch - if @opponent.is_a?(Array) - for trainer in @opponent - rematchId = getRematchId(trainer.name,trainer.trainer_type) - incrNbRematches(rematchId) - end - else - rematchId = getRematchId(@opponent.name,@opponent.trainer_type) - incrNbRematches(rematchId) - end - end - rescue - $game_switches[SWITCH_IS_REMATCH]=false - end - - - # Collect Pay Day money in a wild battle that ended in a capture - pbGainMoney if @decision==4 - # Pass on Pokérus within the party - if @internalBattle - infected = [] - $Trainer.party.each_with_index do |pkmn,i| - infected.push(i) if pkmn.pokerusStage==1 - end - infected.each do |idxParty| - strain = $Trainer.party[idxParty].pokerusStrain - if idxParty>0 && $Trainer.party[idxParty-1].pokerusStage==0 - $Trainer.party[idxParty-1].givePokerus(strain) if rand(3)==0 # 33% - end - if idxParty<$Trainer.party.length-1 && $Trainer.party[idxParty+1].pokerusStage==0 - $Trainer.party[idxParty+1].givePokerus(strain) if rand(3)==0 # 33% - end - end - end - - pbParty(0).each_with_index do |pkmn,i| - next if !pkmn - @peer.pbOnLeavingBattle(self,pkmn,@usedInBattle[0][i],true) # Reset form - pkmn.item = @initialItems[0][i] - pkmn.spriteform_head=nil - pkmn.spriteform_body=nil - end - pbRecordAndStoreCaughtPokemon - - # Clean up battle stuff - @scene.pbEndBattle(@decision) - @battlers.each do |b| - next if !b - pbCancelChoice(b.index) # Restore unused items to Bag - BattleHandlers.triggerAbilityOnSwitchOut(b.ability,b,true) if b.abilityActive? - end - - return @decision - end - - #============================================================================= - # Judging - #============================================================================= - def pbJudgeCheckpoint(user,move=nil); end - - def pbDecisionOnTime - counts = [0,0] - hpTotals = [0,0] - for side in 0...2 - pbParty(side).each do |pkmn| - next if !pkmn || !pkmn.able? - counts[side] += 1 - hpTotals[side] += pkmn.hp - end - end - return 1 if counts[0]>counts[1] # Win (player has more able Pokémon) - return 2 if counts[0]hpTotals[1] # Win (player has more HP in total) - return 2 if hpTotals[0]1 - end - return 1 if counts[0]>counts[1] # Win (player has more able Pokémon) - return 2 if counts[0]hpTotals[1] # Win (player has a bigger average HP %) - return 2 if hpTotals[0] 0 || expShare.length > 0 || expAll - # Gain EVs and Exp for participants - eachInTeam(0, 0) do |pkmn, i| - next if !pkmn.able? - next unless b.participants.include?(i) || expShare.include?(i) - pbGainEVsOne(i, b) - pbGainExpOne(i, b, numPartic, expShare, expAll) - end - # Gain EVs and Exp for all other Pokémon because of Exp All - if expAll - showMessage = true - eachInTeam(0, 0) do |pkmn, i| - next if !pkmn.able? - next if b.participants.include?(i) || expShare.include?(i) - pbDisplayPaused(_INTL("Your party Pokémon in waiting also got Exp. Points!")) if showMessage - showMessage = false - pbGainEVsOne(i, b) - pbGainExpOne(i, b, numPartic, expShare, expAll, false) - end - end - end - # Clear the participants array - b.participants = [] - end - end - - def pbGainEVsOne(idxParty, defeatedBattler) - pkmn = pbParty(0)[idxParty] # The Pokémon gaining EVs from defeatedBattler - evYield = defeatedBattler.pokemon.evYield - # Num of effort points pkmn already has - evTotal = 0 - GameData::Stat.each_main { |s| evTotal += pkmn.ev[s.id] } - # Modify EV yield based on pkmn's held item - if !BattleHandlers.triggerEVGainModifierItem(pkmn.item, pkmn, evYield) - BattleHandlers.triggerEVGainModifierItem(@initialItems[0][idxParty], pkmn, evYield) - end - # Double EV gain because of Pokérus - if pkmn.pokerusStage >= 1 # Infected or cured - evYield.each_key { |stat| evYield[stat] *= 2 } - end - # Gain EVs for each stat in turn - if pkmn.shadowPokemon? && pkmn.saved_ev - pkmn.saved_ev.each_value { |e| evTotal += e } - GameData::Stat.each_main do |s| - evGain = evYield[s.id].clamp(0, Pokemon::EV_STAT_LIMIT - pkmn.ev[s.id] - pkmn.saved_ev[s.id]) - evGain = evGain.clamp(0, Pokemon::EV_LIMIT - evTotal) - pkmn.saved_ev[s.id] += evGain - evTotal += evGain - end - else - GameData::Stat.each_main do |s| - evGain = evYield[s.id].clamp(0, Pokemon::EV_STAT_LIMIT - pkmn.ev[s.id]) - evGain = evGain.clamp(0, Pokemon::EV_LIMIT - evTotal) - pkmn.ev[s.id] += evGain - evTotal += evGain - end - end - end - - - def pbGainExpOne(idxParty, defeatedBattler, numPartic, expShare, expAll, showMessages = true) - pkmn = pbParty(0)[idxParty] # The Pokémon gaining EVs from defeatedBattler - growth_rate = pkmn.growth_rate - # Don't bother calculating if gainer is already at max Exp - if pkmn.exp >= growth_rate.maximum_exp - pkmn.calc_stats # To ensure new EVs still have an effect - return - end - isPartic = defeatedBattler.participants.include?(idxParty) - hasExpShare = expShare.include?(idxParty) - level = defeatedBattler.level - # Main Exp calculation - exp = 0 - a = level * defeatedBattler.pokemon.base_exp - if expShare.length > 0 && (isPartic || hasExpShare) - if numPartic == 0 # No participants, all Exp goes to Exp Share holders - exp = a / (Settings::SPLIT_EXP_BETWEEN_GAINERS ? expShare.length : 1) - elsif Settings::SPLIT_EXP_BETWEEN_GAINERS # Gain from participating and/or Exp Share - exp = a / (2 * numPartic) if isPartic - exp += a / (2 * expShare.length) if hasExpShare - else - # Gain from participating and/or Exp Share (Exp not split) - exp = (isPartic) ? a : a / 2 - end - elsif isPartic # Participated in battle, no Exp Shares held by anyone - exp = a / (Settings::SPLIT_EXP_BETWEEN_GAINERS ? numPartic : 1) - elsif expAll # Didn't participate in battle, gaining Exp due to Exp All - # NOTE: Exp All works like the Exp Share from Gen 6+, not like the Exp All - # from Gen 1, i.e. Exp isn't split between all Pokémon gaining it. - exp = a / 2 - end - return if exp <= 0 - # Pokémon gain more Exp from trainer battles - exp = (exp * 1.5).floor if trainerBattle? - # Scale the gained Exp based on the gainer's level (or not) - if Settings::SCALED_EXP_FORMULA - exp /= 5 - levelAdjust = (2 * level + 10.0) / (pkmn.level + level + 10.0) - levelAdjust = levelAdjust ** 5 - levelAdjust = Math.sqrt(levelAdjust) - exp *= levelAdjust - exp = exp.floor - exp += 1 if isPartic || hasExpShare - else - exp /= 7 - end - # Foreign Pokémon gain more Exp - isOutsider = (pkmn.owner.id != pbPlayer.id || - (pkmn.owner.language != 0 && pkmn.owner.language != pbPlayer.language)) || - pkmn.isSelfFusion? #also self fusions - if isOutsider - if pkmn.owner.language != 0 && pkmn.owner.language != pbPlayer.language - exp = (exp * 1.7).floor - else - exp = (exp * 1.5).floor - end - end - # Modify Exp gain based on pkmn's held item - i = BattleHandlers.triggerExpGainModifierItem(pkmn.item, pkmn, exp) - if i < 0 - i = BattleHandlers.triggerExpGainModifierItem(@initialItems[0][idxParty], pkmn, exp) - end - exp = i if i >= 0 - # Make sure Exp doesn't exceed the maximum - - exp = 0 if $PokemonSystem.level_caps==1 && pokemonExceedsLevelCap(pkmn) - - expFinal = growth_rate.add_exp(pkmn.exp, exp) - expGained = expFinal - pkmn.exp - - - - - return if expGained <= 0 - # "Exp gained" message - if showMessages - if isOutsider - pbDisplayPaused(_INTL("{1} got a boosted {2} Exp. Points!", pkmn.name, expGained)) - else - pbDisplayPaused(_INTL("{1} got {2} Exp. Points!", pkmn.name, expGained)) - end - end - curLevel = pkmn.level - newLevel = growth_rate.level_from_exp(expFinal) - dontAnimate=false - if newLevel < curLevel - dontAnimate = true - # debugInfo = "Levels: #{curLevel}->#{newLevel} | Exp: #{pkmn.exp}->#{expFinal} | gain: #{expGained}" - # raise RuntimeError.new( - # echoln _INTL("{1}'s new level is less than its\r\ncurrent level, which shouldn't happen.\r\n[Debug: {2}]", - # pkmn.name, debugInfo) - pbDisplayPaused(_INTL("{1}'s growth rate has changed to '{2}''. Its level will be adjusted to reflect its current exp.", pkmn.name, pkmn.growth_rate.real_name)) - end - # Give Exp - if pkmn.shadowPokemon? - pkmn.exp += expGained - return - end - tempExp1 = pkmn.exp - battler = pbFindBattler(idxParty) - loop do - # For each level gained in turn... - # EXP Bar animation - levelMinExp = growth_rate.minimum_exp_for_level(curLevel) - levelMaxExp = growth_rate.minimum_exp_for_level(curLevel + 1) - tempExp2 = (levelMaxExp < expFinal) ? levelMaxExp : expFinal - pkmn.exp = tempExp2 - - - - if pkmn.isFusion? - if pkmn.exp_gained_since_fused == nil - pkmn.exp_gained_since_fused = expGained - else - pkmn.exp_gained_since_fused += expGained - end - - end - @scene.pbEXPBar(battler, levelMinExp, levelMaxExp, tempExp1, tempExp2) if !dontAnimate - - - tempExp1 = tempExp2 - curLevel += 1 - if curLevel > newLevel - # Gained all the Exp now, end the animation - pkmn.calc_stats - battler.pbUpdate(false) if battler - @scene.pbRefreshOne(battler.index) if battler - break - end - # Levelled up - pbCommonAnimation("LevelUp", battler) if battler - oldTotalHP = pkmn.totalhp - oldAttack = pkmn.attack - oldDefense = pkmn.defense - oldSpAtk = pkmn.spatk - oldSpDef = pkmn.spdef - oldSpeed = pkmn.speed - if battler && battler.pokemon - battler.pokemon.changeHappiness("levelup") - end - pkmn.calc_stats - battler.pbUpdate(false) if battler - @scene.pbRefreshOne(battler.index) if battler - pbDisplayPaused(_INTL("{1} grew to Lv. {2}!", pkmn.name, curLevel)) - if !$game_switches[SWITCH_NO_LEVELS_MODE] - @scene.pbLevelUp(pkmn, battler, oldTotalHP, oldAttack, oldDefense, - oldSpAtk, oldSpDef, oldSpeed) - end - - echoln "256" - - # Learn all moves learned at this level - moveList = pkmn.getMoveList - moveList.each { |m| pbLearnMove(idxParty, m[1]) if m[0] == curLevel } - end - end - - #============================================================================= - # Learning a move - #============================================================================= - def pbLearnMove(idxParty, newMove) - pkmn = pbParty(0)[idxParty] - return if !pkmn - pkmnName = pkmn.name - battler = pbFindBattler(idxParty) - moveName = GameData::Move.get(newMove).name - # Pokémon already knows the move - return if pkmn.moves.any? { |m| m && m.id == newMove } - # Pokémon has space for the new move; just learn it - if pkmn.moves.length < Pokemon::MAX_MOVES - move = Pokemon::Move.new(newMove) - pkmn.moves.push(move) - pkmn.add_learned_move(move) - pbDisplay(_INTL("{1} learned {2}!", pkmnName, moveName)) { pbSEPlay("Pkmn move learnt") } - if battler - battler.moves.push(PokeBattle_Move.from_pokemon_move(self, pkmn.moves.last)) - battler.pbCheckFormOnMovesetChange - end - return - end - # Pokémon already knows the maximum number of moves; try to forget one to learn the new move - loop do - pbDisplayPaused(_INTL("{1} wants to learn {2}, but it already knows {3} moves.", - pkmnName, moveName, pkmn.moves.length.to_word)) - if pbDisplayConfirm(_INTL("Forget a move to learn {1}?", moveName)) - pbDisplayPaused(_INTL("Which move should be forgotten?")) - forgetMove = @scene.pbForgetMove(pkmn, newMove) - if forgetMove >= 0 - oldMoveName = pkmn.moves[forgetMove].name - pkmn.moves[forgetMove] = Pokemon::Move.new(newMove) # Replaces current/total PP - pkmn.add_learned_move(newMove) - battler.moves[forgetMove] = PokeBattle_Move.from_pokemon_move(self, pkmn.moves[forgetMove]) if battler - - pbDisplayPaused(_INTL("1, 2, and... ... ... Ta-da!")) - pbDisplayPaused(_INTL("{1} forgot how to use {2}. And...", pkmnName, oldMoveName)) - pbDisplay(_INTL("{1} learned {2}!", pkmnName, moveName)) { pbSEPlay("Pkmn move learnt") } - battler.pbCheckFormOnMovesetChange if battler - break - elsif pbDisplayConfirm(_INTL("Give up on learning {1}?", moveName)) - pbDisplay(_INTL("{1} did not learn {2}.", pkmnName, moveName)) - break - end - elsif pbDisplayConfirm(_INTL("Give up on learning {1}?", moveName)) - pbDisplay(_INTL("{1} did not learn {2}.", pkmnName, moveName)) - break - end - end - end -end diff --git a/Data/Scripts/011_Battle/003_Battle/005_Battle_Action_AttacksPriority.rb b/Data/Scripts/011_Battle/003_Battle/005_Battle_Action_AttacksPriority.rb deleted file mode 100644 index 9487bf0af..000000000 --- a/Data/Scripts/011_Battle/003_Battle/005_Battle_Action_AttacksPriority.rb +++ /dev/null @@ -1,248 +0,0 @@ -class PokeBattle_Battle - #============================================================================= - # Choosing a move/target - #============================================================================= - def pbCanChooseMove?(idxBattler,idxMove,showMessages,sleepTalk=false) - battler = @battlers[idxBattler] - move = battler.moves[idxMove] - return false unless move - if move.pp==0 && move.total_pp>0 && !sleepTalk - pbDisplayPaused(_INTL("There's no PP left for this move!")) if showMessages - return false - end - if battler.effects[PBEffects::Encore]>0 - idxEncoredMove = battler.pbEncoredMoveIndex - return false if idxEncoredMove>=0 && idxMove!=idxEncoredMove - end - return battler.pbCanChooseMove?(move,true,showMessages,sleepTalk) - end - - def pbCanChooseAnyMove?(idxBattler,sleepTalk=false) - battler = @battlers[idxBattler] - battler.eachMoveWithIndex do |m,i| - next if m.pp==0 && m.total_pp>0 && !sleepTalk - if battler.effects[PBEffects::Encore]>0 - idxEncoredMove = battler.pbEncoredMoveIndex - next if idxEncoredMove>=0 && i!=idxEncoredMove - end - next if !battler.pbCanChooseMove?(m,true,false,sleepTalk) - return true - end - return false - end - - # Called when the Pokémon is Encored, or if it can't use any of its moves. - # Makes the Pokémon use the Encored move (if Encored), or Struggle. - def pbAutoChooseMove(idxBattler,showMessages=true) - battler = @battlers[idxBattler] - if battler.fainted? - pbClearChoice(idxBattler) - return true - end - # Encore - idxEncoredMove = battler.pbEncoredMoveIndex - if idxEncoredMove>=0 && pbCanChooseMove?(idxBattler,idxEncoredMove,false) - encoreMove = battler.moves[idxEncoredMove] - @choices[idxBattler][0] = :UseMove # "Use move" - @choices[idxBattler][1] = idxEncoredMove # Index of move to be used - @choices[idxBattler][2] = encoreMove # PokeBattle_Move object - @choices[idxBattler][3] = -1 # No target chosen yet - return true if singleBattle? - if pbOwnedByPlayer?(idxBattler) - if showMessages - pbDisplayPaused(_INTL("{1} has to use {2}!",battler.name,encoreMove.name)) - end - return pbChooseTarget(battler,encoreMove) - end - return true - end - # Struggle - if pbOwnedByPlayer?(idxBattler) && showMessages - pbDisplayPaused(_INTL("{1} has no moves left!",battler.name)) - end - @choices[idxBattler][0] = :UseMove # "Use move" - @choices[idxBattler][1] = -1 # Index of move to be used - @choices[idxBattler][2] = @struggle # Struggle PokeBattle_Move object - @choices[idxBattler][3] = -1 # No target chosen yet - return true - end - - def pbRegisterMove(idxBattler,idxMove,showMessages=true) - battler = @battlers[idxBattler] - move = battler.moves[idxMove] - return false if !pbCanChooseMove?(idxBattler,idxMove,showMessages) - @choices[idxBattler][0] = :UseMove # "Use move" - @choices[idxBattler][1] = idxMove # Index of move to be used - @choices[idxBattler][2] = move # PokeBattle_Move object - @choices[idxBattler][3] = -1 # No target chosen yet - return true - end - - def pbChoseMove?(idxBattler,moveID) - return false if !@battlers[idxBattler] || @battlers[idxBattler].fainted? - if @choices[idxBattler][0]==:UseMove && @choices[idxBattler][1] - return @choices[idxBattler][2].id == moveID - end - return false - end - - def pbChoseMoveFunctionCode?(idxBattler,code) - return false if @battlers[idxBattler].fainted? - if @choices[idxBattler][0]==:UseMove && @choices[idxBattler][1] - return @choices[idxBattler][2].function == code - end - return false - end - - def pbRegisterTarget(idxBattler,idxTarget) - @choices[idxBattler][3] = idxTarget # Set target of move - end - - # Returns whether the idxTarget will be targeted by a move with target_data - # used by a battler in idxUser. - def pbMoveCanTarget?(idxUser,idxTarget,target_data) - return false if target_data.num_targets == 0 - case target_data.id - when :NearAlly - return false if opposes?(idxUser,idxTarget) - return false if !nearBattlers?(idxUser,idxTarget) - when :UserOrNearAlly - return true if idxUser==idxTarget - return false if opposes?(idxUser,idxTarget) - return false if !nearBattlers?(idxUser,idxTarget) - when :UserAndAllies - return false if opposes?(idxUser,idxTarget) - when :NearFoe, :RandomNearFoe, :AllNearFoes - return false if !opposes?(idxUser,idxTarget) - return false if !nearBattlers?(idxUser,idxTarget) - when :Foe - return false if !opposes?(idxUser,idxTarget) - when :AllFoes - return false if !opposes?(idxUser,idxTarget) - when :NearOther, :AllNearOthers - return false if !nearBattlers?(idxUser,idxTarget) - when :Other - return false if idxUser==idxTarget - end - return true - end - - #============================================================================= - # Turn order calculation (priority) - #============================================================================= - def pbCalculatePriority(fullCalc=false,indexArray=nil) - needRearranging = false - if fullCalc - @priorityTrickRoom = (@field.effects[PBEffects::TrickRoom]>0) - # Recalculate everything from scratch - randomOrder = Array.new(maxBattlerIndex+1) { |i| i } - (randomOrder.length-1).times do |i| # Can't use shuffle! here - r = i+pbRandom(randomOrder.length-i) - randomOrder[i], randomOrder[r] = randomOrder[r], randomOrder[i] - end - @priority.clear - for i in 0..maxBattlerIndex - b = @battlers[i] - next if !b - # [battler, speed, sub-priority, priority, tie-breaker order] - bArray = [b,b.pbSpeed,0,0,randomOrder[i]] - if @choices[b.index][0]==:UseMove || @choices[b.index][0]==:Shift - # Calculate move's priority - if @choices[b.index][0]==:UseMove - move = @choices[b.index][2] - pri = move.priority - if b.abilityActive? - pri = BattleHandlers.triggerPriorityChangeAbility(b.ability,b,move,pri) - end - bArray[3] = pri - @choices[b.index][4] = pri - end - # Calculate sub-priority (first/last within priority bracket) - # NOTE: Going fast beats going slow. A Pokémon with Stall and Quick - # Claw will go first in its priority bracket if Quick Claw - # triggers, regardless of Stall. - subPri = 0 - # Abilities (Stall) - if b.abilityActive? - newSubPri = BattleHandlers.triggerPriorityBracketChangeAbility(b.ability, - b,subPri,self) - if subPri!=newSubPri - subPri = newSubPri - b.effects[PBEffects::PriorityAbility] = true - b.effects[PBEffects::PriorityItem] = false - end - end - # Items (Quick Claw, Custap Berry, Lagging Tail, Full Incense) - if b.itemActive? - newSubPri = BattleHandlers.triggerPriorityBracketChangeItem(b.item, - b,subPri,self) - if subPri!=newSubPri - subPri = newSubPri - b.effects[PBEffects::PriorityAbility] = false - b.effects[PBEffects::PriorityItem] = true - end - end - bArray[2] = subPri - end - @priority.push(bArray) - end - needRearranging = true - else - if (@field.effects[PBEffects::TrickRoom]>0)!=@priorityTrickRoom - needRearranging = true - @priorityTrickRoom = (@field.effects[PBEffects::TrickRoom]>0) - end - # Just recheck all battler speeds - @priority.each do |orderArray| - next if !orderArray - next if indexArray && !indexArray.include?(orderArray[0].index) - oldSpeed = orderArray[1] - orderArray[1] = orderArray[0].pbSpeed - needRearranging = true if orderArray[1]!=oldSpeed - end - end - # Reorder the priority array - if needRearranging - @priority.sort! { |a,b| - if a[3]!=b[3] - # Sort by priority (highest value first) - b[3]<=>a[3] - elsif a[2]!=b[2] - # Sort by sub-priority (highest value first) - b[2]<=>a[2] - elsif @priorityTrickRoom - # Sort by speed (lowest first), and use tie-breaker if necessary - (a[1]==b[1]) ? b[4]<=>a[4] : a[1]<=>b[1] - else - # Sort by speed (highest first), and use tie-breaker if necessary - (a[1]==b[1]) ? b[4]<=>a[4] : b[1]<=>a[1] - end - } - # Write the priority order to the debug log - logMsg = (fullCalc) ? "[Round order] " : "[Round order recalculated] " - comma = false - @priority.each do |orderArray| - logMsg += ", " if comma - logMsg += "#{orderArray[0].pbThis(comma)} (#{orderArray[0].index})" - comma = true - end - PBDebug.log(logMsg) - end - end - - def pbPriority(onlySpeedSort=false) - ret = [] - if onlySpeedSort - # Sort battlers by their speed stats and tie-breaker order only. - tempArray = [] - @priority.each { |pArray| tempArray.push([pArray[0],pArray[1],pArray[4]]) } - tempArray.sort! { |a,b| (a[1]==b[1]) ? b[2]<=>a[2] : b[1]<=>a[1] } - tempArray.each { |tArray| ret.push(tArray[0]) } - else - # Sort battlers by priority, sub-priority and their speed. Ties are - # resolved in the same way each time this method is called in a round. - @priority.each { |pArray| ret.push(pArray[0]) if !pArray[0].fainted? } - end - return ret - end -end diff --git a/Data/Scripts/011_Battle/003_Battle/006_Battle_Action_Switching.rb b/Data/Scripts/011_Battle/003_Battle/006_Battle_Action_Switching.rb deleted file mode 100644 index 19359a448..000000000 --- a/Data/Scripts/011_Battle/003_Battle/006_Battle_Action_Switching.rb +++ /dev/null @@ -1,415 +0,0 @@ -class PokeBattle_Battle - #============================================================================= - # Choosing Pokémon to switch - #============================================================================= - # Checks whether the replacement Pokémon (at party index idxParty) can enter - # battle. - # NOTE: Messages are only shown while in the party screen when choosing a - # command for the next round. - def pbCanSwitchLax?(idxBattler, idxParty, partyScene = nil) - return true if idxParty < 0 - party = pbParty(idxBattler) - return false if idxParty >= party.length - return false if !party[idxParty] - if party[idxParty].egg? - partyScene.pbDisplay(_INTL("An Egg can't battle!")) if partyScene - return false - end - if !pbIsOwner?(idxBattler, idxParty) - owner = pbGetOwnerFromPartyIndex(idxBattler, idxParty) - partyScene.pbDisplay(_INTL("You can't switch {1}'s Pokémon with one of yours!", - owner.name)) if partyScene - return false - end - if party[idxParty].fainted? - partyScene.pbDisplay(_INTL("{1} has no energy left to battle!", - party[idxParty].name)) if partyScene - return false - end - if pbFindBattler(idxParty, idxBattler) - partyScene.pbDisplay(_INTL("{1} is already in battle!", - party[idxParty].name)) if partyScene - return false - end - return true - end - - # Check whether the currently active Pokémon (at battler index idxBattler) can - # switch out (and that its replacement at party index idxParty can switch in). - # NOTE: Messages are only shown while in the party screen when choosing a - # command for the next round. - def pbCanSwitch?(idxBattler, idxParty = -1, partyScene = nil) - # Check whether party Pokémon can switch in - return false if !pbCanSwitchLax?(idxBattler, idxParty, partyScene) - # Make sure another battler isn't already choosing to switch to the party - # Pokémon - eachSameSideBattler(idxBattler) do |b| - next if choices[b.index][0] != :SwitchOut || choices[b.index][1] != idxParty - partyScene.pbDisplay(_INTL("{1} has already been selected.", - pbParty(idxBattler)[idxParty].name)) if partyScene - return false - end - # Check whether battler can switch out - battler = @battlers[idxBattler] - return true if battler.fainted? - # Ability/item effects that allow switching no matter what - if battler.abilityActive? - if BattleHandlers.triggerCertainSwitchingUserAbility(battler.ability, battler, self) - return true - end - end - if battler.itemActive? - if BattleHandlers.triggerCertainSwitchingUserItem(battler.item, battler, self) - return true - end - end - # Other certain switching effects - return true if Settings::MORE_TYPE_EFFECTS && battler.pbHasType?(:GHOST) - # Other certain trapping effects - if battler.effects[PBEffects::Trapping] > 0 || - battler.effects[PBEffects::MeanLook] >= 0 || - battler.effects[PBEffects::Ingrain] || - @field.effects[PBEffects::FairyLock] > 0 - partyScene.pbDisplay(_INTL("{1} can't be switched out!", battler.pbThis)) if partyScene - return false - end - # Trapping abilities/items - eachOtherSideBattler(idxBattler) do |b| - next if !b.abilityActive? - if BattleHandlers.triggerTrappingTargetAbility(b.ability, battler, b, self) - partyScene.pbDisplay(_INTL("{1}'s {2} prevents switching!", - b.pbThis, b.abilityName)) if partyScene - return false - end - end - eachOtherSideBattler(idxBattler) do |b| - next if !b.itemActive? - if BattleHandlers.triggerTrappingTargetItem(b.item, battler, b, self) - partyScene.pbDisplay(_INTL("{1}'s {2} prevents switching!", - b.pbThis, b.itemName)) if partyScene - return false - end - end - return true - end - - def pbCanChooseNonActive?(idxBattler) - pbParty(idxBattler).each_with_index do |_pkmn, i| - return true if pbCanSwitchLax?(idxBattler, i) - end - return false - end - - def pbRegisterSwitch(idxBattler, idxParty) - return false if !pbCanSwitch?(idxBattler, idxParty) - @choices[idxBattler][0] = :SwitchOut - @choices[idxBattler][1] = idxParty # Party index of Pokémon to switch in - @choices[idxBattler][2] = nil - return true - end - - #============================================================================= - # Open the party screen and potentially pick a replacement Pokémon (or AI - # chooses replacement) - #============================================================================= - # Open party screen and potentially choose a Pokémon to switch with. Used in - # all instances where the party screen is opened. - def pbPartyScreen(idxBattler, checkLaxOnly = false, canCancel = false, shouldRegister = false) - ret = -1 - @scene.pbPartyScreen(idxBattler, canCancel) { |idxParty, partyScene| - if checkLaxOnly - next false if !pbCanSwitchLax?(idxBattler, idxParty, partyScene) - else - next false if !pbCanSwitch?(idxBattler, idxParty, partyScene) - end - if shouldRegister - next false if idxParty < 0 || !pbRegisterSwitch(idxBattler, idxParty) - end - ret = idxParty - next true - } - return ret - end - - # For choosing a replacement Pokémon when prompted in the middle of other - # things happening (U-turn, Baton Pass, in def pbSwitch). - def pbSwitchInBetween(idxBattler, checkLaxOnly = false, canCancel = false) - return pbPartyScreen(idxBattler, checkLaxOnly, canCancel) if pbOwnedByPlayer?(idxBattler) - return @battleAI.pbDefaultChooseNewEnemy(idxBattler, pbParty(idxBattler)) - end - - #============================================================================= - # Switching Pokémon - #============================================================================= - # General switching method that checks if any Pokémon need to be sent out and, - # if so, does. Called at the end of each round. - def pbEORSwitch(favorDraws = false) - return if @decision > 0 && !favorDraws - return if @decision == 5 && favorDraws - pbJudge - return if @decision > 0 - # Check through each fainted battler to see if that spot can be filled. - switched = [] - loop do - switched.clear - @battlers.each do |b| - next if !b || !b.fainted? - idxBattler = b.index - next if !pbCanChooseNonActive?(idxBattler) - if !pbOwnedByPlayer?(idxBattler) # Opponent/ally is switching in - next if wildBattle? && opposes?(idxBattler) # Wild Pokémon can't switch - idxPartyNew = pbSwitchInBetween(idxBattler) - opponent = pbGetOwnerFromBattlerIndex(idxBattler) - # NOTE: The player is only offered the chance to switch their own - # Pokémon when an opponent replaces a fainted Pokémon in single - # battles. In double battles, etc. there is no such offer. - if @internalBattle && @switchStyle && trainerBattle? && pbSideSize(0) == 1 && - opposes?(idxBattler) && !@battlers[0].fainted? && !switched.include?(0) && - pbCanChooseNonActive?(0) && @battlers[0].effects[PBEffects::Outrage] == 0 - idxPartyForName = idxPartyNew - enemyParty = pbParty(idxBattler) - if enemyParty[idxPartyNew].ability == :ILLUSION - new_index = pbLastInTeam(idxBattler) - idxPartyForName = new_index if new_index >= 0 && new_index != idxPartyNew - end - switchMessageHard = _INTL("{1} is about to send in a new Pokémon. Will you switch your Pokémon?", opponent.fullname) - switchMessageNormal = _INTL("{1} is about to send in {2}. Will you switch your Pokémon?", opponent.full_name, enemyParty[idxPartyForName].name) - switchMessage = $game_switches[SWITCH_GAME_DIFFICULTY_HARD] ? switchMessageHard : switchMessageNormal - if pbDisplayConfirm(switchMessage) - idxPlayerPartyNew = pbSwitchInBetween(0, false, true) - if idxPlayerPartyNew >= 0 - pbMessageOnRecall(@battlers[0]) - pbRecallAndReplace(0, idxPlayerPartyNew) - switched.push(0) - end - end - end - pbRecallAndReplace(idxBattler, idxPartyNew) - switched.push(idxBattler) - elsif trainerBattle? # Player switches in in a trainer battle - idxPlayerPartyNew = pbGetReplacementPokemonIndex(idxBattler) # Owner chooses - pbRecallAndReplace(idxBattler, idxPlayerPartyNew) - switched.push(idxBattler) - else - # Player's Pokémon has fainted in a wild battle - switch = false - if !pbDisplayConfirm(_INTL("Use next Pokémon?")) - switch = (pbRun(idxBattler, true) <= 0) - else - switch = true - end - if switch - idxPlayerPartyNew = pbGetReplacementPokemonIndex(idxBattler) # Owner chooses - pbRecallAndReplace(idxBattler, idxPlayerPartyNew) - switched.push(idxBattler) - end - end - end - break if switched.length == 0 - pbPriority(true).each do |b| - b.pbEffectsOnSwitchIn(true) if switched.include?(b.index) - end - end - end - - def pbGetReplacementPokemonIndex(idxBattler, random = false) - if random - return -1 if !pbCanSwitch?(idxBattler) # Can battler switch out? - choices = [] # Find all Pokémon that can switch in - eachInTeamFromBattlerIndex(idxBattler) do |_pkmn, i| - choices.push(i) if pbCanSwitchLax?(idxBattler, i) - end - return -1 if choices.length == 0 - return choices[pbRandom(choices.length)] - else - return pbSwitchInBetween(idxBattler, true) - end - end - - # Actually performs the recalling and sending out in all situations. - def pbRecallAndReplace(idxBattler, idxParty, randomReplacement = false, batonPass = false) - @scene.pbRecall(idxBattler) if !@battlers[idxBattler].fainted? - @battlers[idxBattler].pbAbilitiesOnSwitchOut # Inc. primordial weather check - @scene.pbShowPartyLineup(idxBattler & 1) if pbSideSize(idxBattler) == 1 - pbMessagesOnReplace(idxBattler, idxParty) if !randomReplacement - pbReplace(idxBattler, idxParty, batonPass) - end - - def pbMessageOnRecall(battler) - if battler.pbOwnedByPlayer? - if battler.hp <= battler.totalhp / 4 - pbDisplayBrief(_INTL("Good job, {1}! Come back!", battler.name)) - elsif battler.hp <= battler.totalhp / 2 - pbDisplayBrief(_INTL("OK, {1}! Come back!", battler.name)) - elsif battler.turnCount >= 5 - pbDisplayBrief(_INTL("{1}, that's enough! Come back!", battler.name)) - elsif battler.turnCount >= 2 - pbDisplayBrief(_INTL("{1}, come back!", battler.name)) - else - pbDisplayBrief(_INTL("{1}, switch out! Come back!", battler.name)) - end - else - owner = pbGetOwnerName(battler.index) - pbDisplayBrief(_INTL("{1} withdrew {2}!", owner, battler.name)) - end - end - - # Only called from def pbRecallAndReplace and Battle Arena's def pbSwitch. - def pbMessagesOnReplace(idxBattler, idxParty) - party = pbParty(idxBattler) - newPkmnName = party[idxParty].name - if party[idxParty].ability == :ILLUSION - new_index = pbLastInTeam(idxBattler) - newPkmnName = party[new_index].name if new_index >= 0 && new_index != idxParty - end - if pbOwnedByPlayer?(idxBattler) - opposing = @battlers[idxBattler].pbDirectOpposing - if opposing.fainted? || opposing.hp == opposing.totalhp - pbDisplayBrief(_INTL("You're in charge, {1}!", newPkmnName)) - elsif opposing.hp >= opposing.totalhp / 2 - pbDisplayBrief(_INTL("Go for it, {1}!", newPkmnName)) - elsif opposing.hp >= opposing.totalhp / 4 - pbDisplayBrief(_INTL("Just a little more! Hang in there, {1}!", newPkmnName)) - else - pbDisplayBrief(_INTL("Your opponent's weak! Get 'em, {1}!", newPkmnName)) - end - else - owner = pbGetOwnerFromBattlerIndex(idxBattler) - pbDisplayBrief(_INTL("{1} sent out {2}!", owner.full_name, newPkmnName)) - end - end - - # Only called from def pbRecallAndReplace above and Battle Arena's def - # pbSwitch. - def pbReplace(idxBattler, idxParty, batonPass = false) - party = pbParty(idxBattler) - idxPartyOld = @battlers[idxBattler].pokemonIndex - # Initialise the new Pokémon - @battlers[idxBattler].pbInitialize(party[idxParty], idxParty, batonPass) - # Reorder the party for this battle - partyOrder = pbPartyOrder(idxBattler) - partyOrder[idxParty], partyOrder[idxPartyOld] = partyOrder[idxPartyOld], partyOrder[idxParty] - # Send out the new Pokémon - pbSendOut([[idxBattler, party[idxParty]]]) - pbCalculatePriority(false, [idxBattler]) if Settings::RECALCULATE_TURN_ORDER_AFTER_SPEED_CHANGES - end - - # Called from def pbReplace above and at the start of battle. - # sendOuts is an array; each element is itself an array: [idxBattler,pkmn] - def pbSendOut(sendOuts, startBattle = false) - sendOuts.each { |b| @peer.pbOnEnteringBattle(self, b[1]) } - @scene.pbSendOutBattlers(sendOuts, startBattle) - sendOuts.each do |b| - @scene.pbResetMoveIndex(b[0]) - pbSetSeen(@battlers[b[0]]) - @usedInBattle[b[0] & 1][b[0] / 2] = true - end - end - - #============================================================================= - # Effects upon a Pokémon entering battle - #============================================================================= - # Called at the start of battle only. - def pbOnActiveAll - # Weather-inducing abilities, Trace, Imposter, etc. - pbCalculatePriority(true) - pbPriority(true).each { |b| b.pbEffectsOnSwitchIn(true) } - pbCalculatePriority - # Check forms are correct - eachBattler { |b| b.pbCheckForm } - end - - # Called when a Pokémon switches in (entry effects, entry hazards). - def pbOnActiveOne(battler) - return false if battler.fainted? - # Introduce Shadow Pokémon - if battler.opposes? && battler.shadowPokemon? - pbCommonAnimation("Shadow", battler) - pbDisplay(_INTL("Oh!\nA Shadow Pokémon!")) - end - # Record money-doubling effect of Amulet Coin/Luck Incense - if !battler.opposes? && [:AMULETCOIN, :LUCKINCENSE].include?(battler.item_id) - @field.effects[PBEffects::AmuletCoin] = true - end - # Update battlers' participants (who will gain Exp/EVs when a battler faints) - eachBattler { |b| b.pbUpdateParticipants } - # Healing Wish - if @positions[battler.index].effects[PBEffects::HealingWish] - pbCommonAnimation("HealingWish", battler) - pbDisplay(_INTL("The healing wish came true for {1}!", battler.pbThis(true))) - battler.pbRecoverHP(battler.totalhp) - battler.pbCureStatus(false) - @positions[battler.index].effects[PBEffects::HealingWish] = false - end - # Lunar Dance - if @positions[battler.index].effects[PBEffects::LunarDance] - pbCommonAnimation("LunarDance", battler) - pbDisplay(_INTL("{1} became cloaked in mystical moonlight!", battler.pbThis)) - battler.pbRecoverHP(battler.totalhp) - battler.pbCureStatus(false) - battler.eachMove { |m| m.pp = m.total_pp } - @positions[battler.index].effects[PBEffects::LunarDance] = false - end - # Entry hazards - # Stealth Rock - if battler.pbOwnSide.effects[PBEffects::StealthRock] && battler.takesIndirectDamage? && - GameData::Type.exists?(:ROCK) - bTypes = battler.pbTypes(true) - eff = Effectiveness.calculate(:ROCK, bTypes[0], bTypes[1], bTypes[2]) - if !Effectiveness.ineffective?(eff) - eff = eff.to_f / Effectiveness::NORMAL_EFFECTIVE - oldHP = battler.hp - battler.pbReduceHP(battler.totalhp * eff / 8, false) - pbDisplay(_INTL("Pointed stones dug into {1}!", battler.pbThis)) - battler.pbItemHPHealCheck - if battler.pbAbilitiesOnDamageTaken(oldHP) # Switched out - return pbOnActiveOne(battler) # For replacement battler - end - end - end - # Spikes - if battler.pbOwnSide.effects[PBEffects::Spikes] > 0 && battler.takesIndirectDamage? && - !battler.airborne? - spikesDiv = [8, 6, 4][battler.pbOwnSide.effects[PBEffects::Spikes] - 1] - oldHP = battler.hp - battler.pbReduceHP(battler.totalhp / spikesDiv, false) - pbDisplay(_INTL("{1} is hurt by the spikes!", battler.pbThis)) - battler.pbItemHPHealCheck - if battler.pbAbilitiesOnDamageTaken(oldHP) # Switched out - return pbOnActiveOne(battler) # For replacement battler - end - end - # Toxic Spikes - if battler.pbOwnSide.effects[PBEffects::ToxicSpikes] > 0 && !battler.fainted? && - !battler.airborne? - if battler.pbHasType?(:POISON) - battler.pbOwnSide.effects[PBEffects::ToxicSpikes] = 0 - pbDisplay(_INTL("{1} absorbed the poison spikes!", battler.pbThis)) - elsif battler.pbCanPoison?(nil, false) - if battler.pbOwnSide.effects[PBEffects::ToxicSpikes] == 2 - battler.pbPoison(nil, _INTL("{1} was badly poisoned by the poison spikes!", battler.pbThis), true) - else - battler.pbPoison(nil, _INTL("{1} was poisoned by the poison spikes!", battler.pbThis)) - end - end - end - # Sticky Web - if battler.pbOwnSide.effects[PBEffects::StickyWeb] && !battler.fainted? && - !battler.airborne? - pbDisplay(_INTL("{1} was caught in a sticky web!", battler.pbThis)) - if battler.pbCanLowerStatStage?(:SPEED) - battler.pbLowerStatStage(:SPEED, 1, nil) - battler.pbItemStatRestoreCheck - end - end - # Battler faints if it is knocked out because of an entry hazard above - if battler.fainted? - battler.pbFaint - pbGainExp - pbJudge - return false - end - battler.pbCheckForm - return true - end -end diff --git a/Data/Scripts/011_Battle/003_Battle/007_Battle_Action_UseItem.rb b/Data/Scripts/011_Battle/003_Battle/007_Battle_Action_UseItem.rb deleted file mode 100644 index 801583ea6..000000000 --- a/Data/Scripts/011_Battle/003_Battle/007_Battle_Action_UseItem.rb +++ /dev/null @@ -1,148 +0,0 @@ -class PokeBattle_Battle - #============================================================================= - # Choosing to use an item - #============================================================================= - def pbCanUseItemOnPokemon?(item,pkmn,battler,scene,showMessages=true) - if !pkmn || pkmn.egg? - scene.pbDisplay(_INTL("It won't have any effect.")) if showMessages - return false - end - # Embargo - if battler && battler.effects[PBEffects::Embargo]>0 - scene.pbDisplay(_INTL("Embargo's effect prevents the item's use on {1}!", - battler.pbThis(true))) if showMessages - return false - end - return true - end - - # NOTE: Using a Poké Ball consumes all your actions for the round. The method - # below is one half of making this happen; the other half is in the - # ItemHandlers::CanUseInBattle for Poké Balls. - def pbItemUsesAllActions?(item) - return true if GameData::Item.get(item).is_poke_ball? - return false - end - - def pbRegisterItem(idxBattler,item,idxTarget=nil,idxMove=nil) - # Register for use of item on a Pokémon in the party - @choices[idxBattler][0] = :UseItem - @choices[idxBattler][1] = item # ID of item to be used - @choices[idxBattler][2] = idxTarget # Party index of Pokémon to use item on - @choices[idxBattler][3] = idxMove # Index of move to recharge (Ethers) - # Delete the item from the Bag. If it turns out it will have no effect, it - # will be re-added to the Bag later. - pbConsumeItemInBag(item,idxBattler) - return true - end - - #============================================================================= - # Using an item - #============================================================================= - def pbConsumeItemInBag(item,idxBattler) - return if !item - useType = GameData::Item.get(item).battle_use - return if useType==0 || (useType>=6 && useType<=10) # Not consumed upon use - if pbOwnedByPlayer?(idxBattler) - if !$PokemonBag.pbDeleteItem(item) - raise _INTL("Tried to consume item that wasn't in the Bag somehow.") - end - else - items = pbGetOwnerItems(idxBattler) - items.each_with_index do |thisItem,i| - next if thisItem!=item - items[i] = nil - break - end - items.compact! - end - end - - def pbReturnUnusedItemToBag(item,idxBattler) - return if !item - useType = GameData::Item.get(item).battle_use - return if useType==0 || (useType>=6 && useType<=10) # Not consumed upon use - if pbOwnedByPlayer?(idxBattler) - if $PokemonBag && $PokemonBag.pbCanStore?(item) - $PokemonBag.pbStoreItem(item) - else - raise _INTL("Couldn't return unused item to Bag somehow.") - end - else - items = pbGetOwnerItems(idxBattler) - items.push(item) if items - end - end - - def pbUseItemMessage(item,trainerName) - itemName = GameData::Item.get(item).name - if itemName.starts_with_vowel? - pbDisplayBrief(_INTL("{1} used an {2}.",trainerName,itemName)) - else - pbDisplayBrief(_INTL("{1} used a {2}.",trainerName,itemName)) - end - end - - # Uses an item on a Pokémon in the trainer's party. - def pbUseItemOnPokemon(item,idxParty,userBattler) - trainerName = pbGetOwnerName(userBattler.index) - pbUseItemMessage(item,trainerName) - pkmn = pbParty(userBattler.index)[idxParty] - battler = pbFindBattler(idxParty,userBattler.index) - ch = @choices[userBattler.index] - if ItemHandlers.triggerCanUseInBattle(item,pkmn,battler,ch[3],true,self,@scene,false) - ItemHandlers.triggerBattleUseOnPokemon(item,pkmn,battler,ch,@scene) - ch[1] = nil # Delete item from choice - return - end - pbDisplay(_INTL("But it had no effect!")) - # Return unused item to Bag - pbReturnUnusedItemToBag(item,userBattler.index) - end - - # Uses an item on a Pokémon in battle that belongs to the trainer. - def pbUseItemOnBattler(item,idxParty,userBattler) - trainerName = pbGetOwnerName(userBattler.index) - pbUseItemMessage(item,trainerName) - battler = pbFindBattler(idxParty,userBattler.index) - ch = @choices[userBattler.index] - if battler - if ItemHandlers.triggerCanUseInBattle(item,battler.pokemon,battler,ch[3],true,self,@scene,false) - ItemHandlers.triggerBattleUseOnBattler(item,battler,@scene) - ch[1] = nil # Delete item from choice - return - else - pbDisplay(_INTL("But it had no effect!")) - end - else - pbDisplay(_INTL("But it's not where this item can be used!")) - end - # Return unused item to Bag - pbReturnUnusedItemToBag(item,userBattler.index) - end - - # Uses a Poké Ball in battle directly. - def pbUsePokeBallInBattle(item,idxBattler,userBattler) - idxBattler = userBattler.index if idxBattler<0 - battler = @battlers[idxBattler] - ItemHandlers.triggerUseInBattle(item,battler,self) - @choices[userBattler.index][1] = nil # Delete item from choice - end - - # Uses an item in battle directly. - def pbUseItemInBattle(item,idxBattler,userBattler) - trainerName = pbGetOwnerName(userBattler.index) - pbUseItemMessage(item,trainerName) - battler = (idxBattler<0) ? userBattler : @battlers[idxBattler] - pkmn = battler.pokemon - ch = @choices[userBattler.index] - if ItemHandlers.triggerCanUseInBattle(item,pkmn,battler,ch[3],true,self,@scene,false) - ItemHandlers.triggerUseInBattle(item,battler,self) - ch[1] = nil # Delete item from choice - return - end - pbDisplay(_INTL("But it had no effect!")) - # Return unused item to Bag - pbReturnUnusedItemToBag(item,userBattler.index) - end -end diff --git a/Data/Scripts/011_Battle/003_Battle/008_Battle_Action_Running.rb b/Data/Scripts/011_Battle/003_Battle/008_Battle_Action_Running.rb deleted file mode 100644 index e26fc9aa2..000000000 --- a/Data/Scripts/011_Battle/003_Battle/008_Battle_Action_Running.rb +++ /dev/null @@ -1,156 +0,0 @@ -class PokeBattle_Battle - #============================================================================= - # Running from battle - #============================================================================= - def pbCanRun?(idxBattler) - return false if trainerBattle? - battler = @battlers[idxBattler] - return false if !@canRun && !battler.opposes? - return true if battler.pbHasType?(:GHOST) && Settings::MORE_TYPE_EFFECTS - return true if battler.abilityActive? && - BattleHandlers.triggerRunFromBattleAbility(battler.ability,battler) - return true if battler.itemActive? && - BattleHandlers.triggerRunFromBattleItem(battler.item,battler) - return false if battler.effects[PBEffects::Trapping]>0 || - battler.effects[PBEffects::MeanLook]>=0 || - battler.effects[PBEffects::Ingrain] || - @field.effects[PBEffects::FairyLock]>0 - eachOtherSideBattler(idxBattler) do |b| - return false if b.abilityActive? && - BattleHandlers.triggerTrappingTargetAbility(b.ability,battler,b,self) - return false if b.itemActive? && - BattleHandlers.triggerTrappingTargetItem(b.item,battler,b,self) - end - return true - end - - # Return values: - # -1: Failed fleeing - # 0: Wasn't possible to attempt fleeing, continue choosing action for the round - # 1: Succeeded at fleeing, battle will end - # duringBattle is true for replacing a fainted Pokémon during the End Of Round - # phase, and false for choosing the Run command. - def pbRun(idxBattler,duringBattle=false) - battler = @battlers[idxBattler] - if battler.opposes? - return 0 if trainerBattle? - @choices[idxBattler][0] = :Run - @choices[idxBattler][1] = 0 - @choices[idxBattler][2] = nil - return -1 - end - # Fleeing from trainer battles - if trainerBattle? - if $DEBUG && Input.press?(Input::CTRL) - if pbDisplayConfirm(_INTL("Treat this battle as a win?")) - @decision = 1 - return 1 - elsif pbDisplayConfirm(_INTL("Treat this battle as a loss?")) - @decision = 2 - return 1 - end - elsif @internalBattle - if pbDisplayConfirm(_INTL("Would you like to forfeit the match and quit now?")) - pbSEPlay("Battle flee") - pbDisplay(_INTL("{1} forfeited the match!",self.pbPlayer.name)) - @decision = 2 - return 1 - end - elsif pbDisplayConfirm(_INTL("Would you like to forfeit the match and quit now?")) - pbSEPlay("Battle flee") - pbDisplay(_INTL("{1} forfeited the match!",self.pbPlayer.name)) - @decision = 3 - return 1 - end - return 0 - end - # Fleeing from wild battles - if $DEBUG && Input.press?(Input::CTRL) - pbSEPlay("Battle flee") - pbDisplayPaused(_INTL("You got away safely!")) - @decision = 3 - return 1 - end - if !@canRun - pbDisplayPaused(_INTL("You can't escape!")) - return 0 - end - if !duringBattle - if battler.pbHasType?(:GHOST) && Settings::MORE_TYPE_EFFECTS - pbSEPlay("Battle flee") - pbDisplayPaused(_INTL("You got away safely!")) - @decision = 3 - return 1 - end - # Abilities that guarantee escape - if battler.abilityActive? - if BattleHandlers.triggerRunFromBattleAbility(battler.ability,battler) - pbShowAbilitySplash(battler,true) - pbHideAbilitySplash(battler) - pbSEPlay("Battle flee") - pbDisplayPaused(_INTL("You got away safely!")) - @decision = 3 - return 1 - end - end - # Held items that guarantee escape - if battler.itemActive? - if BattleHandlers.triggerRunFromBattleItem(battler.item,battler) - pbSEPlay("Battle flee") - pbDisplayPaused(_INTL("{1} fled using its {2}!", - battler.pbThis,battler.itemName)) - @decision = 3 - return 1 - end - end - # Other certain trapping effects - if battler.effects[PBEffects::Trapping]>0 || - battler.effects[PBEffects::MeanLook]>=0 || - battler.effects[PBEffects::Ingrain] || - @field.effects[PBEffects::FairyLock]>0 - pbDisplayPaused(_INTL("You can't escape!")) - return 0 - end - # Trapping abilities/items - eachOtherSideBattler(idxBattler) do |b| - next if !b.abilityActive? - if BattleHandlers.triggerTrappingTargetAbility(b.ability,battler,b,self) - pbDisplayPaused(_INTL("{1} prevents escape with {2}!",b.pbThis,b.abilityName)) - return 0 - end - end - eachOtherSideBattler(idxBattler) do |b| - next if !b.itemActive? - if BattleHandlers.triggerTrappingTargetItem(b.item,battler,b,self) - pbDisplayPaused(_INTL("{1} prevents escape with {2}!",b.pbThis,b.itemName)) - return 0 - end - end - end - # Fleeing calculation - # Get the speeds of the Pokémon fleeing and the fastest opponent - # NOTE: Not pbSpeed, because using unmodified Speed. - @runCommand += 1 if !duringBattle # Make it easier to flee next time - speedPlayer = @battlers[idxBattler].speed - speedEnemy = 1 - eachOtherSideBattler(idxBattler) do |b| - speed = b.speed - speedEnemy = speed if speedEnemyspeedEnemy - rate = 256 - else - rate = (speedPlayer*128)/speedEnemy - rate += @runCommand*30 - end - if rate>=256 || @battleAI.pbAIRandom(256)=0 - # return false if !pbHasMegaRing?(idxBattler) - # side = @battlers[idxBattler].idxOwnSide - # owner = pbGetOwnerIndexFromBattlerIndex(idxBattler) - # return @megaEvolution[side][owner]==-1 - end - - def pbRegisterMegaEvolution(idxBattler) - side = @battlers[idxBattler].idxOwnSide - owner = pbGetOwnerIndexFromBattlerIndex(idxBattler) - @megaEvolution[side][owner] = idxBattler - end - - def pbUnregisterMegaEvolution(idxBattler) - side = @battlers[idxBattler].idxOwnSide - owner = pbGetOwnerIndexFromBattlerIndex(idxBattler) - @megaEvolution[side][owner] = -1 if @megaEvolution[side][owner]==idxBattler - end - - def pbToggleRegisteredMegaEvolution(idxBattler) - side = @battlers[idxBattler].idxOwnSide - owner = pbGetOwnerIndexFromBattlerIndex(idxBattler) - if @megaEvolution[side][owner]==idxBattler - @megaEvolution[side][owner] = -1 - else - @megaEvolution[side][owner] = idxBattler - end - end - - def pbRegisteredMegaEvolution?(idxBattler) - side = @battlers[idxBattler].idxOwnSide - owner = pbGetOwnerIndexFromBattlerIndex(idxBattler) - return @megaEvolution[side][owner]==idxBattler - end - - #============================================================================= - # Mega Evolving a battler - #============================================================================= - def pbMegaEvolve(idxBattler) - battler = @battlers[idxBattler] - return if !battler || !battler.pokemon - return if !battler.hasMega? || battler.mega? - trainerName = pbGetOwnerName(idxBattler) - # Break Illusion - if battler.hasActiveAbility?(:ILLUSION) - BattleHandlers.triggerTargetAbilityOnHit(battler.ability,nil,battler,nil,self) - end - # Mega Evolve - case battler.pokemon.megaMessage - when 1 # Rayquaza - pbDisplay(_INTL("{1}'s fervent wish has reached {2}!",trainerName,battler.pbThis)) - else - pbDisplay(_INTL("{1}'s {2} is reacting to {3}'s {4}!", - battler.pbThis,battler.itemName,trainerName,pbGetMegaRingName(idxBattler))) - end - pbCommonAnimation("MegaEvolution",battler) - battler.pokemon.makeMega - battler.form = battler.pokemon.form - battler.pbUpdate(true) - @scene.pbChangePokemon(battler,battler.pokemon) - @scene.pbRefreshOne(idxBattler) - pbCommonAnimation("MegaEvolution2",battler) - megaName = battler.pokemon.megaName - megaName = _INTL("Mega {1}", battler.pokemon.speciesName) if nil_or_empty?(megaName) - pbDisplay(_INTL("{1} has Mega Evolved into {2}!",battler.pbThis,megaName)) - side = battler.idxOwnSide - owner = pbGetOwnerIndexFromBattlerIndex(idxBattler) - @megaEvolution[side][owner] = -2 - if battler.isSpecies?(:GENGAR) && battler.mega? - battler.effects[PBEffects::Telekinesis] = 0 - end - pbCalculatePriority(false,[idxBattler]) if Settings::RECALCULATE_TURN_ORDER_AFTER_MEGA_EVOLUTION - # Trigger ability - battler.pbEffectsOnSwitchIn - end - - #============================================================================= - # Primal Reverting a battler - #============================================================================= - def pbPrimalReversion(idxBattler) - battler = @battlers[idxBattler] - return if !battler || !battler.pokemon - return if !battler.hasPrimal? || battler.primal? - if battler.isSpecies?(:KYOGRE) - pbCommonAnimation("PrimalKyogre",battler) - elsif battler.isSpecies?(:GROUDON) - pbCommonAnimation("PrimalGroudon",battler) - end - battler.pokemon.makePrimal - battler.form = battler.pokemon.form - battler.pbUpdate(true) - @scene.pbChangePokemon(battler,battler.pokemon) - @scene.pbRefreshOne(idxBattler) - if battler.isSpecies?(:KYOGRE) - pbCommonAnimation("PrimalKyogre2",battler) - elsif battler.isSpecies?(:GROUDON) - pbCommonAnimation("PrimalGroudon2",battler) - end - pbDisplay(_INTL("{1}'s Primal Reversion!\nIt reverted to its primal form!",battler.pbThis)) - end -end diff --git a/Data/Scripts/011_Battle/003_Battle/010_Battle_Phase_Command.rb b/Data/Scripts/011_Battle/003_Battle/010_Battle_Phase_Command.rb deleted file mode 100644 index a5529ae4d..000000000 --- a/Data/Scripts/011_Battle/003_Battle/010_Battle_Phase_Command.rb +++ /dev/null @@ -1,253 +0,0 @@ -class PokeBattle_Battle - #============================================================================= - # Clear commands - #============================================================================= - def pbClearChoice(idxBattler) - @choices[idxBattler] = [] if !@choices[idxBattler] - @choices[idxBattler][0] = :None - @choices[idxBattler][1] = 0 - @choices[idxBattler][2] = nil - @choices[idxBattler][3] = -1 - end - - def pbCancelChoice(idxBattler) - # If idxBattler's choice was to use an item, return that item to the Bag - if @choices[idxBattler][0] == :UseItem - item = @choices[idxBattler][1] - pbReturnUnusedItemToBag(item, idxBattler) if item - end - # If idxBattler chose to Mega Evolve, cancel it - pbUnregisterMegaEvolution(idxBattler) - # Clear idxBattler's choice - pbClearChoice(idxBattler) - end - - #============================================================================= - # Use main command menu (Fight/Pokémon/Bag/Run) - #============================================================================= - def pbCommandMenu(idxBattler,firstAction) - return @scene.pbCommandMenu(idxBattler,firstAction) - end - - #============================================================================= - # Check whether actions can be taken - #============================================================================= - def pbCanShowCommands?(idxBattler) - battler = @battlers[idxBattler] - return false if !battler || battler.fainted? - return false if battler.usingMultiTurnAttack? - return true - end - - def pbCanShowFightMenu?(idxBattler) - battler = @battlers[idxBattler] - # Encore - return false if battler.effects[PBEffects::Encore]>0 - # No moves that can be chosen (will Struggle instead) - usable = false - battler.eachMoveWithIndex do |_m,i| - next if !pbCanChooseMove?(idxBattler,i,false) - usable = true - break - end - return usable - end - - #============================================================================= - # Use sub-menus to choose an action, and register it if is allowed - #============================================================================= - # Returns true if a choice was made, false if cancelled. - def pbFightMenu(idxBattler) - # Auto-use Encored move or no moves choosable, so auto-use Struggle - return pbAutoChooseMove(idxBattler) if !pbCanShowFightMenu?(idxBattler) - # Battle Palace only - return true if pbAutoFightMenu(idxBattler) - # Regular move selection - ret = false - @scene.pbFightMenu(idxBattler,pbCanMegaEvolve?(idxBattler)) { |cmd| - case cmd - when -1 # Cancel - when -2 # Toggle Mega Evolution - pbToggleRegisteredMegaEvolution(idxBattler) - next false - when -3 # Shift - pbUnregisterMegaEvolution(idxBattler) - pbRegisterShift(idxBattler) - ret = true - else # Chose a move to use - next false if cmd<0 || !@battlers[idxBattler].moves[cmd] || - !@battlers[idxBattler].moves[cmd].id - next false if !pbRegisterMove(idxBattler,cmd) - next false if !singleBattle? && - !pbChooseTarget(@battlers[idxBattler],@battlers[idxBattler].moves[cmd]) - ret = true - end - next true - } - return ret - end - - def pbAutoFightMenu(idxBattler); return false; end - - def pbChooseTarget(battler,move) - target_data = move.pbTarget(battler) - idxTarget = @scene.pbChooseTarget(battler.index,target_data) - return false if idxTarget<0 - pbRegisterTarget(battler.index,idxTarget) - return true - end - - def pbItemMenu(idxBattler,firstAction) - if !@internalBattle - pbDisplay(_INTL("Items can't be used here.")) - return false - end - ret = false - @scene.pbItemMenu(idxBattler,firstAction) { |item,useType,idxPkmn,idxMove,itemScene| - next false if !item - battler = pkmn = nil - case useType - when 1, 2, 6, 7 # Use on Pokémon/Pokémon's move - next false if !ItemHandlers.hasBattleUseOnPokemon(item) - battler = pbFindBattler(idxPkmn,idxBattler) - pkmn = pbParty(idxBattler)[idxPkmn] - next false if !pbCanUseItemOnPokemon?(item,pkmn,battler,itemScene) - when 3, 8 # Use on battler - next false if !ItemHandlers.hasBattleUseOnBattler(item) - battler = pbFindBattler(idxPkmn,idxBattler) - pkmn = battler.pokemon if battler - next false if !pbCanUseItemOnPokemon?(item,pkmn,battler,itemScene) - when 4, 9 # Poké Balls - next false if idxPkmn<0 - battler = @battlers[idxPkmn] - pkmn = battler.pokemon if battler - when 5, 10 # No target (Poké Doll, Guard Spec., Launcher items) - battler = @battlers[idxBattler] - pkmn = battler.pokemon if battler - else - next false - end - next false if !pkmn - next false if !ItemHandlers.triggerCanUseInBattle(item, - pkmn,battler,idxMove,firstAction,self,itemScene) - next false if !pbRegisterItem(idxBattler,item,idxPkmn,idxMove) - ret = true - next true - } - return ret - end - - def pbPartyMenu(idxBattler) - ret = -1 - if @debug - ret = @battleAI.pbDefaultChooseNewEnemy(idxBattler,pbParty(idxBattler)) - else - ret = pbPartyScreen(idxBattler,false,true,true) - end - return ret>=0 - end - - def pbRunMenu(idxBattler) - # Regardless of succeeding or failing to run, stop choosing actions - return pbRun(idxBattler)!=0 - end - - def pbCallMenu(idxBattler) - return pbRegisterCall(idxBattler) - end - - def pbDebugMenu - # NOTE: This doesn't do anything yet. Maybe you can write your own debugging - # options! - end - - #============================================================================= - # Command phase - #============================================================================= - def pbCommandPhase - @scene.pbBeginCommandPhase - # Reset choices if commands can be shown - @battlers.each_with_index do |b,i| - next if !b - pbClearChoice(i) if pbCanShowCommands?(i) - end - # Reset choices to perform Mega Evolution if it wasn't done somehow - for side in 0...2 - @megaEvolution[side].each_with_index do |megaEvo,i| - @megaEvolution[side][i] = -1 if megaEvo>=0 - end - end - # Choose actions for the round (player first, then AI) - pbCommandPhaseLoop(true) # Player chooses their actions - return if @decision!=0 # Battle ended, stop choosing actions - pbCommandPhaseLoop(false) # AI chooses their actions - end - - def pbCommandPhaseLoop(isPlayer) - # NOTE: Doing some things (e.g. running, throwing a Poké Ball) takes up all - # your actions in a round. - actioned = [] - idxBattler = -1 - loop do - break if @decision!=0 # Battle ended, stop choosing actions - idxBattler += 1 - break if idxBattler>=@battlers.length - next if !@battlers[idxBattler] || pbOwnedByPlayer?(idxBattler)!=isPlayer - next if @choices[idxBattler][0]!=:None # Action is forced, can't choose one - next if !pbCanShowCommands?(idxBattler) # Action is forced, can't choose one - # AI controls this battler - if @controlPlayer || !pbOwnedByPlayer?(idxBattler) - @battleAI.pbDefaultChooseEnemyCommand(idxBattler) - next - end - # Player chooses an action - actioned.push(idxBattler) - commandsEnd = false # Whether to cancel choosing all other actions this round - loop do - cmd = pbCommandMenu(idxBattler,actioned.length==1) - # If being Sky Dropped, can't do anything except use a move - if cmd>0 && @battlers[idxBattler].effects[PBEffects::SkyDrop]>=0 - pbDisplay(_INTL("Sky Drop won't let {1} go!",@battlers[idxBattler].pbThis(true))) - next - end - case cmd - when 0 # Fight - break if pbFightMenu(idxBattler) - when 1 # Bag - if pbItemMenu(idxBattler,actioned.length==1) - commandsEnd = true if pbItemUsesAllActions?(@choices[idxBattler][1]) - break - end - when 2 # Pokémon - if pbPartyMenu(idxBattler) - @scene.setLastCommandIndex(idxBattler,0) - break - end - when 3 # Run - # NOTE: "Run" is only an available option for the first battler the - # player chooses an action for in a round. Attempting to run - # from battle prevents you from choosing any other actions in - # that round. - if pbRunMenu(idxBattler) - commandsEnd = true - break - end - when 4 # Call - break if pbCallMenu(idxBattler) - when -2 # Debug - pbDebugMenu - next - when -1 # Go back to previous battler's action choice - next if actioned.length<=1 - actioned.pop # Forget this battler was done - idxBattler = actioned.last-1 - pbCancelChoice(idxBattler+1) # Clear the previous battler's choice - actioned.pop # Forget the previous battler was done - break - end - pbCancelChoice(idxBattler) - end - break if commandsEnd - end - end -end diff --git a/Data/Scripts/011_Battle/003_Battle/011_Battle_Phase_Attack.rb b/Data/Scripts/011_Battle/003_Battle/011_Battle_Phase_Attack.rb deleted file mode 100644 index 07bcaf913..000000000 --- a/Data/Scripts/011_Battle/003_Battle/011_Battle_Phase_Attack.rb +++ /dev/null @@ -1,190 +0,0 @@ -class PokeBattle_Battle - #============================================================================= - # Attack phase actions - #============================================================================= - # Quick Claw, Custap Berry's "X let it move first!" message. - def pbAttackPhasePriorityChangeMessages - pbPriority.each do |b| - if b.effects[PBEffects::PriorityAbility] && b.abilityActive? - BattleHandlers.triggerPriorityBracketUseAbility(b.ability,b,self) - elsif b.effects[PBEffects::PriorityItem] && b.itemActive? - BattleHandlers.triggerPriorityBracketUseItem(b.item,b,self) - end - end - end - - def pbAttackPhaseCall - pbPriority.each do |b| - next unless @choices[b.index][0]==:Call && !b.fainted? - b.lastMoveFailed = false # Counts as a successful move for Stomping Tantrum - pbCall(b.index) - end - end - - def pbPursuit(idxSwitcher) - @switching = true - pbPriority.each do |b| - next if b.fainted? || !b.opposes?(idxSwitcher) # Shouldn't hit an ally - next if b.movedThisRound? || !pbChoseMoveFunctionCode?(b.index,"088") # Pursuit - # Check whether Pursuit can be used - next unless pbMoveCanTarget?(b.index,idxSwitcher,@choices[b.index][2].pbTarget(b)) - next unless pbCanChooseMove?(b.index,@choices[b.index][1],false) - next if b.status == :SLEEP || b.status == :FROZEN - next if b.effects[PBEffects::SkyDrop]>=0 - next if b.hasActiveAbility?(:TRUANT) && b.effects[PBEffects::Truant] - # Mega Evolve - if !wildBattle? || !b.opposes? - owner = pbGetOwnerIndexFromBattlerIndex(b.index) - pbMegaEvolve(b.index) if @megaEvolution[b.idxOwnSide][owner]==b.index - end - # Use Pursuit - @choices[b.index][3] = idxSwitcher # Change Pursuit's target - if b.pbProcessTurn(@choices[b.index],false) - b.effects[PBEffects::Pursuit] = true - end - break if @decision>0 || @battlers[idxSwitcher].fainted? - end - @switching = false - end - - def pbAttackPhaseSwitch - pbPriority.each do |b| - next unless @choices[b.index][0]==:SwitchOut && !b.fainted? - idxNewPkmn = @choices[b.index][1] # Party index of Pokémon to switch to - b.lastMoveFailed = false # Counts as a successful move for Stomping Tantrum - @lastMoveUser = b.index - # Switching message - pbMessageOnRecall(b) - # Pursuit interrupts switching - pbPursuit(b.index) - return if @decision>0 - # Switch Pokémon - pbRecallAndReplace(b.index,idxNewPkmn) - b.pbEffectsOnSwitchIn(true) - end - end - - def pbAttackPhaseItems - pbPriority.each do |b| - next unless @choices[b.index][0] == :UseItem && !b.fainted? - b.lastMoveFailed = false # Counts as a successful move for Stomping Tantrum - item = @choices[b.index][1] - next if !item - case GameData::Item.get(item).battle_use - when 1, 2, 6, 7 # Use on Pokémon/Pokémon's move - pbUseItemOnPokemon(item, @choices[b.index][2], b) if @choices[b.index][2] >= 0 - when 3, 8 # Use on battler - pbUseItemOnBattler(item, @choices[b.index][2], b) - when 4, 9 # Use Poké Ball - pbUsePokeBallInBattle(item, @choices[b.index][2], b) - when 5, 10 # Use directly - pbUseItemInBattle(item, @choices[b.index][2], b) - else - next - end - return if @decision > 0 - end - pbCalculatePriority if Settings::RECALCULATE_TURN_ORDER_AFTER_SPEED_CHANGES - end - - def pbAttackPhaseMegaEvolution - pbPriority.each do |b| - next if wildBattle? && b.opposes? - next unless @choices[b.index][0]==:UseMove && !b.fainted? - owner = pbGetOwnerIndexFromBattlerIndex(b.index) - next if @megaEvolution[b.idxOwnSide][owner]!=b.index - pbMegaEvolve(b.index) - end - end - - def pbAttackPhaseMoves - # Show charging messages (Focus Punch) - pbPriority.each do |b| - next unless @choices[b.index][0]==:UseMove && !b.fainted? - next if b.movedThisRound? - @choices[b.index][2].pbDisplayChargeMessage(b) - end - # Main move processing loop - loop do - priority = pbPriority - # Forced to go next - advance = false - priority.each do |b| - next unless b.effects[PBEffects::MoveNext] && !b.fainted? - next unless @choices[b.index][0]==:UseMove || @choices[b.index][0]==:Shift - next if b.movedThisRound? - advance = b.pbProcessTurn(@choices[b.index]) - break if advance - end - return if @decision>0 - next if advance - # Regular priority order - priority.each do |b| - next if b.effects[PBEffects::Quash]>0 || b.fainted? - next unless @choices[b.index][0]==:UseMove || @choices[b.index][0]==:Shift - next if b.movedThisRound? - advance = b.pbProcessTurn(@choices[b.index]) - break if advance - end - return if @decision>0 - next if advance - # Quashed - quashLevel = 0 - loop do - quashLevel += 1 - moreQuash = false - priority.each do |b| - moreQuash = true if b.effects[PBEffects::Quash]>quashLevel - next unless b.effects[PBEffects::Quash]==quashLevel && !b.fainted? - next unless @choices[b.index][0]==:UseMove || @choices[b.index][0]==:Shift - next if b.movedThisRound? - advance = b.pbProcessTurn(@choices[b.index]) - break - end - break if advance || !moreQuash - end - return if @decision>0 - next if advance - # Check for all done - priority.each do |b| - if !b.fainted? && !b.movedThisRound? - advance = true if @choices[b.index][0]==:UseMove || @choices[b.index][0]==:Shift - end - break if advance - end - next if advance - # All Pokémon have moved; end the loop - break - end - end - - #============================================================================= - # Attack phase - #============================================================================= - def pbAttackPhase - @scene.pbBeginAttackPhase - # Reset certain effects - @battlers.each_with_index do |b,i| - next if !b - b.turnCount += 1 if !b.fainted? - @successStates[i].clear - if @choices[i][0]!=:UseMove && @choices[i][0]!=:Shift && @choices[i][0]!=:SwitchOut - b.effects[PBEffects::DestinyBond] = false - b.effects[PBEffects::Grudge] = false - end - b.effects[PBEffects::Rage] = false if !pbChoseMoveFunctionCode?(i,"093") # Rage - end - PBDebug.log("") - # Calculate move order for this round - pbCalculatePriority(true) - # Perform actions - pbAttackPhasePriorityChangeMessages - pbAttackPhaseCall - pbAttackPhaseSwitch - return if @decision>0 - pbAttackPhaseItems - return if @decision>0 - pbAttackPhaseMegaEvolution - pbAttackPhaseMoves - end -end diff --git a/Data/Scripts/011_Battle/003_Battle/012_Battle_Phase_EndOfRound.rb b/Data/Scripts/011_Battle/003_Battle/012_Battle_Phase_EndOfRound.rb deleted file mode 100644 index ab90bcf9e..000000000 --- a/Data/Scripts/011_Battle/003_Battle/012_Battle_Phase_EndOfRound.rb +++ /dev/null @@ -1,666 +0,0 @@ -class PokeBattle_Battle - #============================================================================= - # Decrement effect counters - #============================================================================= - def pbEORCountDownBattlerEffect(priority,effect) - priority.each do |b| - next if b.fainted? || b.effects[effect]==0 - b.effects[effect] -= 1 - yield b if block_given? && b.effects[effect]==0 - end - end - - def pbEORCountDownSideEffect(side,effect,msg) - if @sides[side].effects[effect]>0 - @sides[side].effects[effect] -= 1 - pbDisplay(msg) if @sides[side].effects[effect]==0 - end - end - - def pbEORCountDownFieldEffect(effect,msg) - if @field.effects[effect]>0 - @field.effects[effect] -= 1 - if @field.effects[effect]==0 - pbDisplay(msg) - if effect==PBEffects::MagicRoom - pbPriority(true).each { |b| b.pbItemTerrainStatBoostCheck } - end - end - end - end - - #============================================================================= - # End Of Round weather - #============================================================================= - def pbEORWeather(priority) - # NOTE: Primordial weather doesn't need to be checked here, because if it - # could wear off here, it will have worn off already. - # Count down weather duration - @field.weatherDuration -= 1 if @field.weatherDuration>0 - # Weather wears off - if @field.weatherDuration==0 - case @field.weather - when :Sun then pbDisplay(_INTL("The sunlight faded.")) - when :Rain then pbDisplay(_INTL("The rain stopped.")) - when :Sandstorm then pbDisplay(_INTL("The sandstorm subsided.")) - when :Hail then pbDisplay(_INTL("The hail stopped.")) - when :ShadowSky then pbDisplay(_INTL("The shadow sky faded.")) - end - @field.weather = :None - # Check for form changes caused by the weather changing - eachBattler { |b| b.pbCheckFormOnWeatherChange } - # Start up the default weather - pbStartWeather(nil,@field.defaultWeather) if @field.defaultWeather != :None - return if @field.weather == :None - end - # Weather continues - weather_data = GameData::BattleWeather.try_get(@field.weather) - pbCommonAnimation(weather_data.animation) if weather_data - case @field.weather -# when :Sun then pbDisplay(_INTL("The sunlight is strong.")) -# when :Rain then pbDisplay(_INTL("Rain continues to fall.")) - when :Sandstorm then pbDisplay(_INTL("The sandstorm is raging.")) - when :Hail then pbDisplay(_INTL("The hail is crashing down.")) -# when :HarshSun then pbDisplay(_INTL("The sunlight is extremely harsh.")) -# when :HeavyRain then pbDisplay(_INTL("It is raining heavily.")) -# when :StrongWinds then pbDisplay(_INTL("The wind is strong.")) - when :ShadowSky then pbDisplay(_INTL("The shadow sky continues.")) - end - # Effects due to weather - curWeather = pbWeather - priority.each do |b| - # Weather-related abilities - if b.abilityActive? - BattleHandlers.triggerEORWeatherAbility(b.ability,curWeather,b,self) - b.pbFaint if b.fainted? - end - # Weather damage - # NOTE: - case curWeather - when :Sandstorm - next if !b.takesSandstormDamage? - pbDisplay(_INTL("{1} is buffeted by the sandstorm!",b.pbThis)) - @scene.pbDamageAnimation(b) - b.pbReduceHP(b.totalhp/16,false) - b.pbItemHPHealCheck - b.pbFaint if b.fainted? - when :Hail - next if !b.takesHailDamage? - pbDisplay(_INTL("{1} is buffeted by the hail!",b.pbThis)) - @scene.pbDamageAnimation(b) - b.pbReduceHP(b.totalhp/16,false) - b.pbItemHPHealCheck - b.pbFaint if b.fainted? - when :ShadowSky - next if !b.takesShadowSkyDamage? - pbDisplay(_INTL("{1} is hurt by the shadow sky!",b.pbThis)) - @scene.pbDamageAnimation(b) - b.pbReduceHP(b.totalhp/16,false) - b.pbItemHPHealCheck - b.pbFaint if b.fainted? - end - end - end - - #============================================================================= - # End Of Round terrain - #============================================================================= - def pbEORTerrain - # Count down terrain duration - @field.terrainDuration -= 1 if @field.terrainDuration>0 - # Terrain wears off - if @field.terrain != :None && @field.terrainDuration == 0 - case @field.terrain - when :Electric - pbDisplay(_INTL("The electric current disappeared from the battlefield!")) - when :Grassy - pbDisplay(_INTL("The grass disappeared from the battlefield!")) - when :Misty - pbDisplay(_INTL("The mist disappeared from the battlefield!")) - when :Psychic - pbDisplay(_INTL("The weirdness disappeared from the battlefield!")) - end - @field.terrain = :None - # Start up the default terrain - pbStartTerrain(nil, @field.defaultTerrain, false) if @field.defaultTerrain != :None - return if @field.terrain == :None - end - # Terrain continues - terrain_data = GameData::BattleTerrain.try_get(@field.terrain) - pbCommonAnimation(terrain_data.animation) if terrain_data - case @field.terrain - when :Electric then pbDisplay(_INTL("An electric current is running across the battlefield.")) - when :Grassy then pbDisplay(_INTL("Grass is covering the battlefield.")) - when :Misty then pbDisplay(_INTL("Mist is swirling about the battlefield.")) - when :Psychic then pbDisplay(_INTL("The battlefield is weird.")) - end - end - - #============================================================================= - # End Of Round shift distant battlers to middle positions - #============================================================================= - def pbEORShiftDistantBattlers - # Move battlers around if none are near to each other - # NOTE: This code assumes each side has a maximum of 3 battlers on it, and - # is not generalised to larger side sizes. - if !singleBattle? - swaps = [] # Each element is an array of two battler indices to swap - for side in 0...2 - next if pbSideSize(side)==1 # Only battlers on sides of size 2+ need to move - # Check if any battler on this side is near any battler on the other side - anyNear = false - eachSameSideBattler(side) do |b| - eachOtherSideBattler(b) do |otherB| - next if !nearBattlers?(otherB.index,b.index) - anyNear = true - break - end - break if anyNear - end - break if anyNear - # No battlers on this side are near any battlers on the other side; try - # to move them - # NOTE: If we get to here (assuming both sides are of size 3 or less), - # there is definitely only 1 able battler on this side, so we - # don't need to worry about multiple battlers trying to move into - # the same position. If you add support for a side of size 4+, - # this code will need revising to account for that, as well as to - # add more complex code to ensure battlers will end up near each - # other. - eachSameSideBattler(side) do |b| - # Get the position to move to - pos = -1 - case pbSideSize(side) - when 2 then pos = [2,3,0,1][b.index] # The unoccupied position - when 3 then pos = (side==0) ? 2 : 3 # The centre position - end - next if pos<0 - # Can't move if the same trainer doesn't control both positions - idxOwner = pbGetOwnerIndexFromBattlerIndex(b.index) - next if pbGetOwnerIndexFromBattlerIndex(pos)!=idxOwner - swaps.push([b.index,pos]) - end - end - # Move battlers around - swaps.each do |pair| - next if pbSideSize(pair[0])==2 && swaps.length>1 - next if !pbSwapBattlers(pair[0],pair[1]) - case pbSideSize(side) - when 2 - pbDisplay(_INTL("{1} moved across!",@battlers[pair[1]].pbThis)) - when 3 - pbDisplay(_INTL("{1} moved to the center!",@battlers[pair[1]].pbThis)) - end - end - end - end - - #============================================================================= - # End Of Round phase - #============================================================================= - def pbEndOfRoundPhase - PBDebug.log("") - PBDebug.log("[End of round]") - @endOfRound = true - @scene.pbBeginEndOfRoundPhase - pbCalculatePriority # recalculate speeds - priority = pbPriority(true) # in order of fastest -> slowest speeds only - # Weather - pbEORWeather(priority) - # Future Sight/Doom Desire - @positions.each_with_index do |pos,idxPos| - next if !pos || pos.effects[PBEffects::FutureSightCounter]==0 - pos.effects[PBEffects::FutureSightCounter] -= 1 - next if pos.effects[PBEffects::FutureSightCounter]>0 - next if !@battlers[idxPos] || @battlers[idxPos].fainted? # No target - moveUser = nil - eachBattler do |b| - next if b.opposes?(pos.effects[PBEffects::FutureSightUserIndex]) - next if b.pokemonIndex!=pos.effects[PBEffects::FutureSightUserPartyIndex] - moveUser = b - break - end - next if moveUser && moveUser.index==idxPos # Target is the user - if !moveUser # User isn't in battle, get it from the party - party = pbParty(pos.effects[PBEffects::FutureSightUserIndex]) - pkmn = party[pos.effects[PBEffects::FutureSightUserPartyIndex]] - if pkmn && pkmn.able? - moveUser = PokeBattle_Battler.new(self,pos.effects[PBEffects::FutureSightUserIndex]) - moveUser.pbInitDummyPokemon(pkmn,pos.effects[PBEffects::FutureSightUserPartyIndex]) - end - end - next if !moveUser # User is fainted - move = pos.effects[PBEffects::FutureSightMove] - pbDisplay(_INTL("{1} took the {2} attack!",@battlers[idxPos].pbThis, - GameData::Move.get(move).name)) - # NOTE: Future Sight failing against the target here doesn't count towards - # Stomping Tantrum. - userLastMoveFailed = moveUser.lastMoveFailed - @futureSight = true - moveUser.pbUseMoveSimple(move,idxPos) - @futureSight = false - moveUser.lastMoveFailed = userLastMoveFailed - @battlers[idxPos].pbFaint if @battlers[idxPos].fainted? - pos.effects[PBEffects::FutureSightCounter] = 0 - pos.effects[PBEffects::FutureSightMove] = nil - pos.effects[PBEffects::FutureSightUserIndex] = -1 - pos.effects[PBEffects::FutureSightUserPartyIndex] = -1 - end - # Wish - @positions.each_with_index do |pos,idxPos| - next if !pos || pos.effects[PBEffects::Wish]==0 - pos.effects[PBEffects::Wish] -= 1 - next if pos.effects[PBEffects::Wish]>0 - next if !@battlers[idxPos] || !@battlers[idxPos].canHeal? - wishMaker = pbThisEx(idxPos,pos.effects[PBEffects::WishMaker]) - @battlers[idxPos].pbRecoverHP(pos.effects[PBEffects::WishAmount]) - pbDisplay(_INTL("{1}'s wish came true!",wishMaker)) - end - # Sea of Fire damage (Fire Pledge + Grass Pledge combination) - curWeather = pbWeather - for side in 0...2 - next if sides[side].effects[PBEffects::SeaOfFire]==0 - next if [:Rain, :HeavyRain].include?(curWeather) - @battle.pbCommonAnimation("SeaOfFire") if side==0 - @battle.pbCommonAnimation("SeaOfFireOpp") if side==1 - priority.each do |b| - next if b.opposes?(side) - next if !b.takesIndirectDamage? || b.pbHasType?(:FIRE) - oldHP = b.hp - @scene.pbDamageAnimation(b) - b.pbReduceHP(b.totalhp/8,false) - pbDisplay(_INTL("{1} is hurt by the sea of fire!",b.pbThis)) - b.pbItemHPHealCheck - b.pbAbilitiesOnDamageTaken(oldHP) - b.pbFaint if b.fainted? - end - end - # Status-curing effects/abilities and HP-healing items - priority.each do |b| - next if b.fainted? - # Grassy Terrain (healing) - if @field.terrain == :Grassy && b.affectedByTerrain? && b.canHeal? - PBDebug.log("[Lingering effect] Grassy Terrain heals #{b.pbThis(true)}") - b.pbRecoverHP(b.totalhp/16) - pbDisplay(_INTL("{1}'s HP was restored.",b.pbThis)) - end - # Healer, Hydration, Shed Skin - BattleHandlers.triggerEORHealingAbility(b.ability,b,self) if b.abilityActive? - # Black Sludge, Leftovers - BattleHandlers.triggerEORHealingItem(b.item,b,self) if b.itemActive? - end - # Aqua Ring - priority.each do |b| - next if !b.effects[PBEffects::AquaRing] - next if !b.canHeal? - hpGain = b.totalhp/16 - hpGain = (hpGain*1.3).floor if b.hasActiveItem?(:BIGROOT) - b.pbRecoverHP(hpGain) - pbDisplay(_INTL("Aqua Ring restored {1}'s HP!",b.pbThis(true))) - end - # Ingrain - priority.each do |b| - next if !b.effects[PBEffects::Ingrain] - next if !b.canHeal? - hpGain = b.totalhp/16 - hpGain = (hpGain*1.3).floor if b.hasActiveItem?(:BIGROOT) - b.pbRecoverHP(hpGain) - pbDisplay(_INTL("{1} absorbed nutrients with its roots!",b.pbThis)) - end - # Leech Seed - priority.each do |b| - next if b.effects[PBEffects::LeechSeed]<0 - next if !b.takesIndirectDamage? - recipient = @battlers[b.effects[PBEffects::LeechSeed]] - next if !recipient || recipient.fainted? - oldHP = b.hp - oldHPRecipient = recipient.hp - pbCommonAnimation("LeechSeed",recipient,b) - hpLoss = b.pbReduceHP(b.totalhp/8) - recipient.pbRecoverHPFromDrain(hpLoss,b, - _INTL("{1}'s health is sapped by Leech Seed!",b.pbThis)) - recipient.pbAbilitiesOnDamageTaken(oldHPRecipient) if recipient.hp0 - b.effects[PBEffects::Toxic] += 1 - b.effects[PBEffects::Toxic] = 15 if b.effects[PBEffects::Toxic]>15 - end - if b.hasActiveAbility?(:POISONHEAL) - if b.canHeal? - anim_name = GameData::Status.get(:POISON).animation - pbCommonAnimation(anim_name, b) if anim_name - pbShowAbilitySplash(b) - b.pbRecoverHP(b.totalhp/8) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - pbDisplay(_INTL("{1}'s HP was restored.",b.pbThis)) - else - pbDisplay(_INTL("{1}'s {2} restored its HP.",b.pbThis,b.abilityName)) - end - pbHideAbilitySplash(b) - end - elsif b.takesIndirectDamage? - oldHP = b.hp - dmg = (b.statusCount==0) ? b.totalhp/8 : b.totalhp*b.effects[PBEffects::Toxic]/16 - b.pbContinueStatus { b.pbReduceHP(dmg,false) } - b.pbItemHPHealCheck - b.pbAbilitiesOnDamageTaken(oldHP) - b.pbFaint if b.fainted? - end - end - # Damage from burn - priority.each do |b| - next if b.status != :BURN || !b.takesIndirectDamage? - oldHP = b.hp - dmg = (Settings::MECHANICS_GENERATION >= 7) ? b.totalhp/16 : b.totalhp/8 - dmg = (dmg/2.0).round if b.hasActiveAbility?(:HEATPROOF) - b.pbContinueStatus { b.pbReduceHP(dmg,false) } - b.pbItemHPHealCheck - b.pbAbilitiesOnDamageTaken(oldHP) - b.pbFaint if b.fainted? - end - # Damage from sleep (Nightmare) - priority.each do |b| - b.effects[PBEffects::Nightmare] = false if !b.asleep? - next if !b.effects[PBEffects::Nightmare] || !b.takesIndirectDamage? - oldHP = b.hp - b.pbReduceHP(b.totalhp/4) - pbDisplay(_INTL("{1} is locked in a nightmare!",b.pbThis)) - b.pbItemHPHealCheck - b.pbAbilitiesOnDamageTaken(oldHP) - b.pbFaint if b.fainted? - end - # Curse - priority.each do |b| - next if !b.effects[PBEffects::Curse] || !b.takesIndirectDamage? - oldHP = b.hp - b.pbReduceHP(b.totalhp/4) - pbDisplay(_INTL("{1} is afflicted by the curse!",b.pbThis)) - b.pbItemHPHealCheck - b.pbAbilitiesOnDamageTaken(oldHP) - b.pbFaint if b.fainted? - end - # Trapping attacks (Bind/Clamp/Fire Spin/Magma Storm/Sand Tomb/Whirlpool/Wrap) - priority.each do |b| - next if b.fainted? || b.effects[PBEffects::Trapping]==0 - b.effects[PBEffects::Trapping] -= 1 - moveName = GameData::Move.get(b.effects[PBEffects::TrappingMove]).name - if b.effects[PBEffects::Trapping]==0 - pbDisplay(_INTL("{1} was freed from {2}!",b.pbThis,moveName)) - else - case b.effects[PBEffects::TrappingMove] - when :BIND then pbCommonAnimation("Bind", b) - when :CLAMP then pbCommonAnimation("Clamp", b) - when :FIRESPIN then pbCommonAnimation("FireSpin", b) - when :MAGMASTORM then pbCommonAnimation("MagmaStorm", b) - when :SANDTOMB then pbCommonAnimation("SandTomb", b) - when :WRAP then pbCommonAnimation("Wrap", b) - when :INFESTATION then pbCommonAnimation("Infestation", b) - else pbCommonAnimation("Wrap", b) - end - if b.takesIndirectDamage? - hpLoss = (Settings::MECHANICS_GENERATION >= 6) ? b.totalhp/8 : b.totalhp/16 - if @battlers[b.effects[PBEffects::TrappingUser]].hasActiveItem?(:BINDINGBAND) - hpLoss = (Settings::MECHANICS_GENERATION >= 6) ? b.totalhp/6 : b.totalhp/8 - end - @scene.pbDamageAnimation(b) - b.pbReduceHP(hpLoss,false) - pbDisplay(_INTL("{1} is hurt by {2}!",b.pbThis,moveName)) - b.pbItemHPHealCheck - # NOTE: No need to call pbAbilitiesOnDamageTaken as b can't switch out. - b.pbFaint if b.fainted? - end - end - end - # Taunt - pbEORCountDownBattlerEffect(priority,PBEffects::Taunt) { |battler| - pbDisplay(_INTL("{1}'s taunt wore off!",battler.pbThis)) - } - # Encore - priority.each do |b| - next if b.fainted? || b.effects[PBEffects::Encore]==0 - idxEncoreMove = b.pbEncoredMoveIndex - if idxEncoreMove>=0 - b.effects[PBEffects::Encore] -= 1 - if b.effects[PBEffects::Encore]==0 || b.moves[idxEncoreMove].pp==0 - b.effects[PBEffects::Encore] = 0 - pbDisplay(_INTL("{1}'s encore ended!",b.pbThis)) - end - else - PBDebug.log("[End of effect] #{b.pbThis}'s encore ended (encored move no longer known)") - b.effects[PBEffects::Encore] = 0 - b.effects[PBEffects::EncoreMove] = nil - end - end - # Disable/Cursed Body - pbEORCountDownBattlerEffect(priority,PBEffects::Disable) { |battler| - battler.effects[PBEffects::DisableMove] = nil - pbDisplay(_INTL("{1} is no longer disabled!",battler.pbThis)) - } - # Magnet Rise - pbEORCountDownBattlerEffect(priority,PBEffects::MagnetRise) { |battler| - pbDisplay(_INTL("{1}'s electromagnetism wore off!",battler.pbThis)) - } - # Telekinesis - pbEORCountDownBattlerEffect(priority,PBEffects::Telekinesis) { |battler| - pbDisplay(_INTL("{1} was freed from the telekinesis!",battler.pbThis)) - } - # Heal Block - pbEORCountDownBattlerEffect(priority,PBEffects::HealBlock) { |battler| - pbDisplay(_INTL("{1}'s Heal Block wore off!",battler.pbThis)) - } - # Embargo - pbEORCountDownBattlerEffect(priority,PBEffects::Embargo) { |battler| - pbDisplay(_INTL("{1} can use items again!",battler.pbThis)) - battler.pbItemTerrainStatBoostCheck - } - # Yawn - pbEORCountDownBattlerEffect(priority,PBEffects::Yawn) { |battler| - if battler.pbCanSleepYawn? - PBDebug.log("[Lingering effect] #{battler.pbThis} fell asleep because of Yawn") - battler.pbSleep - end - } - # Perish Song - perishSongUsers = [] - priority.each do |b| - next if b.fainted? || b.effects[PBEffects::PerishSong]==0 - b.effects[PBEffects::PerishSong] -= 1 - pbDisplay(_INTL("{1}'s perish count fell to {2}!",b.pbThis,b.effects[PBEffects::PerishSong])) - if b.effects[PBEffects::PerishSong]==0 - perishSongUsers.push(b.effects[PBEffects::PerishSongUser]) - b.pbReduceHP(b.hp) - end - b.pbItemHPHealCheck - b.pbFaint if b.fainted? - end - if perishSongUsers.length>0 - # If all remaining Pokemon fainted by a Perish Song triggered by a single side - if (perishSongUsers.find_all { |idxBattler| opposes?(idxBattler) }.length==perishSongUsers.length) || - (perishSongUsers.find_all { |idxBattler| !opposes?(idxBattler) }.length==perishSongUsers.length) - pbJudgeCheckpoint(@battlers[perishSongUsers[0]]) - end - end - # Check for end of battle - if @decision>0 - pbGainExp - return - end - for side in 0...2 - # Reflect - pbEORCountDownSideEffect(side,PBEffects::Reflect, - _INTL("{1}'s Reflect wore off!",@battlers[side].pbTeam)) - # Light Screen - pbEORCountDownSideEffect(side,PBEffects::LightScreen, - _INTL("{1}'s Light Screen wore off!",@battlers[side].pbTeam)) - # Safeguard - pbEORCountDownSideEffect(side,PBEffects::Safeguard, - _INTL("{1} is no longer protected by Safeguard!",@battlers[side].pbTeam)) - # Mist - pbEORCountDownSideEffect(side,PBEffects::Mist, - _INTL("{1} is no longer protected by mist!",@battlers[side].pbTeam)) - # Tailwind - pbEORCountDownSideEffect(side,PBEffects::Tailwind, - _INTL("{1}'s Tailwind petered out!",@battlers[side].pbTeam)) - # Lucky Chant - pbEORCountDownSideEffect(side,PBEffects::LuckyChant, - _INTL("{1}'s Lucky Chant wore off!",@battlers[side].pbTeam)) - # Pledge Rainbow - pbEORCountDownSideEffect(side,PBEffects::Rainbow, - _INTL("The rainbow on {1}'s side disappeared!",@battlers[side].pbTeam(true))) - # Pledge Sea of Fire - pbEORCountDownSideEffect(side,PBEffects::SeaOfFire, - _INTL("The sea of fire around {1} disappeared!",@battlers[side].pbTeam(true))) - # Pledge Swamp - pbEORCountDownSideEffect(side,PBEffects::Swamp, - _INTL("The swamp around {1} disappeared!",@battlers[side].pbTeam(true))) - # Aurora Veil - pbEORCountDownSideEffect(side,PBEffects::AuroraVeil, - _INTL("{1}'s Aurora Veil wore off!",@battlers[side].pbTeam(true))) - end - # Trick Room - pbEORCountDownFieldEffect(PBEffects::TrickRoom, - _INTL("The twisted dimensions returned to normal!")) - # Gravity - pbEORCountDownFieldEffect(PBEffects::Gravity, - _INTL("Gravity returned to normal!")) - # Water Sport - pbEORCountDownFieldEffect(PBEffects::WaterSportField, - _INTL("The effects of Water Sport have faded.")) - # Mud Sport - pbEORCountDownFieldEffect(PBEffects::MudSportField, - _INTL("The effects of Mud Sport have faded.")) - # Wonder Room - pbEORCountDownFieldEffect(PBEffects::WonderRoom, - _INTL("Wonder Room wore off, and Defense and Sp. Def stats returned to normal!")) - # Magic Room - pbEORCountDownFieldEffect(PBEffects::MagicRoom, - _INTL("Magic Room wore off, and held items' effects returned to normal!")) - # End of terrains - pbEORTerrain - priority.each do |b| - next if b.fainted? - # Hyper Mode (Shadow Pokémon) - if b.inHyperMode? - if pbRandom(100)<10 - b.pokemon.hyper_mode = false - b.pokemon.adjustHeart(-50) - pbDisplay(_INTL("{1} came to its senses!",b.pbThis)) - else - pbDisplay(_INTL("{1} is in Hyper Mode!",b.pbThis)) - end - end - # Uproar - if b.effects[PBEffects::Uproar]>0 - b.effects[PBEffects::Uproar] -= 1 - if b.effects[PBEffects::Uproar]==0 - pbDisplay(_INTL("{1} calmed down.",b.pbThis)) - else - pbDisplay(_INTL("{1} is making an uproar!",b.pbThis)) - end - end - # Slow Start's end message - if b.effects[PBEffects::SlowStart]>0 - b.effects[PBEffects::SlowStart] -= 1 - if b.effects[PBEffects::SlowStart]==0 - pbDisplay(_INTL("{1} finally got its act together!",b.pbThis)) - end - end - # Bad Dreams, Moody, Speed Boost - BattleHandlers.triggerEOREffectAbility(b.ability,b,self) if b.abilityActive? - # Flame Orb, Sticky Barb, Toxic Orb - BattleHandlers.triggerEOREffectItem(b.item,b,self) if b.itemActive? - # Harvest, Pickup - BattleHandlers.triggerEORGainItemAbility(b.ability,b,self) if b.abilityActive? - end - pbGainExp - return if @decision>0 - # Form checks - priority.each { |b| b.pbCheckForm(true) } - # Switch Pokémon in if possible - pbEORSwitch - return if @decision>0 - # In battles with at least one side of size 3+, move battlers around if none - # are near to any foes - pbEORShiftDistantBattlers - # Try to make Trace work, check for end of primordial weather - priority.each { |b| b.pbContinualAbilityChecks } - # Reset/count down battler-specific effects (no messages) - eachBattler do |b| - b.effects[PBEffects::BanefulBunker] = false - b.effects[PBEffects::Charge] -= 1 if b.effects[PBEffects::Charge]>0 - b.effects[PBEffects::Counter] = -1 - b.effects[PBEffects::CounterTarget] = -1 - b.effects[PBEffects::Electrify] = false - b.effects[PBEffects::Endure] = false - b.effects[PBEffects::FirstPledge] = 0 - b.effects[PBEffects::Flinch] = false - b.effects[PBEffects::FocusPunch] = false - b.effects[PBEffects::FollowMe] = 0 - b.effects[PBEffects::HelpingHand] = false - b.effects[PBEffects::HyperBeam] -= 1 if b.effects[PBEffects::HyperBeam]>0 - b.effects[PBEffects::KingsShield] = false - b.effects[PBEffects::LaserFocus] -= 1 if b.effects[PBEffects::LaserFocus]>0 - if b.effects[PBEffects::LockOn]>0 # Also Mind Reader - b.effects[PBEffects::LockOn] -= 1 - b.effects[PBEffects::LockOnPos] = -1 if b.effects[PBEffects::LockOn]==0 - end - b.effects[PBEffects::MagicBounce] = false - b.effects[PBEffects::MagicCoat] = false - b.effects[PBEffects::MirrorCoat] = -1 - b.effects[PBEffects::MirrorCoatTarget] = -1 - b.effects[PBEffects::Powder] = false - b.effects[PBEffects::Prankster] = false - b.effects[PBEffects::PriorityAbility] = false - b.effects[PBEffects::PriorityItem] = false - b.effects[PBEffects::Protect] = false - b.effects[PBEffects::RagePowder] = false - b.effects[PBEffects::Roost] = false - b.effects[PBEffects::Snatch] = 0 - b.effects[PBEffects::SpikyShield] = false - b.effects[PBEffects::Spotlight] = 0 - b.effects[PBEffects::ThroatChop] -= 1 if b.effects[PBEffects::ThroatChop]>0 - b.lastHPLost = 0 - b.lastHPLostFromFoe = 0 - b.tookDamage = false - b.tookPhysicalHit = false - b.lastRoundMoveFailed = b.lastMoveFailed - b.lastAttacker.clear - b.lastFoeAttacker.clear - end - # Reset/count down side-specific effects (no messages) - for side in 0...2 - @sides[side].effects[PBEffects::CraftyShield] = false - if !@sides[side].effects[PBEffects::EchoedVoiceUsed] - @sides[side].effects[PBEffects::EchoedVoiceCounter] = 0 - end - @sides[side].effects[PBEffects::EchoedVoiceUsed] = false - @sides[side].effects[PBEffects::MatBlock] = false - @sides[side].effects[PBEffects::QuickGuard] = false - @sides[side].effects[PBEffects::Round] = false - @sides[side].effects[PBEffects::WideGuard] = false - end - # Reset/count down field-specific effects (no messages) - @field.effects[PBEffects::IonDeluge] = false - @field.effects[PBEffects::FairyLock] -= 1 if @field.effects[PBEffects::FairyLock]>0 - @field.effects[PBEffects::FusionBolt] = false - @field.effects[PBEffects::FusionFlare] = false - @endOfRound = false - end -end diff --git a/Data/Scripts/011_Battle/003_BattleHandlers_Abilities.rb b/Data/Scripts/011_Battle/003_BattleHandlers_Abilities.rb deleted file mode 100644 index 0d76a08fa..000000000 --- a/Data/Scripts/011_Battle/003_BattleHandlers_Abilities.rb +++ /dev/null @@ -1,2426 +0,0 @@ -#=============================================================================== -# SpeedCalcAbility handlers -#=============================================================================== - -BattleHandlers::SpeedCalcAbility.add(:CHLOROPHYLL, - proc { |ability,battler,mult| - next mult * 2 if [:Sun, :HarshSun].include?(battler.battle.pbWeather) - } -) - -BattleHandlers::SpeedCalcAbility.add(:QUICKFEET, - proc { |ability,battler,mult| - next mult*1.5 if battler.pbHasAnyStatus? - } -) - -BattleHandlers::SpeedCalcAbility.add(:SANDRUSH, - proc { |ability,battler,mult| - next mult * 2 if [:Sandstorm].include?(battler.battle.pbWeather) - } -) - -BattleHandlers::SpeedCalcAbility.add(:SLOWSTART, - proc { |ability,battler,mult| - next mult/2 if battler.effects[PBEffects::SlowStart]>0 - } -) - -BattleHandlers::SpeedCalcAbility.add(:SLUSHRUSH, - proc { |ability,battler,mult| - next mult * 2 if [:Hail].include?(battler.battle.pbWeather) - } -) - -BattleHandlers::SpeedCalcAbility.add(:SURGESURFER, - proc { |ability,battler,mult| - next mult*2 if battler.battle.field.terrain == :Electric - } -) - -BattleHandlers::SpeedCalcAbility.add(:SWIFTSWIM, - proc { |ability,battler,mult| - next mult * 2 if [:Rain, :HeavyRain].include?(battler.battle.pbWeather) - } -) - -BattleHandlers::SpeedCalcAbility.add(:UNBURDEN, - proc { |ability,battler,mult| - next mult*2 if battler.effects[PBEffects::Unburden] && !battler.item - } -) - -#=============================================================================== -# WeightCalcAbility handlers -#=============================================================================== - -BattleHandlers::WeightCalcAbility.add(:HEAVYMETAL, - proc { |ability,battler,w| - next w*2 - } -) - -BattleHandlers::WeightCalcAbility.add(:LIGHTMETAL, - proc { |ability,battler,w| - next [w/2,1].max - } -) - -#=============================================================================== -# AbilityOnHPDroppedBelowHalf handlers -#=============================================================================== - -BattleHandlers::AbilityOnHPDroppedBelowHalf.add(:EMERGENCYEXIT, - proc { |ability,battler,battle| - next false if battler.effects[PBEffects::SkyDrop]>=0 || battler.inTwoTurnAttack?("0CE") # Sky Drop - # In wild battles - if battle.wildBattle? - next false if battler.opposes? && battle.pbSideBattlerCount(battler.index)>1 - next false if !battle.pbCanRun?(battler.index) - battle.pbShowAbilitySplash(battler,true) - battle.pbHideAbilitySplash(battler) - pbSEPlay("Battle flee") - battle.pbDisplay(_INTL("{1} fled from battle!",battler.pbThis)) - battle.decision = 3 # Escaped - next true - end - # In trainer battles - next false if battle.pbAllFainted?(battler.idxOpposingSide) - next false if !battle.pbCanSwitch?(battler.index) # Battler can't switch out - next false if !battle.pbCanChooseNonActive?(battler.index) # No Pokémon can switch in - battle.pbShowAbilitySplash(battler,true) - battle.pbHideAbilitySplash(battler) - if !PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("{1}'s {2} activated!",battler.pbThis,battler.abilityName)) - end - battle.pbDisplay(_INTL("{1} went back to {2}!", - battler.pbThis,battle.pbGetOwnerName(battler.index))) - if battle.endOfRound # Just switch out - battle.scene.pbRecall(battler.index) if !battler.fainted? - battler.pbAbilitiesOnSwitchOut # Inc. primordial weather check - next true - end - newPkmn = battle.pbGetReplacementPokemonIndex(battler.index) # Owner chooses - next false if newPkmn<0 # Shouldn't ever do this - battle.pbRecallAndReplace(battler.index,newPkmn) - battle.pbClearChoice(battler.index) # Replacement Pokémon does nothing this round - next true - } -) - -BattleHandlers::AbilityOnHPDroppedBelowHalf.copy(:EMERGENCYEXIT,:WIMPOUT) - -#=============================================================================== -# StatusCheckAbilityNonIgnorable handlers -#=============================================================================== - -BattleHandlers::StatusCheckAbilityNonIgnorable.add(:COMATOSE, - proc { |ability,battler,status| - next false if !battler.isSpecies?(:KOMALA) - next true if status.nil? || status == :SLEEP - } -) - -#=============================================================================== -# StatusImmunityAbility handlers -#=============================================================================== - -BattleHandlers::StatusImmunityAbility.add(:FLOWERVEIL, - proc { |ability,battler,status| - next true if battler.pbHasType?(:GRASS) - } -) - -BattleHandlers::StatusImmunityAbility.add(:IMMUNITY, - proc { |ability,battler,status| - next true if status == :POISON - } -) - -BattleHandlers::StatusImmunityAbility.add(:INSOMNIA, - proc { |ability,battler,status| - next true if status == :SLEEP - } -) - -BattleHandlers::StatusImmunityAbility.copy(:INSOMNIA,:SWEETVEIL,:VITALSPIRIT) - -BattleHandlers::StatusImmunityAbility.add(:LEAFGUARD, - proc { |ability,battler,status| - next true if [:Sun, :HarshSun].include?(battler.battle.pbWeather) - } -) - -BattleHandlers::StatusImmunityAbility.add(:LIMBER, - proc { |ability,battler,status| - next true if status == :PARALYSIS - } -) - -BattleHandlers::StatusImmunityAbility.add(:MAGMAARMOR, - proc { |ability,battler,status| - next true if status == :FROZEN - } -) - -BattleHandlers::StatusImmunityAbility.add(:WATERVEIL, - proc { |ability,battler,status| - next true if status == :BURN - } -) - -BattleHandlers::StatusImmunityAbility.copy(:WATERVEIL,:WATERBUBBLE) - -#=============================================================================== -# StatusImmunityAbilityNonIgnorable handlers -#=============================================================================== - -BattleHandlers::StatusImmunityAbilityNonIgnorable.add(:COMATOSE, - proc { |ability,battler,status| - next true if battler.isSpecies?(:KOMALA) - } -) - -BattleHandlers::StatusImmunityAbilityNonIgnorable.add(:SHIELDSDOWN, - proc { |ability,battler,status| - next true if battler.isFusionOf(:MINIOR_C) && battler.form<7 - } -) - -#=============================================================================== -# StatusImmunityAllyAbility handlers -#=============================================================================== - -BattleHandlers::StatusImmunityAllyAbility.add(:FLOWERVEIL, - proc { |ability,battler,status| - next true if battler.pbHasType?(:GRASS) - } -) - -BattleHandlers::StatusImmunityAbility.add(:SWEETVEIL, - proc { |ability,battler,status| - next true if status == :SLEEP - } -) - -#=============================================================================== -# AbilityOnStatusInflicted handlers -#=============================================================================== - -BattleHandlers::AbilityOnStatusInflicted.add(:SYNCHRONIZE, - proc { |ability,battler,user,status| - next if !user || user.index==battler.index - case status - when :POISON - if user.pbCanPoisonSynchronize?(battler) - battler.battle.pbShowAbilitySplash(battler) - msg = nil - if !PokeBattle_SceneConstants::USE_ABILITY_SPLASH - msg = _INTL("{1}'s {2} poisoned {3}!",battler.pbThis,battler.abilityName,user.pbThis(true)) - end - user.pbPoison(nil,msg,(battler.statusCount>0)) - battler.battle.pbHideAbilitySplash(battler) - end - when :BURN - if user.pbCanBurnSynchronize?(battler) - battler.battle.pbShowAbilitySplash(battler) - msg = nil - if !PokeBattle_SceneConstants::USE_ABILITY_SPLASH - msg = _INTL("{1}'s {2} burned {3}!",battler.pbThis,battler.abilityName,user.pbThis(true)) - end - user.pbBurn(nil,msg) - battler.battle.pbHideAbilitySplash(battler) - end - when :PARALYSIS - if user.pbCanParalyzeSynchronize?(battler) - battler.battle.pbShowAbilitySplash(battler) - msg = nil - if !PokeBattle_SceneConstants::USE_ABILITY_SPLASH - msg = _INTL("{1}'s {2} paralyzed {3}! It may be unable to move!", - battler.pbThis,battler.abilityName,user.pbThis(true)) - end - user.pbParalyze(nil,msg) - battler.battle.pbHideAbilitySplash(battler) - end - end - } -) - -#=============================================================================== -# StatusCureAbility handlers -#=============================================================================== - -BattleHandlers::StatusCureAbility.add(:IMMUNITY, - proc { |ability,battler| - next if battler.status != :POISON - battler.battle.pbShowAbilitySplash(battler) - battler.pbCureStatus(PokeBattle_SceneConstants::USE_ABILITY_SPLASH) - if !PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battler.battle.pbDisplay(_INTL("{1}'s {2} cured its poisoning!",battler.pbThis,battler.abilityName)) - end - battler.battle.pbHideAbilitySplash(battler) - } -) - -BattleHandlers::StatusCureAbility.add(:INSOMNIA, - proc { |ability,battler| - next if battler.status != :SLEEP - battler.battle.pbShowAbilitySplash(battler) - battler.pbCureStatus(PokeBattle_SceneConstants::USE_ABILITY_SPLASH) - if !PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battler.battle.pbDisplay(_INTL("{1}'s {2} woke it up!",battler.pbThis,battler.abilityName)) - end - battler.battle.pbHideAbilitySplash(battler) - } -) - -BattleHandlers::StatusCureAbility.copy(:INSOMNIA,:VITALSPIRIT) - -BattleHandlers::StatusCureAbility.add(:LIMBER, - proc { |ability,battler| - next if battler.status != :PARALYSIS - battler.battle.pbShowAbilitySplash(battler) - battler.pbCureStatus(PokeBattle_SceneConstants::USE_ABILITY_SPLASH) - if !PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battler.battle.pbDisplay(_INTL("{1}'s {2} cured its paralysis!",battler.pbThis,battler.abilityName)) - end - battler.battle.pbHideAbilitySplash(battler) - } -) - -BattleHandlers::StatusCureAbility.add(:MAGMAARMOR, - proc { |ability,battler| - next if battler.status != :FROZEN - battler.battle.pbShowAbilitySplash(battler) - battler.pbCureStatus(PokeBattle_SceneConstants::USE_ABILITY_SPLASH) - if !PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battler.battle.pbDisplay(_INTL("{1}'s {2} defrosted it!",battler.pbThis,battler.abilityName)) - end - battler.battle.pbHideAbilitySplash(battler) - } -) - -BattleHandlers::StatusCureAbility.add(:OBLIVIOUS, - proc { |ability,battler| - next if battler.effects[PBEffects::Attract]<0 && - (battler.effects[PBEffects::Taunt]==0 || Settings::MECHANICS_GENERATION <= 5) - battler.battle.pbShowAbilitySplash(battler) - if battler.effects[PBEffects::Attract]>=0 - battler.pbCureAttract - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battler.battle.pbDisplay(_INTL("{1} got over its infatuation.",battler.pbThis)) - else - battler.battle.pbDisplay(_INTL("{1}'s {2} cured its infatuation status!", - battler.pbThis,battler.abilityName)) - end - end - if battler.effects[PBEffects::Taunt]>0 && Settings::MECHANICS_GENERATION >= 6 - battler.effects[PBEffects::Taunt] = 0 - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battler.battle.pbDisplay(_INTL("{1}'s Taunt wore off!",battler.pbThis)) - else - battler.battle.pbDisplay(_INTL("{1}'s {2} made its taunt wear off!", - battler.pbThis,battler.abilityName)) - end - end - battler.battle.pbHideAbilitySplash(battler) - } -) - -BattleHandlers::StatusCureAbility.add(:OWNTEMPO, - proc { |ability,battler| - next if battler.effects[PBEffects::Confusion]==0 - battler.battle.pbShowAbilitySplash(battler) - battler.pbCureConfusion - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battler.battle.pbDisplay(_INTL("{1} snapped out of its confusion.",battler.pbThis)) - else - battler.battle.pbDisplay(_INTL("{1}'s {2} snapped it out of its confusion!", - battler.pbThis,battler.abilityName)) - end - battler.battle.pbHideAbilitySplash(battler) - } -) - -BattleHandlers::StatusCureAbility.add(:WATERVEIL, - proc { |ability,battler| - next if battler.status != :BURN - battler.battle.pbShowAbilitySplash(battler) - battler.pbCureStatus(PokeBattle_SceneConstants::USE_ABILITY_SPLASH) - if !PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battler.battle.pbDisplay(_INTL("{1}'s {2} healed its burn!",battler.pbThis,battler.abilityName)) - end - battler.battle.pbHideAbilitySplash(battler) - } -) - -BattleHandlers::StatusCureAbility.copy(:WATERVEIL,:WATERBUBBLE) - -#=============================================================================== -# StatLossImmunityAbility handlers -#=============================================================================== - -BattleHandlers::StatLossImmunityAbility.add(:BIGPECKS, - proc { |ability,battler,stat,battle,showMessages| - next false if stat!=:DEFENSE - if showMessages - battle.pbShowAbilitySplash(battler) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("{1}'s {2} cannot be lowered!",battler.pbThis,GameData::Stat.get(stat).name)) - else - battle.pbDisplay(_INTL("{1}'s {2} prevents {3} loss!",battler.pbThis, - battler.abilityName,GameData::Stat.get(stat).name)) - end - battle.pbHideAbilitySplash(battler) - end - next true - } -) - -BattleHandlers::StatLossImmunityAbility.add(:CLEARBODY, - proc { |ability,battler,stat,battle,showMessages| - if showMessages - battle.pbShowAbilitySplash(battler) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("{1}'s stats cannot be lowered!",battler.pbThis)) - else - battle.pbDisplay(_INTL("{1}'s {2} prevents stat loss!",battler.pbThis,battler.abilityName)) - end - battle.pbHideAbilitySplash(battler) - end - next true - } -) - -BattleHandlers::StatLossImmunityAbility.copy(:CLEARBODY,:WHITESMOKE) - -BattleHandlers::StatLossImmunityAbility.add(:FLOWERVEIL, - proc { |ability,battler,stat,battle,showMessages| - next false if !battler.pbHasType?(:GRASS) - if showMessages - battle.pbShowAbilitySplash(battler) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("{1}'s stats cannot be lowered!",battler.pbThis)) - else - battle.pbDisplay(_INTL("{1}'s {2} prevents stat loss!",battler.pbThis,battler.abilityName)) - end - battle.pbHideAbilitySplash(battler) - end - next true - } -) - -BattleHandlers::StatLossImmunityAbility.add(:HYPERCUTTER, - proc { |ability,battler,stat,battle,showMessages| - next false if stat!=:ATTACK - if showMessages - battle.pbShowAbilitySplash(battler) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("{1}'s {2} cannot be lowered!",battler.pbThis,GameData::Stat.get(stat).name)) - else - battle.pbDisplay(_INTL("{1}'s {2} prevents {3} loss!",battler.pbThis, - battler.abilityName,GameData::Stat.get(stat).name)) - end - battle.pbHideAbilitySplash(battler) - end - next true - } -) - -BattleHandlers::StatLossImmunityAbility.add(:KEENEYE, - proc { |ability,battler,stat,battle,showMessages| - next false if stat!=:ACCURACY - if showMessages - battle.pbShowAbilitySplash(battler) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("{1}'s {2} cannot be lowered!",battler.pbThis,GameData::Stat.get(stat).name)) - else - battle.pbDisplay(_INTL("{1}'s {2} prevents {3} loss!",battler.pbThis, - battler.abilityName,GameData::Stat.get(stat).name)) - end - battle.pbHideAbilitySplash(battler) - end - next true - } -) - -#=============================================================================== -# StatLossImmunityAbilityNonIgnorable handlers -#=============================================================================== - -BattleHandlers::StatLossImmunityAbilityNonIgnorable.add(:FULLMETALBODY, - proc { |ability,battler,stat,battle,showMessages| - if showMessages - battle.pbShowAbilitySplash(battler) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("{1}'s stats cannot be lowered!",battler.pbThis)) - else - battle.pbDisplay(_INTL("{1}'s {2} prevents stat loss!",battler.pbThis,battler.abilityName)) - end - battle.pbHideAbilitySplash(battler) - end - next true - } -) - -#=============================================================================== -# StatLossImmunityAllyAbility handlers -#=============================================================================== - -BattleHandlers::StatLossImmunityAllyAbility.add(:FLOWERVEIL, - proc { |ability,bearer,battler,stat,battle,showMessages| - next false if !battler.pbHasType?(:GRASS) - if showMessages - battle.pbShowAbilitySplash(bearer) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("{1}'s stats cannot be lowered!",battler.pbThis)) - else - battle.pbDisplay(_INTL("{1}'s {2} prevents {3}'s stat loss!", - bearer.pbThis,bearer.abilityName,battler.pbThis(true))) - end - battle.pbHideAbilitySplash(bearer) - end - next true - } -) - -#=============================================================================== -# AbilityOnStatGain handlers -#=============================================================================== - -# There aren't any! - -#=============================================================================== -# AbilityOnStatLoss handlers -#=============================================================================== - -BattleHandlers::AbilityOnStatLoss.add(:COMPETITIVE, - proc { |ability,battler,stat,user| - next if user && !user.opposes?(battler) - battler.pbRaiseStatStageByAbility(:SPECIAL_ATTACK,2,battler,GameData::Ability.get(ability).real_name) - } -) - -BattleHandlers::AbilityOnStatLoss.add(:DEFIANT, - proc { |ability,battler,stat,user| - next if user && !user.opposes?(battler) - battler.pbRaiseStatStageByAbility(:ATTACK,2,battler,GameData::Ability.get(ability).real_name) - } -) - -#=============================================================================== -# PriorityChangeAbility handlers -#=============================================================================== - -BattleHandlers::PriorityChangeAbility.add(:GALEWINGS, - proc { |ability,battler,move,pri| - next pri+1 if battler.hp==battler.totalhp && move.type == :FLYING - } -) - -BattleHandlers::PriorityChangeAbility.add(:PRANKSTER, - proc { |ability,battler,move,pri| - if move.statusMove? - battler.effects[PBEffects::Prankster] = true - next pri+1 - end - } -) - -BattleHandlers::PriorityChangeAbility.add(:TRIAGE, - proc { |ability,battler,move,pri| - next pri+3 if move.healingMove? - } -) - -#=============================================================================== -# PriorityBracketChangeAbility handlers -#=============================================================================== - -BattleHandlers::PriorityBracketChangeAbility.add(:STALL, - proc { |ability,battler,subPri,battle| - next -1 if subPri==0 - } -) - -#=============================================================================== -# PriorityBracketUseAbility handlers -#=============================================================================== - -# There aren't any! - -#=============================================================================== -# AbilityOnFlinch handlers -#=============================================================================== - -BattleHandlers::AbilityOnFlinch.add(:STEADFAST, - proc { |ability,battler,battle| - battler.pbRaiseStatStageByAbility(:SPEED,1,battler,GameData::Ability.get(ability).real_name) - } -) - -#=============================================================================== -# MoveBlockingAbility handlers -#=============================================================================== - -BattleHandlers::MoveBlockingAbility.add(:DAZZLING, - proc { |ability,bearer,user,targets,move,battle| - next false if battle.choices[user.index][4]<=0 - next false if !bearer.opposes?(user) - ret = false - targets.each do |b| - next if !b.opposes?(user) - ret = true - end - next ret - } -) - -BattleHandlers::MoveBlockingAbility.copy(:DAZZLING,:QUEENLYMAJESTY) - -#=============================================================================== -# MoveImmunityTargetAbility handlers -#=============================================================================== - -BattleHandlers::MoveImmunityTargetAbility.add(:BULLETPROOF, - proc { |ability,user,target,move,type,battle| - next false if !move.bombMove? - battle.pbShowAbilitySplash(target) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("It doesn't affect {1}...",target.pbThis(true))) - else - battle.pbDisplay(_INTL("{1}'s {2} made {3} ineffective!", - target.pbThis,target.abilityName,move.name)) - end - battle.pbHideAbilitySplash(target) - next true - } -) - -BattleHandlers::MoveImmunityTargetAbility.add(:FLASHFIRE, - proc { |ability,user,target,move,type,battle| - next false if user.index==target.index - next false if type != :FIRE - battle.pbShowAbilitySplash(target) - if !target.effects[PBEffects::FlashFire] - target.effects[PBEffects::FlashFire] = true - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("The power of {1}'s Fire-type moves rose!",target.pbThis(true))) - else - battle.pbDisplay(_INTL("The power of {1}'s Fire-type moves rose because of its {2}!", - target.pbThis(true),target.abilityName)) - end - else - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("It doesn't affect {1}...",target.pbThis(true))) - else - battle.pbDisplay(_INTL("{1}'s {2} made {3} ineffective!", - target.pbThis,target.abilityName,move.name)) - end - end - battle.pbHideAbilitySplash(target) - next true - } -) - -BattleHandlers::MoveImmunityTargetAbility.add(:LIGHTNINGROD, - proc { |ability,user,target,move,type,battle| - next pbBattleMoveImmunityStatAbility(user,target,move,type,:ELECTRIC,:SPECIAL_ATTACK,1,battle) - } -) - -BattleHandlers::MoveImmunityTargetAbility.add(:MOTORDRIVE, - proc { |ability,user,target,move,type,battle| - next pbBattleMoveImmunityStatAbility(user,target,move,type,:ELECTRIC,:SPEED,1,battle) - } -) - -BattleHandlers::MoveImmunityTargetAbility.add(:SAPSIPPER, - proc { |ability,user,target,move,type,battle| - next pbBattleMoveImmunityStatAbility(user,target,move,type,:GRASS,:ATTACK,1,battle) - } -) - -BattleHandlers::MoveImmunityTargetAbility.add(:SOUNDPROOF, - proc { |ability,user,target,move,type,battle| - next false if !move.soundMove? - battle.pbShowAbilitySplash(target) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("It doesn't affect {1}...",target.pbThis(true))) - else - battle.pbDisplay(_INTL("{1}'s {2} blocks {3}!",target.pbThis,target.abilityName,move.name)) - end - battle.pbHideAbilitySplash(target) - next true - - } -) - -BattleHandlers::MoveImmunityTargetAbility.add(:STORMDRAIN, - proc { |ability,user,target,move,type,battle| - next pbBattleMoveImmunityStatAbility(user,target,move,type,:WATER,:SPECIAL_ATTACK,1,battle) - } -) - -BattleHandlers::MoveImmunityTargetAbility.add(:TELEPATHY, - proc { |ability,user,target,move,type,battle| - next false if move.statusMove? - next false if user.index==target.index || target.opposes?(user) - battle.pbShowAbilitySplash(target) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("{1} avoids attacks by its ally Pokémon!",target.pbThis(true))) - else - battle.pbDisplay(_INTL("{1} avoids attacks by its ally Pokémon with {2}!", - target.pbThis,target.abilityName)) - end - battle.pbHideAbilitySplash(target) - next true - } -) - -BattleHandlers::MoveImmunityTargetAbility.add(:VOLTABSORB, - proc { |ability,user,target,move,type,battle| - next pbBattleMoveImmunityHealAbility(user,target,move,type,:ELECTRIC,battle) - } -) - -BattleHandlers::MoveImmunityTargetAbility.add(:WATERABSORB, - proc { |ability,user,target,move,type,battle| - next pbBattleMoveImmunityHealAbility(user,target,move,type,:WATER,battle) - } -) - -BattleHandlers::MoveImmunityTargetAbility.copy(:WATERABSORB,:DRYSKIN) - -BattleHandlers::MoveImmunityTargetAbility.add(:WONDERGUARD, - proc { |ability,user,target,move,type,battle| - next false if move.statusMove? - next false if !type || Effectiveness.super_effective?(target.damageState.typeMod) - battle.pbShowAbilitySplash(target) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("It doesn't affect {1}...",target.pbThis(true))) - else - battle.pbDisplay(_INTL("{1} avoided damage with {2}!",target.pbThis,target.abilityName)) - end - battle.pbHideAbilitySplash(target) - next true - } -) - -#=============================================================================== -# MoveBaseTypeModifierAbility handlers -#=============================================================================== - -BattleHandlers::MoveBaseTypeModifierAbility.add(:AERILATE, - proc { |ability,user,move,type| - next if type != :NORMAL || !GameData::Type.exists?(:FLYING) - move.powerBoost = true - next :FLYING - } -) - -BattleHandlers::MoveBaseTypeModifierAbility.add(:GALVANIZE, - proc { |ability,user,move,type| - next if type != :NORMAL || !GameData::Type.exists?(:ELECTRIC) - move.powerBoost = true - next :ELECTRIC - } -) - -BattleHandlers::MoveBaseTypeModifierAbility.add(:LIQUIDVOICE, - proc { |ability,user,move,type| - next :WATER if GameData::Type.exists?(:WATER) && move.soundMove? - } -) - -BattleHandlers::MoveBaseTypeModifierAbility.add(:NORMALIZE, - proc { |ability,user,move,type| - next if !GameData::Type.exists?(:NORMAL) - move.powerBoost = true if Settings::MECHANICS_GENERATION >= 7 - next :NORMAL - } -) - -BattleHandlers::MoveBaseTypeModifierAbility.add(:PIXILATE, - proc { |ability,user,move,type| - next if type != :NORMAL || !GameData::Type.exists?(:FAIRY) - move.powerBoost = true - next :FAIRY - } -) - -BattleHandlers::MoveBaseTypeModifierAbility.add(:REFRIGERATE, - proc { |ability,user,move,type| - next if type != :NORMAL || !GameData::Type.exists?(:ICE) - move.powerBoost = true - next :ICE - } -) - -#=============================================================================== -# AccuracyCalcUserAbility handlers -#=============================================================================== - -BattleHandlers::AccuracyCalcUserAbility.add(:COMPOUNDEYES, - proc { |ability,mods,user,target,move,type| - mods[:accuracy_multiplier] *= 1.3 - } -) - -BattleHandlers::AccuracyCalcUserAbility.add(:HUSTLE, - proc { |ability,mods,user,target,move,type| - mods[:accuracy_multiplier] *= 0.8 if move.physicalMove? - } -) - -BattleHandlers::AccuracyCalcUserAbility.add(:KEENEYE, - proc { |ability,mods,user,target,move,type| - mods[:evasion_stage] = 0 if mods[:evasion_stage] > 0 && Settings::MECHANICS_GENERATION >= 6 - } -) - -BattleHandlers::AccuracyCalcUserAbility.add(:NOGUARD, - proc { |ability,mods,user,target,move,type| - mods[:base_accuracy] = 0 - } -) - -BattleHandlers::AccuracyCalcUserAbility.add(:UNAWARE, - proc { |ability,mods,user,target,move,type| - mods[:evasion_stage] = 0 if move.damagingMove? - } -) - -BattleHandlers::AccuracyCalcUserAbility.add(:VICTORYSTAR, - proc { |ability,mods,user,target,move,type| - mods[:accuracy_multiplier] *= 1.1 - } -) - -#=============================================================================== -# AccuracyCalcUserAllyAbility handlers -#=============================================================================== - -BattleHandlers::AccuracyCalcUserAllyAbility.add(:VICTORYSTAR, - proc { |ability,mods,user,target,move,type| - mods[:accuracy_multiplier] *= 1.1 - } -) - -#=============================================================================== -# AccuracyCalcTargetAbility handlers -#=============================================================================== - -BattleHandlers::AccuracyCalcTargetAbility.add(:LIGHTNINGROD, - proc { |ability,mods,user,target,move,type| - mods[:base_accuracy] = 0 if type == :ELECTRIC - } -) - -BattleHandlers::AccuracyCalcTargetAbility.add(:NOGUARD, - proc { |ability,mods,user,target,move,type| - mods[:base_accuracy] = 0 - } -) - -BattleHandlers::AccuracyCalcTargetAbility.add(:SANDVEIL, - proc { |ability,mods,user,target,move,type| - mods[:evasion_multiplier] *= 1.25 if target.battle.pbWeather == :Sandstorm - } -) - -BattleHandlers::AccuracyCalcTargetAbility.add(:SNOWCLOAK, - proc { |ability,mods,user,target,move,type| - mods[:evasion_multiplier] *= 1.25 if target.battle.pbWeather == :Hail - } -) - -BattleHandlers::AccuracyCalcTargetAbility.add(:STORMDRAIN, - proc { |ability,mods,user,target,move,type| - mods[:base_accuracy] = 0 if type == :WATER - } -) - -BattleHandlers::AccuracyCalcTargetAbility.add(:TANGLEDFEET, - proc { |ability,mods,user,target,move,type| - mods[:accuracy_multiplier] /= 2 if target.effects[PBEffects::Confusion] > 0 - } -) - -BattleHandlers::AccuracyCalcTargetAbility.add(:UNAWARE, - proc { |ability,mods,user,target,move,type| - mods[:accuracy_stage] = 0 if move.damagingMove? - } -) - -BattleHandlers::AccuracyCalcTargetAbility.add(:WONDERSKIN, - proc { |ability,mods,user,target,move,type| - if move.statusMove? && user.opposes?(target) - mods[:base_accuracy] = 50 if mods[:base_accuracy] > 50 - end - } -) - -#=============================================================================== -# DamageCalcUserAbility handlers -#=============================================================================== - -BattleHandlers::DamageCalcUserAbility.add(:AERILATE, - proc { |ability,user,target,move,mults,baseDmg,type| - mults[:base_damage_multiplier] *= 1.2 if move.powerBoost - } -) - -BattleHandlers::DamageCalcUserAbility.copy(:AERILATE,:PIXILATE,:REFRIGERATE,:GALVANIZE) - -BattleHandlers::DamageCalcUserAbility.add(:ANALYTIC, - proc { |ability,user,target,move,mults,baseDmg,type| - if (target.battle.choices[target.index][0]!=:UseMove && - target.battle.choices[target.index][0]!=:Shift) || - target.movedThisRound? - mults[:base_damage_multiplier] *= 1.3 - end - } -) - -BattleHandlers::DamageCalcUserAbility.add(:BLAZE, - proc { |ability,user,target,move,mults,baseDmg,type| - if user.hp <= user.totalhp / 3 && type == :FIRE - mults[:attack_multiplier] *= 1.5 - end - } -) - -BattleHandlers::DamageCalcUserAbility.add(:DEFEATIST, - proc { |ability,user,target,move,mults,baseDmg,type| - mults[:attack_multiplier] /= 2 if user.hp <= user.totalhp / 2 - } -) - -BattleHandlers::DamageCalcUserAbility.add(:FLAREBOOST, - proc { |ability,user,target,move,mults,baseDmg,type| - if user.burned? && move.specialMove? - mults[:base_damage_multiplier] *= 1.5 - end - } -) - -BattleHandlers::DamageCalcUserAbility.add(:FLASHFIRE, - proc { |ability,user,target,move,mults,baseDmg,type| - if user.effects[PBEffects::FlashFire] && type == :FIRE - mults[:attack_multiplier] *= 1.5 - end - } -) - -BattleHandlers::DamageCalcUserAbility.add(:FLOWERGIFT, - proc { |ability,user,target,move,mults,baseDmg,type| - if move.physicalMove? && [:Sun, :HarshSun].include?(user.battle.pbWeather) - mults[:attack_multiplier] *= 1.5 - end - } -) - -BattleHandlers::DamageCalcUserAbility.add(:GUTS, - proc { |ability,user,target,move,mults,baseDmg,type| - if user.pbHasAnyStatus? && move.physicalMove? - mults[:attack_multiplier] *= 1.5 - end - } -) - -BattleHandlers::DamageCalcUserAbility.add(:HUGEPOWER, - proc { |ability,user,target,move,mults,baseDmg,type| - mults[:attack_multiplier] *= 2 if move.physicalMove? - } -) - -BattleHandlers::DamageCalcUserAbility.copy(:HUGEPOWER,:PUREPOWER) - -BattleHandlers::DamageCalcUserAbility.add(:HUSTLE, - proc { |ability,user,target,move,mults,baseDmg,type| - mults[:attack_multiplier] *= 1.5 if move.physicalMove? - } -) - -BattleHandlers::DamageCalcUserAbility.add(:IRONFIST, - proc { |ability,user,target,move,mults,baseDmg,type| - mults[:base_damage_multiplier] *= 1.2 if move.punchingMove? - } -) - -BattleHandlers::DamageCalcUserAbility.add(:MEGALAUNCHER, - proc { |ability,user,target,move,mults,baseDmg,type| - mults[:base_damage_multiplier] *= 1.5 if move.pulseMove? - } -) - -BattleHandlers::DamageCalcUserAbility.add(:MINUS, - proc { |ability,user,target,move,mults,baseDmg,type| - next if !move.specialMove? - user.eachAlly do |b| - next if !b.hasActiveAbility?([:MINUS, :PLUS]) - mults[:attack_multiplier] *= 1.5 - break - end - } -) - -BattleHandlers::DamageCalcUserAbility.copy(:MINUS,:PLUS) - -BattleHandlers::DamageCalcUserAbility.add(:NEUROFORCE, - proc { |ability,user,target,move,mults,baseDmg,type| - if Effectiveness.super_effective?(target.damageState.typeMod) - mults[:final_damage_multiplier] *= 1.25 - end - } -) - -BattleHandlers::DamageCalcUserAbility.add(:OVERGROW, - proc { |ability,user,target,move,mults,baseDmg,type| - if user.hp <= user.totalhp / 3 && type == :GRASS - mults[:attack_multiplier] *= 1.5 - end - } -) - -BattleHandlers::DamageCalcUserAbility.add(:RECKLESS, - proc { |ability,user,target,move,mults,baseDmg,type| - mults[:base_damage_multiplier] *= 1.2 if move.recoilMove? - } -) - -BattleHandlers::DamageCalcUserAbility.add(:RIVALRY, - proc { |ability,user,target,move,mults,baseDmg,type| - if user.gender!=2 && target.gender!=2 - if user.gender==target.gender - mults[:base_damage_multiplier] *= 1.25 - else - mults[:base_damage_multiplier] *= 0.75 - end - end - } -) - -BattleHandlers::DamageCalcUserAbility.add(:SANDFORCE, - proc { |ability,user,target,move,mults,baseDmg,type| - if user.battle.pbWeather == :Sandstorm && - [:ROCK, :GROUND, :STEEL].include?(type) - mults[:base_damage_multiplier] *= 1.3 - end - } -) - -BattleHandlers::DamageCalcUserAbility.add(:SHEERFORCE, - proc { |ability,user,target,move,mults,baseDmg,type| - mults[:base_damage_multiplier] *= 1.3 if move.addlEffect > 0 - } -) - -BattleHandlers::DamageCalcUserAbility.add(:SLOWSTART, - proc { |ability,user,target,move,mults,baseDmg,type| - mults[:attack_multiplier] /= 2 if user.effects[PBEffects::SlowStart] > 0 && move.physicalMove? - } -) - -BattleHandlers::DamageCalcUserAbility.add(:SOLARPOWER, - proc { |ability,user,target,move,mults,baseDmg,type| - if move.specialMove? && [:Sun, :HarshSun].include?(user.battle.pbWeather) - mults[:attack_multiplier] *= 1.5 - end - } -) - -BattleHandlers::DamageCalcUserAbility.add(:SNIPER, - proc { |ability,user,target,move,mults,baseDmg,type| - if target.damageState.critical - mults[:final_damage_multiplier] *= 1.5 - end - } -) - -BattleHandlers::DamageCalcUserAbility.add(:STAKEOUT, - proc { |ability,user,target,move,mults,baseDmg,type| - mults[:attack_multiplier] *= 2 if target.battle.choices[target.index][0] == :SwitchOut - } -) - -BattleHandlers::DamageCalcUserAbility.add(:STEELWORKER, - proc { |ability,user,target,move,mults,baseDmg,type| - mults[:attack_multiplier] *= 1.5 if type == :STEEL - } -) - -BattleHandlers::DamageCalcUserAbility.add(:STRONGJAW, - proc { |ability,user,target,move,mults,baseDmg,type| - mults[:base_damage_multiplier] *= 1.5 if move.bitingMove? - } -) - -BattleHandlers::DamageCalcUserAbility.add(:SWARM, - proc { |ability,user,target,move,mults,baseDmg,type| - if user.hp <= user.totalhp / 3 && type == :BUG - mults[:attack_multiplier] *= 1.5 - end - } -) - -BattleHandlers::DamageCalcUserAbility.add(:TECHNICIAN, - proc { |ability,user,target,move,mults,baseDmg,type| - if user.index != target.index && move && move.id != :STRUGGLE && - baseDmg * mults[:base_damage_multiplier] <= 60 - mults[:base_damage_multiplier] *= 1.5 - end - } -) - -BattleHandlers::DamageCalcUserAbility.add(:TINTEDLENS, - proc { |ability,user,target,move,mults,baseDmg,type| - mults[:final_damage_multiplier] *= 2 if Effectiveness.resistant?(target.damageState.typeMod) - } -) - -BattleHandlers::DamageCalcUserAbility.add(:TORRENT, - proc { |ability,user,target,move,mults,baseDmg,type| - if user.hp <= user.totalhp / 3 && type == :WATER - mults[:attack_multiplier] *= 1.5 - end - } -) - -BattleHandlers::DamageCalcUserAbility.add(:TOUGHCLAWS, - proc { |ability,user,target,move,mults,baseDmg,type| - mults[:base_damage_multiplier] *= 4 / 3.0 if move.contactMove? - } -) - -BattleHandlers::DamageCalcUserAbility.add(:TOXICBOOST, - proc { |ability,user,target,move,mults,baseDmg,type| - if user.poisoned? && move.physicalMove? - mults[:base_damage_multiplier] *= 1.5 - end - } -) - -BattleHandlers::DamageCalcUserAbility.add(:WATERBUBBLE, - proc { |ability,user,target,move,mults,baseDmg,type| - mults[:attack_multiplier] *= 2 if type == :WATER - } -) - -#=============================================================================== -# DamageCalcUserAllyAbility handlers -#=============================================================================== - -BattleHandlers::DamageCalcUserAllyAbility.add(:BATTERY, - proc { |ability,user,target,move,mults,baseDmg,type| - next if !move.specialMove? - mults[:final_damage_multiplier] *= 1.3 - } -) - -BattleHandlers::DamageCalcUserAllyAbility.add(:FLOWERGIFT, - proc { |ability,user,target,move,mults,baseDmg,type| - if move.physicalMove? && [:Sun, :HarshSun].include?(user.battle.pbWeather) - mults[:attack_multiplier] *= 1.5 - end - } -) - -#=============================================================================== -# DamageCalcTargetAbility handlers -#=============================================================================== - -BattleHandlers::DamageCalcTargetAbility.add(:DRYSKIN, - proc { |ability,user,target,move,mults,baseDmg,type| - mults[:base_damage_multiplier] *= 1.25 if type == :FIRE - } -) - -BattleHandlers::DamageCalcTargetAbility.add(:FILTER, - proc { |ability,user,target,move,mults,baseDmg,type| - if Effectiveness.super_effective?(target.damageState.typeMod) - mults[:final_damage_multiplier] *= 0.75 - end - } -) - -BattleHandlers::DamageCalcTargetAbility.copy(:FILTER,:SOLIDROCK) - -BattleHandlers::DamageCalcTargetAbility.add(:FLOWERGIFT, - proc { |ability,user,target,move,mults,baseDmg,type| - if move.specialMove? && [:Sun, :HarshSun].include?(user.battle.pbWeather) - mults[:defense_multiplier] *= 1.5 - end - } -) - -BattleHandlers::DamageCalcTargetAbility.add(:FLUFFY, - proc { |ability,user,target,move,mults,baseDmg,type| - mults[:final_damage_multiplier] *= 2 if move.calcType == :FIRE - mults[:final_damage_multiplier] /= 2 if move.contactMove? - } -) - -BattleHandlers::DamageCalcTargetAbility.add(:FURCOAT, - proc { |ability,user,target,move,mults,baseDmg,type| - mults[:defense_multiplier] *= 2 if move.physicalMove? || move.function == "122" # Psyshock - } -) - -BattleHandlers::DamageCalcTargetAbility.add(:GRASSPELT, - proc { |ability,user,target,move,mults,baseDmg,type| - if user.battle.field.terrain == :Grassy - mults[:defense_multiplier] *= 1.5 - end - } -) - -BattleHandlers::DamageCalcTargetAbility.add(:HEATPROOF, - proc { |ability,user,target,move,mults,baseDmg,type| - mults[:base_damage_multiplier] /= 2 if type == :FIRE - } -) - -BattleHandlers::DamageCalcTargetAbility.add(:MARVELSCALE, - proc { |ability,user,target,move,mults,baseDmg,type| - if target.pbHasAnyStatus? && move.physicalMove? - mults[:defense_multiplier] *= 1.5 - end - } -) - -BattleHandlers::DamageCalcTargetAbility.add(:MULTISCALE, - proc { |ability,user,target,move,mults,baseDmg,type| - mults[:final_damage_multiplier] /= 2 if target.hp == target.totalhp - } -) - -BattleHandlers::DamageCalcTargetAbility.add(:THICKFAT, - proc { |ability,user,target,move,mults,baseDmg,type| - mults[:base_damage_multiplier] /= 2 if type == :FIRE || type == :ICE - } -) - -BattleHandlers::DamageCalcTargetAbility.add(:WATERBUBBLE, - proc { |ability,user,target,move,mults,baseDmg,type| - mults[:final_damage_multiplier] /= 2 if type == :FIRE - } -) - -#=============================================================================== -# DamageCalcTargetAbilityNonIgnorable handlers -#=============================================================================== - -BattleHandlers::DamageCalcTargetAbilityNonIgnorable.add(:PRISMARMOR, - proc { |ability,user,target,move,mults,baseDmg,type| - if Effectiveness.super_effective?(target.damageState.typeMod) - mults[:final_damage_multiplier] *= 0.75 - end - } -) - -BattleHandlers::DamageCalcTargetAbilityNonIgnorable.add(:SHADOWSHIELD, - proc { |ability,user,target,move,mults,baseDmg,type| - if target.hp==target.totalhp - mults[:final_damage_multiplier] /= 2 - end - } -) - -#=============================================================================== -# DamageCalcTargetAllyAbility handlers -#=============================================================================== - -BattleHandlers::DamageCalcTargetAllyAbility.add(:FLOWERGIFT, - proc { |ability,user,target,move,mults,baseDmg,type| - if move.specialMove? && [:Sun, :HarshSun].include?(user.battle.pbWeather) - mults[:defense_multiplier] *= 1.5 - end - } -) - -BattleHandlers::DamageCalcTargetAllyAbility.add(:FRIENDGUARD, - proc { |ability,user,target,move,mults,baseDmg,type| - mults[:final_damage_multiplier] *= 0.75 - } -) - -#=============================================================================== -# CriticalCalcUserAbility handlers -#=============================================================================== - -BattleHandlers::CriticalCalcUserAbility.add(:MERCILESS, - proc { |ability,user,target,c| - next 99 if target.poisoned? - } -) - -BattleHandlers::CriticalCalcUserAbility.add(:SUPERLUCK, - proc { |ability,user,target,c| - next c+1 - } -) - -#=============================================================================== -# CriticalCalcTargetAbility handlers -#=============================================================================== - -BattleHandlers::CriticalCalcTargetAbility.add(:BATTLEARMOR, - proc { |ability,user,target,c| - next -1 - } -) - -BattleHandlers::CriticalCalcTargetAbility.copy(:BATTLEARMOR,:SHELLARMOR) - -#=============================================================================== -# TargetAbilityOnHit handlers -#=============================================================================== - -BattleHandlers::TargetAbilityOnHit.add(:AFTERMATH, - proc { |ability,user,target,move,battle| - next if !target.fainted? - next if !move.pbContactMove?(user) - battle.pbShowAbilitySplash(target) - if !battle.moldBreaker - dampBattler = battle.pbCheckGlobalAbility(:DAMP) - if dampBattler - battle.pbShowAbilitySplash(dampBattler) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("{1} cannot use {2}!",target.pbThis,target.abilityName)) - else - battle.pbDisplay(_INTL("{1} cannot use {2} because of {3}'s {4}!", - target.pbThis,target.abilityName,dampBattler.pbThis(true),dampBattler.abilityName)) - end - battle.pbHideAbilitySplash(dampBattler) - battle.pbHideAbilitySplash(target) - next - end - end - if user.takesIndirectDamage?(PokeBattle_SceneConstants::USE_ABILITY_SPLASH) && - user.affectedByContactEffect?(PokeBattle_SceneConstants::USE_ABILITY_SPLASH) - battle.scene.pbDamageAnimation(user) - user.pbReduceHP(user.totalhp/4,false) - battle.pbDisplay(_INTL("{1} was caught in the aftermath!",user.pbThis)) - end - battle.pbHideAbilitySplash(target) - } -) - -BattleHandlers::TargetAbilityOnHit.add(:ANGERPOINT, - proc { |ability,user,target,move,battle| - next if !target.damageState.critical - next if !target.pbCanRaiseStatStage?(:ATTACK,target) - battle.pbShowAbilitySplash(target) - target.stages[:ATTACK] = 6 - battle.pbCommonAnimation("StatUp",target) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("{1} maxed its {2}!",target.pbThis,GameData::Stat.get(:ATTACK).name)) - else - battle.pbDisplay(_INTL("{1}'s {2} maxed its {3}!", - target.pbThis,target.abilityName,GameData::Stat.get(:ATTACK).name)) - end - battle.pbHideAbilitySplash(target) - } -) - -BattleHandlers::TargetAbilityOnHit.add(:CURSEDBODY, - proc { |ability,user,target,move,battle| - next if user.fainted? - next if user.effects[PBEffects::Disable]>0 - regularMove = nil - user.eachMove do |m| - next if m.id!=user.lastRegularMoveUsed - regularMove = m - break - end - next if !regularMove || (regularMove.pp==0 && regularMove.total_pp>0) - next if battle.pbRandom(100)>=30 - battle.pbShowAbilitySplash(target) - if !move.pbMoveFailedAromaVeil?(target,user,PokeBattle_SceneConstants::USE_ABILITY_SPLASH) - user.effects[PBEffects::Disable] = 3 - user.effects[PBEffects::DisableMove] = regularMove.id - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("{1}'s {2} was disabled!",user.pbThis,regularMove.name)) - else - battle.pbDisplay(_INTL("{1}'s {2} was disabled by {3}'s {4}!", - user.pbThis,regularMove.name,target.pbThis(true),target.abilityName)) - end - battle.pbHideAbilitySplash(target) - user.pbItemStatusCureCheck - end - battle.pbHideAbilitySplash(target) - } -) - -BattleHandlers::TargetAbilityOnHit.add(:CUTECHARM, - proc { |ability,user,target,move,battle| - next if target.fainted? - next if !move.pbContactMove?(user) - next if battle.pbRandom(100)>=30 - battle.pbShowAbilitySplash(target) - if user.pbCanAttract?(target,PokeBattle_SceneConstants::USE_ABILITY_SPLASH) && - user.affectedByContactEffect?(PokeBattle_SceneConstants::USE_ABILITY_SPLASH) - msg = nil - if !PokeBattle_SceneConstants::USE_ABILITY_SPLASH - msg = _INTL("{1}'s {2} made {3} fall in love!",target.pbThis, - target.abilityName,user.pbThis(true)) - end - user.pbAttract(target,msg) - end - battle.pbHideAbilitySplash(target) - } -) - -BattleHandlers::TargetAbilityOnHit.add(:EFFECTSPORE, - proc { |ability,user,target,move,battle| - # NOTE: This ability has a 30% chance of triggering, not a 30% chance of - # inflicting a status condition. It can try (and fail) to inflict a - # status condition that the user is immune to. - next if !move.pbContactMove?(user) - next if battle.pbRandom(100)>=30 - r = battle.pbRandom(3) - next if r==0 && user.asleep? - next if r==1 && user.poisoned? - next if r==2 && user.paralyzed? - battle.pbShowAbilitySplash(target) - if user.affectedByPowder?(PokeBattle_SceneConstants::USE_ABILITY_SPLASH) && - user.affectedByContactEffect?(PokeBattle_SceneConstants::USE_ABILITY_SPLASH) - case r - when 0 - if user.pbCanSleep?(target,PokeBattle_SceneConstants::USE_ABILITY_SPLASH) - msg = nil - if !PokeBattle_SceneConstants::USE_ABILITY_SPLASH - msg = _INTL("{1}'s {2} made {3} fall asleep!",target.pbThis, - target.abilityName,user.pbThis(true)) - end - user.pbSleep(msg) - end - when 1 - if user.pbCanPoison?(target,PokeBattle_SceneConstants::USE_ABILITY_SPLASH) - msg = nil - if !PokeBattle_SceneConstants::USE_ABILITY_SPLASH - msg = _INTL("{1}'s {2} poisoned {3}!",target.pbThis, - target.abilityName,user.pbThis(true)) - end - user.pbPoison(target,msg) - end - when 2 - if user.pbCanParalyze?(target,PokeBattle_SceneConstants::USE_ABILITY_SPLASH) - msg = nil - if !PokeBattle_SceneConstants::USE_ABILITY_SPLASH - msg = _INTL("{1}'s {2} paralyzed {3}! It may be unable to move!", - target.pbThis,target.abilityName,user.pbThis(true)) - end - user.pbParalyze(target,msg) - end - end - end - battle.pbHideAbilitySplash(target) - } -) - -BattleHandlers::TargetAbilityOnHit.add(:FLAMEBODY, - proc { |ability,user,target,move,battle| - next if !move.pbContactMove?(user) - next if user.burned? || battle.pbRandom(100)>=30 - battle.pbShowAbilitySplash(target) - if user.pbCanBurn?(target,PokeBattle_SceneConstants::USE_ABILITY_SPLASH) && - user.affectedByContactEffect?(PokeBattle_SceneConstants::USE_ABILITY_SPLASH) - msg = nil - if !PokeBattle_SceneConstants::USE_ABILITY_SPLASH - msg = _INTL("{1}'s {2} burned {3}!",target.pbThis,target.abilityName,user.pbThis(true)) - end - user.pbBurn(target,msg) - end - battle.pbHideAbilitySplash(target) - } -) - -BattleHandlers::TargetAbilityOnHit.add(:GOOEY, - proc { |ability,user,target,move,battle| - next if !move.pbContactMove?(user) - user.pbLowerStatStageByAbility(:SPEED,1,target,true,true,GameData::Ability.get(ability).real_name) - } -) - -BattleHandlers::TargetAbilityOnHit.copy(:GOOEY,:TANGLINGHAIR) - -BattleHandlers::TargetAbilityOnHit.add(:ILLUSION, - proc { |ability,user,target,move,battle| - # NOTE: This intentionally doesn't show the ability splash. - next if !target.effects[PBEffects::Illusion] - target.effects[PBEffects::Illusion] = nil - battle.scene.pbChangePokemon(target,target.pokemon) - battle.pbDisplay(_INTL("{1}'s illusion wore off!",target.pbThis)) - battle.pbSetSeen(target) - } -) - -BattleHandlers::TargetAbilityOnHit.add(:INNARDSOUT, - proc { |ability,user,target,move,battle| - next if !target.fainted? || user.dummy - battle.pbShowAbilitySplash(target) - if user.takesIndirectDamage?(PokeBattle_SceneConstants::USE_ABILITY_SPLASH) - battle.scene.pbDamageAnimation(user) - user.pbReduceHP(target.damageState.hpLost,false) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("{1} is hurt!",user.pbThis)) - else - battle.pbDisplay(_INTL("{1} is hurt by {2}'s {3}!",user.pbThis, - target.pbThis(true),target.abilityName)) - end - end - battle.pbHideAbilitySplash(target) - } -) - -BattleHandlers::TargetAbilityOnHit.add(:IRONBARBS, - proc { |ability,user,target,move,battle| - next if !move.pbContactMove?(user) - battle.pbShowAbilitySplash(target) - if user.takesIndirectDamage?(PokeBattle_SceneConstants::USE_ABILITY_SPLASH) && - user.affectedByContactEffect?(PokeBattle_SceneConstants::USE_ABILITY_SPLASH) - battle.scene.pbDamageAnimation(user) - user.pbReduceHP(user.totalhp/8,false) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("{1} is hurt!",user.pbThis)) - else - battle.pbDisplay(_INTL("{1} is hurt by {2}'s {3}!",user.pbThis, - target.pbThis(true),target.abilityName)) - end - end - battle.pbHideAbilitySplash(target) - } -) - -BattleHandlers::TargetAbilityOnHit.copy(:IRONBARBS,:ROUGHSKIN) - -BattleHandlers::TargetAbilityOnHit.add(:JUSTIFIED, - proc { |ability,user,target,move,battle| - next if move.calcType != :DARK - target.pbRaiseStatStageByAbility(:ATTACK,1,target,GameData::Ability.get(ability).real_name) - } -) - -BattleHandlers::TargetAbilityOnHit.add(:MUMMY, - proc { |ability,user,target,move,battle| - next if !move.pbContactMove?(user) - next if user.fainted? - next if user.unstoppableAbility? || user.ability == ability - oldAbil = nil - battle.pbShowAbilitySplash(target) if user.opposes?(target) - if user.affectedByContactEffect?(PokeBattle_SceneConstants::USE_ABILITY_SPLASH) - oldAbil = user.ability - battle.pbShowAbilitySplash(user,true,false) if user.opposes?(target) - user.ability = ability - battle.pbReplaceAbilitySplash(user) if user.opposes?(target) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("{1}'s Ability became {2}!",user.pbThis,user.abilityName)) - else - battle.pbDisplay(_INTL("{1}'s Ability became {2} because of {3}!", - user.pbThis,user.abilityName,target.pbThis(true))) - end - battle.pbHideAbilitySplash(user) if user.opposes?(target) - end - battle.pbHideAbilitySplash(target) if user.opposes?(target) - user.pbOnAbilityChanged(oldAbil) if oldAbil != nil - } -) - -BattleHandlers::TargetAbilityOnHit.add(:POISONPOINT, - proc { |ability,user,target,move,battle| - next if !move.pbContactMove?(user) - next if user.poisoned? || battle.pbRandom(100)>=30 - battle.pbShowAbilitySplash(target) - if user.pbCanPoison?(target,PokeBattle_SceneConstants::USE_ABILITY_SPLASH) && - user.affectedByContactEffect?(PokeBattle_SceneConstants::USE_ABILITY_SPLASH) - msg = nil - if !PokeBattle_SceneConstants::USE_ABILITY_SPLASH - msg = _INTL("{1}'s {2} poisoned {3}!",target.pbThis,target.abilityName,user.pbThis(true)) - end - user.pbPoison(target,msg) - end - battle.pbHideAbilitySplash(target) - } -) - -BattleHandlers::TargetAbilityOnHit.add(:RATTLED, - proc { |ability,user,target,move,battle| - next if ![:BUG, :DARK, :GHOST].include?(move.calcType) - target.pbRaiseStatStageByAbility(:SPEED,1,target,GameData::Ability.get(ability).real_name) - } -) - -BattleHandlers::TargetAbilityOnHit.add(:STAMINA, - proc { |ability,user,target,move,battle| - target.pbRaiseStatStageByAbility(:DEFENSE,1,target,GameData::Ability.get(ability).real_name) - } -) - -BattleHandlers::TargetAbilityOnHit.add(:STATIC, - proc { |ability,user,target,move,battle| - next if !move.pbContactMove?(user) - next if user.paralyzed? || battle.pbRandom(100)>=30 - battle.pbShowAbilitySplash(target) - if user.pbCanParalyze?(target,PokeBattle_SceneConstants::USE_ABILITY_SPLASH) && - user.affectedByContactEffect?(PokeBattle_SceneConstants::USE_ABILITY_SPLASH) - msg = nil - if !PokeBattle_SceneConstants::USE_ABILITY_SPLASH - msg = _INTL("{1}'s {2} paralyzed {3}! It may be unable to move!", - target.pbThis,target.abilityName,user.pbThis(true)) - end - user.pbParalyze(target,msg) - end - battle.pbHideAbilitySplash(target) - } -) - -BattleHandlers::TargetAbilityOnHit.add(:WATERCOMPACTION, - proc { |ability,user,target,move,battle| - next if move.calcType != :WATER - target.pbRaiseStatStageByAbility(:DEFENSE,2,target,GameData::Ability.get(ability).real_name) - } -) - -BattleHandlers::TargetAbilityOnHit.add(:WEAKARMOR, - proc { |ability,user,target,move,battle| - next if !move.physicalMove? - next if !target.pbCanLowerStatStage?(:DEFENSE, target) && - !target.pbCanRaiseStatStage?(:SPEED, target) - battle.pbShowAbilitySplash(target) - target.pbLowerStatStageByAbility(:DEFENSE, 1, target, false,GameData::Ability.get(ability).real_name) - target.pbRaiseStatStageByAbility(:SPEED, - (Settings::MECHANICS_GENERATION >= 7) ? 2 : 1, target, false,GameData::Ability.get(ability).real_name) - battle.pbHideAbilitySplash(target) - } -) - -#=============================================================================== -# UserAbilityOnHit handlers -#=============================================================================== - -BattleHandlers::UserAbilityOnHit.add(:POISONTOUCH, - proc { |ability,user,target,move,battle| - next if !move.contactMove? - next if battle.pbRandom(100)>=30 - battle.pbShowAbilitySplash(user) - if target.hasActiveAbility?(:SHIELDDUST) && !battle.moldBreaker - battle.pbShowAbilitySplash(target) - if !PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("{1} is unaffected!",target.pbThis)) - end - battle.pbHideAbilitySplash(target) - elsif target.pbCanPoison?(user,PokeBattle_SceneConstants::USE_ABILITY_SPLASH) - msg = nil - if !PokeBattle_SceneConstants::USE_ABILITY_SPLASH - msg = _INTL("{1}'s {2} poisoned {3}!",user.pbThis,user.abilityName,target.pbThis(true)) - end - target.pbPoison(user,msg) - end - battle.pbHideAbilitySplash(user) - } -) - -#=============================================================================== -# UserAbilityEndOfMove handlers -#=============================================================================== - -BattleHandlers::UserAbilityEndOfMove.add(:BEASTBOOST, - proc { |ability,user,targets,move,battle| - next if battle.pbAllFainted?(user.idxOpposingSide) - numFainted = 0 - targets.each { |b| numFainted += 1 if b.damageState.fainted } - next if numFainted == 0 - userStats = user.plainStats - highestStatValue = 0 - userStats.each_value { |value| highestStatValue = value if highestStatValue < value } - GameData::Stat.each_main_battle do |s| - next if userStats[s.id] < highestStatValue - if user.pbCanRaiseStatStage?(s.id, user) - user.pbRaiseStatStageByAbility(s.id, numFainted, user,GameData::Ability.get(ability).real_name) - end - break - end - } -) - -BattleHandlers::UserAbilityEndOfMove.add(:MAGICIAN, - proc { |ability,user,targets,move,battle| - next if battle.futureSight - next if !move.pbDamagingMove? - next if user.item - next if battle.wildBattle? && user.opposes? - targets.each do |b| - next if b.damageState.unaffected || b.damageState.substitute - next if !b.item - next if b.unlosableItem?(b.item) || user.unlosableItem?(b.item) - battle.pbShowAbilitySplash(user) - if b.hasActiveAbility?(:STICKYHOLD) - battle.pbShowAbilitySplash(b) if user.opposes?(b) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("{1}'s item cannot be stolen!",b.pbThis)) - end - battle.pbHideAbilitySplash(b) if user.opposes?(b) - next - end - user.item = b.item - b.item = nil - b.effects[PBEffects::Unburden] = true - if battle.wildBattle? && !user.initialItem && b.initialItem==user.item - user.setInitialItem(user.item) - b.setInitialItem(nil) - end - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("{1} stole {2}'s {3}!",user.pbThis, - b.pbThis(true),user.itemName)) - else - battle.pbDisplay(_INTL("{1} stole {2}'s {3} with {4}!",user.pbThis, - b.pbThis(true),user.itemName,user.abilityName)) - end - battle.pbHideAbilitySplash(user) - user.pbHeldItemTriggerCheck - break - end - } -) - -BattleHandlers::UserAbilityEndOfMove.add(:MOXIE, - proc { |ability,user,targets,move,battle| - next if battle.pbAllFainted?(user.idxOpposingSide) - numFainted = 0 - targets.each { |b| numFainted += 1 if b.damageState.fainted } - next if numFainted==0 || !user.pbCanRaiseStatStage?(:ATTACK,user) - user.pbRaiseStatStageByAbility(:ATTACK,numFainted,user,GameData::Ability.get(ability).real_name) - } -) - -#=============================================================================== -# TargetAbilityAfterMoveUse handlers -#=============================================================================== - -BattleHandlers::TargetAbilityAfterMoveUse.add(:BERSERK, - proc { |ability,target,user,move,switched,battle| - next if !move.damagingMove? - next if target.damageState.initialHP=target.totalhp/2 - next if !target.pbCanRaiseStatStage?(:SPECIAL_ATTACK,target) - target.pbRaiseStatStageByAbility(:SPECIAL_ATTACK,1,target,GameData::Ability.get(ability).real_name) - } -) - -BattleHandlers::TargetAbilityAfterMoveUse.add(:COLORCHANGE, - proc { |ability,target,user,move,switched,battle| - next if target.damageState.calcDamage==0 || target.damageState.substitute - next if !move.calcType || GameData::Type.get(move.calcType).pseudo_type - next if target.pbHasType?(move.calcType) && !target.pbHasOtherType?(move.calcType) - typeName = GameData::Type.get(move.calcType).name - battle.pbShowAbilitySplash(target) - target.pbChangeTypes(move.calcType) - battle.pbDisplay(_INTL("{1}'s {2} made it the {3} type!",target.pbThis, - target.abilityName,typeName)) - battle.pbHideAbilitySplash(target) - } -) - -BattleHandlers::TargetAbilityAfterMoveUse.add(:PICKPOCKET, - proc { |ability,target,user,move,switched,battle| - # NOTE: According to Bulbapedia, this can still trigger to steal the user's - # item even if it was switched out by a Red Card. This doesn't make - # sense, so this code doesn't do it. - next if battle.wildBattle? && target.opposes? - next if !move.contactMove? - next if switched.include?(user.index) - next if user.effects[PBEffects::Substitute]>0 || target.damageState.substitute - next if target.item || !user.item - next if user.unlosableItem?(user.item) || target.unlosableItem?(user.item) - battle.pbShowAbilitySplash(target) - if user.hasActiveAbility?(:STICKYHOLD) - battle.pbShowAbilitySplash(user) if target.opposes?(user) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("{1}'s item cannot be stolen!",user.pbThis)) - end - battle.pbHideAbilitySplash(user) if target.opposes?(user) - battle.pbHideAbilitySplash(target) - next - end - target.item = user.item - user.item = nil - user.effects[PBEffects::Unburden] = true - if battle.wildBattle? && !target.initialItem && user.initialItem==target.item - target.setInitialItem(target.item) - user.setInitialItem(nil) - end - battle.pbDisplay(_INTL("{1} pickpocketed {2}'s {3}!",target.pbThis, - user.pbThis(true),target.itemName)) - battle.pbHideAbilitySplash(target) - target.pbHeldItemTriggerCheck - } -) - -#=============================================================================== -# EORWeatherAbility handlers -#=============================================================================== - -BattleHandlers::EORWeatherAbility.add(:DRYSKIN, - proc { |ability,weather,battler,battle| - case weather - when :Sun, :HarshSun - battle.pbShowAbilitySplash(battler) - battle.scene.pbDamageAnimation(battler) - battler.pbReduceHP(battler.totalhp/8,false) - battle.pbDisplay(_INTL("{1} was hurt by the sunlight!",battler.pbThis)) - battle.pbHideAbilitySplash(battler) - battler.pbItemHPHealCheck - when :Rain, :HeavyRain - next if !battler.canHeal? - battle.pbShowAbilitySplash(battler) - battler.pbRecoverHP(battler.totalhp/8) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("{1}'s HP was restored.",battler.pbThis)) - else - battle.pbDisplay(_INTL("{1}'s {2} restored its HP.",battler.pbThis,battler.abilityName)) - end - battle.pbHideAbilitySplash(battler) - end - } -) - -BattleHandlers::EORWeatherAbility.add(:ICEBODY, - proc { |ability,weather,battler,battle| - next unless weather == :Hail - next if !battler.canHeal? - battle.pbShowAbilitySplash(battler) - battler.pbRecoverHP(battler.totalhp/16) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("{1}'s HP was restored.",battler.pbThis)) - else - battle.pbDisplay(_INTL("{1}'s {2} restored its HP.",battler.pbThis,battler.abilityName)) - end - battle.pbHideAbilitySplash(battler) - } -) - -BattleHandlers::EORWeatherAbility.add(:RAINDISH, - proc { |ability,weather,battler,battle| - next unless [:Rain, :HeavyRain].include?(weather) - next if !battler.canHeal? - battle.pbShowAbilitySplash(battler) - battler.pbRecoverHP(battler.totalhp/16) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("{1}'s HP was restored.",battler.pbThis)) - else - battle.pbDisplay(_INTL("{1}'s {2} restored its HP.",battler.pbThis,battler.abilityName)) - end - battle.pbHideAbilitySplash(battler) - } -) - -BattleHandlers::EORWeatherAbility.add(:SOLARPOWER, - proc { |ability,weather,battler,battle| - next unless [:Sun, :HarshSun].include?(weather) - battle.pbShowAbilitySplash(battler) - battle.scene.pbDamageAnimation(battler) - battler.pbReduceHP(battler.totalhp/8,false) - battle.pbDisplay(_INTL("{1} was hurt by the sunlight!",battler.pbThis)) - battle.pbHideAbilitySplash(battler) - battler.pbItemHPHealCheck - } -) - -#=============================================================================== -# EORHealingAbility handlers -#=============================================================================== - -BattleHandlers::EORHealingAbility.add(:HEALER, - proc { |ability,battler,battle| - next unless battle.pbRandom(100)<30 - battler.eachAlly do |b| - next if b.status == :NONE - battle.pbShowAbilitySplash(battler) - oldStatus = b.status - b.pbCureStatus(PokeBattle_SceneConstants::USE_ABILITY_SPLASH) - if !PokeBattle_SceneConstants::USE_ABILITY_SPLASH - case oldStatus - when :SLEEP - battle.pbDisplay(_INTL("{1}'s {2} woke its partner up!",battler.pbThis,battler.abilityName)) - when :POISON - battle.pbDisplay(_INTL("{1}'s {2} cured its partner's poison!",battler.pbThis,battler.abilityName)) - when :BURN - battle.pbDisplay(_INTL("{1}'s {2} healed its partner's burn!",battler.pbThis,battler.abilityName)) - when :PARALYSIS - battle.pbDisplay(_INTL("{1}'s {2} cured its partner's paralysis!",battler.pbThis,battler.abilityName)) - when :FROZEN - battle.pbDisplay(_INTL("{1}'s {2} defrosted its partner!",battler.pbThis,battler.abilityName)) - end - end - battle.pbHideAbilitySplash(battler) - end - } -) - -BattleHandlers::EORHealingAbility.add(:HYDRATION, - proc { |ability,battler,battle| - next if battler.status == :NONE - next if ![:Rain, :HeavyRain].include?(battle.pbWeather) - battle.pbShowAbilitySplash(battler) - oldStatus = battler.status - battler.pbCureStatus(PokeBattle_SceneConstants::USE_ABILITY_SPLASH) - if !PokeBattle_SceneConstants::USE_ABILITY_SPLASH - case oldStatus - when :SLEEP - battle.pbDisplay(_INTL("{1}'s {2} woke it up!",battler.pbThis,battler.abilityName)) - when :POISON - battle.pbDisplay(_INTL("{1}'s {2} cured its poison!",battler.pbThis,battler.abilityName)) - when :BURN - battle.pbDisplay(_INTL("{1}'s {2} healed its burn!",battler.pbThis,battler.abilityName)) - when :PARALYSIS - battle.pbDisplay(_INTL("{1}'s {2} cured its paralysis!",battler.pbThis,battler.abilityName)) - when :FROZEN - battle.pbDisplay(_INTL("{1}'s {2} defrosted it!",battler.pbThis,battler.abilityName)) - end - end - battle.pbHideAbilitySplash(battler) - } -) - -BattleHandlers::EORHealingAbility.add(:SHEDSKIN, - proc { |ability,battler,battle| - next if battler.status == :NONE - next unless battle.pbRandom(100)<30 - battle.pbShowAbilitySplash(battler) - oldStatus = battler.status - battler.pbCureStatus(PokeBattle_SceneConstants::USE_ABILITY_SPLASH) - if !PokeBattle_SceneConstants::USE_ABILITY_SPLASH - case oldStatus - when :SLEEP - battle.pbDisplay(_INTL("{1}'s {2} woke it up!",battler.pbThis,battler.abilityName)) - when :POISON - battle.pbDisplay(_INTL("{1}'s {2} cured its poison!",battler.pbThis,battler.abilityName)) - when :BURN - battle.pbDisplay(_INTL("{1}'s {2} healed its burn!",battler.pbThis,battler.abilityName)) - when :PARALYSIS - battle.pbDisplay(_INTL("{1}'s {2} cured its paralysis!",battler.pbThis,battler.abilityName)) - when :FROZEN - battle.pbDisplay(_INTL("{1}'s {2} defrosted it!",battler.pbThis,battler.abilityName)) - end - end - battle.pbHideAbilitySplash(battler) - } -) - -#=============================================================================== -# EOREffectAbility handlers -#=============================================================================== - -BattleHandlers::EOREffectAbility.add(:BADDREAMS, - proc { |ability,battler,battle| - battle.eachOtherSideBattler(battler.index) do |b| - next if !b.near?(battler) || !b.asleep? - battle.pbShowAbilitySplash(battler) - next if !b.takesIndirectDamage?(PokeBattle_SceneConstants::USE_ABILITY_SPLASH) - oldHP = b.hp - b.pbReduceHP(b.totalhp/8) - if PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("{1} is tormented!",b.pbThis)) - else - battle.pbDisplay(_INTL("{1} is tormented by {2}'s {3}!",b.pbThis, - battler.pbThis(true),battler.abilityName)) - end - battle.pbHideAbilitySplash(battler) - b.pbItemHPHealCheck - b.pbAbilitiesOnDamageTaken(oldHP) - b.pbFaint if b.fainted? - end - } -) - -BattleHandlers::EOREffectAbility.add(:MOODY, - proc { |ability,battler,battle| - randomUp = [] - randomDown = [] - GameData::Stat.each_battle do |s| - randomUp.push(s.id) if battler.pbCanRaiseStatStage?(s.id, battler) - randomDown.push(s.id) if battler.pbCanLowerStatStage?(s.id, battler) - end - next if randomUp.length==0 && randomDown.length==0 - battle.pbShowAbilitySplash(battler) - if randomUp.length>0 - r = battle.pbRandom(randomUp.length) - battler.pbRaiseStatStageByAbility(randomUp[r],2,battler,false,GameData::Ability.get(ability).real_name) - randomDown.delete(randomUp[r]) - end - if randomDown.length>0 - r = battle.pbRandom(randomDown.length) - battler.pbLowerStatStageByAbility(randomDown[r],1,battler,false,GameData::Ability.get(ability).real_name) - end - battle.pbHideAbilitySplash(battler) - battler.pbItemStatRestoreCheck if randomDown.length>0 - } -) - -BattleHandlers::EOREffectAbility.add(:SPEEDBOOST, - proc { |ability,battler,battle| - # A Pokémon's turnCount is 0 if it became active after the beginning of a - # round - if battler.turnCount>0 && battler.pbCanRaiseStatStage?(:SPEED,battler) - ability_name = GameData::Ability.get(ability).real_name - battler.pbRaiseStatStageByAbility(:SPEED,1,battler,true,ability_name) - end - } -) - -#=============================================================================== -# EORGainItemAbility handlers -#=============================================================================== - -BattleHandlers::EORGainItemAbility.add(:HARVEST, - proc { |ability,battler,battle| - next if battler.item - next if !battler.recycleItem || !GameData::Item.get(battler.recycleItem).is_berry? - if ![:Sun, :HarshSun].include?(battle.pbWeather) - next unless battle.pbRandom(100)<50 - end - battle.pbShowAbilitySplash(battler) - battler.item = battler.recycleItem - battler.setRecycleItem(nil) - battler.setInitialItem(battler.item) if !battler.initialItem - battle.pbDisplay(_INTL("{1} harvested one {2}!",battler.pbThis,battler.itemName)) - battle.pbHideAbilitySplash(battler) - battler.pbHeldItemTriggerCheck - } -) - -BattleHandlers::EORGainItemAbility.add(:PICKUP, - proc { |ability,battler,battle| - next if battler.item - foundItem = nil; fromBattler = nil; use = 0 - battle.eachBattler do |b| - next if b.index==battler.index - next if b.effects[PBEffects::PickupUse]<=use - foundItem = b.effects[PBEffects::PickupItem] - fromBattler = b - use = b.effects[PBEffects::PickupUse] - end - next if !foundItem - battle.pbShowAbilitySplash(battler) - battler.item = foundItem - fromBattler.effects[PBEffects::PickupItem] = nil - fromBattler.effects[PBEffects::PickupUse] = 0 - fromBattler.setRecycleItem(nil) if fromBattler.recycleItem==foundItem - if battle.wildBattle? && !battler.initialItem && fromBattler.initialItem==foundItem - battler.setInitialItem(foundItem) - fromBattler.setInitialItem(nil) - end - battle.pbDisplay(_INTL("{1} found one {2}!",battler.pbThis,battler.itemName)) - battle.pbHideAbilitySplash(battler) - battler.pbHeldItemTriggerCheck - } -) - -#=============================================================================== -# CertainSwitchingUserAbility handlers -#=============================================================================== - -# There aren't any! - -#=============================================================================== -# TrappingTargetAbility handlers -#=============================================================================== - -BattleHandlers::TrappingTargetAbility.add(:ARENATRAP, - proc { |ability,switcher,bearer,battle| - next true if !switcher.airborne? - } -) - -BattleHandlers::TrappingTargetAbility.add(:MAGNETPULL, - proc { |ability,switcher,bearer,battle| - next true if switcher.pbHasType?(:STEEL) - } -) - -BattleHandlers::TrappingTargetAbility.add(:SHADOWTAG, - proc { |ability,switcher,bearer,battle| - next true if !switcher.hasActiveAbility?(:SHADOWTAG) - } -) - -#=============================================================================== -# AbilityOnSwitchIn handlers -#=============================================================================== - -BattleHandlers::AbilityOnSwitchIn.add(:AIRLOCK, - proc { |ability,battler,battle| - battle.pbShowAbilitySplash(battler) - if !PokeBattle_SceneConstants::USE_ABILITY_SPLASH - battle.pbDisplay(_INTL("{1} has {2}!",battler.pbThis,battler.abilityName)) - end - battle.pbDisplay(_INTL("The effects of the weather disappeared.")) - battle.pbHideAbilitySplash(battler) - } -) - -BattleHandlers::AbilityOnSwitchIn.copy(:AIRLOCK,:CLOUDNINE) - -BattleHandlers::AbilityOnSwitchIn.add(:ANTICIPATION, - proc { |ability,battler,battle| - next if !battler.pbOwnedByPlayer? - battlerTypes = battler.pbTypes(true) - type1 = battlerTypes[0] - type2 = battlerTypes[1] || type1 - type3 = battlerTypes[2] || type2 - found = false - battle.eachOtherSideBattler(battler.index) do |b| - b.eachMove do |m| - next if m.statusMove? - if type1 - moveType = m.type - if Settings::MECHANICS_GENERATION >= 6 && m.function == "090" # Hidden Power - moveType = pbHiddenPower(b.pokemon)[0] - end - eff = Effectiveness.calculate(moveType,type1,type2,type3) - next if Effectiveness.ineffective?(eff) - next if !Effectiveness.super_effective?(eff) && m.function != "070" # OHKO - else - next if m.function != "070" # OHKO - end - found = true - break - end - break if found - end - if found - battle.pbShowAbilitySplash(battler) - battle.pbDisplay(_INTL("{1} shuddered with anticipation!",battler.pbThis)) - battle.pbHideAbilitySplash(battler) - end - } -) - -BattleHandlers::AbilityOnSwitchIn.add(:AURABREAK, - proc { |ability,battler,battle| - battle.pbShowAbilitySplash(battler) - battle.pbDisplay(_INTL("{1} reversed all other Pokémon's auras!",battler.pbThis)) - battle.pbHideAbilitySplash(battler) - } -) - -BattleHandlers::AbilityOnSwitchIn.add(:COMATOSE, - proc { |ability,battler,battle| - battle.pbShowAbilitySplash(battler) - battle.pbDisplay(_INTL("{1} is drowsing!",battler.pbThis)) - battle.pbHideAbilitySplash(battler) - } -) - -BattleHandlers::AbilityOnSwitchIn.add(:DARKAURA, - proc { |ability,battler,battle| - battle.pbShowAbilitySplash(battler) - battle.pbDisplay(_INTL("{1} is radiating a dark aura!",battler.pbThis)) - battle.pbHideAbilitySplash(battler) - } -) - -BattleHandlers::AbilityOnSwitchIn.add(:DELTASTREAM, - proc { |ability,battler,battle| - pbBattleWeatherAbility(:StrongWinds, battler, battle, true) - } -) - -BattleHandlers::AbilityOnSwitchIn.add(:DESOLATELAND, - proc { |ability,battler,battle| - pbBattleWeatherAbility(:HarshSun, battler, battle, true) - } -) - -BattleHandlers::AbilityOnSwitchIn.add(:DOWNLOAD, - proc { |ability,battler,battle| - oDef = oSpDef = 0 - battle.eachOtherSideBattler(battler.index) do |b| - oDef += b.defense - oSpDef += b.spdef - end - stat = (oDef