diff options
author | entrpntr <12521136+entrpntr@users.noreply.github.com> | 2020-05-26 14:28:16 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-05-26 14:28:16 -0400 |
commit | 418ac97a9c2142aae82051e6bdb149c9103b7282 (patch) | |
tree | cf004df596ca9099dda5dc4ce8e924643e7c8207 | |
parent | a831702736defce904078495b013a4cdd55b9b41 (diff) | |
parent | dac5598524c04c5ac220e7c9616484c01da70d60 (diff) |
Merge pull request #37 from libjet/bank14
Disassemble bank $14
-rwxr-xr-x | data/growth_rates.asm | 19 | ||||
-rwxr-xr-x | data/party_menu_qualities.asm | 35 | ||||
-rwxr-xr-x | data/pokemon/unused_pic_banks.asm | 17 | ||||
-rwxr-xr-x | data/text/unused_gen1_trainer_names.asm | 71 | ||||
-rwxr-xr-x | data/types/names.asm | 50 | ||||
-rwxr-xr-x | engine/battle/unreferenced_getgen1trainerclassname.asm | 21 | ||||
-rwxr-xr-x | engine/events/basement_key.asm | 32 | ||||
-rwxr-xr-x | engine/events/card_key.asm | 37 | ||||
-rwxr-xr-x | engine/events/fishing_gfx.asm | 24 | ||||
-rwxr-xr-x | engine/events/poisonstep.asm | 154 | ||||
-rwxr-xr-x | engine/events/sacred_ash.asm | 68 | ||||
-rwxr-xr-x | engine/events/squirtbottle.asm | 45 | ||||
-rwxr-xr-x | engine/events/sweet_scent.asm | 65 | ||||
-rwxr-xr-x | engine/link/init_list.asm | 55 | ||||
-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 | ||||
-rw-r--r-- | main.asm | 98 | ||||
-rw-r--r-- | wram.asm | 7 |
23 files changed, 3371 insertions, 79 deletions
diff --git a/data/growth_rates.asm b/data/growth_rates.asm new file mode 100755 index 00000000..aee2a16e --- /dev/null +++ b/data/growth_rates.asm @@ -0,0 +1,19 @@ +growth_rate: MACRO +; [1]/[2]*n**3 + [3]*n**2 + [4]*n - [5] + dn \1, \2 + if \3 & $80 ; signed + db -\3 | $80 + else + db \3 + endc + db \4, \5 +ENDM + +GrowthRates: +; entries correspond to GROWTH_* (see constants/pokemon_data_constants.asm) + growth_rate 1, 1, 0, 0, 0 ; Medium Fast + growth_rate 3, 4, 10, 0, 30 ; Slightly Fast + growth_rate 3, 4, 20, 0, 70 ; Slightly Slow + growth_rate 6, 5, -15, 100, 140 ; Medium Slow + growth_rate 4, 5, 0, 0, 0 ; Fast + growth_rate 5, 4, 0, 0, 0 ; Slow diff --git a/data/party_menu_qualities.asm b/data/party_menu_qualities.asm new file mode 100755 index 00000000..0f8b19bf --- /dev/null +++ b/data/party_menu_qualities.asm @@ -0,0 +1,35 @@ +; WritePartyMenuTilemap.Jumptable indexes (see engine/party_menu.asm) + const_def + const PARTYMENUQUALITY_NICKNAMES + const PARTYMENUQUALITY_HP_BAR + const PARTYMENUQUALITY_HP_DIGITS + const PARTYMENUQUALITY_LEVEL + const PARTYMENUQUALITY_STATUS + const PARTYMENUQUALITY_TMHM_COMPAT + const PARTYMENUQUALITY_EVO_STONE_COMPAT + const PARTYMENUQUALITY_GENDER + +partymenuqualities: MACRO +rept _NARG + db PARTYMENUQUALITY_\1 + shift +endr + db -1 ; end +ENDM + +PartyMenuQualityPointers: +; entries correspond to PARTYMENUACTION_* constants + dw .Default ; PARTYMENUACTION_CHOOSE_POKEMON + dw .Default ; PARTYMENUACTION_HEALING_ITEM + dw .Default ; PARTYMENUACTION_SWITCH + dw .TMHM ; PARTYMENUACTION_TEACH_TMHM + dw .Default ; PARTYMENUACTION_MOVE + dw .EvoStone ; PARTYMENUACTION_EVO_STONE + dw .Gender ; PARTYMENUACTION_GIVE_MON + dw .Gender ; PARTYMENUACTION_GIVE_MON_FEMALE + dw .Default ; PARTYMENUACTION_GIVE_ITEM + +.Default: partymenuqualities NICKNAMES, HP_BAR, HP_DIGITS, LEVEL, STATUS +.TMHM: partymenuqualities NICKNAMES, TMHM_COMPAT, LEVEL, STATUS +.EvoStone: partymenuqualities NICKNAMES, EVO_STONE_COMPAT, LEVEL, STATUS +.Gender: partymenuqualities NICKNAMES, GENDER, LEVEL, STATUS diff --git a/data/pokemon/unused_pic_banks.asm b/data/pokemon/unused_pic_banks.asm new file mode 100755 index 00000000..2ede9c3f --- /dev/null +++ b/data/pokemon/unused_pic_banks.asm @@ -0,0 +1,17 @@ +; This was a table of Pokémon sprite banks in the 1997 G/S prototype. +; See pokegold-spaceworld's gfx/pokemon/pkmn_pic_banks.asm. + +Unreferenced_MonPicBanks: + ; last mon in bank, bank # + db RAICHU, $15 + 0 + db DUGTRIO, $15 + 1 + db GRAVELER, $15 + 2 + db KRABBY, $15 + 3 + db STARMIE, $15 + 4 + db ARTICUNO, $15 + 5 + db ARIADOS, $15 + 6 ; JARANRA in pokegold-spaceworld + db ESPEON, $15 + 7 ; KOUNYA in pokegold-spaceworld + db OCTILLERY, $15 + 8 ; BOMBSEEKER in pokegold-spaceworld + db LARVITAR, $15 + 9 ; NYULA in pokegold-spaceworld + db $ff, $15 + 10 + db $ff, $15 + 11 diff --git a/data/text/unused_gen1_trainer_names.asm b/data/text/unused_gen1_trainer_names.asm new file mode 100755 index 00000000..fa839f36 --- /dev/null +++ b/data/text/unused_gen1_trainer_names.asm @@ -0,0 +1,71 @@ +Gen1TrainerClassNames: +; Untranslated trainer class names from Red. + dw .Youngster + dw .BugCatcher + dw .Lass + dw wOTClassName ; sailor + dw .JrTrainerM + dw .JrTrainerF + dw .Pokemaniac + dw .SuperNerd + dw wOTClassName ; hiker + dw wOTClassName ; biker + dw .Burglar + dw .Engineer + dw .Jack + dw wOTClassName ; fisher + dw .Swimmer + dw wOTClassName ; cue ball + dw wOTClassName ; gambler + dw .Beauty + dw wOTClassName ; psychic + dw .Rocker + dw .Juggler + dw wOTClassName ; tamer + dw wOTClassName ; bird keeper + dw .Blackbelt + dw wOTClassName ; rival1 + dw .ProfOak + dw .Chief + dw .Scientist + dw wOTClassName ; giovanni + dw .Rocket + dw .CooltrainerM + dw .CooltrainerF + dw wOTClassName ; bruno + dw wOTClassName ; brock + dw wOTClassName ; misty + dw wOTClassName ; lt.surge + dw wOTClassName ; erika + dw wOTClassName ; koga + dw wOTClassName ; blaine + dw wOTClassName ; sabrina + dw wOTClassName ; gentleman + dw wOTClassName ; rival2 + dw wOTClassName ; rival3 + dw wOTClassName ; lorelei + dw wOTClassName ; channeler + dw wOTClassName ; agatha + dw wOTClassName ; lance + +.Youngster: db "たんパン@" +.BugCatcher: db "むしとり@" +.Lass: db "ミニスカ@" +.JrTrainerM: db "ボーイ@" +.JrTrainerF: db "ガール@" +.Pokemaniac: db "マニア@" +.SuperNerd: db "りかけい@" +.Burglar: db "どろぼう@" +.Engineer: db "オヤジ@" +.Jack: db "ジャック@" +.Swimmer: db "かいパン@" +.Beauty: db "おねえさん@" +.Rocker: db "グループ@" +.Juggler: db "ジャグラー@" +.Blackbelt: db "からて@" +.ProfOak: db "オーキド@" +.Chief: db "チーフ@" +.Scientist: db "けんきゅういん@" +.Rocket: db "だんいん@" +.CooltrainerM: db "エりート♂@" +.CooltrainerF: db "エりート♀@" diff --git a/data/types/names.asm b/data/types/names.asm new file mode 100755 index 00000000..62d8e13b --- /dev/null +++ b/data/types/names.asm @@ -0,0 +1,50 @@ +TypeNames: +; entries correspond to types (see constants/type_constants.asm) + dw Normal + dw Fighting + dw Flying + dw Poison + dw Ground + dw Rock + dw Bird + dw Bug + dw Ghost + dw Steel + dw Normal + dw Normal + dw Normal + dw Normal + dw Normal + dw Normal + dw Normal + dw Normal + dw Normal + dw CurseType + dw Fire + dw Water + dw Grass + dw Electric + dw Psychic + dw Ice + dw Dragon + dw Dark + +Normal: db "NORMAL@" +Fighting: db "FIGHTING@" +Flying: db "FLYING@" +Poison: db "POISON@" +CurseType: db "???@" +Fire: db "FIRE@" +Water: db "WATER@" +Grass: db "GRASS@" +Electric: db "ELECTRIC@" +Psychic: db "PSYCHIC@" +Ice: db "ICE@" +Ground: db "GROUND@" +Rock: db "ROCK@" +Bird: db "BIRD@" +Bug: db "BUG@" +Ghost: db "GHOST@" +Steel: db "STEEL@" +Dragon: db "DRAGON@" +Dark: db "DARK@" diff --git a/engine/battle/unreferenced_getgen1trainerclassname.asm b/engine/battle/unreferenced_getgen1trainerclassname.asm new file mode 100755 index 00000000..04532523 --- /dev/null +++ b/engine/battle/unreferenced_getgen1trainerclassname.asm @@ -0,0 +1,21 @@ +Unreferenced_GetGen1TrainerClassName: + ld hl, Gen1TrainerClassNames + ld a, [wTrainerClass] + dec a + ld c, a + ld b, 0 + add hl, bc + add hl, bc + ld a, [hli] + ld h, [hl] + ld l, a + ld de, wStringBuffer1 +.copy + ld a, [hli] + ld [de], a + inc de + cp "@" + jr nz, .copy + ret + +INCLUDE "data/text/unused_gen1_trainer_names.asm" diff --git a/engine/events/basement_key.asm b/engine/events/basement_key.asm new file mode 100755 index 00000000..ab8c39ce --- /dev/null +++ b/engine/events/basement_key.asm @@ -0,0 +1,32 @@ +_BasementKey: +; Are we even in the right map to use this? + ld a, [wMapGroup] + cp GROUP_GOLDENROD_UNDERGROUND + jr nz, .nope + + ld a, [wMapNumber] + cp MAP_GOLDENROD_UNDERGROUND + jr nz, .nope +; Are we on the tile in front of the door? + call GetFacingTileCoord + ld a, d + cp 22 + jr nz, .nope + ld a, e + cp 10 + jr nz, .nope +; Let's use the Basement Key + ld hl, .BasementKeyScript + call QueueScript + ld a, TRUE + ld [wItemEffectSucceeded], a + ret + +.nope + ld a, FALSE + ld [wItemEffectSucceeded], a + ret + +.BasementKeyScript: + closetext + farsjump BasementDoorScript diff --git a/engine/events/card_key.asm b/engine/events/card_key.asm new file mode 100755 index 00000000..c15b1def --- /dev/null +++ b/engine/events/card_key.asm @@ -0,0 +1,37 @@ +_CardKey: +; Are we even in the right map to use this? + ld a, [wMapGroup] + cp GROUP_RADIO_TOWER_3F + jr nz, .nope + + ld a, [wMapNumber] + cp MAP_RADIO_TOWER_3F + jr nz, .nope +; Are we facing the slot? + ld a, [wPlayerDirection] + and %1100 + cp OW_UP + jr nz, .nope + + call GetFacingTileCoord + ld a, d + cp 18 + jr nz, .nope + ld a, e + cp 6 + jr nz, .nope +; Let's use the Card Key. + ld hl, .CardKeyScript + call QueueScript + ld a, TRUE + ld [wItemEffectSucceeded], a + ret + +.nope + ld a, FALSE + ld [wItemEffectSucceeded], a + ret + +.CardKeyScript: + closetext + farsjump CardKeySlotScript diff --git a/engine/events/fishing_gfx.asm b/engine/events/fishing_gfx.asm new file mode 100755 index 00000000..c4a0b9fa --- /dev/null +++ b/engine/events/fishing_gfx.asm @@ -0,0 +1,24 @@ +LoadFishingGFX: + ld de, FishingGFX + ld hl, vTiles0 tile $02 + lb bc, BANK(FishingGFX), 2 + call Get2bpp + + ld de, FishingGFX tile $02 + ld hl, vTiles0 tile $06 + lb bc, BANK(FishingGFX), 2 + call Get2bpp + + ld de, FishingGFX tile $04 + ld hl, vTiles0 tile $0a + lb bc, BANK(FishingGFX), 2 + call Get2bpp + + ld de, FishingGFX tile $06 + ld hl, vTiles0 tile $fc + lb bc, BANK(FishingGFX), 2 + call Get2bpp + ret + +FishingGFX: +INCBIN "gfx/overworld/chris_fish.2bpp" diff --git a/engine/events/poisonstep.asm b/engine/events/poisonstep.asm new file mode 100755 index 00000000..98a6e25a --- /dev/null +++ b/engine/events/poisonstep.asm @@ -0,0 +1,154 @@ +DoPoisonStep:: + ld a, [wPartyCount] + and a + jr z, .no_faint + + xor a + ld c, wPoisonStepDataEnd - wPoisonStepData + ld hl, wPoisonStepData +.loop_clearPoisonStepData + ld [hli], a + dec c + jr nz, .loop_clearPoisonStepData + + xor a + ld [wCurPartyMon], a +.loop_check_poison + call .DamageMonIfPoisoned + jr nc, .not_poisoned +; the output flag is stored in c, copy it to [wPoisonStepPartyFlags + [wCurPartyMon]] +; and set the corresponding flag in wPoisonStepFlagSum + ld a, [wCurPartyMon] + ld e, a + ld d, 0 + ld hl, wPoisonStepPartyFlags + add hl, de + ld [hl], c + ld a, [wPoisonStepFlagSum] + or c + ld [wPoisonStepFlagSum], a + +.not_poisoned + ld a, [wPartyCount] + ld hl, wCurPartyMon + inc [hl] + cp [hl] + jr nz, .loop_check_poison + + ld a, [wPoisonStepFlagSum] + and %10 + jr nz, .someone_has_fainted + ld a, [wPoisonStepFlagSum] + and %01 + jr z, .no_faint + call .PlayPoisonSFX + xor a + ret + +.someone_has_fainted + ld a, BANK(.Script_MonFaintedToPoison) + ld hl, .Script_MonFaintedToPoison + call CallScript + scf + ret + +.no_faint + xor a + ret + +.DamageMonIfPoisoned: +; check if mon is poisoned, return if not + ld a, MON_STATUS + call GetPartyParamLocation + ld a, [hl] + and 1 << PSN + ret z + +; check if mon is already fainted, return if so + ld a, MON_HP + call GetPartyParamLocation + ld a, [hli] + ld b, a + ld c, [hl] + or c + ret z + +; do 1 HP damage + dec bc + ld [hl], c + dec hl + ld [hl], b + +; check if mon has fainted as a result of poison damage + ld a, b + or c + jr nz, .not_fainted + +; the mon has fainted, reset its status, set carry, and return %10 + ld a, MON_STATUS + call GetPartyParamLocation + ld [hl], 0 + ld c, %10 + scf + ret + +.not_fainted +; set carry and return %01 + ld c, %01 + scf + ret + +.PlayPoisonSFX: + ld de, SFX_POISON + call PlaySFX + ld b, $2 + predef LoadPoisonBGPals + call DelayFrame + ret + +.Script_MonFaintedToPoison: + callasm .PlayPoisonSFX + opentext + callasm .CheckWhitedOut + iffalse .whiteout + closetext + end + +.whiteout + farsjump Script_OverworldWhiteout + +.CheckWhitedOut: + xor a + ld [wCurPartyMon], a + ld de, wPoisonStepPartyFlags +.party_loop + push de + ld a, [de] + and %10 + jr z, .mon_not_fainted + ld c, HAPPINESS_POISONFAINT + farcall ChangeHappiness + farcall GetPartyNick + ld hl, .PoisonFaintText + call PrintText + +.mon_not_fainted + pop de + inc de + ld hl, wCurPartyMon + inc [hl] + ld a, [wPartyCount] + cp [hl] + jr nz, .party_loop + predef CheckPlayerPartyForFitMon + ld a, d + ld [wScriptVar], a + ret + +.PoisonFaintText: + text_far _PoisonFaintText + text_end + +.PoisonWhiteoutText: + text_far _PoisonWhiteoutText + text_end diff --git a/engine/events/sacred_ash.asm b/engine/events/sacred_ash.asm new file mode 100755 index 00000000..d105b2fb --- /dev/null +++ b/engine/events/sacred_ash.asm @@ -0,0 +1,68 @@ +_SacredAsh: + ld a, $0 + ld [wItemEffectSucceeded], a + call CheckAnyFaintedMon + ret nc + + ld hl, SacredAshScript + call QueueScript + ld a, $1 + ld [wItemEffectSucceeded], a + ret + +CheckAnyFaintedMon: + ld de, PARTYMON_STRUCT_LENGTH + ld bc, wPartySpecies + ld hl, wPartyMon1HP + ld a, [wPartyCount] + and a + ret z + +.loop + push af + push hl + ld a, [bc] + inc bc + cp EGG + jr z, .next + + ld a, [hli] + or [hl] + jr z, .done + +.next + pop hl + add hl, de + pop af + dec a + jr nz, .loop + xor a + ret + +.done + pop hl + pop af + scf + ret + +SacredAshScript: + special HealParty + reloadmappart + playsound SFX_WARP_TO + special FadeOutPalettes + special FadeInPalettes + special FadeOutPalettes + special FadeInPalettes + special FadeOutPalettes + special FadeInPalettes + waitsfx + writetext .UseSacredAshText + playsound SFX_CAUGHT_MON + waitsfx + waitbutton + closetext + end + +.UseSacredAshText: + text_far _UseSacredAshText + text_end diff --git a/engine/events/squirtbottle.asm b/engine/events/squirtbottle.asm new file mode 100755 index 00000000..411b5c2e --- /dev/null +++ b/engine/events/squirtbottle.asm @@ -0,0 +1,45 @@ +_Squirtbottle: + ld hl, .SquirtbottleScript + call QueueScript + ld a, $1 + ld [wItemEffectSucceeded], a + ret + +.SquirtbottleScript: + reloadmappart + special UpdateTimePals + callasm .CheckCanUseSquirtbottle + iffalse .SquirtbottleNothingScript + farsjump WateredWeirdTreeScript + +.SquirtbottleNothingScript: + jumptext .SquirtbottleNothingText + +.SquirtbottleNothingText: + text_far _SquirtbottleNothingText + text_end + +.CheckCanUseSquirtbottle: + ld a, [wMapGroup] + cp GROUP_ROUTE_36 + jr nz, .nope + + ld a, [wMapNumber] + cp MAP_ROUTE_36 + jr nz, .nope + + farcall GetFacingObject + jr c, .nope + + ld a, d + cp SPRITEMOVEDATA_SUDOWOODO + jr nz, .nope + + ld a, 1 + ld [wScriptVar], a + ret + +.nope + xor a + ld [wScriptVar], a + ret diff --git a/engine/events/sweet_scent.asm b/engine/events/sweet_scent.asm new file mode 100755 index 00000000..9b99a256 --- /dev/null +++ b/engine/events/sweet_scent.asm @@ -0,0 +1,65 @@ +SweetScentFromMenu: + ld hl, .SweetScent + call QueueScript + ld a, $1 + ld [wFieldMoveSucceeded], a + ret + +.SweetScent: + reloadmappart + special UpdateTimePals + callasm GetPartyNick + writetext UseSweetScentText + waitbutton + callasm SweetScentEncounter + iffalse SweetScentNothing + checkflag ENGINE_BUG_CONTEST_TIMER + iftrue .BugCatchingContest + randomwildmon + startbattle + reloadmapafterbattle + end + +.BugCatchingContest: + farsjump BugCatchingContestBattleScript + +SweetScentNothing: + writetext SweetScentNothingText + waitbutton + closetext + end + +SweetScentEncounter: + farcall CanUseSweetScent + jr nc, .no_battle + ld hl, wStatusFlags2 + bit STATUSFLAGS2_BUG_CONTEST_TIMER_F, [hl] + jr nz, .not_in_bug_contest + farcall GetMapEncounterRate + ld a, b + and a + jr z, .no_battle + farcall ChooseWildEncounter + jr nz, .no_battle + jr .start_battle + +.not_in_bug_contest + farcall ChooseWildEncounter_BugContest + +.start_battle + ld a, $1 + ld [wScriptVar], a + ret + +.no_battle + xor a + ld [wScriptVar], a + ret + +UseSweetScentText: + text_far _UseSweetScentText + text_end + +SweetScentNothingText: + text_far _SweetScentNothingText + text_end diff --git a/engine/link/init_list.asm b/engine/link/init_list.asm new file mode 100755 index 00000000..b85cf001 --- /dev/null +++ b/engine/link/init_list.asm @@ -0,0 +1,55 @@ +InitList: +; This entire function is useless. + ld a, [wInitListType] + + cp INIT_ENEMYOT_LIST + jr nz, .check_party_ot_name + ld hl, wOTPartyCount + ld de, wOTPartyMonOT + ld a, ENEMY_OT_NAME + jr .done + +.check_party_ot_name + cp INIT_PLAYEROT_LIST + jr nz, .check_mon_name + ld hl, wPartyCount + ld de, wPartyMonOT + ld a, PARTY_OT_NAME + jr .done + +.check_mon_name + cp INIT_MON_LIST + jr nz, .check_item_name + ld hl, wCurMart + ld de, PokemonNames + ld a, MON_NAME + jr .done + +.check_item_name + cp INIT_BAG_ITEM_LIST + jr nz, .check_ob_item_name + ld hl, wNumItems + ld de, ItemNames + ld a, ITEM_NAME + jr .done + +.check_ob_item_name + ld hl, wCurMart + ld de, ItemNames + ld a, ITEM_NAME +.done + ld [wNamedObjectTypeBuffer], a + ld a, l + ld [wListPointer], a + ld a, h + ld [wListPointer + 1], a + ld a, e + ld [wUnusedCFFE], a + ld a, d + ld [wUnusedCFFE + 1], a + ld bc, ItemAttributes + ld a, c + ld [wItemAttributesPtr], a + ld a, b + ld [wItemAttributesPtr + 1], a + ret 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" @@ -356,83 +356,27 @@ INCLUDE "engine/pokemon/mail.asm" SECTION "bank14", ROMX -SelectMonFromParty:: - dr $50000, $5001d -SelectTradeOrDayCareMon:: - dr $5001d, $5004f -LoadPartyMenuGFX:: - dr $5004f, $5005f -WritePartyMenuTilemap:: - dr $5005f, $50355 -InitPartyMenuGFX:: - dr $50355, $5037a -InitPartyMenuWithCancel:: - dr $5037a, $503a2 -InitPartyMenuNoCancel:: - dr $503a2, $503cc -PartyMenuSelect:: - dr $503cc, $5040f -PrintPartyMenuText:: - dr $5040f, $504db -PrintPartyMenuActionText:: - dr $504db, $5054f -LoadFishingGFX:: - dr $5054f, $50610 -DoPoisonStep:: - dr $50610, $506f2 -SweetScentFromMenu:: - dr $506f2, $50763 -_Squirtbottle:: - dr $50763, $507ac -_CardKey:: - dr $507ac, $507e7 -_BasementKey:: - dr $507e7, $50819 -_SacredAsh:: - dr $50819, $5087d -CopyMonToTempMon:: - dr $5087d, $50940 -PrintMonTypes:: - dr $50940, $5096d -PrintMoveType:: - dr $5096d, $50986 -PrintType:: - dr $50986, $50997 -GetTypeName:: - dr $50997, $50b3d -DrawPlayerHP:: - dr $50b3d, $50b41 -DrawEnemyHP:: - dr $50b41, $50bae -StatsScreenInit:: - dr $50bae, $5128f - -PrintTempMonStats:: - dr $5128f, $512f1 -GetGender:: - dr $512f1, $51364 -ListMovePP:: - dr $51364, $513e4 -Unused_PlaceEnemyHPLevel:: - dr $513e4, $51437 -PlaceNonFaintStatus:: - dr $51437, $51478 -ListMoves:: - dr $51478, $514c2 -InitList:: - dr $514c2, $51524 -CalcLevel:: - dr $51524, $51550 -CalcExpAtLevel:: - dr $51550, $5161b -_SwitchPartyMons:: - dr $5161b, $51749 + +INCLUDE "engine/pokemon/party_menu.asm" +INCLUDE "engine/events/fishing_gfx.asm" +INCLUDE "engine/events/poisonstep.asm" +INCLUDE "engine/events/sweet_scent.asm" +INCLUDE "engine/events/squirtbottle.asm" +INCLUDE "engine/events/card_key.asm" +INCLUDE "engine/events/basement_key.asm" +INCLUDE "engine/events/sacred_ash.asm" +INCLUDE "engine/pokemon/tempmon.asm" +INCLUDE "engine/pokemon/types.asm" +INCLUDE "engine/battle/unreferenced_getgen1trainerclassname.asm" +INCLUDE "engine/pokemon/mon_stats.asm" +INCLUDE "engine/link/init_list.asm" +INCLUDE "engine/pokemon/experience.asm" +INCLUDE "engine/pokemon/switchpartymons.asm" INCLUDE "engine/gfx/load_pics.asm" INCLUDE "engine/pokemon/move_mon_wo_mail.asm" INCLUDE "data/pokemon/base_stats.asm" +INCLUDE "data/pokemon/unused_pic_banks.asm" -Unknown53a6b:: - dr $53a6b, $53a83 EggPic:: INCBIN "gfx/pokemon/egg/front.2bpp.lz" @@ -705,8 +649,10 @@ _DepositPKMN:: _WithdrawPKMN:: dr $e2d71, $e2f47 _MovePKMNWithoutMail:: - dr $e2f47, $e3d25 + dr $e2f47, $e3773 +StatsScreenDPad:: + dr $e3773, $e3d25 _ChangeBox:: dr $e3d25, $e3f74 @@ -756,7 +702,9 @@ _LoadFontsBattleExtra:: LoadBattleFontsHPBar:: dr $f8066, $f8081 LoadHPBar:: - dr $f8081, $f80d9 + dr $f8081, $f80a6 +StatsScreen_LoadFont:: + dr $f80a6, $f80d9 LoadStatsScreenPageTilesGFX:: dr $f80d9, $f8bb2 EnemyHPBarBorderGFX:: @@ -1583,15 +1583,14 @@ wMailboxItems:: ds MAILBOX_CAPACITY wMailboxEnd:: ENDU ; cffc -wcffc:: ds 1 ; cffc -wcffd:: ds 1 ; cffd +wListPointer:: dw ; cffc wUnusedCFFE:: dw ; cffe SECTION "WRAM 1", WRAMX -wd000:: ds 1 ; d000 -wd001:: ds 1 ; d001 +wItemAttributesPtr:: dw ; d000 + wCurItem:: db ; d002 wCurItemQuantity:: ; d003 wMartItemID:: |