123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373 |
- GainExperience:
- ld a, [wLinkState]
- cp LINK_STATE_BATTLING
- ret z ; return if link battle
- call DivideExpDataByNumMonsGainingExp
- ld hl, wPartyMon1
- xor a
- ld [wWhichPokemon], a
- .partyMonLoop ; loop over each mon and add gained exp
- inc hl
- ld a, [hli]
- or [hl] ; is mon's HP 0?
- jp z, .nextMon ; if so, go to next mon
- push hl
- ld hl, wPartyGainExpFlags
- ld a, [wWhichPokemon]
- ld c, a
- ld b, FLAG_TEST
- predef FlagActionPredef
- ld a, c
- and a ; is mon's gain exp flag set?
- pop hl
- jp z, .nextMon ; if mon's gain exp flag not set, go to next mon
- ld de, (wPartyMon1HPExp + 1) - (wPartyMon1HP + 1)
- add hl, de
- ld d, h
- ld e, l
- ld hl, wEnemyMonBaseStats
- ld c, NUM_STATS
- .gainStatExpLoop
- ld a, [hli]
- ld b, a ; enemy mon base stat
- ld a, [de] ; stat exp
- add b ; add enemy mon base state to stat exp
- ld [de], a
- jr nc, .nextBaseStat
- ; if there was a carry, increment the upper byte
- dec de
- ld a, [de]
- inc a
- jr z, .maxStatExp ; jump if the value overflowed
- ld [de], a
- inc de
- jr .nextBaseStat
- .maxStatExp ; if the upper byte also overflowed, then we have hit the max stat exp
- ld a, $ff
- ld [de], a
- inc de
- ld [de], a
- .nextBaseStat
- dec c
- jr z, .statExpDone
- inc de
- inc de
- jr .gainStatExpLoop
- .statExpDone
- xor a
- ld [H_MULTIPLICAND], a
- ld [H_MULTIPLICAND + 1], a
- ld a, [wEnemyMonBaseExp]
- ld [H_MULTIPLICAND + 2], a
- ld a, [wEnemyMonLevel]
- ld [H_MULTIPLIER], a
- call Multiply
- ld a, 7
- ld [H_DIVISOR], a
- ld b, 4
- call Divide
- ld hl, wPartyMon1OTID - (wPartyMon1DVs - 1)
- add hl, de
- ld b, [hl] ; party mon OTID
- inc hl
- ld a, [wPlayerID]
- cp b
- jr nz, .tradedMon
- ld b, [hl]
- ld a, [wPlayerID + 1]
- cp b
- ld a, 0
- jr z, .next
- .tradedMon
- call BoostExp ; traded mon exp boost
- ld a, 1
- .next
- ld [wGainBoostedExp], a
- ld a, [wIsInBattle]
- dec a ; is it a trainer battle?
- call nz, BoostExp ; if so, boost exp
- inc hl
- inc hl
- inc hl
- ; add the gained exp to the party mon's exp
- ld b, [hl]
- ld a, [H_QUOTIENT + 3]
- ld [wExpAmountGained + 1], a
- add b
- ld [hld], a
- ld b, [hl]
- ld a, [H_QUOTIENT + 2]
- ld [wExpAmountGained], a
- adc b
- ld [hl], a
- jr nc, .noCarry
- dec hl
- inc [hl]
- inc hl
- .noCarry
- ; calculate exp for the mon at max level, and cap the exp at that value
- inc hl
- push hl
- ld a, [wWhichPokemon]
- ld c, a
- ld b, 0
- ld hl, wPartySpecies
- add hl, bc
- ld a, [hl] ; species
- ld [wd0b5], a
- call GetMonHeader
- ld d, MAX_LEVEL
- callab CalcExperience ; get max exp
- ; compare max exp with current exp
- ld a, [hExperience]
- ld b, a
- ld a, [hExperience + 1]
- ld c, a
- ld a, [hExperience + 2]
- ld d, a
- pop hl
- ld a, [hld]
- sub d
- ld a, [hld]
- sbc c
- ld a, [hl]
- sbc b
- jr c, .next2
- ; the mon's exp is greater than the max exp, so overwrite it with the max exp
- ld a, b
- ld [hli], a
- ld a, c
- ld [hli], a
- ld a, d
- ld [hld], a
- dec hl
- .next2
- push hl
- ld a, [wWhichPokemon]
- ld hl, wPartyMonNicks
- call GetPartyMonName
- ld hl, GainedText
- call PrintText
- xor a ; PLAYER_PARTY_DATA
- ld [wMonDataLocation], a
- call LoadMonData
- pop hl
- ld bc, wPartyMon1Level - wPartyMon1Exp
- add hl, bc
- push hl
- callba CalcLevelFromExperience
- pop hl
- ld a, [hl] ; current level
- cp d
- jp z, .nextMon ; if level didn't change, go to next mon
- ld a, [wCurEnemyLVL]
- push af
- push hl
- ld a, d
- ld [wCurEnemyLVL], a
- ld [hl], a
- ld bc, wPartyMon1Species - wPartyMon1Level
- add hl, bc
- ld a, [hl] ; species
- ld [wd0b5], a
- ld [wd11e], a
- call GetMonHeader
- ld bc, (wPartyMon1MaxHP + 1) - wPartyMon1Species
- add hl, bc
- push hl
- ld a, [hld]
- ld c, a
- ld b, [hl]
- push bc ; push max HP (from before levelling up)
- ld d, h
- ld e, l
- ld bc, (wPartyMon1HPExp - 1) - wPartyMon1MaxHP
- add hl, bc
- ld b, $1 ; consider stat exp when calculating stats
- call CalcStats
- pop bc ; pop max HP (from before levelling up)
- pop hl
- ld a, [hld]
- sub c
- ld c, a
- ld a, [hl]
- sbc b
- ld b, a ; bc = difference between old max HP and new max HP after levelling
- ld de, (wPartyMon1HP + 1) - wPartyMon1MaxHP
- add hl, de
- ; add to the current HP the amount of max HP gained when levelling
- ld a, [hl] ; wPartyMon1HP + 1
- add c
- ld [hld], a
- ld a, [hl] ; wPartyMon1HP + 1
- adc b
- ld [hl], a ; wPartyMon1HP
- ld a, [wPlayerMonNumber]
- ld b, a
- ld a, [wWhichPokemon]
- cp b ; is the current mon in battle?
- jr nz, .printGrewLevelText
- ; current mon is in battle
- ld de, wBattleMonHP
- ; copy party mon HP to battle mon HP
- ld a, [hli]
- ld [de], a
- inc de
- ld a, [hl]
- ld [de], a
- ; copy other stats from party mon to battle mon
- ld bc, wPartyMon1Level - (wPartyMon1HP + 1)
- add hl, bc
- push hl
- ld de, wBattleMonLevel
- ld bc, 1 + NUM_STATS * 2 ; size of stats
- call CopyData
- pop hl
- ld a, [wPlayerBattleStatus3]
- bit 3, a ; is the mon transformed?
- jr nz, .recalcStatChanges
- ; the mon is not transformed, so update the unmodified stats
- ld de, wPlayerMonUnmodifiedLevel
- ld bc, 1 + NUM_STATS * 2
- call CopyData
- .recalcStatChanges
- xor a ; battle mon
- ld [wCalculateWhoseStats], a
- callab CalculateModifiedStats
- callab ApplyBurnAndParalysisPenaltiesToPlayer
- callab ApplyBadgeStatBoosts
- callab DrawPlayerHUDAndHPBar
- callab PrintEmptyString
- call SaveScreenTilesToBuffer1
- .printGrewLevelText
- ld hl, GrewLevelText
- call PrintText
- xor a ; PLAYER_PARTY_DATA
- ld [wMonDataLocation], a
- call LoadMonData
- ld d, $1
- callab PrintStatsBox
- call WaitForTextScrollButtonPress
- call LoadScreenTilesFromBuffer1
- xor a ; PLAYER_PARTY_DATA
- ld [wMonDataLocation], a
- ld a, [wd0b5]
- ld [wd11e], a
- predef LearnMoveFromLevelUp
- ld hl, wCanEvolveFlags
- ld a, [wWhichPokemon]
- ld c, a
- ld b, FLAG_SET
- predef FlagActionPredef
- pop hl
- pop af
- ld [wCurEnemyLVL], a
- .nextMon
- ld a, [wPartyCount]
- ld b, a
- ld a, [wWhichPokemon]
- inc a
- cp b
- jr z, .done
- ld [wWhichPokemon], a
- ld bc, wPartyMon2 - wPartyMon1
- ld hl, wPartyMon1
- call AddNTimes
- jp .partyMonLoop
- .done
- ld hl, wPartyGainExpFlags
- xor a
- ld [hl], a ; clear gain exp flags
- ld a, [wPlayerMonNumber]
- ld c, a
- ld b, FLAG_SET
- push bc
- predef FlagActionPredef ; set the gain exp flag for the mon that is currently out
- ld hl, wPartyFoughtCurrentEnemyFlags
- xor a
- ld [hl], a
- pop bc
- predef_jump FlagActionPredef ; set the fought current enemy flag for the mon that is currently out
- ; divide enemy base stats, catch rate, and base exp by the number of mons gaining exp
- DivideExpDataByNumMonsGainingExp:
- ld a, [wPartyGainExpFlags]
- ld b, a
- xor a
- ld c, $8
- ld d, $0
- .countSetBitsLoop ; loop to count set bits in wPartyGainExpFlags
- xor a
- srl b
- adc d
- ld d, a
- dec c
- jr nz, .countSetBitsLoop
- cp $2
- ret c ; return if only one mon is gaining exp
- ld [wd11e], a ; store number of mons gaining exp
- ld hl, wEnemyMonBaseStats
- ld c, wEnemyMonBaseExp + 1 - wEnemyMonBaseStats
- .divideLoop
- xor a
- ld [H_DIVIDEND], a
- ld a, [hl]
- ld [H_DIVIDEND + 1], a
- ld a, [wd11e]
- ld [H_DIVISOR], a
- ld b, $2
- call Divide ; divide value by number of mons gaining exp
- ld a, [H_QUOTIENT + 3]
- ld [hli], a
- dec c
- jr nz, .divideLoop
- ret
- ; multiplies exp by 1.5
- BoostExp:
- ld a, [H_QUOTIENT + 2]
- ld b, a
- ld a, [H_QUOTIENT + 3]
- ld c, a
- srl b
- rr c
- add c
- ld [H_QUOTIENT + 3], a
- ld a, [H_QUOTIENT + 2]
- adc b
- ld [H_QUOTIENT + 2], a
- ret
- GainedText:
- TX_FAR _GainedText
- TX_ASM
- ld a, [wBoostExpByExpAll]
- ld hl, WithExpAllText
- and a
- ret nz
- ld hl, ExpPointsText
- ld a, [wGainBoostedExp]
- and a
- ret z
- ld hl, BoostedText
- ret
- WithExpAllText:
- TX_FAR _WithExpAllText
- TX_ASM
- ld hl, ExpPointsText
- ret
- BoostedText:
- TX_FAR _BoostedText
- ExpPointsText:
- TX_FAR _ExpPointsText
- db "@"
- GrewLevelText:
- TX_FAR _GrewLevelText
- TX_SFX_LEVEL_UP
- db "@"
|