Set DVs to 0 for all your Pokemon - pret/pokecrystal GitHub Wiki
In generations 1 and 2, the equivalent of Individual Values (IVs) are Determinant values (DVs), and only four DVs are stored for each Pokémon: Attack, Defense, Speed, and Special (used for both Sp.Atk and Sp.Def); the HP DV is determined from the DVs stored for the other four. Unlike IVs, DVs range from 0-15.
If you want to make it so that the player can only get Pokémon with 0 DVs, this tutorial will teach you how do to it.
Contents
- Force gift Pokémon to have 0 DVs
- Force regular wild Pokémon to have 0 DVs
- Force roaming Pokémon to have 0 DVs
- Force the shiny Gyarados to have 0 DVs
1. Force gift Pokémon to have 0 DVs
The routine TryAddMonToParty
, as the name suggests, tries to add a Pokémon to either the player's or the opponent's party depending on some parameters, and it contains a subroutine called GeneratePartyMonStats
that generates the Pokémon's stats. If the player gets a Pokémon as a gift, it randomly generates its DVs, so we'll force the subroutine to set them to 0. For that, let's edit engine/pokemon/move_mon.asm:
GeneratePartyMonStats:
...
.registerpokedex
ld a, [wCurPartySpecies]
ld [wTempSpecies], a
dec a
push de
call CheckCaughtMon
ld a, [wTempSpecies]
dec a
call SetSeenAndCaughtMon
pop de
pop hl
push hl
ld a, [wBattleMode]
and a
jr nz, .copywildmonDVs
- call Random
- ld b, a
- call Random
- ld c, a
+ ld b, 0
+ ld c, 0
.initializeDVs
ld a, b
ld [de], a
inc de
ld a, c
ld [de], a
inc de
...
Register b
stores both the Attack (high nibble) and Defense (low nibble) DVs, while c
stores both the Speed (high nibble) and Special (low nibble) DVs, so loading 0 affects both nibbles of a byte (if you don't know what a nibble is, Wikipedia is your best friend).
In any case, this is all for gift Pokémon, but wild and roaming Pokémon use another routine called LoadEnemyMon
to determine their DVs.
2. Force regular wild Pokémon to have 0 DVs
Edit engine/battle/core.asm:
LoadEnemyMon:
; Initialize enemy monster parameters
; To do this we pull the species from wTempEnemyMonSpecies
...
.GenerateDVs:
; Generate new random DVs
- call BattleRandom
- ld b, a
- call BattleRandom
- ld c, a
+ ld b, 0
+ ld c, 0
.UpdateDVs:
; Input DVs in register bc
ld hl, wEnemyMonDVs
ld a, b
ld [hli], a
ld [hl], c
...
3. Force roaming Pokémon to have 0 DVs
Edit engine/battle/core.asm:
LoadEnemyMon:
...
; If it hasn't, we need to initialize the DVs
; (HP is initialized at the end of the battle)
call GetRoamMonDVs
inc hl
- call BattleRandom
+ ld a, 0
ld [hld], a
ld c, a
- call BattleRandom
ld [hl], a
ld b, a
; We're done with DVs
jr .UpdateDVs
...
If you want to optimize this, you can replace ld a, 0
with xor a
.
4. Force shiny Gyarados to have 0 DVs
In generation 2, shininess used to be determined by DVs, so the shiny Gyarados from the Lake of Rage has fixed DVs corresponding to valid shiny values. However, if you edit these values, this Gyarados won't be shiny anymore, so it's up to your discretion. Providing possible solutions is out of the scope of this tutorial.
Let's edit constants/battle_constants.asm:
; shiny dvs
-DEF ATKDEFDV_SHINY EQU $EA
-DEF SPDSPCDV_SHINY EQU $AA
+DEF ATKDEFDV_SHINY EQU 0
+DEF SPDSPCDV_SHINY EQU 0
And that's it! All the Pokémon the player can get will have 0 DVs. Enjoy your challenging Pokémon game!