diff options
Diffstat (limited to 'engine/items')
-rw-r--r-- | engine/items/buy_sell_toss.asm | 220 | ||||
-rw-r--r-- | engine/items/item_effects.asm | 2958 | ||||
-rw-r--r-- | engine/items/items.asm | 581 | ||||
-rw-r--r-- | engine/items/mart.asm | 895 | ||||
-rw-r--r-- | engine/items/pack.asm | 1608 | ||||
-rw-r--r-- | engine/items/pack_kris.asm | 20 | ||||
-rw-r--r-- | engine/items/print_item_description.asm | 32 | ||||
-rw-r--r-- | engine/items/switch_items.asm | 271 | ||||
-rw-r--r-- | engine/items/tmhm.asm | 574 | ||||
-rw-r--r-- | engine/items/tmhm2.asm | 46 | ||||
-rw-r--r-- | engine/items/update_item_description.asm | 13 |
11 files changed, 7218 insertions, 0 deletions
diff --git a/engine/items/buy_sell_toss.asm b/engine/items/buy_sell_toss.asm new file mode 100644 index 000000000..3303f4319 --- /dev/null +++ b/engine/items/buy_sell_toss.asm @@ -0,0 +1,220 @@ +SelectQuantityToToss: + ld hl, TossItem_MenuHeader + call LoadMenuHeader + call Toss_Sell_Loop + ret + +SelectQuantityToBuy: + farcall GetItemPrice +RooftopSale_SelectQuantityToBuy: + ld a, d + ld [wBuffer1], a + ld a, e + ld [wBuffer2], a + ld hl, BuyItem_MenuHeader + call LoadMenuHeader + call Toss_Sell_Loop + ret + +SelectQuantityToSell: + farcall GetItemPrice + ld a, d + ld [wBuffer1], a + ld a, e + ld [wBuffer2], a + ld hl, SellItem_MenuHeader + call LoadMenuHeader + call Toss_Sell_Loop + ret + +Toss_Sell_Loop: + ld a, 1 + ld [wItemQuantityChangeBuffer], a +.loop + call BuySellToss_UpdateQuantityDisplay ; update display + call BuySellToss_InterpretJoypad ; joy action + jr nc, .loop + cp -1 + jr nz, .nope ; pressed B + scf + ret + +.nope + and a + ret + +BuySellToss_InterpretJoypad: + call JoyTextDelay_ForcehJoyDown ; get joypad + bit B_BUTTON_F, c + jr nz, .b + bit A_BUTTON_F, c + jr nz, .a + bit D_DOWN_F, c + jr nz, .down + bit D_UP_F, c + jr nz, .up + bit D_LEFT_F, c + jr nz, .left + bit D_RIGHT_F, c + jr nz, .right + and a + ret + +.b + ld a, -1 + scf + ret + +.a + ld a, 0 + scf + ret + +.down + ld hl, wItemQuantityChangeBuffer + dec [hl] + jr nz, .finish_down + ld a, [wItemQuantityBuffer] + ld [hl], a + +.finish_down + and a + ret + +.up + ld hl, wItemQuantityChangeBuffer + inc [hl] + ld a, [wItemQuantityBuffer] + cp [hl] + jr nc, .finish_up + ld [hl], 1 + +.finish_up + and a + ret + +.left + ld a, [wItemQuantityChangeBuffer] + sub 10 + jr c, .load_1 + jr z, .load_1 + jr .finish_left + +.load_1 + ld a, 1 + +.finish_left + ld [wItemQuantityChangeBuffer], a + and a + ret + +.right + ld a, [wItemQuantityChangeBuffer] + add 10 + ld b, a + ld a, [wItemQuantityBuffer] + cp b + jr nc, .finish_right + ld b, a + +.finish_right + ld a, b + ld [wItemQuantityChangeBuffer], a + and a + ret + +BuySellToss_UpdateQuantityDisplay: + call MenuBox + call MenuBoxCoord2Tile + ld de, SCREEN_WIDTH + 1 + add hl, de + ld [hl], "×" + inc hl + ld de, wItemQuantityChangeBuffer + lb bc, PRINTNUM_LEADINGZEROS | 1, 2 + call PrintNum + ld a, [wMenuDataPointer] + ld e, a + ld a, [wMenuDataPointer + 1] + ld d, a + ld a, [wMenuDataBank] + call FarCall_de + ret + +ret_25097: + ret + +DisplayPurchasePrice: + call BuySell_MultiplyPrice + call BuySell_DisplaySubtotal + ret + +DisplaySellingPrice: + call BuySell_MultiplyPrice + call Sell_HalvePrice + call BuySell_DisplaySubtotal + ret + +BuySell_MultiplyPrice: + xor a + ld [hMultiplicand + 0], a + ld a, [wBuffer1] + ld [hMultiplicand + 1], a + ld a, [wBuffer2] + ld [hMultiplicand + 2], a + ld a, [wItemQuantityChangeBuffer] + ld [hMultiplier], a + push hl + call Multiply + pop hl + ret + +Sell_HalvePrice: + push hl + ld hl, hProduct + 1 + ld a, [hl] + srl a + ld [hli], a + ld a, [hl] + rra + ld [hli], a + ld a, [hl] + rra + ld [hl], a + pop hl + ret + +BuySell_DisplaySubtotal: + push hl + ld hl, hMoneyTemp + ld a, [hProduct + 1] + ld [hli], a + ld a, [hProduct + 2] + ld [hli], a + ld a, [hProduct + 3] + ld [hl], a + pop hl + inc hl + ld de, hMoneyTemp + lb bc, PRINTNUM_MONEY | 3, 6 + call PrintNum + call WaitBGMap + ret + +TossItem_MenuHeader: + db MENU_BACKUP_TILES ; flags + menu_coords 15, 9, SCREEN_WIDTH - 1, TEXTBOX_Y - 1 + dw ret_25097 + db 0 ; default option + +BuyItem_MenuHeader: + db MENU_BACKUP_TILES ; flags + menu_coords 7, 15, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1 + dw DisplayPurchasePrice + db -1 ; default option + +SellItem_MenuHeader: + db MENU_BACKUP_TILES ; flags + menu_coords 7, 15, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1 + dw DisplaySellingPrice + db 0 ; default option diff --git a/engine/items/item_effects.asm b/engine/items/item_effects.asm new file mode 100644 index 000000000..1439b2c6d --- /dev/null +++ b/engine/items/item_effects.asm @@ -0,0 +1,2958 @@ +_DoItemEffect:: + ld a, [wCurItem] + ld [wd265], a + call GetItemName + call CopyName1 + ld a, 1 + ld [wItemEffectSucceeded], a + ld a, [wCurItem] + dec a + ld hl, ItemEffects + rst JumpTable + ret + +ItemEffects: +; entries correspond to item ids + dw PokeBallEffect ; MASTER_BALL + dw PokeBallEffect ; ULTRA_BALL + dw NoEffect ; BRIGHTPOWDER + dw PokeBallEffect ; GREAT_BALL + dw PokeBallEffect ; POKE_BALL + dw TownMapEffect ; TOWN_MAP + dw BicycleEffect ; BICYCLE + dw EvoStoneEffect ; MOON_STONE + dw StatusHealingEffect ; ANTIDOTE + dw StatusHealingEffect ; BURN_HEAL + dw StatusHealingEffect ; ICE_HEAL + dw StatusHealingEffect ; AWAKENING + dw StatusHealingEffect ; PARLYZ_HEAL + dw FullRestoreEffect ; FULL_RESTORE + dw RestoreHPEffect ; MAX_POTION + dw RestoreHPEffect ; HYPER_POTION + dw RestoreHPEffect ; SUPER_POTION + dw RestoreHPEffect ; POTION + dw EscapeRopeEffect ; ESCAPE_ROPE + dw RepelEffect ; REPEL + dw RestorePPEffect ; MAX_ELIXER + dw EvoStoneEffect ; FIRE_STONE + dw EvoStoneEffect ; THUNDERSTONE + dw EvoStoneEffect ; WATER_STONE + dw NoEffect ; ITEM_19 + dw VitaminEffect ; HP_UP + dw VitaminEffect ; PROTEIN + dw VitaminEffect ; IRON + dw VitaminEffect ; CARBOS + dw NoEffect ; LUCKY_PUNCH + dw VitaminEffect ; CALCIUM + dw RareCandyEffect ; RARE_CANDY + dw XAccuracyEffect ; X_ACCURACY + dw EvoStoneEffect ; LEAF_STONE + dw NoEffect ; METAL_POWDER + dw NoEffect ; NUGGET + dw PokeDollEffect ; POKE_DOLL + dw StatusHealingEffect ; FULL_HEAL + dw ReviveEffect ; REVIVE + dw ReviveEffect ; MAX_REVIVE + dw GuardSpecEffect ; GUARD_SPEC + dw SuperRepelEffect ; SUPER_REPEL + dw MaxRepelEffect ; MAX_REPEL + dw DireHitEffect ; DIRE_HIT + dw NoEffect ; ITEM_2D + dw RestoreHPEffect ; FRESH_WATER + dw RestoreHPEffect ; SODA_POP + dw RestoreHPEffect ; LEMONADE + dw XItemEffect ; X_ATTACK + dw NoEffect ; ITEM_32 + dw XItemEffect ; X_DEFEND + dw XItemEffect ; X_SPEED + dw XItemEffect ; X_SPECIAL + dw CoinCaseEffect ; COIN_CASE + dw ItemfinderEffect ; ITEMFINDER + dw PokeFluteEffect ; POKE_FLUTE + dw NoEffect ; EXP_SHARE + dw OldRodEffect ; OLD_ROD + dw GoodRodEffect ; GOOD_ROD + dw NoEffect ; SILVER_LEAF + dw SuperRodEffect ; SUPER_ROD + dw RestorePPEffect ; PP_UP + dw RestorePPEffect ; ETHER + dw RestorePPEffect ; MAX_ETHER + dw RestorePPEffect ; ELIXER + dw NoEffect ; RED_SCALE + dw NoEffect ; SECRETPOTION + dw NoEffect ; S_S_TICKET + dw NoEffect ; MYSTERY_EGG + dw NoEffect ; CLEAR_BELL + dw NoEffect ; SILVER_WING + dw RestoreHPEffect ; MOOMOO_MILK + dw NoEffect ; QUICK_CLAW + dw StatusHealingEffect ; PSNCUREBERRY + dw NoEffect ; GOLD_LEAF + dw NoEffect ; SOFT_SAND + dw NoEffect ; SHARP_BEAK + dw StatusHealingEffect ; PRZCUREBERRY + dw StatusHealingEffect ; BURNT_BERRY + dw StatusHealingEffect ; ICE_BERRY + dw NoEffect ; POISON_BARB + dw NoEffect ; KINGS_ROCK + dw BitterBerryEffect ; BITTER_BERRY + dw StatusHealingEffect ; MINT_BERRY + dw NoEffect ; RED_APRICORN + dw NoEffect ; TINYMUSHROOM + dw NoEffect ; BIG_MUSHROOM + dw NoEffect ; SILVERPOWDER + dw NoEffect ; BLU_APRICORN + dw NoEffect ; ITEM_5A + dw NoEffect ; AMULET_COIN + dw NoEffect ; YLW_APRICORN + dw NoEffect ; GRN_APRICORN + dw NoEffect ; CLEANSE_TAG + dw NoEffect ; MYSTIC_WATER + dw NoEffect ; TWISTEDSPOON + dw NoEffect ; WHT_APRICORN + dw NoEffect ; BLACKBELT + dw NoEffect ; BLK_APRICORN + dw NoEffect ; ITEM_64 + dw NoEffect ; PNK_APRICORN + dw NoEffect ; BLACKGLASSES + dw NoEffect ; SLOWPOKETAIL + dw NoEffect ; PINK_BOW + dw NoEffect ; STICK + dw NoEffect ; SMOKE_BALL + dw NoEffect ; NEVERMELTICE + dw NoEffect ; MAGNET + dw StatusHealingEffect ; MIRACLEBERRY + dw NoEffect ; PEARL + dw NoEffect ; BIG_PEARL + dw NoEffect ; EVERSTONE + dw NoEffect ; SPELL_TAG + dw RestoreHPEffect ; RAGECANDYBAR + dw NoEffect ; GS_BALL + dw BlueCardEffect ; BLUE_CARD + dw NoEffect ; MIRACLE_SEED + dw NoEffect ; THICK_CLUB + dw NoEffect ; FOCUS_BAND + dw NoEffect ; ITEM_78 + dw EnergypowderEffect ; ENERGYPOWDER + dw EnergyRootEffect ; ENERGY_ROOT + dw HealPowderEffect ; HEAL_POWDER + dw RevivalHerbEffect ; REVIVAL_HERB + dw NoEffect ; HARD_STONE + dw NoEffect ; LUCKY_EGG + dw CardKeyEffect ; CARD_KEY + dw NoEffect ; MACHINE_PART + dw NoEffect ; EGG_TICKET + dw NoEffect ; LOST_ITEM + dw NoEffect ; STARDUST + dw NoEffect ; STAR_PIECE + dw BasementKeyEffect ; BASEMENT_KEY + dw NoEffect ; PASS + dw NoEffect ; ITEM_87 + dw NoEffect ; ITEM_88 + dw NoEffect ; ITEM_89 + dw NoEffect ; CHARCOAL + dw RestoreHPEffect ; BERRY_JUICE + dw NoEffect ; SCOPE_LENS + dw NoEffect ; ITEM_8D + dw NoEffect ; ITEM_8E + dw NoEffect ; METAL_COAT + dw NoEffect ; DRAGON_FANG + dw NoEffect ; ITEM_91 + dw NoEffect ; LEFTOVERS + dw NoEffect ; ITEM_93 + dw NoEffect ; ITEM_94 + dw NoEffect ; ITEM_95 + dw RestorePPEffect ; MYSTERYBERRY + dw NoEffect ; DRAGON_SCALE + dw NoEffect ; BERSERK_GENE + dw NoEffect ; ITEM_99 + dw NoEffect ; ITEM_9A + dw NoEffect ; ITEM_9B + dw SacredAshEffect ; SACRED_ASH + dw PokeBallEffect ; HEAVY_BALL + dw NoEffect ; FLOWER_MAIL + dw PokeBallEffect ; LEVEL_BALL + dw PokeBallEffect ; LURE_BALL + dw PokeBallEffect ; FAST_BALL + dw NoEffect ; ITEM_A2 + dw NoEffect ; LIGHT_BALL + dw PokeBallEffect ; FRIEND_BALL + dw PokeBallEffect ; MOON_BALL + dw PokeBallEffect ; LOVE_BALL + dw NormalBoxEffect ; NORMAL_BOX + dw GorgeousBoxEffect ; GORGEOUS_BOX + dw EvoStoneEffect ; SUN_STONE + dw NoEffect ; POLKADOT_BOW + dw NoEffect ; ITEM_AB + dw NoEffect ; UP_GRADE + dw RestoreHPEffect ; BERRY + dw RestoreHPEffect ; GOLD_BERRY + dw SquirtbottleEffect ; SQUIRTBOTTLE + dw NoEffect ; ITEM_B0 + dw PokeBallEffect ; PARK_BALL + dw NoEffect ; RAINBOW_WING + dw NoEffect ; ITEM_B3 + +PokeBallEffect: + ld a, [wBattleMode] + dec a + jp nz, UseBallInTrainerBattle + + ld a, [wPartyCount] + cp PARTY_LENGTH + jr nz, .room_in_party + + ld a, BANK(sBoxCount) + call GetSRAMBank + ld a, [sBoxCount] + cp MONS_PER_BOX + call CloseSRAM + jp z, Ball_BoxIsFullMessage + +.room_in_party + xor a + ld [wWildMon], a + ld a, [wCurItem] + cp PARK_BALL + call nz, ReturnToBattle_UseBall + + ld hl, wOptions + res NO_TEXT_SCROLL, [hl] + ld hl, UsedItemText + call PrintText + + ld a, [wEnemyMonCatchRate] + ld b, a + ld a, [wBattleType] + cp BATTLETYPE_TUTORIAL + jp z, .catch_without_fail + ld a, [wCurItem] + cp MASTER_BALL + jp z, .catch_without_fail + ld a, [wCurItem] + ld c, a + ld hl, BallMultiplierFunctionTable + +.get_multiplier_loop + ld a, [hli] + cp $ff + jr z, .skip_or_return_from_ball_fn + cp c + jr z, .call_ball_function + inc hl + inc hl + jr .get_multiplier_loop + +.call_ball_function + ld a, [hli] + ld h, [hl] + ld l, a + ld de, .skip_or_return_from_ball_fn + push de + jp hl + +.skip_or_return_from_ball_fn + ld a, [wCurItem] + cp LEVEL_BALL + ld a, b + jp z, .skip_hp_calc + + ld a, b + ld [hMultiplicand + 2], a + + ld hl, wEnemyMonHP + ld b, [hl] + inc hl + ld c, [hl] + inc hl + ld d, [hl] + inc hl + ld e, [hl] + sla c + rl b + + ld h, d + ld l, e + add hl, de + add hl, de + ld d, h + ld e, l + ld a, d + and a + jr z, .okay_1 + + srl d + rr e + srl d + rr e + srl b + rr c + srl b + rr c + + ld a, c + and a + jr nz, .okay_1 + ld c, $1 +.okay_1 + ld b, e + + push bc + ld a, b + sub c + ld [hMultiplier], a + xor a + ld [hDividend + 0], a + ld [hMultiplicand + 0], a + ld [hMultiplicand + 1], a + call Multiply + pop bc + + ld a, b + ld [hDivisor], a + ld b, $4 + call Divide + + ld a, [hQuotient + 2] + and a + jr nz, .statuscheck + ld a, 1 +.statuscheck +; This routine is buggy. It was intended that SLP and FRZ provide a higher +; catch rate than BRN/PSN/PAR, which in turn provide a higher catch rate than +; no status effect at all. But instead, it makes BRN/PSN/PAR provide no +; benefit. +; Uncomment the line below to fix this. + ld b, a + ld a, [wEnemyMonStatus] + and 1 << FRZ | SLP + ld c, 10 + jr nz, .addstatus + ; ld a, [wEnemyMonStatus] + and a + ld c, 5 + jr nz, .addstatus + ld c, 0 +.addstatus + ld a, b + add c + jr nc, .max_1 + ld a, $ff +.max_1 + + ; BUG: farcall overwrites a, and GetItemHeldEffect takes b anyway. + ; This is probably the reason the HELD_CATCH_CHANCE effect is never used. + ; Uncomment the line below to fix. + ld d, a + push de + ld a, [wBattleMonItem] + ; ld b, a + farcall GetItemHeldEffect + ld a, b + cp HELD_CATCH_CHANCE + pop de + ld a, d + jr nz, .max_2 + add c + jr nc, .max_2 + ld a, $ff +.max_2 + +.skip_hp_calc + ld b, a + ld [wBuffer1], a + call Random + + cp b + ld a, 0 + jr z, .catch_without_fail + jr nc, .fail_to_catch + +.catch_without_fail + ld a, [wEnemyMonSpecies] + +.fail_to_catch + ld [wWildMon], a + ld c, 20 + call DelayFrames + + ld a, [wCurItem] + cp POKE_BALL + 1 ; Assumes Master/Ultra/Great come before + jr c, .not_kurt_ball + ld a, POKE_BALL +.not_kurt_ball + ld [wBattleAnimParam], a + + ld de, ANIM_THROW_POKE_BALL + ld a, e + ld [wFXAnimID], a + ld a, d + ld [wFXAnimID + 1], a + xor a + ld [hBattleTurn], a + ld [wBuffer2], a + ld [wNumHits], a + predef PlayBattleAnim + + ld a, [wWildMon] + and a + jr nz, .caught + ld a, [wBuffer2] + cp $1 + ld hl, Text_NoShake + jp z, .shake_and_break_free + cp $2 + ld hl, Text_OneShake + jp z, .shake_and_break_free + cp $3 + ld hl, Text_TwoShakes + jp z, .shake_and_break_free + cp $4 + ld hl, Text_ThreeShakes + jp z, .shake_and_break_free +.caught + + ld hl, wEnemyMonStatus + ld a, [hli] + push af + inc hl + ld a, [hli] + push af + ld a, [hl] + push af + push hl + ld hl, wEnemyMonItem + ld a, [hl] + push af + push hl + ld hl, wEnemySubStatus5 + ld a, [hl] + push af + set SUBSTATUS_TRANSFORMED, [hl] + +; This code is buggy. Any wild Pokémon that has Transformed will be +; caught as a Ditto, even if it was something else like Mew. +; To fix, do not set [wTempEnemyMonSpecies] to DITTO. + bit SUBSTATUS_TRANSFORMED, a + jr nz, .ditto + jr .not_ditto + +.ditto + ld a, DITTO + ld [wTempEnemyMonSpecies], a + jr .load_data + +.not_ditto + set SUBSTATUS_TRANSFORMED, [hl] + ld hl, wEnemyBackupDVs + ld a, [wEnemyMonDVs] + ld [hli], a + ld a, [wEnemyMonDVs + 1] + ld [hl], a + +.load_data + ld a, [wTempEnemyMonSpecies] + ld [wCurPartySpecies], a + ld a, [wEnemyMonLevel] + ld [wCurPartyLevel], a + farcall LoadEnemyMon + + pop af + ld [wEnemySubStatus5], a + + pop hl + pop af + ld [hl], a + pop hl + pop af + ld [hld], a + pop af + ld [hld], a + dec hl + pop af + ld [hl], a + + ld hl, wEnemySubStatus5 + bit SUBSTATUS_TRANSFORMED, [hl] + jr nz, .Transformed + ld hl, wWildMonMoves + ld de, wEnemyMonMoves + ld bc, NUM_MOVES + call CopyBytes + + ld hl, wWildMonPP + ld de, wEnemyMonPP + ld bc, NUM_MOVES + call CopyBytes + +.Transformed: + ld a, [wEnemyMonSpecies] + ld [wWildMon], a + ld [wCurPartySpecies], a + ld [wd265], a + ld a, [wBattleType] + cp BATTLETYPE_TUTORIAL + jp z, .FinishTutorial + + farcall StubbedTrainerRankings_WildMonsCaught + + ld hl, Text_GotchaMonWasCaught + call PrintText + + call ClearSprites + + ld a, [wd265] + dec a + call CheckCaughtMon + + ld a, c + push af + ld a, [wd265] + dec a + call SetSeenAndCaughtMon + pop af + and a + jr nz, .skip_pokedex + + call CheckReceivedDex + jr z, .skip_pokedex + + ld hl, Text_AddedToPokedex + call PrintText + + call ClearSprites + + ld a, [wEnemyMonSpecies] + ld [wd265], a + predef NewPokedexEntry + +.skip_pokedex + ld a, [wBattleType] + cp BATTLETYPE_CONTEST + jp z, .catch_bug_contest_mon + cp BATTLETYPE_CELEBI + jr nz, .not_celebi + ld hl, wBattleResult + set BATTLERESULT_CAUGHT_CELEBI, [hl] +.not_celebi + + ld a, [wPartyCount] + cp PARTY_LENGTH + jr z, .SendToPC + + xor a ; PARTYMON + ld [wMonType], a + call ClearSprites + + predef TryAddMonToParty + + farcall SetCaughtData + + ld a, [wCurItem] + cp FRIEND_BALL + jr nz, .SkipPartyMonFriendBall + + ld a, [wPartyCount] + dec a + ld hl, wPartyMon1Happiness + ld bc, PARTYMON_STRUCT_LENGTH + call AddNTimes + + ld a, FRIEND_BALL_HAPPINESS + ld [hl], a + +.SkipPartyMonFriendBall: + ld hl, Text_AskNicknameNewlyCaughtMon + call PrintText + + ld a, [wCurPartySpecies] + ld [wd265], a + call GetPokemonName + + call YesNoBox + jp c, .return_from_capture + + ld a, [wPartyCount] + dec a + ld [wCurPartyMon], a + ld hl, wPartyMonNicknames + ld bc, MON_NAME_LENGTH + call AddNTimes + + ld d, h + ld e, l + push de + xor a ; PARTYMON + ld [wMonType], a + ld b, 0 + farcall NamingScreen + + call RotateThreePalettesRight + + call LoadStandardFont + + pop hl + ld de, wStringBuffer1 + call InitName + + jp .return_from_capture + +.SendToPC: + call ClearSprites + + predef SendMonIntoBox + + farcall SetBoxMonCaughtData + + ld a, BANK(sBoxCount) + call GetSRAMBank + + ld a, [sBoxCount] + cp MONS_PER_BOX + jr nz, .BoxNotFullYet + ld hl, wBattleResult + set BATTLERESULT_BOX_FULL, [hl] +.BoxNotFullYet: + ld a, [wCurItem] + cp FRIEND_BALL + jr nz, .SkipBoxMonFriendBall + ; The captured mon is now first in the box + ld a, FRIEND_BALL_HAPPINESS + ld [sBoxMon1Happiness], a +.SkipBoxMonFriendBall: + call CloseSRAM + + ld hl, Text_AskNicknameNewlyCaughtMon + call PrintText + + ld a, [wCurPartySpecies] + ld [wd265], a + call GetPokemonName + + call YesNoBox + jr c, .SkipBoxMonNickname + + xor a + ld [wCurPartyMon], a + ld a, BOXMON + ld [wMonType], a + ld de, wMonOrItemNameBuffer + ld b, $0 + farcall NamingScreen + + ld a, BANK(sBoxMonNicknames) + call GetSRAMBank + + ld hl, wMonOrItemNameBuffer + ld de, sBoxMonNicknames + ld bc, MON_NAME_LENGTH + call CopyBytes + + ld hl, sBoxMonNicknames + ld de, wStringBuffer1 + call InitName + + call CloseSRAM + +.SkipBoxMonNickname: + ld a, BANK(sBoxMonNicknames) + call GetSRAMBank + + ld hl, sBoxMonNicknames + ld de, wMonOrItemNameBuffer + ld bc, MON_NAME_LENGTH + call CopyBytes + + call CloseSRAM + + ld hl, Text_SentToBillsPC + call PrintText + + call RotateThreePalettesRight + call LoadStandardFont + jr .return_from_capture + +.catch_bug_contest_mon + farcall BugContest_SetCaughtContestMon + jr .return_from_capture + +.FinishTutorial: + ld hl, Text_GotchaMonWasCaught + +.shake_and_break_free + call PrintText + call ClearSprites + +.return_from_capture + ld a, [wBattleType] + cp BATTLETYPE_TUTORIAL + ret z + cp BATTLETYPE_DEBUG + ret z + cp BATTLETYPE_CONTEST + jr z, .used_park_ball + + ld a, [wWildMon] + and a + jr z, .toss + + call ClearBGPalettes + call ClearTileMap + +.toss + ld hl, wNumItems + inc a + ld [wItemQuantityChangeBuffer], a + jp TossItem + +.used_park_ball + ld hl, wParkBallsRemaining + dec [hl] + ret + +BallMultiplierFunctionTable: +; table of routines that increase or decrease the catch rate based on +; which ball is used in a certain situation. + dbw ULTRA_BALL, UltraBallMultiplier + dbw GREAT_BALL, GreatBallMultiplier + dbw SAFARI_BALL, SafariBallMultiplier ; Safari Ball, leftover from RBY + dbw HEAVY_BALL, HeavyBallMultiplier + dbw LEVEL_BALL, LevelBallMultiplier + dbw LURE_BALL, LureBallMultiplier + dbw FAST_BALL, FastBallMultiplier + dbw MOON_BALL, MoonBallMultiplier + dbw LOVE_BALL, LoveBallMultiplier + dbw PARK_BALL, ParkBallMultiplier + db -1 ; end + +UltraBallMultiplier: +; multiply catch rate by 2 + sla b + ret nc + ld b, $ff + ret + +SafariBallMultiplier: +GreatBallMultiplier: +ParkBallMultiplier: +; multiply catch rate by 1.5 + ld a, b + srl a + add b + ld b, a + ret nc + ld b, $ff + ret + +GetPokedexEntryBank: + push hl + push de + ld a, [wEnemyMonSpecies] + rlca + rlca + maskbits NUM_DEX_ENTRY_BANKS + ld hl, .PokedexEntryBanks + ld d, 0 + ld e, a + add hl, de + ld a, [hl] + pop de + pop hl + ret + +.PokedexEntryBanks: + db BANK("Pokedex Entries 001-064") + db BANK("Pokedex Entries 065-128") + db BANK("Pokedex Entries 129-192") + db BANK("Pokedex Entries 193-251") + +HeavyBallMultiplier: +; subtract 20 from catch rate if weight < 102.4 kg +; else add 0 to catch rate if weight < 204.8 kg +; else add 20 to catch rate if weight < 307.2 kg +; else add 30 to catch rate if weight < 409.6 kg +; else add 40 to catch rate (never happens) + ld a, [wEnemyMonSpecies] + ld hl, PokedexDataPointerTable + dec a + ld e, a + ld d, 0 + add hl, de + add hl, de + ld a, BANK(PokedexDataPointerTable) + call GetFarHalfword + +.SkipText: + call GetPokedexEntryBank + call GetFarByte + inc hl + cp "@" + jr nz, .SkipText + + call GetPokedexEntryBank + push bc + inc hl + inc hl + call GetFarHalfword + + srl h + rr l + ld b, h + ld c, l + +rept 4 + srl b + rr c +endr + call .subbc + + srl b + rr c + call .subbc + + ld a, h + pop bc + jr .compare + +.subbc + ; subtract bc from hl + push bc + ld a, b + cpl + ld b, a + ld a, c + cpl + ld c, a + inc bc + add hl, bc + pop bc + ret + +.compare + ld c, a + cp HIGH(1024) ; 102.4 kg + jr c, .lightmon + + ld hl, .WeightsTable +.lookup + ld a, c + cp [hl] + jr c, .heavymon + inc hl + inc hl + jr .lookup + +.heavymon + inc hl + ld a, b + add [hl] + ld b, a + ret nc + ld b, $ff + ret + +.lightmon + ld a, b + sub 20 + ld b, a + ret nc + ld b, $1 + ret + +.WeightsTable: +; weight factor, boost + db HIGH(2048), 0 + db HIGH(3072), 20 + db HIGH(4096), 30 + db HIGH(65280), 40 + +LureBallMultiplier: +; multiply catch rate by 3 if this is a fishing rod battle + ld a, [wBattleType] + cp BATTLETYPE_FISH + ret nz + + ld a, b + add a + jr c, .max + + add b + jr nc, .done +.max + ld a, $ff +.done + ld b, a + ret + +MoonBallMultiplier: +; This function is buggy. +; Intent: multiply catch rate by 4 if mon evolves with moon stone +; Reality: no boost + push bc + ld a, [wTempEnemyMonSpecies] + dec a + ld c, a + ld b, 0 + ld hl, EvosAttacksPointers + add hl, bc + add hl, bc + ld a, BANK(EvosAttacksPointers) + call GetFarHalfword + pop bc + + push bc + ld a, BANK("Evolutions and Attacks") + call GetFarByte + cp EVOLVE_ITEM + pop bc + ret nz + + inc hl + inc hl + inc hl + +; Moon Stone's constant from Pokémon Red is used. +; No Pokémon evolve with Burn Heal, +; so Moon Balls always have a catch rate of 1×. + push bc + ld a, BANK("Evolutions and Attacks") + call GetFarByte + cp MOON_STONE_RED ; BURN_HEAL + pop bc + ret nz + + sla b + jr c, .max + sla b + jr nc, .done +.max + ld b, $ff +.done + ret + +LoveBallMultiplier: +; This function is buggy. +; Intent: multiply catch rate by 8 if mons are of same species, different sex +; Reality: multiply catch rate by 8 if mons are of same species, same sex + + ; does species match? + ld a, [wTempEnemyMonSpecies] + ld c, a + ld a, [wTempBattleMonSpecies] + cp c + ret nz + + ; check player mon species + push bc + ld a, [wTempBattleMonSpecies] + ld [wCurPartySpecies], a + xor a ; PARTYMON + ld [wMonType], a + ld a, [wCurBattleMon] + ld [wCurPartyMon], a + farcall GetGender + jr c, .done1 ; no effect on genderless + + ld d, 0 ; male + jr nz, .playermale + inc d ; female +.playermale + + ; check wild mon species + push de + ld a, [wTempEnemyMonSpecies] + ld [wCurPartySpecies], a + ld a, WILDMON + ld [wMonType], a + farcall GetGender + jr c, .done2 ; no effect on genderless + + ld d, 0 ; male + jr nz, .wildmale + inc d ; female +.wildmale + + ld a, d + pop de + cp d + pop bc + ret nz ; for the intended effect, this should be "ret z" + + sla b + jr c, .max + sla b + jr c, .max + sla b + ret nc +.max + ld b, $ff + ret + +.done2 + pop de + +.done1 + pop bc + ret + +FastBallMultiplier: +; This function is buggy. +; Intent: multiply catch rate by 4 if enemy mon is in one of the three +; FleeMons tables. +; Reality: multiply catch rate by 4 if enemy mon is one of the first three in +; the first FleeMons table. + ld a, [wTempEnemyMonSpecies] + ld c, a + ld hl, FleeMons + ld d, 3 + +.loop + ld a, BANK(FleeMons) + call GetFarByte + + inc hl + cp -1 + jr z, .next + cp c + jr nz, .next ; for the intended effect, this should be "jr nz, .loop" + sla b + jr c, .max + + sla b + ret nc + +.max + ld b, $ff + ret + +.next + dec d + jr nz, .loop + ret + +LevelBallMultiplier: +; multiply catch rate by 8 if player mon level / 4 > enemy mon level +; multiply catch rate by 4 if player mon level / 2 > enemy mon level +; multiply catch rate by 2 if player mon level > enemy mon level + ld a, [wBattleMonLevel] + ld c, a + ld a, [wEnemyMonLevel] + cp c + ret nc ; if player is lower level, we're done here + sla b + jr c, .max + + srl c + cp c + ret nc ; if player/2 is lower level, we're done here + sla b + jr c, .max + + srl c + cp c + ret nc ; if player/4 is lower level, we're done here + sla b + ret nc + +.max + ld b, $ff + ret + +; These two texts were carried over from gen 1. +; They are not used in gen 2, and are dummied out. + +Text_RBY_CatchMarowak: + ; It dodged the thrown BALL! This #MON can't be caught! + text_jump UnknownText_0x1c5a5a + db "@" + +Text_RBY_NoShake: + ; You missed the #MON! + text_jump UnknownText_0x1c5a90 + db "@" + +Text_NoShake: + ; Oh no! The #MON broke free! + text_jump UnknownText_0x1c5aa6 + db "@" + +Text_OneShake: + ; Aww! It appeared to be caught! + text_jump UnknownText_0x1c5ac3 + db "@" + +Text_TwoShakes: + ; Aargh! Almost had it! + text_jump UnknownText_0x1c5ae3 + db "@" + +Text_ThreeShakes: + ; Shoot! It was so close too! + text_jump UnknownText_0x1c5afa + db "@" + +Text_GotchaMonWasCaught: + ; Gotcha! @ was caught!@ @ + text_jump UnknownText_0x1c5b17 + start_asm + call WaitSFX + push bc + ld de, MUSIC_NONE + call PlayMusic + call DelayFrame + ld de, MUSIC_CAPTURE + call PlayMusic + pop bc + ld hl, TextJump_Waitbutton + ret + +TextJump_Waitbutton: + ; @ + text_jump Text_Waitbutton_2 + db "@" + +Text_SentToBillsPC: + ; was sent to BILL's PC. + text_jump UnknownText_0x1c5b38 + db "@" + +Text_AddedToPokedex: + ; 's data was newly added to the #DEX.@ @ + text_jump UnknownText_0x1c5b53 + db "@" + +Text_AskNicknameNewlyCaughtMon: + ; Give a nickname to @ ? + text_jump UnknownText_0x1c5b7f + db "@" + +ReturnToBattle_UseBall: + farcall _ReturnToBattle_UseBall + ret + +TownMapEffect: + farcall PokegearMap + ret + +BicycleEffect: + farcall BikeFunction + ret + +EvoStoneEffect: + ld b, PARTYMENUACTION_EVO_STONE + call UseItem_SelectMon + + jp c, .DecidedNotToUse + + ld a, MON_ITEM + call GetPartyParamLocation + + ld a, [hl] + cp EVERSTONE + jr z, .NoEffect + + ld a, $1 + ld [wForceEvolution], a + farcall EvolvePokemon + + ld a, [wMonTriedToEvolve] + and a + jr z, .NoEffect + + jp UseDisposableItem + +.NoEffect: + call WontHaveAnyEffectMessage + +.DecidedNotToUse: + xor a + ld [wItemEffectSucceeded], a + ret + +VitaminEffect: + ld b, PARTYMENUACTION_HEALING_ITEM + call UseItem_SelectMon + + jp c, RareCandy_StatBooster_ExitMenu + + call RareCandy_StatBooster_GetParameters + + call GetStatExpRelativePointer + + ld a, MON_STAT_EXP + call GetPartyParamLocation + + add hl, bc + ld a, [hl] + cp 100 + jr nc, NoEffectMessage + + add 10 + ld [hl], a + call UpdateStatsAfterItem + + call GetStatExpRelativePointer + + ld hl, StatStrings + add hl, bc + ld a, [hli] + ld h, [hl] + ld l, a + ld de, wStringBuffer2 + ld bc, ITEM_NAME_LENGTH + call CopyBytes + + call Play_SFX_FULL_HEAL + + ld hl, Text_StatRose + call PrintText + + ld c, HAPPINESS_USEDITEM + farcall ChangeHappiness + + jp UseDisposableItem + +NoEffectMessage: + ld hl, WontHaveAnyEffectText + call PrintText + jp ClearPalettes + +UpdateStatsAfterItem: + ld a, MON_MAXHP + call GetPartyParamLocation + ld d, h + ld e, l + ld a, MON_STAT_EXP - 1 + call GetPartyParamLocation + ld b, TRUE + predef_jump CalcMonStats + +RareCandy_StatBooster_ExitMenu: + xor a + ld [wItemEffectSucceeded], a + jp ClearPalettes + +Text_StatRose: + ; 's @ rose. + text_jump UnknownText_0x1c5b9a + db "@" + +StatStrings: + dw .health + dw .attack + dw .defense + dw .speed + dw .special + +.health db "HEALTH@" +.attack db "ATTACK@" +.defense db "DEFENSE@" +.speed db "SPEED@" +.special db "SPECIAL@" + +GetStatExpRelativePointer: + ld a, [wCurItem] + ld hl, Table_eeeb +.next + cp [hl] + inc hl + jr z, .got_it + inc hl + jr .next + +.got_it + ld a, [hl] + ld c, a + ld b, 0 + ret + +Table_eeeb: + db HP_UP, MON_HP_EXP - MON_STAT_EXP + db PROTEIN, MON_ATK_EXP - MON_STAT_EXP + db IRON, MON_DEF_EXP - MON_STAT_EXP + db CARBOS, MON_SPD_EXP - MON_STAT_EXP + db CALCIUM, MON_SPC_EXP - MON_STAT_EXP + +RareCandy_StatBooster_GetParameters: + ld a, [wCurPartySpecies] + ld [wCurSpecies], a + ld [wd265], a + ld a, MON_LEVEL + call GetPartyParamLocation + ld a, [hl] + ld [wCurPartyLevel], a + call GetBaseData + ld a, [wCurPartyMon] + ld hl, wPartyMonNicknames + call GetNick + ret + +RareCandyEffect: + ld b, PARTYMENUACTION_HEALING_ITEM + call UseItem_SelectMon + + jp c, RareCandy_StatBooster_ExitMenu + + call RareCandy_StatBooster_GetParameters + + ld a, MON_LEVEL + call GetPartyParamLocation + + ld a, [hl] + cp MAX_LEVEL + jp nc, NoEffectMessage + + inc a + ld [hl], a + ld [wCurPartyLevel], a + push de + ld d, a + farcall CalcExpAtLevel + + pop de + ld a, MON_EXP + call GetPartyParamLocation + + ld a, [hMultiplicand] + ld [hli], a + ld a, [hMultiplicand + 1] + ld [hli], a + ld a, [hMultiplicand + 2] + ld [hl], a + + ld a, MON_MAXHP + call GetPartyParamLocation + ld a, [hli] + ld b, a + ld c, [hl] + push bc + call UpdateStatsAfterItem + + ld a, MON_MAXHP + 1 + call GetPartyParamLocation + + pop bc + ld a, [hld] + sub c + ld c, a + ld a, [hl] + sbc b + ld b, a + dec hl + ld a, [hl] + add c + ld [hld], a + ld a, [hl] + adc b + ld [hl], a + farcall LevelUpHappinessMod + + ld a, PARTYMENUTEXT_LEVEL_UP + call ItemActionText + + xor a ; PARTYMON + ld [wMonType], a + predef CopyMonToTempMon + + hlcoord 9, 0 + ld b, 10 + ld c, 9 + call TextBox + + hlcoord 11, 1 + ld bc, 4 + predef PrintTempMonStats + + call WaitPressAorB_BlinkCursor + + xor a ; PARTYMON + ld [wMonType], a + ld a, [wCurPartySpecies] + ld [wd265], a + predef LearnLevelMoves + + xor a + ld [wForceEvolution], a + farcall EvolvePokemon + + jp UseDisposableItem + +HealPowderEffect: + ld b, PARTYMENUACTION_HEALING_ITEM + call UseItem_SelectMon + + jp c, StatusHealer_ExitMenu + + call UseStatusHealer + + cp $0 + jr nz, .asm_efc9 + ld c, HAPPINESS_BITTERPOWDER + farcall ChangeHappiness + + call LooksBitterMessage + + ld a, $0 + +.asm_efc9 + jp StatusHealer_Jumptable + +StatusHealingEffect: + ld b, PARTYMENUACTION_HEALING_ITEM + call UseItem_SelectMon + jp c, StatusHealer_ExitMenu + +FullyHealStatus: + call UseStatusHealer + jp StatusHealer_Jumptable + +UseStatusHealer: + call IsMonFainted + ld a, $1 + ret z + call GetItemHealingAction + ld a, MON_STATUS + call GetPartyParamLocation + ld a, [hl] + and c + jr nz, .good + call IsItemUsedOnConfusedMon + ld a, $1 + ret nc + ld b, PARTYMENUTEXT_HEAL_CONFUSION +.good + xor a + ld [hl], a + ld a, b + ld [wPartyMenuActionText], a + call HealStatus + call Play_SFX_FULL_HEAL + call ItemActionTextWaitButton + call UseDisposableItem + ld a, $0 + ret + +IsItemUsedOnConfusedMon: + call IsItemUsedOnBattleMon + jr nc, .nope + ld a, [wPlayerSubStatus3] + bit SUBSTATUS_CONFUSED, a + jr z, .nope + ld a, c + cp $ff + jr nz, .nope + scf + ret + +.nope + and a + ret + +BattlemonRestoreHealth: + call IsItemUsedOnBattleMon + ret nc + ld a, MON_HP + call GetPartyParamLocation + ld a, [hli] + ld [wBattleMonHP], a + ld a, [hld] + ld [wBattleMonHP + 1], a + ret + +HealStatus: + call IsItemUsedOnBattleMon + ret nc + xor a + ld [wBattleMonStatus], a + ld hl, wPlayerSubStatus5 + res SUBSTATUS_TOXIC, [hl] + ld hl, wPlayerSubStatus1 + res SUBSTATUS_NIGHTMARE, [hl] + call GetItemHealingAction + ld a, c + cp %11111111 + jr nz, .not_full_heal + ld hl, wPlayerSubStatus3 + res SUBSTATUS_CONFUSED, [hl] +.not_full_heal + push bc + farcall CalcPlayerStats + pop bc + ret + +GetItemHealingAction: + push hl + ld a, [wCurItem] + ld hl, StatusHealingActions + ld bc, 3 +.next + cp [hl] + jr z, .found_it + add hl, bc + jr .next + +.found_it + inc hl + ld b, [hl] + inc hl + ld a, [hl] + ld c, a + cp %11111111 + pop hl + ret + +INCLUDE "data/items/heal_status.asm" + +StatusHealer_Jumptable: + ld hl, .dw + rst JumpTable + ret + +.dw + dw StatusHealer_ClearPalettes + dw StatusHealer_NoEffect + dw StatusHealer_ExitMenu + +RevivalHerbEffect: + ld b, PARTYMENUACTION_HEALING_ITEM + call UseItem_SelectMon + jp c, StatusHealer_ExitMenu + + call RevivePokemon + cp 0 + jr nz, .asm_f0c5 + + ld c, HAPPINESS_REVIVALHERB + farcall ChangeHappiness + call LooksBitterMessage + ld a, 0 + +.asm_f0c5 + jp StatusHealer_Jumptable + +ReviveEffect: + ld b, PARTYMENUACTION_HEALING_ITEM + call UseItem_SelectMon + jp c, StatusHealer_ExitMenu + + call RevivePokemon + jp StatusHealer_Jumptable + +RevivePokemon: + call IsMonFainted + ld a, 1 + ret nz + ld a, [wBattleMode] + and a + jr z, .skip_to_revive + + ld a, [wCurPartyMon] + ld c, a + ld d, 0 + ld hl, wBattleParticipantsIncludingFainted + ld b, CHECK_FLAG + predef SmallFarFlagAction + ld a, c + and a + jr z, .skip_to_revive + + ld a, [wCurPartyMon] + ld c, a + ld hl, wBattleParticipantsNotFainted + ld b, SET_FLAG + predef SmallFarFlagAction + +.skip_to_revive + xor a + ld [wLowHealthAlarm], a + ld a, [wCurItem] + cp REVIVE + jr z, .revive_half_hp + + call ReviveFullHP + jr .finish_revive + +.revive_half_hp + call ReviveHalfHP + +.finish_revive + call HealHP_SFX_GFX + ld a, PARTYMENUTEXT_REVIVE + ld [wPartyMenuActionText], a + call ItemActionTextWaitButton + call UseDisposableItem + ld a, 0 + ret + +FullRestoreEffect: + ld b, PARTYMENUACTION_HEALING_ITEM + call UseItem_SelectMon + jp c, StatusHealer_ExitMenu + + call IsMonFainted + jp z, StatusHealer_NoEffect + + call IsMonAtFullHealth + jr c, .NotAtFullHealth + + jp FullyHealStatus + +.NotAtFullHealth: + call .FullRestore + jp StatusHealer_Jumptable + +.FullRestore: + xor a + ld [wLowHealthAlarm], a + call ReviveFullHP + ld a, MON_STATUS + call GetPartyParamLocation + xor a + ld [hli], a + ld [hl], a + call HealStatus + call BattlemonRestoreHealth + call HealHP_SFX_GFX + ld a, PARTYMENUTEXT_HEAL_HP + ld [wPartyMenuActionText], a + call ItemActionTextWaitButton + call UseDisposableItem + ld a, 0 + ret + +BitterBerryEffect: + ld hl, wPlayerSubStatus3 + bit SUBSTATUS_CONFUSED, [hl] + ld a, 1 + jr z, .done + + res SUBSTATUS_CONFUSED, [hl] + xor a + ld [hBattleTurn], a + call UseItemText + + ld hl, ConfusedNoMoreText + call StdBattleTextBox + + ld a, 0 + +.done + jp StatusHealer_Jumptable + +RestoreHPEffect: + call ItemRestoreHP + jp StatusHealer_Jumptable + +EnergypowderEffect: + ld c, HAPPINESS_BITTERPOWDER + jr EnergypowderEnergyRootCommon + +EnergyRootEffect: + ld c, HAPPINESS_ENERGYROOT + +EnergypowderEnergyRootCommon: + push bc + call ItemRestoreHP + pop bc + cp 0 + jr nz, .skip_happiness + + farcall ChangeHappiness + call LooksBitterMessage + ld a, 0 + +.skip_happiness + jp StatusHealer_Jumptable + +ItemRestoreHP: + ld b, PARTYMENUACTION_HEALING_ITEM + call UseItem_SelectMon + ld a, 2 + ret c + + call IsMonFainted + ld a, 1 + ret z + + call IsMonAtFullHealth + ld a, 1 + ret nc + + xor a + ld [wLowHealthAlarm], a + call GetHealingItemAmount + call RestoreHealth + call BattlemonRestoreHealth + call HealHP_SFX_GFX + ld a, PARTYMENUTEXT_HEAL_HP + ld [wPartyMenuActionText], a + call ItemActionTextWaitButton + call UseDisposableItem + ld a, 0 + ret + +HealHP_SFX_GFX: + push de + ld de, SFX_POTION + call WaitPlaySFX + pop de + ld a, [wCurPartyMon] + hlcoord 11, 0 + ld bc, SCREEN_WIDTH * 2 + call AddNTimes + ld a, $2 + ld [wWhichHPBar], a + predef_jump AnimateHPBar + +UseItem_SelectMon: + call .SelectMon + ret c + + ld a, [wCurPartySpecies] + cp EGG + jr nz, .not_egg + + call CantUseOnEggMessage + scf + ret + +.not_egg + and a + ret + +.SelectMon: + ld a, b + ld [wPartyMenuActionText], a + push hl + push de + push bc + call ClearBGPalettes + call ChooseMonToUseItemOn + pop bc + pop de + pop hl + ret + +ChooseMonToUseItemOn: + farcall LoadPartyMenuGFX + farcall InitPartyMenuWithCancel + farcall InitPartyMenuGFX + farcall WritePartyMenuTilemap + farcall PrintPartyMenuText + call WaitBGMap + call SetPalettes + call DelayFrame + farcall PartyMenuSelect + ret + +ItemActionText: + ld [wPartyMenuActionText], a + ld a, [wCurPartySpecies] + push af + ld a, [wCurPartyMon] + push af + push hl + push de + push bc + farcall WritePartyMenuTilemap + farcall PrintPartyMenuActionText + call WaitBGMap + call SetPalettes + call DelayFrame + pop bc + pop de + pop hl + pop af + ld [wCurPartyMon], a + pop af + ld [wCurPartySpecies], a + ret + +ItemActionTextWaitButton: + xor a + ld [hBGMapMode], a + hlcoord 0, 0 + ld bc, wTileMapEnd - wTileMap + ld a, " " + call ByteFill + ld a, [wPartyMenuActionText] + call ItemActionText + ld a, $1 + ld [hBGMapMode], a + ld c, 50 + call DelayFrames + jp WaitPressAorB_BlinkCursor + +StatusHealer_NoEffect: + call WontHaveAnyEffectMessage + jr StatusHealer_ClearPalettes + +StatusHealer_ExitMenu: + xor a + ld [wItemEffectSucceeded], a +StatusHealer_ClearPalettes: + call ClearPalettes + ret + +IsItemUsedOnBattleMon: + ld a, [wBattleMode] + and a + ret z + ld a, [wCurPartyMon] + push hl + ld hl, wCurBattleMon + cp [hl] + pop hl + jr nz, .nope + scf + ret + +.nope + xor a + ret + +ReviveHalfHP: + call LoadHPFromBuffer1 + srl d + rr e + jr ContinueRevive + +ReviveFullHP: + call LoadHPFromBuffer1 +ContinueRevive: + ld a, MON_HP + call GetPartyParamLocation + ld [hl], d + inc hl + ld [hl], e + jp LoadCurHPIntoBuffer5 + +RestoreHealth: + ld a, MON_HP + 1 + call GetPartyParamLocation + ld a, [hl] + add e + ld [hld], a + ld a, [hl] + adc d + ld [hl], a + jr c, .full_hp + call LoadCurHPIntoBuffer5 + ld a, MON_HP + 1 + call GetPartyParamLocation + ld d, h + ld e, l + ld a, MON_MAXHP + 1 + call GetPartyParamLocation + ld a, [de] + sub [hl] + dec de + dec hl + ld a, [de] + sbc [hl] + jr c, .finish +.full_hp + call ReviveFullHP +.finish + ret + +RemoveHP: + ld a, MON_HP + 1 + call GetPartyParamLocation + ld a, [hl] + sub e + ld [hld], a + ld a, [hl] + sbc d + ld [hl], a + jr nc, .okay + xor a + ld [hld], a + ld [hl], a +.okay + call LoadCurHPIntoBuffer5 + ret + +IsMonFainted: + push de + call LoadMaxHPToBuffer1 + call LoadCurHPToBuffer3 + call LoadHPFromBuffer3 + ld a, d + or e + pop de + ret + +IsMonAtFullHealth: + call LoadHPFromBuffer3 + ld h, d + ld l, e + call LoadHPFromBuffer1 + ld a, l + sub e + ld a, h + sbc d + ret + +LoadCurHPIntoBuffer5: + ld a, MON_HP + call GetPartyParamLocation + ld a, [hli] + ld [wBuffer6], a + ld a, [hl] + ld [wBuffer5], a + ret + +LoadHPIntoBuffer5: + ld a, d + ld [wBuffer6], a + ld a, e + ld [wBuffer5], a + ret + +LoadHPFromBuffer5: + ld a, [wBuffer6] + ld d, a + ld a, [wBuffer5] + ld e, a + ret + +LoadCurHPToBuffer3: + ld a, MON_HP + call GetPartyParamLocation + ld a, [hli] + ld [wBuffer4], a + ld a, [hl] + ld [wBuffer3], a + ret + +LoadHPFromBuffer3: + ld a, [wBuffer4] + ld d, a + ld a, [wBuffer3] + ld e, a + ret + +LoadMaxHPToBuffer1: + push hl + ld a, MON_MAXHP + call GetPartyParamLocation + ld a, [hli] + ld [wBuffer2], a + ld a, [hl] + ld [wBuffer1], a + pop hl + ret + +LoadHPFromBuffer1: + ld a, [wBuffer2] + ld d, a + ld a, [wBuffer1] + ld e, a + ret + +GetOneFifthMaxHP: + push bc + ld a, MON_MAXHP + call GetPartyParamLocation + ld a, [hli] + ld [hDividend + 0], a + ld a, [hl] + ld [hDividend + 1], a + ld a, 5 + ld [hDivisor], a + ld b, 2 + call Divide + ld a, [hQuotient + 1] + ld d, a + ld a, [hQuotient + 2] + ld e, a + pop bc + ret + +GetHealingItemAmount: + push hl + ld a, [wCurItem] + ld hl, HealingHPAmounts + ld d, a +.next + ld a, [hli] + cp -1 + jr z, .NotFound + cp d + jr z, .done + inc hl + inc hl + jr .next + +.NotFound: + scf +.done + ld e, [hl] + inc hl + ld d, [hl] + pop hl + ret + +INCLUDE "data/items/heal_hp.asm" + +Softboiled_MilkDrinkFunction: +; Softboiled/Milk Drink in the field + ld a, [wPartyMenuCursor] + dec a + ld b, a + call .SelectMilkDrinkRecipient ; select pokemon + jr c, .skip + ld a, b + ld [wCurPartyMon], a + call IsMonFainted + call GetOneFifthMaxHP + call RemoveHP + push bc + call HealHP_SFX_GFX + pop bc + call GetOneFifthMaxHP + ld a, c + ld [wCurPartyMon], a + call IsMonFainted + call RestoreHealth + call HealHP_SFX_GFX + ld a, PARTYMENUTEXT_HEAL_HP + call ItemActionText + call JoyWaitAorB +.skip + ld a, b + inc a + ld [wPartyMenuCursor], a + ret + +.SelectMilkDrinkRecipient: +.loop + push bc + ld a, PARTYMENUACTION_HEALING_ITEM + ld [wPartyMenuActionText], a + call ChooseMonToUseItemOn + pop bc + jr c, .set_carry + ld a, [wPartyMenuCursor] + dec a + ld c, a + ld a, b + cp c + jr z, .cant_use ; chose the same mon as user + ld a, c + ld [wCurPartyMon], a + call IsMonFainted + jr z, .cant_use + call IsMonAtFullHealth + jr nc, .cant_use + xor a + ret + +.set_carry + scf + ret + +.cant_use + push bc + ld hl, .Text_CantBeUsed + call MenuTextBoxBackup + pop bc + jr .loop + +.Text_CantBeUsed: + ; That can't be used on this #MON. + text_jump UnknownText_0x1c5bac + db "@" + +EscapeRopeEffect: + xor a + ld [wItemEffectSucceeded], a + farcall EscapeRopeFunction + + ld a, [wItemEffectSucceeded] + cp 1 + call z, UseDisposableItem + ret + +SuperRepelEffect: + ld b, 200 + jr UseRepel + +MaxRepelEffect: + ld b, 250 + jr UseRepel + +RepelEffect: + ld b, 100 + +UseRepel: + ld a, [wRepelEffect] + and a + ld hl, TextJump_RepelUsedEarlierIsStillInEffect + jp nz, PrintText + + ld a, b + ld [wRepelEffect], a + jp UseItemText + +TextJump_RepelUsedEarlierIsStillInEffect: + ; The REPEL used earlier is still in effect. + text_jump Text_RepelUsedEarlierIsStillInEffect + db "@" + +XAccuracyEffect: + ld hl, wPlayerSubStatus4 + bit SUBSTATUS_X_ACCURACY, [hl] + jp nz, WontHaveAnyEffect_NotUsedMessage + set SUBSTATUS_X_ACCURACY, [hl] + jp UseItemText + +PokeDollEffect: + ld a, [wBattleMode] + dec a + jr nz, .asm_f4a6 + inc a + ld [wForcedSwitch], a + ld a, [wBattleResult] + and BATTLERESULT_BITMASK + or DRAW + ld [wBattleResult], a + jp UseItemText + +.asm_f4a6 + xor a + ld [wItemEffectSucceeded], a + ret + +GuardSpecEffect: + ld hl, wPlayerSubStatus4 + bit SUBSTATUS_MIST, [hl] + jp nz, WontHaveAnyEffect_NotUsedMessage + set SUBSTATUS_MIST, [hl] + jp UseItemText + +DireHitEffect: + ld hl, wPlayerSubStatus4 + bit SUBSTATUS_FOCUS_ENERGY, [hl] + jp nz, WontHaveAnyEffect_NotUsedMessage + set SUBSTATUS_FOCUS_ENERGY, [hl] + jp UseItemText + +XItemEffect: + call UseItemText + + ld a, [wCurItem] + ld hl, XItemStats + +.loop + cp [hl] + jr z, .got_it + inc hl + inc hl + jr .loop + +.got_it + inc hl + ld b, [hl] + xor a + ld [hBattleTurn], a + ld [wAttackMissed], a + ld [wEffectFailed], a + farcall CheckIfStatCanBeRaised + call WaitSFX + + farcall BattleCommand_StatUpMessage + farcall BattleCommand_StatUpFailText + + ld a, [wCurBattleMon] + ld [wCurPartyMon], a + ld c, HAPPINESS_USEDXITEM + farcall ChangeHappiness + ret + +INCLUDE "data/items/x_stats.asm" + +PokeFluteEffect: + ld a, [wBattleMode] + and a + jr nz, .dummy +.dummy + + xor a + ld [wd002], a + + ld b, $ff ^ SLP + + ld hl, wPartyMon1Status + call .CureSleep + + ld a, [wBattleMode] + cp WILD_BATTLE + jr z, .skip_otrainer + ld hl, wOTPartyMon1Status + call .CureSleep +.skip_otrainer + + ld hl, wBattleMonStatus + ld a, [hl] + and b + ld [hl], a + ld hl, wEnemyMonStatus + ld a, [hl] + and b + ld [hl], a + + ld a, [wd002] + and a + ld hl, .CatchyTune + jp z, PrintText + ld hl, .PlayedTheFlute + call PrintText + + ld a, [wLowHealthAlarm] + and 1 << DANGER_ON_F + jr nz, .dummy2 +.dummy2 + ld hl, .AllSleepingMonWokeUp + jp PrintText + +.CureSleep: + ld de, PARTYMON_STRUCT_LENGTH + ld c, PARTY_LENGTH + +.loop + ld a, [hl] + push af + and SLP + jr z, .not_asleep + ld a, 1 + ld [wd002], a +.not_asleep + pop af + and b + ld [hl], a + add hl, de + dec c + jr nz, .loop + ret + +.CatchyTune: + ; Played the # FLUTE. Now, that's a catchy tune! + text_jump UnknownText_0x1c5bf9 + db "@" + +.AllSleepingMonWokeUp: + ; All sleeping #MON woke up. + text_jump UnknownText_0x1c5c28 + db "@" + +.PlayedTheFlute: + ; played the # FLUTE.@ @ + text_jump UnknownText_0x1c5c44 + start_asm + ld a, [wBattleMode] + and a + jr nz, .battle + + push de + ld de, SFX_POKEFLUTE + call WaitPlaySFX + call WaitSFX + pop de + +.battle + jp PokeFluteTerminatorCharacter + +BlueCardEffect: + ld hl, .bluecardtext + jp MenuTextBoxWaitButton + +.bluecardtext + text_jump UnknownText_0x1c5c5e + db "@" + +CoinCaseEffect: + ld hl, .coincasetext + jp MenuTextBoxWaitButton + +.coincasetext + text_jump UnknownText_0x1c5c7b + db "@" + +OldRodEffect: + ld e, $0 + jr UseRod + +GoodRodEffect: + ld e, $1 + jr UseRod + +SuperRodEffect: + ld e, $2 + jr UseRod + +UseRod: + farcall FishFunction + ret + +ItemfinderEffect: + farcall ItemFinder + ret + +RestorePPEffect: + ld a, [wCurItem] + ld [wd002], a + +.loop + ; Party Screen opens to choose on which mon to use the Item + ld b, PARTYMENUACTION_HEALING_ITEM + call UseItem_SelectMon + jp c, PPRestoreItem_Cancel + +.loop2 + ld a, [wd002] + cp MAX_ELIXER + jp z, Elixer_RestorePPofAllMoves + cp ELIXER + jp z, Elixer_RestorePPofAllMoves + + ld hl, TextJump_RaiseThePPOfWhichMove + ld a, [wd002] + cp PP_UP + jr z, .ppup + ld hl, TextJump_RestoreThePPOfWhichMove + +.ppup + call PrintText + + ld a, [wCurMoveNum] + push af + xor a + ld [wCurMoveNum], a + ld a, $2 + ld [wMoveSelectionMenuType], a + farcall MoveSelectionScreen + pop bc + + ld a, b + ld [wCurMoveNum], a + jr nz, .loop + ld hl, wPartyMon1Moves + ld bc, PARTYMON_STRUCT_LENGTH + call GetMthMoveOfNthPartymon + + push hl + ld a, [hl] + ld [wd265], a + call GetMoveName + call CopyName1 + pop hl + + ld a, [wd002] + cp PP_UP + jp nz, Not_PP_Up + + ld a, [hl] + cp SKETCH + jr z, .CantUsePPUpOnSketch + + ld bc, MON_PP - MON_MOVES + add hl, bc + ld a, [hl] + cp PP_UP_MASK + jr c, .do_ppup + +.CantUsePPUpOnSketch: +.pp_is_maxed_out + ld hl, TextJump_PPIsMaxedOut + call PrintText + jr .loop2 + +.do_ppup + ld a, [hl] + add PP_UP_ONE + ld [hl], a + ld a, $1 + ld [wd265], a + call ApplyPPUp + call Play_SFX_FULL_HEAL + + ld hl, TextJump_PPsIncreased + call PrintText + +FinishPPRestore: + call ClearPalettes + jp UseDisposableItem + +BattleRestorePP: + ld a, [wBattleMode] + and a + jr z, .not_in_battle + ld a, [wCurPartyMon] + ld b, a + ld a, [wCurBattleMon] + cp b + jr nz, .not_in_battle + ld a, [wPlayerSubStatus5] + bit SUBSTATUS_TRANSFORMED, a + jr nz, .not_in_battle + call .UpdateBattleMonPP + +.not_in_battle + call Play_SFX_FULL_HEAL + ld hl, UnknownText_0xf739 + call PrintText + jr FinishPPRestore + +.UpdateBattleMonPP: + ld a, [wCurPartyMon] + ld hl, wPartyMon1Moves + ld bc, PARTYMON_STRUCT_LENGTH + call AddNTimes + ld de, wBattleMonMoves + ld b, NUM_MOVES +.loop + ld a, [de] + and a + jr z, .done + cp [hl] + jr nz, .next + push hl + push de + push bc +rept NUM_MOVES + 2 ; wBattleMonPP - wBattleMonMoves + inc de +endr + ld bc, MON_PP - MON_MOVES + add hl, bc + ld a, [hl] + ld [de], a + pop bc + pop de + pop hl + +.next + inc hl + inc de + dec b + jr nz, .loop + +.done + ret + +Not_PP_Up: + call RestorePP + jr nz, BattleRestorePP + jp PPRestoreItem_NoEffect + +Elixer_RestorePPofAllMoves: + xor a + ld hl, wMenuCursorY + ld [hli], a + ld [hl], a + ld b, NUM_MOVES +.moveLoop + push bc + ld hl, wPartyMon1Moves + ld bc, PARTYMON_STRUCT_LENGTH + call GetMthMoveOfNthPartymon + ld a, [hl] + and a + jr z, .next + + call RestorePP + jr z, .next + ld hl, wMenuCursorX + inc [hl] + +.next + ld hl, wMenuCursorY + inc [hl] + pop bc + dec b + jr nz, .moveLoop + ld a, [wMenuCursorX] + and a + jp nz, BattleRestorePP + +PPRestoreItem_NoEffect: + call WontHaveAnyEffectMessage + +PPRestoreItem_Cancel: + call ClearPalettes + xor a + ld [wItemEffectSucceeded], a + ret + +RestorePP: + xor a ; PARTYMON + ld [wMonType], a + call GetMaxPPOfMove + ld hl, wPartyMon1PP + ld bc, PARTYMON_STRUCT_LENGTH + call GetMthMoveOfNthPartymon + ld a, [wd265] + ld b, a + ld a, [hl] + and PP_MASK + cp b + jr nc, .dont_restore + + ld a, [wd002] + cp MAX_ELIXER + jr z, .restore_all + cp MAX_ETHER + jr z, .restore_all + + ld c, 5 + cp MYSTERYBERRY + jr z, .restore_some + + ld c, 10 + +.restore_some + ld a, [hl] + and PP_MASK + add c + cp b + jr nc, .restore_all + ld b, a + +.restore_all + ld a, [hl] + and PP_UP_MASK + or b + ld [hl], a + ret + +.dont_restore + xor a + ret + +TextJump_RaiseThePPOfWhichMove: + ; Raise the PP of which move? + text_jump Text_RaiseThePPOfWhichMove + db "@" + +TextJump_RestoreThePPOfWhichMove: + ; Restore the PP of which move? + text_jump Text_RestoreThePPOfWhichMove + db "@" + +TextJump_PPIsMaxedOut: + ; 's PP is maxed out. + text_jump Text_PPIsMaxedOut + db "@" + +TextJump_PPsIncreased: + ; 's PP increased. + text_jump Text_PPsIncreased + db "@" + +UnknownText_0xf739: + ; PP was restored. + text_jump UnknownText_0x1c5cf1 + db "@" + +SquirtbottleEffect: + farcall _Squirtbottle + ret + +CardKeyEffect: + farcall _CardKey + ret + +BasementKeyEffect: + farcall _BasementKey + ret + +SacredAshEffect: + farcall _SacredAsh + ld a, [wItemEffectSucceeded] + cp $1 + ret nz + call UseDisposableItem + ret + +NormalBoxEffect: + ld c, DECOFLAG_SILVER_TROPHY_DOLL + jr OpenBox + +GorgeousBoxEffect: + ld c, DECOFLAG_GOLD_TROPHY_DOLL +OpenBox: + farcall SetSpecificDecorationFlag + + ld hl, .text + call PrintText + + jp UseDisposableItem + +.text + ; There was a trophy inside! + text_jump UnknownText_0x1c5d03 + db "@" + +NoEffect: + jp IsntTheTimeMessage + +Play_SFX_FULL_HEAL: + push de + ld de, SFX_FULL_HEAL + call WaitPlaySFX + pop de + ret + +UseItemText: + ld hl, UsedItemText + call PrintText + call Play_SFX_FULL_HEAL + call WaitPressAorB_BlinkCursor +UseDisposableItem: + ld hl, wNumItems + ld a, 1 + ld [wItemQuantityChangeBuffer], a + jp TossItem + +UseBallInTrainerBattle: + call ReturnToBattle_UseBall + ld de, ANIM_THROW_POKE_BALL + ld a, e + ld [wFXAnimID], a + ld a, d + ld [wFXAnimID + 1], a + xor a + ld [wBattleAnimParam], a + ld [hBattleTurn], a + ld [wNumHits], a + predef PlayBattleAnim + ld hl, BlockedTheBallText + call PrintText + ld hl, DontBeAThiefText + call PrintText + jr UseDisposableItem + +WontHaveAnyEffect_NotUsedMessage: + ld hl, WontHaveAnyEffectText + call PrintText + + ; Item wasn't used. + ld a, $2 + ld [wItemEffectSucceeded], a + ret + +LooksBitterMessage: + ld hl, LooksBitterText + jp PrintText + +Ball_BoxIsFullMessage: + ld hl, Ball_BoxIsFullText + call PrintText + + ; Item wasn't used. + ld a, $2 + ld [wItemEffectSucceeded], a + ret + +CantUseOnEggMessage: + ld hl, CantUseOnEggText + jr CantUseItemMessage + +IsntTheTimeMessage: + ld hl, IsntTheTimeText + jr CantUseItemMessage + +WontHaveAnyEffectMessage: + ld hl, WontHaveAnyEffectText + jr CantUseItemMessage + +BelongsToSomeoneElseMessage: + ld hl, BelongsToSomeoneElseText + jr CantUseItemMessage + +CyclingIsntAllowedMessage: + ld hl, CyclingIsntAllowedText + jr CantUseItemMessage + +CantGetOnYourBikeMessage: + ld hl, CantGetOnYourBikeText + +CantUseItemMessage: +; Item couldn't be used. + xor a + ld [wItemEffectSucceeded], a + jp PrintText + +LooksBitterText: + ; It looks bitter… + text_jump UnknownText_0x1c5d3e + db "@" + +CantUseOnEggText: + ; That can't be used on an EGG. + text_jump UnknownText_0x1c5d50 + db "@" + +IsntTheTimeText: + ; OAK: ! This isn't the time to use that! + text_jump UnknownText_0x1c5d6e + db "@" + +BelongsToSomeoneElseText: + ; That belongs to someone else! + text_jump UnknownText_0x1c5d97 + db "@" + +WontHaveAnyEffectText: + ; It won't have any effect. + text_jump UnknownText_0x1c5db6 + db "@" + +BlockedTheBallText: + ; The trainer blocked the BALL! + text_jump UnknownText_0x1c5dd0 + db "@" + +DontBeAThiefText: + ; Don't be a thief! + text_jump UnknownText_0x1c5def + db "@" + +CyclingIsntAllowedText: + ; Cycling isn't allowed here. + text_jump UnknownText_0x1c5e01 + db "@" + +CantGetOnYourBikeText: + ; Can't get on your @ now. + text_jump UnknownText_0x1c5e1d + db "@" + +Ball_BoxIsFullText: + ; The #MON BOX is full. That can't be used now. + text_jump UnknownText_0x1c5e3a + db "@" + +UsedItemText: + ; used the@ . + text_jump UnknownText_0x1c5e68 + db "@" + +GotOnTheItemText: + ; got on the@ . + text_jump UnknownText_0x1c5e7b + db "@" + +GotOffTheItemText: + ; got off@ the @ . + text_jump UnknownText_0x1c5e90 + db "@" + +ApplyPPUp: + ld a, MON_MOVES + call GetPartyParamLocation + push hl + ld de, wBuffer1 + predef FillPP + pop hl + ld bc, MON_PP - MON_MOVES + add hl, bc + ld de, wBuffer1 + ld b, 0 +.loop + inc b + ld a, b + cp NUM_MOVES + 1 + ret z + ld a, [wd265] + dec a + jr nz, .use + ld a, [wMenuCursorY] + inc a + cp b + jr nz, .skip + +.use + ld a, [hl] + and PP_UP_MASK + ld a, [de] ; wasted cycle + call nz, ComputeMaxPP + +.skip + inc hl + inc de + jr .loop + +ComputeMaxPP: + push bc + ; Divide the base PP by 5. + ld a, [de] + ld [hDividend + 3], a + xor a + ld [hDividend], a + ld [hDividend + 1], a + ld [hDividend + 2], a + ld a, 5 + ld [hDivisor], a + ld b, 4 + call Divide + ; Get the number of PP, which are bits 6 and 7 of the PP value stored in RAM. + ld a, [hl] + ld b, a + swap a + and $f + srl a + srl a + ld c, a + ; If this value is 0, we are done + and a + jr z, .NoPPUp + +.loop + ; Normally, a move with 40 PP would have 64 PP with three PP Ups. + ; Since this would overflow into bit 6, we prevent that from happening + ; by decreasing the extra amount of PP each PP Up provides, resulting + ; in a maximum of 61. + ld a, [hQuotient + 2] + cp $8 + jr c, .okay + ld a, $7 + +.okay + add b + ld b, a + ld a, [wd265] + dec a + jr z, .NoPPUp + dec c + jr nz, .loop + +.NoPPUp: + ld [hl], b + pop bc + ret + +RestoreAllPP: + ld a, MON_PP + call GetPartyParamLocation + push hl + ld a, MON_MOVES + call GetPartyParamLocation + pop de + xor a ; PARTYMON + ld [wMenuCursorY], a + ld [wMonType], a + ld c, NUM_MOVES +.loop + ld a, [hli] + and a + ret z + push hl + push de + push bc + call GetMaxPPOfMove + pop bc + pop de + ld a, [de] + and PP_UP_MASK + ld b, a + ld a, [wd265] + add b + ld [de], a + inc de + ld hl, wMenuCursorY + inc [hl] + pop hl + dec c + jr nz, .loop + ret + +GetMaxPPOfMove: + ld a, [wStringBuffer1 + 0] + push af + ld a, [wStringBuffer1 + 1] + push af + + ld a, [wMonType] + and a + + ld hl, wPartyMon1Moves + ld bc, PARTYMON_STRUCT_LENGTH + jr z, .got_partymon ; PARTYMON + + ld hl, wOTPartyMon1Moves + dec a + jr z, .got_partymon ; OTPARTYMON + + ld hl, wTempMonMoves + dec a + jr z, .got_nonpartymon ; BOXMON + + ld hl, wTempMonMoves ; Wasted cycles + dec a + jr z, .got_nonpartymon ; TEMPMON + + ld hl, wBattleMonMoves ; WILDMON + +.got_nonpartymon ; BOXMON, TEMPMON, WILDMON + call GetMthMoveOfCurrentMon + jr .gotdatmove + +.got_partymon ; PARTYMON, OTPARTYMON + call GetMthMoveOfNthPartymon + +.gotdatmove + ld a, [hl] + dec a + + push hl + ld hl, Moves + MOVE_PP + ld bc, MOVE_LENGTH + call AddNTimes + ld a, BANK(Moves) + call GetFarByte + ld b, a + ld de, wStringBuffer1 + ld [de], a + pop hl + + push bc + ld bc, MON_PP - MON_MOVES + ld a, [wMonType] + cp WILDMON + jr nz, .notwild + ld bc, wEnemyMonPP - wEnemyMonMoves +.notwild + add hl, bc + ld a, [hl] + and PP_UP_MASK + pop bc + + or b + ld hl, wStringBuffer1 + 1 + ld [hl], a + xor a + ld [wd265], a + ld a, b ; this gets lost anyway + call ComputeMaxPP + ld a, [hl] + and PP_MASK + ld [wd265], a + + pop af + ld [wStringBuffer1 + 1], a + pop af + ld [wStringBuffer1 + 0], a + ret + +GetMthMoveOfNthPartymon: + ld a, [wCurPartyMon] + call AddNTimes + +GetMthMoveOfCurrentMon: + ld a, [wMenuCursorY] + ld c, a + ld b, 0 + add hl, bc + ret diff --git a/engine/items/items.asm b/engine/items/items.asm new file mode 100644 index 000000000..28c79f4cc --- /dev/null +++ b/engine/items/items.asm @@ -0,0 +1,581 @@ +_ReceiveItem:: + call DoesHLEqualNumItems + jp nz, PutItemInPocket + push hl + call CheckItemPocket + pop de + ld a, [wItemAttributeParamBuffer] + dec a + ld hl, .Pockets + rst JumpTable + ret + +.Pockets: +; entries correspond to item types + dw .Item + dw .KeyItem + dw .Ball + dw .TMHM + +.Item: + ld h, d + ld l, e + jp PutItemInPocket + +.KeyItem: + ld h, d + ld l, e + jp ReceiveKeyItem + +.Ball: + ld hl, wNumBalls + jp PutItemInPocket + +.TMHM: + ld h, d + ld l, e + ld a, [wCurItem] + ld c, a + call GetTMHMNumber + jp ReceiveTMHM + +_TossItem:: + call DoesHLEqualNumItems + jr nz, .remove + push hl + call CheckItemPocket + pop de + ld a, [wItemAttributeParamBuffer] + dec a + ld hl, .Pockets + rst JumpTable + ret + +.Pockets: +; entries correspond to item types + dw .Item + dw .KeyItem + dw .Ball + dw .TMHM + +.Ball: + ld hl, wNumBalls + jp RemoveItemFromPocket + +.TMHM: + ld h, d + ld l, e + ld a, [wCurItem] + ld c, a + call GetTMHMNumber + jp TossTMHM + +.KeyItem: + ld h, d + ld l, e + jp TossKeyItem + +.Item: + ld h, d + ld l, e + +.remove + jp RemoveItemFromPocket + +_CheckItem:: + call DoesHLEqualNumItems + jr nz, .nope + push hl + call CheckItemPocket + pop de + ld a, [wItemAttributeParamBuffer] + dec a + ld hl, .Pockets + rst JumpTable + ret + +.Pockets: +; entries correspond to item types + dw .Item + dw .KeyItem + dw .Ball + dw .TMHM + +.Ball: + ld hl, wNumBalls + jp CheckTheItem + +.TMHM: + ld h, d + ld l, e + ld a, [wCurItem] + ld c, a + call GetTMHMNumber + jp CheckTMHM + +.KeyItem: + ld h, d + ld l, e + jp CheckKeyItems + +.Item: + ld h, d + ld l, e + +.nope + jp CheckTheItem + +DoesHLEqualNumItems: + ld a, l + cp LOW(wNumItems) + ret nz + ld a, h + cp HIGH(wNumItems) + ret + +GetPocketCapacity: + ld c, MAX_ITEMS + ld a, e + cp LOW(wNumItems) + jr nz, .not_bag + ld a, d + cp HIGH(wNumItems) + ret z + +.not_bag + ld c, MAX_PC_ITEMS + ld a, e + cp LOW(wPCItems) + jr nz, .not_pc + ld a, d + cp HIGH(wPCItems) + ret z + +.not_pc + ld c, MAX_BALLS + ret + +PutItemInPocket: + ld d, h + ld e, l + inc hl + ld a, [wCurItem] + ld c, a + ld b, 0 +.loop + ld a, [hli] + cp -1 + jr z, .terminator + cp c + jr nz, .next + ld a, 99 + sub [hl] + add b + ld b, a + ld a, [wItemQuantityChangeBuffer] + cp b + jr z, .ok + jr c, .ok + +.next + inc hl + jr .loop + +.terminator + call GetPocketCapacity + ld a, [de] + cp c + jr c, .ok + and a + ret + +.ok + ld h, d + ld l, e + ld a, [wCurItem] + ld c, a + ld a, [wItemQuantityChangeBuffer] + ld [wItemQuantityBuffer], a +.loop2 + inc hl + ld a, [hli] + cp -1 + jr z, .terminator2 + cp c + jr nz, .loop2 + ld a, [wItemQuantityBuffer] + add [hl] + cp 100 + jr nc, .newstack + ld [hl], a + jr .done + +.newstack + ld [hl], 99 + sub 99 + ld [wItemQuantityBuffer], a + jr .loop2 + +.terminator2 + dec hl + ld a, [wCurItem] + ld [hli], a + ld a, [wItemQuantityBuffer] + ld [hli], a + ld [hl], -1 + ld h, d + ld l, e + inc [hl] + +.done + scf + ret + +RemoveItemFromPocket: + ld d, h + ld e, l + ld a, [hli] + ld c, a + ld a, [wCurItemQuantity] + cp c + jr nc, .ok ; memory + ld c, a + ld b, $0 + add hl, bc + add hl, bc + ld a, [wCurItem] + cp [hl] + inc hl + jr z, .skip + ld h, d + ld l, e + inc hl + +.ok + ld a, [wCurItem] + ld b, a +.loop + ld a, [hli] + cp b + jr z, .skip + cp -1 + jr z, .nope + inc hl + jr .loop + +.skip + ld a, [wItemQuantityChangeBuffer] + ld b, a + ld a, [hl] + sub b + jr c, .nope + ld [hl], a + ld [wItemQuantityBuffer], a + and a + jr nz, .yup + dec hl + ld b, h + ld c, l + inc hl + inc hl +.loop2 + ld a, [hli] + ld [bc], a + inc bc + cp -1 + jr nz, .loop2 + ld h, d + ld l, e + dec [hl] + +.yup + scf + ret + +.nope + and a + ret + +CheckTheItem: + ld a, [wCurItem] + ld c, a +.loop + inc hl + ld a, [hli] + cp -1 + jr z, .done + cp c + jr nz, .loop + scf + ret + +.done + and a + ret + +ReceiveKeyItem: + ld hl, wNumKeyItems + ld a, [hli] + cp MAX_KEY_ITEMS + jr nc, .nope + ld c, a + ld b, 0 + add hl, bc + ld a, [wCurItem] + ld [hli], a + ld [hl], -1 + ld hl, wNumKeyItems + inc [hl] + scf + ret + +.nope + and a + ret + +TossKeyItem: + ld a, [wCurItemQuantity] + ld e, a + ld d, 0 + ld hl, wNumKeyItems + ld a, [hl] + cp e + jr nc, .ok + call .Toss + ret nc + jr .ok2 + +.ok + dec [hl] + inc hl + add hl, de + +.ok2 + ld d, h + ld e, l + inc hl +.loop + ld a, [hli] + ld [de], a + inc de + cp -1 + jr nz, .loop + scf + ret + +.Toss: + ld hl, wNumKeyItems + ld a, [wCurItem] + ld c, a +.loop3 + inc hl + ld a, [hl] + cp c + jr z, .ok3 + cp -1 + jr nz, .loop3 + xor a + ret + +.ok3 + ld a, [wNumKeyItems] + dec a + ld [wNumKeyItems], a + scf + ret + +CheckKeyItems: + ld a, [wCurItem] + ld c, a + ld hl, wKeyItems +.loop + ld a, [hli] + cp c + jr z, .done + cp -1 + jr nz, .loop + and a + ret + +.done + scf + ret + +ReceiveTMHM: + dec c + ld b, 0 + ld hl, wTMsHMs + add hl, bc + ld a, [wItemQuantityChangeBuffer] + add [hl] + cp 100 + jr nc, .toomany + ld [hl], a + scf + ret + +.toomany + and a + ret + +TossTMHM: + dec c + ld b, 0 + ld hl, wTMsHMs + add hl, bc + ld a, [wItemQuantityChangeBuffer] + ld b, a + ld a, [hl] + sub b + jr c, .nope + ld [hl], a + ld [wItemQuantityBuffer], a + jr nz, .yup + ld a, [wTMHMPocketScrollPosition] + and a + jr z, .yup + dec a + ld [wTMHMPocketScrollPosition], a + +.yup + scf + ret + +.nope + and a + ret + +CheckTMHM: + dec c + ld b, $0 + ld hl, wTMsHMs + add hl, bc + ld a, [hl] + and a + ret z + scf + ret + +GetTMHMNumber:: +; Return the number of a TM/HM by item id c. + ld a, c +; Skip any dummy items. + cp ITEM_C3 ; TM04-05 + jr c, .done + cp ITEM_DC ; TM28-29 + jr c, .skip + dec a +.skip + dec a +.done + sub TM01 + inc a + ld c, a + ret + +GetNumberedTMHM: +; Return the item id of a TM/HM by number c. + ld a, c +; Skip any gaps. + cp ITEM_C3 - (TM01 - 1) + jr c, .done + cp ITEM_DC - (TM01 - 1) - 1 + jr c, .skip_one +.skip_two + inc a +.skip_one + inc a +.done + add TM01 + dec a + ld c, a + ret + +_CheckTossableItem:: +; Return 1 in wItemAttributeParamBuffer and carry if wCurItem can't be removed from the bag. + ld a, ITEMATTR_PERMISSIONS + call GetItemAttr + bit CANT_TOSS_F, a + jr nz, ItemAttr_ReturnCarry + and a + ret + +CheckSelectableItem: +; Return 1 in wItemAttributeParamBuffer and carry if wCurItem can't be selected. + ld a, ITEMATTR_PERMISSIONS + call GetItemAttr + bit CANT_SELECT_F, a + jr nz, ItemAttr_ReturnCarry + and a + ret + +CheckItemPocket:: +; Return the pocket for wCurItem in wItemAttributeParamBuffer. + ld a, ITEMATTR_POCKET + call GetItemAttr + and $f + ld [wItemAttributeParamBuffer], a + ret + +CheckItemContext: +; Return the context for wCurItem in wItemAttributeParamBuffer. + ld a, ITEMATTR_HELP + call GetItemAttr + and $f + ld [wItemAttributeParamBuffer], a + ret + +CheckItemMenu: +; Return the menu for wCurItem in wItemAttributeParamBuffer. + ld a, ITEMATTR_HELP + call GetItemAttr + swap a + and $f + ld [wItemAttributeParamBuffer], a + ret + +GetItemAttr: +; Get attribute a of wCurItem. + + push hl + push bc + + ld hl, ItemAttributes + ld c, a + ld b, 0 + add hl, bc + + xor a + ld [wItemAttributeParamBuffer], a + + ld a, [wCurItem] + dec a + ld c, a + ld a, ITEMATTR_STRUCT_LENGTH + call AddNTimes + ld a, BANK(ItemAttributes) + call GetFarByte + + pop bc + pop hl + ret + +ItemAttr_ReturnCarry: + ld a, 1 + ld [wItemAttributeParamBuffer], a + scf + ret + +GetItemPrice: +; Return the price of wCurItem in de. + push hl + push bc + ld a, ITEMATTR_PRICE + call GetItemAttr + ld e, a + ld a, ITEMATTR_PRICE_HI + call GetItemAttr + ld d, a + pop bc + pop hl + ret diff --git a/engine/items/mart.asm b/engine/items/mart.asm new file mode 100644 index 000000000..7e185662b --- /dev/null +++ b/engine/items/mart.asm @@ -0,0 +1,895 @@ + const_def + const MARTTEXT_HOW_MANY + const MARTTEXT_COSTS_THIS_MUCH + const MARTTEXT_NOT_ENOUGH_MONEY + const MARTTEXT_BAG_FULL + const MARTTEXT_HERE_YOU_GO + const MARTTEXT_SOLD_OUT + +OpenMartDialog:: + call GetMart + ld a, c + ld [wEngineBuffer1], a + call LoadMartPointer + ld a, [wEngineBuffer1] + ld hl, .dialogs + rst JumpTable + ret + +.dialogs + dw MartDialog + dw HerbShop + dw BargainShop + dw Pharmacist + dw RooftopSale + +MartDialog: + ld a, 0 + ld [wEngineBuffer1], a + xor a ; STANDARDMART_HOWMAYIHELPYOU + ld [wEngineBuffer5], a + call StandardMart + ret + +HerbShop: + call FarReadMart + call LoadStandardMenuHeader + ld hl, Text_HerbShop_Intro + call MartTextBox + call BuyMenu + ld hl, Text_HerbShop_ComeAgain + call MartTextBox + ret + +BargainShop: + ld b, BANK(BargainShopData) + ld de, BargainShopData + call LoadMartPointer + call ReadMart + call LoadStandardMenuHeader + ld hl, Text_BargainShop_Intro + call MartTextBox + call BuyMenu + ld hl, wBargainShopFlags + ld a, [hli] + or [hl] + jr z, .skip_set + ld hl, wDailyFlags + set DAILYFLAGS_GOLDENROD_UNDERGROUND_BARGAIN_F, [hl] + +.skip_set + ld hl, Text_BargainShop_ComeAgain + call MartTextBox + ret + +Pharmacist: + call FarReadMart + call LoadStandardMenuHeader + ld hl, Text_Pharmacist_Intro + call MartTextBox + call BuyMenu + ld hl, Text_Pharmacist_ComeAgain + call MartTextBox + ret + +RooftopSale: + ld b, BANK(RooftopSaleMart1) + ld de, RooftopSaleMart1 + ld hl, wStatusFlags + bit STATUSFLAGS_HALL_OF_FAME_F, [hl] + jr z, .ok + ld b, BANK(RooftopSaleMart2) + ld de, RooftopSaleMart2 + +.ok + call LoadMartPointer + call ReadMart + call LoadStandardMenuHeader + ld hl, Text_Mart_HowMayIHelpYou + call MartTextBox + call BuyMenu + ld hl, Text_Mart_ComeAgain + call MartTextBox + ret + +INCLUDE "data/items/rooftop_sale.asm" + +LoadMartPointer: + ld a, b + ld [wMartPointerBank], a + ld a, e + ld [wMartPointer], a + ld a, d + ld [wMartPointer + 1], a + ld hl, wCurMart + xor a + ld bc, wCurMartEnd - wCurMart + call ByteFill + xor a + ld [wEngineBuffer5], a + ld [wBargainShopFlags], a + ld [wFacingDirection], a + ret + +GetMart: + ld a, e + cp (Marts.End - Marts) / 2 + jr c, .IsAMart + ld b, BANK(DefaultMart) + ld de, DefaultMart + ret + +.IsAMart: + ld hl, Marts + add hl, de + add hl, de + ld e, [hl] + inc hl + ld d, [hl] + ld b, BANK(Marts) + ret + +; StandardMart.MartFunctions indexes + const_def + const STANDARDMART_HOWMAYIHELPYOU ; 0 + const STANDARDMART_TOPMENU ; 1 + const STANDARDMART_BUY ; 2 + const STANDARDMART_SELL ; 3 + const STANDARDMART_QUIT ; 4 + const STANDARDMART_ANYTHINGELSE ; 5 + +StandardMart: +.loop + ld a, [wEngineBuffer5] + ld hl, .MartFunctions + rst JumpTable + ld [wEngineBuffer5], a + cp -1 + jr nz, .loop + ret + +.MartFunctions: +; entries correspond to STANDARDMART_* constants + dw .HowMayIHelpYou + dw .TopMenu + dw .Buy + dw .Sell + dw .Quit + dw .AnythingElse + +.HowMayIHelpYou: + call LoadStandardMenuHeader + ld hl, Text_Mart_HowMayIHelpYou + call PrintText + ld a, STANDARDMART_TOPMENU + ret + +.TopMenu: + ld hl, MenuHeader_BuySell + call CopyMenuHeader + call VerticalMenu + jr c, .quit + ld a, [wMenuCursorY] + cp $1 + jr z, .buy + cp $2 + jr z, .sell +.quit + ld a, STANDARDMART_QUIT + ret +.buy + ld a, STANDARDMART_BUY + ret +.sell + ld a, STANDARDMART_SELL + ret + +.Buy: + call ExitMenu + call FarReadMart + call BuyMenu + and a + ld a, STANDARDMART_ANYTHINGELSE + ret + +.Sell: + call ExitMenu + call SellMenu + ld a, STANDARDMART_ANYTHINGELSE + ret + +.Quit: + call ExitMenu + ld hl, Text_Mart_ComeAgain + call MartTextBox + ld a, -1 + ret + +.AnythingElse: + call LoadStandardMenuHeader + ld hl, Text_Mart_AnythingElse + call PrintText + ld a, STANDARDMART_TOPMENU + ret + +FarReadMart: + ld hl, wMartPointer + ld a, [hli] + ld h, [hl] + ld l, a + ld de, wCurMart +.CopyMart: + ld a, [wMartPointerBank] + call GetFarByte + ld [de], a + inc hl + inc de + cp -1 + jr nz, .CopyMart + ld hl, wMartItem1BCD + ld de, wCurMart + 1 +.ReadMartItem: + ld a, [de] + inc de + cp -1 + jr z, .done + push de + call GetMartItemPrice + pop de + jr .ReadMartItem + +.done + ret + +GetMartItemPrice: +; Return the price of item a in BCD at hl and in tiles at wStringBuffer1. + push hl + ld [wCurItem], a + farcall GetItemPrice + pop hl + +GetMartPrice: +; Return price de in BCD at hl and in tiles at wStringBuffer1. + push hl + ld a, d + ld [wStringBuffer2], a + ld a, e + ld [wStringBuffer2 + 1], a + ld hl, wStringBuffer1 + ld de, wStringBuffer2 + lb bc, PRINTNUM_LEADINGZEROS | 2, 6 ; 6 digits + call PrintNum + pop hl + + ld de, wStringBuffer1 + ld c, 6 / 2 ; 6 digits +.loop + call .CharToNybble + swap a + ld b, a + call .CharToNybble + or b + ld [hli], a + dec c + jr nz, .loop + ret + +.CharToNybble: + ld a, [de] + inc de + cp " " + jr nz, .not_space + ld a, "0" + +.not_space + sub "0" + ret + +ReadMart: +; Load the mart pointer. Mart data is local (no need for bank). + ld hl, wMartPointer + ld a, [hli] + ld h, [hl] + ld l, a + push hl +; set hl to the first item + inc hl + ld bc, wMartItem1BCD + ld de, wCurMart + 1 +.loop +; copy the item to wCurMart + (ItemIndex) + ld a, [hli] + ld [de], a + inc de +; -1 is the terminator + cp -1 + jr z, .done + + push de +; copy the price to de + ld a, [hli] + ld e, a + ld a, [hli] + ld d, a +; convert the price to 3-byte BCD at [bc] + push hl + ld h, b + ld l, c + call GetMartPrice + ld b, h + ld c, l + pop hl + + pop de + jr .loop + +.done + pop hl + ld a, [hl] + ld [wCurMart], a + ret + +INCLUDE "data/items/bargain_shop.asm" + +BuyMenu: + call FadeToMenu + farcall BlankScreen + xor a + ld [wMenuScrollPositionBackup], a + ld a, 1 + ld [wMenuCursorBufferBackup], a +.loop + call BuyMenuLoop ; menu loop + jr nc, .loop + call CloseSubmenu + ret + +LoadBuyMenuText: +; load text from a nested table +; which table is in wEngineBuffer1 +; which entry is in register a + push af + call GetMartDialogGroup ; gets a pointer from GetMartDialogGroup.MartTextFunctionPointers + ld a, [hli] + ld h, [hl] + ld l, a + pop af + ld e, a + ld d, 0 + add hl, de + add hl, de + ld a, [hli] + ld h, [hl] + ld l, a + call PrintText + ret + +MartAskPurchaseQuantity: + call GetMartDialogGroup ; gets a pointer from GetMartDialogGroup.MartTextFunctionPointers + inc hl + inc hl + ld a, [hl] + and a + jp z, StandardMartAskPurchaseQuantity + cp 1 + jp z, BargainShopAskPurchaseQuantity + jp RooftopSaleAskPurchaseQuantity + +GetMartDialogGroup: + ld a, [wEngineBuffer1] + ld e, a + ld d, 0 + ld hl, .MartTextFunctionPointers + add hl, de + add hl, de + add hl, de + ret + +.MartTextFunctionPointers: + dwb .StandardMartPointers, 0 + dwb .HerbShopPointers, 0 + dwb .BargainShopPointers, 1 + dwb .PharmacyPointers, 0 + dwb .StandardMartPointers, 2 + +.StandardMartPointers: + dw Text_Mart_HowMany + dw Text_Mart_CostsThisMuch + dw Text_Mart_InsufficientFunds + dw Text_Mart_BagFull + dw Text_Mart_HereYouGo + dw BuyMenuLoop + +.HerbShopPointers: + dw Text_HerbShop_HowMany + dw Text_HerbShop_CostsThisMuch + dw Text_HerbShop_InsufficientFunds + dw Text_HerbShop_BagFull + dw Text_HerbShop_HereYouGo + dw BuyMenuLoop + +.BargainShopPointers: + dw BuyMenuLoop + dw Text_BargainShop_CostsThisMuch + dw Text_BargainShop_InsufficientFunds + dw Text_BargainShop_BagFull + dw Text_BargainShop_HereYouGo + dw Text_BargainShop_SoldOut + +.PharmacyPointers: + dw Text_Pharmacy_HowMany + dw Text_Pharmacy_CostsThisMuch + dw Text_Pharmacy_InsufficientFunds + dw Text_Pharmacy_BagFull + dw Text_Pharmacy_HereYouGo + dw BuyMenuLoop + +BuyMenuLoop: + farcall PlaceMoneyTopRight + call UpdateSprites + ld hl, MenuHeader_Buy + call CopyMenuHeader + ld a, [wMenuCursorBufferBackup] + ld [wMenuCursorBuffer], a + ld a, [wMenuScrollPositionBackup] + ld [wMenuScrollPosition], a + call ScrollingMenu + ld a, [wMenuScrollPosition] + ld [wMenuScrollPositionBackup], a + ld a, [wMenuCursorY] + ld [wMenuCursorBufferBackup], a + call SpeechTextBox + ld a, [wMenuJoypad] + cp B_BUTTON + jr z, .set_carry + cp A_BUTTON + jr z, .useless_pointer + +.useless_pointer + call MartAskPurchaseQuantity + jr c, .cancel + call MartConfirmPurchase + jr c, .cancel + ld de, wMoney + ld bc, hMoneyTemp + ld a, 3 ; useless load + call CompareMoney + jr c, .insufficient_funds + ld hl, wNumItems + call ReceiveItem + jr nc, .insufficient_bag_space + ld a, [wMartItemID] + ld e, a + ld d, 0 + ld b, SET_FLAG + ld hl, wBargainShopFlags + call FlagAction + call PlayTransactionSound + ld de, wMoney + ld bc, hMoneyTemp + call TakeMoney + ld a, MARTTEXT_HERE_YOU_GO + call LoadBuyMenuText + call JoyWaitAorB + +.cancel + call SpeechTextBox + and a + ret + +.set_carry + scf + ret + +.insufficient_bag_space + ld a, MARTTEXT_BAG_FULL + call LoadBuyMenuText + call JoyWaitAorB + and a + ret + +.insufficient_funds + ld a, MARTTEXT_NOT_ENOUGH_MONEY + call LoadBuyMenuText + call JoyWaitAorB + and a + ret + +StandardMartAskPurchaseQuantity: + ld a, 99 + ld [wItemQuantityBuffer], a + ld a, MARTTEXT_HOW_MANY + call LoadBuyMenuText + farcall SelectQuantityToBuy + call ExitMenu + ret + +MartConfirmPurchase: + predef PartyMonItemName + ld a, MARTTEXT_COSTS_THIS_MUCH + call LoadBuyMenuText + call YesNoBox + ret + +BargainShopAskPurchaseQuantity: + ld a, 1 + ld [wItemQuantityChangeBuffer], a + ld a, [wMartItemID] + ld e, a + ld d, 0 + ld b, CHECK_FLAG + ld hl, wBargainShopFlags + call FlagAction + ld a, c + and a + jr nz, .SoldOut + ld a, [wMartItemID] + ld e, a + ld d, 0 + ld hl, wMartPointer + ld a, [hli] + ld h, [hl] + ld l, a + inc hl + add hl, de + add hl, de + add hl, de + inc hl + ld a, [hli] + ld [hMoneyTemp + 2], a + ld a, [hl] + ld [hMoneyTemp + 1], a + xor a + ld [hMoneyTemp], a + and a + ret + +.SoldOut: + ld a, MARTTEXT_SOLD_OUT + call LoadBuyMenuText + call JoyWaitAorB + scf + ret + +RooftopSaleAskPurchaseQuantity: + ld a, MARTTEXT_HOW_MANY + call LoadBuyMenuText + call .GetSalePrice + ld a, 99 + ld [wItemQuantityBuffer], a + farcall RooftopSale_SelectQuantityToBuy + call ExitMenu + ret + +.GetSalePrice: + ld a, [wMartItemID] + ld e, a + ld d, 0 + ld hl, wMartPointer + ld a, [hli] + ld h, [hl] + ld l, a + inc hl + add hl, de + add hl, de + add hl, de + inc hl + ld e, [hl] + inc hl + ld d, [hl] + ret + +Text_Mart_HowMany: + ; How many? + text_jump UnknownText_0x1c4bfd + db "@" + +Text_Mart_CostsThisMuch: + ; @ (S) will be ¥@ . + text_jump UnknownText_0x1c4c08 + db "@" + +MenuHeader_Buy: + db MENU_BACKUP_TILES ; flags + menu_coords 1, 3, SCREEN_WIDTH - 1, TEXTBOX_Y - 1 + dw .MenuData + db 1 ; default option + +.MenuData + db SCROLLINGMENU_DISPLAY_ARROWS | SCROLLINGMENU_ENABLE_FUNCTION3 ; flags + db 4, 8 ; rows, columns + db 1 ; horizontal spacing + dbw 0, wCurMart + dba PlaceMenuItemName + dba .PrintBCDPrices + dba UpdateItemDescription + +.PrintBCDPrices: + ld a, [wScrollingMenuCursorPosition] + ld c, a + ld b, 0 + ld hl, wMartItem1BCD + add hl, bc + add hl, bc + add hl, bc + push de + ld d, h + ld e, l + pop hl + ld bc, SCREEN_WIDTH + add hl, bc + ld c, PRINTNUM_LEADINGZEROS | PRINTNUM_MONEY | 3 + call PrintBCDNumber + ret + +Text_HerbShop_Intro: + ; Hello, dear. I sell inexpensive herbal medicine. They're good, but a trifle bitter. Your #MON may not like them. Hehehehe… + text_jump UnknownText_0x1c4c28 + db "@" + +Text_HerbShop_HowMany: + ; How many? + text_jump UnknownText_0x1c4ca3 + db "@" + +Text_HerbShop_CostsThisMuch: + ; @ (S) will be ¥@ . + text_jump UnknownText_0x1c4cae + db "@" + +Text_HerbShop_HereYouGo: + ; Thank you, dear. Hehehehe… + text_jump UnknownText_0x1c4cce + db "@" + +Text_HerbShop_BagFull: + ; Oh? Your PACK is full, dear. + text_jump UnknownText_0x1c4cea + db "@" + +Text_HerbShop_InsufficientFunds: + ; Hehehe… You don't have the money. + text_jump UnknownText_0x1c4d08 + db "@" + +Text_HerbShop_ComeAgain: + ; Come again, dear. Hehehehe… + text_jump UnknownText_0x1c4d2a + db "@" + +Text_BargainShop_Intro: + ; Hiya! Care to see some bargains? I sell rare items that nobody else carries--but only one of each item. + text_jump UnknownText_0x1c4d47 + db "@" + +Text_BargainShop_CostsThisMuch: + ; costs ¥@ . Want it? + text_jump UnknownText_0x1c4db0 + db "@" + +Text_BargainShop_HereYouGo: + ; Thanks. + text_jump UnknownText_0x1c4dcd + db "@" + +Text_BargainShop_BagFull: + ; Uh-oh, your PACK is chock-full. + text_jump UnknownText_0x1c4dd6 + db "@" + +Text_BargainShop_SoldOut: + ; You bought that already. I'm all sold out of it. + text_jump UnknownText_0x1c4df7 + db "@" + +Text_BargainShop_InsufficientFunds: + ; Uh-oh, you're short on funds. + text_jump UnknownText_0x1c4e28 + db "@" + +Text_BargainShop_ComeAgain: + ; Come by again sometime. + text_jump UnknownText_0x1c4e46 + db "@" + +Text_Pharmacist_Intro: + ; What's up? Need some medicine? + text_jump UnknownText_0x1c4e5f + db "@" + +Text_Pharmacy_HowMany: + ; How many? + text_jump UnknownText_0x1c4e7e + db "@" + +Text_Pharmacy_CostsThisMuch: + ; @ (S) will cost ¥@ . + text_jump UnknownText_0x1c4e89 + db "@" + +Text_Pharmacy_HereYouGo: + ; Thanks much! + text_jump UnknownText_0x1c4eab + db "@" + +Text_Pharmacy_BagFull: + ; You don't have any more space. + text_jump UnknownText_0x1c4eb9 + db "@" + +Text_Pharmacy_InsufficientFunds: + ; Huh? That's not enough money. + text_jump UnknownText_0x1c4ed8 + db "@" + +Text_Pharmacist_ComeAgain: + ; All right. See you around. + text_jump UnknownText_0x1c4ef6 + db "@" + +SellMenu: + call DisableSpriteUpdates + farcall DepositSellInitPackBuffers +.loop + farcall DepositSellPack + ld a, [wPackUsedItem] + and a + jp z, .quit + call .TryToSellItem + jr .loop + +.quit + call ReturnToMapWithSpeechTextbox + and a + ret + +.Unreferenced_NothingToSell: + ld hl, .NothingToSellText + call MenuTextBoxBackup + and a + ret + +.NothingToSellText: + ; You don't have anything to sell. + text_jump UnknownText_0x1c4f12 + db "@" + +.TryToSellItem: + farcall CheckItemMenu + ld a, [wItemAttributeParamBuffer] + ld hl, .dw + rst JumpTable + ret + +.dw + dw .try_sell + dw .cant_buy + dw .cant_buy + dw .cant_buy + dw .try_sell + dw .try_sell + dw .try_sell + +.cant_buy + ret + +.try_sell + farcall _CheckTossableItem + ld a, [wItemAttributeParamBuffer] + and a + jr z, .okay_to_sell + ld hl, TextMart_CantBuyFromYou + call PrintText + and a + ret + +.okay_to_sell + ld hl, Text_Mart_SellHowMany + call PrintText + farcall PlaceMoneyAtTopLeftOfTextbox + farcall SelectQuantityToSell + call ExitMenu + jr c, .declined + hlcoord 1, 14 + lb bc, 3, 18 + call ClearBox + ld hl, Text_Mart_ICanPayThisMuch + call PrintTextBoxText + call YesNoBox + jr c, .declined + ld de, wMoney + ld bc, hMoneyTemp + call GiveMoney + ld a, [wMartItemID] + ld hl, wNumItems + call TossItem + predef PartyMonItemName + hlcoord 1, 14 + lb bc, 3, 18 + call ClearBox + ld hl, Text_Mart_SoldForAmount + call PrintTextBoxText + call PlayTransactionSound + farcall PlaceMoneyBottomLeft + call JoyWaitAorB + +.declined + call ExitMenu + and a + ret + +Text_Mart_SellHowMany: + ; How many? + text_jump UnknownText_0x1c4f33 + db "@" + +Text_Mart_ICanPayThisMuch: + ; I can pay you ¥@ . Is that OK? + text_jump UnknownText_0x1c4f3e + db "@" + +.UnusedString15f7d: + db "!ダミー!@" + +Text_Mart_HowMayIHelpYou: + ; Welcome! How may I help you? + text_jump UnknownText_0x1c4f62 + db "@" + +MenuHeader_BuySell: + db MENU_BACKUP_TILES ; flags + menu_coords 0, 0, 7, 8 + dw .MenuData + db 1 ; default option + +.MenuData + db STATICMENU_CURSOR ; strings + db 3 ; items + db "BUY@" + db "SELL@" + db "QUIT@" + +Text_Mart_HereYouGo: + ; Here you are. Thank you! + text_jump UnknownText_0x1c4f80 + db "@" + +Text_Mart_InsufficientFunds: + ; You don't have enough money. + text_jump UnknownText_0x1c4f9a + db "@" + +Text_Mart_BagFull: + ; You can't carry any more items. + text_jump UnknownText_0x1c4fb7 + db "@" + +TextMart_CantBuyFromYou: + ; Sorry, I can't buy that from you. + text_jump UnknownText_0x1c4fd7 + db "@" + +Text_Mart_ComeAgain: + ; Please come again! + text_jump UnknownText_0x1c4ff9 + db "@" + +Text_Mart_AnythingElse: + text_jump UnknownText_0x1c500d + db "@" + +Text_Mart_SoldForAmount: + text_jump UnknownText_0x1c502e + db "@" + +PlayTransactionSound: + call WaitSFX + ld de, SFX_TRANSACTION + call PlaySFX + ret + +MartTextBox: + call MenuTextBox + call JoyWaitAorB + call ExitMenu + ret diff --git a/engine/items/pack.asm b/engine/items/pack.asm new file mode 100644 index 000000000..67e9fe900 --- /dev/null +++ b/engine/items/pack.asm @@ -0,0 +1,1608 @@ +; Pack.Jumptable and BattlePack.Jumptable indexes + const_def + const PACKSTATE_INITGFX ; 0 + const PACKSTATE_INITITEMSPOCKET ; 1 + const PACKSTATE_ITEMSPOCKETMENU ; 2 + const PACKSTATE_INITBALLSPOCKET ; 3 + const PACKSTATE_BALLSPOCKETMENU ; 4 + const PACKSTATE_INITKEYITEMSPOCKET ; 5 + const PACKSTATE_KEYITEMSPOCKETMENU ; 6 + const PACKSTATE_INITTMHMPOCKET ; 7 + const PACKSTATE_TMHMPOCKETMENU ; 8 + const PACKSTATE_QUITNOSCRIPT ; 9 + const PACKSTATE_QUITRUNSCRIPT ; 10 + +Pack: + ld hl, wOptions + set NO_TEXT_SCROLL, [hl] + call InitPackBuffers +.loop + call JoyTextDelay + ld a, [wJumptableIndex] + bit 7, a + jr nz, .done + call .RunJumptable + call DelayFrame + jr .loop + +.done + ld a, [wCurrPocket] + ld [wLastPocket], a + ld hl, wOptions + res NO_TEXT_SCROLL, [hl] + ret + +.RunJumptable: + ld a, [wJumptableIndex] + ld hl, .Jumptable + call Pack_GetJumptablePointer + jp hl + +.Jumptable: +; entries correspond to PACKSTATE_* constants + dw .InitGFX ; 0 + dw .InitItemsPocket ; 1 + dw .ItemsPocketMenu ; 2 + dw .InitBallsPocket ; 3 + dw .BallsPocketMenu ; 4 + dw .InitKeyItemsPocket ; 5 + dw .KeyItemsPocketMenu ; 6 + dw .InitTMHMPocket ; 7 + dw .TMHMPocketMenu ; 8 + dw Pack_QuitNoScript ; 9 + dw Pack_QuitRunScript ; 10 + +.InitGFX: + xor a + ld [hBGMapMode], a + call Pack_InitGFX + ld a, [wPackJumptableIndex] + ld [wJumptableIndex], a + call Pack_InitColors + ret + +.InitItemsPocket: + xor a ; ITEM_POCKET + ld [wCurrPocket], a + call ClearPocketList + call DrawPocketName + call WaitBGMap_DrawPackGFX + call Pack_JumptableNext + ret + +.ItemsPocketMenu: + ld hl, ItemsPocketMenuHeader + call CopyMenuHeader + ld a, [wItemsPocketCursor] + ld [wMenuCursorBuffer], a + ld a, [wItemsPocketScrollPosition] + ld [wMenuScrollPosition], a + call ScrollingMenu + ld a, [wMenuScrollPosition] + ld [wItemsPocketScrollPosition], a + ld a, [wMenuCursorY] + ld [wItemsPocketCursor], a + ld b, PACKSTATE_INITTMHMPOCKET ; left + ld c, PACKSTATE_INITBALLSPOCKET ; right + call Pack_InterpretJoypad + ret c + call .ItemBallsKey_LoadSubmenu + ret + +.InitKeyItemsPocket: + ld a, KEY_ITEM_POCKET + ld [wCurrPocket], a + call ClearPocketList + call DrawPocketName + call WaitBGMap_DrawPackGFX + call Pack_JumptableNext + ret + +.KeyItemsPocketMenu: + ld hl, KeyItemsPocketMenuHeader + call CopyMenuHeader + ld a, [wKeyItemsPocketCursor] + ld [wMenuCursorBuffer], a + ld a, [wKeyItemsPocketScrollPosition] + ld [wMenuScrollPosition], a + call ScrollingMenu + ld a, [wMenuScrollPosition] + ld [wKeyItemsPocketScrollPosition], a + ld a, [wMenuCursorY] + ld [wKeyItemsPocketCursor], a + ld b, PACKSTATE_INITBALLSPOCKET ; left + ld c, PACKSTATE_INITTMHMPOCKET ; right + call Pack_InterpretJoypad + ret c + call .ItemBallsKey_LoadSubmenu + ret + +.InitTMHMPocket: + ld a, TM_HM_POCKET + ld [wCurrPocket], a + call ClearPocketList + call DrawPocketName + xor a + ld [hBGMapMode], a + call WaitBGMap_DrawPackGFX + call Pack_JumptableNext + ret + +.TMHMPocketMenu: + farcall TMHMPocket + ld b, PACKSTATE_INITKEYITEMSPOCKET ; left + ld c, PACKSTATE_INITITEMSPOCKET ; right + call Pack_InterpretJoypad + ret c + farcall _CheckTossableItem + ld a, [wItemAttributeParamBuffer] + and a + jr nz, .use_quit + ld hl, .MenuHeader2 + ld de, .Jumptable2 + jr .load_jump + +.use_quit + ld hl, .MenuHeader1 + ld de, .Jumptable1 +.load_jump + push de + call LoadMenuHeader + call VerticalMenu + call ExitMenu + pop hl + ret c + ld a, [wMenuCursorY] + dec a + call Pack_GetJumptablePointer + jp hl + +.MenuHeader1: + db MENU_BACKUP_TILES ; flags + menu_coords 13, 7, SCREEN_WIDTH - 1, TEXTBOX_Y - 1 + dw .MenuData_1 + db 1 ; default option + +.MenuData_1: + db STATICMENU_CURSOR | STATICMENU_NO_TOP_SPACING ; flags + db 2 ; items + db "USE@" + db "QUIT@" + +.Jumptable1: + dw .UseItem + dw QuitItemSubmenu + +.MenuHeader2: + db MENU_BACKUP_TILES ; flags + menu_coords 13, 5, SCREEN_WIDTH - 1, TEXTBOX_Y - 1 + dw .MenuData_2 + db 1 ; default option + +.MenuData_2: + db STATICMENU_CURSOR | STATICMENU_NO_TOP_SPACING ; flags + db 3 ; items + db "USE@" + db "GIVE@" + db "QUIT@" + +.Jumptable2: + dw .UseItem + dw GiveItem + dw QuitItemSubmenu + +.UseItem: + farcall AskTeachTMHM + ret c + farcall ChooseMonToLearnTMHM + jr c, .declined + ld hl, wOptions + ld a, [hl] + push af + res NO_TEXT_SCROLL, [hl] + farcall TeachTMHM + pop af + ld [wOptions], a +.declined + xor a + ld [hBGMapMode], a + call Pack_InitGFX + call WaitBGMap_DrawPackGFX + call Pack_InitColors + ret + +.InitBallsPocket: + ld a, BALL_POCKET + ld [wCurrPocket], a + call ClearPocketList + call DrawPocketName + call WaitBGMap_DrawPackGFX + call Pack_JumptableNext + ret + +.BallsPocketMenu: + ld hl, BallsPocketMenuHeader + call CopyMenuHeader + ld a, [wBallsPocketCursor] + ld [wMenuCursorBuffer], a + ld a, [wBallsPocketScrollPosition] + ld [wMenuScrollPosition], a + call ScrollingMenu + ld a, [wMenuScrollPosition] + ld [wBallsPocketScrollPosition], a + ld a, [wMenuCursorY] + ld [wBallsPocketCursor], a + ld b, PACKSTATE_INITITEMSPOCKET ; left + ld c, PACKSTATE_INITKEYITEMSPOCKET ; right + call Pack_InterpretJoypad + ret c + call .ItemBallsKey_LoadSubmenu + ret + +.ItemBallsKey_LoadSubmenu: + farcall _CheckTossableItem + ld a, [wItemAttributeParamBuffer] + and a + jr nz, .tossable + farcall CheckSelectableItem + ld a, [wItemAttributeParamBuffer] + and a + jr nz, .selectable + farcall CheckItemMenu + ld a, [wItemAttributeParamBuffer] + and a + jr nz, .usable + jr .unusable + +.selectable + farcall CheckItemMenu + ld a, [wItemAttributeParamBuffer] + and a + jr nz, .selectable_usable + jr .selectable_unusable + +.tossable + farcall CheckSelectableItem + ld a, [wItemAttributeParamBuffer] + and a + jr nz, .tossable_selectable + jr .tossable_unselectable + +.usable + ld hl, MenuHeader_UsableKeyItem + ld de, Jumptable_UseGiveTossRegisterQuit + jr .build_menu + +.selectable_usable + ld hl, MenuHeader_UsableItem + ld de, Jumptable_UseGiveTossQuit + jr .build_menu + +.tossable_selectable + ld hl, MenuHeader_UnusableItem + ld de, Jumptable_UseQuit + jr .build_menu + +.tossable_unselectable + ld hl, MenuHeader_UnusableKeyItem + ld de, Jumptable_UseRegisterQuit + jr .build_menu + +.unusable + ld hl, MenuHeader_HoldableKeyItem + ld de, Jumptable_GiveTossRegisterQuit + jr .build_menu + +.selectable_unusable + ld hl, MenuHeader_HoldableItem + ld de, Jumptable_GiveTossQuit +.build_menu + push de + call LoadMenuHeader + call VerticalMenu + call ExitMenu + pop hl + ret c + ld a, [wMenuCursorY] + dec a + call Pack_GetJumptablePointer + jp hl + +MenuHeader_UsableKeyItem: + db MENU_BACKUP_TILES ; flags + menu_coords 13, 1, SCREEN_WIDTH - 1, TEXTBOX_Y - 1 + dw .MenuData + db 1 ; default option + +.MenuData: + db STATICMENU_CURSOR | STATICMENU_NO_TOP_SPACING ; flags + db 5 ; items + db "USE@" + db "GIVE@" + db "TOSS@" + db "SEL@" + db "QUIT@" + +Jumptable_UseGiveTossRegisterQuit: + dw UseItem + dw GiveItem + dw TossMenu + dw RegisterItem + dw QuitItemSubmenu + +MenuHeader_UsableItem: + db MENU_BACKUP_TILES ; flags + menu_coords 13, 3, SCREEN_WIDTH - 1, TEXTBOX_Y - 1 + dw .MenuData + db 1 ; default option + +.MenuData: + db STATICMENU_CURSOR | STATICMENU_NO_TOP_SPACING ; flags + db 4 ; items + db "USE@" + db "GIVE@" + db "TOSS@" + db "QUIT@" + +Jumptable_UseGiveTossQuit: + dw UseItem + dw GiveItem + dw TossMenu + dw QuitItemSubmenu + +MenuHeader_UnusableItem: + db MENU_BACKUP_TILES ; flags + menu_coords 13, 7, SCREEN_WIDTH - 1, TEXTBOX_Y - 1 + dw .MenuData + db 1 ; default option + +.MenuData: + db STATICMENU_CURSOR | STATICMENU_NO_TOP_SPACING ; flags + db 2 ; items + db "USE@" + db "QUIT@" + +Jumptable_UseQuit: + dw UseItem + dw QuitItemSubmenu + +MenuHeader_UnusableKeyItem: + db MENU_BACKUP_TILES ; flags + menu_coords 13, 5, SCREEN_WIDTH - 1, TEXTBOX_Y - 1 + dw .MenuData + db 1 ; default option + +.MenuData: + db STATICMENU_CURSOR | STATICMENU_NO_TOP_SPACING ; flags + db 3 ; items + db "USE@" + db "SEL@" + db "QUIT@" + +Jumptable_UseRegisterQuit: + dw UseItem + dw RegisterItem + dw QuitItemSubmenu + +MenuHeader_HoldableKeyItem: + db MENU_BACKUP_TILES ; flags + menu_coords 13, 3, SCREEN_WIDTH - 1, TEXTBOX_Y - 1 + dw .MenuData + db 1 ; default option + +.MenuData: + db STATICMENU_CURSOR | STATICMENU_NO_TOP_SPACING ; flags + db 4 ; items + db "GIVE@" + db "TOSS@" + db "SEL@" + db "QUIT@" + +Jumptable_GiveTossRegisterQuit: + dw GiveItem + dw TossMenu + dw RegisterItem + dw QuitItemSubmenu + +MenuHeader_HoldableItem: + db MENU_BACKUP_TILES ; flags + menu_coords 13, 5, SCREEN_WIDTH - 1, TEXTBOX_Y - 1 + dw .MenuData + db 1 ; default option + +.MenuData: + db STATICMENU_CURSOR | STATICMENU_NO_TOP_SPACING ; flags + db 3 ; items + db "GIVE@" + db "TOSS@" + db "QUIT@" + +Jumptable_GiveTossQuit: + dw GiveItem + dw TossMenu + dw QuitItemSubmenu + +UseItem: + farcall CheckItemMenu + ld a, [wItemAttributeParamBuffer] + ld hl, .dw + rst JumpTable + ret + +.dw +; entries correspond to ITEMMENU_* constants + dw .Oak ; ITEMMENU_NOUSE + dw .Oak + dw .Oak + dw .Oak + dw .Current ; ITEMMENU_CURRENT + dw .Party ; ITEMMENU_PARTY + dw .Field ; ITEMMENU_CLOSE + +.Oak: + ld hl, Text_ThisIsntTheTime + call Pack_PrintTextNoScroll + ret + +.Current: + call DoItemEffect + ret + +.Party: + ld a, [wPartyCount] + and a + jr z, .NoPokemon + call DoItemEffect + xor a + ld [hBGMapMode], a + call Pack_InitGFX + call WaitBGMap_DrawPackGFX + call Pack_InitColors + ret + +.NoPokemon: + ld hl, TextJump_YouDontHaveAMon + call Pack_PrintTextNoScroll + ret + +.Field: + call DoItemEffect + ld a, [wItemEffectSucceeded] + and a + jr z, .Oak + ld a, PACKSTATE_QUITRUNSCRIPT + ld [wJumptableIndex], a + ret + +TossMenu: + ld hl, Text_ThrowAwayHowMany + call Pack_PrintTextNoScroll + farcall SelectQuantityToToss + push af + call ExitMenu + pop af + jr c, .finish + call Pack_GetItemName + ld hl, Text_ConfirmThrowAway + call MenuTextBox + call YesNoBox + push af + call ExitMenu + pop af + jr c, .finish + ld hl, wNumItems + ld a, [wCurItemQuantity] + call TossItem + call Pack_GetItemName + ld hl, Text_ThrewAway + call Pack_PrintTextNoScroll +.finish + ret + +Unreferenced_ResetPocketCursorPositions: + ld a, [wCurrPocket] + and a ; ITEM_POCKET + jr z, .items + dec a ; BALL_POCKET + jr z, .balls + dec a ; KEY_ITEM_POCKET + jr z, .key + ret + +.balls + xor a + ld [wBallsPocketCursor], a + ld [wBallsPocketScrollPosition], a + ret + +.items + xor a + ld [wItemsPocketCursor], a + ld [wItemsPocketScrollPosition], a + ret + +.key + xor a + ld [wKeyItemsPocketCursor], a + ld [wKeyItemsPocketScrollPosition], a + ret + +RegisterItem: + farcall CheckSelectableItem + ld a, [wItemAttributeParamBuffer] + and a + jr nz, .cant_register + ld a, [wCurrPocket] + rrca + rrca + and REGISTERED_POCKET + ld b, a + ld a, [wCurItemQuantity] + inc a + and REGISTERED_NUMBER + or b + ld [wWhichRegisteredItem], a + ld a, [wCurItem] + ld [wRegisteredItem], a + call Pack_GetItemName + ld de, SFX_FULL_HEAL + call WaitPlaySFX + ld hl, Text_RegisteredItem + call Pack_PrintTextNoScroll + ret + +.cant_register + ld hl, Text_CantRegister + call Pack_PrintTextNoScroll + ret + +GiveItem: + ld a, [wPartyCount] + and a + jp z, .NoPokemon + ld a, [wOptions] + push af + res NO_TEXT_SCROLL, a + ld [wOptions], a + ld a, PARTYMENUACTION_GIVE_ITEM + ld [wPartyMenuActionText], a + call ClearBGPalettes + farcall LoadPartyMenuGFX + farcall InitPartyMenuWithCancel + farcall InitPartyMenuGFX +.loop + farcall WritePartyMenuTilemap + farcall PrintPartyMenuText + call WaitBGMap + call SetPalettes + call DelayFrame + farcall PartyMenuSelect + jr c, .finish + ld a, [wCurPartySpecies] + cp EGG + jr nz, .give + ld hl, .Egg + call PrintText + jr .loop + +.give + ld a, [wJumptableIndex] + push af + ld a, [wPackJumptableIndex] + push af + call GetCurNick + ld hl, wStringBuffer1 + ld de, wMonOrItemNameBuffer + ld bc, MON_NAME_LENGTH + call CopyBytes + call TryGiveItemToPartymon + pop af + ld [wPackJumptableIndex], a + pop af + ld [wJumptableIndex], a +.finish + pop af + ld [wOptions], a + xor a + ld [hBGMapMode], a + call Pack_InitGFX + call WaitBGMap_DrawPackGFX + call Pack_InitColors + ret + +.NoPokemon: + ld hl, TextJump_YouDontHaveAMon + call Pack_PrintTextNoScroll + ret +.Egg: + ; An EGG can't hold an item. + text_jump Text_AnEGGCantHoldAnItem + db "@" + +QuitItemSubmenu: + ret + +BattlePack: + ld hl, wOptions + set NO_TEXT_SCROLL, [hl] + call InitPackBuffers +.loop + call JoyTextDelay + ld a, [wJumptableIndex] + bit 7, a + jr nz, .end + call .RunJumptable + call DelayFrame + jr .loop + +.end + ld a, [wCurrPocket] + ld [wLastPocket], a + ld hl, wOptions + res NO_TEXT_SCROLL, [hl] + ret + +.RunJumptable: + ld a, [wJumptableIndex] + ld hl, .Jumptable + call Pack_GetJumptablePointer + jp hl + +.Jumptable: +; entries correspond to PACKSTATE_* constants + dw .InitGFX ; 0 + dw .InitItemsPocket ; 1 + dw .ItemsPocketMenu ; 2 + dw .InitBallsPocket ; 3 + dw .BallsPocketMenu ; 4 + dw .InitKeyItemsPocket ; 5 + dw .KeyItemsPocketMenu ; 6 + dw .InitTMHMPocket ; 7 + dw .TMHMPocketMenu ; 8 + dw Pack_QuitNoScript ; 9 + dw Pack_QuitRunScript ; 10 + +.InitGFX: + xor a + ld [hBGMapMode], a + call Pack_InitGFX + ld a, [wPackJumptableIndex] + ld [wJumptableIndex], a + call Pack_InitColors + ret + +.InitItemsPocket: + xor a ; ITEM_POCKET + ld [wCurrPocket], a + call ClearPocketList + call DrawPocketName + call WaitBGMap_DrawPackGFX + call Pack_JumptableNext + ret + +.ItemsPocketMenu: + ld hl, ItemsPocketMenuHeader + call CopyMenuHeader + ld a, [wItemsPocketCursor] + ld [wMenuCursorBuffer], a + ld a, [wItemsPocketScrollPosition] + ld [wMenuScrollPosition], a + call ScrollingMenu + ld a, [wMenuScrollPosition] + ld [wItemsPocketScrollPosition], a + ld a, [wMenuCursorY] + ld [wItemsPocketCursor], a + ld b, PACKSTATE_INITTMHMPOCKET ; left + ld c, PACKSTATE_INITBALLSPOCKET ; right + call Pack_InterpretJoypad + ret c + call ItemSubmenu + ret + +.InitKeyItemsPocket: + ld a, KEY_ITEM_POCKET + ld [wCurrPocket], a + call ClearPocketList + call DrawPocketName + call WaitBGMap_DrawPackGFX + call Pack_JumptableNext + ret + +.KeyItemsPocketMenu: + ld hl, KeyItemsPocketMenuHeader + call CopyMenuHeader + ld a, [wKeyItemsPocketCursor] + ld [wMenuCursorBuffer], a + ld a, [wKeyItemsPocketScrollPosition] + ld [wMenuScrollPosition], a + call ScrollingMenu + ld a, [wMenuScrollPosition] + ld [wKeyItemsPocketScrollPosition], a + ld a, [wMenuCursorY] + ld [wKeyItemsPocketCursor], a + ld b, PACKSTATE_INITBALLSPOCKET ; left + ld c, PACKSTATE_INITTMHMPOCKET ; right + call Pack_InterpretJoypad + ret c + call ItemSubmenu + ret + +.InitTMHMPocket: + ld a, TM_HM_POCKET + ld [wCurrPocket], a + call ClearPocketList + call DrawPocketName + xor a + ld [hBGMapMode], a + call WaitBGMap_DrawPackGFX + ld hl, Text_PackEmptyString + call Pack_PrintTextNoScroll + call Pack_JumptableNext + ret + +.TMHMPocketMenu: + farcall TMHMPocket + ld b, PACKSTATE_INITKEYITEMSPOCKET ; left + ld c, PACKSTATE_INITITEMSPOCKET ; right + call Pack_InterpretJoypad + ret c + xor a + call TMHMSubmenu + ret + +.InitBallsPocket: + ld a, BALL_POCKET + ld [wCurrPocket], a + call ClearPocketList + call DrawPocketName + call WaitBGMap_DrawPackGFX + call Pack_JumptableNext + ret + +.BallsPocketMenu: + ld hl, BallsPocketMenuHeader + call CopyMenuHeader + ld a, [wBallsPocketCursor] + ld [wMenuCursorBuffer], a + ld a, [wBallsPocketScrollPosition] + ld [wMenuScrollPosition], a + call ScrollingMenu + ld a, [wMenuScrollPosition] + ld [wBallsPocketScrollPosition], a + ld a, [wMenuCursorY] + ld [wBallsPocketCursor], a + ld b, PACKSTATE_INITITEMSPOCKET ; left + ld c, PACKSTATE_INITKEYITEMSPOCKET ; right + call Pack_InterpretJoypad + ret c + call ItemSubmenu + ret + +ItemSubmenu: + farcall CheckItemContext + ld a, [wItemAttributeParamBuffer] +TMHMSubmenu: + and a + jr z, .NoUse + ld hl, .UsableMenuHeader + ld de, .UsableJumptable + jr .proceed + +.NoUse: + ld hl, .UnusableMenuHeader + ld de, .UnusableJumptable +.proceed + push de + call LoadMenuHeader + call VerticalMenu + call ExitMenu + pop hl + ret c + ld a, [wMenuCursorY] + dec a + call Pack_GetJumptablePointer + jp hl + +.UsableMenuHeader: + db MENU_BACKUP_TILES ; flags + menu_coords 13, 7, SCREEN_WIDTH - 1, TEXTBOX_Y - 1 + dw .UsableMenuData + db 1 ; default option + +.UsableMenuData: + db STATICMENU_CURSOR | STATICMENU_NO_TOP_SPACING ; flags + db 2 ; items + db "USE@" + db "QUIT@" + +.UsableJumptable: + dw .Use + dw .Quit + +.UnusableMenuHeader: + db MENU_BACKUP_TILES ; flags + menu_coords 13, 9, SCREEN_WIDTH - 1, TEXTBOX_Y - 1 + dw .UnusableMenuData + db 1 ; default option + +.UnusableMenuData: + db STATICMENU_CURSOR | STATICMENU_NO_TOP_SPACING ; flags + db 1 ; items + db "QUIT@" + +.UnusableJumptable: + dw .Quit + +.Use: + farcall CheckItemContext + ld a, [wItemAttributeParamBuffer] + ld hl, .ItemFunctionJumptable + rst JumpTable + ret + +.ItemFunctionJumptable: +; entries correspond to ITEMMENU_* constants + dw .Oak ; ITEMMENU_NOUSE + dw .Oak + dw .Oak + dw .Oak + dw .Unused ; ITEMMENU_CURRENT + dw .BattleField ; ITEMMENU_PARTY + dw .BattleOnly ; ITEMMENU_CLOSE + +.Oak: + ld hl, Text_ThisIsntTheTime + call Pack_PrintTextNoScroll + ret + +.Unused: + call DoItemEffect + ld a, [wItemEffectSucceeded] + and a + jr nz, .ReturnToBattle + ret + +.BattleField: + call DoItemEffect + ld a, [wItemEffectSucceeded] + and a + jr nz, .quit_run_script + xor a + ld [hBGMapMode], a + call Pack_InitGFX + call WaitBGMap_DrawPackGFX + call Pack_InitColors + ret + +.ReturnToBattle: + call ClearBGPalettes + jr .quit_run_script + +.BattleOnly: + call DoItemEffect + ld a, [wItemEffectSucceeded] + and a + jr z, .Oak + cp $2 + jr z, .didnt_use_item +.quit_run_script + ld a, PACKSTATE_QUITRUNSCRIPT + ld [wJumptableIndex], a + ret + +.didnt_use_item + xor a + ld [wItemEffectSucceeded], a + ret +.Quit: + ret + +InitPackBuffers: + xor a + ld [wJumptableIndex], a + ; pocket id -> jumptable index + ld a, [wLastPocket] + maskbits NUM_POCKETS + ld [wCurrPocket], a + inc a + add a + dec a + ld [wPackJumptableIndex], a + xor a ; FALSE + ld [wPackUsedItem], a + xor a + ld [wSwitchItem], a + ret + +DepositSellInitPackBuffers: + xor a + ld [hBGMapMode], a + ld [wJumptableIndex], a ; PACKSTATE_INITGFX + ld [wPackJumptableIndex], a ; PACKSTATE_INITGFX + ld [wCurrPocket], a ; ITEM_POCKET + ld [wPackUsedItem], a + ld [wSwitchItem], a + call Pack_InitGFX + call Pack_InitColors + ret + +DepositSellPack: +.loop + call .RunJumptable + call DepositSellTutorial_InterpretJoypad + jr c, .loop + ret + +.RunJumptable: + ld a, [wJumptableIndex] + ld hl, .Jumptable + call Pack_GetJumptablePointer + jp hl + +.Jumptable: +; entries correspond to *_POCKET constants + dw .ItemsPocket + dw .BallsPocket + dw .KeyItemsPocket + dw .TMHMPocket + +.ItemsPocket: + xor a ; ITEM_POCKET + call InitPocket + ld hl, PC_Mart_ItemsPocketMenuHeader + call CopyMenuHeader + ld a, [wItemsPocketCursor] + ld [wMenuCursorBuffer], a + ld a, [wItemsPocketScrollPosition] + ld [wMenuScrollPosition], a + call ScrollingMenu + ld a, [wMenuScrollPosition] + ld [wItemsPocketScrollPosition], a + ld a, [wMenuCursorY] + ld [wItemsPocketCursor], a + ret + +.KeyItemsPocket: + ld a, KEY_ITEM_POCKET + call InitPocket + ld hl, PC_Mart_KeyItemsPocketMenuHeader + call CopyMenuHeader + ld a, [wKeyItemsPocketCursor] + ld [wMenuCursorBuffer], a + ld a, [wKeyItemsPocketScrollPosition] + ld [wMenuScrollPosition], a + call ScrollingMenu + ld a, [wMenuScrollPosition] + ld [wKeyItemsPocketScrollPosition], a + ld a, [wMenuCursorY] + ld [wKeyItemsPocketCursor], a + ret + +.TMHMPocket: + ld a, TM_HM_POCKET + call InitPocket + call WaitBGMap_DrawPackGFX + farcall TMHMPocket + ld a, [wCurItem] + ld [wCurItem], a + ret + +.BallsPocket: + ld a, BALL_POCKET + call InitPocket + ld hl, PC_Mart_BallsPocketMenuHeader + call CopyMenuHeader + ld a, [wBallsPocketCursor] + ld [wMenuCursorBuffer], a + ld a, [wBallsPocketScrollPosition] + ld [wMenuScrollPosition], a + call ScrollingMenu + ld a, [wMenuScrollPosition] + ld [wBallsPocketScrollPosition], a + ld a, [wMenuCursorY] + ld [wBallsPocketCursor], a + ret + +InitPocket: + ld [wCurrPocket], a + call ClearPocketList + call DrawPocketName + call WaitBGMap_DrawPackGFX + ret + +DepositSellTutorial_InterpretJoypad: + ld hl, wMenuJoypad + ld a, [hl] + and A_BUTTON + jr nz, .a_button + ld a, [hl] + and B_BUTTON + jr nz, .b_button + ld a, [hl] + and D_LEFT + jr nz, .d_left + ld a, [hl] + and D_RIGHT + jr nz, .d_right + scf + ret + +.a_button + ld a, TRUE + ld [wPackUsedItem], a + and a + ret + +.b_button + xor a ; FALSE + ld [wPackUsedItem], a + and a + ret + +.d_left + ld a, [wJumptableIndex] + dec a + maskbits NUM_POCKETS + ld [wJumptableIndex], a + push de + ld de, SFX_SWITCH_POCKETS + call PlaySFX + pop de + scf + ret + +.d_right + ld a, [wJumptableIndex] + inc a + maskbits NUM_POCKETS + ld [wJumptableIndex], a + push de + ld de, SFX_SWITCH_POCKETS + call PlaySFX + pop de + scf + ret + +TutorialPack: + call DepositSellInitPackBuffers + ld a, [wInputType] + or a + jr z, .loop + farcall _DudeAutoInput_RightA +.loop + call .RunJumptable + call DepositSellTutorial_InterpretJoypad + jr c, .loop + xor a ; FALSE + ld [wPackUsedItem], a + ret + +.RunJumptable: + ld a, [wJumptableIndex] + ld hl, .dw + call Pack_GetJumptablePointer + jp hl + +.dw +; entries correspond to *_POCKET constants + dw .Items + dw .Balls + dw .KeyItems + dw .TMHM + +.Items: + xor a ; ITEM_POCKET + ld hl, .ItemsMenuHeader + jr .DisplayPocket + +.ItemsMenuHeader: + db MENU_BACKUP_TILES ; flags + menu_coords 7, 1, SCREEN_WIDTH - 1, TEXTBOX_Y - 1 + dw .ItemsMenuData + db 1 ; default option + +.ItemsMenuData: + db STATICMENU_ENABLE_SELECT | STATICMENU_ENABLE_LEFT_RIGHT | STATICMENU_ENABLE_START | STATICMENU_WRAP | STATICMENU_CURSOR ; flags + db 5, 8 ; rows, columns + db 2 ; horizontal spacing + dbw 0, wDudeNumItems + dba PlaceMenuItemName + dba PlaceMenuItemQuantity + dba UpdateItemDescription + +.KeyItems: + ld a, KEY_ITEM_POCKET + ld hl, .KeyItemsMenuHeader + jr .DisplayPocket + +.KeyItemsMenuHeader: + db MENU_BACKUP_TILES ; flags + menu_coords 7, 1, SCREEN_WIDTH - 1, TEXTBOX_Y - 1 + dw .KeyItemsMenuData + db 1 ; default option + +.KeyItemsMenuData: + db STATICMENU_ENABLE_SELECT | STATICMENU_ENABLE_LEFT_RIGHT | STATICMENU_ENABLE_START | STATICMENU_WRAP | STATICMENU_CURSOR ; flags + db 5, 8 ; rows, columns + db 1 ; horizontal spacing + dbw 0, wDudeNumKeyItems + dba PlaceMenuItemName + dba PlaceMenuItemQuantity + dba UpdateItemDescription + +.TMHM: + ld a, TM_HM_POCKET + call InitPocket + call WaitBGMap_DrawPackGFX + farcall TMHMPocket + ld a, [wCurItem] + ld [wCurItem], a + ret + +.Balls: + ld a, BALL_POCKET + ld hl, .BallsMenuHeader + jr .DisplayPocket + +.BallsMenuHeader: + db MENU_BACKUP_TILES ; flags + menu_coords 7, 1, SCREEN_WIDTH - 1, TEXTBOX_Y - 1 + dw .BallsMenuData + db 1 ; default option + +.BallsMenuData: + db STATICMENU_ENABLE_SELECT | STATICMENU_ENABLE_LEFT_RIGHT | STATICMENU_ENABLE_START | STATICMENU_WRAP | STATICMENU_CURSOR ; flags + db 5, 8 ; rows, columns + db 2 ; horizontal spacing + dbw 0, wDudeNumBalls + dba PlaceMenuItemName + dba PlaceMenuItemQuantity + dba UpdateItemDescription + +.DisplayPocket: + push hl + call InitPocket + pop hl + call CopyMenuHeader + call ScrollingMenu + ret + +Pack_JumptableNext: + ld hl, wJumptableIndex + inc [hl] + ret + +Pack_GetJumptablePointer: + ld e, a + ld d, 0 + add hl, de + add hl, de + ld a, [hli] + ld h, [hl] + ld l, a + ret + +Pack_QuitNoScript: + ld hl, wJumptableIndex + set 7, [hl] + xor a ; FALSE + ld [wPackUsedItem], a + ret + +Pack_QuitRunScript: + ld hl, wJumptableIndex + set 7, [hl] + ld a, TRUE + ld [wPackUsedItem], a + ret + +Pack_PrintTextNoScroll: + ld a, [wOptions] + push af + set NO_TEXT_SCROLL, a + ld [wOptions], a + call PrintText + pop af + ld [wOptions], a + ret + +WaitBGMap_DrawPackGFX: + call WaitBGMap +DrawPackGFX: + ld a, [wCurrPocket] + maskbits NUM_POCKETS + ld e, a + ld d, 0 + ld a, [wBattleType] + cp BATTLETYPE_TUTORIAL + jr z, .male_dude + ld a, [wPlayerGender] + bit PLAYERGENDER_FEMALE_F, a + jr nz, .female +.male_dude + ld hl, PackGFXPointers + add hl, de + add hl, de + ld a, [hli] + ld e, a + ld d, [hl] + ld hl, vTiles2 tile $50 + lb bc, BANK(PackGFX), 15 + call Request2bpp + ret + +.female + farcall DrawKrisPackGFX + ret + +PackGFXPointers: + dw PackGFX + (15 tiles) * 1 ; ITEM_POCKET + dw PackGFX + (15 tiles) * 3 ; BALL_POCKET + dw PackGFX + (15 tiles) * 0 ; KEY_ITEM_POCKET + dw PackGFX + (15 tiles) * 2 ; TM_HM_POCKET + +Pack_InterpretJoypad: + ld hl, wMenuJoypad + ld a, [wSwitchItem] + and a + jr nz, .switching_item + ld a, [hl] + and A_BUTTON + jr nz, .a_button + ld a, [hl] + and B_BUTTON + jr nz, .b_button + ld a, [hl] + and D_LEFT + jr nz, .d_left + ld a, [hl] + and D_RIGHT + jr nz, .d_right + ld a, [hl] + and SELECT + jr nz, .select + scf + ret + +.a_button + and a + ret + +.b_button + ld a, PACKSTATE_QUITNOSCRIPT + ld [wJumptableIndex], a + scf + ret + +.d_left + ld a, b + ld [wJumptableIndex], a + ld [wPackJumptableIndex], a + push de + ld de, SFX_SWITCH_POCKETS + call PlaySFX + pop de + scf + ret + +.d_right + ld a, c + ld [wJumptableIndex], a + ld [wPackJumptableIndex], a + push de + ld de, SFX_SWITCH_POCKETS + call PlaySFX + pop de + scf + ret + +.select + farcall SwitchItemsInBag + ld hl, Text_MoveItemWhere + call Pack_PrintTextNoScroll + scf + ret + +.switching_item + ld a, [hl] + and A_BUTTON | SELECT + jr nz, .place_insert + ld a, [hl] + and B_BUTTON + jr nz, .end_switch + scf + ret + +.place_insert + farcall SwitchItemsInBag + ld de, SFX_SWITCH_POKEMON + call WaitPlaySFX + ld de, SFX_SWITCH_POKEMON + call WaitPlaySFX +.end_switch + xor a + ld [wSwitchItem], a + scf + ret + +Pack_InitGFX: + call ClearBGPalettes + call ClearTileMap + call ClearSprites + call DisableLCD + ld hl, PackMenuGFX + ld de, vTiles2 + ld bc, $60 tiles + ld a, BANK(PackMenuGFX) + call FarCopyBytes +; Background (blue if male, pink if female) + hlcoord 0, 1 + ld bc, 11 * SCREEN_WIDTH + ld a, $24 + call ByteFill +; This is where the items themselves will be listed. + hlcoord 5, 1 + lb bc, 11, 15 + call ClearBox +; ◀▶ POCKET ▼▲ ITEMS + hlcoord 0, 0 + ld a, $28 + ld c, SCREEN_WIDTH +.loop + ld [hli], a + inc a + dec c + jr nz, .loop + call DrawPocketName + call PlacePackGFX +; Place the textbox for displaying the item description + hlcoord 0, SCREEN_HEIGHT - 4 - 2 + lb bc, 4, SCREEN_WIDTH - 2 + call TextBox + call EnableLCD + call DrawPackGFX + ret + +PlacePackGFX: + hlcoord 0, 3 + ld a, $50 + ld de, SCREEN_WIDTH - 5 + ld b, 3 +.row + ld c, 5 +.column + ld [hli], a + inc a + dec c + jr nz, .column + add hl, de + dec b + jr nz, .row + ret + +DrawPocketName: + ld a, [wCurrPocket] + ; * 15 + ld d, a + swap a + sub d + ld d, 0 + ld e, a + ld hl, .tilemap + add hl, de + ld d, h + ld e, l + hlcoord 0, 7 + ld c, 3 +.row + ld b, 5 +.col + ld a, [de] + inc de + ld [hli], a + dec b + jr nz, .col + ld a, c + ld c, SCREEN_WIDTH - 5 + add hl, bc + ld c, a + dec c + jr nz, .row + ret + +.tilemap +; ITEM_POCKET + db $00, $04, $04, $04, $01 ; top border + db $06, $07, $08, $09, $0a ; Items + db $02, $05, $05, $05, $03 ; bottom border +; BALL_POCKET + db $00, $04, $04, $04, $01 ; top border + db $15, $16, $17, $18, $19 ; Balls + db $02, $05, $05, $05, $03 ; bottom border +; KEY_ITEM_POCKET + db $00, $04, $04, $04, $01 ; top border + db $0b, $0c, $0d, $0e, $0f ; Key Items + db $02, $05, $05, $05, $03 ; bottom border +; TM_HM_POCKET + db $00, $04, $04, $04, $01 ; top border + db $10, $11, $12, $13, $14 ; TM/HM + db $02, $05, $05, $05, $03 ; bottom border + +Pack_GetItemName: + ld a, [wCurItem] + ld [wNamedObjectIndexBuffer], a + call GetItemName + call CopyName1 + ret + +Unreferenced_Pack_ClearTilemap: + hlcoord 0, 0 + ld bc, SCREEN_WIDTH * SCREEN_HEIGHT + ld a, " " + call ByteFill + ret + +ClearPocketList: + hlcoord 5, 2 + lb bc, 10, SCREEN_WIDTH - 5 + call ClearBox + ret + +Pack_InitColors: + call WaitBGMap + ld b, SCGB_PACKPALS + call GetSGBLayout + call SetPalettes + call DelayFrame + ret + +ItemsPocketMenuHeader: + db MENU_BACKUP_TILES ; flags + menu_coords 7, 1, SCREEN_WIDTH - 1, TEXTBOX_Y - 1 + dw .MenuData + db 1 ; default option + +.MenuData: + db STATICMENU_ENABLE_SELECT | STATICMENU_ENABLE_LEFT_RIGHT | STATICMENU_ENABLE_START | STATICMENU_WRAP | STATICMENU_CURSOR ; flags + db 5, 8 ; rows, columns + db 2 ; horizontal spacing + dbw 0, wNumItems + dba PlaceMenuItemName + dba PlaceMenuItemQuantity + dba UpdateItemDescription + +PC_Mart_ItemsPocketMenuHeader: + db MENU_BACKUP_TILES ; flags + menu_coords 7, 1, SCREEN_WIDTH - 1, TEXTBOX_Y - 1 + dw .MenuData + db 1 ; default option + +.MenuData: + db STATICMENU_ENABLE_SELECT | STATICMENU_ENABLE_LEFT_RIGHT | STATICMENU_ENABLE_START | STATICMENU_WRAP ; flags + db 5, 8 ; rows, columns + db 2 ; horizontal spacing + dbw 0, wNumItems + dba PlaceMenuItemName + dba PlaceMenuItemQuantity + dba UpdateItemDescription + +KeyItemsPocketMenuHeader: + db MENU_BACKUP_TILES ; flags + menu_coords 7, 1, SCREEN_WIDTH - 1, TEXTBOX_Y - 1 + dw .MenuData + db 1 ; default option + +.MenuData: + db STATICMENU_ENABLE_SELECT | STATICMENU_ENABLE_LEFT_RIGHT | STATICMENU_ENABLE_START | STATICMENU_WRAP | STATICMENU_CURSOR ; flags + db 5, 8 ; rows, columns + db 1 ; horizontal spacing + dbw 0, wNumKeyItems + dba PlaceMenuItemName + dba PlaceMenuItemQuantity + dba UpdateItemDescription + +PC_Mart_KeyItemsPocketMenuHeader: + db MENU_BACKUP_TILES ; flags + menu_coords 7, 1, SCREEN_WIDTH - 1, TEXTBOX_Y - 1 + dw .MenuData + db 1 ; default option + +.MenuData: + db STATICMENU_ENABLE_SELECT | STATICMENU_ENABLE_LEFT_RIGHT | STATICMENU_ENABLE_START | STATICMENU_WRAP ; flags + db 5, 8 ; rows, columns + db 1 ; horizontal spacing + dbw 0, wNumKeyItems + dba PlaceMenuItemName + dba PlaceMenuItemQuantity + dba UpdateItemDescription + +BallsPocketMenuHeader: + db MENU_BACKUP_TILES ; flags + menu_coords 7, 1, SCREEN_WIDTH - 1, TEXTBOX_Y - 1 + dw .MenuData + db 1 ; default option + +.MenuData: + db STATICMENU_ENABLE_SELECT | STATICMENU_ENABLE_LEFT_RIGHT | STATICMENU_ENABLE_START | STATICMENU_WRAP | STATICMENU_CURSOR ; flags + db 5, 8 ; rows, columns + db 2 ; horizontal spacing + dbw 0, wNumBalls + dba PlaceMenuItemName + dba PlaceMenuItemQuantity + dba UpdateItemDescription + +PC_Mart_BallsPocketMenuHeader: + db MENU_BACKUP_TILES ; flags + menu_coords 7, 1, SCREEN_WIDTH - 1, TEXTBOX_Y - 1 + dw .MenuData + db 1 ; default option + +.MenuData: + db STATICMENU_ENABLE_SELECT | STATICMENU_ENABLE_LEFT_RIGHT | STATICMENU_ENABLE_START | STATICMENU_WRAP ; flags + db 5, 8 ; rows, columns + db 2 ; horizontal spacing + dbw 0, wNumBalls + dba PlaceMenuItemName + dba PlaceMenuItemQuantity + dba UpdateItemDescription + +Text_PackNoItems: + ; No items. + text_jump UnknownText_0x1c0b9a + db "@" + +Text_ThrowAwayHowMany: + ; Throw away how many? + text_jump UnknownText_0x1c0ba5 + db "@" + +Text_ConfirmThrowAway: + ; Throw away @ @ (S)? + text_jump UnknownText_0x1c0bbb + db "@" + +Text_ThrewAway: + ; Threw away @ (S). + text_jump UnknownText_0x1c0bd8 + db "@" + +Text_ThisIsntTheTime: + ; OAK: ! This isn't the time to use that! + text_jump UnknownText_0x1c0bee + db "@" + +TextJump_YouDontHaveAMon: + ; You don't have a #MON! + text_jump Text_YouDontHaveAMon + db "@" + +Text_RegisteredItem: + ; Registered the @ . + text_jump UnknownText_0x1c0c2e + db "@" + +Text_CantRegister: + ; You can't register that item. + text_jump UnknownText_0x1c0c45 + db "@" + +Text_MoveItemWhere: + ; Where should this be moved to? + text_jump UnknownText_0x1c0c63 + db "@" + +Text_PackEmptyString: + ; + text_jump UnknownText_0x1c0c83 + db "@" + +TextJump_YouCantUseItInABattle: + ; Doesn't seem to be used anywhere + ; "You can't use it in a battle." + text_jump Text_YouCantUseItInABattle + db "@" + +PackMenuGFX: +INCBIN "gfx/pack/pack_menu.2bpp" +PackGFX: +INCBIN "gfx/pack/pack.2bpp" diff --git a/engine/items/pack_kris.asm b/engine/items/pack_kris.asm new file mode 100644 index 000000000..1a169ea6e --- /dev/null +++ b/engine/items/pack_kris.asm @@ -0,0 +1,20 @@ +DrawKrisPackGFX: + ld hl, PackFGFXPointers + add hl, de + add hl, de + ld a, [hli] + ld e, a + ld d, [hl] + ld hl, vTiles2 tile $50 + lb bc, BANK(PackFGFX), 15 + call Request2bpp + ret + +PackFGFXPointers: + dw PackFGFX + (15 tiles) * 1 ; ITEM_POCKET + dw PackFGFX + (15 tiles) * 3 ; BALL_POCKET + dw PackFGFX + (15 tiles) * 0 ; KEY_ITEM_POCKET + dw PackFGFX + (15 tiles) * 2 ; TM_HM_POCKET + +PackFGFX: +INCBIN "gfx/pack/pack_f.2bpp" diff --git a/engine/items/print_item_description.asm b/engine/items/print_item_description.asm new file mode 100644 index 000000000..b0a3a0b33 --- /dev/null +++ b/engine/items/print_item_description.asm @@ -0,0 +1,32 @@ +PrintItemDescription: +; Print the description for item [wCurSpecies] at de. + + ld a, [wCurSpecies] + cp TM01 + jr c, .not_a_tm + + ld [wCurItem], a + push de + farcall GetTMHMItemMove + pop hl + ld a, [wd265] + ld [wCurSpecies], a + predef PrintMoveDesc + ret + +.not_a_tm + push de + ld hl, ItemDescriptions + ld a, [wCurSpecies] + dec a + ld c, a + ld b, 0 + add hl, bc + add hl, bc + ld e, [hl] + inc hl + ld d, [hl] + pop hl + jp PlaceString + +INCLUDE "data/items/descriptions.asm" diff --git a/engine/items/switch_items.asm b/engine/items/switch_items.asm new file mode 100644 index 000000000..81b5ac6a5 --- /dev/null +++ b/engine/items/switch_items.asm @@ -0,0 +1,271 @@ +SwitchItemsInBag: + ld a, [wSwitchItem] + and a + jr z, .init + ld b, a + ld a, [wScrollingMenuCursorPosition] + inc a + cp b + jr z, .trivial + ld a, [wScrollingMenuCursorPosition] + call ItemSwitch_GetNthItem + ld a, [hl] + cp -1 + ret z + ld a, [wSwitchItem] + dec a + ld [wSwitchItem], a + call Function249a7 + jp c, Function249d1 + ld a, [wScrollingMenuCursorPosition] + ld c, a + ld a, [wSwitchItem] + cp c + jr c, .asm_2497a + jr .asm_2494a + +.init + ld a, [wScrollingMenuCursorPosition] + inc a + ld [wSwitchItem], a + ret + +.trivial + xor a + ld [wSwitchItem], a + ret + +.asm_2494a + ld a, [wSwitchItem] + call Function24a40 + ld a, [wScrollingMenuCursorPosition] + ld d, a + ld a, [wSwitchItem] + ld e, a + call Function24a6c + push bc + ld a, [wSwitchItem] + call ItemSwitch_GetNthItem + dec hl + push hl + call ItemSwitch_ConvertSpacingToDW + add hl, bc + ld d, h + ld e, l + pop hl + pop bc + call Function24aab + ld a, [wScrollingMenuCursorPosition] + call Function24a4d + xor a + ld [wSwitchItem], a + ret + +.asm_2497a + ld a, [wSwitchItem] + call Function24a40 + ld a, [wScrollingMenuCursorPosition] + ld d, a + ld a, [wSwitchItem] + ld e, a + call Function24a6c + push bc + ld a, [wSwitchItem] + call ItemSwitch_GetNthItem + ld d, h + ld e, l + call ItemSwitch_ConvertSpacingToDW + add hl, bc + pop bc + call CopyBytes + ld a, [wScrollingMenuCursorPosition] + call Function24a4d + xor a + ld [wSwitchItem], a + ret + +Function249a7: + ld a, [wSwitchItem] + call ItemSwitch_GetNthItem + ld d, h + ld e, l + ld a, [wScrollingMenuCursorPosition] + call ItemSwitch_GetNthItem + ld a, [de] + cp [hl] + jr nz, .asm_249cd + ld a, [wScrollingMenuCursorPosition] + call Function24a97 + cp 99 + jr z, .asm_249cd + ld a, [wSwitchItem] + call Function24a97 + cp 99 + jr nz, .asm_249cf +.asm_249cd + and a + ret + +.asm_249cf + scf + ret + +Function249d1: + ld a, [wSwitchItem] + call ItemSwitch_GetNthItem + inc hl + push hl + ld a, [wScrollingMenuCursorPosition] + call ItemSwitch_GetNthItem + inc hl + ld a, [hl] + pop hl + add [hl] + cp 100 + jr c, .asm_24a01 + sub 99 + push af + ld a, [wScrollingMenuCursorPosition] + call ItemSwitch_GetNthItem + inc hl + ld [hl], 99 + ld a, [wSwitchItem] + call ItemSwitch_GetNthItem + inc hl + pop af + ld [hl], a + xor a + ld [wSwitchItem], a + ret + +.asm_24a01 + push af + ld a, [wScrollingMenuCursorPosition] + call ItemSwitch_GetNthItem + inc hl + pop af + ld [hl], a + ld hl, wMenuData_ItemsPointerAddr + ld a, [hli] + ld h, [hl] + ld l, a + ld a, [wSwitchItem] + cp [hl] + jr nz, .asm_24a25 + dec [hl] + ld a, [wSwitchItem] + call ItemSwitch_GetNthItem + ld [hl], $ff + xor a + ld [wSwitchItem], a + ret + +.asm_24a25 + dec [hl] + call ItemSwitch_ConvertSpacingToDW + push bc + ld a, [wSwitchItem] + call ItemSwitch_GetNthItem + pop bc + push hl + add hl, bc + pop de +.asm_24a34 + ld a, [hli] + ld [de], a + inc de + cp $ff + jr nz, .asm_24a34 + xor a + ld [wSwitchItem], a + ret + +Function24a40: + call ItemSwitch_GetNthItem + ld de, wd002 + call ItemSwitch_ConvertSpacingToDW + call CopyBytes + ret + +Function24a4d: + call ItemSwitch_GetNthItem + ld d, h + ld e, l + ld hl, wd002 + call ItemSwitch_ConvertSpacingToDW + call CopyBytes + ret + +ItemSwitch_GetNthItem: + push af + call ItemSwitch_ConvertSpacingToDW + ld hl, wMenuData_ItemsPointerAddr + ld a, [hli] + ld h, [hl] + ld l, a + inc hl + pop af + call AddNTimes + ret + +Function24a6c: + push hl + call ItemSwitch_ConvertSpacingToDW + ld a, d + sub e + jr nc, .dont_negate + dec a + cpl +.dont_negate + ld hl, 0 + call AddNTimes + ld b, h + ld c, l + pop hl + ret + +ItemSwitch_ConvertSpacingToDW: +; This function is absolutely idiotic. + push hl + ld a, [wMenuData_ScrollingMenuSpacing] + ld c, a + ld b, 0 + ld hl, .spacing_dws + add hl, bc + add hl, bc + ld c, [hl] + inc hl + ld b, [hl] + pop hl + ret + +.spacing_dws + dw 0, 1, 2 + +Function24a97: + push af + call ItemSwitch_ConvertSpacingToDW + ld a, c + cp 2 + jr nz, .not_2 + pop af + call ItemSwitch_GetNthItem + inc hl + ld a, [hl] + ret + +.not_2 + pop af + ld a, $1 + ret + +Function24aab: +.loop + ld a, [hld] + ld [de], a + dec de + dec bc + ld a, b + or c + jr nz, .loop + ret diff --git a/engine/items/tmhm.asm b/engine/items/tmhm.asm new file mode 100644 index 000000000..4958d2afc --- /dev/null +++ b/engine/items/tmhm.asm @@ -0,0 +1,574 @@ +TMHMPocket: + ld a, $1 + ld [hInMenu], a + call TMHM_PocketLoop + ld a, $0 + ld [hInMenu], a + ret nc + call PlaceHollowCursor + call WaitBGMap + ld a, [wCurItem] + dec a + ld [wCurItemQuantity], a + ld hl, wTMsHMs + ld c, a + ld b, 0 + add hl, bc + ld a, [hl] + ld [wItemQuantityBuffer], a + call .ConvertItemToTMHMNumber + scf + ret + +.ConvertItemToTMHMNumber: + ld a, [wCurItem] + ld c, a + callfar GetNumberedTMHM + ld a, c + ld [wCurItem], a + ret + +ConvertCurItemIntoCurTMHM: + ld a, [wCurItem] + ld c, a + callfar GetTMHMNumber + ld a, c + ld [wCurTMHM], a + ret + +GetTMHMItemMove: + call ConvertCurItemIntoCurTMHM + predef GetTMHMMove + ret + +AskTeachTMHM: + ld hl, wOptions + ld a, [hl] + push af + res NO_TEXT_SCROLL, [hl] + ld a, [wCurItem] + cp TM01 + jr c, .NotTMHM + call GetTMHMItemMove + ld a, [wCurTMHM] + ld [wPutativeTMHMMove], a + call GetMoveName + call CopyName1 + ld hl, Text_BootedTM ; Booted up a TM + ld a, [wCurItem] + cp HM01 + jr c, .TM + ld hl, Text_BootedHM ; Booted up an HM +.TM: + call PrintText + ld hl, Text_ItContained + call PrintText + call YesNoBox +.NotTMHM: + pop bc + ld a, b + ld [wOptions], a + ret + +ChooseMonToLearnTMHM: + ld hl, wStringBuffer2 + ld de, wTMHMMoveNameBackup + ld bc, 12 + call CopyBytes + call ClearBGPalettes +ChooseMonToLearnTMHM_NoRefresh: + farcall LoadPartyMenuGFX + farcall InitPartyMenuWithCancel + farcall InitPartyMenuGFX + ld a, PARTYMENUACTION_TEACH_TMHM + ld [wPartyMenuActionText], a +.loopback + farcall WritePartyMenuTilemap + farcall PrintPartyMenuText + call WaitBGMap + call SetPalettes + call DelayFrame + farcall PartyMenuSelect + push af + ld a, [wCurPartySpecies] + cp EGG + pop bc ; now contains the former contents of af + jr z, .egg + push bc + ld hl, wTMHMMoveNameBackup + ld de, wStringBuffer2 + ld bc, 12 + call CopyBytes + pop af ; now contains the original contents of af + ret + +.egg + push hl + push de + push bc + push af + ld de, SFX_WRONG + call PlaySFX + call WaitSFX + pop af + pop bc + pop de + pop hl + jr .loopback + +TeachTMHM: + predef CanLearnTMHMMove + + push bc + ld a, [wCurPartyMon] + ld hl, wPartyMonNicknames + call GetNick + pop bc + + ld a, c + and a + jr nz, .compatible + push de + ld de, SFX_WRONG + call PlaySFX + pop de + ld hl, Text_TMHMNotCompatible + call PrintText + jr .nope + +.compatible + callfar KnowsMove + jr c, .nope + + predef LearnMove + ld a, b + and a + jr z, .nope + + farcall StubbedTrainerRankings_TMsHMsTaught + ld a, [wCurItem] + call IsHM + ret c + + ld c, HAPPINESS_LEARNMOVE + callfar ChangeHappiness + call ConsumeTM + jr .learned_move + +.nope + and a + ret + +.unused + ld a, 2 + ld [wItemEffectSucceeded], a +.learned_move + scf + ret + +Text_BootedTM: + ; Booted up a TM. + text_jump UnknownText_0x1c0373 + db "@" + +Text_BootedHM: + ; Booted up an HM. + text_jump UnknownText_0x1c0384 + db "@" + +Text_ItContained: + ; It contained @ . Teach @ to a #MON? + text_jump UnknownText_0x1c0396 + db "@" + +Text_TMHMNotCompatible: + ; is not compatible with @ . It can't learn @ . + text_jump UnknownText_0x1c03c2 + db "@" + +TMHM_PocketLoop: + xor a + ld [hBGMapMode], a + call TMHM_DisplayPocketItems + ld a, 2 + ld [w2DMenuCursorInitY], a + ld a, 7 + ld [w2DMenuCursorInitX], a + ld a, 1 + ld [w2DMenuNumCols], a + ld a, 5 + sub d + inc a + cp 6 + jr nz, .okay + dec a +.okay + ld [w2DMenuNumRows], a + ld a, $c + ld [w2DMenuFlags1], a + xor a + ld [w2DMenuFlags2], a + ld a, $20 + ld [w2DMenuCursorOffsets], a + ld a, A_BUTTON | B_BUTTON | D_UP | D_DOWN | D_LEFT | D_RIGHT + ld [wMenuJoypadFilter], a + ld a, [wTMHMPocketCursor] + inc a + ld [wMenuCursorY], a + ld a, $1 + ld [wMenuCursorX], a + jr TMHM_ShowTMMoveDescription + +TMHM_JoypadLoop: + call TMHM_DisplayPocketItems + call StaticMenuJoypad + ld b, a + ld a, [wMenuCursorY] + dec a + ld [wTMHMPocketCursor], a + xor a + ld [hBGMapMode], a + ld a, [w2DMenuFlags2] + bit 7, a + jp nz, TMHM_ScrollPocket + ld a, b + ld [wMenuJoypad], a + bit A_BUTTON_F, a + jp nz, TMHM_ChooseTMorHM + bit B_BUTTON_F, a + jp nz, TMHM_ExitPack + bit D_RIGHT_F, a + jp nz, TMHM_ExitPocket + bit D_LEFT_F, a + jp nz, TMHM_ExitPocket +TMHM_ShowTMMoveDescription: + call TMHM_CheckHoveringOverCancel + jp nc, TMHM_ExitPocket + hlcoord 0, 12 + ld b, 4 + ld c, SCREEN_WIDTH - 2 + call TextBox + ld a, [wCurItem] + cp NUM_TMS + NUM_HMS + 1 + jr nc, TMHM_JoypadLoop + ld [wd265], a + predef GetTMHMMove + ld a, [wd265] + ld [wCurSpecies], a + hlcoord 1, 14 + call PrintMoveDesc + jp TMHM_JoypadLoop + +TMHM_ChooseTMorHM: + call TMHM_PlaySFX_ReadText2 + call CountTMsHMs ; This stores the count to wd265. + ld a, [wMenuCursorY] + dec a + ld b, a + ld a, [wTMHMPocketScrollPosition] + add b + ld b, a + ld a, [wd265] + cp b + jr z, _TMHM_ExitPack ; our cursor was hovering over CANCEL +TMHM_CheckHoveringOverCancel: + call TMHM_GetCurrentPocketPosition + ld a, [wMenuCursorY] + ld b, a +.loop + inc c + ld a, c + cp NUM_TMS + NUM_HMS + 1 + jr nc, .okay + ld a, [hli] + and a + jr z, .loop + dec b + jr nz, .loop + ld a, c +.okay + ld [wCurItem], a + cp -1 + ret + +TMHM_ExitPack: + call TMHM_PlaySFX_ReadText2 +_TMHM_ExitPack: + ld a, $2 + ld [wMenuJoypad], a + and a + ret + +TMHM_ExitPocket: + and a + ret + +TMHM_ScrollPocket: + ld a, b + bit 7, a + jr nz, .skip + ld hl, wTMHMPocketScrollPosition + ld a, [hl] + and a + jp z, TMHM_JoypadLoop + dec [hl] + call TMHM_DisplayPocketItems + jp TMHM_ShowTMMoveDescription + +.skip + call TMHM_GetCurrentPocketPosition + ld b, 5 +.loop + inc c + ld a, c + cp NUM_TMS + NUM_HMS + 1 + jp nc, TMHM_JoypadLoop + ld a, [hli] + and a + jr z, .loop + dec b + jr nz, .loop + ld hl, wTMHMPocketScrollPosition + inc [hl] + call TMHM_DisplayPocketItems + jp TMHM_ShowTMMoveDescription + +TMHM_DisplayPocketItems: + ld a, [wBattleType] + cp BATTLETYPE_TUTORIAL + jp z, Tutorial_TMHMPocket + + hlcoord 5, 2 + lb bc, 10, 15 + ld a, " " + call ClearBox + call TMHM_GetCurrentPocketPosition + ld d, $5 +.loop2 + inc c + ld a, c + cp NUM_TMS + NUM_HMS + 1 + jr nc, .NotTMHM + ld a, [hli] + and a + jr z, .loop2 + ld b, a + ld a, c + ld [wd265], a + push hl + push de + push bc + call TMHMPocket_GetCurrentLineCoord + push hl + ld a, [wd265] + cp NUM_TMS + 1 + jr nc, .HM + ld de, wd265 + lb bc, PRINTNUM_LEADINGZEROS | 1, 2 + call PrintNum + jr .okay + +.HM: + push af + sub NUM_TMS + ld [wd265], a + ld [hl], "H" + inc hl + ld de, wd265 + lb bc, PRINTNUM_RIGHTALIGN | 1, 2 + call PrintNum + pop af + ld [wd265], a +.okay + predef GetTMHMMove + ld a, [wd265] + ld [wPutativeTMHMMove], a + call GetMoveName + pop hl + ld bc, 3 + add hl, bc + push hl + call PlaceString + pop hl + pop bc + ld a, c + push bc + cp NUM_TMS + 1 + jr nc, .hm2 + ld bc, SCREEN_WIDTH + 9 + add hl, bc + ld [hl], "×" + inc hl + ld a, "0" ; why are we doing this? + pop bc + push bc + ld a, b + ld [wd265], a + ld de, wd265 + lb bc, 1, 2 + call PrintNum +.hm2 + pop bc + pop de + pop hl + dec d + jr nz, .loop2 + jr .done + +.NotTMHM: + call TMHMPocket_GetCurrentLineCoord + inc hl + inc hl + inc hl + push de + ld de, TMHM_String_Cancel + call PlaceString + pop de +.done + ret + +TMHMPocket_GetCurrentLineCoord: + hlcoord 5, 0 + ld bc, 2 * SCREEN_WIDTH + ld a, 6 + sub d + ld e, a + ; AddNTimes +.loop + add hl, bc + dec e + jr nz, .loop + ret + +Unreferenced_Function2ca95: + pop hl + ld bc, 3 + add hl, bc + predef GetTMHMMove + ld a, [wd265] + ld [wPutativeTMHMMove], a + call GetMoveName + push hl + call PlaceString + pop hl + ret + +TMHM_String_Cancel: + db "CANCEL@" + +TMHM_GetCurrentPocketPosition: + ld hl, wTMsHMs + ld a, [wTMHMPocketScrollPosition] + ld b, a + inc b + ld c, 0 +.loop + inc c + ld a, [hli] + and a + jr z, .loop + dec b + jr nz, .loop + dec hl + dec c + ret + +Tutorial_TMHMPocket: + hlcoord 9, 3 + push de + ld de, TMHM_String_Cancel + call PlaceString + pop de + ret + +TMHM_PlaySFX_ReadText2: + push de + ld de, SFX_READ_TEXT_2 + call PlaySFX + pop de + ret + +Unreferenced_Function2cadf: + call ConvertCurItemIntoCurTMHM + call .CheckHaveRoomForTMHM + ld hl, .NoRoomText + jr nc, .print + ld hl, .ReceivedText +.print + jp PrintText + +.NoRoomText: + ; You have no room for any more @ S. + text_jump UnknownText_0x1c03fa + db "@" + +.ReceivedText: + ; You received @ ! + text_jump UnknownText_0x1c0421 + db "@" + +.CheckHaveRoomForTMHM: + ld a, [wd265] + dec a + ld hl, wTMsHMs + ld b, 0 + ld c, a + add hl, bc + ld a, [hl] + inc a + cp NUM_TMS * 2 + ret nc + ld [hl], a + ret + +ConsumeTM: + call ConvertCurItemIntoCurTMHM + ld a, [wd265] + dec a + ld hl, wTMsHMs + ld b, 0 + ld c, a + add hl, bc + ld a, [hl] + and a + ret z + dec a + ld [hl], a + ret nz + ld a, [wTMHMPocketScrollPosition] + and a + ret z + dec a + ld [wTMHMPocketScrollPosition], a + ret + +CountTMsHMs: + ld b, 0 + ld c, NUM_TMS + NUM_HMS + ld hl, wTMsHMs +.loop + ld a, [hli] + and a + jr z, .skip + inc b +.skip + dec c + jr nz, .loop + ld a, b + ld [wd265], a + ret + +PrintMoveDesc: + push hl + ld hl, MoveDescriptions + ld a, [wCurSpecies] + dec a + ld c, a + ld b, 0 + add hl, bc + add hl, bc + ld a, [hli] + ld e, a + ld d, [hl] + pop hl + jp PlaceString diff --git a/engine/items/tmhm2.asm b/engine/items/tmhm2.asm new file mode 100644 index 000000000..10206d36b --- /dev/null +++ b/engine/items/tmhm2.asm @@ -0,0 +1,46 @@ +CanLearnTMHMMove: + ld a, [wCurPartySpecies] + ld [wCurSpecies], a + call GetBaseData + ld hl, wBaseTMHM + push hl + + ld a, [wPutativeTMHMMove] + ld b, a + ld c, 0 + ld hl, TMHMMoves +.loop + ld a, [hli] + and a + jr z, .end + cp b + jr z, .asm_11659 + inc c + jr .loop + +.asm_11659 + pop hl + ld b, CHECK_FLAG + push de + ld d, 0 + predef SmallFarFlagAction + pop de + ret + +.end + pop hl + ld c, 0 + ret + +GetTMHMMove: + ld a, [wd265] + dec a + ld hl, TMHMMoves + ld b, 0 + ld c, a + add hl, bc + ld a, [hl] + ld [wd265], a + ret + +INCLUDE "data/moves/tmhm_moves.asm" diff --git a/engine/items/update_item_description.asm b/engine/items/update_item_description.asm new file mode 100644 index 000000000..d4bc731a1 --- /dev/null +++ b/engine/items/update_item_description.asm @@ -0,0 +1,13 @@ +UpdateItemDescription: + ld a, [wMenuSelection] + ld [wCurSpecies], a + hlcoord 0, 12 + ld b, 4 + ld c, SCREEN_WIDTH - 2 + call TextBox + ld a, [wMenuSelection] + cp -1 + ret z + decoord 1, 14 + farcall PrintItemDescription + ret |