diff options
Diffstat (limited to 'engine/pokemon')
-rwxr-xr-x | engine/pokemon/experience.asm | 162 | ||||
-rwxr-xr-x | engine/pokemon/mon_stats.asm | 475 | ||||
-rwxr-xr-x | engine/pokemon/party_menu.asm | 783 | ||||
-rw-r--r-- | engine/pokemon/stats_screen.asm | 868 | ||||
-rwxr-xr-x | engine/pokemon/switchpartymons.asm | 145 | ||||
-rwxr-xr-x | engine/pokemon/tempmon.asm | 127 | ||||
-rwxr-xr-x | engine/pokemon/types.asm | 92 |
7 files changed, 2652 insertions, 0 deletions
diff --git a/engine/pokemon/experience.asm b/engine/pokemon/experience.asm new file mode 100755 index 00000000..7d026704 --- /dev/null +++ b/engine/pokemon/experience.asm @@ -0,0 +1,162 @@ +CalcLevel: + ld a, [wTempMonSpecies] + ld [wCurSpecies], a + call GetBaseData + ld d, 1 +.next_level + inc d + ld a, d + cp LOW(MAX_LEVEL + 1) + jr z, .got_level + call CalcExpAtLevel + push hl + ld hl, wTempMonExp + 2 + ldh a, [hProduct + 3] + ld c, a + ld a, [hld] + sub c + ldh a, [hProduct + 2] + ld c, a + ld a, [hld] + sbc c + ldh a, [hProduct + 1] + ld c, a + ld a, [hl] + sbc c + pop hl + jr nc, .next_level + +.got_level + dec d + ret + +CalcExpAtLevel: +; (a/b)*n**3 + c*n**2 + d*n - e + ld a, [wBaseGrowthRate] + add a + add a + ld c, a + ld b, 0 + ld hl, GrowthRates + add hl, bc +; Cube the level + call .LevelSquared + ld a, d + ldh [hMultiplier], a + call Multiply + +; Multiply by a + ld a, [hl] + and $f0 + swap a + ldh [hMultiplier], a + call Multiply +; Divide by b + ld a, [hli] + and $f + ldh [hDivisor], a + ld b, 4 + call Divide +; Push the cubic term to the stack + ldh a, [hQuotient + 1] + push af + ldh a, [hQuotient + 2] + push af + ldh a, [hQuotient + 3] + push af +; Square the level and multiply by the lower 7 bits of c + call .LevelSquared + ld a, [hl] + and $7f + ldh [hMultiplier], a + call Multiply +; Push the absolute value of the quadratic term to the stack + ldh a, [hProduct + 1] + push af + ldh a, [hProduct + 2] + push af + ldh a, [hProduct + 3] + push af + ld a, [hli] + push af +; Multiply the level by d + xor a + ldh [hMultiplicand + 0], a + ldh [hMultiplicand + 1], a + ld a, d + ldh [hMultiplicand + 2], a + ld a, [hli] + ldh [hMultiplier], a + call Multiply +; Subtract e + ld b, [hl] + ldh a, [hProduct + 3] + sub b + ldh [hMultiplicand + 2], a + ld b, 0 + ldh a, [hProduct + 2] + sbc b + ldh [hMultiplicand + 1], a + ldh a, [hProduct + 1] + sbc b + ldh [hMultiplicand], a +; If bit 7 of c is set, c is negative; otherwise, it's positive + pop af + and $80 + jr nz, .subtract +; Add c*n**2 to (d*n - e) + pop bc + ldh a, [hProduct + 3] + add b + ldh [hMultiplicand + 2], a + pop bc + ldh a, [hProduct + 2] + adc b + ldh [hMultiplicand + 1], a + pop bc + ldh a, [hProduct + 1] + adc b + ldh [hMultiplicand], a + jr .done_quadratic + +.subtract +; Subtract c*n**2 from (d*n - e) + pop bc + ldh a, [hProduct + 3] + sub b + ldh [hMultiplicand + 2], a + pop bc + ldh a, [hProduct + 2] + sbc b + ldh [hMultiplicand + 1], a + pop bc + ldh a, [hProduct + 1] + sbc b + ldh [hMultiplicand], a + +.done_quadratic +; Add (a/b)*n**3 to (d*n - e +/- c*n**2) + pop bc + ldh a, [hProduct + 3] + add b + ldh [hMultiplicand + 2], a + pop bc + ldh a, [hProduct + 2] + adc b + ldh [hMultiplicand + 1], a + pop bc + ldh a, [hProduct + 1] + adc b + ldh [hMultiplicand], a + ret + +.LevelSquared: + xor a + ldh [hMultiplicand + 0], a + ldh [hMultiplicand + 1], a + ld a, d + ldh [hMultiplicand + 2], a + ldh [hMultiplier], a + jp Multiply + +INCLUDE "data/growth_rates.asm" diff --git a/engine/pokemon/mon_stats.asm b/engine/pokemon/mon_stats.asm new file mode 100755 index 00000000..04285f87 --- /dev/null +++ b/engine/pokemon/mon_stats.asm @@ -0,0 +1,475 @@ +DrawPlayerHP: + ld a, 1 + jr DrawHP + +DrawEnemyHP: + ld a, 2 + +DrawHP: + ld [wWhichHPBar], a + push hl + push bc + ; box mons have full HP + ld a, [wMonType] + cp BOXMON + jr z, .at_least_1_hp + + ld a, [wTempMonHP] + ld b, a + ld a, [wTempMonHP + 1] + ld c, a + +; Any HP? + or b + jr nz, .at_least_1_hp + + xor a + ld c, a + ld e, a + ld a, 6 + ld d, a + jp .fainted + +.at_least_1_hp + ld a, [wTempMonMaxHP] + ld d, a + ld a, [wTempMonMaxHP + 1] + ld e, a + ld a, [wMonType] + cp BOXMON + jr nz, .not_boxmon + + ld b, d + ld c, e + +.not_boxmon + predef ComputeHPBarPixels + ld a, 6 + ld d, a + ld c, a + +.fainted + ld a, c + pop bc + ld c, a + pop hl + push de + push hl + push hl + call DrawBattleHPBar + pop hl + +; Print HP + bccoord 1, 1, 0 + add hl, bc + ld de, wTempMonHP + ld a, [wMonType] + cp BOXMON + jr nz, .not_boxmon_2 + ld de, wTempMonMaxHP +.not_boxmon_2 + lb bc, 2, 3 + call PrintNum + + ld a, "/" + ld [hli], a + +; Print max HP + ld de, wTempMonMaxHP + lb bc, 2, 3 + call PrintNum + pop hl + pop de + ret + +INCLUDE "engine/pokemon/stats_screen.asm" + +PrintTempMonStats: +; Print wTempMon's stats at hl, with spacing bc. + push bc + push hl + ld de, .StatNames + call PlaceString + pop hl + pop bc + add hl, bc + ld bc, SCREEN_WIDTH + add hl, bc + ld de, wTempMonAttack + lb bc, 2, 3 + call .PrintStat + ld de, wTempMonDefense + call .PrintStat + ld de, wTempMonSpclAtk + call .PrintStat + ld de, wTempMonSpclDef + call .PrintStat + ld de, wTempMonSpeed + jp PrintNum + +.PrintStat: + push hl + call PrintNum + pop hl + ld de, SCREEN_WIDTH * 2 + add hl, de + ret + +.StatNames: + db "ATTACK" + next "DEFENSE" + next "SPCL.ATK" + next "SPCL.DEF" + next "SPEED" + next "@" + +GetGender: +; Return the gender of a given monster (wCurPartyMon/wCurOTMon/wCurWildMon). +; When calling this function, a should be set to an appropriate wMonType value. + +; return values: +; a = 1: f = nc|nz; male +; a = 0: f = nc|z; female +; f = c: genderless + +; This is determined by comparing the Attack and Speed DVs +; with the species' gender ratio. + +; Figure out what type of monster struct we're looking at. + +; 0: PartyMon + ld hl, wPartyMon1DVs + ld bc, PARTYMON_STRUCT_LENGTH + ld a, [wMonType] + and a + jr z, .PartyMon + +; 1: OTPartyMon + ld hl, wOTPartyMon1DVs + dec a + jr z, .PartyMon + +; 2: sBoxMon + ld hl, sBoxMon1DVs + ld bc, BOXMON_STRUCT_LENGTH + dec a + jr z, .sBoxMon + +; 3: Unknown + ld hl, wTempMonDVs + dec a + jr z, .DVs + +; else: WildMon + ld hl, wEnemyMonDVs + jr .DVs + +; Get our place in the party/box. + +.PartyMon: +.sBoxMon + ld a, [wCurPartyMon] + call AddNTimes + +.DVs: +; sBoxMon data is read directly from SRAM. + ld a, [wMonType] + cp BOXMON + ld a, BANK(sBox) + call z, OpenSRAM + +; Attack DV + ld a, [hli] + and $f0 + ld b, a +; Speed DV + ld a, [hl] + and $f0 + swap a + +; Put our DVs together. + or b + ld b, a + +; Close SRAM if we were dealing with a sBoxMon. + ld a, [wMonType] + cp BOXMON + call z, CloseSRAM + +; We need the gender ratio to do anything with this. + push bc + ld a, [wCurPartySpecies] + dec a + ld hl, BaseData + BASE_GENDER + ld bc, BASE_DATA_SIZE + call AddNTimes + pop bc + + ld a, BANK(BaseData) + call GetFarByte + +; The higher the ratio, the more likely the monster is to be female. + + cp GENDER_UNKNOWN + jr z, .Genderless + + and a ; GENDER_F0? + jr z, .Male + + cp GENDER_F100 + jr z, .Female + +; Values below the ratio are male, and vice versa. + cp b + jr c, .Male + +.Female: + xor a + ret + +.Male: + ld a, 1 + and a + ret + +.Genderless: + scf + ret + +ListMovePP: + ld a, [wNumMoves] + inc a + ld c, a + ld a, NUM_MOVES + sub c + ld b, a + push hl + ld a, [wBuffer1] + ld e, a + ld d, $0 + ld a, $3e ; P + call .load_loop + ld a, b + and a + jr z, .skip + ld c, a + ld a, "-" + call .load_loop + +.skip + pop hl + inc hl + inc hl + inc hl + ld d, h + ld e, l + ld hl, wTempMonMoves + ld b, 0 +.loop + ld a, [hli] + and a + jr z, .done + push bc + push hl + push de + ld hl, wMenuCursorY + ld a, [hl] + push af + ld [hl], b + push hl + callfar GetMaxPPOfMove + pop hl + pop af + ld [hl], a + pop de + pop hl + push hl + ld bc, wTempMonPP - (wTempMonMoves + 1) + add hl, bc + ld a, [hl] + and $3f + ld [wStringBuffer1 + 4], a + ld h, d + ld l, e + push hl + ld de, wStringBuffer1 + 4 + lb bc, 1, 2 + call PrintNum + ld a, "/" + ld [hli], a + ld de, wTempPP + lb bc, 1, 2 + call PrintNum + pop hl + ld a, [wBuffer1] + ld e, a + ld d, 0 + add hl, de + ld d, h + ld e, l + pop hl + pop bc + inc b + ld a, b + cp NUM_MOVES + jr nz, .loop + +.done + ret + +.load_loop + ld [hli], a + ld [hld], a + add hl, de + dec c + jr nz, .load_loop + ret + +Unused_PlaceEnemyHPLevel: + push hl + push hl + ld hl, wPartyMonNicknames + ld a, [wCurPartyMon] + call GetNick + pop hl + call PlaceString + call CopyMonToTempMon + pop hl + ld a, [wCurPartySpecies] + cp EGG + jr z, .egg + push hl + ld bc, -12 + add hl, bc + ld b, $0 + call DrawEnemyHP + pop hl + ld bc, 5 + add hl, bc + push de + call PrintLevel + pop de + +.egg + ret + +PlaceStatusString: + push de + inc de + inc de + ld a, [de] + ld b, a + inc de + ld a, [de] + or b + pop de + jr nz, PlaceNonFaintStatus + push de + ld de, FntString + call CopyStatusString + pop de + ld a, $1 + and a + ret + +FntString: + db "FNT@" + +CopyStatusString: + ld a, [de] + inc de + ld [hli], a + ld a, [de] + inc de + ld [hli], a + ld a, [de] + ld [hl], a + ret + +PlaceNonFaintStatus: + push de + ld a, [de] + ld de, PsnString + bit PSN, a + jr nz, .place + ld de, BrnString + bit BRN, a + jr nz, .place + ld de, FrzString + bit FRZ, a + jr nz, .place + ld de, ParString + bit PAR, a + jr nz, .place + ld de, SlpString + and SLP + jr z, .no_status + +.place + call CopyStatusString + ld a, $1 + and a + +.no_status + pop de + ret + +SlpString: db "SLP@" +PsnString: db "PSN@" +BrnString: db "BRN@" +FrzString: db "FRZ@" +ParString: db "PAR@" + +ListMoves: +; List moves at hl, spaced every [wBuffer1] tiles. + ld de, wListMoves_MoveIndicesBuffer + ld b, $0 +.moves_loop + ld a, [de] + inc de + and a + jr z, .no_more_moves + push de + push hl + push hl + ld [wCurSpecies], a + ld a, MOVE_NAME + ld [wNamedObjectTypeBuffer], a + call GetName + ld de, wStringBuffer1 + pop hl + push bc + call PlaceString + pop bc + ld a, b + ld [wNumMoves], a + inc b + pop hl + push bc + ld a, [wBuffer1] + ld c, a + ld b, 0 + add hl, bc + pop bc + pop de + ld a, b + cp NUM_MOVES + jr z, .done + jr .moves_loop + +.no_more_moves + ld a, b +.nonmove_loop + push af + ld [hl], "-" + ld a, [wBuffer1] + ld c, a + ld b, 0 + add hl, bc + pop af + inc a + cp NUM_MOVES + jr nz, .nonmove_loop + +.done + ret diff --git a/engine/pokemon/party_menu.asm b/engine/pokemon/party_menu.asm new file mode 100755 index 00000000..93f9b93b --- /dev/null +++ b/engine/pokemon/party_menu.asm @@ -0,0 +1,783 @@ +SelectMonFromParty: + call DisableSpriteUpdates + xor a + ld [wPartyMenuActionText], a + call ClearBGPalettes + call InitPartyMenuLayout + call WaitBGMap + call SetPalettes + call DelayFrame + call PartyMenuSelect + call ReturnToMapWithSpeechTextbox + ret + +SelectTradeOrDayCareMon: + ld a, b + ld [wPartyMenuActionText], a + call DisableSpriteUpdates + call ClearBGPalettes + call InitPartyMenuLayout + call WaitBGMap + ld b, SCGB_PARTY_MENU + call GetSGBLayout + call SetPalettes + call DelayFrame + call PartyMenuSelect + call ReturnToMapWithSpeechTextbox + ret + +InitPartyMenuLayout: + call LoadPartyMenuGFX + call InitPartyMenuWithCancel + call InitPartyMenuGFX + call WritePartyMenuTilemap + call PrintPartyMenuText + ret + +LoadPartyMenuGFX: + call LoadFontsBattleExtra + callfar InitPartyMenuPalettes ; engine/color.asm + callfar ClearSpriteAnims2 + ret + +WritePartyMenuTilemap: + ld hl, wOptions + ld a, [hl] + push af + set NO_TEXT_SCROLL, [hl] + xor a + ldh [hBGMapMode], a + hlcoord 0, 0 + ld bc, SCREEN_WIDTH * SCREEN_HEIGHT + ld a, " " + call ByteFill ; blank the tilemap + call GetPartyMenuQualityIndexes +.loop + ld a, [hli] + cp -1 + jr z, .end + push hl + ld hl, .Jumptable + rst JumpTable + pop hl + jr .loop +.end + pop af + ld [wOptions], a + ret + +.Jumptable: +; entries correspond to PARTYMENUQUALITY_* constants + dw PlacePartyNicknames + dw PlacePartyHPBar + dw PlacePartyMenuHPDigits + dw PlacePartyMonLevel + dw PlacePartyMonStatus + dw PlacePartyMonTMHMCompatibility + dw PlacePartyMonEvoStoneCompatibility + dw PlacePartyMonGender + +PlacePartyNicknames: + hlcoord 3, 1 + ld a, [wPartyCount] + and a + jr z, .end + ld c, a + ld b, 0 +.loop + push bc + push hl + push hl + ld hl, wPartyMonNicknames + ld a, b + call GetNick + pop hl + call PlaceString + pop hl + ld de, 2 * SCREEN_WIDTH + add hl, de + pop bc + inc b + dec c + jr nz, .loop + +.end + dec hl + dec hl + ld de, .CANCEL + call PlaceString + ret + +.CANCEL: + db "CANCEL@" + +PlacePartyHPBar: + xor a + ld [wSGBPals], a + ld a, [wPartyCount] + and a + ret z + ld c, a + ld b, 0 + hlcoord 11, 2 +.loop + push bc + push hl + call PartyMenuCheckEgg + jr z, .skip + push hl + call PlacePartymonHPBar + pop hl + ld d, $6 + ld b, $0 + call DrawBattleHPBar + ld hl, wHPPals + ld a, [wSGBPals] + ld c, a + ld b, $0 + add hl, bc + call SetHPPal + ld b, SCGB_PARTY_MENU_HP_PALS + call GetSGBLayout +.skip + ld hl, wSGBPals + inc [hl] + pop hl + ld de, 2 * SCREEN_WIDTH + add hl, de + pop bc + inc b + dec c + jr nz, .loop + ld b, SCGB_PARTY_MENU + call GetSGBLayout + ret + +PlacePartymonHPBar: + ld a, b + ld bc, PARTYMON_STRUCT_LENGTH + ld hl, wPartyMon1HP + call AddNTimes + ld a, [hli] + or [hl] + jr nz, .not_fainted + xor a + ld e, a + ld c, a + ret + +.not_fainted + dec hl + ld a, [hli] + ld b, a + ld a, [hli] + ld c, a + ld a, [hli] + ld d, a + ld a, [hli] + ld e, a + predef ComputeHPBarPixels + ret + +PlacePartyMenuHPDigits: + ld a, [wPartyCount] + and a + ret z + ld c, a + ld b, 0 + hlcoord 13, 1 +.loop + push bc + push hl + call PartyMenuCheckEgg + jr z, .next + push hl + ld a, b + ld bc, PARTYMON_STRUCT_LENGTH + ld hl, wPartyMon1HP + call AddNTimes + ld e, l + ld d, h + pop hl + push de + lb bc, 2, 3 + call PrintNum + pop de + ld a, "/" + ld [hli], a + inc de + inc de + lb bc, 2, 3 + call PrintNum + +.next + pop hl + ld de, 2 * SCREEN_WIDTH + add hl, de + pop bc + inc b + dec c + jr nz, .loop + ret + +PlacePartyMonLevel: + ld a, [wPartyCount] + and a + ret z + ld c, a + ld b, 0 + hlcoord 8, 2 +.loop + push bc + push hl + call PartyMenuCheckEgg + jr z, .next + push hl + ld a, b + ld bc, PARTYMON_STRUCT_LENGTH + ld hl, wPartyMon1Level + call AddNTimes + ld e, l + ld d, h + pop hl + ld a, [de] + cp 100 ; This is distinct from MAX_LEVEL. + jr nc, .ThreeDigits + ld a, "<LV>" + ld [hli], a + lb bc, PRINTNUM_LEFTALIGN | 1, 2 + ; jr .okay +.ThreeDigits: + lb bc, PRINTNUM_LEFTALIGN | 1, 3 +; .okay + call PrintNum + +.next + pop hl + ld de, SCREEN_WIDTH * 2 + add hl, de + pop bc + inc b + dec c + jr nz, .loop + ret + +PlacePartyMonStatus: + ld a, [wPartyCount] + and a + ret z + ld c, a + ld b, 0 + hlcoord 5, 2 +.loop + push bc + push hl + call PartyMenuCheckEgg + jr z, .next + push hl + ld a, b + ld bc, PARTYMON_STRUCT_LENGTH + ld hl, wPartyMon1Status + call AddNTimes + ld e, l + ld d, h + pop hl + call PlaceStatusString + +.next + pop hl + ld de, SCREEN_WIDTH * 2 + add hl, de + pop bc + inc b + dec c + jr nz, .loop + ret + +PlacePartyMonTMHMCompatibility: + ld a, [wPartyCount] + and a + ret z + ld c, a + ld b, 0 + hlcoord 12, 2 +.loop + push bc + push hl + call PartyMenuCheckEgg + jr z, .next + push hl + ld hl, wPartySpecies + ld e, b + ld d, 0 + add hl, de + ld a, [hl] + ld [wCurPartySpecies], a + predef CanLearnTMHMMove + pop hl + call .PlaceAbleNotAble + call PlaceString + +.next + pop hl + ld de, SCREEN_WIDTH * 2 + add hl, de + pop bc + inc b + dec c + jr nz, .loop + ret + +.PlaceAbleNotAble: + ld a, c + and a + jr nz, .able + ld de, .string_not_able + ret + +.able + ld de, .string_able + ret + +.string_able + db "ABLE@" + +.string_not_able + db "NOT ABLE@" + +PlacePartyMonEvoStoneCompatibility: + ld a, [wPartyCount] + and a + ret z + ld c, a + ld b, 0 + hlcoord 12, 2 +.loop + push bc + push hl + call PartyMenuCheckEgg + jr z, .next + push hl + ld a, b + ld bc, PARTYMON_STRUCT_LENGTH + ld hl, wPartyMon1Species + call AddNTimes + ld a, [hl] + dec a + ld e, a + ld d, 0 + ld hl, EvosAttacksPointers + add hl, de + add hl, de + call .DetermineCompatibility + pop hl + call PlaceString + +.next + pop hl + ld de, 2 * SCREEN_WIDTH + add hl, de + pop bc + inc b + dec c + jr nz, .loop + ret + +.DetermineCompatibility: + ld de, wStringBuffer1 + ld a, BANK(EvosAttacksPointers) + ld bc, 2 + call FarCopyBytes + ld hl, wStringBuffer1 + ld a, [hli] + ld h, [hl] + ld l, a + ld de, wStringBuffer1 + ld a, BANK("Evolutions and Attacks") + ld bc, 10 + call FarCopyBytes + ld hl, wStringBuffer1 +.loop2 + ld a, [hli] + and a + jr z, .nope + inc hl + inc hl + cp EVOLVE_ITEM + jr nz, .loop2 + dec hl + dec hl + ld a, [wCurItem] + cp [hl] + inc hl + inc hl + jr nz, .loop2 + ld de, .string_able + ret + +.nope + ld de, .string_not_able + ret + +.string_able + db "ABLE@" +.string_not_able + db "NOT ABLE@" + +PlacePartyMonGender: + ld a, [wPartyCount] + and a + ret z + ld c, a + ld b, 0 + hlcoord 12, 2 +.loop + push bc + push hl + call PartyMenuCheckEgg + jr z, .next + ld [wCurPartySpecies], a + push hl + ld a, b + ld [wCurPartyMon], a + xor a + ld [wMonType], a + call GetGender + ld de, .unknown + jr c, .got_gender + ld de, .male + jr nz, .got_gender + ld de, .female + +.got_gender + pop hl + call PlaceString + +.next + pop hl + ld de, 2 * SCREEN_WIDTH + add hl, de + pop bc + inc b + dec c + jr nz, .loop + ret + +.male + db "♂…MALE@" + +.female + db "♀…FEMALE@" + +.unknown + db "…UNKNOWN@" + +PartyMenuCheckEgg: + ld a, LOW(wPartySpecies) + add b + ld e, a + ld a, HIGH(wPartySpecies) + adc 0 + ld d, a + ld a, [de] + cp EGG + ret + +GetPartyMenuQualityIndexes: + ld a, [wPartyMenuActionText] + and $f0 + jr nz, .skip + ld a, [wPartyMenuActionText] + and $f + ld e, a + ld d, 0 + ld hl, PartyMenuQualityPointers + add hl, de + add hl, de + ld a, [hli] + ld h, [hl] + ld l, a + ret + +.skip + ld hl, PartyMenuQualityPointers.Default + ret + +INCLUDE "data/party_menu_qualities.asm" + +InitPartyMenuGFX: + ld hl, wPartyCount + ld a, [hli] + and a + ret z + ld c, a + xor a + ldh [hObjectStructIndexBuffer], a +.loop + push bc + push hl + ld hl, LoadMenuMonIcon + ld a, BANK(LoadMenuMonIcon) + ld e, MONICON_PARTYMENU + rst FarCall + ldh a, [hObjectStructIndexBuffer] + inc a + ldh [hObjectStructIndexBuffer], a + pop hl + pop bc + dec c + jr nz, .loop + callfar PlaySpriteAnimations + ret + +InitPartyMenuWithCancel: +; with cancel + xor a + ld [wSwitchMon], a + ld de, PartyMenuAttributes + call SetMenuAttributes + ld a, [wPartyCount] + inc a + ld [w2DMenuNumRows], a ; list length + dec a + ld b, a + ld a, [wPartyMenuCursor] + and a + jr z, .skip + inc b + cp b + jr c, .done + +.skip + ld a, 1 + +.done + ld [wMenuCursorY], a + ld a, A_BUTTON | B_BUTTON + ld [wMenuJoypadFilter], a + ret + +InitPartyMenuNoCancel: +; no cancel + ld de, PartyMenuAttributes + call SetMenuAttributes + ld a, [wPartyCount] + ld [w2DMenuNumRows], a ; list length + ld b, a + ld a, [wPartyMenuCursor] + and a + jr z, .skip + inc b + cp b + jr c, .done +.skip + ld a, 1 +.done + ld [wMenuCursorY], a + ld a, A_BUTTON | B_BUTTON + ld [wMenuJoypadFilter], a + ret + +PartyMenuAttributes: +; cursor y +; cursor x +; num rows +; num cols +; bit 6: animate sprites bit 5: wrap around +; ? +; distance between items (hi: y, lo: x) +; allowed buttons (mask) + db 1, 0 + db 0, 1 + db $60, $00 + dn 2, 0 + db 0 + +PartyMenuSelect: +; sets carry if exitted menu. + call StaticMenuJoypad + call PlaceHollowCursor + ld a, [wPartyCount] + inc a + ld b, a + ld a, [wMenuCursorY] ; menu selection? + cp b + jr z, .exitmenu ; CANCEL + ld [wPartyMenuCursor], a + ldh a, [hJoyLast] + ld b, a + bit B_BUTTON_F, b + jr nz, .exitmenu ; B button + ld a, [wMenuCursorY] + dec a + ld [wCurPartyMon], a + ld c, a + ld b, $0 + ld hl, wPartySpecies + add hl, bc + ld a, [hl] + ld [wCurPartySpecies], a + + ld de, SFX_READ_TEXT_2 + call PlaySFX + call WaitSFX + and a + ret + +.exitmenu + ld de, SFX_READ_TEXT_2 + call PlaySFX + call WaitSFX + scf + ret + +PrintPartyMenuText: + hlcoord 0, 14 + lb bc, 2, 18 + call Textbox + ld a, [wPartyCount] + and a + jr nz, .haspokemon + ld de, YouHaveNoPKMNString + jr .gotstring +.haspokemon + ld a, [wPartyMenuActionText] + and $f ; drop high nibble + ld hl, PartyMenuStrings + ld e, a + ld d, $0 + add hl, de + add hl, de + ld a, [hli] + ld d, [hl] + ld e, a +.gotstring + ld a, [wOptions] + push af + set NO_TEXT_SCROLL, a + ld [wOptions], a + hlcoord 1, 16 ; Coord + call PlaceString + pop af + ld [wOptions], a + ret + +PartyMenuStrings: + dw ChooseAMonString + dw UseOnWhichPKMNString + dw WhichPKMNString + dw TeachWhichPKMNString + dw MoveToWhereString + dw UseOnWhichPKMNString + dw ChooseAMonString ; Probably used to be ChooseAFemalePKMNString + dw ChooseAMonString ; Probably used to be ChooseAMalePKMNString + dw ToWhichPKMNString + +ChooseAMonString: + db "Choose a #MON.@" + +UseOnWhichPKMNString: + db "Use on which <PK><MN>?@" + +WhichPKMNString: + db "Which <PK><MN>?@" + +TeachWhichPKMNString: + db "Teach which <PK><MN>?@" + +MoveToWhereString: + db "Move to where?@" + +ChooseAFemalePKMNString: +; unused + db "Choose a ♀<PK><MN>.@" + +ChooseAMalePKMNString: +; unused + db "Choose a ♂<PK><MN>.@" + +ToWhichPKMNString: + db "To which <PK><MN>?@" + +YouHaveNoPKMNString: + db "You have no <PK><MN>!@" + +PrintPartyMenuActionText: + ld a, [wCurPartyMon] + ld hl, wPartyMonNicknames + call GetNick + ld a, [wPartyMenuActionText] + and $f + ld hl, .MenuActionTexts + call .PrintText + ret + +.MenuActionTexts: +; entries correspond to PARTYMENUTEXT_* constants + dw .CuredOfPoisonText + dw .BurnWasHealedText + dw .WasDefrostedText + dw .WokeUpText + dw .RidOfParalysisText + dw .RecoveredSomeHPText + dw .HealthReturnedText + dw .RevitalizedText + dw .GrewToLevelText + dw .CameToItsSensesText + +.RecoveredSomeHPText: + text_far _RecoveredSomeHPText + text_end + +.CuredOfPoisonText: + text_far _CuredOfPoisonText + text_end + +.RidOfParalysisText: + text_far _RidOfParalysisText + text_end + +.BurnWasHealedText: + text_far _BurnWasHealedText + text_end + +.WasDefrostedText: + text_far _WasDefrostedText + text_end + +.WokeUpText: + text_far _WokeUpText + text_end + +.HealthReturnedText: + text_far _HealthReturnedText + text_end + +.RevitalizedText: + text_far _RevitalizedText + text_end + +.GrewToLevelText: + text_far _GrewToLevelText + text_end + +.CameToItsSensesText: + text_far _CameToItsSensesText + text_end + +.PrintText: + ld e, a + ld d, 0 + add hl, de + add hl, de + ld a, [hli] + ld h, [hl] + ld l, a + ld a, [wOptions] + push af + set NO_TEXT_SCROLL, a + ld [wOptions], a + call PrintText + pop af + ld [wOptions], a + ret diff --git a/engine/pokemon/stats_screen.asm b/engine/pokemon/stats_screen.asm new file mode 100644 index 00000000..a2345f37 --- /dev/null +++ b/engine/pokemon/stats_screen.asm @@ -0,0 +1,868 @@ + const_def 1 + const PINK_PAGE ; 1 + const GREEN_PAGE ; 2 + const BLUE_PAGE ; 3 + +StatsScreenInit: + ldh a, [hMapAnims] + push af + xor a + ldh [hMapAnims], a ; disable overworld tile animations + + ld c, 1 + call StatsScreenMain + + ; restore old values + pop af + ldh [hMapAnims], a + ret + +StatsScreenMain: + push bc + ld a, [wMonType] + cp TEMPMON + jr nz, .not_tempmon + ld a, [wBufferMonSpecies] + ld [wCurSpecies], a + call GetBaseData + ld hl, wBufferMon + ld de, wTempMon + ld bc, PARTYMON_STRUCT_LENGTH + call CopyBytes + jr .got_stats + +.not_tempmon + call CopyMonToTempMon + ld a, [wCurPartySpecies] + cp EGG + jp z, .got_stats + ld a, [wMonType] + cp BOXMON + jr c, .got_stats + call CalcTempmonStats + +.got_stats + call ClearBGPalettes + call ClearTilemap + call UpdateSprites + callfar StatsScreen_LoadFont + + pop bc + ld a, [wCurPartySpecies] + cp EGG + jp z, EggStatsInit + call StatsScreen_InitUpperHalf + ld b, 0 + jp StatsScreen_JumpToLoadPageFunction + +StatsScreen_LoadPage: + push bc + ld de, .done_loading + push de +; first jump to LoadPage function in jumptable + jp hl + +; return here after LoadPage function finishes +.done_loading + pop bc + ld b, 1 + +.joypad_loop + call GetJoypad + ld a, [wMonType] + cp TEMPMON + jr nz, .not_tempmon + push hl + push de + push bc + farcall StatsScreenDPad + pop bc + pop de + pop hl + ld a, [wMenuJoypad] + and D_DOWN | D_UP + jr nz, StatsScreenMain + ld a, [wMenuJoypad] + jr .joypad_action + +.not_tempmon + ldh a, [hJoyPressed] + +.joypad_action + and D_DOWN | D_UP | D_LEFT | D_RIGHT | A_BUTTON | B_BUTTON + jr z, .joypad_loop + bit B_BUTTON_F, a + jp nz, StatsScreen_Exit + bit D_LEFT_F, a + jr nz, .d_left + bit D_RIGHT_F, a + jr nz, .d_right + bit A_BUTTON_F, a + jr nz, .a_button + bit D_UP_F, a + jr nz, .d_up + +; .d_down + ld a, [wMonType] + cp BOXMON + jr nc, .joypad_loop + and a + ld a, [wPartyCount] + jr z, .next_mon + ld a, [wOTPartyCount] +.next_mon + ld b, a + ld a, [wCurPartyMon] + inc a + cp b + jr z, .joypad_loop + ld [wCurPartyMon], a + ld b, a + ld a, [wMonType] + and a + jr nz, .load_mon + ld a, b + inc a + ld [wPartyMenuCursor], a + jr .load_mon + +.d_up + ld a, [wCurPartyMon] + and a + jr z, .joypad_loop + dec a + ld [wCurPartyMon], a + ld b, a + ld a, [wMonType] + and a + jr nz, .load_mon + ld a, b + inc a + ld [wPartyMenuCursor], a +; fall through +.load_mon + jp StatsScreenMain + +.a_button + ld a, c + cp BLUE_PAGE ; last page + jr z, StatsScreen_Exit + +.d_right + inc c + ld a, BLUE_PAGE ; last page + cp c + jr nc, StatsScreen_JumpToLoadPageFunction + ld c, PINK_PAGE ; first page + jr StatsScreen_JumpToLoadPageFunction + +.d_left + dec c + jr nz, StatsScreen_JumpToLoadPageFunction + ld c, BLUE_PAGE ; last page +; fall through + +StatsScreen_JumpToLoadPageFunction: + ld hl, StatsScreen_LoadPageJumptable + push bc + dec c + ld b, 0 + add hl, bc + add hl, bc + ld a, [hli] + ld h, [hl] + ld l, a + pop bc + jp StatsScreen_LoadPage + +EggStatsInit: + push bc + call EggStatsScreen + pop bc +; fall through + +EggStats_JoypadLoop: + call GetJoypad + ld a, [wMonType] + cp TEMPMON + jr nz, .not_tempmon +; .tempmon + push hl + push de + push bc + farcall StatsScreenDPad + pop bc + pop de + pop hl + ld a, [wMenuJoypad] + and D_DOWN | D_UP + jp nz, StatsScreenMain + ld a, [wMenuJoypad] + jr .joypad_action + +.not_tempmon + ldh a, [hJoyPressed] +.joypad_action + and D_DOWN | D_UP | A_BUTTON | B_BUTTON + jr z, EggStats_JoypadLoop + bit A_BUTTON_F, a + jr nz, StatsScreen_Exit + bit B_BUTTON_F, a + jr nz, StatsScreen_Exit + bit D_UP_F, a + jr nz, EggStats_UpAction + bit D_DOWN_F, a + jp EggStats_DownAction + +StatsScreen_Exit: + call ClearBGPalettes + call ClearTilemap + ret + +EggStats_DownAction: + ld a, [wMonType] + cp BOXMON + jr nc, EggStats_JoypadLoop + and a + ld a, [wPartyCount] + jr z, .next_mon + ld a, [wOTPartyCount] +.next_mon + ld b, a + ld a, [wCurPartyMon] + inc a + cp b + jr z, EggStats_JoypadLoop + ld [wCurPartyMon], a + ld b, a + ld a, [wMonType] + and a + jr nz, EggStats_ScrollToLoadMon + ld a, b + inc a + ld [wPartyMenuCursor], a + jr EggStats_ScrollToLoadMon + +EggStats_UpAction: + ld a, [wCurPartyMon] + and a + jr z, EggStats_JoypadLoop + dec a + ld [wCurPartyMon], a + ld b, a + ld a, [wMonType] + and a + jr nz, EggStats_ScrollToLoadMon + ld a, b + inc a + ld [wPartyMenuCursor], a +; fall through + +EggStats_ScrollToLoadMon: + jp StatsScreenMain + +StatsScreen_LoadPageJumptable: +; entries correspond to *_PAGE constants + dw LoadPinkPage + dw LoadGreenPage + dw LoadBluePage + +StatsScreen_InitUpperHalf: + push bc + xor a + ldh [hBGMapMode], a + ld a, [wBaseDexNo] + ld [wDeciramBuffer], a + ld [wCurSpecies], a + hlcoord 8, 0 + ld [hl], "№" + inc hl + ld [hl], "." + inc hl + ld de, wDeciramBuffer + lb bc, PRINTNUM_LEADINGZEROS | 1, 3 + call PrintNum + hlcoord 14, 0 + call PrintLevel + ld hl, .NicknamePointers + call GetNicknamePointer +; Nickname + ld a, [wMonType] + cp BOXMON + ld a, BANK(sBoxMonNicknames) + call z, OpenSRAM + ld d, h + ld e, l + hlcoord 8, 2 + call PlaceString + ld a, [wMonType] + cp BOXMON + call z, CloseSRAM +; Gender character + call GetGender + jr c, .next + ld a, "♂" + jr nz, .got_gender + ld a, "♀" +.got_gender + hlcoord 18, 0 + ld [hl], a +.next + hlcoord 9, 4 + ld a, "/" + ld [hli], a + ld a, [wBaseDexNo] + ld [wNamedObjectIndexBuffer], a + call GetPokemonName + call PlaceString + call StatsScreen_PlaceHorizontalDivider + call StatsScreen_PlacePageSwitchArrows + call StatsScreen_PlaceShinyIcon +; Place HP bar + ld hl, wTempMonHP + ld a, [hli] + ld b, a + ld c, [hl] + ld hl, wTempMonMaxHP + ld a, [hli] + ld d, a + ld e, [hl] + callfar ComputeHPBarPixels + ld hl, wCurHPPal + call SetHPPal + ld b, SCGB_STATS_SCREEN_HP_PALS + call GetSGBLayout + pop bc + ret + +.NicknamePointers: + dw wPartyMonNicknames + dw wOTPartyMonNicknames + dw sBoxMonNicknames + dw wBufferMonNick + +LoadPinkPage: + push bc + push bc + xor a + ldh [hBGMapMode], a + ld a, [wBaseDexNo] + ld [wDeciramBuffer], a + ld [wCurSpecies], a + ld b, PINK_PAGE + call StatsScreen_LoadPageIndicators + +; Load graphics + hlcoord 0, 8 + lb bc, 10, 20 + call ClearBox + hlcoord 0, 9 + ld b, 0 + call DrawPlayerHP + hlcoord 8, 9 + ld [hl], $41 ; right HP/exp bar end cap + hlcoord 0, 12 + ld de, .Status_Type + call PlaceString + ld a, [wTempMonPokerusStatus] + ld b, a + and $f + jr nz, .HasPokerus + ld a, b + and $f0 + jr z, .NotImmuneToPkrs + hlcoord 8, 8 + ld [hl], "." ; Pokérus immunity dot +.NotImmuneToPkrs: + ld a, [wMonType] + cp BOXMON + jr z, .StatusOK + hlcoord 6, 13 + push hl + ld de, wTempMonStatus + call PlaceStatusString + pop hl + jr .StatusOK +.HasPokerus: + ld de, .PkrsStr + hlcoord 1, 13 + call PlaceString + jr .done_status +.StatusOK: + ld de, .OK_str + call z, PlaceString +.done_status + hlcoord 1, 15 + call PrintMonTypes + ld bc, 9 + decoord 0, 16 + hlcoord 0, 17 + call CopyBytes + ld a, " " + ld bc, 9 + hlcoord 0, 17 + call ByteFill + hlcoord 9, 8 + ld de, SCREEN_WIDTH + ld b, 10 + ld a, $31 ; vertical divider +.vertical_divider + ld [hl], a + add hl, de + dec b + jr nz, .vertical_divider + hlcoord 10, 9 + ld de, .ExpPointStr + call PlaceString +; print next level + ld a, [wTempMonLevel] + push af + cp MAX_LEVEL + jr z, .got_level + inc a + ld [wTempMonLevel], a +.got_level + hlcoord 17, 14 + call PrintLevel + pop af + ld [wTempMonLevel], a + ld de, wTempMonExp + hlcoord 13, 10 + lb bc, 3, 7 + call PrintNum +; level-up graphics and strings + call .CalcExpToNextLevel + ld de, wBuffer1 + hlcoord 13, 13 + lb bc, 3, 7 + call PrintNum + hlcoord 10, 12 + ld de, .LevelUpStr + call PlaceString + hlcoord 14, 14 + ld de, .ToStr + call PlaceString + ld a, [wTempMonLevel] + ld b, a + ld de, wTempMonExp + 2 + hlcoord 11, 16 + predef FillInExpBar + hlcoord 10, 16 + ld [hl], $40 ; left exp bar end cap + hlcoord 19, 16 + ld [hl], $41 ; right exp bar end cap + +; Load palettes / place frontpic + pop bc + farcall LoadStatsScreenPals + call WaitBGMap + ld a, 1 + ldh [hBGMapMode], a + pop bc + ld a, b + and a + jp z, StatsScreen_PlaceFrontpic + ret + +.CalcExpToNextLevel: + ld a, [wTempMonLevel] + cp MAX_LEVEL + jr z, .AlreadyAtMaxLevel + inc a + ld d, a + call CalcExpAtLevel + ld hl, wTempMonExp + 2 + ld hl, wTempMonExp + 2 + ldh a, [hQuotient + 3] + sub [hl] + dec hl + ld [wBuffer3], a + ldh a, [hQuotient + 2] + sbc [hl] + dec hl + ld [wBuffer2], a + ldh a, [hQuotient + 1] + sbc [hl] + ld [wBuffer1], a + ret + +.AlreadyAtMaxLevel: + ld hl, wBuffer1 + xor a + ld [hli], a + ld [hli], a + ld [hl], a + ret + +.Status_Type: + db "STATUS/" + next "TYPE/@" + +.OK_str: + db "OK @" + +.ExpPointStr: + db "EXP POINTS@" + +.LevelUpStr: + db "LEVEL UP@" + +.ToStr: + db "TO@" + +.PkrsStr: + db "#RUS@" + +Unreferenced_Function50f4d: + hlcoord 7, 0 + ld bc, SCREEN_WIDTH + ld d, SCREEN_HEIGHT +.loop + ld a, $31 ; vertical divider + ld [hl], a + add hl, bc + dec d + jr nz, .loop + ret + +StatsScreen_PlaceHorizontalDivider: + hlcoord 0, 7 + ld b, SCREEN_WIDTH + ld a, $62 ; horizontal divider (empty HP/exp bar) +.loop + ld [hli], a + dec b + jr nz, .loop + ret + +StatsScreen_PlacePageSwitchArrows: + hlcoord 12, 6 + ld [hl], "◀" + hlcoord 19, 6 + ld [hl], "▶" + ret + +StatsScreen_PlaceShinyIcon: + ld bc, wTempMonDVs + callfar CheckShininess + ret nc + hlcoord 19, 0 + ld [hl], "⁂" + ret + +LoadGreenPage: + push bc + push bc + xor a + ldh [hBGMapMode], a + ld b, GREEN_PAGE + call StatsScreen_LoadPageIndicators + +; Load graphics + hlcoord 0, 8 + lb bc, 10, 20 + call ClearBox +; item info + hlcoord 0, 8 + ld de, .Item + call PlaceString + ld a, [wTempMonItem] + and a + ld de, .ThreeDashes + jr z, .got_item_name + ld b, a + farcall TimeCapsule_ReplaceTeruSama + ld a, b + ld [wNamedObjectIndexBuffer], a + call GetItemName +.got_item_name + hlcoord 6, 8 + call PlaceString +; move info + ld hl, wTempMonMoves + ld de, wListMoves_MoveIndicesBuffer + ld bc, NUM_MOVES + call CopyBytes + hlcoord 0, 10 + ld de, .Move + call PlaceString + hlcoord 8, 10 + ld a, SCREEN_WIDTH * 2 + ld [wBuffer1], a + call ListMoves + hlcoord 12, 11 + ld a, SCREEN_WIDTH * 2 + ld [wBuffer1], a + call ListMovePP + +; Load palettes / place frontpic + pop bc + farcall LoadStatsScreenPals + call WaitBGMap + ld a, 1 + ldh [hBGMapMode], a + pop bc + ld a, b + and a + jp z, StatsScreen_PlaceFrontpic + ret + +.Item: + db "ITEM@" + +.ThreeDashes: + db "---@" + +.Move: + db "MOVE@" + +LoadBluePage: + push bc + push bc + xor a + ldh [hBGMapMode], a + ld b, BLUE_PAGE + call StatsScreen_LoadPageIndicators + +; Load graphics + hlcoord 0, 8 + lb bc, 10, 20 + call ClearBox + call .PlaceOTInfo + hlcoord 10, 8 + ld de, SCREEN_WIDTH + ld b, 10 + ld a, $31 ; vertical divider +.vertical_divider + ld [hl], a + add hl, de + dec b + jr nz, .vertical_divider + hlcoord 11, 8 + ld bc, 6 + call PrintTempMonStats + +; Load palettes / place frontpic + pop bc + farcall LoadStatsScreenPals + call WaitBGMap + ld a, 1 + ldh [hBGMapMode], a + pop bc + ld a, b + and a + jp z, StatsScreen_PlaceFrontpic + ret + +.PlaceOTInfo: + hlcoord 0, 9 + ld de, IDNoString + call PlaceString + hlcoord 0, 12 + ld de, OTString + call PlaceString + hlcoord 2, 10 + ld de, wTempMonID + lb bc, PRINTNUM_LEADINGZEROS | 2, 5 + call PrintNum + ld hl, .OTNamePointers + call GetNicknamePointer +; OT name + ld a, [wMonType] + cp BOXMON + ld a, BANK(sBoxMonOT) + call z, OpenSRAM + ld de, wStringBuffer1 + push de + ld bc, NAME_LENGTH + call CopyBytes + pop de + ld a, [wMonType] + cp BOXMON + call z, CloseSRAM + callfar CorrectNickErrors + push de + +; Adjust coordinate of OT name based on index of nickname terminator + lb bc, 0, -1 +.loop + inc c + ld a, [de] + inc de + cp "@" + jr nz, .loop +; remove left padding if name was 8-10 chars (somehow?) + ld a, NAME_LENGTH - 1 + sub c + cp 3 ; NAME_LENGTH - PLAYER_NAME_LENGTH +; otherwise, use 2 spaces of left padding + jr c, .ok + ld a, 2 ; NAME_LENGTH - PLAYER_NAME_LENGTH - 1 +.ok + ld c, a + hlcoord 0, 13 + add hl, bc +; that's finally over ... place string, quit forever + pop de + call PlaceString + ret + +.OTNamePointers: + dw wPartyMonOT + dw wOTPartyMonOT + dw sBoxMonOT + dw wBufferMonOT + +IDNoString: + db "<ID>№.@" + +OTString: + db "OT/@" + +StatsScreen_PlaceFrontpic: + push bc + call SetPalettes + ld hl, wTempMonDVs + call GetUnownLetter + hlcoord 0, 0 + ld a, [wCurPartySpecies] + cp UNOWN + jr z, .unown + + call PrepMonFrontpic + jr .play_cry + +.unown + xor a + ld [wBoxAlignment], a + call _PrepMonFrontpic + +.play_cry + ld a, [wCurPartySpecies] + call PlayMonCry + pop bc + ld b, 1 + ret + +EggStatsScreen: + ld hl, wCurHPPal + call SetHPPal + ld b, SCGB_STATS_SCREEN_HP_PALS + call GetSGBLayout + call StatsScreen_PlaceHorizontalDivider + hlcoord 8, 1 + ld de, EggString + call PlaceString + hlcoord 8, 3 + ld de, IDNoString + call PlaceString + hlcoord 8, 5 + ld de, OTString + call PlaceString + hlcoord 11, 3 + ld de, FiveQMarkString + call PlaceString + hlcoord 11, 5 + ld de, FiveQMarkString + call PlaceString + ld a, [wTempMonHappiness] ; egg status + ld de, EggSoonString + cp $6 + jr c, .picked + ld de, EggCloseString + cp $b + jr c, .picked + ld de, EggMoreTimeString + cp $29 + jr c, .picked + ld de, EggALotMoreTimeString +.picked + hlcoord 1, 9 + call PlaceString + call WaitBGMap + ld a, 1 + ldh [hBGMapMode], a + call SetPalettes ; pals + hlcoord 0, 0 + call PrepMonFrontpic + ld a, [wTempMonHappiness] + cp 6 + ret nc + ld de, SFX_2_BOOPS + call PlaySFX + call WaitSFX + ret + +EggString: + db "EGG@" + +FiveQMarkString: + db "?????@" + +EggSoonString: + db "It's making sounds" + next "inside. It's going" + next "to hatch soon!@" + +EggCloseString: + db "It moves around" + next "inside sometimes." + next "It must be close" + next "to hatching.@" + +EggMoreTimeString: + db "Wonder what's" + next "inside? It needs" + next "more time, though.@" + +EggALotMoreTimeString: + db "This EGG needs a" + next "lot more time to" + next "hatch.@" + +StatsScreen_LoadPageIndicators: + hlcoord 13, 5 + ld a, $36 ; first of 4 small square tiles + call .load_square + hlcoord 15, 5 + ld a, $36 ; " " " " + call .load_square + hlcoord 17, 5 + ld a, $36 ; " " " " + call .load_square + ld a, b + cp GREEN_PAGE + ld a, $3a ; first of 4 large square tiles + hlcoord 13, 5 ; PINK_PAGE (< GREEN_PAGE) + jr c, .load_square + hlcoord 15, 5 ; GREEN_PAGE (= GREEN_PAGE) + jr z, .load_square + hlcoord 17, 5 ; BLUE_PAGE (> GREEN_PAGE) +.load_square + ld [hli], a + inc a + ld [hld], a + push bc + ld bc, SCREEN_WIDTH + add hl, bc + pop bc + inc a + ld [hli], a + inc a + ld [hl], a + ret + +GetNicknamePointer: + ld a, [wMonType] + add a + ld c, a + ld b, 0 + add hl, bc + ld a, [hli] + ld h, [hl] + ld l, a + ld a, [wMonType] + cp TEMPMON + ret z + ld a, [wCurPartyMon] + jp SkipNames diff --git a/engine/pokemon/switchpartymons.asm b/engine/pokemon/switchpartymons.asm new file mode 100755 index 00000000..24d19df6 --- /dev/null +++ b/engine/pokemon/switchpartymons.asm @@ -0,0 +1,145 @@ +_SwitchPartyMons: + ld a, [wSwitchMon] + dec a + ld [wBuffer3], a + ld b, a + ld a, [wMenuCursorY] + dec a + ld [wBuffer2], a + cp b + jr z, .skip + call .SwapMonAndMail + ld a, [wBuffer3] + call .ClearSprite + ld a, [wBuffer2] + call .ClearSprite +.skip + ret + +.ClearSprite: + push af + hlcoord 0, 1 + ld bc, 2 * SCREEN_WIDTH + call AddNTimes + ld bc, 2 * SCREEN_WIDTH + ld a, " " + call ByteFill + pop af + ld hl, wVirtualOAMSprite00 + ld bc, 4 * SPRITEOAMSTRUCT_LENGTH + call AddNTimes + ld de, SPRITEOAMSTRUCT_LENGTH + ld c, 4 +.gfx_loop + ld [hl], SCREEN_WIDTH_PX ; y (off-screen) + add hl, de + dec c + jr nz, .gfx_loop + ld de, SFX_SWITCH_POKEMON + call WaitPlaySFX + ret + +.SwapMonAndMail: + push hl + push de + push bc + ld bc, wPartySpecies + ld a, [wBuffer2] + ld l, a + ld h, $0 + add hl, bc + ld d, h + ld e, l + ld a, [wBuffer3] + ld l, a + ld h, $0 + add hl, bc + ld a, [hl] + push af + ld a, [de] + ld [hl], a + pop af + ld [de], a + ld a, [wBuffer2] + ld hl, wPartyMon1Species + ld bc, PARTYMON_STRUCT_LENGTH + call AddNTimes + push hl + ld de, wceed + ld bc, PARTYMON_STRUCT_LENGTH + call CopyBytes + ld a, [wBuffer3] + ld hl, wPartyMon1 + ld bc, PARTYMON_STRUCT_LENGTH + call AddNTimes + pop de + push hl + ld bc, PARTYMON_STRUCT_LENGTH + call CopyBytes + pop de + ld hl, wceed + ld bc, PARTYMON_STRUCT_LENGTH + call CopyBytes + ld a, [wBuffer2] + ld hl, wPartyMonOT + call SkipNames + push hl + call .CopyNameTowceed + ld a, [wBuffer3] + ld hl, wPartyMonOT + call SkipNames + pop de + push hl + call .CopyName + pop de + ld hl, wceed + call .CopyName + ld hl, wPartyMonNicknames + ld a, [wBuffer2] + call SkipNames + push hl + call .CopyNameTowceed + ld hl, wPartyMonNicknames + ld a, [wBuffer3] + call SkipNames + pop de + push hl + call .CopyName + pop de + ld hl, wceed + call .CopyName + ld hl, sPartyMail + ld a, [wBuffer2] + ld bc, MAIL_STRUCT_LENGTH + call AddNTimes + push hl + ld de, wceed + ld bc, MAIL_STRUCT_LENGTH + ld a, BANK(sPartyMail) + call OpenSRAM + call CopyBytes + ld hl, sPartyMail + ld a, [wBuffer3] + ld bc, MAIL_STRUCT_LENGTH + call AddNTimes + pop de + push hl + ld bc, MAIL_STRUCT_LENGTH + call CopyBytes + pop de + ld hl, wceed + ld bc, MAIL_STRUCT_LENGTH + call CopyBytes + call CloseSRAM + pop bc + pop de + pop hl + ret + +.CopyNameTowceed: + ld de, wceed + +.CopyName: + ld bc, NAME_LENGTH + call CopyBytes + ret diff --git a/engine/pokemon/tempmon.asm b/engine/pokemon/tempmon.asm new file mode 100755 index 00000000..97ce1ee7 --- /dev/null +++ b/engine/pokemon/tempmon.asm @@ -0,0 +1,127 @@ +CopyMonToTempMon: +; gets the BaseData of a mon +; and copies the party_struct to wTempMon + + ld a, [wCurPartyMon] + ld e, a + call GetMonSpecies + ld a, [wCurPartySpecies] + ld [wCurSpecies], a + call GetBaseData + + ld a, [wMonType] + ld hl, wPartyMon1Species + ld bc, PARTYMON_STRUCT_LENGTH + and a + jr z, .copywholestruct + ld hl, wOTPartyMon1Species + ld bc, PARTYMON_STRUCT_LENGTH + cp OTPARTYMON + jr z, .copywholestruct + ld bc, BOXMON_STRUCT_LENGTH + callfar CopyBoxmonToTempMon + jr .done + +.copywholestruct + ld a, [wCurPartyMon] + call AddNTimes + ld de, wTempMon + ld bc, PARTYMON_STRUCT_LENGTH + call CopyBytes + +.done + ret + +CalcBufferMonStats: + ld bc, wBufferMon + jr _TempMonStatsCalculation + +CalcTempmonStats: + ld bc, wTempMon +_TempMonStatsCalculation: + ld hl, MON_LEVEL + add hl, bc + ld a, [hl] + ld [wCurPartyLevel], a + ld hl, MON_MAXHP + add hl, bc + ld d, h + ld e, l + ld hl, MON_STAT_EXP - 1 + add hl, bc + push bc + ld b, TRUE + predef CalcMonStats + pop bc + ld hl, MON_HP + add hl, bc + ld d, h + ld e, l + ld a, [wCurPartySpecies] + cp EGG + jr nz, .not_egg + xor a + ld [de], a + inc de + ld [de], a + jr .zero_status + +.not_egg + push bc + ld hl, MON_MAXHP + add hl, bc + ld bc, 2 + call CopyBytes + pop bc + +.zero_status + ld hl, MON_STATUS + add hl, bc + xor a + ld [hli], a + ld [hl], a + ret + +GetMonSpecies: +; [wMonType] has the type of the mon +; e = Nr. of mon (i.e. [wCurPartyMon]) + + ld a, [wMonType] + and a ; PARTYMON + jr z, .partymon + cp OTPARTYMON + jr z, .otpartymon + cp BOXMON + jr z, .boxmon + cp TEMPMON + jr z, .breedmon + ; WILDMON + +.partymon + ld hl, wPartySpecies + jr .done + +.otpartymon + ld hl, wOTPartySpecies + jr .done + +.boxmon + ld a, BANK(sBoxSpecies) + call OpenSRAM + ld hl, sBoxSpecies + call .done + call CloseSRAM + ret + +.breedmon + ld a, [wBreedMon1Species] + jr .done2 + +.done + ld d, 0 + add hl, de + ld a, [hl] + +.done2 + ld [wCurPartySpecies], a + ret diff --git a/engine/pokemon/types.asm b/engine/pokemon/types.asm new file mode 100755 index 00000000..3c9d28cd --- /dev/null +++ b/engine/pokemon/types.asm @@ -0,0 +1,92 @@ +PrintMonTypes: +; Print one or both types of [wCurSpecies] +; on the stats screen at hl. + + push hl + call GetBaseData + pop hl + + push hl + ld a, [wBaseType1] + call .Print + + ; Single-typed monsters really + ; have two of the same type. + ld a, [wBaseType1] + ld b, a + ld a, [wBaseType2] + cp b + pop hl + jr z, .hide_type_2 + + ld bc, $28 + add hl, bc + +.Print: + ld b, a + jr PrintType + +.hide_type_2 + ; Erase any type name that was here before. + ; Seems to be pointless in localized versions. + ld a, " " + ld bc, SCREEN_WIDTH - 3 + add hl, bc + ld [hl], a + inc bc + add hl, bc + ld bc, NAME_LENGTH_JAPANESE - 1 + jp ByteFill + +PrintMoveType: +; Print the type of move b at hl. + + push hl + ld a, b + dec a + ld bc, MOVE_LENGTH + ld hl, Moves + call AddNTimes + ld de, wStringBuffer1 + ld a, BANK(Moves) + call FarCopyBytes + ld a, [wStringBuffer1 + MOVE_TYPE] + pop hl + + ld b, a + +PrintType: +; Print type b at hl. + + ld a, b + + push hl + add a + ld hl, TypeNames + ld e, a + ld d, 0 + add hl, de + ld a, [hli] + ld e, a + ld d, [hl] + pop hl + + jp PlaceString + +GetTypeName: +; Copy the name of type [wNamedObjectIndexBuffer] to wStringBuffer1. + + ld a, [wNamedObjectIndexBuffer] + ld hl, TypeNames + ld e, a + ld d, 0 + add hl, de + add hl, de + ld a, [hli] + ld h, [hl] + ld l, a + ld de, wStringBuffer1 + ld bc, MOVE_NAME_LENGTH + jp CopyBytes + +INCLUDE "data/types/names.asm" |