experience.asm 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. GainExperience:
  2. ld a, [wLinkState]
  3. cp LINK_STATE_BATTLING
  4. ret z ; return if link battle
  5. call DivideExpDataByNumMonsGainingExp
  6. ld hl, wPartyMon1
  7. xor a
  8. ld [wWhichPokemon], a
  9. .partyMonLoop ; loop over each mon and add gained exp
  10. inc hl
  11. ld a, [hli]
  12. or [hl] ; is mon's HP 0?
  13. jp z, .nextMon ; if so, go to next mon
  14. push hl
  15. ld hl, wPartyGainExpFlags
  16. ld a, [wWhichPokemon]
  17. ld c, a
  18. ld b, FLAG_TEST
  19. predef FlagActionPredef
  20. ld a, c
  21. and a ; is mon's gain exp flag set?
  22. pop hl
  23. jp z, .nextMon ; if mon's gain exp flag not set, go to next mon
  24. ld de, (wPartyMon1HPExp + 1) - (wPartyMon1HP + 1)
  25. add hl, de
  26. ld d, h
  27. ld e, l
  28. ld hl, wEnemyMonBaseStats
  29. ld c, NUM_STATS
  30. .gainStatExpLoop
  31. ld a, [hli]
  32. ld b, a ; enemy mon base stat
  33. ld a, [de] ; stat exp
  34. add b ; add enemy mon base state to stat exp
  35. ld [de], a
  36. jr nc, .nextBaseStat
  37. ; if there was a carry, increment the upper byte
  38. dec de
  39. ld a, [de]
  40. inc a
  41. jr z, .maxStatExp ; jump if the value overflowed
  42. ld [de], a
  43. inc de
  44. jr .nextBaseStat
  45. .maxStatExp ; if the upper byte also overflowed, then we have hit the max stat exp
  46. ld a, $ff
  47. ld [de], a
  48. inc de
  49. ld [de], a
  50. .nextBaseStat
  51. dec c
  52. jr z, .statExpDone
  53. inc de
  54. inc de
  55. jr .gainStatExpLoop
  56. .statExpDone
  57. xor a
  58. ld [H_MULTIPLICAND], a
  59. ld [H_MULTIPLICAND + 1], a
  60. ld a, [wEnemyMonBaseExp]
  61. ld [H_MULTIPLICAND + 2], a
  62. ld a, [wEnemyMonLevel]
  63. ld [H_MULTIPLIER], a
  64. call Multiply
  65. ld a, 7
  66. ld [H_DIVISOR], a
  67. ld b, 4
  68. call Divide
  69. ld hl, wPartyMon1OTID - (wPartyMon1DVs - 1)
  70. add hl, de
  71. ld b, [hl] ; party mon OTID
  72. inc hl
  73. ld a, [wPlayerID]
  74. cp b
  75. jr nz, .tradedMon
  76. ld b, [hl]
  77. ld a, [wPlayerID + 1]
  78. cp b
  79. ld a, 0
  80. jr z, .next
  81. .tradedMon
  82. call BoostExp ; traded mon exp boost
  83. ld a, 1
  84. .next
  85. ld [wGainBoostedExp], a
  86. ld a, [wIsInBattle]
  87. dec a ; is it a trainer battle?
  88. call nz, BoostExp ; if so, boost exp
  89. inc hl
  90. inc hl
  91. inc hl
  92. ; add the gained exp to the party mon's exp
  93. ld b, [hl]
  94. ld a, [H_QUOTIENT + 3]
  95. ld [wExpAmountGained + 1], a
  96. add b
  97. ld [hld], a
  98. ld b, [hl]
  99. ld a, [H_QUOTIENT + 2]
  100. ld [wExpAmountGained], a
  101. adc b
  102. ld [hl], a
  103. jr nc, .noCarry
  104. dec hl
  105. inc [hl]
  106. inc hl
  107. .noCarry
  108. ; calculate exp for the mon at max level, and cap the exp at that value
  109. inc hl
  110. push hl
  111. ld a, [wWhichPokemon]
  112. ld c, a
  113. ld b, 0
  114. ld hl, wPartySpecies
  115. add hl, bc
  116. ld a, [hl] ; species
  117. ld [wd0b5], a
  118. call GetMonHeader
  119. ld d, MAX_LEVEL
  120. callab CalcExperience ; get max exp
  121. ; compare max exp with current exp
  122. ld a, [hExperience]
  123. ld b, a
  124. ld a, [hExperience + 1]
  125. ld c, a
  126. ld a, [hExperience + 2]
  127. ld d, a
  128. pop hl
  129. ld a, [hld]
  130. sub d
  131. ld a, [hld]
  132. sbc c
  133. ld a, [hl]
  134. sbc b
  135. jr c, .next2
  136. ; the mon's exp is greater than the max exp, so overwrite it with the max exp
  137. ld a, b
  138. ld [hli], a
  139. ld a, c
  140. ld [hli], a
  141. ld a, d
  142. ld [hld], a
  143. dec hl
  144. .next2
  145. push hl
  146. ld a, [wWhichPokemon]
  147. ld hl, wPartyMonNicks
  148. call GetPartyMonName
  149. ld hl, GainedText
  150. call PrintText
  151. xor a ; PLAYER_PARTY_DATA
  152. ld [wMonDataLocation], a
  153. call LoadMonData
  154. pop hl
  155. ld bc, wPartyMon1Level - wPartyMon1Exp
  156. add hl, bc
  157. push hl
  158. callba CalcLevelFromExperience
  159. pop hl
  160. ld a, [hl] ; current level
  161. cp d
  162. jp z, .nextMon ; if level didn't change, go to next mon
  163. ld a, [wCurEnemyLVL]
  164. push af
  165. push hl
  166. ld a, d
  167. ld [wCurEnemyLVL], a
  168. ld [hl], a
  169. ld bc, wPartyMon1Species - wPartyMon1Level
  170. add hl, bc
  171. ld a, [hl] ; species
  172. ld [wd0b5], a
  173. ld [wd11e], a
  174. call GetMonHeader
  175. ld bc, (wPartyMon1MaxHP + 1) - wPartyMon1Species
  176. add hl, bc
  177. push hl
  178. ld a, [hld]
  179. ld c, a
  180. ld b, [hl]
  181. push bc ; push max HP (from before levelling up)
  182. ld d, h
  183. ld e, l
  184. ld bc, (wPartyMon1HPExp - 1) - wPartyMon1MaxHP
  185. add hl, bc
  186. ld b, $1 ; consider stat exp when calculating stats
  187. call CalcStats
  188. pop bc ; pop max HP (from before levelling up)
  189. pop hl
  190. ld a, [hld]
  191. sub c
  192. ld c, a
  193. ld a, [hl]
  194. sbc b
  195. ld b, a ; bc = difference between old max HP and new max HP after levelling
  196. ld de, (wPartyMon1HP + 1) - wPartyMon1MaxHP
  197. add hl, de
  198. ; add to the current HP the amount of max HP gained when levelling
  199. ld a, [hl] ; wPartyMon1HP + 1
  200. add c
  201. ld [hld], a
  202. ld a, [hl] ; wPartyMon1HP + 1
  203. adc b
  204. ld [hl], a ; wPartyMon1HP
  205. ld a, [wPlayerMonNumber]
  206. ld b, a
  207. ld a, [wWhichPokemon]
  208. cp b ; is the current mon in battle?
  209. jr nz, .printGrewLevelText
  210. ; current mon is in battle
  211. ld de, wBattleMonHP
  212. ; copy party mon HP to battle mon HP
  213. ld a, [hli]
  214. ld [de], a
  215. inc de
  216. ld a, [hl]
  217. ld [de], a
  218. ; copy other stats from party mon to battle mon
  219. ld bc, wPartyMon1Level - (wPartyMon1HP + 1)
  220. add hl, bc
  221. push hl
  222. ld de, wBattleMonLevel
  223. ld bc, 1 + NUM_STATS * 2 ; size of stats
  224. call CopyData
  225. pop hl
  226. ld a, [wPlayerBattleStatus3]
  227. bit 3, a ; is the mon transformed?
  228. jr nz, .recalcStatChanges
  229. ; the mon is not transformed, so update the unmodified stats
  230. ld de, wPlayerMonUnmodifiedLevel
  231. ld bc, 1 + NUM_STATS * 2
  232. call CopyData
  233. .recalcStatChanges
  234. xor a ; battle mon
  235. ld [wCalculateWhoseStats], a
  236. callab CalculateModifiedStats
  237. callab ApplyBurnAndParalysisPenaltiesToPlayer
  238. callab ApplyBadgeStatBoosts
  239. callab DrawPlayerHUDAndHPBar
  240. callab PrintEmptyString
  241. call SaveScreenTilesToBuffer1
  242. .printGrewLevelText
  243. ld hl, GrewLevelText
  244. call PrintText
  245. xor a ; PLAYER_PARTY_DATA
  246. ld [wMonDataLocation], a
  247. call LoadMonData
  248. ld d, $1
  249. callab PrintStatsBox
  250. call WaitForTextScrollButtonPress
  251. call LoadScreenTilesFromBuffer1
  252. xor a ; PLAYER_PARTY_DATA
  253. ld [wMonDataLocation], a
  254. ld a, [wd0b5]
  255. ld [wd11e], a
  256. predef LearnMoveFromLevelUp
  257. ld hl, wCanEvolveFlags
  258. ld a, [wWhichPokemon]
  259. ld c, a
  260. ld b, FLAG_SET
  261. predef FlagActionPredef
  262. pop hl
  263. pop af
  264. ld [wCurEnemyLVL], a
  265. .nextMon
  266. ld a, [wPartyCount]
  267. ld b, a
  268. ld a, [wWhichPokemon]
  269. inc a
  270. cp b
  271. jr z, .done
  272. ld [wWhichPokemon], a
  273. ld bc, wPartyMon2 - wPartyMon1
  274. ld hl, wPartyMon1
  275. call AddNTimes
  276. jp .partyMonLoop
  277. .done
  278. ld hl, wPartyGainExpFlags
  279. xor a
  280. ld [hl], a ; clear gain exp flags
  281. ld a, [wPlayerMonNumber]
  282. ld c, a
  283. ld b, FLAG_SET
  284. push bc
  285. predef FlagActionPredef ; set the gain exp flag for the mon that is currently out
  286. ld hl, wPartyFoughtCurrentEnemyFlags
  287. xor a
  288. ld [hl], a
  289. pop bc
  290. predef_jump FlagActionPredef ; set the fought current enemy flag for the mon that is currently out
  291. ; divide enemy base stats, catch rate, and base exp by the number of mons gaining exp
  292. DivideExpDataByNumMonsGainingExp:
  293. ld a, [wPartyGainExpFlags]
  294. ld b, a
  295. xor a
  296. ld c, $8
  297. ld d, $0
  298. .countSetBitsLoop ; loop to count set bits in wPartyGainExpFlags
  299. xor a
  300. srl b
  301. adc d
  302. ld d, a
  303. dec c
  304. jr nz, .countSetBitsLoop
  305. cp $2
  306. ret c ; return if only one mon is gaining exp
  307. ld [wd11e], a ; store number of mons gaining exp
  308. ld hl, wEnemyMonBaseStats
  309. ld c, wEnemyMonBaseExp + 1 - wEnemyMonBaseStats
  310. .divideLoop
  311. xor a
  312. ld [H_DIVIDEND], a
  313. ld a, [hl]
  314. ld [H_DIVIDEND + 1], a
  315. ld a, [wd11e]
  316. ld [H_DIVISOR], a
  317. ld b, $2
  318. call Divide ; divide value by number of mons gaining exp
  319. ld a, [H_QUOTIENT + 3]
  320. ld [hli], a
  321. dec c
  322. jr nz, .divideLoop
  323. ret
  324. ; multiplies exp by 1.5
  325. BoostExp:
  326. ld a, [H_QUOTIENT + 2]
  327. ld b, a
  328. ld a, [H_QUOTIENT + 3]
  329. ld c, a
  330. srl b
  331. rr c
  332. add c
  333. ld [H_QUOTIENT + 3], a
  334. ld a, [H_QUOTIENT + 2]
  335. adc b
  336. ld [H_QUOTIENT + 2], a
  337. ret
  338. GainedText:
  339. TX_FAR _GainedText
  340. TX_ASM
  341. ld a, [wBoostExpByExpAll]
  342. ld hl, WithExpAllText
  343. and a
  344. ret nz
  345. ld hl, ExpPointsText
  346. ld a, [wGainBoostedExp]
  347. and a
  348. ret z
  349. ld hl, BoostedText
  350. ret
  351. WithExpAllText:
  352. TX_FAR _WithExpAllText
  353. TX_ASM
  354. ld hl, ExpPointsText
  355. ret
  356. BoostedText:
  357. TX_FAR _BoostedText
  358. ExpPointsText:
  359. TX_FAR _ExpPointsText
  360. db "@"
  361. GrewLevelText:
  362. TX_FAR _GrewLevelText
  363. TX_SFX_LEVEL_UP
  364. db "@"