meekrhino / digimon_world_randomizer

Digimon World 1 (PS1) data randomizer. Create a unique, brand new experience for the classic game.
35 stars 5 forks source link

Randomized recruitments give the PP of the original Digimon #49

Closed SydMontague closed 5 years ago

SydMontague commented 5 years ago

For example, when talking to Betamon recruits Coelamon you still only get 1 prosperity point for it.

The first step of the proposed solution is to rewrite the recalcPP function of the game, that gets called when saving the game. This would still leave the PP counter broken until the player saves, but at least provide an easy way to fix it.

For that we intend to encode the prosperity value of each recruited Digimon in the least significant two bits of a Digimon's "height" value. In the above example Betamon's height would have to be set to 162, to represent the prosperity value of 2 Coelamon is giving. Alternatively 158 would be possible as well, leading to the same result but in certain circumstances a smaller difference from the vanilla value.

The relevant ASM code is

// unchanged
0x000efa30 addu r17,r0,r0         21 88 00 00
0x000efa34 addiu r16,r0,0x0003    03 00 10 24
0x000efa38 addiu r18,r0,0x009c    9C 00 12 24
0x000efa3c beq r0,r0,0x000efad4   25 00 00 10
0x000efa40 addiu r19,r0,0x00cb    CB 00 13 24
// changed code
0x000efa44 jal 0x0010643c         0F 19 04 0C
0x000efa48 andi r4,r19,0xffff     FF FF 64 32
0x000efa4c beq r2,r0,0x000efac8   1E 00 40 10
0x000efa50 nop                    00 00 00 00
0x000efa54 lui r2,0x8013          13 80 02 3C
0x000efa58 addiu r2,r2,0xcece     CE CE 42 24
0x000efa5C addu r2,r2,r18         21 10 52 00
0x000efa60 lbu r2,0x0000(r2)      00 00 42 90
0x000efa64 andi r2,r2,0x0003      03 00 42 30
0x000efa68 addu r17,r2,r17        21 88 51 00
0x000efa6c beq r0,r0,0x000efac8   16 00 00 10
// vanilla from here on, everything till 0x000efac8 is dead code

An alternative way of storing the prosperity values is using the dead code area of the function...

meekrhino commented 5 years ago

Naively setting the new height value should just come down to:

height = (height & 0xFFFC) | new_pp

It gets slightly more complicated if we want to use the least intrusive change that gives the required bits.