kwsch / PKHeX

Pokémon Save File Editor
https://projectpokemon.org/pkhex/
Other
3.63k stars 682 forks source link

The last 3 IVs of all the Gen4 roamers block data are swapped #4346

Closed Real96 closed 3 weeks ago

Real96 commented 3 weeks ago

Describe the bug The last 3 IVs of all the Gen4 roamers block data are swapped. PKHex atm shows them in this wrong order:

To Reproduce Steps to reproduce the behavior:

  1. Open a Gen4 save file where raomers Pokémon are still roaming
  2. SAV tab -> Block data
  3. Scroll down to any Roamer data block
  4. You can see the error by checking the latest 3 IVs (SpA, SpD, Spe)

Expected behavior PKHex should show the IVs of roamer block data as follow:

Screenshots image

Additional context This same behaviour happens in Gen5 raomers block data, but it is correct in these games.

kwsch commented 3 weeks ago

The consistent internal ordering maintained by PKHeX is Speed-Middle like is stored in the 32-bit IV structure, not Speed-Last like is displayed in games.

        get => [IV_HP, IV_ATK, IV_DEF, IV_SPE, IV_SPA, IV_SPD];

Roamer4.cs and Roamer5.cs both implement the same 32-bit read/write order, so if you're saying that Gen5 roamer IVs are wrong, then that would be something worth revising.

    private int IV_HP  { get => (int)(IV32 >> 00) & 0x1F; set => IV32 = (IV32 & ~(0x1Fu << 00)) | (uint)((value > 31 ? 31 : value) << 00); }
    private int IV_ATK { get => (int)(IV32 >> 05) & 0x1F; set => IV32 = (IV32 & ~(0x1Fu << 05)) | (uint)((value > 31 ? 31 : value) << 05); }
    private int IV_DEF { get => (int)(IV32 >> 10) & 0x1F; set => IV32 = (IV32 & ~(0x1Fu << 10)) | (uint)((value > 31 ? 31 : value) << 10); }
    private int IV_SPE { get => (int)(IV32 >> 15) & 0x1F; set => IV32 = (IV32 & ~(0x1Fu << 15)) | (uint)((value > 31 ? 31 : value) << 15); }
    private int IV_SPA { get => (int)(IV32 >> 20) & 0x1F; set => IV32 = (IV32 & ~(0x1Fu << 20)) | (uint)((value > 31 ? 31 : value) << 20); }
    private int IV_SPD { get => (int)(IV32 >> 25) & 0x1F; set => IV32 = (IV32 & ~(0x1Fu << 25)) | (uint)((value > 31 ? 31 : value) << 25); }
Real96 commented 3 weeks ago

The consistent internal ordering maintained by PKHeX is Speed-Middle like is stored in the 32-bit IV structure, not Speed-Last like is displayed in games.

        get => [IV_HP, IV_ATK, IV_DEF, IV_SPE, IV_SPA, IV_SPD];

Roamer4.cs and Roamer5.cs both implement the same 32-bit read/write order, so if you're saying that Gen5 roamer IVs are wrong, then that would be something worth revising.

The image below shows that in Gen5 the IVs are ordered correctly:

image

If you create an Entei with PID 3519569699 (D1C85F23) and IVs 26/10/24/0/6/16 (as showed in the first image of Entei block data), PKHex will flag it as not legal. So Gen4 roamers block data are showed with swapped IVs atm (unless the speed-middle like is the wanted one, in this case the bug is in Gen5 roamers block).