diff options
author | luckytyphlosion <alan.rj.huang@gmail.com> | 2015-12-26 16:27:21 -0500 |
---|---|---|
committer | luckytyphlosion <alan.rj.huang@gmail.com> | 2015-12-26 16:27:21 -0500 |
commit | 47979336e29d7e22d524e35ddc50576874ead009 (patch) | |
tree | 91723be28641be80ad475b61b5b40f03e1eab9ae | |
parent | 043e9327650f2ee0053fe43a29c9d63bc5e120d3 (diff) |
Start disassembling bank0F (Battle)
All current findings will be located in engine/battle/core_.asm
-rw-r--r-- | engine/battle/common_text.asm | 4 | ||||
-rwxr-xr-x | engine/battle/core.asm | 60 | ||||
-rw-r--r-- | engine/battle/core_.asm | 685 | ||||
-rwxr-xr-x | engine/battle/end_of_battle.asm | 2 | ||||
-rw-r--r-- | engine/battle/init_battle_variables.asm | 2 | ||||
-rwxr-xr-x | engine/items/items.asm | 12 | ||||
-rw-r--r-- | home.asm | 4 | ||||
-rwxr-xr-x | scripts/viridiancity.asm | 4 | ||||
-rwxr-xr-x | wram.asm | 2 | ||||
-rwxr-xr-x | yellow/main.asm | 95 |
10 files changed, 738 insertions, 132 deletions
diff --git a/engine/battle/common_text.asm b/engine/battle/common_text.asm index 687fbf99..f357f695 100644 --- a/engine/battle/common_text.asm +++ b/engine/battle/common_text.asm @@ -8,7 +8,7 @@ PrintBeginningBattleText: ; f4000 (3d:4000) cp LAVENDER_HOUSE_1 jr c, .pokemonTower .notPokemonTower - ld a,[W_BATTLETYPE] + ld a,[wBattleType] cp $4 ; new battle type? jr nz,.notnewbattletype callab Func_fd0d0 @@ -35,7 +35,7 @@ PrintBeginningBattleText: ; f4000 (3d:4000) call DelayFrames ld hl, TrainerWantsToFightText .wildBattle - ld a, [W_BATTLETYPE] + ld a, [wBattleType] and a jr nz, .doNotDrawPokeballs push hl diff --git a/engine/battle/core.asm b/engine/battle/core.asm index 6066d7ee..e6c5b3c1 100755 --- a/engine/battle/core.asm +++ b/engine/battle/core.asm @@ -157,6 +157,9 @@ SlidePlayerAndEnemySilhouettesOnScreen: ; 3c04c (f:404c) ld [rBGP], a ld [rOBP0], a ld [rOBP1], a + call UpdateGBCPal_BGP + call UpdateGBCPal_OBP0 + call UpdateGBCPal_OBP1 .slideSilhouettesLoop ; slide silhouettes of the player's pic and the enemy's pic onto the screen ld h, b ld l, $40 @@ -193,7 +196,7 @@ SlidePlayerAndEnemySilhouettesOnScreen: ; 3c04c (f:404c) ; the lower of the player's pic (his body) is part of the background, but his head is a sprite ; the reason for this is that it shares Y coordinates with the lower part of the enemy pic, so background scrolling wouldn't work for both pics ; instead, the enemy pic is part of the background and uses the scroll register, while the player's head is a sprite and is slid by changing its X coordinates in a loop -SlidePlayerHeadLeft: ; 3c0ff (f:40ff) +SlidePlayerHeadLeft: ; 3c108 (f:4108) push bc ld hl, wOAMBuffer + $01 ld c, $15 ; number of OAM entries @@ -207,7 +210,7 @@ SlidePlayerHeadLeft: ; 3c0ff (f:40ff) pop bc ret -SetScrollXForSlidingPlayerBodyLeft: ; 3c110 (f:4110) +SetScrollXForSlidingPlayerBodyLeft: ; 3c119 (f:4119) ld a, [rLY] cp l jr nz, SetScrollXForSlidingPlayerBodyLeft @@ -219,7 +222,7 @@ SetScrollXForSlidingPlayerBodyLeft: ; 3c110 (f:4110) jr z, .loop ret -StartBattle: ; 3c11e (f:411e) +StartBattle: ; 3c127 (f:4127) xor a ld [wPartyGainExpFlags], a ld [wPartyFoughtCurrentEnemyFlags], a @@ -246,12 +249,17 @@ StartBattle: ; 3c11e (f:411e) call DelayFrames call SaveScreenTilesToBuffer1 .checkAnyPartyAlive + ld a, [wBattleType] + cp $3 + jp z, .specialBattle + cp $4 + jp z, .specialBattle call AnyPartyAlive ld a, d and a jp z, HandlePlayerBlackOut ; jump if no mon is alive call LoadScreenTilesFromBuffer1 - ld a, [W_BATTLETYPE] + ld a, [wBattleType] and a ; is it a normal battle? jp z, .playerSendOutFirstMon ; if so, send out player mon ; safari zone battle @@ -341,7 +349,7 @@ StartBattle: ; 3c11e (f:411e) jr MainInBattleLoop ; wild mon or link battle enemy ran from battle -EnemyRan: ; 3c202 (f:4202) +EnemyRan: ; 3c202 (f:4218) call LoadScreenTilesFromBuffer1 ld a, [wLinkState] cp LINK_STATE_BATTLING @@ -359,15 +367,15 @@ EnemyRan: ; 3c202 (f:4202) ld [H_WHOSETURN], a jpab AnimationSlideEnemyMonOff -WildRanText: ; 3c229 (f:4229) +WildRanText: ; 3c23f (f:423f) TX_FAR _WildRanText db "@" -EnemyRanText: ; 3c22e (f:422e) +EnemyRanText: ; 3c23f (f:423f) TX_FAR _EnemyRanText db "@" -MainInBattleLoop: ; 3c233 (f:4233) +MainInBattleLoop: ; 3c249 (f:4249) call ReadPlayerMonCurHPAndStatus ld hl, wBattleMonHP ld a, [hli] @@ -443,7 +451,7 @@ MainInBattleLoop: ; 3c233 (f:4233) ; the link battle enemy has switched mons ld a, [wPlayerBattleStatus1] bit UsingTrappingMove, a ; check if using multi-turn move like Wrap - jr z, .asm_3c2dd + jr z, .specialMoveNotUsed ld a, [wPlayerMoveListIndex] ld hl, wBattleMonMoves ld c, a @@ -452,9 +460,9 @@ MainInBattleLoop: ; 3c233 (f:4233) ld a, [hl] cp METRONOME ; a MIRROR MOVE check is missing, might lead to a desync in link battles ; when combined with multi-turn moves - jr nz, .asm_3c2dd + jr nz, .specialMoveNotUsed ld [wPlayerSelectedMove], a -.asm_3c2dd +.specialMoveNotUsed callab SwitchEnemyMon .noLinkBattle ld a, [wPlayerSelectedMove] @@ -1583,7 +1591,7 @@ NoWillText: ; 3cab4 (f:4ab4) TryRunningFromBattle: ; 3cab9 (f:4ab9) call IsGhostBattle jp z, .canEscape ; jump if it's a ghost battle - ld a, [W_BATTLETYPE] + ld a, [wBattleType] cp $2 jp z, .canEscape ; jump if it's a safari battle ld a, [wLinkState] @@ -2086,14 +2094,14 @@ CenterMonName: ; 3ce9c (f:4e9c) DisplayBattleMenu: ; 3ceb3 (f:4eb3) call LoadScreenTilesFromBuffer1 ; restore saved screen - ld a, [W_BATTLETYPE] + ld a, [wBattleType] and a jr nz, .nonstandardbattle call DrawHUDsAndHPBars call PrintEmptyString call SaveScreenTilesToBuffer1 .nonstandardbattle - ld a, [W_BATTLETYPE] + ld a, [wBattleType] cp $2 ; safari ld a, BATTLE_MENU_TEMPLATE jr nz, .menuselected @@ -2101,7 +2109,7 @@ DisplayBattleMenu: ; 3ceb3 (f:4eb3) .menuselected ld [wTextBoxID], a call DisplayTextBoxID - ld a, [W_BATTLETYPE] + ld a, [wBattleType] dec a jp nz, .handleBattleMenuInput ; handle menu input if it's not the old man tutorial ; the following happens for the old man tutorial @@ -2143,7 +2151,7 @@ DisplayBattleMenu: ; 3ceb3 (f:4eb3) ld [wLastMenuItem], a jr .rightColumn .leftColumn ; put cursor in left column of menu - ld a, [W_BATTLETYPE] + ld a, [wBattleType] cp $2 ld a, " " jr z, .safariLeftColumn @@ -2176,7 +2184,7 @@ DisplayBattleMenu: ; 3ceb3 (f:4eb3) jr nz, .rightColumn jr .AButtonPressed ; the A button was pressed .rightColumn ; put cursor in right column of menu - ld a, [W_BATTLETYPE] + ld a, [wBattleType] cp $2 ld a, " " jr z, .safariRightColumn @@ -2213,7 +2221,7 @@ DisplayBattleMenu: ; 3ceb3 (f:4eb3) ld [wCurrentMenuItem], a .AButtonPressed call PlaceUnfilledArrowMenuCursor - ld a, [W_BATTLETYPE] + ld a, [wBattleType] cp $2 ; is it a Safari battle? ld a, [wCurrentMenuItem] ld [wBattleAndStartSavedMenuItem], a @@ -2235,7 +2243,7 @@ DisplayBattleMenu: ; 3ceb3 (f:4eb3) and a jr nz, .upperLeftMenuItemWasNotSelected ; the upper left menu item was selected - ld a, [W_BATTLETYPE] + ld a, [wBattleType] cp $2 jr z, .throwSafariBallWasSelected ; the "FIGHT" menu was selected @@ -2263,7 +2271,7 @@ DisplayBattleMenu: ; 3ceb3 (f:4eb3) .notLinkBattle call SaveScreenTilesToBuffer2 - ld a, [W_BATTLETYPE] + ld a, [wBattleType] cp $2 ; is it a safari battle? jr nz, BagWasSelected @@ -2274,14 +2282,14 @@ DisplayBattleMenu: ; 3ceb3 (f:4eb3) BagWasSelected: call LoadScreenTilesFromBuffer1 - ld a, [W_BATTLETYPE] + ld a, [wBattleType] and a ; is it a normal battle? jr nz, .next ; normal battle call DrawHUDsAndHPBars .next - ld a, [W_BATTLETYPE] + ld a, [wBattleType] dec a ; is it the old man tutorial? jr nz, DisplayPlayerBag ; no, it is a normal battle ld hl, OldManItemList @@ -2332,7 +2340,7 @@ UseBagItem: call ClearSprites xor a ld [wCurrentMenuItem], a - ld a, [W_BATTLETYPE] + ld a, [wBattleType] cp $2 ; is it a safari battle? jr z, .checkIfMonCaptured @@ -2354,7 +2362,7 @@ UseBagItem: and a ; was the enemy mon captured with a ball? jr nz, .returnAfterCapturingMon - ld a, [W_BATTLETYPE] + ld a, [wBattleType] cp $2 ; is it a safari battle? jr z, .returnAfterUsingItem_NoCapture ; not a safari battle @@ -2385,7 +2393,7 @@ PartyMenuOrRockOrRun: jp nz, BattleMenu_RunWasSelected ; party menu or rock was selected call SaveScreenTilesToBuffer2 - ld a, [W_BATTLETYPE] + ld a, [wBattleType] cp $2 ; is it a safari battle? jr nz, .partyMenuWasSelected ; safari battle @@ -6406,7 +6414,7 @@ SwapPlayerAndEnemyLevels: ; 3ec81 (f:6c81) ; also writes OAM data and loads tile patterns for the Red or Old Man back sprite's head ; (for use when scrolling the player sprite and enemy's silhouettes on screen) LoadPlayerBackPic: ; 3ec92 (f:6c92) - ld a, [W_BATTLETYPE] + ld a, [wBattleType] dec a ; is it the old man tutorial? ld de, RedPicBack jr nz, .next diff --git a/engine/battle/core_.asm b/engine/battle/core_.asm new file mode 100644 index 00000000..45f231df --- /dev/null +++ b/engine/battle/core_.asm @@ -0,0 +1,685 @@ +BattleCore: + +; These are move effects (second value from the Moves table in bank $E). +ResidualEffects1: ; 3c000 (f:4000) +; most non-side effects + db CONVERSION_EFFECT + db HAZE_EFFECT + db SWITCH_AND_TELEPORT_EFFECT + db MIST_EFFECT + db FOCUS_ENERGY_EFFECT + db CONFUSION_EFFECT + db HEAL_EFFECT + db TRANSFORM_EFFECT + db LIGHT_SCREEN_EFFECT + db REFLECT_EFFECT + db POISON_EFFECT + db PARALYZE_EFFECT + db SUBSTITUTE_EFFECT + db MIMIC_EFFECT + db LEECH_SEED_EFFECT + db SPLASH_EFFECT + db -1 +SetDamageEffects: ; 3c011 (f:4011) +; moves that do damage but not through normal calculations +; e.g., Super Fang, Psywave + db SUPER_FANG_EFFECT + db SPECIAL_DAMAGE_EFFECT + db -1 +ResidualEffects2: ; 3c014 (f:4014) +; non-side effects not included in ResidualEffects1 +; stat-affecting moves, sleep-inflicting moves, and Bide +; e.g., Meditate, Bide, Hypnosis + db $01 + db ATTACK_UP1_EFFECT + db DEFENSE_UP1_EFFECT + db SPEED_UP1_EFFECT + db SPECIAL_UP1_EFFECT + db ACCURACY_UP1_EFFECT + db EVASION_UP1_EFFECT + db ATTACK_DOWN1_EFFECT + db DEFENSE_DOWN1_EFFECT + db SPEED_DOWN1_EFFECT + db SPECIAL_DOWN1_EFFECT + db ACCURACY_DOWN1_EFFECT + db EVASION_DOWN1_EFFECT + db BIDE_EFFECT + db SLEEP_EFFECT + db ATTACK_UP2_EFFECT + db DEFENSE_UP2_EFFECT + db SPEED_UP2_EFFECT + db SPECIAL_UP2_EFFECT + db ACCURACY_UP2_EFFECT + db EVASION_UP2_EFFECT + db ATTACK_DOWN2_EFFECT + db DEFENSE_DOWN2_EFFECT + db SPEED_DOWN2_EFFECT + db SPECIAL_DOWN2_EFFECT + db ACCURACY_DOWN2_EFFECT + db EVASION_DOWN2_EFFECT + db -1 +AlwaysHappenSideEffects: ; 3c030 (f:4030) +; Attacks that aren't finished after they faint the opponent. + db DRAIN_HP_EFFECT + db EXPLODE_EFFECT + db DREAM_EATER_EFFECT + db PAY_DAY_EFFECT + db TWO_TO_FIVE_ATTACKS_EFFECT + db $1E + db ATTACK_TWICE_EFFECT + db RECOIL_EFFECT + db TWINEEDLE_EFFECT + db RAGE_EFFECT + db -1 +SpecialEffects: ; 3c03b (f:403b) +; Effects from arrays 2, 4, and 5B, minus Twineedle and Rage. +; Includes all effects that do not need to be called at the end of +; ExecutePlayerMove (or ExecuteEnemyMove), because they have already been handled + db DRAIN_HP_EFFECT + db EXPLODE_EFFECT + db DREAM_EATER_EFFECT + db PAY_DAY_EFFECT + db SWIFT_EFFECT + db TWO_TO_FIVE_ATTACKS_EFFECT + db $1E + db CHARGE_EFFECT + db SUPER_FANG_EFFECT + db SPECIAL_DAMAGE_EFFECT + db FLY_EFFECT + db ATTACK_TWICE_EFFECT + db JUMP_KICK_EFFECT + db RECOIL_EFFECT + ; fallthrough to Next EffectsArray +SpecialEffectsCont: ; 3c049 (f:4049) +; damaging moves whose effect is executed prior to damage calculation + db THRASH_PETAL_DANCE_EFFECT + db TRAPPING_EFFECT + db -1 + +SlidePlayerAndEnemySilhouettesOnScreen: ; 3c04c (f:404c) + call LoadPlayerBackPic + ld a, MESSAGE_BOX ; the usual text box at the bottom of the screen + ld [wTextBoxID], a + call DisplayTextBoxID + coord hl, 1, 5 + lb bc, 3, 7 + call ClearScreenArea + call DisableLCD + call LoadFontTilePatterns + call LoadHudAndHpBarAndStatusTilePatterns + ld hl, vBGMap0 + ld bc, $400 +.clearBackgroundLoop + ld a, " " + ld [hli], a + dec bc + ld a, b + or c + jr nz, .clearBackgroundLoop +; copy the work RAM tile map to VRAM + coord hl, 0, 0 + ld de, vBGMap0 + ld b, 18 ; number of rows +.copyRowLoop + ld c, 20 ; number of columns +.copyColumnLoop + ld a, [hli] + ld [de], a + inc e + dec c + jr nz, .copyColumnLoop + ld a, 12 ; number of off screen tiles to the right of screen in VRAM + add e ; skip the off screen tiles + ld e, a + jr nc, .noCarry + inc d +.noCarry + dec b + jr nz, .copyRowLoop + call EnableLCD + ld a, $90 + ld [hWY], a + ld [rWY], a + xor a + ld [hTilesetType], a + ld [hSCY], a + dec a + ld [wUpdateSpritesEnabled], a + call Delay3 + xor a + ld [H_AUTOBGTRANSFERENABLED], a + ld b, $70 + ld c, $90 + ld a, c + ld [hSCX], a + call DelayFrame + ld a, %11100100 ; inverted palette for silhouette effect + ld [rBGP], a + ld [rOBP0], a + ld [rOBP1], a + call UpdateGBCPal_BGP + call UpdateGBCPal_OBP0 + call UpdateGBCPal_OBP1 +.slideSilhouettesLoop ; slide silhouettes of the player's pic and the enemy's pic onto the screen + ld h, b + ld l, $40 + call SetScrollXForSlidingPlayerBodyLeft ; begin background scrolling on line $40 + inc b + inc b + ld h, $0 + ld l, $60 + call SetScrollXForSlidingPlayerBodyLeft ; end background scrolling on line $60 + call SlidePlayerHeadLeft + ld a, c + ld [hSCX], a + dec c + dec c + jr nz, .slideSilhouettesLoop + ld a, $1 + ld [H_AUTOBGTRANSFERENABLED], a + ld a, $31 + ld [hStartTileID], a + coord hl, 1, 5 + predef CopyUncompressedPicToTilemap + xor a + ld [hWY], a + ld [rWY], a + inc a + ld [H_AUTOBGTRANSFERENABLED], a + call Delay3 + ld b, SET_PAL_BATTLE + call RunPaletteCommand + call HideSprites + jpab PrintBeginningBattleText + +; when a battle is starting, silhouettes of the player's pic and the enemy's pic are slid onto the screen +; the lower of the player's pic (his body) is part of the background, but his head is a sprite +; the reason for this is that it shares Y coordinates with the lower part of the enemy pic, so background scrolling wouldn't work for both pics +; instead, the enemy pic is part of the background and uses the scroll register, while the player's head is a sprite and is slid by changing its X coordinates in a loop +SlidePlayerHeadLeft: ; 3c108 (f:4108) + push bc + ld hl, wOAMBuffer + $01 + ld c, $15 ; number of OAM entries + ld de, $4 ; size of OAM entry +.loop + dec [hl] ; decrement X + dec [hl] ; decrement X + add hl, de ; next OAM entry + dec c + jr nz, .loop + pop bc + ret + +SetScrollXForSlidingPlayerBodyLeft: ; 3c119 (f:4119) + ld a, [rLY] + cp l + jr nz, SetScrollXForSlidingPlayerBodyLeft + ld a, h + ld [rSCX], a +.loop + ld a, [rLY] + cp h + jr z, .loop + ret + +StartBattle: ; 3c127 (f:4127) + xor a + ld [wPartyGainExpFlags], a + ld [wPartyFoughtCurrentEnemyFlags], a + ld [wActionResultOrTookBattleTurn], a + inc a + ld [wFirstMonsNotOutYet], a + ld hl, wEnemyMon1HP + ld bc, wEnemyMon2 - wEnemyMon1 - 1 + ld d, $3 +.findFirstAliveEnemyMonLoop + inc d + ld a, [hli] + or [hl] + jr nz, .foundFirstAliveEnemyMon + add hl, bc + jr .findFirstAliveEnemyMonLoop +.foundFirstAliveEnemyMon + ld a, d + ld [wSerialExchangeNybbleReceiveData], a + ld a, [wIsInBattle] + dec a ; is it a trainer battle? + call nz, EnemySendOutFirstMon ; if it is a trainer battle, send out enemy mon + ld c, 40 + call DelayFrames + call SaveScreenTilesToBuffer1 +.checkAnyPartyAlive + ld a, [wBattleType] + cp $3 + jp z, .specialBattle + cp $4 + jp z, .specialBattle + call AnyPartyAlive + ld a, d + and a + jp z, HandlePlayerBlackOut ; jump if no mon is alive +.specialBattle + call LoadScreenTilesFromBuffer1 + ld a, [wBattleType] + and a ; is it a normal battle? + jp z, .playerSendOutFirstMon ; if so, send out player mon +; safari zone battle +.displaySafariZoneBattleMenu + call DisplayBattleMenu + ret c ; return if the player ran from battle + ld a, [wActionResultOrTookBattleTurn] + and a ; was the item used successfully? + jr z, .displaySafariZoneBattleMenu ; if not, display the menu again; XXX does this ever jump? + ld a, [wNumSafariBalls] + and a + jr nz, .notOutOfSafariBalls + call LoadScreenTilesFromBuffer1 + ld hl, .outOfSafariBallsText + jp PrintText +.notOutOfSafariBalls + callab PrintSafariZoneBattleText + ld a, [wEnemyMonSpeed + 1] + add a + ld b, a ; init b (which is later compared with random value) to (enemy speed % 256) * 2 + jp c, EnemyRan ; if (enemy speed % 256) > 127, the enemy runs + ld a, [wSafariBaitFactor] + and a ; is bait factor 0? + jr z, .checkEscapeFactor +; bait factor is not 0 +; divide b by 4 (making the mon less likely to run) + srl b + srl b +.checkEscapeFactor + ld a, [wSafariEscapeFactor] + and a ; is escape factor 0? + jr z, .compareWithRandomValue +; escape factor is not 0 +; multiply b by 2 (making the mon more likely to run) + sla b + jr nc, .compareWithRandomValue +; cap b at 255 + ld b, $ff +.compareWithRandomValue + call Random + cp b + jr nc, .checkAnyPartyAlive + jr EnemyRan ; if b was greater than the random value, the enemy runs + +.outOfSafariBallsText + TX_FAR _OutOfSafariBallsText + db "@" + +.playerSendOutFirstMon + xor a + ld [wWhichPokemon], a +.findFirstAliveMonLoop + call HasMonFainted + jr nz, .foundFirstAliveMon +; fainted, go to the next one + ld hl, wWhichPokemon + inc [hl] + jr .findFirstAliveMonLoop +.foundFirstAliveMon + ld a, [wWhichPokemon] + ld [wPlayerMonNumber], a + inc a + ld hl, wPartySpecies - 1 + ld c, a + ld b, 0 + add hl, bc + ld a, [hl] ; species + ld [wcf91], a + ld [wBattleMonSpecies2], a + call LoadScreenTilesFromBuffer1 + coord hl, 1, 5 + ld a, $9 + call SlideTrainerPicOffScreen + call SaveScreenTilesToBuffer1 + ld a, [wWhichPokemon] + ld c, a + ld b, FLAG_SET + push bc + ld hl, wPartyGainExpFlags + predef FlagActionPredef + ld hl, wPartyFoughtCurrentEnemyFlags + pop bc + predef FlagActionPredef + call LoadBattleMonFromParty + call LoadScreenTilesFromBuffer1 + call SendOutMon + jr MainInBattleLoop + +; wild mon or link battle enemy ran from battle +EnemyRan: ; 3c202 (f:4218) + call LoadScreenTilesFromBuffer1 + ld a, [wLinkState] + cp LINK_STATE_BATTLING + ld hl, WildRanText + jr nz, .printText +; link battle + xor a + ld [wBattleResult], a + ld hl, EnemyRanText +.printText + call PrintText + ld a, SFX_RUN + call PlaySoundWaitForCurrent + xor a + ld [H_WHOSETURN], a + jpab AnimationSlideEnemyMonOff + +WildRanText: ; 3c23f (f:423f) + TX_FAR _WildRanText + db "@" + +EnemyRanText: ; 3c23f (f:423f) + TX_FAR _EnemyRanText + db "@" + +MainInBattleLoop: ; 3c249 (f:4249) + call ReadPlayerMonCurHPAndStatus + ld hl, wBattleMonHP + ld a, [hli] + or [hl] ; is battle mon HP 0? + jp z, HandlePlayerMonFainted ; if battle mon HP is 0, jump + ld hl, wEnemyMonHP + ld a, [hli] + or [hl] ; is enemy mon HP 0? + jp z, HandleEnemyMonFainted ; if enemy mon HP is 0, jump + call SaveScreenTilesToBuffer1 + xor a + ld [wFirstMonsNotOutYet], a + ld a, [wPlayerBattleStatus2] + and (1 << NeedsToRecharge) | (1 << UsingRage) ; check if the player is using Rage or needs to recharge + jr nz, .selectEnemyMove +; the player is not using Rage and doesn't need to recharge + ld hl, wEnemyBattleStatus1 + res Flinched, [hl] ; reset flinch bit + ld hl, wPlayerBattleStatus1 + res Flinched, [hl] ; reset flinch bit + ld a, [hl] + and (1 << ThrashingAbout) | (1 << ChargingUp) ; check if the player is thrashing about or charging for an attack + jr nz, .selectEnemyMove ; if so, jump +; the player is neither thrashing about nor charging for an attack + call DisplayBattleMenu ; show battle menu + ret c ; return if player ran from battle + ld a, [wEscapedFromBattle] + and a + ret nz ; return if pokedoll was used to escape from battle + ld a, [wBattleMonStatus] + and (1 << FRZ) | SLP ; is mon frozen or asleep? + jr nz, .selectEnemyMove ; if so, jump + ld a, [wPlayerBattleStatus1] + and (1 << StoringEnergy) | (1 << UsingTrappingMove) ; check player is using Bide or using a multi-turn attack like wrap + jr nz, .selectEnemyMove ; if so, jump + ld a, [wEnemyBattleStatus1] + bit UsingTrappingMove, a ; check if enemy is using a multi-turn attack like wrap + jr z, .selectPlayerMove ; if not, jump +; enemy is using a mult-turn attack like wrap, so player is trapped and cannot execute a move + ld a, $ff + ld [wPlayerSelectedMove], a + jr .selectEnemyMove +.selectPlayerMove + ld a, [wActionResultOrTookBattleTurn] + and a ; has the player already used the turn (e.g. by using an item, trying to run or switching pokemon) + jr nz, .selectEnemyMove + ld [wMoveMenuType], a + inc a + ld [W_ANIMATIONID], a + xor a + ld [wMenuItemToSwap], a + call MoveSelectionMenu + push af + call LoadScreenTilesFromBuffer1 + call DrawHUDsAndHPBars + pop af + jr nz, MainInBattleLoop ; if the player didn't select a move, jump +.selectEnemyMove + call SelectEnemyMove + ld a, [wLinkState] + cp LINK_STATE_BATTLING + jr nz, .noLinkBattle +; link battle + ld a, [wSerialExchangeNybbleReceiveData] + cp $f + jp z, EnemyRan + cp $e + jr z, .noLinkBattle + cp $d + jr z, .noLinkBattle + sub $4 + jr c, .noLinkBattle +; the link battle enemy has switched mons + ld a, [wPlayerBattleStatus1] + bit UsingTrappingMove, a ; check if using multi-turn move like Wrap + jr z, .specialMoveNotUsed + ld a, [wPlayerMoveListIndex] + ld hl, wBattleMonMoves + ld c, a + ld b, 0 + add hl, bc + ld a, [hl] + cp METRONOME ; a MIRROR MOVE check is missing, might lead to a desync in link battles + ; when combined with multi-turn moves + jr nz, .specialMoveNotUsed + ld [wPlayerSelectedMove], a +.specialMoveNotUsed + callab SwitchEnemyMon +.noLinkBattle + ld a, [wPlayerSelectedMove] + cp QUICK_ATTACK + jr nz, .playerDidNotUseQuickAttack + ld a, [wEnemySelectedMove] + cp QUICK_ATTACK + jr z, .compareSpeed ; if both used Quick Attack + jp .playerMovesFirst ; if player used Quick Attack and enemy didn't +.playerDidNotUseQuickAttack + ld a, [wEnemySelectedMove] + cp QUICK_ATTACK + jr z, .enemyMovesFirst ; if enemy used Quick Attack and player didn't + ld a, [wPlayerSelectedMove] + cp COUNTER + jr nz, .playerDidNotUseCounter + ld a, [wEnemySelectedMove] + cp COUNTER + jr z, .compareSpeed ; if both used Counter + jr .enemyMovesFirst ; if player used Counter and enemy didn't +.playerDidNotUseCounter + ld a, [wEnemySelectedMove] + cp COUNTER + jr z, .playerMovesFirst ; if enemy used Counter and player didn't +.compareSpeed + ld de, wBattleMonSpeed ; player speed value + ld hl, wEnemyMonSpeed ; enemy speed value + ld c, $2 + call StringCmp ; compare speed values + jr z, .speedEqual + jr nc, .playerMovesFirst ; if player is faster + jr .enemyMovesFirst ; if enemy is faster +.speedEqual ; 50/50 chance for both players + ld a, [$ffaa] + cp $2 + jr z, .invertOutcome + call BattleRandom + cp $80 + jr c, .playerMovesFirst + jr .enemyMovesFirst +.invertOutcome + call BattleRandom + cp $80 + jr c, .enemyMovesFirst + jr .playerMovesFirst +.enemyMovesFirst + ld a, $1 + ld [H_WHOSETURN], a + callab TrainerAI + jr c, .AIActionUsedEnemyFirst + call ExecuteEnemyMove + ld a, [wEscapedFromBattle] + and a ; was Teleport, Road, or Whirlwind used to escape from battle? + ret nz ; if so, return + ld a, b + and a + jp z, HandlePlayerMonFainted +.AIActionUsedEnemyFirst + call HandlePoisonBurnLeechSeed + jp z, HandleEnemyMonFainted + call DrawHUDsAndHPBars + call ExecutePlayerMove + ld a, [wEscapedFromBattle] + and a ; was Teleport, Road, or Whirlwind used to escape from battle? + ret nz ; if so, return + ld a, b + and a + jp z, HandleEnemyMonFainted + call HandlePoisonBurnLeechSeed + jp z, HandlePlayerMonFainted + call DrawHUDsAndHPBars + call CheckNumAttacksLeft + jp MainInBattleLoop +.playerMovesFirst + call ExecutePlayerMove + ld a, [wEscapedFromBattle] + and a ; was Teleport, Road, or Whirlwind used to escape from battle? + ret nz ; if so, return + ld a, b + and a + jp z, HandleEnemyMonFainted + call HandlePoisonBurnLeechSeed + jp z, HandlePlayerMonFainted + call DrawHUDsAndHPBars + ld a, $1 + ld [H_WHOSETURN], a + callab TrainerAI + jr c, .AIActionUsedPlayerFirst + call ExecuteEnemyMove + ld a, [wEscapedFromBattle] + and a ; was Teleport, Road, or Whirlwind used to escape from battle? + ret nz ; if so, return + ld a, b + and a + jp z, HandlePlayerMonFainted +.AIActionUsedPlayerFirst + call HandlePoisonBurnLeechSeed + jp z, HandleEnemyMonFainted + call DrawHUDsAndHPBars + call CheckNumAttacksLeft + jp MainInBattleLoop + +HandlePoisonBurnLeechSeed: ; 3c3d3 (f:43d3) + dr $3c3d3,$3c525 +CheckNumAttacksLeft: ; 3c525 (f:4525) + dr $3c525,$3c53b +HandleEnemyMonFainted: ; 3c53b (f:453b) + dr $3c53b,$3c71d +HandlePlayerMonFainted: ; 3c71d (f:471d) + dr $3c71d,$3c89c +HandlePlayerBlackOut: ; 3c89c (f:489c) + dr $3c89c,$3c944 +SlideTrainerPicOffScreen: ; 3c944 (f:4944) + dr $3c944,$3c973 +EnemySendOut: ; 3c973 (f:4973) + dr $3c973,$3c98f +EnemySendOutFirstMon: ; 3c98f (f:498f) + dr $3c98f,$3cae8 +AnyPartyAlive: ; 3cae8 (f:4ae8) + dr $3cae8,$3cafc +HasMonFainted: ; 3cafc (f:4afc) + dr $3cafc,$3cc10 +LoadBattleMonFromParty: ; 3cc10 (f:4c10) + dr $3cc10,$3ccfb +SendOutMon: ; 3ccfb (f:4cfb) + dr $3ccfb,$3ce08 +ReadPlayerMonCurHPAndStatus: ; 3ce08 (f:4e08) + dr $3ce08,$3ce1f +DrawHUDsAndHPBars: ; 3ce1f (f:4e1f) + dr $3ce1f,$3ceb1 +DrawEnemyHUDAndHPBar: ; 3ceb1 (f:4eb1) + dr $3ceb1,$3cf78 +DisplayBattleMenu: ; 3cf78 (f:4f78) + dr $3cf78,$3d320 +MoveSelectionMenu: ; 3d320 (f:5320) + dr $3d320,$3d6d6 +SelectEnemyMove: ; 3d6d6 (f:56d6) + dr $3d6d6,$3d7d0 +ExecutePlayerMove: ; 3d7d0 (f:57d0) + dr $3d7d0,$3d9ac +IsGhostBattle: ; 3d9ac (f:59ac) + dr $3d9ac,$3ddc3 +PrintDoesntAffectText: ; 3ddc3 (f:5dc3) + dr $3ddc3,$3e5bb + +AIGetTypeEffectiveness: ; 3e5bb (f:65bb) + ld a,[wEnemyMoveType] + ld d,a ; d = type of enemy move + ld hl,wBattleMonType + ld b,[hl] ; b = type 1 of player's pokemon + inc hl + ld c,[hl] ; c = type 2 of player's pokemon + ld a,$10 + ld [wd11e],a ; initialize [wd11e] to neutral effectiveness + ld hl,TypeEffects +.loop + ld a,[hli] + cp a,$ff + ret z + cp d ; match the type of the move + jr nz,.nextTypePair1 + ld a,[hli] + cp b ; match with type 1 of pokemon + jr z,.done + cp c ; or match with type 2 of pokemon + jr z,.done + jr .nextTypePair2 +.nextTypePair1 + inc hl +.nextTypePair2 + inc hl + jr .loop + +.done + ld a, [wTrainerClass] + cp LORELEI + jr nz, .ok + ld a, [wEnemyMonSpecies] + cp DEWGONG + jr nz, .ok + call BattleRandom + cp $66 ; 40 percent + ret c +.ok + + ld a,[hl] + ld [wd11e],a ; store damage multiplier + ret + +INCLUDE "data/type_effects.asm" + +MoveHitTest: ; 3e6f1 (f:66f1) + dr $3e6f1,$3e842 +ExecuteEnemyMove: ; 3e842 (f:6842) + dr $3e842,$3ec87 +LoadEnemyMonData: ; 3ec87 (f:6c87) + dr $3ec87,$3edb8 +DoBattleTransitionAndInitBattleVariables: ; 3edb8 (f:6db8) + dr $3edb8,$3ee18 +LoadPlayerBackPic: ; 3ee18 (f:6e18) + dr $3ee18,$3eeb3 +QuarterSpeedDueToParalysis: ; 3eeb3 (f:6eb3) + dr $3eeb3,$3efe4 +LoadHudAndHpBarAndStatusTilePatterns: ; 3efe4 (f:6fe4) + dr $3efe4,$3efe7 +LoadHudTilePatterns: ; 3efe7 (f:6fe7) + dr $3efe7,$3f027 +BattleRandom: ; 3f027 (f:7027) + dr $3f027,$3f3de +StatModifierUpEffect: ; 3f3de (f:73de) + dr $3f3de,$3fb2e +PrintButItFailedText_: ; 3fb2e (f:7b2e) + dr $3fb2e,$3fb39 +PrintDidntAffectText: ; 3fb39 (f:7b39) + dr $3fb39,$3fb49 +PrintMayNotAttackText: ; 3fb49 (f:7b49) + dr $3fb49,$3fb83 +PlayCurrentMoveAnimation: ; 3fb83 (f:7b83) + dr $3fb83,$40000
\ No newline at end of file diff --git a/engine/battle/end_of_battle.asm b/engine/battle/end_of_battle.asm index 5760889b..53a68b64 100755 --- a/engine/battle/end_of_battle.asm +++ b/engine/battle/end_of_battle.asm @@ -52,7 +52,7 @@ EndOfBattle: ; 13765 (4:7765) ld [wLowHealthAlarm], a ;disable low health alarm ld [wChannelSoundIDs + CH4], a ld [wIsInBattle], a - ld [W_BATTLETYPE], a + ld [wBattleType], a ld [wMoveMissed], a ld [wCurOpponent], a ld [wForcePlayerToChooseMon], a diff --git a/engine/battle/init_battle_variables.asm b/engine/battle/init_battle_variables.asm index 5383a546..8c43e8f8 100644 --- a/engine/battle/init_battle_variables.asm +++ b/engine/battle/init_battle_variables.asm @@ -33,6 +33,6 @@ InitBattleVariables: ; f6236 (3d:6236) cp SAFARI_ZONE_REST_HOUSE_1 jr nc, .notSafariBattle ld a, $2 ; safari battle - ld [W_BATTLETYPE], a + ld [wBattleType], a .notSafariBattle jpab PlayBattleMusic diff --git a/engine/items/items.asm b/engine/items/items.asm index 1b1f7d7a..4ff01eff 100755 --- a/engine/items/items.asm +++ b/engine/items/items.asm @@ -106,7 +106,7 @@ ItemUseBall: ; d3ad (3:53ad) jp z,ItemUseNotTime ; not in battle dec a jp nz,ThrowBallAtTrainerMon - ld a,[W_BATTLETYPE] + ld a,[wBattleType] cp $1 jr z,.UseBall cp $4 ; pikachu battle? @@ -121,7 +121,7 @@ ItemUseBall: ; d3ad (3:53ad) ;ok, you can use a ball xor a ld [wCapturedMonSpecies],a - ld a,[W_BATTLETYPE] + ld a,[wBattleType] cp a,2 ;SafariBattle jr nz,.skipSafariZoneCode .safariZone @@ -138,7 +138,7 @@ ItemUseBall: ; d3ad (3:53ad) callab IsGhostBattle ld b,$10 jp z,.next12 - ld a,[W_BATTLETYPE] + ld a,[wBattleType] cp $1 jr z,.oldManBattle cp $4 @@ -149,7 +149,7 @@ ItemUseBall: ; d3ad (3:53ad) ld de,wPlayerName ld bc,NAME_LENGTH call CopyData ; save the player's name in the Wild Monster data - ld a, [W_BATTLETYPE] + ld a, [wBattleType] cp $1 jp nz,.BallSuccess ld a,$1 @@ -406,7 +406,7 @@ ItemUseBall: ; d3ad (3:53ad) ld [wCapturedMonSpecies],a ld [wcf91],a ld [wd11e],a - ld a,[W_BATTLETYPE] + ld a,[wBattleType] cp $1 jp z,.printText1 ; just barely out of reach for a relative jump cp $4 @@ -468,7 +468,7 @@ ItemUseBall: ; d3ad (3:53ad) call PrintText call ClearSprites .End - ld a,[W_BATTLETYPE] + ld a,[wBattleType] and a ret nz ld hl,wNumBagItems @@ -1540,7 +1540,7 @@ DisplayListMenuID:: ; 2ae0 (0:2ae0) ld [H_AUTOBGTRANSFERENABLED],a ; disable auto-transfer ld a,1 ld [hJoy7],a ; joypad state update flag - ld a,[W_BATTLETYPE] + ld a,[wBattleType] and a ; is it the Old Man battle? jr nz,.specialBattleType ld a,$01 ; hardcoded bank @@ -1596,7 +1596,7 @@ DisplayListMenuIDLoop:: ; 2b4d (0:2b4d) ld a,1 ld [H_AUTOBGTRANSFERENABLED],a ; enable transfer call Delay3 - ld a,[W_BATTLETYPE] + ld a,[wBattleType] and a ; is it the Old Man battle? jr z,.notOldManBattle .oldManBattle diff --git a/scripts/viridiancity.asm b/scripts/viridiancity.asm index a660898b..ece2c4a1 100755 --- a/scripts/viridiancity.asm +++ b/scripts/viridiancity.asm @@ -72,7 +72,7 @@ ViridianCityScript1: ; 19062 (6:5062) ; set up battle for Old Man ld a, $1 - ld [W_BATTLETYPE], a + ld [wBattleType], a ld a, 5 ld [wCurEnemyLVL], a ld a, WEEDLE @@ -98,7 +98,7 @@ ViridianCityScript2: ; 1908f (6:508f) ld [hSpriteIndexOrTextID], a call DisplayTextID xor a - ld [W_BATTLETYPE], a + ld [wBattleType], a ld [wJoyIgnore], a ld a, $0 ld [W_VIRIDIANCITYCURSCRIPT], a @@ -1606,7 +1606,7 @@ wCurOpponent:: ; d059 ; in a trainer battle, this is the trainer class + 200 ds 1 -W_BATTLETYPE:: ; d05a +wBattleType:: ; d05a ; in normal battle, this is 0 ; in old man battle, this is 1 ; in safari battle, this is 2 diff --git a/yellow/main.asm b/yellow/main.asm index ee205439..ba1ccd6b 100755 --- a/yellow/main.asm +++ b/yellow/main.asm @@ -4025,96 +4025,7 @@ INCLUDE "engine/evos_moves.asm" SECTION "bank0F",ROMX,BANK[$0F] - dr $3c000,$3c04c -SlidePlayerAndEnemySilhouettesOnScreen: ; 3c04c (f:404c) - dr $3c04c,$3c127 -StartBattle: ; 3c127 (f:4127) - dr $3c127,$3c973 -EnemySendOut: ; 3c973 (f:4973) - dr $3c973,$3cae8 -AnyPartyAlive: ; 3cae8 (f:4ae8) - dr $3cae8,$3ce08 -ReadPlayerMonCurHPAndStatus: ; 3ce08 (f:4e08) - dr $3ce08,$3ce1f -DrawHUDsAndHPBars: ; 3ce1f (f:4e1f) - dr $3ce1f,$3ceb1 -DrawEnemyHUDAndHPBar: ; 3ceb1 (f:4eb1) - dr $3ceb1,$3d320 -MoveSelectionMenu: ; 3d320 (f:5320) - dr $3d320,$3d9ac -IsGhostBattle: ; 3d9ac (f:59ac) - dr $3d9ac,$3ddc3 -PrintDoesntAffectText: ; 3ddc3 (f:5dc3) - dr $3ddc3,$3e5bb - -AIGetTypeEffectiveness: ; 3e5bb (f:65bb) - ld a,[wEnemyMoveType] - ld d,a ; d = type of enemy move - ld hl,wBattleMonType - ld b,[hl] ; b = type 1 of player's pokemon - inc hl - ld c,[hl] ; c = type 2 of player's pokemon - ld a,$10 - ld [wd11e],a ; initialize [wd11e] to neutral effectiveness - ld hl,TypeEffects -.loop - ld a,[hli] - cp a,$ff - ret z - cp d ; match the type of the move - jr nz,.nextTypePair1 - ld a,[hli] - cp b ; match with type 1 of pokemon - jr z,.done - cp c ; or match with type 2 of pokemon - jr z,.done - jr .nextTypePair2 -.nextTypePair1 - inc hl -.nextTypePair2 - inc hl - jr .loop - -.done - ld a, [wTrainerClass] - cp LORELEI - jr nz, .ok - ld a, [wEnemyMonSpecies] - cp DEWGONG - jr nz, .ok - call BattleRandom - cp $66 ; 40 percent - ret c -.ok - - ld a,[hl] - ld [wd11e],a ; store damage multiplier - ret - -INCLUDE "data/type_effects.asm" - -MoveHitTest: ; 3e6f1 (f:66f1) - dr $3e6f1,$3ec87 -LoadEnemyMonData: ; 3ec87 (f:6c87) - dr $3ec87,$3edb8 -DoBattleTransitionAndInitBattleVariables: ; 3edb8 (f:6db8) - dr $3edb8,$3eeb3 -QuarterSpeedDueToParalysis: ; 3eeb3 (f:6eb3) - dr $3eeb3,$3efe7 -LoadHudTilePatterns: ; 3efe7 (f:6fe7) - dr $3efe7,$3f027 -BattleRandom: ; 3f027 (f:7027) - dr $3f027,$3f3de -StatModifierUpEffect: ; 3f3de (f:73de) - dr $3f3de,$3fb2e -PrintButItFailedText_: ; 3fb2e (f:7b2e) - dr $3fb2e,$3fb39 -PrintDidntAffectText: ; 3fb39 (f:7b39) - dr $3fb39,$3fb49 -PrintMayNotAttackText: ; 3fb49 (f:7b49) - dr $3fb49,$3fb83 -PlayCurrentMoveAnimation: ; 3fb83 (f:7b83) - dr $3fb83,$40000 +INCLUDE "engine/battle/core_.asm" SECTION "bank10",ROMX,BANK[$10] @@ -4294,7 +4205,9 @@ SECTION "bank1E",ROMX,BANK[$1E] AnimationTileset2: ; 78757 (1e:4757) dr $78757,$78c17 SlotMachineTiles2: ; 78c17 (1e:4c17) - dr $78c17,$797af + dr $78c17,$79353 +AnimationSlideEnemyMonOff: ; 79353 (1e:5353) + dr $79353,$797af AnimationSubstitute: ; 797af (1e:57af) dr $797af,$79816 HideSubstituteShowMonAnim: ; 79816 (1e:5816) |