; try to evolve the mon in [wWhichPokemon] TryEvolvingMon: ; 3adb8 (e:6db8) EvolveTradeMon: 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: ; 3adc6 (e:6dc6) 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: ; 3add8 (e:6dd8) ; 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, [wIsInBattle] ; are we in battle? and a ld a, [hli] jp nz, .nextEvoEntry1 ; don't evolve if we're in a battle as wcf91 could be holding the last mon sent out ld b, a ; evolution item ld a, [wcf91] ; last item used 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(MonsterNames) ; 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: ; 3afa8 (e:6fa8) ; 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: ; 3afdf (e:6fdf) ld hl, StoppedEvolvingText call PrintText call ClearScreen pop hl call Evolution_ReloadTilesetTilePatterns jp Evolution_PartyMonLoop EvolvedText: ; 3afef (e:6fef) TX_FAR _EvolvedText db "@" IntoText: ; 3aff4 (e:6ff4) TX_FAR _IntoText db "@" StoppedEvolvingText: ; 3aff9 (e:6ff9) TX_FAR _StoppedEvolvingText db "@" IsEvolvingText: ; 3affe (e:6ffes) TX_FAR _IsEvolvingText db "@" Evolution_ReloadTilesetTilePatterns: ; 3b003 (e:7003) ld a, [wLinkState] cp LINK_STATE_TRADING ret z jp ReloadTilesetTilePatterns LearnMoveFromLevelUp: ; 3b00c (e:700c) ld a, [wd11e] ; species ld [wcf91], a call GetMonLearnset .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 ld a, b and a jr z, .done callab IsThisPartymonStarterPikachu_Party jr nc, .done ld a, [wMoveNum] cp THUNDERBOLT jr z, .foundThunderOrThunderbolt cp THUNDER jr nz, .done .foundThunderOrThunderbolt ld a, $5 ld [wd49c], a ld a, $85 ld [wPikachuMood], a .done ld a, [wcf91] ld [wd11e], a ret Func_3b079: ; 3b079 (e:7079) ld a, [wcf91] push af call Func_3b0a2 jr c, .asm_3b09c call Func_3b10f jr nc, .asm_3b096 call Func_3b0a2 jr c, .asm_3b09c call Func_3b10f jr nc, .asm_3b096 call Func_3b0a2 jr c, .asm_3b09c .asm_3b096 pop af ld [wcf91], a and a ret .asm_3b09c pop af ld [wcf91], a scf ret Func_3b0a2: ; 3b0a2 (e:70a2) ; XXX what is wcf91 entering this function? ld a, [wd11e] ld [wMoveNum], a predef CanLearnTM ld a, c and a jr nz, .asm_3b0ec ld hl, Pointer_3b0ee ld a, [wcf91] ld de, $1 call IsInArray jr c, .asm_3b0d2 ld a, $ff ld [wMonHGrowthRate], a ld a, [wd11e] ld hl, wMonHMoves ld de, $1 call IsInArray jr c, .asm_3b0ec .asm_3b0d2 ld a, [wd11e] ld d, a call GetMonLearnset .loop ld a, [hli] and a jr z, .asm_3b0ea ld b, a ld a, [wCurEnemyLVL] cp b jr c, .asm_3b0ea ld a, [hli] cp d jr z, .asm_3b0ec jr .loop .asm_3b0ea and a ret .asm_3b0ec scf ret Pointer_3b0ee: ; 3b0ee (e:70ee) db NIDOKING db IVYSAUR db EXEGGUTOR db GENGAR db NIDOQUEEN db ARCANINE db GYARADOS db BLASTOISE db GOLEM db DRAGONITE db NINETALES db DRAGONAIR db KABUTOPS db OMASTAR db JIGGLYPUFF db FLAREON db JOLTEON db VAPOREON db BEEDRILL db BUTTERFREE db MACHAMP db CLOYSTER db CLEFABLE db ALAKAZAM db STARMIE db VENUSAUR db TENTACRUEL db CHARMELEON db WARTORTLE db CHARIZARD db VILEPLUME db VICTREEBEL db $ff Func_3b10f: ; 3b10f (e:710f) ld c, $0 .asm_3b111 ld hl, EvosMovesPointerTable ld b, $0 add hl, bc add hl, bc ld a, [hli] ld h, [hl] ld l, a .asm_3b11b ld a, [hli] and a jr z, .asm_3b130 cp $2 jr nz, .asm_3b124 inc hl .asm_3b124 inc hl ld a, [wcf91] cp [hl] jr z, .asm_3b138 inc hl ld a, [hl] and a jr nz, .asm_3b11b .asm_3b130 inc c ld a, c cp VICTREEBEL jr c, .asm_3b111 and a ret .asm_3b138 inc c ld a, c ld [wcf91], a scf 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: ; 3113f (e:713f) call GetPredefRegisters push hl push de push bc call GetMonLearnset 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: ; 3b1c3 (e:71c3) ld c, NUM_MOVES - 1 .loop inc de ld a, [de] ld [hli], a dec c jr nz, .loop ret Evolution_FlagAction: ; 3b1cc (e:71cc) predef_jump FlagActionPredef GetMonLearnset: ; 3b1d1 (e:71d1) ld hl, EvosMovesPointerTable ld b, 0 ld a, [wcf91] dec a ld c, a add hl, bc 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 ret INCLUDE "data/evos_moves.asm"