ref: 3756ec6dd94daf1ea5826f9bd9e30e00087f242f
dir: /home/move_mon.asm/
; Copies [hl, bc) to [de, de + bc - hl). ; In other words, the source data is from hl up to but not including bc, ; and the destination is de. CopyDataUntil:: ld a, [hli] ld [de], a inc de ld a, h cp b jr nz, CopyDataUntil ld a, l cp c jr nz, CopyDataUntil ret ; Function to remove a pokemon from the party or the current box. ; wWhichPokemon determines the pokemon. ; [wRemoveMonFromBox] == 0 specifies the party. ; [wRemoveMonFromBox] != 0 specifies the current box. RemovePokemon:: jpfar _RemovePokemon AddPartyMon:: push hl push de push bc farcall _AddPartyMon pop bc pop de pop hl ret ; calculates all 5 stats of current mon and writes them to [de] CalcStats:: ld c, $0 .statsLoop inc c call CalcStat ldh a, [hMultiplicand+1] ld [de], a inc de ldh a, [hMultiplicand+2] ld [de], a inc de ld a, c cp NUM_STATS jr nz, .statsLoop ret ; calculates stat c of current mon ; c: stat to calc (HP=1,Atk=2,Def=3,Spd=4,Spc=5) ; b: consider stat exp? ; hl: base ptr to stat exp values ([hl + 2*c - 1] and [hl + 2*c]) CalcStat:: push hl push de push bc ld a, b ld d, a push hl ld hl, wMonHeader ld b, $0 add hl, bc ld a, [hl] ; read base value of stat ld e, a pop hl push hl sla c ld a, d and a jr z, .statExpDone ; consider stat exp? add hl, bc ; skip to corresponding stat exp value .statExpLoop ; calculates ceil(Sqrt(stat exp)) in b xor a ldh [hMultiplicand], a ldh [hMultiplicand+1], a inc b ; increment current stat exp bonus ld a, b cp $ff jr z, .statExpDone ldh [hMultiplicand+2], a ldh [hMultiplier], a call Multiply ld a, [hld] ld d, a ldh a, [hProduct + 3] sub d ld a, [hli] ld d, a ldh a, [hProduct + 2] sbc d ; test if (current stat exp bonus)^2 < stat exp jr c, .statExpLoop .statExpDone srl c pop hl push bc ld bc, wPartyMon1DVs - (wPartyMon1HPExp - 1) ; also wEnemyMonDVs - wEnemyMonHP add hl, bc pop bc ld a, c cp $2 jr z, .getAttackIV cp $3 jr z, .getDefenseIV cp $4 jr z, .getSpeedIV cp $5 jr z, .getSpecialIV .getHpIV push bc ld a, [hl] ; Atk IV swap a and $1 sla a sla a sla a ld b, a ld a, [hli] ; Def IV and $1 sla a sla a add b ld b, a ld a, [hl] ; Spd IV swap a and $1 sla a add b ld b, a ld a, [hl] ; Spc IV and $1 add b ; HP IV: LSB of the other 4 IVs pop bc jr .calcStatFromIV .getAttackIV ld a, [hl] swap a and $f jr .calcStatFromIV .getDefenseIV ld a, [hl] and $f jr .calcStatFromIV .getSpeedIV inc hl ld a, [hl] swap a and $f jr .calcStatFromIV .getSpecialIV inc hl ld a, [hl] and $f .calcStatFromIV ld d, $0 add e ld e, a jr nc, .noCarry inc d ; de = Base + IV .noCarry sla e rl d ; de = (Base + IV) * 2 srl b srl b ; b = ceil(Sqrt(stat exp)) / 4 ld a, b add e jr nc, .noCarry2 inc d ; de = (Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4 .noCarry2 ldh [hMultiplicand+2], a ld a, d ldh [hMultiplicand+1], a xor a ldh [hMultiplicand], a ld a, [wCurEnemyLVL] ldh [hMultiplier], a call Multiply ; ((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level ldh a, [hMultiplicand] ldh [hDividend], a ldh a, [hMultiplicand+1] ldh [hDividend+1], a ldh a, [hMultiplicand+2] ldh [hDividend+2], a ld a, $64 ldh [hDivisor], a ld a, $3 ld b, a call Divide ; (((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level) / 100 ld a, c cp $1 ld a, 5 ; + 5 for non-HP stat jr nz, .notHPStat ld a, [wCurEnemyLVL] ld b, a ldh a, [hMultiplicand+2] add b ldh [hMultiplicand+2], a jr nc, .noCarry3 ldh a, [hMultiplicand+1] inc a ldh [hMultiplicand+1], a ; HP: (((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level) / 100 + Level .noCarry3 ld a, 10 ; +10 for HP stat .notHPStat ld b, a ldh a, [hMultiplicand+2] add b ldh [hMultiplicand+2], a jr nc, .noCarry4 ldh a, [hMultiplicand+1] inc a ; non-HP: (((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level) / 100 + 5 ldh [hMultiplicand+1], a ; HP: (((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level) / 100 + Level + 10 .noCarry4 ldh a, [hMultiplicand+1] ; check for overflow (>999) cp HIGH(MAX_STAT_VALUE) + 1 jr nc, .overflow cp HIGH(MAX_STAT_VALUE) jr c, .noOverflow ldh a, [hMultiplicand+2] cp LOW(MAX_STAT_VALUE) + 1 jr c, .noOverflow .overflow ld a, HIGH(MAX_STAT_VALUE) ; overflow: cap at 999 ldh [hMultiplicand+1], a ld a, LOW(MAX_STAT_VALUE) ldh [hMultiplicand+2], a .noOverflow pop bc pop de pop hl ret AddEnemyMonToPlayerParty:: homecall_sf _AddEnemyMonToPlayerParty ret MoveMon:: homecall_sf _MoveMon ret