summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlibjet <libj3t@gmail.com>2020-05-25 15:38:13 +0100
committerlibjet <libj3t@gmail.com>2020-05-25 15:38:13 +0100
commit2c54d71504ab56d947ff2df2b26e8e9ebbd27bca (patch)
tree654cbd9f7d749800934df2bf543ebcac492c2fe5
parent1e5871640db027e6acbafbb968354657ca4c7e75 (diff)
Add engine/pokemon/experience.asm
-rwxr-xr-xdata/growth_rates.asm19
-rwxr-xr-xengine/pokemon/experience.asm162
-rw-r--r--main.asm6
3 files changed, 182 insertions, 5 deletions
diff --git a/data/growth_rates.asm b/data/growth_rates.asm
new file mode 100755
index 00000000..aee2a16e
--- /dev/null
+++ b/data/growth_rates.asm
@@ -0,0 +1,19 @@
+growth_rate: MACRO
+; [1]/[2]*n**3 + [3]*n**2 + [4]*n - [5]
+ dn \1, \2
+ if \3 & $80 ; signed
+ db -\3 | $80
+ else
+ db \3
+ endc
+ db \4, \5
+ENDM
+
+GrowthRates:
+; entries correspond to GROWTH_* (see constants/pokemon_data_constants.asm)
+ growth_rate 1, 1, 0, 0, 0 ; Medium Fast
+ growth_rate 3, 4, 10, 0, 30 ; Slightly Fast
+ growth_rate 3, 4, 20, 0, 70 ; Slightly Slow
+ growth_rate 6, 5, -15, 100, 140 ; Medium Slow
+ growth_rate 4, 5, 0, 0, 0 ; Fast
+ growth_rate 5, 4, 0, 0, 0 ; Slow
diff --git a/engine/pokemon/experience.asm b/engine/pokemon/experience.asm
new file mode 100755
index 00000000..7d026704
--- /dev/null
+++ b/engine/pokemon/experience.asm
@@ -0,0 +1,162 @@
+CalcLevel:
+ ld a, [wTempMonSpecies]
+ ld [wCurSpecies], a
+ call GetBaseData
+ ld d, 1
+.next_level
+ inc d
+ ld a, d
+ cp LOW(MAX_LEVEL + 1)
+ jr z, .got_level
+ call CalcExpAtLevel
+ push hl
+ ld hl, wTempMonExp + 2
+ ldh a, [hProduct + 3]
+ ld c, a
+ ld a, [hld]
+ sub c
+ ldh a, [hProduct + 2]
+ ld c, a
+ ld a, [hld]
+ sbc c
+ ldh a, [hProduct + 1]
+ ld c, a
+ ld a, [hl]
+ sbc c
+ pop hl
+ jr nc, .next_level
+
+.got_level
+ dec d
+ ret
+
+CalcExpAtLevel:
+; (a/b)*n**3 + c*n**2 + d*n - e
+ ld a, [wBaseGrowthRate]
+ add a
+ add a
+ ld c, a
+ ld b, 0
+ ld hl, GrowthRates
+ add hl, bc
+; Cube the level
+ call .LevelSquared
+ ld a, d
+ ldh [hMultiplier], a
+ call Multiply
+
+; Multiply by a
+ ld a, [hl]
+ and $f0
+ swap a
+ ldh [hMultiplier], a
+ call Multiply
+; Divide by b
+ ld a, [hli]
+ and $f
+ ldh [hDivisor], a
+ ld b, 4
+ call Divide
+; Push the cubic term to the stack
+ ldh a, [hQuotient + 1]
+ push af
+ ldh a, [hQuotient + 2]
+ push af
+ ldh a, [hQuotient + 3]
+ push af
+; Square the level and multiply by the lower 7 bits of c
+ call .LevelSquared
+ ld a, [hl]
+ and $7f
+ ldh [hMultiplier], a
+ call Multiply
+; Push the absolute value of the quadratic term to the stack
+ ldh a, [hProduct + 1]
+ push af
+ ldh a, [hProduct + 2]
+ push af
+ ldh a, [hProduct + 3]
+ push af
+ ld a, [hli]
+ push af
+; Multiply the level by d
+ xor a
+ ldh [hMultiplicand + 0], a
+ ldh [hMultiplicand + 1], a
+ ld a, d
+ ldh [hMultiplicand + 2], a
+ ld a, [hli]
+ ldh [hMultiplier], a
+ call Multiply
+; Subtract e
+ ld b, [hl]
+ ldh a, [hProduct + 3]
+ sub b
+ ldh [hMultiplicand + 2], a
+ ld b, 0
+ ldh a, [hProduct + 2]
+ sbc b
+ ldh [hMultiplicand + 1], a
+ ldh a, [hProduct + 1]
+ sbc b
+ ldh [hMultiplicand], a
+; If bit 7 of c is set, c is negative; otherwise, it's positive
+ pop af
+ and $80
+ jr nz, .subtract
+; Add c*n**2 to (d*n - e)
+ pop bc
+ ldh a, [hProduct + 3]
+ add b
+ ldh [hMultiplicand + 2], a
+ pop bc
+ ldh a, [hProduct + 2]
+ adc b
+ ldh [hMultiplicand + 1], a
+ pop bc
+ ldh a, [hProduct + 1]
+ adc b
+ ldh [hMultiplicand], a
+ jr .done_quadratic
+
+.subtract
+; Subtract c*n**2 from (d*n - e)
+ pop bc
+ ldh a, [hProduct + 3]
+ sub b
+ ldh [hMultiplicand + 2], a
+ pop bc
+ ldh a, [hProduct + 2]
+ sbc b
+ ldh [hMultiplicand + 1], a
+ pop bc
+ ldh a, [hProduct + 1]
+ sbc b
+ ldh [hMultiplicand], a
+
+.done_quadratic
+; Add (a/b)*n**3 to (d*n - e +/- c*n**2)
+ pop bc
+ ldh a, [hProduct + 3]
+ add b
+ ldh [hMultiplicand + 2], a
+ pop bc
+ ldh a, [hProduct + 2]
+ adc b
+ ldh [hMultiplicand + 1], a
+ pop bc
+ ldh a, [hProduct + 1]
+ adc b
+ ldh [hMultiplicand], a
+ ret
+
+.LevelSquared:
+ xor a
+ ldh [hMultiplicand + 0], a
+ ldh [hMultiplicand + 1], a
+ ld a, d
+ ldh [hMultiplicand + 2], a
+ ldh [hMultiplier], a
+ jp Multiply
+
+INCLUDE "data/growth_rates.asm"
diff --git a/main.asm b/main.asm
index ca1a95ea..b17c9db3 100644
--- a/main.asm
+++ b/main.asm
@@ -370,11 +370,7 @@ INCLUDE "engine/pokemon/types.asm"
INCLUDE "engine/battle/unreferenced_getgen1trainerclassname.asm"
INCLUDE "engine/pokemon/mon_stats.asm"
INCLUDE "engine/link/init_list.asm"
-
-CalcLevel::
- dr $51524, $51550
-CalcExpAtLevel::
- dr $51550, $5161b
+INCLUDE "engine/pokemon/experience.asm"
_SwitchPartyMons::
dr $5161b, $51749