summaryrefslogtreecommitdiff
path: root/home/move_mon.asm
diff options
context:
space:
mode:
authordannye <33dannye@gmail.com>2020-11-04 00:06:44 -0600
committerdannye <33dannye@gmail.com>2020-11-04 00:06:44 -0600
commit5647ca687b92954dcf37a6ea6bfbc9a341c32de4 (patch)
treedde1937a1bfdb3a835f4155e1c2eb8f1aaf86f63 /home/move_mon.asm
parent53fcd05aa24693093d8af1dc8ec4fedd3957decc (diff)
Sync with pokered
Diffstat (limited to 'home/move_mon.asm')
-rw-r--r--home/move_mon.asm239
1 files changed, 239 insertions, 0 deletions
diff --git a/home/move_mon.asm b/home/move_mon.asm
new file mode 100644
index 00000000..c766fbd5
--- /dev/null
+++ b/home/move_mon.asm
@@ -0,0 +1,239 @@
+; 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