123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514 |
- ; try to evolve the mon in [wWhichPokemon]
- TryEvolvingMon:
- ld hl, wCanEvolveFlags
- xor a
- ld [hl], a
- ld a, [wWhichPokemon]
- ld c, a
- ld b, FLAG_SET
- call Evolution_FlagAction
- ; this is only called after battle
- ; it is supposed to do level up evolutions, though there is a bug that allows item evolutions to occur
- EvolutionAfterBattle:
- ld a, [hTilesetType]
- push af
- xor a
- ld [wEvolutionOccurred], a
- dec a
- ld [wWhichPokemon], a
- push hl
- push bc
- push de
- ld hl, wPartyCount
- push hl
- Evolution_PartyMonLoop: ; loop over party mons
- ld hl, wWhichPokemon
- inc [hl]
- pop hl
- inc hl
- ld a, [hl]
- cp $ff ; have we reached the end of the party?
- jp z, .done
- ld [wEvoOldSpecies], a
- push hl
- ld a, [wWhichPokemon]
- ld c, a
- ld hl, wCanEvolveFlags
- ld b, FLAG_TEST
- call Evolution_FlagAction
- ld a, c
- and a ; is the mon's bit set?
- jp z, Evolution_PartyMonLoop ; if not, go to the next mon
- ld a, [wEvoOldSpecies]
- dec a
- ld b, 0
- ld hl, EvosMovesPointerTable
- add a
- rl b
- ld c, a
- add hl, bc
- ld a, [hli]
- ld h, [hl]
- ld l, a
- push hl
- ld a, [wcf91]
- push af
- xor a ; PLAYER_PARTY_DATA
- ld [wMonDataLocation], a
- call LoadMonData
- pop af
- ld [wcf91], a
- pop hl
- .evoEntryLoop ; loop over evolution entries
- ld a, [hli]
- and a ; have we reached the end of the evolution data?
- jr z, Evolution_PartyMonLoop
- ld b, a ; evolution type
- cp EV_TRADE
- jr z, .checkTradeEvo
- ; not trade evolution
- ld a, [wLinkState]
- cp LINK_STATE_TRADING
- jr z, Evolution_PartyMonLoop ; if trading, go the next mon
- ld a, b
- cp EV_ITEM
- jr z, .checkItemEvo
- ld a, [wForceEvolution]
- and a
- jr nz, Evolution_PartyMonLoop
- ld a, b
- cp EV_LEVEL
- jr z, .checkLevel
- .checkTradeEvo
- ld a, [wLinkState]
- cp LINK_STATE_TRADING
- jp nz, .nextEvoEntry1 ; if not trading, go to the next evolution entry
- ld a, [hli] ; level requirement
- ld b, a
- ld a, [wLoadedMonLevel]
- cp b ; is the mon's level greater than the evolution requirement?
- jp c, Evolution_PartyMonLoop ; if so, go the next mon
- jr .doEvolution
- .checkItemEvo
- ld a, [hli]
- ld b, a ; evolution item
- ld a, [wcf91] ; this is supposed to be the last item used, but it is also used to hold species numbers
- cp b ; was the evolution item in this entry used?
- jp nz, .nextEvoEntry1 ; if not, go to the next evolution entry
- .checkLevel
- ld a, [hli] ; level requirement
- ld b, a
- ld a, [wLoadedMonLevel]
- cp b ; is the mon's level greater than the evolution requirement?
- jp c, .nextEvoEntry2 ; if so, go the next evolution entry
- .doEvolution
- ld [wCurEnemyLVL], a
- ld a, 1
- ld [wEvolutionOccurred], a
- push hl
- ld a, [hl]
- ld [wEvoNewSpecies], a
- ld a, [wWhichPokemon]
- ld hl, wPartyMonNicks
- call GetPartyMonName
- call CopyStringToCF4B
- ld hl, IsEvolvingText
- call PrintText
- ld c, 50
- call DelayFrames
- xor a
- ld [H_AUTOBGTRANSFERENABLED], a
- coord hl, 0, 0
- lb bc, 12, 20
- call ClearScreenArea
- ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a
- ld a, $ff
- ld [wUpdateSpritesEnabled], a
- call ClearSprites
- callab EvolveMon
- jp c, CancelledEvolution
- ld hl, EvolvedText
- call PrintText
- pop hl
- ld a, [hl]
- ld [wd0b5], a
- ld [wLoadedMonSpecies], a
- ld [wEvoNewSpecies], a
- ld a, MONSTER_NAME
- ld [wNameListType], a
- ld a, BANK(TrainerNames) ; bank is not used for monster names
- ld [wPredefBank], a
- call GetName
- push hl
- ld hl, IntoText
- call PrintText_NoCreatingTextBox
- ld a, SFX_GET_ITEM_2
- call PlaySoundWaitForCurrent
- call WaitForSoundToFinish
- ld c, 40
- call DelayFrames
- call ClearScreen
- call RenameEvolvedMon
- ld a, [wd11e]
- push af
- ld a, [wd0b5]
- ld [wd11e], a
- predef IndexToPokedex
- ld a, [wd11e]
- dec a
- ld hl, BaseStats
- ld bc, MonBaseStatsEnd - MonBaseStats
- call AddNTimes
- ld de, wMonHeader
- call CopyData
- ld a, [wd0b5]
- ld [wMonHIndex], a
- pop af
- ld [wd11e], a
- ld hl, wLoadedMonHPExp - 1
- ld de, wLoadedMonStats
- ld b, $1
- call CalcStats
- ld a, [wWhichPokemon]
- ld hl, wPartyMon1
- ld bc, wPartyMon2 - wPartyMon1
- call AddNTimes
- ld e, l
- ld d, h
- push hl
- push bc
- ld bc, wPartyMon1MaxHP - wPartyMon1
- add hl, bc
- ld a, [hli]
- ld b, a
- ld c, [hl]
- ld hl, wLoadedMonMaxHP + 1
- ld a, [hld]
- sub c
- ld c, a
- ld a, [hl]
- sbc b
- ld b, a
- ld hl, wLoadedMonHP + 1
- ld a, [hl]
- add c
- ld [hld], a
- ld a, [hl]
- adc b
- ld [hl], a
- dec hl
- pop bc
- call CopyData
- ld a, [wd0b5]
- ld [wd11e], a
- xor a
- ld [wMonDataLocation], a
- call LearnMoveFromLevelUp
- pop hl
- predef SetPartyMonTypes
- ld a, [wIsInBattle]
- and a
- call z, Evolution_ReloadTilesetTilePatterns
- predef IndexToPokedex
- ld a, [wd11e]
- dec a
- ld c, a
- ld b, FLAG_SET
- ld hl, wPokedexOwned
- push bc
- call Evolution_FlagAction
- pop bc
- ld hl, wPokedexSeen
- call Evolution_FlagAction
- pop de
- pop hl
- ld a, [wLoadedMonSpecies]
- ld [hl], a
- push hl
- ld l, e
- ld h, d
- jr .nextEvoEntry2
- .nextEvoEntry1
- inc hl
- .nextEvoEntry2
- inc hl
- jp .evoEntryLoop
- .done
- pop de
- pop bc
- pop hl
- pop af
- ld [hTilesetType], a
- ld a, [wLinkState]
- cp LINK_STATE_TRADING
- ret z
- ld a, [wIsInBattle]
- and a
- ret nz
- ld a, [wEvolutionOccurred]
- and a
- call nz, PlayDefaultMusic
- ret
- RenameEvolvedMon:
- ; Renames the mon to its new, evolved form's standard name unless it had a
- ; nickname, in which case the nickname is kept.
- ld a, [wd0b5]
- push af
- ld a, [wMonHIndex]
- ld [wd0b5], a
- call GetName
- pop af
- ld [wd0b5], a
- ld hl, wcd6d
- ld de, wcf4b
- .compareNamesLoop
- ld a, [de]
- inc de
- cp [hl]
- inc hl
- ret nz
- cp "@"
- jr nz, .compareNamesLoop
- ld a, [wWhichPokemon]
- ld bc, NAME_LENGTH
- ld hl, wPartyMonNicks
- call AddNTimes
- push hl
- call GetName
- ld hl, wcd6d
- pop de
- jp CopyData
- CancelledEvolution:
- ld hl, StoppedEvolvingText
- call PrintText
- call ClearScreen
- pop hl
- call Evolution_ReloadTilesetTilePatterns
- jp Evolution_PartyMonLoop
- EvolvedText:
- TX_FAR _EvolvedText
- db "@"
- IntoText:
- TX_FAR _IntoText
- db "@"
- StoppedEvolvingText:
- TX_FAR _StoppedEvolvingText
- db "@"
- IsEvolvingText:
- TX_FAR _IsEvolvingText
- db "@"
- Evolution_ReloadTilesetTilePatterns:
- ld a, [wLinkState]
- cp LINK_STATE_TRADING
- ret z
- jp ReloadTilesetTilePatterns
- LearnMoveFromLevelUp:
- ld hl, EvosMovesPointerTable
- ld a, [wd11e] ; species
- ld [wcf91], a
- dec a
- ld bc, 0
- ld hl, EvosMovesPointerTable
- add a
- rl b
- ld c, a
- add hl, bc
- ld a, [hli]
- ld h, [hl]
- ld l, a
- .skipEvolutionDataLoop ; loop to skip past the evolution data, which comes before the move data
- ld a, [hli]
- and a ; have we reached the end of the evolution data?
- jr nz, .skipEvolutionDataLoop ; if not, jump back up
- .learnSetLoop ; loop over the learn set until we reach a move that is learnt at the current level or the end of the list
- ld a, [hli]
- and a ; have we reached the end of the learn set?
- jr z, .done ; if we've reached the end of the learn set, jump
- ld b, a ; level the move is learnt at
- ld a, [wCurEnemyLVL]
- cp b ; is the move learnt at the mon's current level?
- ld a, [hli] ; move ID
- jr nz, .learnSetLoop
- ld d, a ; ID of move to learn
- ld a, [wMonDataLocation]
- and a
- jr nz, .next
- ; If [wMonDataLocation] is 0 (PLAYER_PARTY_DATA), get the address of the mon's
- ; current moves in party data. Every call to this function sets
- ; [wMonDataLocation] to 0 because other data locations are not supported.
- ; If it is not 0, this function will not work properly.
- ld hl, wPartyMon1Moves
- ld a, [wWhichPokemon]
- ld bc, wPartyMon2 - wPartyMon1
- call AddNTimes
- .next
- ld b, NUM_MOVES
- .checkCurrentMovesLoop ; check if the move to learn is already known
- ld a, [hli]
- cp d
- jr z, .done ; if already known, jump
- dec b
- jr nz, .checkCurrentMovesLoop
- ld a, d
- ld [wMoveNum], a
- ld [wd11e], a
- call GetMoveName
- call CopyStringToCF4B
- predef LearnMove
- .done
- ld a, [wcf91]
- ld [wd11e], a
- ret
- ; writes the moves a mon has at level [wCurEnemyLVL] to [de]
- ; move slots are being filled up sequentially and shifted if all slots are full
- WriteMonMoves:
- call GetPredefRegisters
- push hl
- push de
- push bc
- ld hl, EvosMovesPointerTable
- ld b, 0
- ld a, [wcf91] ; cur mon ID
- dec a
- add a
- rl b
- ld c, a
- add hl, bc
- ld a, [hli]
- ld h, [hl]
- ld l, a
- .skipEvoEntriesLoop
- ld a, [hli]
- and a
- jr nz, .skipEvoEntriesLoop
- jr .firstMove
- .nextMove
- pop de
- .nextMove2
- inc hl
- .firstMove
- ld a, [hli] ; read level of next move in learnset
- and a
- jp z, .done ; end of list
- ld b, a
- ld a, [wCurEnemyLVL]
- cp b
- jp c, .done ; mon level < move level (assumption: learnset is sorted by level)
- ld a, [wLearningMovesFromDayCare]
- and a
- jr z, .skipMinLevelCheck
- ld a, [wDayCareStartLevel]
- cp b
- jr nc, .nextMove2 ; min level >= move level
- .skipMinLevelCheck
- ; check if the move is already known
- push de
- ld c, NUM_MOVES
- .alreadyKnowsCheckLoop
- ld a, [de]
- inc de
- cp [hl]
- jr z, .nextMove
- dec c
- jr nz, .alreadyKnowsCheckLoop
- ; try to find an empty move slot
- pop de
- push de
- ld c, NUM_MOVES
- .findEmptySlotLoop
- ld a, [de]
- and a
- jr z, .writeMoveToSlot2
- inc de
- dec c
- jr nz, .findEmptySlotLoop
- ; no empty move slots found
- pop de
- push de
- push hl
- ld h, d
- ld l, e
- call WriteMonMoves_ShiftMoveData ; shift all moves one up (deleting move 1)
- ld a, [wLearningMovesFromDayCare]
- and a
- jr z, .writeMoveToSlot
- ; shift PP as well if learning moves from day care
- push de
- ld bc, wPartyMon1PP - (wPartyMon1Moves + 3)
- add hl, bc
- ld d, h
- ld e, l
- call WriteMonMoves_ShiftMoveData ; shift all move PP data one up
- pop de
- .writeMoveToSlot
- pop hl
- .writeMoveToSlot2
- ld a, [hl]
- ld [de], a
- ld a, [wLearningMovesFromDayCare]
- and a
- jr z, .nextMove
- ; write move PP value if learning moves from day care
- push hl
- ld a, [hl]
- ld hl, wPartyMon1PP - wPartyMon1Moves
- add hl, de
- push hl
- dec a
- ld hl, Moves
- ld bc, MoveEnd - Moves
- call AddNTimes
- ld de, wBuffer
- ld a, BANK(Moves)
- call FarCopyData
- ld a, [wBuffer + 5]
- pop hl
- ld [hl], a
- pop hl
- jr .nextMove
- .done
- pop bc
- pop de
- pop hl
- ret
- ; shifts all move data one up (freeing 4th move slot)
- WriteMonMoves_ShiftMoveData:
- ld c, NUM_MOVES - 1
- .loop
- inc de
- ld a, [de]
- ld [hli], a
- dec c
- jr nz, .loop
- ret
- Evolution_FlagAction:
- predef_jump FlagActionPredef
- INCLUDE "data/evos_moves.asm"
|