This page is for small hints about how to edit pokecrystal that don't need an entire tutorial of their own. Any sort of tips, tricks, hints, pointers to obscure but useful code routines, engine trivia—it all goes here. ## Contents - [Change the odds of encountering a shiny Pokémon](#change-the-odds-of-encountering-a-shiny-pokémon) - [Stop the blue palette from animating its white hue](#stop-the-blue-palette-from-animating-its-white-hue) - [Make overworld sprites darker at night](#make-overworld-sprites-darker-at-night) - [Enemy trainers have maximum happiness for a powerful Return](#enemy-trainers-have-maximum-happiness-for-a-powerful-return) - [Lowercasing Pokémon names cuts off their first letter](#lowercasing-pokémon-names-cuts-off-their-first-letter) - [Pan in cutscenes by making the player invisible](#pan-in-cutscenes-by-making-the-player-invisible) - [Prevent NPCs' heads from flipping when they walk down](#prevent-NPCs-heads-from-flipping-when-they-walk-down) - [Use HGSS behavior for fainting without saving on the S.S. Aqua](#use-hgss-behavior-for-fainting-without-saving-on-the-s.s.-aqua) ## Change the odds of encountering a shiny Pokémon The odds of encountering a shiny Pokémon in Gen 2 are 1 in 8,192. That value isn't literally defined anywhere: it's a consequence of making shininess based on DVs. A shiny Pokémon has: - Attack DV = 2, 3, 6, 7, 10, 11, 14, or 15 - Defense, Speed, and Special DVs = 10 Since all four DVs are random from 0 to 15, some multiplication shows that 1 in 8,192 Pokémon will be shiny. The routine that checks those specific values is `CheckShininess` in [engine/gfx/color.asm](../blob/master/engine/gfx/color.asm). If you want different odds, just change which DVs count as shiny. (The `Unused_CheckShininess` routine right below it would just make a Pokémon shiny if all its DVs are 10 or higher, which gives odds of about 1 in 50.) Also, the red Gyarados has hard-coded values for its DVs of 14/10/10/10; they're defined as `ATKDEFDV_SHINY` and `SPDSPCDV_SHINY` in [constants/battle_constants.asm](../blob/master/constants/battle_constants.asm). ## Stop the blue palette from animating its white hue There are eight palettes used for tilesets: `GRAY`, `RED`, `GREEN`, `WATER`, `YELLOW`, `BROWN`, `ROOF`, and `TEXT`. It's called `WATER` instead of `BLUE` because its lightest hue gets animated for some tilesets, cycling between three colors. This makes water (and rocks, whirlpools, and waterfalls) look more dynamic, but it prevents you from making static blue tiles (like Mart roofs). To stop it, edit [engine/tilesets/tileset_anims.asm](../blob/master/engine/tilesets/tileset_anims.asm) and replace all the instances of `dw NULL, AnimateWaterPalette` with `dw NULL, WaitTileAnimation`. ## Make overworld sprites darker at night Edit [gfx/overworld/npc_sprites.pal](../blob/master/gfx/overworld/npc_sprites.pal): ```diff ; nite - RGB 15,14,24, 31,19,10, 31,07,01, 00,00,00 ; red - RGB 15,14,24, 31,19,10, 10,09,31, 00,00,00 ; blue - RGB 15,14,24, 31,19,10, 07,23,03, 00,00,00 ; green - RGB 15,14,24, 31,19,10, 15,10,03, 00,00,00 ; brown - RGB 15,14,24, 31,19,10, 30,10,06, 00,00,00 ; pink + RGB 15,14,24, 16,10,09, 17,03,00, 00,00,00 ; red + RGB 15,14,24, 16,10,09, 05,04,27, 00,00,00 ; blue + RGB 15,14,24, 16,10,09, 03,10,02, 00,00,00 ; green + RGB 15,14,24, 16,10,09, 08,04,02, 00,00,00 ; brown + RGB 15,14,24, 16,10,09, 18,05,04, 00,00,00 ; pink RGB 31,31,31, 31,31,31, 13,13,13, 00,00,00 ; silver RGB 15,14,24, 08,13,19, 00,11,13, 00,00,00 ; tree RGB 15,14,24, 12,09,15, 08,04,05, 00,00,00 ; rock ``` ## Enemy trainers have maximum happiness for a powerful Return Edit [engine/pokemon/move_mon.asm](../blob/master/engine/pokemon/move_mon.asm): ```diff TryAddMonToParty: ... GeneratePartyMonStats: ; wBattleMode specifies whether it's a wild mon or not. ; wMonType specifies whether it's an opposing mon or not. ; wCurPartySpecies/wCurPartyLevel specify the species and level. ; hl points to the wPartyMon struct to fill. ... ; Initialize happiness. + ld a, [wMonType] + and $f ld a, BASE_HAPPINESS + jr z, .got_happiness + ld a, $ff ; max happiness for enemy trainers +.got_happiness ld [de], a inc de ... ``` ## Lowercasing Pokémon names cuts off their first letter If you simply lowercase all the names in [data/pokemon/names.asm](../blob/master/data/pokemon/names.asm) and rebuild the ROM, the first letter of their names may be missing. The cause is changing `"FARFETCH'D"` to `"Farfetch'd"`, because `'d` is actually a single character. The fix is to pad its name to the same length as all the rest with an `@`, so that it becomes `"Farfetch'd@"`. ## Pan in cutscenes by making the player invisible The player's object is always at the center of the screen. So if you want to pan the camera during a cutscene, you have to get around that. The key is the `show_person` and `hide_person` movement commands, which make an object visible or invisible. Let's say you have a map with two placeholder sprites: `YOURMAP_CHRIS_PLACEHOLDER`, an `object_event` which uses `SPRITE_CHRIS`, and `YOURMAP_KRIS_PLACEHOLDER`, which uses `SPRITE_KRIS`. Then define these movement scripts: ``` ShowPersonMovement: show_person step_end HidePersonMovement: hide_person step_end ``` In your cutscene script, to show the placeholder and make the player invisible: ``` checkflag ENGINE_PLAYER_IS_FEMALE iftrue .ShowGirlPlaceholder appear YOURMAP_CHRIS_PLACEHOLDER sjump .HidePlayer .ShowGirlPlaceholder appear YOURMAP_KRIS_PLACEHOLDER .HidePlayer applymovement PLAYER, HidePersonMovement ``` And to make the player visible again and disappear the placeholder: ``` applymovement PLAYER, ShowPersonMovement checkflag ENGINE_PLAYER_IS_FEMALE iftrue .HideGirlPlaceholder disappear YOURMAP_CHRIS_PLACEHOLDER sjump .HidPlaceholder .HideGirlPlaceholder disappear YOURMAP_KRIS_PLACEHOLDER .HidPlaceholder ``` In between those script snippets, you can move the player around to look like the camera is panning around the map. ## Prevent NPCs' heads from flipping when they walk down When NPCs walk up or down, they flip horizontally every other frame to create the alternating left-right step animation. But for NPCs with asymmetrical faces, this can look awkward when they walk down. To disable this flipping for all overworld sprites, edit [data/sprites/facings.asm](../blob/master/data/sprites/facings.asm): ```diff FacingStepDown3: ; walking down 2 db 4 ; # - db 0, 8, X_FLIP, $80 - db 0, 0, X_FLIP, $81 + db 0, 0, 0, $80 + db 0, 8, 0, $81 db 8, 8, RELATIVE_ATTRIBUTES | X_FLIP, $82 db 8, 0, RELATIVE_ATTRIBUTES | X_FLIP, $83 ``` Note that the player sprite in the naming screen and the Town Map are unaffected by this. Also, this prevents the bicycling player sprite from moving side to side. ## Use HGSS behavior for fainting without saving on the S.S. Aqua You may have noticed how when you get on the S.S. Aqua or go to either port without saving, then white out, that you're taken to either your cabin or the Vermilion/Olivine Pokémon Center instead of the Pokémon Center you last used. To fix this (using the HGSS behavior), edit `.LeaveFastShipScript` in [maps/OlivinePort.asm](https://github.com/pret/pokecrystal/blob/master/maps/OlivinePort.asm) and [maps/VermilionPort.asm](https://github.com/pret/pokecrystal/blob/master/maps/VermilionPort.asm): ```diff applymovement PLAYER, MovementData_0x74a32 appear OLIVINEPORT_SAILOR1 setscene SCENE_DEFAULT setevent EVENT_TEMPORARY_UNTIL_MAP_RELOAD_1 - blackoutmod OLIVINE_CITY end ``` ```diff applymovement PLAYER, MovementData_0x74ef3 appear VERMILIONPORT_SAILOR1 setscene SCENE_DEFAULT setevent EVENT_FAST_SHIP_CABINS_SE_SSE_CAPTAINS_CABIN_TWIN_1 setevent EVENT_FAST_SHIP_CABINS_SE_SSE_GENTLEMAN setevent EVENT_FAST_SHIP_PASSENGERS_FIRST_TRIP clearevent EVENT_OLIVINE_PORT_PASSAGE_POKEFAN_M setevent EVENT_FAST_SHIP_FIRST_TIME setevent EVENT_TEMPORARY_UNTIL_MAP_RELOAD_1 - blackoutmod VERMILION_CITY end ``` Also edit `.EnterFastShipScript` in [maps/FastShip1F.asm](https://github.com/pret/pokecrystal/blob/master/maps/FastShip1F.asm): ```diff applymovement FASTSHIP1F_SAILOR1, MovementData_0x7520e applymovement PLAYER, MovementData_0x75217 applymovement FASTSHIP1F_SAILOR1, MovementData_0x75211 pause 30 playsound SFX_BOAT earthquake 30 - blackoutmod FAST_SHIP_CABINS_SW_SSW_NW clearevent EVENT_FAST_SHIP_HAS_ARRIVED checkevent EVENT_FAST_SHIP_FIRST_TIME iftrue .SkipGrandpa setscene SCENE_FASTSHIP1F_MEET_GRANDPA end ```