EvolvePokemon: ld hl, wEvolvableFlags xor a ld [hl], a ld a, [wCurPartyMon] ld c, a ld b, SET_FLAG call EvoFlagAction EvolveAfterBattle: xor a ld [wMonTriedToEvolve], a dec a ld [wCurPartyMon], a push hl push bc push de ld hl, wPartyCount push hl EvolveAfterBattle_MasterLoop: ld hl, wCurPartyMon inc [hl] pop hl inc hl ld a, [hl] cp $ff jp z, .ReturnToMap ld [wEvolutionOldSpecies], a push hl ld a, [wCurPartyMon] ld c, a ld hl, wEvolvableFlags ld b, CHECK_FLAG call EvoFlagAction ld a, c and a jp z, EvolveAfterBattle_MasterLoop ld a, [wEvolutionOldSpecies] call GetPokemonIndexFromID ld b, h ld c, l ld hl, EvosAttacksPointers ld a, BANK(EvosAttacksPointers) call LoadDoubleIndirectPointer ldh [hTemp], a push hl xor a ld [wMonType], a predef CopyMonToTempMon pop hl .loop call GetNextEvoAttackByte and a jr z, EvolveAfterBattle_MasterLoop ld b, a cp EVOLVE_TRADE jr z, .trade ld a, [wLinkMode] and a jp nz, .dont_evolve_check ld a, b cp EVOLVE_ITEM jp z, .item ld a, [wForceEvolution] and a jp nz, .dont_evolve_check ld a, b cp EVOLVE_LEVEL jp z, .level cp EVOLVE_HAPPINESS jr z, .happiness ; EVOLVE_STAT call GetNextEvoAttackByte ld c, a ld a, [wTempMonLevel] cp c jp c, .skip_evolution_species_parameter call IsMonHoldingEverstone jp z, .skip_evolution_species_parameter push hl ld de, wTempMonAttack ld hl, wTempMonDefense ld c, 2 call CompareBytes ld c, ATK_EQ_DEF jr z, .got_tyrogue_evo ld c, ATK_LT_DEF jr c, .got_tyrogue_evo ld c, ATK_GT_DEF .got_tyrogue_evo pop hl call GetNextEvoAttackByte cp c jp nz, .skip_evolution_species jp .proceed .happiness ld a, [wTempMonHappiness] cp HAPPINESS_TO_EVOLVE jp c, .skip_evolution_species_parameter call IsMonHoldingEverstone jp z, .skip_evolution_species_parameter call GetNextEvoAttackByte cp TR_ANYTIME jr z, .proceed cp TR_MORNDAY jr z, .happiness_daylight ; TR_NITE ld a, [wTimeOfDay] cp NITE_F jp nz, .skip_evolution_species jr .proceed .happiness_daylight ld a, [wTimeOfDay] cp NITE_F jp z, .skip_evolution_species jr .proceed .trade ld a, [wLinkMode] and a jp z, .skip_evolution_species_parameter call IsMonHoldingEverstone jp z, .skip_evolution_species_parameter call GetNextEvoAttackByte ld b, a inc a jr z, .proceed ld a, [wLinkMode] cp LINK_TIMECAPSULE jp z, .skip_evolution_species ld a, [wTempMonItem] cp b jp nz, .skip_evolution_species xor a ld [wTempMonItem], a jr .proceed .item call GetNextEvoAttackByte ld b, a ld a, [wCurItem] cp b jp nz, .skip_evolution_species ld a, [wForceEvolution] and a jp z, .skip_evolution_species ld a, [wLinkMode] and a jp nz, .skip_evolution_species jr .proceed .level call GetNextEvoAttackByte ld b, a ld a, [wTempMonLevel] cp b jp c, .skip_evolution_species call IsMonHoldingEverstone jp z, .skip_evolution_species .proceed ld a, [wTempMonLevel] ld [wCurPartyLevel], a ld a, $1 ld [wMonTriedToEvolve], a ldh a, [hTemp] call GetFarWord call GetPokemonIDFromIndex ld [wEvolutionNewSpecies], a ld a, [wCurPartyMon] ld hl, wPartyMonNicknames call GetNickname call CopyName1 ld hl, EvolvingText call PrintText ld c, 50 call DelayFrames xor a ldh [hBGMapMode], a hlcoord 0, 0 lb bc, 12, 20 call ClearBox ld a, $1 ldh [hBGMapMode], a call ClearSprites farcall EvolutionAnimation push af call ClearSprites pop af jp c, CancelEvolution ld hl, CongratulationsYourPokemonText call PrintText ld a, [wEvolutionNewSpecies] ld [wCurSpecies], a ld [wTempMonSpecies], a ld [wNamedObjectIndex], a call GetPokemonName push hl ld hl, EvolvedIntoText call PrintTextboxText farcall StubbedTrainerRankings_MonsEvolved ld de, MUSIC_NONE call PlayMusic ld de, SFX_CAUGHT_MON call PlaySFX call WaitSFX ld c, 40 call DelayFrames call ClearTilemap call UpdateSpeciesNameIfNotNicknamed call GetBaseData ld hl, wTempMonExp + 2 ld de, wTempMonMaxHP ld b, TRUE predef CalcMonStats ld a, [wCurPartyMon] ld hl, wPartyMons ld bc, PARTYMON_STRUCT_LENGTH call AddNTimes ld e, l ld d, h ld bc, MON_MAXHP add hl, bc ld a, [hli] ld b, a ld c, [hl] ld hl, wTempMonMaxHP + 1 ld a, [hld] sub c ld c, a ld a, [hl] sbc b ld b, a ld hl, wTempMonHP + 1 ld a, [hl] add c ld [hld], a ld a, [hl] adc b ld [hl], a ld hl, wTempMonSpecies ld bc, PARTYMON_STRUCT_LENGTH call CopyBytes ld a, [wCurSpecies] ld [wTempSpecies], a xor a ld [wMonType], a ; call LearnEvolutionMove call LearnLevelMoves ld a, [wTempSpecies] call SetSeenAndCaughtMon ld a, [wTempSpecies] call GetPokemonIndexFromID ld a, l sub LOW(UNOWN) if HIGH(UNOWN) == 0 or h else jr nz, .skip_unown if HIGH(UNOWN) == 1 dec h else ld a, h cp HIGH(UNOWN) endc endc jr nz, .skip_unown ld hl, wTempMonDVs predef GetUnownLetter callfar UpdateUnownDex .skip_unown pop de pop hl ld a, [wTempMonSpecies] ld [hl], a push hl ld l, e ld h, d jp EvolveAfterBattle_MasterLoop .dont_evolve_check ld a, b cp EVOLVE_STAT jr nz, .skip_evolution_species_parameter inc hl .skip_evolution_species_parameter inc hl .skip_evolution_species inc hl inc hl jp .loop .UnusedReturnToMap: ; unreferenced pop hl .ReturnToMap: pop de pop bc pop hl ld a, [wLinkMode] and a ret nz ld a, [wBattleMode] and a ret nz ld a, [wMonTriedToEvolve] and a call nz, RestartMapMusic ret ; BUG: Does not take in the designated move correctly, resulting in strange behaviour usually seen when GetMoveIDFromIndex takes an 8-bit index. ; Comments proceeding ; LearnEvolutionMove: ; ld a, [wTempSpecies] ; ld [wCurPartySpecies], a ; call GetPokemonIndexFromID ; ld b, h ; ld c, l ; ld hl, EvolutionMoves ; add hl, bc ; add hl, bc ; dec hl ; dec hl ; ld a, [hli] ; ld h, [hl] ; ld l, a ; Moves through the table by going up according to the Pokemon's ID, storing the equivalent move in hl. This is fine. ; or h ; hl == 0? ; ret z ; call GetMoveIDFromIndex ; grabs what's in hl (the move) and converts it to 8-bit...or something like that. anyway, it should return in register a. ; push hl ; I don't actually know why it does this. Removing it produces manmade horrors beyond my comprehension, so it isn't part of the current problem. ; ld d, a ; preserve a ; ld hl, wPartyMon1Moves ; ld a, [wCurPartyMon] ; ld bc, PARTYMON_STRUCT_LENGTH ; call AddNTimes ; ld b, NUM_MOVES ; .check_move ; ld a, [hli] ; cp d ; use preserved a to check if a move is there ; jr z, .has_move ; dec b ; jr nz, .check_move ; ld a, d ; take the preserved a and reload ; ld [wPutativeTMHMMove], a ; proceed to learn the move with adequate preprep ; ld [wNamedObjectIndex], a ; call GetMoveName ; call CopyName1 ; predef LearnMove ; ld a, [wCurPartySpecies] ; ld [wTempSpecies], a ; .has_move ; pop hl ; ret ; so wtf is going on UpdateSpeciesNameIfNotNicknamed: ld a, [wCurSpecies] push af ld a, [wBaseSpecies] ld [wNamedObjectIndex], a call GetPokemonName pop af ld [wCurSpecies], a ld hl, wStringBuffer1 ld de, wStringBuffer2 .loop ld a, [de] inc de cp [hl] inc hl ret nz cp "@" jr nz, .loop ld a, [wCurPartyMon] ld bc, MON_NAME_LENGTH ld hl, wPartyMonNicknames call AddNTimes push hl ld a, [wCurSpecies] ld [wNamedObjectIndex], a call GetPokemonName ld hl, wStringBuffer1 pop de ld bc, MON_NAME_LENGTH jp CopyBytes CancelEvolution: ld hl, StoppedEvolvingText call PrintText call ClearTilemap jp EvolveAfterBattle_MasterLoop IsMonHoldingEverstone: push hl ld a, [wCurPartyMon] ld hl, wPartyMon1Item ld bc, PARTYMON_STRUCT_LENGTH call AddNTimes ld a, [hl] cp EVERSTONE pop hl ret CongratulationsYourPokemonText: text_far _CongratulationsYourPokemonText text_end EvolvedIntoText: text_far _EvolvedIntoText text_end StoppedEvolvingText: text_far _StoppedEvolvingText text_end EvolvingText: text_far _EvolvingText text_end LearnLevelMoves: ld a, [wTempSpecies] ld [wCurPartySpecies], a call GetPokemonIndexFromID ld b, h ld c, l ld hl, EvosAttacksPointers ld a, BANK(EvosAttacksPointers) call LoadDoubleIndirectPointer ldh [hTemp], a call SkipEvolutions .find_move call GetNextEvoAttackByte and a jr z, .done ld b, a ld a, [wCurPartyLevel] cp b call GetNextEvoAttackByte ld e, a call GetNextEvoAttackByte ld d, a jr nz, .find_move push hl ld h, d ld l, e call GetMoveIDFromIndex ld d, a ld hl, wPartyMon1Moves ld a, [wCurPartyMon] ld bc, PARTYMON_STRUCT_LENGTH call AddNTimes ld b, NUM_MOVES .check_move call GetNextEvoAttackByte cp d jr z, .has_move dec b jr nz, .check_move jr .learn .has_move pop hl jr .find_move .learn ld a, d ld [wPutativeTMHMMove], a ld [wNamedObjectIndex], a call GetMoveName call CopyName1 predef LearnMove pop hl jr .find_move .done ld a, [wCurPartySpecies] ld [wTempSpecies], a ret FillMoves: ; Fill in moves at de for wCurPartySpecies at wCurPartyLevel push hl push de push bc ld a, [wCurPartySpecies] call GetPokemonIndexFromID ld b, h ld c, l ld hl, EvosAttacksPointers ld a, BANK(EvosAttacksPointers) call LoadDoubleIndirectPointer ldh [hTemp], a call SkipEvolutions jr .GetLevel .NextMove: pop de .GetMove: inc hl inc hl .GetLevel: call GetNextEvoAttackByte and a jp z, .done ld b, a ld a, [wCurPartyLevel] cp b jp c, .done ld a, [wSkipMovesBeforeLevelUp] and a jr z, .CheckMove ld a, [wPrevPartyLevel] cp b jr nc, .GetMove .CheckMove: push de ld c, NUM_MOVES ldh a, [hTemp] push hl call GetFarWord call GetMoveIDFromIndex pop hl ld b, a .CheckRepeat: ld a, [de] inc de cp b jr z, .NextMove dec c jr nz, .CheckRepeat pop de push de ld c, NUM_MOVES .CheckSlot: ld a, [de] and a jr z, .LearnMove inc de dec c jr nz, .CheckSlot pop de push de push hl ld h, d ld l, e call ShiftMoves ld a, [wEvolutionOldSpecies] and a jr z, .ShiftedMove push de ld bc, wPartyMon1PP - (wPartyMon1Moves + NUM_MOVES - 1) add hl, bc ld d, h ld e, l call ShiftMoves pop de .ShiftedMove: pop hl .LearnMove: ldh a, [hTemp] push hl call GetFarWord call GetMoveIDFromIndex pop hl ld b, a ld [de], a ld a, [wEvolutionOldSpecies] and a jr z, .NextMove push hl ld a, b ld hl, MON_PP - MON_MOVES add hl, de push hl ld l, a ld a, MOVE_PP call GetMoveAttribute pop hl ld [hl], a pop hl jp .NextMove .done pop bc pop de pop hl ret ShiftMoves: ld c, NUM_MOVES - 1 .loop inc de ld a, [de] ld [hli], a dec c jr nz, .loop ret EvoFlagAction: push de ld d, $0 predef SmallFarFlagAction pop de ret GetLowestEvolutionStage: ; Return the first mon to evolve into wCurPartySpecies. ; Instead of looking it up, we just load it from a table. This is a lot more efficient. ld a, [wCurPartySpecies] call GetPokemonIndexFromID ld bc, FirstEvoStages - 2 add hl, hl add hl, bc ld a, BANK(FirstEvoStages) call GetFarWord call GetPokemonIDFromIndex ld [wCurPartySpecies], a ret SkipEvolutions:: ; Receives a pointer to the evos and attacks for a mon in b:hl, and skips to the attacks. ld a, b call GetFarByte inc hl and a ret z cp EVOLVE_STAT jr nz, .no_extra_skip inc hl .no_extra_skip inc hl inc hl inc hl jr SkipEvolutions DetermineEvolutionItemResults:: ; in: b:de: pointer to evos and attacks struct, wCurItem: item ; out: de: species ID or zero; a, b, hl: clobbered ld h, d ld l, e ld de, 0 ld a, b ldh [hTemp], a .loop call GetNextEvoAttackByte and a ret z cp EVOLVE_STAT jr z, .skip_species_two_parameters cp EVOLVE_ITEM jr nz, .skip_species_parameter call GetNextEvoAttackByte ld b, a ld a, [wCurItem] cp b jr nz, .skip_species ldh a, [hTemp] call GetFarWord ld d, h ld e, l ret .skip_species_two_parameters inc hl .skip_species_parameter inc hl .skip_species inc hl inc hl jr .loop GetNextEvoAttackByte: ldh a, [hTemp] call GetFarByte inc hl ret