diff options
author | pikalaxalt <PikalaxALT@gmail.com> | 2016-06-22 20:22:09 -0400 |
---|---|---|
committer | pikalaxalt <PikalaxALT@gmail.com> | 2016-06-22 20:22:09 -0400 |
commit | 705c6fb69d3ae2da0bc47c70b2f361e8228caa5e (patch) | |
tree | 05c9770d0e5d6253c3f0e1881b8b842b87db2736 /items/item_effects.asm | |
parent | b5aad665f6f50d4ed04b0fc51ec45dc46ccf9fdf (diff) |
Ball functions
Diffstat (limited to 'items/item_effects.asm')
-rwxr-xr-x | items/item_effects.asm | 834 |
1 files changed, 814 insertions, 20 deletions
diff --git a/items/item_effects.asm b/items/item_effects.asm index bfd47e4e..8a2a93bd 100755 --- a/items/item_effects.asm +++ b/items/item_effects.asm @@ -11,7 +11,7 @@ DoItemEffect_:: ; e7a6 (3:67a6) rst JumpTable ret -.ItemEffects: ; e7c0 +.ItemEffects dw MasterBall dw UltraBall dw Brightpowder @@ -192,7 +192,6 @@ DoItemEffect_:: ; e7a6 (3:67a6) dw RainbowWing dw ItemB3 -IF DEF(GOLD) FastBall: ; e926 FriendBall: ; e926 GreatBall: ; e926 @@ -205,8 +204,800 @@ MoonBall: ; e926 ParkBall: ; e926 PokeBall: ; e926 UltraBall: ; e926 - dr $e926, $ee55 + ld a, [wBattleMode] + dec a + jp nz, Functionf7e7 + ld a, [wPartyCount] + cp PARTY_LENGTH + jr nz, .room_in_party_or_pc + ld a, $1 + call OpenSRAM + ld a, [$ad6c] + cp $14 + call CloseSRAM + jp z, FailToUseBall +.room_in_party_or_pc + xor a + ld [wWildMon], a + ld a, [wd002] + cp PARK_BALL + call nz, ReturnToBattle_UseBall + ld hl, Options + res NO_TEXT_SCROLL, [hl] + ld hl, Text_UsedItem ; $7884 + call PrintText + ld a, [wd114] + ld b, a + ld a, [wBattleType] + cp BATTLETYPE_TUTORIAL + jp z, .catch_without_fail + ld a, [wd002] + cp MASTER_BALL + jp z, .catch_without_fail + ld a, [wd002] + ld c, a + ld hl, BallMultiplierFunctionTable ; $6c73 +.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, [wd002] + cp LEVEL_BALL + ld a, b + jp z, .skip_hp_calc + ld a, b + ld [hPrintNum4], a + ld hl, wEnemyMonHP + ld b, [hl] + inc hl + ld c, [hl] + inc hl + ld d, [hl] + inc hl + ld e, [hl] +; (3 * MaxHP - 2 * CurHP) / (3 * MaxHP) * level + sla c + rl b + ld h, d + ld l, e + add hl, de + add hl, de + ld d, h + ld e, l +; This routine is buggy. The intention is to get de, the Max HP score, +; to be an 8-bit number. To do this, we divide both bc and de by 4. +; It only does this division once, and doesn't check to make sure that +; e is not zero. In addition to passing along a divide-by-zero error, +; this could also cause an unusually small denominator to be passed, +; sending the resulting catch rate through the floor. + ld a, d + and a + jr z, .okay_hp_div + srl d + rr e + srl d + rr e + srl b + rr c + srl b + rr c + ld a, c + and a + jr nz, .okay_hp_div + ld c, $1 +.okay_hp_div + ld b, e + push bc + ld a, b + sub c + ld [hRemainder], a + xor a + ld [hDividend], a + ld [hQuotient], a + ld [hStringCmpString2], a + call Multiply + pop bc + ld a, b + ld [hRemainder], a + ld b, $4 + call Divide + ld a, [hPrintNum4] + 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, $a + jr nz, .add_status + ; ld a, [wEnemyMonStatus] + and a + ld c, $5 + jr nz, .add_status + ld c, $0 +.add_status + ld a, b + add c + jr nc, .max_catch_rate + ld a, $ff +.max_catch_rate + ld d, a + push de + + ; BUG: callba 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 a, [wBattleMonItem] + ; ld b, a + callba GetItemHeldEffect ; d:7e9b + ld a, b + cp HELD_CATCH_CHANCE + pop de + ld a, d + jr nz, .skip_hp_calc + add c + jr nc, .skip_hp_calc + ld a, $ff +.skip_hp_calc + ld b, a + ld [wCurHPAnimMaxHP], a + call Random + cp b + ld a, $0 + jr z, .catch_without_fail + jr nc, .asm_ea23 +.catch_without_fail + ld a, [wEnemyMonSpecies] +.asm_ea23 + ld [wWildMon], a + ld c, 20 + call DelayFrames + ld a, [wd002] + cp POKE_BALL + 1 + jr c, .asm_ea34 + ld a, $5 +.asm_ea34 + ld [wcb67], a + ld de, ANIM_THROW_POKE_BALL + ld a, e + ld [wcf3e], a + ld a, d + ld [wcf3f], a + xor a + ld [hBattleTurn], a + ld [wBuffer2], a + ld [wcf46], a + predef PlayBattleAnim + ld a, [wWildMon] + and a + jr nz, .caught + ld a, [wBuffer2] + cp $1 + ld hl, Text_ThePokemonBrokeFree ; $6e09 + jp z, .break_free + cp $2 + ld hl, Text_AppearedToBeCaught ; $6e0e + jp z, .break_free + cp $3 + ld hl, Text_AarghAlmostHadIt ; $6e13 + jp z, .break_free + cp $4 + ld hl, Text_ShootItWasSoCloseToo ; $6e18 + jp z, .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] + 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, wcbd0 + ld a, [wEnemyMonDVs] + ld [hli], a + ld a, [wEnemyMonMovesEnd + 1] + ld [hl], a +.load_data + ld a, [wTempEnemyMonSpecies] + ld [wCurPartySpecies], a + ld a, [wEnemyMonLevel] + ld [wCurPartyLevel], a + callba 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 [wd004], a + ld [wd151], a + ld a, [wBattleType] + cp BATTLETYPE_TUTORIAL + jp z, .finish_tutorial + ld hl, Text_GotchaMonWasCaught ; $6e1d + call PrintText + call ClearSprites + ld a, [wd151] + dec a + call CheckCaughtMon + ld a, c + push af + ld a, [wd151] + dec a + call SetSeenAndCaughtMon + pop af + and a + jr nz, .skip_dex + call CheckReceivedDex + jr z, .skip_dex + ld hl, Text_MonNewlyAddedToPokedex ; $6e44 + call PrintText + call ClearSprites + ld a, [wEnemyMonSpecies] + ld [wd151], a + predef NewPokedexEntry +.skip_dex + ld a, [wBattleType] + cp BATTLETYPE_CONTEST + jp z, .catch_bug_contest_mon + ld a, [wPartyCount] + cp PARTY_LENGTH + jr z, .send_mon_to_pc + xor a + ld [wMonType], a + call ClearSprites + predef TryAddMonToParty + ld a, [wd002] + cp FRIEND_BALL + jr nz, .skip_party_mon_friend_ball + ld a, [wPartyCount] + dec a + ld hl, wPartyMon1Happiness + ld bc, PARTYMON_STRUCT_LENGTH + call AddNTimes + ld a, FRIEND_BALL_HAPPINESS + ld [hl], a +.skip_party_mon_friend_ball + ld hl, Text_AskNicknameNewlyCaughtMon ; $6e49 + call PrintText + ld a, [wCurPartySpecies] + ld [wd151], a + call GetPokemonName + call YesNoBox + jp c, .end_ball_function + ld a, [wPartyCount] + dec a + ld [wd005], a + ld hl, wPartyMon1Nickname + ld bc, PKMN_NAME_LENGTH + call AddNTimes + ld d, h + ld e, l + push de + xor a + ld [wMonType], a + ld b, $0 + callba NamingScreen + call RotateThreePalettesRight + call Functiond9e + pop hl + ld de, wStringBuffer1 + call InitName + jp .end_ball_function + +.send_mon_to_pc + call ClearSprites + predef SentPkmnIntoBox + ld a, BANK(sBoxCount) + call OpenSRAM + ld a, [sBoxCount] + cp MONS_PER_BOX + jr nz, .not_full_yet + ld hl, wBattleResult + set 7, [hl] +.not_full_yet + ld a, [wd002] + cp FRIEND_BALL + jr nz, .skip_box_mon_friend_ball + ld a, FRIEND_BALL_HAPPINESS + ld [sBoxMon1Happiness], a +.skip_box_mon_friend_ball + call CloseSRAM + ld hl, Text_AskNicknameNewlyCaughtMon ; $6e49 + call PrintText + ld a, [wd004] + ld [wd151], a + call GetPokemonName + call YesNoBox + jr c, .init_name_in_sram + xor a + ld [wd005], a + ld a, $2 + ld [wMonType], a + ld de, wMonOrItemNameBuffer + ld b, $0 + callba NamingScreen + ld a, $1 + call OpenSRAM + ld hl, wMonOrItemNameBuffer + ld de, sBoxMonNicknames + ld bc, PKMN_NAME_LENGTH + call CopyBytes + ld hl, sBoxMonNicknames + ld de, wStringBuffer1 + call InitName + call CloseSRAM +.init_name_in_sram + ld a, $1 + call OpenSRAM + ld hl, sBoxMonNicknames + ld de, wMonOrItemNameBuffer + ld bc, PKMN_NAME_LENGTH + call CopyBytes + call CloseSRAM + ld hl, Text_SentToBillsPC ; $6e3f + call PrintText + call RotateThreePalettesRight + call Functiond9e + jr .end_ball_function + +.catch_bug_contest_mon + callba BugContest_SetCaughtContestMon ; same bank + jr .end_ball_function + +.finish_tutorial + ld hl, Text_GotchaMonWasCaught ; $6e1d +.break_free + call PrintText + call ClearSprites +.end_ball_function + 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 [wd009], a + jp TossItem + +.used_park_ball + ld hl, wParkBalls + dec [hl] + ret + +BallMultiplierFunctionTable: ; ec73 + 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 $ff + +UltraBallMultiplier: + sla b + ret nc + ld b, $ff + ret + +GreatBallMultiplier: +SafariBallMultiplier: +ParkBallMultiplier: + ld a, b + srl a + add b + ld b, a + ret nc + ld b, $ff + ret + +HeavyBallMultiplier: + ld a, [wEnemyMon] + dec a + ld hl, PokedexDataPointerTable + ld e, a + ld d, $0 + add hl, de + add hl, de + rlca + rlca + and $3 + add BANK(PokedexEntries1) ; $68 + ld d, a + ld a, BANK(PokedexDataPointerTable) + call GetFarHalfword +.loop + ld a, d + call GetFarByte + inc hl + cp "@" + jr nz, .loop + ld a, d + push bc + inc hl + inc hl + call GetFarHalfword + srl h + rr l + ld b, h + ld c, l + srl b + rr c + srl b + rr c + srl b + rr c + srl b + rr c + call .sub_bc + srl b + rr c + call .sub_bc + ld a, h + pop bc + jr .compare + +.sub_bc + 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 1024 >> 8 ; 102.4 kg + jr c, .lightmon + ld hl, .WeightsTable ; $6d18 +.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 2048 >> 8, 0 + db 3072 >> 8, 20 + db 4096 >> 8, 30 + db 65280 >> 8, 40 + +LureBallMultiplier: + ld a, [wBattleType] + cp BATTLETYPE_FISH + ret nz + ld a, b + add a + jr c, .asm_ed2d + add b + jr nc, .asm_ed2f +.asm_ed2d + ld a, $ff +.asm_ed2f + 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 ; $67bd + add hl, bc + add hl, bc + ld a, BANK(EvosAttacksPointers) ; $10 + call GetFarHalfword + pop bc + push bc + ld a, BANK(EvosAttacksPointers) ; $10 + 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(EvosAttacksPointers) ; $10 + 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 + ld a, [wTempEnemyMonSpecies] + ld c, a + ld a, [wd0ee] + cp c + ret nz + push bc + ld a, [wd0ee] + ld [wCurPartySpecies], a + xor a + ld [wMonType], a + ld a, [wCurBattleMon] + ld [wd005], a + callba GetGender ; 14:52f1 + jr c, .asm_edba + ld d, $0 + jr nz, .asm_ed8d + inc d +.asm_ed8d + push de + ld a, [wTempEnemyMonSpecies] + ld [wd004], a + ld a, $4 + ld [wMonType], a + callba GetGender ; 14:52f1 + jr c, .asm_edb9 + ld d, $0 + jr nz, .asm_eda6 + inc d +.asm_eda6 + ld a, d + pop de + cp d + pop bc + ret nz ; for the intended effect, this should be “ret z” + sla b + jr c, .asm_edb6 + sla b + jr c, .asm_edb6 + sla b + ret nc +.asm_edb6 + ld b, $ff + ret + +.asm_edb9 + pop de +.asm_edba + 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 +.asm_edc5 + ld a, BANK(FleeMons) + call GetFarByte + inc hl + cp $ff + jr z, .asm_eddc + cp c + jr nz, .asm_eddc ; for the intended effect, this should be “jr nz, .loop” + sla b + jr c, .asm_edd9 + sla b + ret nc +.asm_edd9 + ld b, $ff + ret + +.asm_eddc + dec d + jr nz, .asm_edc5 + 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 + sla b + jr c, .asm_edfc + srl c + cp c + ret nc + sla b + jr c, .asm_edfc + srl c + cp c + ret nc + sla b + ret nc +.asm_edfc + 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_ThisMonCantBeCaught: + text_jump Text_ThisMonCantBeCaught_ + db "@" + +Text_YouMissedThePokemon: + text_jump Text_YouMissedThePokemon_ + db "@" + +Text_ThePokemonBrokeFree: + text_jump Text_ThePokemonBrokeFree_ + db "@" + +Text_AppearedToBeCaught: + text_jump Text_AppearedToBeCaught_ + db "@" + +Text_AarghAlmostHadIt: + text_jump Text_AarghAlmostHadIt_ + db "@" + +Text_ShootItWasSoCloseToo: + text_jump Text_ShootItWasSoCloseToo_ + db "@" + +Text_GotchaMonWasCaught: + text_jump Text_GotchaMonWasCaught_ + start_asm + call WaitSFX + push bc + ld de, MUSIC_NONE + call PlayMusic + call DelayFrame + ld de, MUSIC_CAPTURE + call PlayMusic + pop bc + ld hl, Text_CaughtMonWaitbutton + ret + +Text_CaughtMonWaitbutton: + text_jump Text_CaughtMonWaitbutton_ + db "@" + +Text_SentToBillsPC: + text_jump Text_SentToBillsPC_ + db "@" + +Text_MonNewlyAddedToPokedex: + text_jump Text_MonNewlyAddedToPokedex_ + db "@" + +Text_AskNicknameNewlyCaughtMon: + text_jump Text_AskNicknameNewlyCaughtMon_ + db "@" + +ReturnToBattle_UseBall: ; ee4e (3:6e4e) + callba ReturnToBattle_UseBall_ ; 9:7307 + ret + +IF DEF(GOLD) TownMap: ; ee55 dr $ee55, $ee5c @@ -446,25 +1237,19 @@ Twistedspoon: ; f7c4 UpGrade: ; f7c4 WhtApricorn: ; f7c4 YlwApricorn: ; f7c4 - dr $f7c4, $f900 -ENDC + dr $f7c4, $f7e7 -IF DEF(SILVER) +Functionf7e7: + dr $f7e7, $f823 -FastBall ; e924 -FriendBall ; e924 -GreatBall ; e924 -HeavyBall ; e924 -LevelBall ; e924 -LoveBall ; e924 -LureBall ; e924 -MasterBall ; e924 -MoonBall ; e924 -ParkBall ; e924 -PokeBall ; e924 -UltraBall ; e924 - dr $e924, $ee53 +FailToUseBall: + dr $f823, $f884 + +Text_UsedItem: + dr $f884, $f900 +ENDC +IF DEF(SILVER) TownMap ; ee53 dr $ee53, $ee5a @@ -704,5 +1489,14 @@ Twistedspoon ; f7c2 UpGrade ; f7c2 WhtApricorn ; f7c2 YlwApricorn ; f7c2 - dr $f7c2, $f8fe + dr $f7c2, $f7e5 + +Functionf7e7: + dr $f7e5, $f821 + +FailToUseBall: + dr $f821, $f882 + +Text_UsedItem: + dr $f882, $f8fe ENDC |