diff options
Diffstat (limited to 'src/engine')
31 files changed, 9918 insertions, 1855 deletions
diff --git a/src/engine/bank01.asm b/src/engine/bank01.asm index b73b47c..090ecf0 100644 --- a/src/engine/bank01.asm +++ b/src/engine/bank01.asm @@ -353,7 +353,7 @@ DuelMainInterface: ; 426d (1:426d) ld [wSkipDuelistIsThinkingDelay], a ldtx hl, DuelistIsThinkingText call DrawWideTextBox_PrintTextNoDelay - call Func_2bbf + call AIDoAction_Turn ld a, $ff ld [wPlayerAttackingCardIndex], a ld [wPlayerAttackingMoveIndex], a @@ -1967,7 +1967,7 @@ ChooseInitialArenaAndBenchPokemon: ; 4cd5 (1:4cd5) ; AI opponent's turn push af push hl - call Func_2bc3 + call AIDoAction_StartDuel pop hl pop af ld [hl], a @@ -3720,7 +3720,7 @@ Func_57df: ; 57df (1:57df) Func_5805: ; 5805 (1:5805) call Func_3b31 - ld a, [wccc8] + ld a, [wNumberPrizeCardsToTake] ld l, a ld h, $00 call LoadTxRam3 @@ -3731,7 +3731,7 @@ Func_5805: ; 5805 (1:5805) ldtx hl, WillDrawNPrizesText call DrawWideTextBox_WaitForInput - ld a, [wccc8] + ld a, [wNumberPrizeCardsToTake] call Func_310a ld hl, hTemp_ffa0 ld d, [hl] @@ -3757,7 +3757,7 @@ Func_5805: ; 5805 (1:5805) call GetTurnDuelistVariable cp DUELIST_TYPE_LINK_OPP jr z, .link_opponent - call Func_2bd7 + call AIDoAction_TakePrize ld c, DECK_SIZE .asm_5858 call DoFrame @@ -3775,7 +3775,7 @@ Func_5805: ; 5805 (1:5805) call nz, AddCardToHand .asm_586f ld a, [wcbfc] - ld hl, wccc8 + ld hl, wNumberPrizeCardsToTake cp [hl] jr nc, .asm_587e ld l, a @@ -6288,10 +6288,10 @@ DiscardSavedDuelData: ; 6785 (1:6785) ; 0x6793 ; loads a player deck (sDeck*Cards) from SRAM to wPlayerDeck -; s0b700 determines which sDeck*Cards source (0-3) +; sCurrentlySelectedDeck determines which sDeck*Cards source (0-3) LoadPlayerDeck: ; 6793 (1:6793) call EnableSRAM - ld a, [s0b700] + ld a, [sCurrentlySelectedDeck] ld l, a ld h, sDeck2Cards - sDeck1Cards call HtimesL @@ -6835,6 +6835,7 @@ OppAction_ExecutePokemonPowerEffect: ; 6b07 (1:6b07) ret ; 0x6b15 +; execute the EFFECTCMDTYPE_AFTER_DAMAGE command of the used Pokemon Power OppAction_6b15: ; 6b15 (1:6b15) ld a, EFFECTCMDTYPE_AFTER_DAMAGE call TryExecuteEffectCommandFunction @@ -7491,7 +7492,7 @@ ReplaceKnockedOutPokemon: ; 6f23 (1:6f23) .opponent cp DUELIST_TYPE_LINK_OPP jr z, .link_opponent - call Func_2bcf + call AIDoAction_KOSwitch ldh a, [hTemp_ffa0] ldh [hTempPlayAreaLocation_ff9d], a jr .replace_pokemon @@ -7524,7 +7525,7 @@ Func_6fa5: ; 6fa5 (1:6fa5) ret ; 0x6fc7 -; return in wccc8 the amount of Pokemon in the turn holder's +; return in wNumberPrizeCardsToTake the amount of Pokemon in the turn holder's ; play area that are still there despite having 0 HP. ; that is, the number of Pokemon that have just been knocked out. ; Clefairy Doll and Mysterious Fossil don't count. @@ -7557,7 +7558,7 @@ CountKnockedOutPokemon: ; 6fc7 (1:6fc7) dec c jr nz, .loop ld a, b - ld [wccc8], a + ld [wNumberPrizeCardsToTake], a or a ret z scf diff --git a/src/engine/bank02.asm b/src/engine/bank02.asm index d48250f..5a7761e 100644 --- a/src/engine/bank02.asm +++ b/src/engine/bank02.asm @@ -2171,7 +2171,7 @@ Func_8f8a: ; 8f8a (2:4f8a) Func_8f9d: ; 8f9d (2:4f9d) call EnableSRAM - ld a, [s0b700] + ld a, [sCurrentlySelectedDeck] call DisableSRAM ld h, $3 ld l, a @@ -2185,7 +2185,7 @@ Func_8f9d: ; 8f9d (2:4f9d) call FillRectangle ld a, [wceb1] call EnableSRAM - ld [s0b700], a + ld [sCurrentlySelectedDeck], a call DisableSRAM call Func_9326 call GetPointerToDeckName @@ -2519,7 +2519,7 @@ Func_9168: ; 9168 (2:5168) ld [wceb5], a .asm_9214 call EnableSRAM - ld a, [s0b700] + ld a, [sCurrentlySelectedDeck] ld c, a ld b, $0 ld d, $2 @@ -2539,7 +2539,7 @@ Func_9168: ; 9168 (2:5168) jr .asm_921f .asm_9234 ld a, c - ld [s0b700], a + ld [sCurrentlySelectedDeck], a call DisableSRAM call Func_9326 call EnableLCD @@ -2628,7 +2628,7 @@ Func_9314: ; 9314 (2:5314) Func_9326: ; 9326 (2:5326) call EnableSRAM - ld a, [s0b700] + ld a, [sCurrentlySelectedDeck] call DisableSRAM ld h, 3 ld l, a @@ -2643,7 +2643,32 @@ Func_9326: ; 9326 (2:5326) ret Func_9345: ; 9345 (2:5345) - INCROM $9345, $9843 + INCROM $9345, $9649 + +; checks if selected deck has any basics +Func_9649: ; 9649 (2:5649) + ld hl, wcf17 +.asm_964c + ld a, [hli] + ld e, a + or a + jr z, .asm_9665 + call LoadCardDataToBuffer1_FromCardID + jr c, .asm_9665 + ld a, [wLoadedCard1Type] + and $08 + jr nz, .asm_964c + ld a, [wLoadedCard1Stage] + or a + jr nz, .asm_964c + scf + ret +.asm_9665 + or a + ret +; 0x9667 + + INCROM $9667, $9843 Func_9843: ; 9843 (2:5843) INCROM $9843, $98a6 diff --git a/src/engine/bank03.asm b/src/engine/bank03.asm index ac5117e..4febfe9 100644 --- a/src/engine/bank03.asm +++ b/src/engine/bank03.asm @@ -29,11 +29,11 @@ LoadMap: ; c000 (3:4000) ld a, PLAYER_TURN ldh [hWhoseTurn], a farcall Func_1c440 - ld a, [wd0bb] + ld a, [wTempMap] ld [wCurMap], a - ld a, [wd0bc] + ld a, [wTempPlayerXCoord] ld [wPlayerXCoord], a - ld a, [wd0bd] + ld a, [wTempPlayerYCoord] ld [wPlayerYCoord], a call Func_c36a call Func_c184 @@ -54,7 +54,7 @@ LoadMap: ; c000 (3:4000) .asm_c092 call DoFrameIfLCDEnabled call SetScreenScroll - call Func_c0ce + call HandleOverworldMode ld hl, wd0b4 ld a, [hl] and $d0 @@ -79,13 +79,13 @@ LoadMap: ; c000 (3:4000) call Func_c280 ret -Func_c0ce: ; c0ce (3:40ce) - ld a, [wd0bf] +HandleOverworldMode: ; c0ce (3:40ce) + ld a, [wOverworldMode] res 7, a rlca - add LOW(PointerTable_c0e0) + add LOW(OverworldModePointers) ld l, a - ld a, HIGH(PointerTable_c0e0) + ld a, HIGH(OverworldModePointers) adc $0 ld h, a ld a, [hli] @@ -93,58 +93,59 @@ Func_c0ce: ; c0ce (3:40ce) ld l, a jp hl -PointerTable_c0e0: ; c0e0 (3:40e0) - dw Func_c0e8 - dw Func_c0ed - dw Func_c0f1 - dw Func_c10a +OverworldModePointers: ; c0e0 (3:40e0) + dw Func_c0e8 ; on map + dw CallHandlePlayerMoveMode + dw SetScriptData + dw EnterScript Func_c0e8: ; c0e8 (3:40e8) farcall Func_10e55 ret -Func_c0ed: ; c0ed (3:40ed) - call Func_c510 +CallHandlePlayerMoveMode: ; c0ed (3:40ed) + call HandlePlayerMoveMode ret -Func_c0f1: ; c0f1 (3:40f1) - ld a, [wd3b6] - ld [wd3aa], a - farcall Func_1c768 +SetScriptData: ; c0f1 (3:40f1) + ld a, [wScriptNPC] + ld [wLoadedNPCTempIndex], a + farcall SetNewScriptNPC ld a, c - ld [wd0c6], a + ld [wNextScript], a ld a, b - ld [wd0c7], a + ld [wNextScript+1], a ld a, $3 - ld [wd0bf], a - jr Func_c10a + ld [wOverworldMode], a + jr EnterScript -Func_c10a: ; c10a (3:410a) - ld hl, wd0c6 +EnterScript: ; c10a (3:410a) + ld hl, wNextScript ld a, [hli] ld h, [hl] ld l, a jp hl ; closes dialogue window. seems to be for other things as well. -CloseDialogueBox: ; c111 (3:4111) +CloseAdvancedDialogueBox: ; c111 (3:4111) ld a, [wd0c1] bit 0, a - call nz, Func_c135 + call nz, CloseTextBox ld a, [wd0c1] bit 1, a jr z, .asm_c12a - ld a, [wd3b6] - ld [wd3aa], a + ld a, [wScriptNPC] + ld [wLoadedNPCTempIndex], a farcall Func_1c5e9 .asm_c12a xor a ld [wd0c1], a ld a, [wd0c0] - ld [wd0bf], a + ld [wOverworldMode], a ret -Func_c135: ; c135 (3:4135) +; redraws the background and removes textbox control +CloseTextBox: ; c135 (3:4135) push hl farcall Func_80028 ld hl, wd0c1 @@ -175,12 +176,12 @@ Func_c158: ; c158 (3:4158) cp $1 ret nz ld a, [wd0c4] - ld [wd3ab], a - call Func_39c3 + ld [wTempNPC], a + call FindLoadedNPC jr c, .asm_c179 - ld a, [wd3aa] - ld l, $4 - call Func_39ad + ld a, [wLoadedNPCTempIndex] + ld l, LOADED_NPC_DIRECTION + call GetItemInLoadedNPCIndex ld a, [wd0c5] ld [hl], a farcall Func_1c58e @@ -188,7 +189,7 @@ Func_c158: ; c158 (3:4158) ret Func_c17a: ; c17a (3:417a) - ld a, [wd0bf] + ld a, [wOverworldMode] cp $3 ret z call Func_c9b8 @@ -203,7 +204,7 @@ Func_c184: ; c184 (3:4184) ld c, $0 .asm_c190 ld a, c - ld [wd0bf], a + ld [wOverworldMode], a ld [wd0c0], a pop bc ret @@ -230,13 +231,13 @@ Func_c1b1: ; c1b1 (3:41b1) ld a, $c ld [wd32e], a ld a, $0 - ld [wd0bb], a + ld [wTempMap], a ld a, $c - ld [wd0bc], a + ld [wTempPlayerXCoord], a ld a, $c - ld [wd0bd], a + ld [wTempPlayerYCoord], a ld a, $2 - ld [wd0be], a + ld [wTempPlayerDirection], a call Func_c9cb call Func_c9dd farcall Func_80b7a @@ -277,13 +278,13 @@ Func_c1f8: ; c1f8 (3:41f8) Func_c228: ; c228 (3:4228) ld a, [wCurMap] - ld [wd0bb], a + ld [wTempMap], a ld a, [wPlayerXCoord] - ld [wd0bc], a + ld [wTempPlayerXCoord], a ld a, [wPlayerYCoord] - ld [wd0bd], a - ld a, [wd334] - ld [wd0be], a + ld [wTempPlayerYCoord], a + ld a, [wPlayerDirection] + ld [wTempPlayerDirection], a ret Func_c241: ; c241 (3:4241) @@ -579,24 +580,24 @@ Func_c4b9: ; c4b9 (3:44b9) ld a, b ld [wd337], a ld a, $0 - farcall Func_1299f + farcall CreateSpriteAndAnimBufferEntry ld a, [wWhichSprite] - ld [wd336], a + ld [wPlayerSpriteIndex], a ld b, $2 ld a, [wCurMap] cp OVERWORLD_MAP jr z, .asm_c4ee - ld a, [wd0be] + ld a, [wTempPlayerDirection] ld b, a .asm_c4ee ld a, b - ld [wd334], a - call Func_c5e9 + ld [wPlayerDirection], a + call UpdatePlayerSprite ld a, [wCurMap] cp OVERWORLD_MAP call nz, Func_c6f7 xor a - ld [wd335], a + ld [wPlayerCurrentlyMoving], a ld [wd338], a ld a, [wCurMap] cp OVERWORLD_MAP @@ -605,42 +606,42 @@ Func_c4b9: ; c4b9 (3:44b9) .asm_c50f ret -Func_c510: ; c510 (3:4510) - ld a, [wd336] +HandlePlayerMoveMode: ; c510 (3:4510) + ld a, [wPlayerSpriteIndex] ld [wWhichSprite], a - ld a, [wd335] + ld a, [wPlayerCurrentlyMoving] bit 4, a ret nz bit 0, a - call z, Func_c5ac - ld a, [wd335] + call z, HandlePlayerMoveModeInput + ld a, [wPlayerCurrentlyMoving] or a - jr z, .asm_c535 + jr z, .notMoving bit 0, a call nz, Func_c66c - ld a, [wd335] + ld a, [wPlayerCurrentlyMoving] bit 1, a call nz, Func_c6dc ret -.asm_c535 +.notMoving ldh a, [hKeysPressed] and START - call nz, Func_c74d + call nz, OpenStartMenu ret Func_c53d: ; c53d (3:453d) - ld a, [wd336] + ld a, [wPlayerSpriteIndex] ld [wWhichSprite], a - ld a, [wd335] + ld a, [wPlayerCurrentlyMoving] bit 0, a call nz, Func_c687 - ld a, [wd335] + ld a, [wPlayerCurrentlyMoving] bit 1, a call nz, Func_c6dc ret Func_c554: ; c554 (3:4554) - ld a, [wd336] + ld a, [wPlayerSpriteIndex] ld [wWhichSprite], a ld a, [wCurMap] cp OVERWORLD_MAP @@ -694,80 +695,81 @@ Func_c58b: ; c58b (3:458b) pop hl ret -Func_c5ac: ; c5ac (3:45ac) +HandlePlayerMoveModeInput: ; c5ac (3:45ac) ldh a, [hKeysHeld] and D_PAD - jr z, .asm_c5bf - call Func_c5cb - call Func_c5fe - ld a, [wd335] + jr z, .skipMoving + call UpdatePlayerDirectionFromDPad + call AttemptPlayerMovementFromDirection + ld a, [wPlayerCurrentlyMoving] and $1 - jr nz, .asm_c5ca -.asm_c5bf + jr nz, .done +.skipMoving ldh a, [hKeysPressed] and A_BUTTON - jr z, .asm_c5ca - call Func_c71e - jr .asm_c5ca -.asm_c5ca + jr z, .done + call FindNPCOrObject + jr .done +.done ret -Func_c5cb: ; c5cb (3:45cb) - call Func_c5d5 -Func_c5ce: ; c5ce (3:45ce) - ld [wd334], a - call Func_c5e9 +UpdatePlayerDirectionFromDPad: ; c5cb (3:45cb) + call GetDirectionFromDPad +UpdatePlayerDirection: ; c5ce (3:45ce) + ld [wPlayerDirection], a + call UpdatePlayerSprite ret -Func_c5d5: ; c5d5 (3:45d5) +GetDirectionFromDPad: ; c5d5 (3:45d5) push hl - ld hl, Unknown_c5e5 + ld hl, KeypadDirectionMap or a - jr z, .asm_c5e2 -.asm_c5dc + jr z, .loadDirectionMapping +.findDirectionMappingLoop rlca - jr c, .asm_c5e2 + jr c, .loadDirectionMapping inc hl - jr .asm_c5dc -.asm_c5e2 + jr .findDirectionMappingLoop +.loadDirectionMapping ld a, [hl] pop hl ret -Unknown_c5e5: ; c5e5 (3:45e5) - db $02,$00,$03,$01 +KeypadDirectionMap: ; c5e5 (3:45e5) + db SOUTH, NORTH, WEST, EAST -Func_c5e9: ; c5e9 (3:45e9) +; Updates sprite depending on direction +UpdatePlayerSprite: ; c5e9 (3:45e9) push bc - ld a, [wd336] + ld a, [wPlayerSpriteIndex] ld [wWhichSprite], a ld a, [wd337] ld b, a - ld a, [wd334] + ld a, [wPlayerDirection] add b farcall Func_12ab5 pop bc ret -Func_c5fe: ; c5fe (3:45fe) +AttemptPlayerMovementFromDirection: ; c5fe (3:45fe) push bc - call Func_c653 - call AttemptScriptedMovement + call FindPlayerMovementFromDirection + call AttemptPlayerMovement pop bc ret -StartScriptedMovement: ; c607 (3:4607) +StartScript_dMovement: ; c607 (3:4607) push bc - ld a, [wd336] + ld a, [wPlayerSpriteIndex] ld [wWhichSprite], a ld a, [wd339] - call FindScriptedMovementWithOffset - call AttemptScriptedMovement + call FindPlayerMovementWithOffset + call AttemptPlayerMovement pop bc ret ; bc is the location the player is being scripted to move towards. -AttemptScriptedMovement: ; c619 (3:4619) +AttemptPlayerMovement: ; c619 (3:4619) push hl push bc ld a, b @@ -783,9 +785,9 @@ AttemptScriptedMovement: ; c619 (3:4619) ld [wPlayerXCoord], a ld a, c ld [wPlayerYCoord], a - ld a, [wd335] ; I believe everything starting here is animation related. + ld a, [wPlayerCurrentlyMoving] ; I believe everything starting here is animation related. or $1 - ld [wd335], a + ld [wPlayerCurrentlyMoving], a ld a, $10 ld [wd338], a ld c, SPRITE_ANIM_FIELD_0F @@ -800,15 +802,15 @@ AttemptScriptedMovement: ; c619 (3:4619) pop hl ret -Func_c653: ; c653 (3:4653) - ld a, [wd334] +FindPlayerMovementFromDirection: ; c653 (3:4653) + ld a, [wPlayerDirection] -FindScriptedMovementWithOffset: ; c656 (3:4656) +FindPlayerMovementWithOffset: ; c656 (3:4656) rlca ld c, a ld b, $0 push hl - ld hl, ScriptedMovementOffsetTable + ld hl, PlayerMovementOffsetTable add hl, bc ld a, [wPlayerXCoord] add [hl] @@ -832,7 +834,7 @@ Func_c66c: ; c66c (3:466c) jr c, .asm_c67e inc c .asm_c67e - ld a, [wd334] + ld a, [wPlayerDirection] call Func_c694 pop bc pop hl @@ -876,7 +878,7 @@ Func_c694: ; c694 (3:4694) ld a, [wd338] or a jr nz, .asm_c6c3 - ld hl, wd335 + ld hl, wPlayerCurrentlyMoving set 1, [hl] .asm_c6c3 call Func_c41c @@ -903,20 +905,20 @@ Func_c6d4: ; c6d4 (3:46d4) Func_c6dc: ; c6dc (3:46dc) push hl - ld hl, wd335 + ld hl, wPlayerCurrentlyMoving res 0, [hl] res 1, [hl] call Func_c6f7 call Func_3997 call Func_c70d - ld a, [wd0bf] + ld a, [wOverworldMode] cp $1 call z, Func_c9c0 pop hl ret Func_c6f7: ; c6f7 (3:46f7) - ld a, [wd336] + ld a, [wPlayerSpriteIndex] ld [wWhichSprite], a ld c, SPRITE_ANIM_FIELD_0F call GetSpriteAnimBufferProperty @@ -929,7 +931,7 @@ Func_c6f7: ; c6f7 (3:46f7) Func_c70d: ; c70d (3:470d) push hl - ld hl, wd0bb + ld hl, wTempMap ld a, [wCurMap] cp [hl] jr z, .asm_c71c @@ -939,38 +941,40 @@ Func_c70d: ; c70d (3:470d) pop hl ret -Func_c71e: ; c71e (3:471e) +; Arrives here if A button is pressed when not moving + in map move state +FindNPCOrObject: ; c71e (3:471e) ld a, $ff - ld [wd3b6], a - call Func_c653 + ld [wScriptNPC], a + call FindPlayerMovementFromDirection call GetPermissionOfMapPosition and $40 - jr z, .asm_c73d - farcall Func_1c72e - jr c, .asm_c73d - ld a, [wd3aa] - ld [wd3b6], a - ld a, $2 - jr .asm_c748 -.asm_c73d - call Func_3a5e - jr nc, .asm_c746 - ld a, $3 - jr .asm_c748 -.asm_c746 + jr z, .noNPC + farcall FindNPCAtLocation + jr c, .noNPC + ld a, [wLoadedNPCTempIndex] + ld [wScriptNPC], a + ld a, OWMODE_START_SCRIPT + jr .changeStateExit + +.noNPC + call HandleMoveModeAPress + jr nc, .exit + ld a, OWMODE_SCRIPT + jr .changeStateExit +.exit or a ret -.asm_c748 - ld [wd0bf], a +.changeStateExit + ld [wOverworldMode], a scf ret -Func_c74d: ; c74d (3:474d) +OpenStartMenu: ; c74d (3:474d) push hl push bc push de call MainMenu_c75a - call CloseDialogueBox + call CloseAdvancedDialogueBox pop de pop bc pop hl @@ -1060,7 +1064,7 @@ PC_c7ea: ; c7ea (3:47ea) ld a, MUSIC_PC_MAIN_MENU call PlaySong call Func_c241 - call $4915 + call Func_c915 call DoFrameIfLCDEnabled ldtx hl, TurnedPCOnText call PrintScrollableText_NoTextBoxLabel @@ -1087,11 +1091,11 @@ PC_c7ea: ; c7ea (3:47ea) call Func_c32b jr .asm_c801 .asm_c82f - call Func_c135 + call CloseTextBox call DoFrameIfLCDEnabled ldtx hl, TurnedPCOffText call Func_c891 - call CloseDialogueBox + call CloseAdvancedDialogueBox xor a ld [wd112], a call Func_39fc @@ -1108,7 +1112,7 @@ Func_c891: ; c891 (3:4891) ld hl, wd3b9 ld a, [hli] or [hl] - call nz, Func_c135 + call nz, CloseTextBox .asm_c8a1 xor a @@ -1119,7 +1123,7 @@ Func_c891: ; c891 (3:4891) ld a, $1 call Func_c29b call Func_c241 - call $4915 + call Func_c915 call DoFrameIfLCDEnabled call PrintScrollableText_NoTextBoxLabel ret @@ -1141,7 +1145,7 @@ Func_c8ba: ; c8ba (3:48ba) jr z, .asm_c8d4 .asm_c8d1 - call Func_c135 + call CloseTextBox .asm_c8d4 ld hl, wd3b9 @@ -1152,20 +1156,20 @@ Func_c8ba: ; c8ba (3:48ba) ld a, $1 call Func_c29b call Func_c241 - call $4915 + call Func_c915 call DoFrameIfLCDEnabled call $2c62 ret ; 0xc8ed -Func_c8ed: ; c8ed (3:c8ed) +Func_c8ed: ; c8ed (3:48ed) push hl push bc push de push hl ld a, $1 call Func_c29b - call $4915 + call Func_c915 call DoFrameIfLCDEnabled pop hl ld a, l @@ -1200,22 +1204,23 @@ Func_c915: ; c915 (3:4915) pop bc ret -Func_c926: ; c926 (3:4926) +SetNextNPCAndScript: ; c926 (3:4926) push bc - call Func_39c3 - ld a, [wd3aa] - ld [wd3b6], a - farcall Func_1c768 + call FindLoadedNPC + ld a, [wLoadedNPCTempIndex] + ld [wScriptNPC], a + farcall SetNewScriptNPC pop bc +; fallthrough -Func_c935: ; c935 (3:4935) +SetNextScript: ; c935 (3:4935) push hl - ld hl, wd0c6 + ld hl, wNextScript ld [hl], c inc hl ld [hl], b ld a, $3 - ld [wd0bf], a + ld [wOverworldMode], a pop hl ret @@ -1223,51 +1228,51 @@ Func_c943: ; c943 (3:4943) push hl push bc push de - ld l, $0 - call Func_3abd - jr nc, .asm_c98f -.asm_c94d + ld l, MAP_SCRIPT_NPCS + call GetMapScriptPointer + jr nc, .quit +.loadNPCLoop ld a, l - ld [wd4c4], a + ld [wTempPointer], a ld a, h - ld [wd4c5], a - ld a, $4 - ld [wd4c6], a - ld de, wd3ab - ld bc, $0006 - call Func_3bf5 - ld a, [wd3ab] + ld [wTempPointer + 1], a + ld a, BANK(MapScripts) + ld [wTempPointerBank], a + ld de, wTempNPC + ld bc, NPC_MAP_SIZE + call CopyBankedDataToDE + ld a, [wTempNPC] or a - jr z, .asm_c98f + jr z, .quit push hl - ld a, [wd3af] + ld a, [wLoadNPCFunction] ld l, a - ld a, [wd3b0] + ld a, [wLoadNPCFunction+1] ld h, a or l - jr z, .asm_c97a + jr z, .noScript call CallHL2 - jr nc, .asm_c988 -.asm_c97a - ld a, [wd3ab] - farcall Func_11857 + jr nc, .nextNPC +.noScript + ld a, [wTempNPC] + farcall LoadNPCSpriteData call Func_c998 farcall Func_1c485 -.asm_c988 +.nextNPC pop hl - ld bc, $0006 + ld bc, NPC_MAP_SIZE add hl, bc - jr .asm_c94d -.asm_c98f - ld l, $2 - call Func_c9c2 + jr .loadNPCLoop +.quit + ld l, MAP_SCRIPT_POST_NPC + call CallMapScriptPointerIfExists pop de pop bc pop hl ret Func_c998: ; c998 (3:4998) - ld a, [wd3ab] + ld a, [wTempNPC] cp $22 ret nz ld a, [wd3d0] @@ -1286,24 +1291,24 @@ Func_c998: ; c998 (3:4998) ret Func_c9b8: ; c9b8 (3:49b8) - ld l, $8 - jr Func_c9c2 + ld l, MAP_SCRIPT_LOAD_MAP + jr CallMapScriptPointerIfExists Func_c9bc: ; c9bc (3:49bc) - ld l, $a - jr Func_c9c2 + ld l, MAP_SCRIPT_AFTER_DUEL + jr CallMapScriptPointerIfExists Func_c9c0: ; c9c0 (3:49c0) - ld l, $c + ld l, MAP_SCRIPT_MOVED_PLAYER -Func_c9c2: ; c9c2 (3:49c2) - call Func_3abd +CallMapScriptPointerIfExists: ; c9c2 (3:49c2) + call GetMapScriptPointer ret nc jp hl Func_c9c7: ; c9c7 (3:49c7) - ld l, $e - jr Func_c9c2 + ld l, MAP_SCRIPT_CLOSE_TEXTBOX + jr CallMapScriptPointerIfExists Func_c9cb: ; c9cb (3:49cb) push hl @@ -1321,48 +1326,50 @@ Func_c9cb: ; c9cb (3:49cb) pop hl ret +; Clears temporary flags before determining Imakuni Room Func_c9dd: ; c9dd (3:49dd) xor a - ld [wd411], a - call Func_c9e8 + ld [wEventFlags + EVENT_FLAG_BYTES - 1], a + call DetermineImakuniRoom call Func_ca0e ret -Func_c9e8: ; c9e8 (3:49e8) +; Determines what room Imakuni is in when you reset +; Skips current room and does not occur if you haven't talked to Imakuni +DetermineImakuniRoom: ; c9e8 (3:49e8) ld c, $0 - call Func_ca69 - db $13 - cp $2 - jr c, .asm_ca04 -.asm_c9f2 + get_flag_value EVENT_IMAKUNI_STATE + cp IMAKUNI_TALKED + jr c, .finish +.tryLoadImakuniLoop call UpdateRNGSources and $3 ld c, a ld b, $0 - ld hl, Unknown_ca0a + ld hl, ImakuniPossibleRooms add hl, bc - ld a, [wd0bb] + ld a, [wTempMap] cp [hl] - jr z, .asm_c9f2 -.asm_ca04 + jr z, .tryLoadImakuniLoop +.finish ld a, c - call Func_ca8f - db $34 + set_flag_value EVENT_IMAKUNI_ROOM ret -Unknown_ca0a: ; ca0a (3:4a04) - INCROM $ca0a, $ca0e +ImakuniPossibleRooms: ; ca0a (3:4a04) + db FIGHTING_CLUB_LOBBY + db SCIENCE_CLUB_LOBBY + db LIGHTNING_CLUB_LOBBY + db WATER_CLUB_LOBBY Func_ca0e: ; ca0e (3:4a0e) ld a, [wd32e] cp $b jr z, .asm_ca68 - call Func_ca69 - db $22 + get_flag_value EVENT_RECEIVED_LEGENDARY_CARD or a jr nz, .asm_ca4a - call Func_ca69 - db $40 + get_flag_value EVENT_FLAG_40 cp $7 jr z, .asm_ca68 or a @@ -1370,12 +1377,10 @@ Func_ca0e: ; ca0e (3:4a0e) cp $2 jr z, .asm_ca62 ld c, $1 - call Func_ca8f - db $40 + set_flag_value EVENT_FLAG_40 jr .asm_ca62 .asm_ca33 - call Func_ca69 - db $3f + get_flag_value EVENT_FLAG_3F cp $7 jr z, .asm_ca68 or a @@ -1383,8 +1388,7 @@ Func_ca0e: ; ca0e (3:4a0e) cp $2 jr z, .asm_ca68 ld c, $1 - call Func_ca8f - db $3f + set_flag_value EVENT_FLAG_3F jr .asm_ca68 .asm_ca4a call UpdateRNGSources @@ -1394,35 +1398,36 @@ Func_ca0e: ; ca0e (3:4a0e) jr z, .asm_ca56 ld c, $0 .asm_ca56 - call Func_ca8f - db $41 + set_flag_value EVENT_FLAG_41 jr .asm_ca5c .asm_ca5c ld c, $7 - call Func_ca8f - db $40 + set_flag_value EVENT_FLAG_40 .asm_ca62 ld c, $7 - call Func_ca8f - db $3f + set_flag_value EVENT_FLAG_3F .asm_ca68 ret -Func_ca69: ; ca69 (3:4a69) - call Func_cab3 -CheckIfEventFlagSet: ; ca6c (3:4a6c) +GetStackFlagValue: ; ca69 (3:4a69) + call GetByteAfterCall +; fallthrough + +; returns the event flag's value in a +; also ors it with itself before returning +GetEventFlagValue: ; ca6c (3:4a6c) push hl push bc - call GetEventFlagMod + call GetEventFlag ld c, [hl] - ld a, [wd3d1] -.asm_ca75 + ld a, [wLoadedFlagBits] +.shiftLoop bit 0, a - jr nz, .asm_ca7f + jr nz, .lsbReached srl a srl c - jr .asm_ca75 -.asm_ca7f + jr .shiftLoop +.lsbReached and c pop bc pop hl @@ -1430,17 +1435,27 @@ CheckIfEventFlagSet: ; ca6c (3:4a6c) ret ; 0xca84 - INCROM $ca84, $ca8f +ZeroStackFlagValue2: ; ca84 (3:4a84) + call GetByteAfterCall + push bc + ld c, $00 + call SetEventFlagValue + pop bc + ret -Func_ca8f: ; ca8f (3:4a8f) - call Func_cab3 +; Use macro set_flag_value. The byte db'd after this func is called +; is used at the flag argument for SetEventFlagValue +SetStackFlagValue: ; ca8f (3:4a8f) + call GetByteAfterCall +; fallthrough -; a - pointer on table for cb1d, c - set or reset control bit -ModifyEventFlags: ; ca92 (3:4a92) +; a - flag +; c - value - truncated to fit only the flag's bounds +SetEventFlagValue: ; ca92 (3:4a92) push hl push bc - call GetEventFlagMod - ld a, [wd3d1] + call GetEventFlag + ld a, [wLoadedFlagBits] .asm_ca9a bit 0, a jr nz, .asm_caa4 @@ -1448,10 +1463,10 @@ ModifyEventFlags: ; ca92 (3:4a92) sla c jr .asm_ca9a .asm_caa4 - ld a, [wd3d1] + ld a, [wLoadedFlagBits] and c ld c, a - ld a, [wd3d1] + ld a, [wLoadedFlagBits] cpl and [hl] or c @@ -1460,7 +1475,8 @@ ModifyEventFlags: ; ca92 (3:4a92) pop hl ret -Func_cab3: ; cab3 (3:4ab3) +; returns in a the byte db'd after the call to a function that calls this +GetByteAfterCall: ; cab3 (3:4ab3) push hl ld hl, sp+$4 push bc @@ -1477,73 +1493,86 @@ Func_cab3: ; cab3 (3:4ab3) ret ; 0xcac2 - INCROM $cac2, $cac5 +MaxStackFlagValue: ; cac2 (3:4ac2) + call GetByteAfterCall +; fallthrough -SetEventFlags: ; cac5 (3:4ac5) +MaxOutEventFlag: ; cac5 (3:4ac5) push bc ld c, $ff - call ModifyEventFlags + call SetEventFlagValue pop bc ret ; 0xcacd - INCROM $cacd, $cad0 +ZeroStackFlagValue: ; cacd (3:4acd) + call GetByteAfterCall +; fallthrough -Func_cad0: ; cad0 (3:4ad0) +ZeroOutEventFlag: ; cad0 (3:4ad0) push bc ld c, $0 - call ModifyEventFlags + call SetEventFlagValue pop bc ret -Func_cad8: ; cad8 (3:4ad8) +TryGiveMedalPCPacks: ; cad8 (3:4ad8) push hl push bc - ld hl, $4b15 + ld hl, MedalEventFlags ld bc, $0008 -.asm_cae0 +.countMedalsLoop ld a, [hli] - call CheckIfEventFlagSet - jr z, .asm_cae7 + call GetEventFlagValue + jr z, .noMedal inc b - -.asm_cae7 +.noMedal dec c - jr nz, .asm_cae0 + jr nz, .countMedalsLoop + ld c, b - call Func_ca8f - ld l, $79 + set_flag_value EVENT_MEDAL_COUNT + ld a, c push af cp $8 - jr nc, .asm_caff + jr nc, .givePacksForEightMedals cp $7 - jr nc, .asm_cb05 + jr nc, .givePacksForSevenMedals cp $3 - jr nc, .asm_cb0b - jr .asm_cb11 + jr nc, .givePacksForTwoMedals + jr .finish -.asm_caff +.givePacksForEightMedals ld a, $c - farcall $4, $4a70 + farcall TryGivePCPack -.asm_cb05 +.givePacksForSevenMedals ld a, $b - farcall $4, $4a70 + farcall TryGivePCPack -.asm_cb0b +.givePacksForTwoMedals ld a, $a - farcall $4, $4a70 + farcall TryGivePCPack -.asm_cb11 +.finish pop af pop bc pop hl ret ; 0xcb15 - INCROM $cb15, $cb1d - -GetEventFlagMod: ; cb1d (3:4b1d) +MedalEventFlags: ; cb15 (3:4b15) + db EVENT_FLAG_08 + db EVENT_FLAG_09 + db EVENT_FLAG_0A + db EVENT_BEAT_AMY + db EVENT_FLAG_0C + db EVENT_FLAG_0D + db EVENT_FLAG_0E + db EVENT_FLAG_0F + +; returns wEventFlags byte in hl, related bits in wLoadedFlagBits +GetEventFlag: ; cb1d (3:4b1d) push bc ld c, a ld b, $0 @@ -1554,7 +1583,7 @@ GetEventFlagMod: ; cb1d (3:4b1d) ld a, [hli] ld c, a ld a, [hl] - ld [wd3d1], a + ld [wLoadedFlagBits], a ld b, $0 ld hl, wEventFlags add hl, bc @@ -1563,11 +1592,139 @@ GetEventFlagMod: ; cb1d (3:4b1d) ; offset - bytes to set or reset EventFlagMods: ; cb37 (3:4b37) - INCROM $cb37, $cc32 + flag_def $3f, %10000000 ; EVENT_FLAG_00 ; 0-7 are reset when game resets + flag_def $3f, %01000000 ; EVENT_FLAG_01 + flag_def $3f, %00100000 ; EVENT_TEMP_TALKED_TO_IMAKUNI + flag_def $3f, %00010000 ; EVENT_TEMP_BATTLED_IMAKUNI + flag_def $3f, %00001000 ; EVENT_FLAG_04 + flag_def $3f, %00000100 ; EVENT_FLAG_05 + flag_def $3f, %00000010 ; EVENT_FLAG_06 + flag_def $3f, %00000001 ; EVENT_FLAG_07 + flag_def $00, %10000000 ; EVENT_FLAG_08 + flag_def $00, %01000000 ; EVENT_FLAG_09 + flag_def $00, %00100000 ; EVENT_FLAG_0A + flag_def $00, %00010000 ; EVENT_BEAT_AMY + flag_def $00, %00001000 ; EVENT_FLAG_0C + flag_def $00, %00000100 ; EVENT_FLAG_0D + flag_def $00, %00000010 ; EVENT_FLAG_0E + flag_def $00, %00000001 ; EVENT_FLAG_0F + flag_def $00, %11111111 ; EVENT_FLAG_10 + flag_def $01, %11110000 ; EVENT_FLAG_11 + flag_def $01, %00001111 ; EVENT_FLAG_12 + flag_def $02, %11000000 ; EVENT_IMAKUNI_STATE + flag_def $02, %00110000 ; EVENT_FLAG_14 + flag_def $02, %00001000 ; EVENT_BEAT_SARA + flag_def $02, %00000100 ; EVENT_BEAT_AMANDA + flag_def $03, %11110000 ; EVENT_FLAG_17 + flag_def $03, %00001111 ; EVENT_FLAG_18 + flag_def $04, %11110000 ; EVENT_FLAG_19 + flag_def $04, %00001111 ; EVENT_FLAG_1A + flag_def $05, %10000000 ; EVENT_FLAG_1B + flag_def $05, %01000000 ; EVENT_FLAG_1C + flag_def $05, %00100000 ; EVENT_FLAG_1D + flag_def $05, %00010000 ; EVENT_FLAG_1E + flag_def $05, %00001111 ; EVENT_FLAG_1F + flag_def $06, %11110000 ; EVENT_FLAG_20 + flag_def $06, %00001100 ; EVENT_FLAG_21 + flag_def $06, %00000010 ; EVENT_RECEIVED_LEGENDARY_CARD + flag_def $06, %00000001 ; EVENT_FLAG_23 + flag_def $07, %11000000 ; EVENT_FLAG_24 + flag_def $07, %00100000 ; EVENT_FLAG_25 + flag_def $07, %00010000 ; EVENT_FLAG_26 + flag_def $07, %00001000 ; EVENT_FLAG_27 + flag_def $07, %00000100 ; EVENT_FLAG_28 + flag_def $07, %00000010 ; EVENT_FLAG_29 + flag_def $07, %00000001 ; EVENT_FLAG_2A + flag_def $08, %11111111 ; EVENT_FLAG_2B + flag_def $09, %11100000 ; EVENT_FLAG_2C + flag_def $09, %00011111 ; EVENT_FLAG_2D + flag_def $0a, %11110000 ; EVENT_MEDAL_COUNT + flag_def $0a, %00001000 ; EVENT_FLAG_2F + flag_def $0a, %00000100 ; EVENT_FLAG_30 + flag_def $0a, %00000011 ; EVENT_FLAG_31 + flag_def $0b, %10000000 ; EVENT_FLAG_32 + flag_def $0b, %01110000 ; EVENT_JOSHUA_STATE + flag_def $0b, %00001100 ; EVENT_IMAKUNI_ROOM + flag_def $0b, %00000011 ; EVENT_FLAG_35 + flag_def $0c, %11100000 ; EVENT_IMAKUNI_WIN_COUNT + flag_def $0c, %00011100 ; EVENT_FLAG_37 + flag_def $0c, %00000010 ; EVENT_FLAG_38 + flag_def $0c, %00000001 ; EVENT_FLAG_39 + flag_def $0d, %10000000 ; EVENT_FLAG_3A + flag_def $0d, %01000000 ; EVENT_FLAG_3B + flag_def $0d, %00100000 ; FLAG_BEAT_BRITTANY + flag_def $0d, %00010000 ; EVENT_FLAG_3D + flag_def $0d, %00001110 ; EVENT_FLAG_3E + flag_def $0e, %11100000 ; EVENT_FLAG_3F + flag_def $0e, %00011100 ; EVENT_FLAG_40 + flag_def $0f, %11100000 ; EVENT_FLAG_41 + flag_def $10, %10000000 ; EVENT_FLAG_42 + flag_def $10, %01000000 ; EVENT_FLAG_43 + flag_def $10, %00110000 ; EVENT_FLAG_44 + flag_def $10, %00001100 ; EVENT_FLAG_45 + flag_def $10, %00000010 ; EVENT_FLAG_46 + flag_def $10, %00000001 ; EVENT_FLAG_47 + flag_def $11, %11100000 ; EVENT_FLAG_48 + flag_def $11, %00011100 ; EVENT_FLAG_49 + flag_def $12, %11100000 ; EVENT_FLAG_4A + flag_def $13, %10000000 ; EVENT_FLAG_4B + flag_def $13, %01100000 ; EVENT_FLAG_4C + flag_def $13, %00011000 ; EVENT_FLAG_4D + flag_def $13, %00000100 ; EVENT_FLAG_4E + flag_def $13, %00000010 ; EVENT_FLAG_4F + flag_def $14, %10000000 ; EVENT_FLAG_50 + flag_def $14, %01000000 ; EVENT_FLAG_51 + flag_def $14, %00100000 ; EVENT_FLAG_52 + flag_def $14, %00010000 ; EVENT_FLAG_53 + flag_def $14, %00001000 ; EVENT_FLAG_54 + flag_def $14, %00000100 ; EVENT_FLAG_55 + flag_def $14, %00000010 ; EVENT_FLAG_56 + flag_def $14, %00000001 ; EVENT_FLAG_57 + flag_def $15, %11110000 ; EVENT_FLAG_58 + flag_def $15, %00001000 ; EVENT_FLAG_59 + flag_def $16, %10000000 ; EVENT_FLAG_5A + flag_def $16, %01000000 ; EVENT_FLAG_5B + flag_def $16, %00100000 ; EVENT_FLAG_5C + flag_def $16, %00010000 ; EVENT_FLAG_5D + flag_def $16, %00001000 ; EVENT_FLAG_5E + flag_def $16, %00000100 ; EVENT_FLAG_5F + flag_def $16, %00000010 ; EVENT_FLAG_60 + flag_def $16, %00000001 ; EVENT_FLAG_61 + flag_def $16, %11111111 ; EVENT_FLAG_62 + flag_def $17, %10000000 ; EVENT_FLAG_63 + flag_def $17, %01000000 ; EVENT_FLAG_64 + flag_def $17, %00110000 ; EVENT_FLAG_65 + flag_def $17, %00001000 ; EVENT_FLAG_66 + flag_def $17, %00000100 ; EVENT_FLAG_67 + flag_def $18, %11000000 ; EVENT_FLAG_68 + flag_def $18, %00110000 ; EVENT_FLAG_69 + flag_def $18, %00001100 ; EVENT_FLAG_6A + flag_def $18, %00000011 ; EVENT_FLAG_6B + flag_def $19, %11000000 ; EVENT_FLAG_6C + flag_def $19, %00100000 ; EVENT_FLAG_6D + flag_def $19, %00010000 ; EVENT_FLAG_6E + flag_def $19, %00001000 ; EVENT_FLAG_6F + flag_def $19, %00000100 ; EVENT_FLAG_70 + flag_def $19, %00111100 ; EVENT_FLAG_71 + flag_def $1a, %11111100 ; EVENT_FLAG_72 + flag_def $1a, %00000011 ; EVENT_FLAG_73 + flag_def $1b, %11111111 ; EVENT_FLAG_74 + flag_def $1c, %11110000 ; EVENT_FLAG_75 + flag_def $1c, %00001111 ; EVENT_FLAG_76 + +; Used for basic level objects that just print text and quit +PrintInteractableObjectText: ; cc25 (3:4c25) + ld hl, wDefaultObjectText + ld a, [hli] + ld h, [hl] + ld l, a + call Func_cc32 + call CloseAdvancedDialogueBox + ret Func_cc32: ; cc32 (3:4c32) push hl - ld hl, wd0c8 + ld hl, wCurrentNPCNameTx ld e, [hl] inc hl ld d, [hl] @@ -1575,74 +1732,76 @@ Func_cc32: ; cc32 (3:4c32) call Func_c8ba ret -Clerk10NPCScript: ; cc3e (3:4c3e) -Clerk11NPCScript: ; cc3e (3:4c3e) -Woman2NPCScript: ; cc3e (3:4c3e) -TorchNPCScript: ; cc3e (3:4c3e) -LegendaryCardTopLeftNPCScript: ; cc3e (3:4c3e) -LegendaryCardTopRightNPCScript: ; cc3e (3:4c3e) -LegendaryCardBottomLeftNPCScript: ; cc3e (3:4c3e) -LegendaryCardBottomCenterLeftNPCScript: ; cc3e (3:4c3e) -LegendaryCardBottomCenterRightNPCScript: ; cc3e (3:4c3e) -LegendaryCardBottomRightNPCScript: ; cc3e (3:4c3e) - call CloseDialogueBox +; Used for things that are represented as NPCs but don't have a Script +; EX: Clerks and legendary cards that interact through Level Objects +Script_Clerk10: ; cc3e (3:4c3e) +Script_GiftCenterClerk: ; cc3e (3:4c3e) +Script_Woman2: ; cc3e (3:4c3e) +Script_Torch: ; cc3e (3:4c3e) +Script_LegendaryCardTopLeft: ; cc3e (3:4c3e) +Script_LegendaryCardTopRight: ; cc3e (3:4c3e) +Script_LegendaryCardLeftSpark: ; cc3e (3:4c3e) +Script_LegendaryCardBottomLeft: ; cc3e (3:4c3e) +Script_LegendaryCardBottomRight: ; cc3e (3:4c3e) +Script_LegendaryCardRightSpark: ; cc3e (3:4c3e) + call CloseAdvancedDialogueBox ret -; called when pressing a in front of an object. creates a pointer to the data right after an RST20 -; was called, then runs RunOverworldScript to handle that data +; Enters into the script loop, continuing until wBreakScriptLoop > 0 +; When the loop is broken, it resumes normal code execution where script ended +; Note: Some scripts "double return" and skip this. RST20: ; cc42 (3:4c42) pop hl ld a, l - ld [wOWScriptPointer], a + ld [wScriptPointer], a ld a, h - ld [wOWScriptPointer+1], a + ld [wScriptPointer+1], a xor a - ld [wBreakOWScriptLoop], a -.asm_cc4f + ld [wBreakScriptLoop], a +.continueScriptLoop call RunOverworldScript - ld a, [wBreakOWScriptLoop] ; if you break out, it jumps + ld a, [wBreakScriptLoop] ; if you break out, it jumps or a - jr z, .asm_cc4f - ld hl, wOWScriptPointer + jr z, .continueScriptLoop + ld hl, wScriptPointer ld a, [hli] ld c, a ld b, [hl] - push bc - ret + retbc -IncreaseOWScriptPointerBy1: ; cc60 (3:4c60) +IncreaseScriptPointerBy1: ; cc60 (3:4c60) ld a, 1 - jr IncreaseOWScriptPointer -IncreaseOWScriptPointerBy2: ; cc64 (3:4c64) + jr IncreaseScriptPointer +IncreaseScriptPointerBy2: ; cc64 (3:4c64) ld a, 2 - jr IncreaseOWScriptPointer -IncreaseOWScriptPointerBy4: ; cc68 (3:4c68) + jr IncreaseScriptPointer +IncreaseScriptPointerBy4: ; cc68 (3:4c68) ld a, 4 - jr IncreaseOWScriptPointer -IncreaseOWScriptPointerBy5: ; cc6c (3:4c6c) + jr IncreaseScriptPointer +IncreaseScriptPointerBy5: ; cc6c (3:4c6c) ld a, 5 - jr IncreaseOWScriptPointer -IncreaseOWScriptPointerBy6: ; cc70 (3:4c70) + jr IncreaseScriptPointer +IncreaseScriptPointerBy6: ; cc70 (3:4c70) ld a, 6 - jr IncreaseOWScriptPointer -IncreaseOWScriptPointerBy7: ; cc74 (3:4c74) + jr IncreaseScriptPointer +IncreaseScriptPointerBy7: ; cc74 (3:4c74) ld a, 7 - jr IncreaseOWScriptPointer -IncreaseOWScriptPointerBy3: ; cc78 (3:4c78) + jr IncreaseScriptPointer +IncreaseScriptPointerBy3: ; cc78 (3:4c78) ld a, 3 -IncreaseOWScriptPointer: ; cc7a (3:4c7a) +IncreaseScriptPointer: ; cc7a (3:4c7a) ld c, a - ld a, [wOWScriptPointer] + ld a, [wScriptPointer] add c - ld [wOWScriptPointer], a - ld a, [wOWScriptPointer+1] + ld [wScriptPointer], a + ld a, [wScriptPointer+1] adc 0 - ld [wOWScriptPointer+1], a + ld [wScriptPointer+1], a ret -SetOWScriptPointer: ; cc8b (3:4c8b) - ld hl, wOWScriptPointer +SetScriptPointer: ; cc8b (3:4c8b) + ld hl, wScriptPointer ld [hl], c inc hl ld [hl], b @@ -1651,23 +1810,23 @@ SetOWScriptPointer: ; cc8b (3:4c8b) INCROM $cc92, $cc96 -GetOWSArgs1AfterPointer: ; cc96 (3:4c96) +GetScriptArgs1AfterPointer: ; cc96 (3:4c96) ld a, $1 - jr GetOWSArgsAfterPointer + jr GetScriptArgsAfterPointer -GetOWSArgs2AfterPointer: ; cc9a (3:4c9a) +GetScriptArgs2AfterPointer: ; cc9a (3:4c9a) ld a, $2 - jr GetOWSArgsAfterPointer -GetOWSArgs3AfterPointer: ; cc9e (3:4c9e) + jr GetScriptArgsAfterPointer +GetScriptArgs3AfterPointer: ; cc9e (3:4c9e) ld a, $3 -GetOWSArgsAfterPointer: ; cca0 (3:4ca0) +GetScriptArgsAfterPointer: ; cca0 (3:4ca0) push hl ld l, a - ld a, [wOWScriptPointer] + ld a, [wScriptPointer] add l ld l, a - ld a, [wOWScriptPointer+1] + ld a, [wScriptPointer+1] adc $0 ld h, a ld a, [hli] @@ -1677,79 +1836,82 @@ GetOWSArgsAfterPointer: ; cca0 (3:4ca0) or b ret -Func_ccb3: ; ccb3 (3:4cb3) +SetScriptControlBytePass: ; ccb3 (3:4cb3) ld a, $ff - ld [wd415], a + ld [wScriptControlByte], a ret -Func_ccb9: ; ccb9 (3:4cb9) +SetScriptControlByteFail: ; ccb9 (3:4cb9) xor a - ld [wd415], a - ret - -OWScript_EndScriptLoop1: ; ccbe (3:4cbe) -OWScript_EndScriptLoop2: ; ccbe (3:4cbe) -OWScript_EndScriptLoop3: ; ccbe (3:4cbe) -OWScript_EndScriptLoop4: ; ccbe (3:4cbe) -OWScript_EndScriptLoop5: ; ccbe (3:4cbe) -OWScript_EndScriptLoop6: ; ccbe (3:4cbe) -OWScript_EndScriptLoop7: ; ccbe (3:4cbe) -OWScript_EndScriptLoop8: ; ccbe (3:4cbe) -OWScript_EndScriptLoop9: ; ccbe (3:4cbe) -OWScript_EndScriptLoop10: ; ccbe (3:4cbe) + ld [wScriptControlByte], a + ret + +; Exits Script mode and runs the next instruction like normal +ScriptCommand_EndScriptLoop1: ; ccbe (3:4cbe) +ScriptCommand_EndScriptLoop2: ; ccbe (3:4cbe) +ScriptCommand_EndScriptLoop3: ; ccbe (3:4cbe) +ScriptCommand_EndScriptLoop4: ; ccbe (3:4cbe) +ScriptCommand_EndScriptLoop5: ; ccbe (3:4cbe) +ScriptCommand_EndScriptLoop6: ; ccbe (3:4cbe) +ScriptCommand_EndScriptLoop7: ; ccbe (3:4cbe) +ScriptCommand_EndScriptLoop8: ; ccbe (3:4cbe) +ScriptCommand_EndScriptLoop9: ; ccbe (3:4cbe) +ScriptCommand_EndScriptLoop10: ; ccbe (3:4cbe) ld a, $01 - ld [wBreakOWScriptLoop], a - jp IncreaseOWScriptPointerBy1 + ld [wBreakScriptLoop], a + jp IncreaseScriptPointerBy1 -OWScript_CloseTextBox: ; ccc6 (3:4cc6) - call CloseDialogueBox - jp IncreaseOWScriptPointerBy1 +ScriptCommand_CloseAdvancedTextBox: ; ccc6 (3:4cc6) + call CloseAdvancedDialogueBox + jp IncreaseScriptPointerBy1 -OWScript_EndScriptCloseText: ; cccc (3:4ccc) - call OWScript_CloseTextBox - call OWScript_EndScriptLoop1 +ScriptCommand_QuitScriptFully: ; cccc (3:4ccc) + call ScriptCommand_CloseAdvancedTextBox + call ScriptCommand_EndScriptLoop1 pop hl ret ; args: 2-Text String Index -OWScript_PrintTextString: ; ccd4 (3:4cd4) +ScriptCommand_PrintTextString: ; ccd4 (3:4cd4) ld l, c ld h, b call Func_cc32 - jp IncreaseOWScriptPointerBy3 + jp IncreaseScriptPointerBy3 Func_ccdc: ; ccdc (3:4cdc) ld l, c ld h, b call Func_c891 - jp IncreaseOWScriptPointerBy3 + jp IncreaseScriptPointerBy3 -Func_cce4: ; cce4 (3:4ce4) +ScriptCommand_AskQuestionJumpDefaultYes: ; cce4 (3:4ce4) ld a, $1 ld [wDefaultYesOrNo], a +; fallthrough -; Asks the player a question then jumps if they answer yes -OWScript_AskQuestionJump: ; cce9 (3:4ce9) +; Asks the player a question then jumps if they answer yes. Seem to be able to +; take a text of 0000 to overwrite last with (yes no) prompt at the bottom +ScriptCommand_AskQuestionJump: ; cce9 (3:4ce9) ld l, c ld h, b call Func_c8ed ld a, [hCurMenuItem] - ld [wd415], a + ld [wScriptControlByte], a jr c, .asm_ccfe - call GetOWSArgs3AfterPointer + call GetScriptArgs3AfterPointer jr z, .asm_ccfe - jp SetOWScriptPointer + jp SetScriptPointer .asm_ccfe - jp IncreaseOWScriptPointerBy5 + jp IncreaseScriptPointerBy5 ; args - prize cards, deck id, duel theme index ; sets a battle up, doesn't start until we break out of the script system. -OWScript_StartBattle: ; cd01 (3:4d01) +ScriptCommand_StartBattle: ; cd01 (3:4d01) call Func_cd66 - ld a, [wd3b6] - ld l, $0 - call Func_39ad + ld a, [wScriptNPC] + ld l, LOADED_NPC_ID + call GetItemInLoadedNPCIndex ld a, [hl] farcall Func_118d3 ld a, [wcc19] @@ -1758,14 +1920,14 @@ OWScript_StartBattle: ; cd01 (3:4d01) ld a, [wd695] ld c, a ld b, $0 - ld hl, $4d63 + ld hl, AaronDeckIDs add hl, bc ld a, [hl] ld [wcc19], a .asm_cd26 - ld a, [wd3b6] - ld l, $0 - call Func_39ad + ld a, [wScriptNPC] + ld l, LOADED_NPC_ID + call GetItemInLoadedNPCIndex ld a, [hl] asm_cd2f ld [wd0c4], a @@ -1779,7 +1941,7 @@ asm_cd2f ld [wGameEvent], a ld hl, wd0b4 set 6, [hl] - jp IncreaseOWScriptPointerBy4 + jp IncreaseScriptPointerBy4 Func_cd4f: ; cd4f (3:4d4f) call Func_cd66 @@ -1790,15 +1952,17 @@ Func_cd4f: ; cd4f (3:4d4f) ld a, [wd696] jr asm_cd2f -Unknown_dd63: ; cd4f (3:4d4f) - INCROM $cd63, $cd66 +AaronDeckIDs: ; cd63 (3:4d63) + db LIGHTNING_AND_FIRE_DECK_ID + db WATER_AND_FIGHTING_DECK_ID + db GRASS_AND_PSYCHIC_DECK_ID Func_cd66: ; cd66 (3:4d66) ld a, c ld [wcc18], a ld a, b ld [wcc19], a - call GetOWSArgs3AfterPointer + call GetScriptArgs3AfterPointer ld a, c ld [wDuelTheme], a ret @@ -1808,103 +1972,106 @@ Func_cd76: ; cd76 (3:4d76) ld [wGameEvent], a ld hl, wd0b4 set 6, [hl] - jp IncreaseOWScriptPointerBy1 + jp IncreaseScriptPointerBy1 -Func_cd83: ; cd83 (3:4d83) - ld a, [wd415] +; prints text arg 1 or arg 2 depending on wScriptControlByte. +ScriptCommand_PrintVariableText: ; cd83 (3:4d83) + ld a, [wScriptControlByte] or a - jr nz, .asm_cd8c - call GetOWSArgs3AfterPointer -.asm_cd8c + jr nz, .printText + call GetScriptArgs3AfterPointer +.printText ld l, c ld h, b call Func_cc32 - jp IncreaseOWScriptPointerBy5 + jp IncreaseScriptPointerBy5 Func_cd94: ; cd94 (3:4d94) - call Func_ca69 - ld b, h + get_flag_value EVENT_FLAG_44 Unknown_cd98: dec a and $3 add a inc a - call GetOWSArgsAfterPointer + call GetScriptArgsAfterPointer ld l, c ld h, b call Func_cc32 - jp IncreaseOWScriptPointerBy7 + jp IncreaseScriptPointerBy7 Func_cda8: ; cda8 (3:4da8) - ld a, [wd415] + ld a, [wScriptControlByte] or a jr nz, .asm_cdb1 - call GetOWSArgs3AfterPointer + call GetScriptArgs3AfterPointer .asm_cdb1 ld l, c ld h, b call Func_c891 - jp IncreaseOWScriptPointerBy5 + jp IncreaseScriptPointerBy5 -OWScript_PrintTextCloseBox: ; cdb9 (3:4db9) +; Does not return to RST20 - pops an extra time to skip that. +ScriptCommand_PrintTextQuitFully: ; cdb9 (3:4db9) ld l, c ld h, b call Func_cc32 - call CloseDialogueBox + call CloseAdvancedDialogueBox ld a, $1 - ld [wBreakOWScriptLoop], a - call IncreaseOWScriptPointerBy3 + ld [wBreakScriptLoop], a + call IncreaseScriptPointerBy3 pop hl ret Func_cdcb: ; cdcb (3:4dcb) - ld a, [wd3b6] - ld [wd3aa], a + ld a, [wScriptNPC] + ld [wLoadedNPCTempIndex], a Func_cdd1: ; cdd1 (3:4dd1) farcall Func_1c50a - jp IncreaseOWScriptPointerBy1 + jp IncreaseScriptPointerBy1 Func_cdd8: ; cdd8 (3:4dd8) - ld a, [wd3aa] + ld a, [wLoadedNPCTempIndex] push af - ld a, [wd3ab] + ld a, [wTempNPC] push af ld a, [wd696] - ld [wd3ab], a - call Func_39c3 + ld [wTempNPC], a + call FindLoadedNPC call Func_cdd1 pop af - ld [wd3ab], a + ld [wTempNPC], a pop af - ld [wd3aa], a + ld [wLoadedNPCTempIndex], a ret Func_cdf5: ; cdf5 (3:4df5) - ld a, [wd3aa] + ld a, [wLoadedNPCTempIndex] push af - ld a, [wd3ab] + ld a, [wTempNPC] push af ld a, [wd696] - ld [wd3ab], a + ld [wTempNPC], a ld a, c - ld [wd3ac], a + ld [wLoadNPCXPos], a ld a, b - ld [wd3ad], a + ld [wLoadNPCYPos], a ld a, $2 - ld [wd3ae], a - ld a, [wd3ab] - farcall Func_11857 + ld [wLoadNPCDirection], a + ld a, [wTempNPC] + farcall LoadNPCSpriteData farcall Func_1c485 pop af - ld [wd3ab], a + ld [wTempNPC], a pop af - ld [wd3aa], a - jp IncreaseOWScriptPointerBy3 - -Func_ce26: ; ce26 (3:4e26) - ld a, [wd3b6] - ld [wd3aa], a - farcall Func_1c455 + ld [wLoadedNPCTempIndex], a + jp IncreaseScriptPointerBy3 + +; Finds and executes an NPCMovement script in the table provided in bc +; based on the active NPC's current direction +ScriptCommand_MoveActiveNPCByDirection: ; ce26 (3:4e26) + ld a, [wScriptNPC] + ld [wLoadedNPCTempIndex], a + farcall GetNPCDirection rlca add c ld l, a @@ -1914,56 +2081,67 @@ Func_ce26: ; ce26 (3:4e26) ld c, [hl] inc hl ld b, [hl] +; fallthrough -Func_ce3a: ; ce3a (3:4e3a) +; Moves an NPC given the list of directions pointed to by bc +; set bit 7 to only rotate the NPC +ExecuteNPCMovement: ; ce3a (3:4e3a) farcall Func_1c78d .asm_ce3e call DoFrameIfLCDEnabled farcall Func_1c7de jr nz, .asm_ce3e - jp IncreaseOWScriptPointerBy3 - -Func_ce4a: ; ce4a (3:4e4a) - ld a, [wd3b6] - ld [wd3aa], a - jr Func_ce3a - -Func_ce52: ; ce52 (3:4e52) - ld a, [wd3aa] + jp IncreaseScriptPointerBy3 + +; Begin a series of NPC movements on the currently talking NPC +; based on the series of directions pointed to by bc +ScriptCommand_MoveActiveNPC: ; ce4a (3:4e4a) + ld a, [wScriptNPC] + ld [wLoadedNPCTempIndex], a + jr ExecuteNPCMovement + +; Begin a series of NPC movements on an arbitrary NPC +; based on the series of directions pointed to by bc +ScriptCommand_MoveWramNPC: ; ce52 (3:4e52) + ld a, [wLoadedNPCTempIndex] push af - ld a, [wd3ab] + ld a, [wTempNPC] push af ld a, [wd696] -asm_ce5d - ld [wd3ab], a - call Func_39c3 - call Func_ce3a +; fallthrough + +; Executes movement on an arbitrary NPC using values in a and on the stack +; Changes and fixes Temp NPC using stack values +ExecuteArbitraryNPCMovementFromStack + ld [wTempNPC], a + call FindLoadedNPC + call ExecuteNPCMovement pop af - ld [wd3ab], a + ld [wTempNPC], a pop af - ld [wd3aa], a + ld [wLoadedNPCTempIndex], a ret -Func_ce6f: ; ce6f (3:4e6f) - ld a, [wd3aa] +ScriptCommand_MoveArbitraryNPC: ; ce6f (3:4e6f) + ld a, [wLoadedNPCTempIndex] push af - ld a, [wd3ab] + ld a, [wTempNPC] push af ld a, c push af - call GetOWSArgs2AfterPointer + call GetScriptArgs2AfterPointer push bc - call IncreaseOWScriptPointerBy1 + call IncreaseScriptPointerBy1 pop bc pop af - jr asm_ce5d + jr ExecuteArbitraryNPCMovementFromStack -Func_ce84: ; ce84 (3:4e84) - call Func_c135 - jp IncreaseOWScriptPointerBy1 +ScriptCommand_CloseTextBox: ; ce84 (3:4e84) + call CloseTextBox + jp IncreaseScriptPointerBy1 ; args: booster pack index, booster pack index, booster pack index -OWScript_GiveBoosterPacks: ; ce8a (3:4e8a) +ScriptCommand_GiveBoosterPacks: ; ce8a (3:4e8a) xor a ld [wd117], a push bc @@ -1976,42 +2154,48 @@ OWScript_GiveBoosterPacks: ; ce8a (3:4e8a) ld [wd117], a pop bc ld a, b - cp $ff + cp NO_BOOSTER jr z, .asm_ceb4 farcall BoosterPack_1031b - call GetOWSArgs3AfterPointer + call GetScriptArgs3AfterPointer ld a, c - cp $ff + cp NO_BOOSTER jr z, .asm_ceb4 farcall BoosterPack_1031b .asm_ceb4 call Func_c2d4 - jp IncreaseOWScriptPointerBy4 + jp IncreaseScriptPointerBy4 -Func_ceba: ; ceba (3:4eba) +ScriptCommand_GiveOneOfEachTrainerBooster: ; ceba (3:4eba) xor a ld [wd117], a call Func_c2a3 - ld hl, $4edd -.asm_cec4 + ld hl, .booster_type_table +.giveBoosterLoop ld a, [hl] - cp $ff - jr z, .asm_ced7 + cp NO_BOOSTER + jr z, .done push hl farcall BoosterPack_1031b ld a, $1 ld [wd117], a pop hl inc hl - jr .asm_cec4 -.asm_ced7 + jr .giveBoosterLoop +.done call Func_c2d4 - jp IncreaseOWScriptPointerBy1 -; 0xcedd - - INCROM $cedd, $cee2 - -Func_cee2: ; cee2 (3:4ee2) + jp IncreaseScriptPointerBy1 + +.booster_type_table + db BOOSTER_COLOSSEUM_TRAINER + db BOOSTER_EVOLUTION_TRAINER + db BOOSTER_MYSTERY_TRAINER_COLORLESS + db BOOSTER_LABORATORY_TRAINER + db NO_BOOSTER ; $ff + +; Shows the card received screen for a given promotional card +; arg can either be the card, $00 for a wram card, or $ff for the 4 legends +ScriptCommand_ShowCardReceivedScreen: ; cee2 (3:4ee2) call Func_c2a3 ld a, c cp $ff @@ -2029,7 +2213,7 @@ Func_cee2: ; cee2 (3:4ee2) call WhiteOutDMGPals call DoFrameIfLCDEnabled call Func_c2d4 - jp IncreaseOWScriptPointerBy2 + jp IncreaseScriptPointerBy2 .asm_cf09 xor a @@ -2049,21 +2233,21 @@ asm_cf16 jr nz, asm_cf1f asm_cf19 - call Func_ccb9 - jp IncreaseOWScriptPointerBy4 + call SetScriptControlByteFail + jp IncreaseScriptPointerBy4 asm_cf1f - call Func_ccb3 - call GetOWSArgs2AfterPointer + call SetScriptControlBytePass + call GetScriptArgs2AfterPointer jr z, asm_cf2a - jp SetOWScriptPointer + jp SetScriptPointer asm_cf2a - jp IncreaseOWScriptPointerBy4 + jp IncreaseScriptPointerBy4 Func_cf2d: ; cf2d (3:4f2d) push bc - call IncreaseOWScriptPointerBy1 + call IncreaseScriptPointerBy1 pop bc call GetRawAmountOfCardsOwned ld a, h @@ -2076,20 +2260,21 @@ Func_cf2d: ; cf2d (3:4f2d) jr nc, asm_cf1f jr asm_cf19 -Func_cf3f: ; cf3f (3:4f3f) +; Gives the first arg as a card. If that's 0 pulls from wd697 +ScriptCommand_GiveCard: ; cf3f (3:4f3f) ld a, c or a - jr nz, .asm_cf46 + jr nz, .giveCard ld a, [wd697] -.asm_cf46 +.giveCard call AddCardToCollection - jp IncreaseOWScriptPointerBy2 + jp IncreaseScriptPointerBy2 -Func_cf4c: ; cf4c (3:4f4c) +ScriptCommand_TakeCard: ; cf4c (3:4f4c) ld a, c call RemoveCardFromCollection - jp IncreaseOWScriptPointerBy2 + jp IncreaseScriptPointerBy2 Func_cf53: ; cf53 (3:4f53) ld c, $1 @@ -2107,17 +2292,17 @@ Func_cf53: ; cf53 (3:4f53) or a jr nz, Func_cf6d Func_cf67: ; cf67 (3:4f67) - call Func_ccb9 - jp IncreaseOWScriptPointerBy3 + call SetScriptControlByteFail + jp IncreaseScriptPointerBy3 Func_cf6d: ; cf6d (3:4f6d) - call Func_ccb3 - call GetOWSArgs1AfterPointer + call SetScriptControlBytePass + call GetScriptArgs1AfterPointer jr z, .asm_cf78 - jp SetOWScriptPointer + jp SetScriptPointer .asm_cf78 - jp IncreaseOWScriptPointerBy3 + jp IncreaseScriptPointerBy3 Func_cf7b: ; cf7b (3:4f7b) ld c, $1 @@ -2139,50 +2324,48 @@ Func_cf7b: ; cf7b (3:4f7b) ld a, c cp $8 jr c, .asm_cf7d - jp IncreaseOWScriptPointerBy1 + jp IncreaseScriptPointerBy1 -; This function doesn't look like a valid function, but it's pointed to in the table. Func_cf96: ; cf96 (3:4f96) ld c, $0 - call Func_ca69 - ld de, $28b7 - ld hl, $08fe + get_flag_value EVENT_FLAG_11 + or a + jr z, Func_cfc0 + cp a, $08 jr c, .asm_cfa4 inc c .asm_cfa4 - call Func_ca69 - rla + get_flag_value EVENT_FLAG_17 cp $8 jr c, .asm_cfad inc c .asm_cfad - call Func_ca69 -.asm_cfb0 - jr nz, .asm_cfb0 - ld [$0138], sp + get_flag_value EVENT_FLAG_20 + cp a, $08 + jr c, .asm_cfb6 inc c +.asm_cfb6 ld a, c rlca add $3 - call GetOWSArgsAfterPointer - jp SetOWScriptPointer + call GetScriptArgsAfterPointer + jp SetScriptPointer Func_cfc0: ; cfc0 (3:4fc0) - call GetOWSArgs1AfterPointer - jp SetOWScriptPointer + call GetScriptArgs1AfterPointer + jp SetScriptPointer Func_cfc6: ; cfc6 (3:4fc6) - ld a, [wd3b6] - ld [wd3aa], a + ld a, [wScriptNPC] + ld [wLoadedNPCTempIndex], a ld a, c farcall Func_1c52e - jp IncreaseOWScriptPointerBy2 + jp IncreaseScriptPointerBy2 Func_cfd4: ; cfd4 (3:4fd4) - call Func_ca69 - dec l + get_flag_value EVENT_FLAG_2D ld b, a .asm_cfd9 ld a, $5 @@ -2206,17 +2389,16 @@ Func_cfd4: ; cfd4 (3:4fd4) or b push bc ld c, a - call Func_ca8f - dec l + set_flag_value EVENT_FLAG_2D pop bc ld b, $0 - ld hl, $5006 + ld hl, Data_d006 add hl, bc ld c, [hl] - call Func_ca8f - dec hl - jp IncreaseOWScriptPointerBy1 + set_flag_value EVENT_FLAG_2B + jp IncreaseScriptPointerBy1 +Data_d006: ; d006 (3:5006) INCROM $d006, $d00b Func_d00b: ; d00b (3:500b) @@ -2225,8 +2407,7 @@ Func_d00b: ; d00b (3:500b) ld hl, wTxRam2 add hl, bc push hl - call Func_ca69 - dec hl + get_flag_value EVENT_FLAG_2B ld e, a ld d, $0 call GetCardName @@ -2234,79 +2415,77 @@ Func_d00b: ; d00b (3:500b) ld [hl], e inc hl ld [hl], d - jp IncreaseOWScriptPointerBy2 + jp IncreaseScriptPointerBy2 Func_d025: ; d025 (3:5025) - call Func_ca69 - dec hl + get_flag_value EVENT_FLAG_2B call GetCardCountInCollectionAndDecks jp c, Func_cf67 jp Func_cf6d Func_d032: ; d032 (3:5032) - call Func_ca69 - dec hl + get_flag_value EVENT_FLAG_2B call GetCardCountInCollection jp c, Func_cf67 jp Func_cf6d Func_d03f: ; d03f (3:503f) - call Func_ca69 - dec hl + get_flag_value EVENT_FLAG_2B call RemoveCardFromCollection - jp IncreaseOWScriptPointerBy1 + jp IncreaseScriptPointerBy1 -OWScript_ScriptJump: ; d049 (3:5049) - call GetOWSArgs1AfterPointer - jp SetOWScriptPointer +ScriptCommand_Jump: ; d049 (3:5049) + call GetScriptArgs1AfterPointer + jp SetScriptPointer -Func_d04f: ; d04f (3:504f) - call Func_cad8 - jp IncreaseOWScriptPointerBy1 +ScriptCommand_TryGiveMedalPCPacks: ; d04f (3:504f) + call TryGiveMedalPCPacks + jp IncreaseScriptPointerBy1 -Func_d055: ; d055 (3:5055) +ScriptCommand_SetPlayerDirection: ; d055 (3:5055) ld a, c - call Func_c5ce - jp IncreaseOWScriptPointerBy2 - + call UpdatePlayerDirection + jp IncreaseScriptPointerBy2 -OWScript_MovePlayer: ; 505c (3:505c) +; arg1 - Direction (index in PlayerMovementOffsetTable) +; arg2 - Tiles Moves (Speed) +ScriptCommand_MovePlayer: ; 505c (3:505c) ld a, c ld [wd339], a ld a, b ld [wd33a], a - call StartScriptedMovement + call StartScript_dMovement .asm_d067 call DoFrameIfLCDEnabled call SetScreenScroll call Func_c53d - ld a, [wd335] + ld a, [wPlayerCurrentlyMoving] and $03 jr nz, .asm_d067 call DoFrameIfLCDEnabled call SetScreenScroll - jp IncreaseOWScriptPointerBy3 + jp IncreaseScriptPointerBy3 -Func_d080: ; d080 (3:5080) +ScriptCommand_SetDialogName: ; d080 (3:5080) ld a, c - farcall Func_11893 - jp IncreaseOWScriptPointerBy2 + farcall SetNPCDialogName + jp IncreaseScriptPointerBy2 -Func_d088: ; d088 (3:5088) +ScriptCommand_SetNextNPCandScript: ; d088 (3:5088) ld a, c - ld [wd3ab], a - call GetOWSArgs2AfterPointer - call Func_c926 - jp IncreaseOWScriptPointerBy4 + ld [wTempNPC], a + call GetScriptArgs2AfterPointer + call SetNextNPCAndScript + jp IncreaseScriptPointerBy4 Func_d095: ; d095 (3:5095) - ld a, [wd3b6] - ld [wd3aa], a + ld a, [wScriptNPC] + ld [wLoadedNPCTempIndex], a push bc - call GetOWSArgs3AfterPointer - ld a, [wd3b6] - ld l, $5 - call Func_39ad + call GetScriptArgs3AfterPointer + ld a, [wScriptNPC] + ld l, LOADED_NPC_FIELD_05 + call GetItemInLoadedNPCIndex res 4, [hl] ld a, [hl] or c @@ -2321,56 +2500,56 @@ Func_d095: ; d095 (3:5095) .asm_d0b6 ld a, e farcall Func_1c57b - jp IncreaseOWScriptPointerBy4 + jp IncreaseScriptPointerBy4 Func_d0be: ; d0be (3:50be) - ld a, [wd3b6] - ld [wd3aa], a + ld a, [wScriptNPC] + ld [wLoadedNPCTempIndex], a ld a, c ld c, b ld b, a farcall Func_1c461 - jp IncreaseOWScriptPointerBy3 + jp IncreaseScriptPointerBy3 -Func_d0ce: ; d0ce (3:50ce) +ScriptCommand_DoFrames: ; d0ce (3:50ce) push bc call DoFrameIfLCDEnabled pop bc dec c - jr nz, Func_d0ce - jp IncreaseOWScriptPointerBy2 + jr nz, ScriptCommand_DoFrames + jp IncreaseScriptPointerBy2 Func_d0d9: ; d0d9 (3:50d9) - ld a, [wd3b6] - ld [wd3aa], a + ld a, [wScriptNPC] + ld [wLoadedNPCTempIndex], a ld d, c ld e, b farcall Func_1c477 ld a, e cp c - jp nz, Func_d48a + jp nz, ScriptEventFailedNoJump ld a, d cp b - jp nz, Func_d48a - jp Func_d490 + jp nz, ScriptEventFailedNoJump + jp ScriptEventPassedTryJump -Func_d0f2: ; d0f2 (3:50f2) +ScriptCommand_JumpIfPlayerCoordMatches: ; d0f2 (3:50f2) ld a, [wPlayerXCoord] cp c - jp nz, Func_d48a + jp nz, ScriptEventFailedNoJump ld a, [wPlayerYCoord] cp b - jp nz, Func_d48a - jp Func_d490 + jp nz, ScriptEventFailedNoJump + jp ScriptEventPassedTryJump Func_d103: ; d103 (3:5103) - ld a, [wd3aa] + ld a, [wLoadedNPCTempIndex] push af - ld a, [wd3ab] + ld a, [wTempNPC] push af ld a, c - ld [wd3ab], a - call Func_39c3 + ld [wTempNPC], a + call FindLoadedNPC jr c, .asm_d119 call $54d1 jr .asm_d11c @@ -2380,9 +2559,9 @@ Func_d103: ; d103 (3:5103) .asm_d11c pop af - ld [wd3ab], a + ld [wTempNPC], a pop af - ld [wd3aa], a + ld [wLoadedNPCTempIndex], a ret Func_d125: ; d125 (3:5125) @@ -2392,7 +2571,7 @@ Func_d125: ; d125 (3:5125) pop af farcall Medal_1029e call Func_c2d4 - jp IncreaseOWScriptPointerBy2 + jp IncreaseScriptPointerBy2 Func_d135: ; d135 (3:5135) sla c @@ -2413,12 +2592,12 @@ Func_d135: ; d135 (3:5135) ld [hl], e inc hl ld [hl], d - jp IncreaseOWScriptPointerBy2 + jp IncreaseScriptPointerBy2 INCROM $d153, $d16b Func_d16b: ; d16b (3:516b) - ld hl, wd0c8 + ld hl, wCurrentNPCNameTx ld e, [hl] inc hl ld d, [hl] @@ -2429,46 +2608,44 @@ Func_d16b: ; d16b (3:516b) add hl, bc push hl ld a, [wd696] - farcall Func_11893 + farcall SetNPCDialogName pop hl - ld a, [wd0c8] + ld a, [wCurrentNPCNameTx] ld [hli], a - ld a, [wd0c9] + ld a, [wCurrentNPCNameTx+1] ld [hl], a pop de - ld hl, wd0c8 + ld hl, wCurrentNPCNameTx ld [hl], e inc hl ld [hl], d - jp IncreaseOWScriptPointerBy2 + jp IncreaseScriptPointerBy2 Func_d195: ; d195 (3:5195) - ld a, [wd3ab] + ld a, [wTempNPC] push af - call Func_ca69 - ld b, l + get_flag_value EVENT_FLAG_45 inc a ld c, a - call Func_ca8f - ld b, l + set_flag_value EVENT_FLAG_45 call Func_f580 pop af - ld [wd3ab], a - jp IncreaseOWScriptPointerBy1 + ld [wTempNPC], a + jp IncreaseScriptPointerBy1 Func_d1ad: ; d1ad (3:51ad) call MainMenu_c75a - jp IncreaseOWScriptPointerBy1 + jp IncreaseScriptPointerBy1 Func_d1b3: ; d1b3 (3:51b3) - call Func_ca69 - ld b, h + get_flag_value EVENT_FLAG_44 dec a cp $2 jr c, .asm_d1c3 ld a, $d call Random add $2 +; fallthrough .asm_d1c3 ld hl, $51dc @@ -2485,13 +2662,12 @@ asm_d1c6 ld [wTxRam2], a ld a, [hl] ld [wTxRam2 + 1], a - jp IncreaseOWScriptPointerBy1 + jp IncreaseScriptPointerBy1 INCROM $d1dc, $d209 Func_d209: ; d209 (3:5209) - call Func_ca69 - ld [hl], c + get_flag_value EVENT_FLAG_71 ld e, a .asm_d20e call UpdateRNGSources @@ -2511,21 +2687,35 @@ Func_d209: ; d209 (3:5209) jr nz, .asm_d20e push bc ld b, $0 - ld hl, $5240 + ld hl, Flags_d240 add hl, bc ld a, [hl] - call SetEventFlags + call MaxOutEventFlag pop bc - ld hl, $5234 + ld hl, LegendaryCards ld a, c jr asm_d1c6 - INCROM $d234, $d244 +LegendaryCards: ; d234 (3:5234) + db ZAPDOS3 + tx Text03f0 + db MOLTRES2 + tx Text03f1 + db ARTICUNO2 + tx Text03f2 + db DRAGONITE1 + tx Text03f3 + +Flags_d240: ; d240 (3:5240) + db EVENT_FLAG_6D + db EVENT_FLAG_6E + db EVENT_FLAG_6F + db EVENT_FLAG_70 Func_d244: ; d244 (3:5244) ld a, c farcall Func_80ba4 - jp IncreaseOWScriptPointerBy2 + jp IncreaseScriptPointerBy2 Func_d24c: ; d24c (3:524c) ld hl, $525e @@ -2533,9 +2723,8 @@ Func_d24c: ; d24c (3:524c) call Func_d28c ld a, [wd695] ld c, a - call Func_ca8f - halt - jp IncreaseOWScriptPointerBy1 + set_flag_value EVENT_FLAG_76 + jp IncreaseScriptPointerBy1 INCROM $d25e, $d271 @@ -2543,7 +2732,7 @@ Func_d271: ; d271 (3:5271) ld hl, $527b xor a call Func_d28c - jp IncreaseOWScriptPointerBy1 + jp IncreaseScriptPointerBy1 ; 0xd27b INCROM $d27b, $d28c @@ -2630,11 +2819,10 @@ Func_d2f6: ; d2f6 (3:52f6) call Func_d28c ld a, [wd694] ld c, a - call Func_ca8f - ld [hl], l + set_flag_value EVENT_FLAG_75 xor a ld [wd694], a - jp IncreaseOWScriptPointerBy1 + jp IncreaseScriptPointerBy1 ; 0xd30c INCROM $d30c, $d317 @@ -2645,14 +2833,13 @@ Func_d317: ; d317 (3:5317) call Func_d28c ld a, [wd694] ld c, a - call Func_ca8f - ld [hl], l - jp IncreaseOWScriptPointerBy1 - + set_flag_value EVENT_FLAG_75 + jp IncreaseScriptPointerBy1 +Unknown_d32b: ; d32b (3:532b) INCROM $d32b, $d336 -OWScript_OpenDeckMachine: ; d336 (3:5336) +ScriptCommand_OpenDeckMachine: ; d336 (3:5336) push bc call Func_c2a3 call PauseSong @@ -2677,34 +2864,35 @@ OWScript_OpenDeckMachine: ; d336 (3:5336) .asm_d364 call ResumeSong call Func_c2d4 - jp IncreaseOWScriptPointerBy2 + jp IncreaseScriptPointerBy2 -Func_d36d: ; d36d (3:536d) - ld a, [wOWScriptPointer] +; args: unused, room, new player x, new player y, new player direction +ScriptCommand_EnterMap: ; d36d (3:536d) + ld a, [wScriptPointer] ld l, a - ld a, [wOWScriptPointer+1] + ld a, [wScriptPointer+1] ld h, a inc hl ld a, [hli] ld a, [hli] - ld [wd0bb], a + ld [wTempMap], a ld a, [hli] - ld [wd0bc], a + ld [wTempPlayerXCoord], a ld a, [hli] - ld [wd0bd], a + ld [wTempPlayerYCoord], a ld a, [hli] - ld [wd0be], a + ld [wTempPlayerDirection], a ld hl, wd0b4 set 4, [hl] - jp IncreaseOWScriptPointerBy6 + jp IncreaseScriptPointerBy6 Func_d38f: ; d38f (3:538f) farcall Func_10c96 - jp IncreaseOWScriptPointerBy2 + jp IncreaseScriptPointerBy2 Func_d396: ; d396 (3:5396) farcall Func_1157c - jp IncreaseOWScriptPointerBy2 + jp IncreaseScriptPointerBy2 Func_d39d: ; d39d (3:539d) ld a, c @@ -2712,8 +2900,7 @@ Func_d39d: ; d39d (3:539d) jr nz, .asm_d3ac farcall Func_10dba ld c, a - call Func_ca8f - ld [hl], d + set_flag_value EVENT_FLAG_72 jr .asm_d3b6 .asm_d3ac @@ -2723,7 +2910,7 @@ Func_d39d: ; d39d (3:539d) set 6, [hl] .asm_d3b6 - jp IncreaseOWScriptPointerBy2 + jp IncreaseScriptPointerBy2 Func_d3b9: ; d3b9 (3:53b9) call Func_3917 @@ -2731,20 +2918,20 @@ Func_d3b9: ; d3b9 (3:53b9) ld [wGameEvent], a ld hl, wd0b4 set 6, [hl] - jp IncreaseOWScriptPointerBy1 + jp IncreaseScriptPointerBy1 -Func_d3c9: ; d3c9 (3:53c9) +ScriptCommand_TryGivePCPack: ; d3c9 (3:53c9) ld a, c - farcall Func_10a70 - jp IncreaseOWScriptPointerBy2 + farcall TryGivePCPack + jp IncreaseScriptPointerBy2 -Func_d3d1: ; d3d1 (3:53d1) - jp IncreaseOWScriptPointerBy1 +ScriptCommand_nop: ; d3d1 (3:53d1) + jp IncreaseScriptPointerBy1 Func_d3d4: ; d3d4 (3:53d4) ld a, [wd693] bank1call Func_7576 - jp IncreaseOWScriptPointerBy1 + jp IncreaseScriptPointerBy1 INCROM $d3dd, $d3e0 @@ -2759,344 +2946,1168 @@ Func_d3e0: ; d3e0 (3:53e0) cp $2 jr nz, .asm_d3e9 farcall Func_10f2e - jp IncreaseOWScriptPointerBy1 + jp IncreaseScriptPointerBy1 Func_d3fe: ; d3fe (3:53fe) ld a, c ld [wd112], a call PlaySong - jp IncreaseOWScriptPointerBy2 + jp IncreaseScriptPointerBy2 Func_d408: ; d408 (3:5408) ld a, c ld [wd111], a - jp IncreaseOWScriptPointerBy2 + jp IncreaseScriptPointerBy2 Func_d40f: ; d40f (3:540f) ld a, c - call Func_3c83 - jp IncreaseOWScriptPointerBy2 + call CallPlaySong + jp IncreaseScriptPointerBy2 -Func_d416: ; d416 (3:5416) +ScriptCommand_PlaySFX: ; d416 (3:5416) ld a, c call PlaySFX - jp IncreaseOWScriptPointerBy2 + jp IncreaseScriptPointerBy2 Func_d41d: ; d41d (3:541d) call Func_39fc - jp IncreaseOWScriptPointerBy1 + jp IncreaseScriptPointerBy1 -Func_d423: ; d423 (3:5423) +ScriptCommand_PauseSong: ; d423 (3:5423) call PauseSong - jp IncreaseOWScriptPointerBy1 + jp IncreaseScriptPointerBy1 -Func_d429: ; d429 (3:5429) +ScriptCommand_ResumeSong: ; d429 (3:5429) call ResumeSong - jp IncreaseOWScriptPointerBy1 + jp IncreaseScriptPointerBy1 -Func_d42f: ; d42f (3:542f) - call Func_3c96 - jp IncreaseOWScriptPointerBy1 +ScriptCommand_WaitForSongToFinish: ; d42f (3:542f) + call WaitForSongToFinish + jp IncreaseScriptPointerBy1 Func_d435: ; d435 (3:5435) ld a, c farcall Func_1c83d - jp IncreaseOWScriptPointerBy2 + jp IncreaseScriptPointerBy2 Func_d43d: ; d43d (3:543d) ld a, GAME_EVENT_CHALLENGE_MACHINE ld [wGameEvent], a ld hl, wd0b4 set 6, [hl] - jp IncreaseOWScriptPointerBy1 + jp IncreaseScriptPointerBy1 -OWScript_CustomModifyEventFlags: ; d44a (3:544a) +; sets the event flag in arg 1 to the value in arg 2 +ScriptCommand_SetFlagValue: ; d44a (3:544a) ld a, c ld c, b - call ModifyEventFlags - jp IncreaseOWScriptPointerBy3 + call SetEventFlagValue + jp IncreaseScriptPointerBy3 -Func_d452: ; d452 (3:5452) +ScriptCommand_IncrementFlagValue: ; d452 (3:5452) ld a, c push af - call CheckIfEventFlagSet + call GetEventFlagValue inc a ld c, a pop af - call ModifyEventFlags - jp IncreaseOWScriptPointerBy2 + call SetEventFlagValue + jp IncreaseScriptPointerBy2 -Func_d460: ; d460 (3:5460) +ScriptCommand_JumpIfFlagZero1: ; d460 (3:5460) ld a, c - call CheckIfEventFlagSet + call GetEventFlagValue or a - jr z, asm_d46d -asm_d467 - call Func_ccb9 - jp IncreaseOWScriptPointerBy4 + jr z, ScriptCommand_JumpIfFlagZero1.passTryJump + +.fail + call SetScriptControlByteFail + jp IncreaseScriptPointerBy4 -asm_d46d - call Func_ccb3 - call GetOWSArgs2AfterPointer - jr z, .asm_d478 - jp SetOWScriptPointer +.passTryJump + call SetScriptControlBytePass + call GetScriptArgs2AfterPointer + jr z, .noJumpTarget + jp SetScriptPointer -.asm_d478 - jp IncreaseOWScriptPointerBy4 +.noJumpTarget + jp IncreaseScriptPointerBy4 -OWScript_JumpIfFlagSet: ; d47b (3:547b) +ScriptCommand_JumpIfFlagNonzero1: ; d47b (3:547b) ld a, c - call CheckIfEventFlagSet + call GetEventFlagValue or a - jr nz, asm_d46d - jr asm_d467 + jr nz, ScriptCommand_JumpIfFlagZero1.passTryJump + jr ScriptCommand_JumpIfFlagZero1.fail -Func_d484: ; d484 (3:5484) - call Func_d4b6 +; args - event flag, value, jump address +ScriptCommand_JumpIfFlagEqual: ; d484 (3:5484) + call GetEventFlagValueBC cp c - jr z, Func_d490 + jr z, ScriptEventPassedTryJump -Func_d48a: ; d48a (3:548a) - call Func_ccb9 - jp IncreaseOWScriptPointerBy5 +ScriptEventFailedNoJump ; d48a (3:548a) + call SetScriptControlByteFail + jp IncreaseScriptPointerBy5 -Func_d490: ; d490 (3:5490) - call Func_ccb3 - call GetOWSArgs3AfterPointer - jr z, .asm_d49b - jp SetOWScriptPointer +ScriptEventPassedTryJump ; d490 (3:5490) + call SetScriptControlBytePass + call GetScriptArgs3AfterPointer + jr z, .noJumpAddress + jp SetScriptPointer -.asm_d49b - jp IncreaseOWScriptPointerBy5 +.noJumpAddress + jp IncreaseScriptPointerBy5 -Func_d49e: ; d49e (3:549e) - call Func_d4b6 +ScriptCommand_JumpIfFlagNotEqual: ; d49e (3:549e) + call GetEventFlagValueBC cp c - jr nz, Func_d490 - jr Func_d48a + jr nz, ScriptEventPassedTryJump + jr ScriptEventFailedNoJump -Func_d4a6: ; d4a6 (3:54a6) - call Func_d4b6 +ScriptCommand_JumpIfFlagNotLessThan: ; d4a6 (3:54a6) + call GetEventFlagValueBC cp c - jr nc, Func_d490 - jr Func_d48a + jr nc, ScriptEventPassedTryJump + jr ScriptEventFailedNoJump -Func_d4ae: ; d4ae (3:54ae) - call Func_d4b6 +ScriptCommand_JumpIfFlagLessThan: ; d4ae (3:54ae) + call GetEventFlagValueBC cp c - jr c, Func_d490 ; 0xd4b2 $dc - jr Func_d48a ; 0xd4b4 $d4 + jr c, ScriptEventPassedTryJump + jr ScriptEventFailedNoJump -Func_d4b6: ; d4b6 (3:54b6) +; Gets event flag at c (Script defaults) +; c takes on the value of b as a side effect +GetEventFlagValueBC: ; d4b6 (3:54b6) ld a, c ld c, b - call CheckIfEventFlagSet + call GetEventFlagValue ret -OWScript_SetEventFlags: ; d4bc (3:54bc) +ScriptCommand_MaxOutFlagValue: ; d4bc (3:54bc) ld a, c - call SetEventFlags - jp IncreaseOWScriptPointerBy2 + call MaxOutEventFlag + jp IncreaseScriptPointerBy2 -Func_d4c3: ; d4c3 (3:54c3) +ScriptCommand_ZeroOutFlagValue: ; d4c3 (3:54c3) ld a, c - call Func_cad0 - jp IncreaseOWScriptPointerBy2 + call ZeroOutEventFlag + jp IncreaseScriptPointerBy2 -Func_d4ca: ; d4ca (3:54ca) +ScriptCommand_JumpIfFlagNonzero2: ; d4ca (3:54ca) ld a, c - call CheckIfEventFlagSet + call GetEventFlagValue or a - jr z, asm_d4e6 -Func_d4d1: - call Func_ccb3 - call GetOWSArgs2AfterPointer - jr z, .asm_d4dc - jp SetOWScriptPointer -.asm_d4dc - jp IncreaseOWScriptPointerBy4 - -OWScript_JumpIfFlagNotSet: + jr z, ScriptCommand_JumpIfFlagZero2.fail + +.passTryJump: + call SetScriptControlBytePass + call GetScriptArgs2AfterPointer + jr z, .noJumpArgs + jp SetScriptPointer +.noJumpArgs + jp IncreaseScriptPointerBy4 + +ScriptCommand_JumpIfFlagZero2: ld a, c - call CheckIfEventFlagSet + call GetEventFlagValue or a - jr z, Func_d4d1 -asm_d4e6 - call Func_ccb9 - jp IncreaseOWScriptPointerBy4 + jr z, ScriptCommand_JumpIfFlagNonzero2.passTryJump + +.fail + call SetScriptControlByteFail + jp IncreaseScriptPointerBy4 ; 0xd4ec - INCROM $d4ec, $d583 +LoadOverworld: ; d4ec (3:54ec) + call Func_d4fb + get_flag_value EVENT_FLAG_3E + or a + ret nz + ld bc, Script_BeginGame + jp SetNextScript + +Func_d4fb: ; d4fb (3:54fb) + zero_flag_value EVENT_FLAG_59 + call Func_f602 + get_flag_value EVENT_FLAG_3F + cp $02 + jr z, .asm_d527 + get_flag_value EVENT_FLAG_40 + cp $02 + jr z, .asm_d521 + get_flag_value EVENT_FLAG_41 + cp $02 + jr z, .asm_d51b + ret +.asm_d51b + ld c, $07 + set_flag_value EVENT_FLAG_41 +.asm_d521 + ld c, $07 + set_flag_value EVENT_FLAG_40 +.asm_d527 + ld c, $07 + set_flag_value EVENT_FLAG_3F + ret + +Script_BeginGame: ; d52e (3:552e) + start_script + run_command ScriptCommand_DoFrames + db $3c + run_command Func_d3e0 + run_command ScriptCommand_DoFrames + db $78 + run_command ScriptCommand_EnterMap + db $02 + db MASON_LABORATORY + db 14 + db 26 + db NORTH + run_command ScriptCommand_QuitScriptFully + +MasonLaboratoryAfterDuel: ; d53b (3:553b) + ld hl, .after_duel_table + call FindEndOfBattleScript + ret + +.after_duel_table + db NPC_SAM + db NPC_SAM + dw $568a + dw $569f + db $00 + +MasonLabLoadMap: ; d549 (3:5549) + get_flag_value EVENT_FLAG_3E + cp $03 + ret nc + ld a, NPC_DRMASON + ld [wTempNPC], a + call FindLoadedNPC + ld bc, Script_EnterLabFirstTime + jp SetNextNPCAndScript + +MasonLabCloseTextBox: ; d55e (3:555e) + ld a, $0a + farcall Func_80b89 + ret + +; Lets you access the Challenge Machine if available +MasonLabPressedA: ; d565 (3:5565) + get_flag_value EVENT_RECEIVED_LEGENDARY_CARD + or a + ret z + ld hl, ChallengeMachineObjectTable + call FindExtraInteractableObjects + ret + +ChallengeMachineObjectTable: ; d572 (3:5572) + db 10, 4, NORTH + dw Script_ChallengeMachine + db 12, 4, NORTH + dw Script_ChallengeMachine + db $00 + +Script_ChallengeMachine: ; d57d (3:557d) + start_script + run_command Func_ccdc + tx Text05bd + run_command Func_d43d + run_command ScriptCommand_QuitScriptFully -Tech1NPCScript: ; d583 (3:5583) +Script_Tech1: ; d583 (3:5583) INCROM $d583, $d5ca -Tech2NPCScript: ; d5ca (3:55ca) +Script_Tech2: ; d5ca (3:55ca) INCROM $d5ca, $d5d5 -Tech3NPCScript: ; d5d5 (3:55d5) +Script_Tech3: ; d5d5 (3:55d5) INCROM $d5d5, $d5e0 -Tech4NPCScript: ; d5e0 (3:55e0) +Script_Tech4: ; d5e0 (3:55e0) INCROM $d5e0, $d5f9 -Tech5NPCScript: ; d5f9 (3:55f9) +Script_Tech5: ; d5f9 (3:55f9) INCROM $d5f9, $d61d -SamNPCScript: ; d61d (3:561d) +Script_Sam: ; d61d (3:561d) INCROM $d61d, $d727 -DrMasonNPCScript: ; d727 (3:5727) +Script_DrMason: ; d727 (3:5727) INCROM $d727, $d753 -OWSequence_d753: ; d753 (3:5753) +Script_EnterLabFirstTime: ; d753 (3:5753) start_script - run_script OWScript_MovePlayer - db $00 + run_command ScriptCommand_MovePlayer + db NORTH db $02 - run_script OWScript_MovePlayer - db $00 + run_command ScriptCommand_MovePlayer + db NORTH db $02 - run_script OWScript_MovePlayer - db $00 + run_command ScriptCommand_MovePlayer + db NORTH db $02 - run_script OWScript_MovePlayer - db $00 + run_command ScriptCommand_MovePlayer + db NORTH db $02 - run_script OWScript_MovePlayer - db $00 + run_command ScriptCommand_MovePlayer + db NORTH db $02 - run_script OWScript_MovePlayer - db $00 + run_command ScriptCommand_MovePlayer + db NORTH db $02 - run_script OWScript_MovePlayer - db $00 + run_command ScriptCommand_MovePlayer + db NORTH db $02 - run_script OWScript_MovePlayer - db $00 + run_command ScriptCommand_MovePlayer + db NORTH db $02 - run_script OWScript_MovePlayer - db $00 + run_command ScriptCommand_MovePlayer + db NORTH db $02 - run_script OWScript_PrintTextString + run_command ScriptCommand_PrintTextString tx Text05e3 - run_script OWScript_CloseTextBox - run_script Func_d088 - db $07 - db $79 - db $57 - run_script OWScript_EndScriptLoop1 + run_command ScriptCommand_CloseAdvancedTextBox + run_command ScriptCommand_SetNextNPCandScript + db NPC_SAM + dw Script_d779 + run_command ScriptCommand_EndScriptLoop1 ret +Script_d779: ; d779 (03:5779) start_script - run_script Func_ce4a - db $80 - db $58 - db $02 - - ; there's more to this script but it hasn't been disassembled yet + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_d880 + run_command ScriptCommand_PrintTextString + tx Text05e4 + run_command ScriptCommand_SetDialogName + db NPC_DRMASON + run_command ScriptCommand_PrintTextString + tx Text05e5 + run_command ScriptCommand_CloseTextBox + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_d882 + run_command Func_cfc6 + db $01 + run_command ScriptCommand_SetPlayerDirection + db $03 + run_command ScriptCommand_CloseAdvancedTextBox + run_command ScriptCommand_SetNextNPCandScript + db NPC_DRMASON + dw Script_d794 + run_command ScriptCommand_EndScriptLoop1 + ret - INCROM $d77e, $d8bb +Script_d794: ; d794 (3:5794) + start_script + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_d88b + run_command ScriptCommand_DoFrames + db 40 + run_command ScriptCommand_PrintTextString + tx Text05e6 + run_command ScriptCommand_CloseTextBox + run_command ScriptCommand_MovePlayer + db WEST + db $01 + run_command ScriptCommand_MovePlayer + db WEST + db $01 + run_command ScriptCommand_SetPlayerDirection + db SOUTH + run_command ScriptCommand_MovePlayer + db SOUTH + db $01 + run_command ScriptCommand_MovePlayer + db SOUTH + db $01 + run_command ScriptCommand_MovePlayer + db SOUTH + db $01 + run_command ScriptCommand_SetPlayerDirection + db WEST + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_d894 + run_command ScriptCommand_PrintTextString + tx Text05e7 + run_command ScriptCommand_SetDialogName + db $07 + run_command ScriptCommand_PrintTextString + tx Text05e8 + +.ows_d7bc + run_command ScriptCommand_CloseTextBox + run_command Func_d317 + run_command ScriptCommand_CloseTextBox + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_75 + db $07 + dw .ows_d80c + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_75 + db $01 + dw .ows_d7e8 + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_75 + db $02 + dw .ows_d7ee + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_75 + db $03 + dw .ows_d7f4 + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_75 + db $04 + dw .ows_d7fa + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_75 + db $05 + dw .ows_d800 + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_75 + db $06 + dw .ows_d806 + run_command ScriptCommand_PrintTextString + tx Text05d6 + run_command ScriptCommand_Jump + dw .ows_d7bc + +.ows_d7e8 + run_command ScriptCommand_PrintTextString + tx Text05d7 + run_command ScriptCommand_Jump + dw .ows_d7bc + +.ows_d7ee + run_command ScriptCommand_PrintTextString + tx Text05d8 + run_command ScriptCommand_Jump + dw .ows_d7bc + +.ows_d7f4 + run_command ScriptCommand_PrintTextString + tx Text05d9 + run_command ScriptCommand_Jump + dw .ows_d7bc + +.ows_d7fa + run_command ScriptCommand_PrintTextString + tx Text05da + run_command ScriptCommand_Jump + dw .ows_d7bc + +.ows_d800 + run_command ScriptCommand_PrintTextString + tx Text05db + run_command ScriptCommand_Jump + dw .ows_d7bc + +.ows_d806 + run_command ScriptCommand_PrintTextString + tx Text05dc + run_command ScriptCommand_Jump + dw .ows_d7bc + +.ows_d80c + run_command ScriptCommand_PrintTextString + tx Text05e9 + run_command ScriptCommand_AskQuestionJumpDefaultYes + dw 0000 + dw .ows_d817 + run_command ScriptCommand_Jump + dw .ows_d7bc + +.ows_d817 + run_command ScriptCommand_SetDialogName + db $01 + run_command ScriptCommand_PrintTextString + tx Text05ea + run_command ScriptCommand_nop + run_command ScriptCommand_SetFlagValue + db EVENT_FLAG_3E + db $01 + run_command ScriptCommand_CloseAdvancedTextBox + run_command ScriptCommand_SetNextNPCandScript + db NPC_SAM + dw Script_d827 + run_command ScriptCommand_EndScriptLoop1 + ret -Tech6NPCScript: ; d8bb (3:58bb) +Script_d827: ; d827 (3:5827) + start_script + run_command ScriptCommand_StartBattle + db PRIZES_2 + db SAMS_PRACTICE_DECK_ID + db MUSIC_DUEL_THEME_1 + run_command ScriptCommand_QuitScriptFully +; 0xd82d + + INCROM $d82d, $d880 + +NPCMovement_d880: ; d880 (3:5880) + db EAST + db $ff + +NPCMovement_d882: ; d882 (3:5882) + db SOUTH + db SOUTH + db WEST + db WEST + db WEST + db WEST + db SOUTH + db EAST | NO_MOVE + db $ff + +NPCMovement_d88b: ; d88b (3:588b) + db WEST + db SOUTH + db SOUTH + db SOUTH + db WEST + db WEST + db WEST + db EAST | NO_MOVE + db $ff + +NPCMovement_d894: ; d894 (4:5894) + db SOUTH | NO_MOVE + db $ff + + INCROM $d896, $d8bb + +Script_Tech6: ; d8bb (3:58bb) INCROM $d8bb, $d8c6 -Tech7NPCScript: ; d8c6 (3:58c6) +Script_Tech7: ; d8c6 (3:58c6) INCROM $d8c6, $d8d1 -Tech8NPCScript: ; d8d1 (3:58d1) +Script_Tech8: ; d8d1 (3:58d1) INCROM $d8d1, $d8dd -AaronNPCScript: ; d8dd (3:58dd) - INCROM $d8dd, $db4a +Script_Aaron: ; d8dd (3:58dd) + INCROM $d8dd, $d932 -IshiharaNPCScript: ; db4a (3:5b4a) - INCROM $db4a, $dc4b +Script_d932: ; d932 (3:5932) + start_script + run_command Func_ccdc + tx Text0605 + run_command ScriptCommand_AskQuestionJumpDefaultYes + tx Text0606 + dw .ows_d93c + run_command ScriptCommand_QuitScriptFully + +.ows_d93c + run_command ScriptCommand_OpenDeckMachine + db $09 + run_command ScriptCommand_QuitScriptFully +; 0xd93f + + INCROM $d93f, $dadd + +Preload_NikkiInIshiharasHouse: ; dadd (3:5add) + get_flag_value EVENT_FLAG_35 + cp $01 + jr nz, .dontLoadNikki + scf + ret +.dontLoadNikki + or a + ret +; 0xdae9 -Ronald2NPCScript: ; dc4b (3:5c4b) - INCROM $dc4b, $dc4b + INCROM $dae9, $db3d -Ronald3NPCScript: ; dc4b (3:5c4b) - INCROM $dc4b, $dc4b +Preload_IshiharaInIshiharasHouse: ; db3d (3:5b3d) + get_flag_value EVENT_FLAG_1C + or a + ret z + get_flag_value EVENT_FLAG_1F + cp $08 + ret + +Script_Ishihara: ; db4a (3:5b4a) + start_script + run_command ScriptCommand_MaxOutFlagValue + db EVENT_FLAG_1D + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_1F + db $00 + dw .ows_db80 + run_command ScriptCommand_JumpIfFlagNonzero2 + db EVENT_FLAG_39 + dw .ows_db5a + run_command ScriptCommand_JumpIfFlagNonzero2 + db EVENT_RECEIVED_LEGENDARY_CARD + dw .ows_dc3e +.ows_db5a + run_command ScriptCommand_JumpIfFlagNonzero2 + db EVENT_FLAG_00 + dw .ows_db90 + run_command ScriptCommand_JumpIfFlagZero2 + db EVENT_FLAG_38 + dw .ows_db90 + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_1F + db $01 + dw .ows_db93 + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_1F + db $02 + dw .ows_db93 + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_1F + db $03 + dw .ows_dbcc + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_1F + db $04 + dw .ows_dbcc + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_1F + db $05 + dw .ows_dc05 + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_1F + db $06 + dw .ows_dc05 +.ows_db80 + run_command ScriptCommand_MaxOutFlagValue + db EVENT_FLAG_00 + run_command ScriptCommand_SetFlagValue + db EVENT_FLAG_1F + db $01 + run_command ScriptCommand_ZeroOutFlagValue + db EVENT_FLAG_38 + run_command ScriptCommand_JumpIfFlagZero2 + db EVENT_RECEIVED_LEGENDARY_CARD + dw .ows_db8d + run_command ScriptCommand_MaxOutFlagValue + db EVENT_FLAG_39 +.ows_db8d + run_command ScriptCommand_PrintTextQuitFully + tx Text0727 + +.ows_db90 + run_command ScriptCommand_PrintTextQuitFully + tx Text0728 + +.ows_db93 + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_1F + db $01 + dw NO_JUMP + run_command ScriptCommand_PrintVariableText + tx Text0729 + tx Text072a + run_command ScriptCommand_SetFlagValue + db EVENT_FLAG_1F + db $02 + run_command ScriptCommand_AskQuestionJump + tx Text072b + dw .ows_dba8 + run_command ScriptCommand_PrintTextQuitFully + tx Text072c + +.ows_dba8 + run_command Func_cf0c + db $ac + dw .ows_dbaf + run_command ScriptCommand_PrintTextQuitFully + tx Text072d + +.ows_dbaf + run_command Func_cf12 + db $ac + dw .ows_dbb6 + run_command ScriptCommand_PrintTextQuitFully + tx Text072e + +.ows_dbb6 + run_command ScriptCommand_MaxOutFlagValue + db EVENT_FLAG_00 + run_command ScriptCommand_SetFlagValue + db EVENT_FLAG_1F + db $03 + run_command ScriptCommand_ZeroOutFlagValue + db EVENT_FLAG_38 + run_command ScriptCommand_PrintTextString + tx Text072f + run_command Func_ccdc + tx Text0730 + run_command ScriptCommand_TakeCard + db CLEFABLE + run_command ScriptCommand_GiveCard + db SURFING_PIKACHU1 + run_command ScriptCommand_ShowCardReceivedScreen + db SURFING_PIKACHU1 + run_command ScriptCommand_PrintTextQuitFully + tx Text0731 + +.ows_dbcc + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_1F + db $03 + dw NO_JUMP + run_command ScriptCommand_PrintVariableText + tx Text0732 + tx Text0733 + run_command ScriptCommand_SetFlagValue + db EVENT_FLAG_1F + db $04 + run_command ScriptCommand_AskQuestionJump + tx Text072b + dw .ows_dbe1 + run_command ScriptCommand_PrintTextQuitFully + tx Text072c + +.ows_dbe1 + run_command Func_cf0c + db $bb + dw .ows_dbe8 + run_command ScriptCommand_PrintTextQuitFully + tx Text0734 + +.ows_dbe8 + run_command Func_cf12 + db $bb + dw .ows_dbef + run_command ScriptCommand_PrintTextQuitFully + tx Text0735 + +.ows_dbef + run_command ScriptCommand_MaxOutFlagValue + db EVENT_FLAG_00 + run_command ScriptCommand_SetFlagValue + db EVENT_FLAG_1F + db $05 + run_command ScriptCommand_ZeroOutFlagValue + db EVENT_FLAG_38 + run_command ScriptCommand_PrintTextString + tx Text072f + run_command Func_ccdc + tx Text0736 + run_command ScriptCommand_TakeCard + db DITTO + run_command ScriptCommand_GiveCard + db FLYING_PIKACHU + run_command ScriptCommand_ShowCardReceivedScreen + db FLYING_PIKACHU + run_command ScriptCommand_PrintTextQuitFully + tx Text0737 + +.ows_dc05 + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_1F + db $05 + dw NO_JUMP + run_command ScriptCommand_PrintVariableText + tx Text0738 + tx Text0739 + run_command ScriptCommand_SetFlagValue + db EVENT_FLAG_1F + db $06 + run_command ScriptCommand_AskQuestionJump + tx Text072b + dw .ows_dc1a + run_command ScriptCommand_PrintTextQuitFully + tx Text072c + +.ows_dc1a + run_command Func_cf0c + db $b8 + dw .ows_dc21 + run_command ScriptCommand_PrintTextQuitFully + tx Text073a + +.ows_dc21 + run_command Func_cf12 + db $b8 + dw .ows_dc28 + run_command ScriptCommand_PrintTextQuitFully + tx Text073b + +.ows_dc28 + run_command ScriptCommand_MaxOutFlagValue + db EVENT_FLAG_00 + run_command ScriptCommand_SetFlagValue + db EVENT_FLAG_1F + db $07 + run_command ScriptCommand_ZeroOutFlagValue + db EVENT_FLAG_38 + run_command ScriptCommand_PrintTextString + tx Text072f + run_command Func_ccdc + tx Text073c + run_command ScriptCommand_TakeCard + db CHANSEY + run_command ScriptCommand_GiveCard + db SURFING_PIKACHU2 + run_command ScriptCommand_ShowCardReceivedScreen + db SURFING_PIKACHU2 + run_command ScriptCommand_PrintTextQuitFully + tx Text073d + +.ows_dc3e + run_command ScriptCommand_MaxOutFlagValue + db EVENT_FLAG_39 + run_command ScriptCommand_PrintTextQuitFully + tx Text073e + +Preload_Ronald1InIshiharasHouse: ; dc43 (3:5c43) + get_flag_value EVENT_RECEIVED_LEGENDARY_CARD + cp $01 + ccf + ret + +Script_Ronald: ; dc4b (3:5c4b) + start_script + run_command ScriptCommand_JumpIfFlagNonzero2 + db EVENT_FLAG_4E + dw .ows_dc55 + run_command ScriptCommand_MaxOutFlagValue + db EVENT_FLAG_4E + run_command ScriptCommand_PrintTextQuitFully + tx Text073f + +.ows_dc55 + run_command ScriptCommand_PrintTextString + tx Text0740 + run_command ScriptCommand_AskQuestionJump + tx Text0741 + dw .ows_dc60 + run_command ScriptCommand_PrintTextQuitFully + tx Text0742 + +.ows_dc60 + run_command ScriptCommand_PrintTextQuitFully + tx Text0743 +; 0xdc63 + + ; could be a commented function, or could be placed by mistake from + ; someone thinking that the Ronald script ended with more code execution + ret -RonaldNPCScript: ; dc4b (3:5c4b) - INCROM $dc4b, $dc64 +Script_Clerk1: ; dc64 (3:5c64) + start_script + run_command ScriptCommand_PrintTextQuitFully + tx Text045a -Clerk1NPCScript: ; dc64 (3:5c64) - INCROM $dc64, $dc76 +FightingClubLobbyAfterDuel: ; dc68 (3:5c68) + ld hl, .after_duel_table + call FindEndOfBattleScript + ret +.after_duel_table + db NPC_IMAKUNI + db NPC_IMAKUNI + dw Script_BeatImakuni + dw Script_LostToImakuni + db $00 -Man1NPCScript: ; dc76 (3:5c76) +Script_Man1: ; dc76 (3:5c76) INCROM $dc76, $dd0d -ImakuniNPCScript: ; dd0d (3:5d0d) - INCROM $dd0d, $dd82 +Script_Imakuni: ; dd0d (3:5d0d) + start_script + run_command ScriptCommand_SetFlagValue + db EVENT_IMAKUNI_STATE + db IMAKUNI_TALKED + run_command ScriptCommand_JumpIfFlagZero2 + db EVENT_TEMP_TALKED_TO_IMAKUNI + dw NO_JUMP + run_command ScriptCommand_PrintVariableText + tx Text0467 + tx Text0468 + run_command ScriptCommand_MaxOutFlagValue + db EVENT_TEMP_TALKED_TO_IMAKUNI + run_command ScriptCommand_AskQuestionJump + tx Text0469 + dw .declineDuel + run_command ScriptCommand_PrintTextString + tx Text046a + run_command ScriptCommand_QuitScriptFully + +.declineDuel + run_command ScriptCommand_PrintTextString + tx Text046b + run_command ScriptCommand_StartBattle + db PRIZES_6 + db IMAKUNI_DECK_ID + db MUSIC_IMAKUNI + run_command ScriptCommand_QuitScriptFully +; 0xdd2d + +Script_BeatImakuni: ; dd2d (3:5d2d) + start_script + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_IMAKUNI_WIN_COUNT + db $07 + dw .giveBoosters + run_command ScriptCommand_IncrementFlagValue + db EVENT_IMAKUNI_WIN_COUNT + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_IMAKUNI_WIN_COUNT + db $03 + dw .threeWins + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_IMAKUNI_WIN_COUNT + db $06 + dw .sixWins +.giveBoosters + run_command ScriptCommand_PrintTextString + tx Text046c + run_command ScriptCommand_GiveOneOfEachTrainerBooster + run_command ScriptCommand_Jump + dw .done + +.threeWins + run_command ScriptCommand_PrintTextString + tx Text046d + run_command ScriptCommand_Jump + dw .giveImakuniCard + +.sixWins + run_command ScriptCommand_PrintTextString + tx Text046e +.giveImakuniCard + run_command ScriptCommand_PrintTextString + tx Text046f + run_command ScriptCommand_GiveCard + db IMAKUNI_CARD + run_command ScriptCommand_ShowCardReceivedScreen + db IMAKUNI_CARD +.done + run_command ScriptCommand_PrintTextString + tx Text0470 + run_command ScriptCommand_Jump + dw ScriptJump_ImakuniCommon + +Script_LostToImakuni: ; dd5c (3:5d5c) + start_script + run_command ScriptCommand_PrintTextString + tx Text0471 + +ScriptJump_ImakuniCommon: ; dd60 (3:5d60) + run_command ScriptCommand_CloseTextBox + run_command ScriptCommand_JumpIfPlayerCoordMatches + db 18 + db 4 + dw .ows_dd69 + run_command ScriptCommand_Jump + dw .ows_dd6e + +.ows_dd69 + run_command ScriptCommand_SetPlayerDirection + db EAST + run_command ScriptCommand_MovePlayer + db WEST + db $01 -Specs1NPCScript: ; dd82 (3:5d82) +.ows_dd6e + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_dd78 + run_command Func_cdcb + run_command ScriptCommand_MaxOutFlagValue + db EVENT_TEMP_BATTLED_IMAKUNI + run_command Func_d408 + db $09 + run_command Func_d41d + run_command ScriptCommand_QuitScriptFully +; 0xdd78 + +NPCMovement_dd78 ; dd78 (3:5d78) + db SOUTH + db SOUTH + db SOUTH + db SOUTH + db EAST + db EAST + db EAST + db EAST + db EAST + db $ff + +Script_Specs1: ; dd82 (3:5d82) INCROM $dd82, $dd8d -ButchNPCScript: ; dd8d (3:5d8d) +Script_Butch: ; dd8d (3:5d8d) INCROM $dd8d, $dd9f -Granny1NPCScript: ; dd9f (3:5d9f) +Script_Granny1: ; dd9f (3:5d9f) INCROM $dd9f, $ddc3 -MitchNPCScript: ; ddc3 (3:5dc3) +Script_Mitch: ; ddc3 (3:5dc3) INCROM $ddc3, $ded1 -Clerk2NPCScript: ; ded1 (3:5ed1) +Script_Clerk2: ; ded1 (3:5ed1) INCROM $ded1, $def2 -ChrisNPCScript: ; def2 (3:5ef2) +Script_Chris: ; def2 (3:5ef2) INCROM $def2, $df39 -MatthewNPCScript: ; df39 (3:5f39) +Script_Matthew: ; df39 (3:5f39) INCROM $df39, $df83 -Woman1NPCScript: ; df83 (3:5f83) +Script_Woman1: ; df83 (3:5f83) INCROM $df83, $dfc0 -Chap1NPCScript: ; dfc0 (3:5fc0) +Script_Chap1: ; dfc0 (3:5fc0) INCROM $dfc0, $dfd2 -Lass3NPCScript: ; dfd2 (3:5fd2) +Script_Lass3: ; dfd2 (3:5fd2) INCROM $dfd2, $dff0 -RyanNPCScript: ; dff0 (3:5ff0) +Script_Ryan: ; dff0 (3:5ff0) INCROM $dff0, $e017 -AndrewNPCScript: ; e017 (3:6017) +Script_Andrew: ; e017 (3:6017) INCROM $e017, $e03e -GeneNPCScript: ; e03e (3:603e) +Script_Gene: ; e03e (3:603e) INCROM $e03e, $e09e -Clerk3NPCScript: ; e09e (3:609e) - INCROM $e09e, $e0cf - -Gal1NPCScript: ; e0cf (3:60cf) - INCROM $e0cf, $e111 +Script_Clerk3: ; e09e (3:609e) + INCROM $e09e, $e0b0 + +Preload_ImakuniInWaterClubLobby: ; e0b0 (3:60b0) + get_flag_value EVENT_IMAKUNI_STATE + cp IMAKUNI_TALKED + jr c, .asm_e0c6 + get_flag_value EVENT_TEMP_BATTLED_IMAKUNI + jr nz, .asm_e0c6 + get_flag_value EVENT_IMAKUNI_ROOM + cp IMAKUNI_WATER_CLUB + jr z, .asm_e0c8 +.asm_e0c6 + or a + ret +.asm_e0c8 + ld a, $10 + ld [wd111], a + scf + ret +; 0xe0cf -Lass1NPCScript: ; e111 (3:6111) - INCROM $e111, $e137 +Script_Gal1: ; e0cf (3:60cf) + start_script + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_12 + db $02 + dw .ows_e10e + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_12 + db $00 + dw NO_JUMP + run_command ScriptCommand_PrintVariableText + tx Text041d + tx Text041e + run_command ScriptCommand_SetFlagValue + db EVENT_FLAG_12 + db $01 + run_command ScriptCommand_AskQuestionJump + tx Text041f + dw .ows_e0eb + run_command ScriptCommand_PrintTextString + tx Text0420 + run_command ScriptCommand_QuitScriptFully + +.ows_e0eb + run_command Func_cf0c + db $59 + dw .ows_e0f3 + run_command ScriptCommand_PrintTextString + tx Text0421 + run_command ScriptCommand_QuitScriptFully + +.ows_e0f3 + run_command Func_cf12 + db $59 + dw .ows_e0fb + run_command ScriptCommand_PrintTextString + tx Text0422 + run_command ScriptCommand_QuitScriptFully + +.ows_e0fb + run_command ScriptCommand_SetFlagValue + db EVENT_FLAG_12 + db $02 + run_command ScriptCommand_PrintTextString + tx Text0423 + run_command Func_ccdc + tx Text0424 + run_command ScriptCommand_TakeCard + db LAPRAS + run_command ScriptCommand_GiveCard + db ARCANINE1 + run_command ScriptCommand_ShowCardReceivedScreen + db ARCANINE1 + run_command ScriptCommand_PrintTextString + tx Text0425 + run_command ScriptCommand_QuitScriptFully + +.ows_e10e + run_command ScriptCommand_PrintTextQuitFully + tx Text0426 + +Script_Lass1: ; e111 (3:6111) + start_script + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_14 + db $01 + dw .ows_e121 + run_command ScriptCommand_PrintTextString + tx Text0427 + run_command ScriptCommand_SetFlagValue + db EVENT_FLAG_14 + db $01 + run_command ScriptCommand_SetFlagValue + db EVENT_IMAKUNI_STATE + db IMAKUNI_MENTIONED + run_command ScriptCommand_QuitScriptFully + +.ows_e121 + run_command ScriptCommand_JumpIfFlagNotEqual + db EVENT_IMAKUNI_ROOM + db IMAKUNI_WATER_CLUB + dw .ows_e12d + run_command ScriptCommand_JumpIfFlagNonzero2 + db EVENT_TEMP_BATTLED_IMAKUNI + dw .ows_e12d + run_command ScriptCommand_PrintTextQuitFully + tx Text0428 + +.ows_e12d + run_command ScriptCommand_PrintTextQuitFully + tx Text0429 + +Preload_Man2InWaterClubLobby: ; e130 (3:6130) + get_flag_value EVENT_JOSHUA_STATE + cp JOSHUA_BEATEN + ret -Man2NPCScript: ; e137 (3:6137) - INCROM $e137, $e13b +Script_Man2: ; e137 (3:6137) + start_script + run_command ScriptCommand_PrintTextQuitFully + tx Text042a -Pappy2NPCScript: ; e13b (3:613b) - INCROM $e13b, $e13f +Script_Pappy2: ; e13b (3:613b) + start_script + run_command ScriptCommand_PrintTextQuitFully + tx Text042b WaterClubMovePlayer: ; e13f (3:613f) ld a, [wPlayerYCoord] cp $8 ret nz - call Func_ca69 - inc sp + get_flag_value EVENT_JOSHUA_STATE cp $2 ret nc - ld a, $21 - ld [wd3ab], a - ld bc, OWSequence_NotReadyToSeeAmy - jp Func_c926 + ld a, NPC_JOSHUA + ld [wTempNPC], a + ld bc, Script_NotReadyToSeeAmy + jp SetNextNPCAndScript WaterClubAfterDuel: ;e157 (3:6157) ld hl, .after_duel_table @@ -3104,162 +4115,525 @@ WaterClubAfterDuel: ;e157 (3:6157) ret .after_duel_table - dw $1f1f - dw OWSequence_BeatSara - dw OWSequence_LostToSara - - dw $2020 - dw OWSequence_BeatAmanda - dw OWSequence_LostToAmanda - - dw $2121 - dw $626c - dw $6260 - - dw $2222 - dw $6322 - dw $6344 + db NPC_SARA + db NPC_SARA + dw Script_BeatSara + dw Script_LostToSara + + db NPC_AMANDA + db NPC_AMANDA + dw Script_BeatAmanda + dw Script_LostToAmanda + + db NPC_JOSHUA + db NPC_JOSHUA + dw Script_BeatJoshua + dw Script_LostToJoshua + + db NPC_AMY + db NPC_AMY + dw Script_BeatAmy + dw Script_LostToAmy db $00 -SaraNPCScript: ; e177 (3:6177) +Script_Sara: ; e177 (3:6177) start_script - run_script OWScript_PrintTextString + run_command ScriptCommand_PrintTextString tx Text042c - run_script OWScript_AskQuestionJump + run_command ScriptCommand_AskQuestionJump tx Text042d dw .yes_duel - run_script OWScript_PrintTextString + run_command ScriptCommand_PrintTextString tx Text042e - run_script OWScript_EndScriptCloseText + run_command ScriptCommand_QuitScriptFully .yes_duel - run_script OWScript_PrintTextString + run_command ScriptCommand_PrintTextString tx Text042f - run_script OWScript_StartBattle - db 2 - db WATERFRONT_POKEMON_DECK_ID ; 6189 + run_command ScriptCommand_StartBattle + db PRIZES_2 + db WATERFRONT_POKEMON_DECK_ID db MUSIC_DUEL_THEME_1 - run_script OWScript_EndScriptCloseText + run_command ScriptCommand_QuitScriptFully -OWSequence_BeatSara: ; e18c (3:618c) +Script_BeatSara: ; e18c (3:618c) start_script - run_script OWScript_SetEventFlags + run_command ScriptCommand_MaxOutFlagValue db EVENT_BEAT_SARA - run_script OWScript_PrintTextString + run_command ScriptCommand_PrintTextString tx Text0430 - run_script OWScript_GiveBoosterPacks + run_command ScriptCommand_GiveBoosterPacks db BOOSTER_COLOSSEUM_WATER db BOOSTER_COLOSSEUM_WATER db NO_BOOSTER - run_script OWScript_PrintTextString + run_command ScriptCommand_PrintTextString tx Text0431 - run_script OWScript_EndScriptCloseText + run_command ScriptCommand_QuitScriptFully -OWSequence_LostToSara: ; e19a (03:619a) +Script_LostToSara: ; e19a (03:619a) start_script - run_script OWScript_PrintTextCloseBox + run_command ScriptCommand_PrintTextQuitFully tx Text0432 -AmandaNPCScript: ; e19e (03:619e) +Script_Amanda: ; e19e (03:619e) start_script - run_script OWScript_PrintTextString + run_command ScriptCommand_PrintTextString tx Text0433 - run_script OWScript_AskQuestionJump + run_command ScriptCommand_AskQuestionJump tx Text0434 dw .yes_duel - run_script OWScript_PrintTextString + run_command ScriptCommand_PrintTextString tx Text0435 - run_script OWScript_EndScriptCloseText + run_command ScriptCommand_QuitScriptFully .yes_duel - run_script OWScript_PrintTextString + run_command ScriptCommand_PrintTextString tx Text0436 - run_script OWScript_StartBattle - db 03 + run_command ScriptCommand_StartBattle + db PRIZES_3 db LONELY_FRIENDS_DECK_ID db MUSIC_DUEL_THEME_1 - run_script OWScript_EndScriptCloseText + run_command ScriptCommand_QuitScriptFully -OWSequence_BeatAmanda: ; e1b3 (03:61b3) +Script_BeatAmanda: ; e1b3 (03:61b3) start_script - run_script OWScript_SetEventFlags + run_command ScriptCommand_MaxOutFlagValue db EVENT_BEAT_AMANDA - run_script OWScript_PrintTextString + run_command ScriptCommand_PrintTextString tx Text0437 - run_script OWScript_GiveBoosterPacks + run_command ScriptCommand_GiveBoosterPacks db BOOSTER_MYSTERY_LIGHTNING_COLORLESS db BOOSTER_MYSTERY_LIGHTNING_COLORLESS db NO_BOOSTER - run_script OWScript_PrintTextString + run_command ScriptCommand_PrintTextString tx Text0438 - run_script OWScript_EndScriptCloseText + run_command ScriptCommand_QuitScriptFully -OWSequence_LostToAmanda: ; e1c1 (03:61c1) +Script_LostToAmanda: ; e1c1 (03:61c1) start_script - run_script OWScript_PrintTextCloseBox + run_command ScriptCommand_PrintTextQuitFully tx Text0439 -OWSequence_NotReadyToSeeAmy: - INCROM $e1c5, $e21c - -JoshuaNPCScript: ; e21c (3:621c) +Script_NotReadyToSeeAmy: ; e1c5 (03:61c5) + start_script + run_command ScriptCommand_JumpIfPlayerCoordMatches + db $12 + db $08 + dw .ows_e1ec + run_command ScriptCommand_JumpIfPlayerCoordMatches + db $14 + db $08 + dw .ows_e1f2 + run_command ScriptCommand_JumpIfPlayerCoordMatches + db $18 + db $08 + dw .ows_e1f8 +.ows_e1d5 + run_command ScriptCommand_MovePlayer + db SOUTH + db $04 + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_e213 + run_command ScriptCommand_PrintTextString + tx Text043a + run_command ScriptCommand_JumpIfPlayerCoordMatches + db $12 + db $0a + dw .ows_e1fe + run_command ScriptCommand_JumpIfPlayerCoordMatches + db $14 + db $0a + dw .ows_e202 + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_e215 + run_command ScriptCommand_QuitScriptFully + +.ows_e1ec + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_e206 + run_command ScriptCommand_Jump + dw .ows_e1d5 +.ows_e1f2 + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_e20b + run_command ScriptCommand_Jump + dw .ows_e1d5 +.ows_e1f8 + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_e20f + run_command ScriptCommand_Jump + dw .ows_e1d5 +.ows_e1fe + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_e218 + run_command ScriptCommand_QuitScriptFully + +.ows_e202 + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_e219 + run_command ScriptCommand_QuitScriptFully + +NPCMovement_e206: ; e206 (3:6206) + db NORTH + db WEST + db WEST + db SOUTH | NO_MOVE + db $ff + +NPCMovement_e20b: ; e20b (3:620b) + db NORTH + db WEST + db SOUTH | NO_MOVE + db $ff + +NPCMovement_e20f: ; e20f (3:620f) + db NORTH + db EAST + db SOUTH | NO_MOVE + db $ff + +NPCMovement_e213: ; e213 (3:6213) + db SOUTH + db $ff + +NPCMovement_e215: ; e215 (3:6215) + db WEST + db SOUTH | NO_MOVE + db $ff + +NPCMovement_e218: ; e218 (3:6218) + db EAST +; fallthrough + +NPCMovement_e219: ; e219 (3:6219) + db EAST + db SOUTH | NO_MOVE + db $ff + +Script_Joshua: ; e21c (3:621c) start_script - run_script OWScript_JumpIfFlagNotSet + run_command ScriptCommand_JumpIfFlagZero2 db EVENT_BEAT_AMANDA dw .sara_and_amanda_not_beaten - run_script OWScript_JumpIfFlagNotSet + run_command ScriptCommand_JumpIfFlagZero2 db EVENT_BEAT_SARA dw .sara_and_amanda_not_beaten - run_script OWScript_ScriptJump + run_command ScriptCommand_Jump dw .beat_sara_and_amanda .sara_and_amanda_not_beaten - run_script OWScript_CustomModifyEventFlags - db $33 ; offset on flagmod table - db $01 ; the control bit - run_script OWScript_PrintTextString + run_command ScriptCommand_SetFlagValue + db EVENT_JOSHUA_STATE + db JOSHUA_TALKED + run_command ScriptCommand_PrintTextString tx Text043b - run_script OWScript_EndScriptCloseText + run_command ScriptCommand_QuitScriptFully + .beat_sara_and_amanda - run_script OWScript_JumpIfFlagSet - db $33 - dw $623c - run_script OWScript_CustomModifyEventFlags - db $33 - db $01 - run_script OWScript_PrintTextString + run_command ScriptCommand_JumpIfFlagNonzero1 + db EVENT_JOSHUA_STATE + dw .already_talked + run_command ScriptCommand_SetFlagValue + db EVENT_JOSHUA_STATE + db JOSHUA_TALKED + run_command ScriptCommand_PrintTextString tx Text043b - run_script OWScript_PrintTextString + run_command ScriptCommand_PrintTextString tx Text043c - run_script Func_d484 - db $33 - db $01 +.already_talked + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_JOSHUA_STATE + db JOSHUA_TALKED + dw NO_JUMP + run_command ScriptCommand_PrintVariableText + tx Text043d + tx Text043e + run_command ScriptCommand_AskQuestionJump + tx Text043f + dw .startDuel + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_JOSHUA_STATE + db JOSHUA_TALKED + dw NO_JUMP + run_command ScriptCommand_PrintVariableText + tx Text0440 + tx Text0441 + run_command ScriptCommand_QuitScriptFully + +.startDuel: + run_command ScriptCommand_PrintTextString + tx Text0442 + run_command ScriptCommand_TryGivePCPack + db $04 + run_command ScriptCommand_StartBattle + db PRIZES_4 + db SOUND_OF_THE_WAVES_DECK_ID + db MUSIC_DUEL_THEME_1 + run_command ScriptCommand_QuitScriptFully - INCROM $e23f, $e304 +Script_LostToJoshua: ; e260 (3:6260) + start_script + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_JOSHUA_STATE + db JOSHUA_TALKED + dw NO_JUMP + run_command ScriptCommand_PrintVariableText + tx Text0443 + tx Text0444 + run_command ScriptCommand_QuitScriptFully + +Script_BeatJoshua: ; e26c (3:626c) + start_script + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_JOSHUA_STATE + db JOSHUA_TALKED + dw NO_JUMP + run_command ScriptCommand_PrintVariableText + tx Text0445 + tx Text0446 + run_command ScriptCommand_GiveBoosterPacks + db BOOSTER_MYSTERY_WATER_COLORLESS + db BOOSTER_MYSTERY_WATER_COLORLESS + db NO_BOOSTER + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_JOSHUA_STATE + db JOSHUA_TALKED + dw NO_JUMP + run_command ScriptCommand_PrintVariableText + tx Text0447 + tx Text0448 + run_command ScriptCommand_JumpIfFlagNotEqual + db EVENT_JOSHUA_STATE + db JOSHUA_BEATEN + dw .firstJoshuaWin + run_command ScriptCommand_QuitScriptFully + +.firstJoshuaWin: + run_command ScriptCommand_SetFlagValue + db EVENT_JOSHUA_STATE + db JOSHUA_BEATEN + run_command ScriptCommand_PrintTextString + tx Text0449 + run_command ScriptCommand_CloseTextBox + run_command ScriptCommand_MoveActiveNPCByDirection + dw NPCMovementTable_e2a1 + run_command ScriptCommand_PrintTextString + tx Text044a + run_command Func_cfc6 + db $00 + run_command ScriptCommand_CloseAdvancedTextBox + run_command ScriptCommand_SetNextNPCandScript + db NPC_AMY + dw Script_MeetAmy + run_command ScriptCommand_EndScriptLoop1 + ret + +NPCMovementTable_e2a1: ; e2a1 (3:62a1) + dw NPCMovement_e2a9 + dw NPCMovement_e2a9 + dw NPCMovement_e2a9 + dw NPCMovement_e2a9 -AmyNPCScript: ; e304 (3:6304) - INCROM $e304, $e369 +NPCMovement_e2a9: ; e2a9 (3:62a9) + db NORTH + db $ff -Clerk4NPCScript: ; e369 (3:6369) +NPCMovement_e2ab: ; e2ab (3:62ab) + db SOUTH + db $ff + +Preload_Amy: ; e2ad (3:62ad) + xor a + ld [wd3d0], a + ld a, [wd0c2] + or a + jr z, .asm_e2cf + ld a, [wPlayerXCoord] + cp $14 + jr nz, .asm_e2cf + ld a, [wPlayerYCoord] + cp $06 + jr nz, .asm_e2cf + ld a, $14 + ld [wLoadNPCXPos], a + ld a, $01 + ld [wd3d0], a +.asm_e2cf + scf + ret + +Script_MeetAmy: ; e2d1 (3:62d1) + start_script + run_command ScriptCommand_PrintTextString + tx Text044b + run_command ScriptCommand_SetDialogName + db NPC_JOSHUA + run_command ScriptCommand_PrintTextString + tx Text044c + run_command ScriptCommand_SetDialogName + db NPC_AMY + run_command ScriptCommand_PrintTextString + tx Text044d + run_command ScriptCommand_CloseTextBox + run_command Func_d095 + db $09 + db $2f + db $10 + run_command ScriptCommand_DoFrames + db $20 + run_command Func_d095 + db $04 + db $0e + db $00 + run_command Func_d0be + db $14 + db $04 + run_command ScriptCommand_SetPlayerDirection + db $03 + run_command ScriptCommand_MovePlayer + db WEST + db $01 + run_command ScriptCommand_SetPlayerDirection + db $00 + run_command ScriptCommand_MovePlayer + db NORTH + db $01 + run_command ScriptCommand_MovePlayer + db NORTH + db $01 + run_command ScriptCommand_MoveArbitraryNPC + db NPC_JOSHUA + dw NPCMovement_e2ab + run_command ScriptCommand_PrintTextString + tx Text044e + run_command ScriptCommand_Jump + dw Script_Amy.askConfirmDuel + +Script_Amy: ; e304 (3:6304) + start_script + run_command ScriptCommand_JumpIfFlagNonzero2 + db EVENT_BEAT_AMY + dw ScriptJump_TalkToAmyAgain + run_command ScriptCommand_PrintTextString + tx Text044f +.askConfirmDuel + run_command ScriptCommand_AskQuestionJump + tx Text0450 + dw .startDuel + +.denyDuel + run_command ScriptCommand_PrintTextString + tx Text0451 + run_command Func_d0d9 + db $14 + db $04 + dw Script_LostToAmy.ows_e34e + run_command ScriptCommand_QuitScriptFully + +.startDuel + run_command ScriptCommand_PrintTextString + tx Text0452 + run_command ScriptCommand_StartBattle + db PRIZES_6 + db GO_GO_RAIN_DANCE_DECK_ID + db MUSIC_DUEL_THEME_2 + run_command ScriptCommand_QuitScriptFully + +Script_BeatAmy: ; e322 (3:6322) + start_script + run_command ScriptCommand_PrintTextString + tx Text0453 + run_command ScriptCommand_JumpIfFlagNonzero2 + db EVENT_BEAT_AMY + dw .beatAmyCommon + run_command ScriptCommand_PrintTextString + tx Text0454 + run_command ScriptCommand_MaxOutFlagValue + db EVENT_BEAT_AMY + run_command ScriptCommand_TryGiveMedalPCPacks + run_command Func_d125 + db EVENT_BEAT_AMY + run_command Func_d435 + db $03 + run_command ScriptCommand_PrintTextString + tx Text0455 +.beatAmyCommon + run_command ScriptCommand_GiveBoosterPacks + db BOOSTER_LABORATORY_WATER + db BOOSTER_LABORATORY_WATER + db NO_BOOSTER + run_command ScriptCommand_PrintTextString + tx Text0456 + run_command Func_d0d9 + db $14 + db $04 + dw Script_LostToAmy.ows_e34e + run_command ScriptCommand_QuitScriptFully + +Script_LostToAmy: ; e344 (3:6344) + start_script + run_command ScriptCommand_PrintTextString + tx Text0457 + run_command Func_d0d9 + db $14 + db $04 + dw .ows_e34e + run_command ScriptCommand_QuitScriptFully + +.ows_e34e + run_command Func_d095 + db $08 + db $2e + db $10 + run_command Func_d0be + db $16 + db $04 + run_command ScriptCommand_QuitScriptFully + +ScriptJump_TalkToAmyAgain: ; e356 (3:6356) + run_command ScriptCommand_PrintTextString + tx Text0458 + run_command ScriptCommand_AskQuestionJump + tx Text0450 + dw .startDuel + run_command ScriptCommand_Jump + dw Script_Amy.denyDuel + +.startDuel + run_command ScriptCommand_PrintTextString + tx Text0459 + run_command ScriptCommand_StartBattle + db PRIZES_6 + db GO_GO_RAIN_DANCE_DECK_ID + db MUSIC_DUEL_THEME_2 + run_command ScriptCommand_QuitScriptFully +; 0xe369 + +Script_Clerk4: ; e369 (3:6369) INCROM $e369, $e39a -Chap2NPCScript: ; e39a (3:639a) +Script_Chap2: ; e39a (3:639a) INCROM $e39a, $e3d9 -Lass4NPCScript: ; e3d9 (3:63d9) +Script_Lass4: ; e3d9 (3:63d9) INCROM $e3d9, $e3dd -Hood1NPCScript: ; e3dd (3:63dd) +Script_Hood1: ; e3dd (3:63dd) INCROM $e3dd, $e408 -JenniferNPCScript: ; e408 (3:6408) +Script_Jennifer: ; e408 (3:6408) INCROM $e408, $e42f -NicholasNPCScript: ; e42f (3:642f) +Script_Nicholas: ; e42f (3:642f) INCROM $e42f, $e456 -BrandonNPCScript: ; e456 (3:6456) +Script_Brandon: ; e456 (3:6456) INCROM $e456, $e4ad -IsaacNPCScript: ; e4ad (3:64ad) - INCROM $e4ad, $e52c +Script_Isaac: ; e4ad (3:64ad) + INCROM $e4ad, $e525 + +GrassClubEntranceAfterDuel: ; e525 (3:6525) + ld hl, GrassClubEntranceAfterDuelTable + call FindEndOfBattleScript + ret FindEndOfBattleScript: ; e52c (3:652c) ld c, $0 @@ -3283,168 +4657,1790 @@ FindEndOfBattleScript: ; e52c (3:652c) .found_enemy ld a, [hli] - ld [wd3ab], a + ld [wTempNPC], a ld b, $0 add hl, bc ld c, [hl] inc hl ld b, [hl] - jp Func_c926 + jp SetNextNPCAndScript ; 0xe553 - INCROM $e553, $e566 +GrassClubEntranceAfterDuelTable: ; e553 (3:6553) + db NPC_MICHAEL + db NPC_MICHAEL + dw $6597 + dw $65ab + + db NPC_RONALD2 + db NPC_RONALD2 + dw Script_BeatFirstRonaldFight + dw Script_LostToFirstRonaldFight + + db NPC_RONALD3 + db NPC_RONALD3 + dw Script_BeatSecondRonaldFight + dw Script_LostToSecondRonaldFight + db $00 -Clerk5NPCScript: ; e566 (3:6566) +Script_Clerk5: ; e566 (3:6566) INCROM $e566, $e573 -MichaelNPCScript: ; e573 (3:6573) - INCROM $e573, $e5d2 +Script_Michael: ; e573 (3:6573) + INCROM $e573, $e5c4 + +GrassClubLobbyAfterDuel: ; e5c4 (3:65c4) + ld hl, .after_duel_table + call FindEndOfBattleScript + ret -BrittanyNPCScript: ; e5d2 (3:65d2) - INCROM $e5d2, $e61f +.after_duel_table + db NPC_BRITTANY + db NPC_BRITTANY + dw Script_BeatBrittany + dw Script_LostToBrittany + db $00 -Lass2NPCScript: ; e61f (3:661f) - INCROM $e61f, $e6d8 +Script_Brittany: ; e5d2 (3:65d2) + start_script + run_command ScriptCommand_JumpIfFlagLessThan + db EVENT_FLAG_35 + db $01 + dw NO_JUMP + run_command ScriptCommand_PrintVariableText + tx Text06e0 + tx Text06e1 + run_command ScriptCommand_AskQuestionJump + tx Text06e2 + dw .wantToDuel + run_command ScriptCommand_PrintTextString + tx Text06e3 + run_command ScriptCommand_QuitScriptFully + +.wantToDuel + run_command ScriptCommand_PrintTextString + tx Text06e4 + run_command ScriptCommand_StartBattle + db PRIZES_4 + db ETCETERA_DECK_ID + db MUSIC_DUEL_THEME_1 + run_command ScriptCommand_QuitScriptFully -Granny2NPCScript: ; e6d8 (3:66d8) +Script_BeatBrittany: ; e5ee (3:65ee) + start_script + run_command ScriptCommand_PrintTextString + tx Text06e5 + run_command ScriptCommand_GiveBoosterPacks + db BOOSTER_MYSTERY_GRASS_COLORLESS + db BOOSTER_MYSTERY_GRASS_COLORLESS + db NO_BOOSTER + run_command ScriptCommand_JumpIfFlagLessThan + db EVENT_FLAG_35 + db $02 + dw NO_JUMP + run_command ScriptCommand_PrintVariableText + tx Text06e6 + tx Text06e7 + run_command ScriptCommand_MaxOutFlagValue + db FLAG_BEAT_BRITTANY + run_command ScriptCommand_JumpIfFlagNotLessThan + db EVENT_FLAG_35 + db $02 + dw .finishScript + run_command ScriptCommand_JumpIfFlagZero2 + db EVENT_FLAG_3A + dw .finishScript + run_command ScriptCommand_JumpIfFlagZero2 + db EVENT_FLAG_3B + dw .finishScript + run_command ScriptCommand_SetFlagValue + db EVENT_FLAG_35 + db $01 + run_command ScriptCommand_MaxOutFlagValue + db EVENT_FLAG_1E + run_command ScriptCommand_PrintTextString + tx Text06e8 +.finishScript + run_command ScriptCommand_QuitScriptFully + +Script_LostToBrittany: ; e618 (3:6618) + start_script + run_command ScriptCommand_PrintTextQuitFully + tx Text06e9 +; 0xe61c + +Script_e61c: ; e61c (3:661c) + run_command ScriptCommand_PrintTextQuitFully + tx Text06ea + +Script_Lass2: ; e61f (3:661f) + start_script + run_command ScriptCommand_JumpIfFlagNonzero2 + db EVENT_FLAG_04 + dw Script_e61c + run_command ScriptCommand_JumpIfFlagNotLessThan + db EVENT_FLAG_37 + db $06 + dw Script_e61c + run_command ScriptCommand_JumpIfFlagNotLessThan + db EVENT_FLAG_37 + db $04 + dw .ows_e6a1 + run_command ScriptCommand_JumpIfFlagNotLessThan + db EVENT_FLAG_37 + db $02 + dw .ows_e66a + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_37 + db $00 + dw NO_JUMP + run_command ScriptCommand_PrintVariableText + tx Text06eb + tx Text06ec + run_command ScriptCommand_SetFlagValue + db EVENT_FLAG_37 + db $01 + run_command ScriptCommand_AskQuestionJump + tx Text06ed + dw .ows_e648 + run_command ScriptCommand_PrintTextQuitFully + tx Text06ee + +.ows_e648 + run_command Func_cf0c + db $1c + dw .ows_e64f + run_command ScriptCommand_PrintTextQuitFully + tx Text06ef + +.ows_e64f + run_command Func_cf12 + db $1c + dw .ows_e656 + run_command ScriptCommand_PrintTextQuitFully + tx Text06f0 + +.ows_e656 + run_command ScriptCommand_MaxOutFlagValue + db EVENT_FLAG_04 + run_command ScriptCommand_SetFlagValue + db EVENT_FLAG_37 + db $02 + run_command ScriptCommand_PrintTextString + tx Text06f1 + run_command Func_ccdc + tx Text06f2 + run_command ScriptCommand_TakeCard + db ODDISH + run_command ScriptCommand_GiveCard + db VILEPLUME + run_command ScriptCommand_ShowCardReceivedScreen + db VILEPLUME + run_command ScriptCommand_PrintTextQuitFully + tx Text06f3 + +.ows_e66a + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_37 + db $02 + dw NO_JUMP + run_command ScriptCommand_PrintVariableText + tx Text06f4 + tx Text06f5 + run_command ScriptCommand_SetFlagValue + db EVENT_FLAG_37 + db $03 + run_command ScriptCommand_AskQuestionJump + tx Text06ed + dw .ows_e67f + run_command ScriptCommand_PrintTextQuitFully + tx Text06f6 + +.ows_e67f + run_command Func_cf0c + db $ab + dw .ows_e686 + run_command ScriptCommand_PrintTextQuitFully + tx Text06f7 + +.ows_e686 + run_command Func_cf12 + db $ab + dw .ows_e68d + run_command ScriptCommand_PrintTextQuitFully + tx Text06f8 + +.ows_e68d + run_command ScriptCommand_MaxOutFlagValue + db EVENT_FLAG_04 + run_command ScriptCommand_SetFlagValue + db EVENT_FLAG_37 + db $04 + run_command ScriptCommand_PrintTextString + tx Text06f9 + run_command Func_ccdc + tx Text06fa + run_command ScriptCommand_TakeCard + db CLEFAIRY + run_command ScriptCommand_GiveCard + db PIKACHU3 + run_command ScriptCommand_ShowCardReceivedScreen + db PIKACHU3 + run_command ScriptCommand_PrintTextQuitFully + tx Text06f3 + +.ows_e6a1 + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_37 + db $04 + dw NO_JUMP + run_command ScriptCommand_PrintVariableText + tx Text06fb + tx Text06fc + run_command ScriptCommand_SetFlagValue + db EVENT_FLAG_37 + db $05 + run_command ScriptCommand_AskQuestionJump + tx Text06ed + dw .ows_e6b6 + run_command ScriptCommand_PrintTextQuitFully + tx Text06fd + +.ows_e6b6 + run_command Func_cf0c + db $32 + dw .ows_e6bd + run_command ScriptCommand_PrintTextQuitFully + tx Text06fe + +.ows_e6bd + run_command Func_cf12 + db $32 + dw .ows_e6c4 + run_command ScriptCommand_PrintTextQuitFully + tx Text06ff + +.ows_e6c4 + run_command ScriptCommand_MaxOutFlagValue + db EVENT_FLAG_04 + run_command ScriptCommand_SetFlagValue + db EVENT_FLAG_37 + db $06 + run_command ScriptCommand_PrintTextString + tx Text0700 + run_command Func_ccdc + tx Text0701 + run_command ScriptCommand_TakeCard + db CHARIZARD + run_command ScriptCommand_GiveCard + db BLASTOISE + run_command ScriptCommand_ShowCardReceivedScreen + db BLASTOISE + run_command ScriptCommand_PrintTextQuitFully + tx Text06f3 +; 0xe6d8 + +Script_Granny2: ; e6d8 (3:66d8) INCROM $e6d8, $e6e3 -Gal2NPCScript: ; e6e3 (3:66e3) +Script_Gal2: ; e6e3 (3:66e3) INCROM $e6e3, $e701 -KristinNPCScript: ; e701 (3:6701) +Script_Kristin: ; e701 (3:6701) INCROM $e701, $e745 -HeatherNPCScript: ; e745 (3:6745) +Script_Heather: ; e745 (3:6745) INCROM $e745, $e79e -NikkiNPCScript: ; e79e (3:679e) - INCROM $e79e, $e84c +Script_Nikki: ; e79e (3:679e) + INCROM $e79e, $e7f6 + +ClubEntranceAfterDuel: ; e7f6 (3:67f6) + ld hl, .after_duel_table + jp FindEndOfBattleScript + +.after_duel_table + db NPC_RONALD2 + db NPC_RONALD2 + dw Script_BeatFirstRonaldFight + dw Script_LostToFirstRonaldFight + + db NPC_RONALD3 + db NPC_RONALD3 + dw Script_BeatSecondRonaldFight + dw Script_LostToSecondRonaldFight + db $00 + +; A Ronald is already loaded or not loaded depending on Pre-Load scripts +; in data/npc_map_data.asm. This just starts a script if possible. +LoadClubEntrance: ; e809 (3:6809) + call TryFirstRonaldFight + call TrySecondRonaldFight + call TryFirstRonaldEncounter + ret + +TryFirstRonaldEncounter: ; e813 (3:6813) + ld a, NPC_RONALD1 + ld [wTempNPC], a + call FindLoadedNPC + ret c + ld bc, Script_FirstRonaldEncounter + jp SetNextNPCAndScript + +TryFirstRonaldFight: ; e822 (3:6822) + ld a, NPC_RONALD2 + ld [$d3ab], a + call FindLoadedNPC + ret c + get_flag_value EVENT_FLAG_4C + or a + ret nz + ld bc, Script_FirstRonaldFight + jp SetNextNPCAndScript + +TrySecondRonaldFight: ; e837 (3:6837) + ld a, NPC_RONALD3 + ld [$d3ab], a + call FindLoadedNPC + ret c + get_flag_value EVENT_FLAG_4D + or a + ret nz + ld bc, ScriptSecondRonaldFight + jp SetNextNPCAndScript +; 0xe84c -Clerk6NPCScript: ; e84c (3:684c) +Script_Clerk6: ; e84c (3:684c) INCROM $e84c, $e850 -Lad3NPCScript: ; e850 (3:6850) - INCROM $e850, $e980 +Script_Lad3: ; e850 (3:6850) + INCROM $e850, $e862 + +Script_FirstRonaldEncounter: ; e862 (3:6862) + start_script + run_command ScriptCommand_MaxOutFlagValue + db EVENT_FLAG_4B + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_e894 + run_command Func_d135 + db $00 + run_command ScriptCommand_PrintTextString + tx Text0645 + run_command ScriptCommand_CloseTextBox + run_command ScriptCommand_MovePlayer + db NORTH + db $01 + run_command ScriptCommand_MovePlayer + db NORTH + db $01 + run_command ScriptCommand_PrintTextString + tx Text0646 + run_command ScriptCommand_AskQuestionJumpDefaultYes + dw 0000 + dw .ows_e882 + run_command ScriptCommand_PrintTextString + tx Text0647 + run_command ScriptCommand_Jump + dw .ows_e885 + +.ows_e882 + run_command ScriptCommand_PrintTextString + tx Text0648 +.ows_e885 + run_command ScriptCommand_PrintTextString + tx Text0649 + run_command ScriptCommand_CloseTextBox + run_command ScriptCommand_SetPlayerDirection + db $03 + run_command ScriptCommand_MovePlayer + db EAST + db $04 + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_e894 + run_command Func_cdcb + run_command Func_d41d + run_command ScriptCommand_QuitScriptFully + +NPCMovement_e894: ; e894 (3:6894) + db SOUTH + db SOUTH + db SOUTH + db SOUTH + db SOUTH + db $ff +; e89a + + INCROM $e89a, $e8c0 + +Script_FirstRonaldFight: ; e8c0 (3:68c0) + start_script + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_e905 + run_command ScriptCommand_DoFrames + db $3c + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_e90d + run_command ScriptCommand_PrintTextString + tx Text064a + run_command ScriptCommand_JumpIfPlayerCoordMatches + db $08 + db $02 + dw $68d6 + run_command ScriptCommand_SetPlayerDirection + db WEST + run_command ScriptCommand_MovePlayer + db WEST + db $01 + run_command ScriptCommand_SetPlayerDirection + db SOUTH + run_command ScriptCommand_MovePlayer + db SOUTH + db $01 + run_command ScriptCommand_MovePlayer + db SOUTH + db $01 + run_command ScriptCommand_PrintTextString + tx Text064b + run_command ScriptCommand_SetFlagValue + db $4c + db $01 + run_command ScriptCommand_StartBattle + db PRIZES_6 + db IM_RONALD_DECK_ID + db MUSIC_RONALD + run_command ScriptCommand_QuitScriptFully + +Script_BeatFirstRonaldFight: ; e8e9 (3:68e9) + start_script + run_command ScriptCommand_PrintTextString + tx Text064c + run_command ScriptCommand_GiveCard + db JIGGLYPUFF1 + run_command ScriptCommand_ShowCardReceivedScreen + db JIGGLYPUFF1 + run_command ScriptCommand_PrintTextString + tx Text064d + run_command ScriptCommand_Jump + dw ScriptJump_FinishedFirstRonaldFight + +Script_LostToFirstRonaldFight: ; e8f7 (3:68f7) + start_script + run_command ScriptCommand_PrintTextString + tx Text064e + +ScriptJump_FinishedFirstRonaldFight + run_command ScriptCommand_SetFlagValue + db EVENT_FLAG_4C + db $02 + run_command ScriptCommand_CloseTextBox + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_e90f + run_command Func_cdcb + run_command Func_d41d + run_command ScriptCommand_QuitScriptFully + +NPCMovement_e905: ; e905 (3:6905) + db EAST + db EAST + db EAST + db EAST + db EAST + db SOUTH + db NORTH | NO_MOVE + db $ff + +NPCMovement_e90d: ; e90d (3:690d) + db NORTH + db $ff + +NPCMovement_e90f: ; e90f (3:690f) + db SOUTH + db SOUTH + db SOUTH + db SOUTH + db SOUTH + db $ff +; e915 + + INCROM $e915, $e91e + +ScriptSecondRonaldFight: ; e91e (3:691e) + start_script + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_e905 + run_command ScriptCommand_DoFrames + db 60 + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_e90d + run_command ScriptCommand_PrintTextString + tx Text064f + run_command ScriptCommand_JumpIfPlayerCoordMatches + db $08 + db $02 + dw .ows_6934 + run_command ScriptCommand_SetPlayerDirection + db WEST + run_command ScriptCommand_MovePlayer + db WEST + db $01 +.ows_6934 + run_command ScriptCommand_SetPlayerDirection + db SOUTH + run_command ScriptCommand_MovePlayer + db SOUTH + db $01 + run_command ScriptCommand_MovePlayer + db SOUTH + db $01 + run_command ScriptCommand_PrintTextString + tx Text0650 + run_command ScriptCommand_SetFlagValue + db EVENT_FLAG_4D + db $01 + run_command ScriptCommand_StartBattle + db PRIZES_6 + db POWERFUL_RONALD_DECK_ID + db MUSIC_RONALD + run_command ScriptCommand_QuitScriptFully + +Script_BeatSecondRonaldFight: ; e947 (3:6947) + start_script + run_command ScriptCommand_PrintTextString + tx Text0651 + run_command ScriptCommand_GiveCard + db SUPER_ENERGY_RETRIEVAL + run_command ScriptCommand_ShowCardReceivedScreen + db SUPER_ENERGY_RETRIEVAL + run_command ScriptCommand_PrintTextString + tx Text0652 + run_command ScriptCommand_Jump + dw ScriptJump_FinishedSecondRonaldFight + +Script_LostToSecondRonaldFight: ; e955 (3:6955) + start_script + run_command ScriptCommand_PrintTextString + tx Text0653 + +ScriptJump_FinishedSecondRonaldFight ; e959 (3:6959) + run_command ScriptCommand_SetFlagValue + db EVENT_FLAG_4D + db $02 + run_command ScriptCommand_CloseTextBox + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_e90f + run_command Func_cdcb + run_command Func_d41d + run_command ScriptCommand_QuitScriptFully +; 0xe963 + + INCROM $e963, $e980 -RobertNPCScript: ; e980 (3:6980) +Script_Robert: ; e980 (3:6980) INCROM $e980, $e9a5 -Pappy1NPCScript: ; e9a5 (3:69a5) +Script_Pappy1: ; e9a5 (3:69a5) INCROM $e9a5, $ea30 -Gal3NPCScript: ; ea30 (3:6a30) +Script_Gal3: ; ea30 (3:6a30) INCROM $ea30, $ea3b -Chap4NPCScript: ; ea3b (3:6a3b) +Script_Chap4: ; ea3b (3:6a3b) INCROM $ea3b, $ea60 -DanielNPCScript: ; ea60 (3:6a60) +Script_Daniel: ; ea60 (3:6a60) INCROM $ea60, $eaa2 -StephanieNPCScript: ; eaa2 (3:6aa2) +Script_Stephanie: ; eaa2 (3:6aa2) INCROM $eaa2, $eadf -Murray2NPCScript: ; eadf (3:6adf) +Script_Murray2: ; eadf (3:6adf) INCROM $eadf, $eadf -MurrayNPCScript: ; eadf (3:6adf) +Script_Murray1: ; eadf (3:6adf) INCROM $eadf, $eb53 -Clerk7NPCScript: ; eb53 (3:6b53) +Script_Clerk7: ; eb53 (3:6b53) INCROM $eb53, $eb84 -Lad1NPCScript: ; eb84 (3:6b84) +Script_Lad1: ; eb84 (3:6b84) INCROM $eb84, $ebc1 -Man3NPCScript: ; ebc1 (3:6bc1) +Script_Man3: ; ebc1 (3:6bc1) INCROM $ebc1, $ebc5 -Specs2NPCScript: ; ebc5 (3:6bc5) +Script_Specs2: ; ebc5 (3:6bc5) INCROM $ebc5, $ebed -Specs3NPCScript: ; ebed (3:6bed) +Script_Specs3: ; ebed (3:6bed) INCROM $ebed, $ec11 -DavidNPCScript: ; ec11 (3:6c11) +Script_David: ; ec11 (3:6c11) INCROM $ec11, $ec42 -ErikNPCScript: ; ec42 (3:6c42) +Script_Erik: ; ec42 (3:6c42) INCROM $ec42, $ec67 -RickNPCScript: ; ec67 (3:6c67) +Script_Rick: ; ec67 (3:6c67) INCROM $ec67, $ecdb -JosephNPCScript: ; ecdb (3:6cdb) +Script_Joseph: ; ecdb (3:6cdb) INCROM $ecdb, $ed45 -Clerk8NPCScript: ; ed45 (3:6d45) - INCROM $ed45, $ed96 +Script_Clerk8: ; ed45 (3:6d45) + INCROM $ed45, $ed57 + +FireClubPressedA: ; ed57 (3:6d57) + ld hl, SlowpokePaintingObjectTable + call FindExtraInteractableObjects + ret + +SlowpokePaintingObjectTable: ; ed5e (3:6d5e) + db 16, 2, NORTH + dw Script_ee76 + db $00 + +; Given a table with data of the form: +; X, Y, Dir, Script +; Searches to try to find a match, and starts a Script if possible +FindExtraInteractableObjects: ; ed64 (3:6d64) + ld de, $5 +.findObjectMatchLoop + ld a, [hl] + or a + ret z + push hl + ld a, [wPlayerXCoord] + cp [hl] + jr nz, .didNotMatch + inc hl + ld a, [wPlayerYCoord] + cp [hl] + jr nz, .didNotMatch + inc hl + ld a, [wPlayerDirection] + cp [hl] + jr z, .foundObject +.didNotMatch + pop hl + add hl, de + jr .findObjectMatchLoop +.foundObject + inc hl + ld c, [hl] + inc hl + ld b, [hl] + pop hl + call SetNextScript + scf + ret +; 0xed8d + + INCROM $ed8d, $ed96 -JessicaNPCScript: ; ed96 (3:6d96) +Script_Jessica: ; ed96 (3:6d96) INCROM $ed96, $ede8 -Chap3NPCScript: ; ede8 (3:6de8) +Script_Chap3: ; ede8 (3:6de8) INCROM $ede8, $ee2c -Lad2NPCScript: ; ee2c (3:6e2c) - INCROM $ee2c, $ee88 +Script_Lad2: ; ee2c (3:6e2c) + INCROM $ee2c, $ee76 + +Script_ee76: ; ee76 (3:6e76) + start_script + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_21 + db $01 + dw .ows_ee7d + run_command ScriptCommand_QuitScriptFully -ManiaNPCScript: ; ee88 (3:6e88) +.ows_ee7d + run_command ScriptCommand_SetFlagValue + db EVENT_FLAG_21 + db $02 + run_command Func_ccdc + tx Text06a2 + run_command ScriptCommand_GiveCard + db SLOWPOKE1 + run_command ScriptCommand_ShowCardReceivedScreen + db SLOWPOKE1 + run_command ScriptCommand_QuitScriptFully +; 0xee88 + +Script_Mania: ; ee88 (3:6e88) INCROM $ee88, $eeb3 -JohnNPCScript: ; eeb3 (3:6eb3) +Script_John: ; eeb3 (3:6eb3) INCROM $eeb3, $eed8 -AdamNPCScript: ; eed8 (3:6ed8) +Script_Adam: ; eed8 (3:6ed8) INCROM $eed8, $eefd -JonathanNPCScript: ; eefd (3:6efd) +Script_Jonathan: ; eefd (3:6efd) INCROM $eefd, $ef22 -KenNPCScript: ; ef22 (3:6f22) - INCROM $ef22, $f025 +Script_Ken: ; ef22 (3:6f22) + INCROM $ef22, $ef96 + +Preload_Clerk9: ; ef96 (3:6f96) + call TryGiveMedalPCPacks + get_flag_value EVENT_MEDAL_COUNT + ld hl, .jumpTable + cp $09 + jp c, JumpToFunctionInTable + debug_ret + jr .asm_efe4 + +.jumpTable + dw .asm_efe4 + dw .asm_efe4 + dw .asm_efe4 + dw .asm_efba + dw .asm_efde + dw .asm_efc9 + dw .asm_efd8 + dw .asm_efd8 + dw .asm_efd8 + +.asm_efba + get_flag_value EVENT_FLAG_3F + or a + jr nz, .asm_efe4 + ld c, $01 + set_flag_value EVENT_FLAG_3F + jr .asm_efe4 + +.asm_efc9 + get_flag_value EVENT_FLAG_40 + or a + jr nz, .asm_efde + ld c, $01 + set_flag_value EVENT_FLAG_40 + jr .asm_efde + +.asm_efd8 + ld c, $07 + set_flag_value EVENT_FLAG_40 +.asm_efde + ld c, $07 + set_flag_value EVENT_FLAG_3F +.asm_efe4 + zero_flag_value EVENT_FLAG_42 + get_flag_value EVENT_FLAG_3F + cp $00 + jr z, .asm_eff8 + cp $07 + jr z, .asm_eff8 + ld c, $01 + jr .asm_f016 + +.asm_eff8 + get_flag_value EVENT_FLAG_40 + cp $00 + jr z, .asm_f008 + cp $07 + jr z, .asm_f008 + ld c, $02 + jr .asm_f016 + +.asm_f008 + get_flag_value EVENT_FLAG_41 + cp $00 + jr z, .asm_f023 + cp $07 + jr z, .asm_f023 + ld c, $03 +.asm_f016 + set_flag_value EVENT_FLAG_44 + max_flag_value EVENT_FLAG_42 + ld a, $0b + ld [wd111], a +.asm_f023 + scf + ret + +Script_Clerk9: ; f025 (3:7025) + start_script + run_command ScriptCommand_JumpIfFlagZero1 + db EVENT_FLAG_3F + dw .ows_f066 + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_41 + db $07 + dw .ows_f069 + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_41 + db $03 + dw .ows_f06f + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_41 + db $02 + dw .ows_f072 + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_41 + db $01 + dw .ows_f06c + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_40 + db $07 + dw .ows_f069 + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_40 + db $03 + dw .ows_f06f + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_40 + db $02 + dw .ows_f072 + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_40 + db $01 + dw .ows_f06c + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_3F + db $07 + dw .ows_f069 + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_3F + db $03 + dw .ows_f06f + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_3F + db $02 + dw .ows_f072 + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_3F + db $01 + dw .ows_f06c +.ows_f066 + run_command ScriptCommand_PrintTextQuitFully + tx Text050a + +.ows_f069 + run_command ScriptCommand_PrintTextQuitFully + tx Text050b + +.ows_f06c + run_command ScriptCommand_PrintTextQuitFully + tx Text050c + +.ows_f06f + run_command ScriptCommand_PrintTextQuitFully + tx Text050d + +.ows_f072 + run_command ScriptCommand_PrintTextQuitFully + tx Text050e + +Preload_ChallengeHallNPCs2: ; f075 (3:7075) + call Preload_ChallengeHallNPCs1 + ccf + ret + +Preload_ChallengeHallNPCs1: ; f07a (3:707a) + get_flag_value EVENT_FLAG_42 + or a + jr z, .quit + ld a, $0b + ld [wd111], a + scf +.quit + ret + +ChallengeHallLobbyLoadMap: ; f088 (3:7088) + get_flag_value EVENT_FLAG_58 + or a + ret z + ld a, $02 + ld [wTempNPC], a + call FindLoadedNPC + ld bc, $7166 + jp SetNextNPCAndScript + +Script_Pappy3: ; f09c (3:709c) + start_script + run_command ScriptCommand_PrintTextQuitFully + tx Text050f + +Script_Gal4: ; f0a0 (3:70a0) + start_script + run_command ScriptCommand_PrintTextQuitFully + tx Text0510 + +Script_Champ: ; f0a4 (3:70a4) + start_script + run_command ScriptCommand_PrintTextQuitFully + tx Text0511 + +Script_Hood2: ; f0a8 (3:70a8) + start_script + run_command ScriptCommand_PrintTextQuitFully + tx Text0512 + +Script_Lass5: ; f0ac (3:70ac) + start_script + run_command ScriptCommand_PrintTextQuitFully + tx Text0513 + +Script_Chap5: ; f0b0 (3:70b0) + start_script + run_command ScriptCommand_PrintTextQuitFully + tx Text0514 + +Preload_ChallengeHallLobbyRonald1: ; f0b4 (3:70b4) + zero_flag_value2 EVENT_FLAG_58 + get_flag_value EVENT_RECEIVED_LEGENDARY_CARD + or a + jr nz, .asm_f0ff + get_flag_value EVENT_FLAG_59 + or a + jr nz, .asm_f11f + get_flag_value EVENT_FLAG_40 + cp $00 + jr z, .asm_f0e5 + call .asm_710f + get_flag_value EVENT_FLAG_40 + ld e, a + get_flag_value EVENT_FLAG_49 + ld d, a + ld hl, Unknown_f156 + call Func_f121 + jr nc, .asm_f11f + jr .asm_f0f7 +.asm_f0e5 + get_flag_value EVENT_FLAG_3F + ld e, a + get_flag_value EVENT_FLAG_48 + ld d, a + ld hl, Unknown_f146 + call Func_f121 + jr nc, .asm_f11f +.asm_f0f7 + ld a, [wPlayerYCoord] + ld [wLoadNPCYPos], a + scf + ret +.asm_f0ff + max_flag_value EVENT_FLAG_54 + max_flag_value EVENT_FLAG_55 + max_flag_value EVENT_FLAG_56 + max_flag_value EVENT_FLAG_57 +.asm_710f + max_flag_value EVENT_FLAG_50 + max_flag_value EVENT_FLAG_51 + max_flag_value EVENT_FLAG_52 + max_flag_value EVENT_FLAG_53 +.asm_f11f + or a + ret + +Func_f121: ; f121 (3:7121) + ld c, $04 +.asm_f123 + ld a, [hli] + cp e + jr nz, .asm_f13e + ld a, [hli] + cp d + jr nz, .asm_f13f + ld a, [hl] + call GetEventFlagValue + or a + jr nz, .asm_f13f + ld a, [hl] + call MaxOutEventFlag + inc hl + ld c, [hl] + set_flag_value EVENT_FLAG_58 + scf + ret +.asm_f13e + inc hl +.asm_f13f + inc hl + inc hl + dec c + jr nz, .asm_f123 + or a + ret +; 0xf146 + +Unknown_f146: ; f146 (3:7146) + INCROM $f146, $f156 -Clerk9NPCScript: ; f025 (3:7025) - INCROM $f025, $f09c +Unknown_f156: ; f156 (3:7156) + INCROM $f156, $f239 + +ChallengeHallAfterDuel: ; f239 (3:7239) + ld c, $00 + ld a, [wDuelResult] + or a + jr z, .won + ld c, $02 +.won + ld b, $00 + ld hl, ChallengeHallAfterDuelTable + add hl, bc + ld c, [hl] + inc hl + ld b, [hl] + ld a, NPC_HOST + ld [wTempNPC], a + jp SetNextNPCAndScript + +ChallengeHallAfterDuelTable: + dw WonAtChallengeHall + dw LostAtChallengeHall + +ChallengeHallLoadMap: ; f258 (3:7258) + get_flag_value EVENT_FLAG_47 + or a + ret z + ld a, NPC_HOST + ld [wTempNPC], a + call FindLoadedNPC + ld bc, Script_f433 + jp SetNextNPCAndScript + +Script_Clerk13: ; f26c (3:726c) + start_script + run_command ScriptCommand_PrintTextQuitFully + tx Text0525 + +Preload_Guide: ; f270 (3:7270) + get_flag_value EVENT_FLAG_42 + or a + jr z, .asm_f281 + ld a, $1c + ld [wLoadNPCXPos], a + ld a, $02 + ld [wLoadNPCYPos], a +.asm_f281 + scf + ret +; 0xf283 -Pappy3NPCScript: ; f09c (3:709c) - INCROM $f09c, $f0a0 +Script_Guide: ; f283 (3:7283) + start_script + run_command ScriptCommand_JumpIfFlagZero2 + db EVENT_FLAG_42 + dw .ows_f28b + run_command ScriptCommand_PrintTextQuitFully + tx Text0526 + +.ows_f28b + run_command ScriptCommand_JumpIfFlagZero1 + db $3f + dw .ows_f292 + run_command ScriptCommand_PrintTextQuitFully + tx Text0527 -Gal4NPCScript: ; f0a0 (3:70a0) - INCROM $f0a0, $f0a4 +.ows_f292 + run_command ScriptCommand_PrintTextQuitFully + tx Text0528 -ChampNPCScript: ; f0a4 (3:70a4) - INCROM $f0a4, $f0a8 +Script_Clerk12: ; f295 (3:7295) + start_script + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_41 + db $03 + dw .ows_f2c4 + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_41 + db $02 + dw .ows_f2c1 + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_40 + db $03 + dw .ows_f2c4 + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_40 + db $02 + dw .ows_f2c1 + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_3F + db $03 + dw .ows_f2c4 + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_3F + db $02 + dw .ows_f2c1 + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_44 + db $02 + dw .ows_f2cd + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_44 + db $03 + dw .ows_f2d3 + run_command ScriptCommand_Jump + dw .ows_f2c7 + +.ows_f2c1 + run_command ScriptCommand_PrintTextQuitFully + tx Text0529 + +.ows_f2c4 + run_command ScriptCommand_PrintTextQuitFully + tx Text052a + +.ows_f2c7 + run_command ScriptCommand_PrintTextString + tx Text052b + run_command ScriptCommand_Jump + dw .ows_f2d6 + +.ows_f2cd + run_command ScriptCommand_PrintTextString + tx Text052c + run_command ScriptCommand_Jump + dw .ows_f2d6 + +.ows_f2d3 + run_command ScriptCommand_PrintTextString + tx Text052d +.ows_f2d6 + run_command ScriptCommand_PrintTextString + tx Text052e + run_command ScriptCommand_AskQuestionJump + tx Text052f + dw .ows_f2e1 + run_command ScriptCommand_PrintTextQuitFully + tx Text0530 + +.ows_f2e1 + run_command ScriptCommand_MaxOutFlagValue + db EVENT_FLAG_59 + run_command ScriptCommand_PrintTextString + tx Text0531 + run_command ScriptCommand_CloseTextBox + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_f349 + run_command ScriptCommand_JumpIfPlayerCoordMatches + db 8 + db 18 + dw .ows_f2fa + run_command ScriptCommand_JumpIfPlayerCoordMatches + db 12 + db 18 + dw .ows_f302 + run_command ScriptCommand_MovePlayer + db NORTH + db $02 + run_command ScriptCommand_Jump + dw .ows_f307 + +.ows_f2fa + run_command ScriptCommand_SetPlayerDirection + db EAST + run_command ScriptCommand_MovePlayer + db EAST + db $02 + run_command ScriptCommand_Jump + dw .ows_f307 + +.ows_f302 + run_command ScriptCommand_SetPlayerDirection + db WEST + run_command ScriptCommand_MovePlayer + db WEST + db $02 +.ows_f307 + run_command ScriptCommand_SetPlayerDirection + db NORTH + run_command ScriptCommand_MovePlayer + db NORTH + db $01 + run_command ScriptCommand_MovePlayer + db NORTH + db $01 + run_command ScriptCommand_MovePlayer + db NORTH + db $01 + run_command ScriptCommand_MovePlayer + db NORTH + db $01 + run_command ScriptCommand_MovePlayer + db NORTH + db $01 + run_command ScriptCommand_JumpIfFlagNonzero2 + db EVENT_FLAG_43 + dw .ows_f33a + run_command ScriptCommand_MaxOutFlagValue + db EVENT_FLAG_43 + run_command ScriptCommand_MovePlayer + db NORTH + db $01 + run_command ScriptCommand_MovePlayer + db NORTH + db $01 + run_command ScriptCommand_SetPlayerDirection + db EAST + run_command ScriptCommand_DoFrames + db 30 + run_command ScriptCommand_SetPlayerDirection + db SOUTH + run_command ScriptCommand_DoFrames + db 20 + run_command ScriptCommand_SetPlayerDirection + db EAST + run_command ScriptCommand_DoFrames + db 20 + run_command ScriptCommand_SetPlayerDirection + db SOUTH + run_command ScriptCommand_DoFrames + db 30 + run_command ScriptCommand_MovePlayer + db SOUTH + db $01 + run_command ScriptCommand_MovePlayer + db SOUTH + db $01 +.ows_f33a + run_command ScriptCommand_SetPlayerDirection + db EAST + run_command ScriptCommand_MovePlayer + db EAST + db $01 + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_f34e + run_command ScriptCommand_CloseAdvancedTextBox + run_command ScriptCommand_SetNextNPCandScript + db $4a + dw Script_f353 + run_command ScriptCommand_EndScriptLoop1 + ret +; f349 -Hood2NPCScript: ; f0a8 (3:70a8) - INCROM $f0a8, $f0ac +NPCMovement_f349: ; f349 (3:7349) + db NORTH + db NORTH + db EAST +; fallthrough -Lass5NPCScript: ; f0ac (3:70ac) - INCROM $f0ac, $f0b0 +NPCMovement_f34c: ; f34c (3:734c) + db WEST | NO_MOVE + db $ff -Chap5NPCScript: ; f0b0 (3:70b0) - INCROM $f0b0, $f26c +NPCMovement_f34e: ; f34e (3:734e) + db WEST + db SOUTH + db SOUTH + db $ff -Clerk13NPCScript: ; f26c (3:726c) - INCROM $f26c, $f283 +Script_Host: ; f352 (3:7352) + ret -GuideNPCScript: ; f283 (3:7283) - INCROM $f283, $f295 +Script_f353: ; f353 (3:7353) + start_script + run_command ScriptCommand_DoFrames + db 20 + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_f37d + run_command ScriptCommand_DoFrames + db 20 + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_f390 + run_command Func_d16b + db $00 + run_command ScriptCommand_PrintTextString + tx Text0532 + run_command ScriptCommand_CloseTextBox + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_f37f + run_command ScriptCommand_PrintTextString + tx Text0533 + run_command ScriptCommand_CloseTextBox + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_f388 + run_command ScriptCommand_PrintTextString + tx Text0534 + run_command ScriptCommand_CloseTextBox + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_f38e + run_command ScriptCommand_PrintTextString + tx Text0535 + run_command Func_cd4f + db $04 + db $00 + db $00 + run_command ScriptCommand_QuitScriptFully + +NPCMovement_f37d: ; f37d (3:737d) + db EAST | NO_MOVE + db $ff + +NPCMovement_f37f: ; f37f (3:737f) + db EAST + db EAST + db SOUTH + db $ff + +NPCMovement_f383: ; f383 (3:7383) + db NORTH + db WEST + db WEST + db SOUTH | NO_MOVE + db $ff + +NPCMovement_f388: ; f388 (3:7388) + db NORTH + db WEST + db WEST +; fallthrough + +NPCMovement_f38b: ; f38b (3:738b) + db WEST + db SOUTH + db $ff + +NPCMovement_f38e: ; f38e (3:738e) + db NORTH + db EAST +; fallthrough + +NPCMovement_f390: ; f390 (3:7390) + db SOUTH | NO_MOVE + db $ff + +LostAtChallengeHall: ; f392 (3:7392) + start_script + run_command ScriptCommand_DoFrames + db 20 + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_f37d + run_command ScriptCommand_DoFrames + db 20 + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_f390 + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_45 + db $02 + dw ScriptJump_f410 + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_45 + db $03 + dw ScriptJump_f410.ows_f41a + run_command Func_d16b + db $00 + run_command Func_d16b + db $01 + run_command ScriptCommand_PrintTextString + tx Text0536 +.ows_f3ae + run_command ScriptCommand_CloseTextBox + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_f38b + run_command ScriptCommand_PrintTextString + tx Text0537 + run_command ScriptCommand_CloseTextBox + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_f38e + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_44 + db $02 + dw .ows_f3ce + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_44 + db $03 + dw .ows_f3d9 + run_command ScriptCommand_SetFlagValue + db EVENT_FLAG_3F + db $03 + run_command ScriptCommand_SetFlagValue + db EVENT_FLAG_48 + db $03 + run_command ScriptCommand_ZeroOutFlagValue + db EVENT_FLAG_51 + run_command ScriptCommand_Jump + dw .ows_f3e2 +.ows_f3ce + run_command ScriptCommand_SetFlagValue + db EVENT_FLAG_40 + db $03 + run_command ScriptCommand_SetFlagValue + db EVENT_FLAG_49 + db $03 + run_command ScriptCommand_ZeroOutFlagValue + db EVENT_FLAG_55 + run_command ScriptCommand_Jump + dw .ows_f3e2 +.ows_f3d9 + run_command ScriptCommand_SetFlagValue + db EVENT_FLAG_41 + db $03 + run_command ScriptCommand_SetFlagValue + db EVENT_FLAG_4A + db $03 + run_command ScriptCommand_Jump + dw .ows_f3e2 +.ows_f3e2 + run_command ScriptCommand_CloseAdvancedTextBox + run_command ScriptCommand_SetNextNPCandScript + db NPC_CLERK12 + dw Script_f3e9 + run_command ScriptCommand_EndScriptLoop1 + ret -Clerk12NPCScript: ; f295 (3:7295) - INCROM $f295, $f352 +Script_f3e9: ; f3e9 (3:73e9) + start_script + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_f40a + run_command ScriptCommand_SetPlayerDirection + db WEST + run_command ScriptCommand_MovePlayer + db WEST + db $01 + run_command ScriptCommand_SetPlayerDirection + db SOUTH + run_command ScriptCommand_MovePlayer + db SOUTH + db $01 + run_command ScriptCommand_MovePlayer + db SOUTH + db $01 + run_command ScriptCommand_MovePlayer + db SOUTH + db $01 + run_command ScriptCommand_MovePlayer + db SOUTH + db $01 + run_command ScriptCommand_MovePlayer + db SOUTH + db $01 + run_command ScriptCommand_MovePlayer + db SOUTH + db $01 + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_f40d + run_command ScriptCommand_QuitScriptFully + +NPCMovement_f40a: ; f40a (3:740a) + db WEST + db EAST | NO_MOVE + db $ff + +NPCMovement_f40d: ; f40d (3:740d) + db EAST + db SOUTH | NO_MOVE + db $ff + +ScriptJump_f410: ; f410 (4:7410) + run_command Func_d16b + db $00 + run_command Func_d16b + db $01 + run_command ScriptCommand_PrintTextString + tx Text0538 + run_command ScriptCommand_Jump + dw LostAtChallengeHall.ows_f3ae + +.ows_f41a + run_command ScriptCommand_PrintTextString + tx Text0539 + run_command ScriptCommand_SetDialogName + db NPC_RONALD1 + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_44 + db $03 + dw .ows_f42e + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_44 + db $01 + dw NO_JUMP + run_command ScriptCommand_PrintVariableText + tx Text053a + tx Text053b +.ows_f42e + run_command ScriptCommand_SetDialogName + db NPC_HOST + run_command ScriptCommand_Jump + dw LostAtChallengeHall.ows_f3ae + +Script_f433: ; f433 (3:7433) + start_script + run_command ScriptCommand_DoFrames + db 20 + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_f37d + run_command ScriptCommand_DoFrames + db 20 + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_f390 + run_command ScriptCommand_Jump + dw WonAtChallengeHall.ows_f4a4 + +WonAtChallengeHall; f441 (3:7441) + start_script + run_command ScriptCommand_DoFrames + db 20 + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_f37d + run_command ScriptCommand_DoFrames + db 20 + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_f390 + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_45 + db $03 + dw ScriptJump_f4db + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_45 + db $02 + dw .ows_f456 +.ows_f456 + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_45 + db $01 + dw NO_JUMP + run_command ScriptCommand_PrintVariableText + tx Text053c + tx Text053d + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_f37f + run_command Func_d16b + db $00 + run_command ScriptCommand_PrintTextString + tx Text053e + run_command ScriptCommand_CloseTextBox + run_command ScriptCommand_MoveWramNPC + dw NPCMovement_f4c8 + run_command Func_cdd8 + run_command ScriptCommand_PrintTextString + tx Text053f + run_command ScriptCommand_CloseTextBox + run_command Func_d195 + run_command Func_cdf5 + db $14 + db $14 + run_command ScriptCommand_MoveWramNPC + dw NPCMovement_f4d0 + run_command Func_d16b + db $00 + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_45 + db $02 + dw NO_JUMP + run_command ScriptCommand_PrintVariableText + tx Text0540 + tx Text0541 + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_f383 + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_45 + db $02 + dw .ows_f4a4 + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_44 + db $03 + dw .ows_f4a1 + run_command ScriptCommand_CloseTextBox + run_command ScriptCommand_SetDialogName + db $02 + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_44 + db $01 + dw NO_JUMP + run_command ScriptCommand_PrintVariableText + tx Text0542 + tx Text0543 + run_command ScriptCommand_SetDialogName + db NPC_HOST + run_command ScriptCommand_CloseTextBox +.ows_f4a1 + run_command ScriptCommand_PrintTextString + tx Text0544 +.ows_f4a4 + run_command ScriptCommand_ZeroOutFlagValue + db EVENT_FLAG_47 + run_command ScriptCommand_PrintTextString + tx Text0545 + run_command ScriptCommand_AskQuestionJumpDefaultYes + tx Text0546 + dw .ows_f4bd + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_45 + db $02 + dw NO_JUMP + run_command ScriptCommand_PrintVariableText + tx Text0547 + tx Text0548 + run_command Func_cd4f + db $04 + db $00 + db $00 + run_command ScriptCommand_QuitScriptFully +.ows_f4bd + run_command ScriptCommand_PrintTextString + tx Text0549 + run_command ScriptCommand_CloseTextBox + run_command ScriptCommand_MaxOutFlagValue + db EVENT_FLAG_47 + run_command Func_d1ad + run_command ScriptCommand_CloseTextBox + run_command ScriptCommand_Jump + dw .ows_f4a4 + +NPCMovement_f4c8: ; f4c8 (3:74c8) + db EAST +NPCMovement_f4c9: ; f4c9 (3:74c9) + db SOUTH + db SOUTH + db SOUTH + db SOUTH + db SOUTH + db SOUTH + db $ff + +NPCMovement_f4d0: ; f4d0 (3:74d0) + db NORTH + db NORTH + db NORTH + db NORTH + db NORTH + db NORTH + db WEST + db $ff + +NPCMovement_f4d8: ; f4d8 (3:74d8) + db EAST + db SOUTH | NO_MOVE + db $ff + +ScriptJump_f4db: ; f4db (3:74db) + run_command ScriptCommand_PrintTextString + tx Text054a + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_f37f + run_command Func_d16b + db $00 + run_command ScriptCommand_PrintTextString + tx Text054b + run_command ScriptCommand_CloseTextBox + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_44 + db $03 + dw .ows_f513 + run_command ScriptCommand_SetDialogName + db $02 + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_44 + db $01 + dw NO_JUMP + run_command ScriptCommand_PrintVariableText + tx Text054c + tx Text054d + run_command ScriptCommand_MoveWramNPC + dw NPCMovement_f4d8 + run_command ScriptCommand_DoFrames + db 40 + run_command ScriptCommand_MoveWramNPC + dw NPCMovement_f34c + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_44 + db $01 + dw NO_JUMP + run_command ScriptCommand_PrintVariableText + tx Text054e + tx Text054f + run_command ScriptCommand_SetDialogName + db NPC_HOST + run_command ScriptCommand_CloseTextBox + run_command ScriptCommand_MoveWramNPC + dw NPCMovement_f4c9 + run_command ScriptCommand_Jump + dw .ows_f516 +.ows_f513 + run_command ScriptCommand_MoveWramNPC + dw NPCMovement_f4c8 +.ows_f516 + run_command Func_cdd8 + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_f383 + run_command ScriptCommand_PrintTextString + tx Text0550 + run_command ScriptCommand_CloseTextBox + run_command ScriptCommand_MoveActiveNPC + dw NPCMovement_f38b + run_command Func_d1b3 + run_command ScriptCommand_PrintTextString + tx Text0551 + run_command ScriptCommand_GiveCard + db $00 + run_command ScriptCommand_ShowCardReceivedScreen + db $00 + run_command ScriptCommand_PrintTextString + tx Text0552 + run_command ScriptCommand_CloseTextBox + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_44 + db $02 + dw .ows_f540 + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_44 + db $03 + dw .ows_f549 + run_command ScriptCommand_SetFlagValue + db EVENT_FLAG_3F + db $02 + run_command ScriptCommand_SetFlagValue + db EVENT_FLAG_48 + db $02 + run_command ScriptCommand_Jump + dw .ows_f552 +.ows_f540 + run_command ScriptCommand_SetFlagValue + db EVENT_FLAG_40 + db $02 + run_command ScriptCommand_SetFlagValue + db EVENT_FLAG_49 + db $02 + run_command ScriptCommand_Jump + dw .ows_f552 +.ows_f549 + run_command ScriptCommand_SetFlagValue + db EVENT_FLAG_41 + db $02 + run_command ScriptCommand_SetFlagValue + db EVENT_FLAG_4A + db $02 + run_command ScriptCommand_Jump + dw .ows_f552 +.ows_f552 + run_command ScriptCommand_CloseAdvancedTextBox + run_command ScriptCommand_SetNextNPCandScript + db NPC_CLERK12 + dw Script_f3e9 + run_command ScriptCommand_EndScriptLoop1 + ret +; f559 -HostNPCScript: ; f352 (3:7352) - INCROM $f352, $f580 +; Loads the NPC to fight at the challenge hall +Preload_ChallengeHallOpponent: ; f559 (3:7559) + get_flag_value EVENT_FLAG_42 + or a + ret z + get_flag_value EVENT_FLAG_46 + or a + jr z, .asm_f56e + ld a, [wd696] + ld [wTempNPC], a + scf + ret +.asm_f56e + call Func_f5db + ld c, $01 + set_flag_value EVENT_FLAG_45 + call Func_f580 + max_flag_value EVENT_FLAG_46 + scf + ret Func_f580: ; f580 (3:7580) - call Func_ca69 - ld b, h + get_flag_value EVENT_FLAG_44 cp $3 jr z, .asm_f596 - call Func_ca69 - ld b, l + get_flag_value EVENT_FLAG_45 cp $3 ld d, $18 jr nz, .asm_f598 @@ -3467,24 +6463,118 @@ Func_f580: ; f580 (3:7580) ld a, [hl] .asm_f5ac - ld [wd3ab], a + ld [wTempNPC], a ld [wd696], a ret ; 0xf5b3 - INCROM $f5b3, $f71f + INCROM $f5b3, $f5db + +Func_f5db: ; f5db (3:75db) + xor a + ld [$d698], a + ld [$d699], a + ld [$d69a], a + ld [$d69b], a + ret +; 0xf5e9 + + INCROM $f5e9, $f602 + +Func_f602: ; f602 (3:7602) + INCROM $f602, $f631 -CourtneyNPCScript: ; f71f (3:771f) +Script_f631: ; f631 (3:7631) + start_script + run_command ScriptCommand_PrintTextString + tx Text0508 + run_command ScriptCommand_CloseAdvancedTextBox + run_command ScriptCommand_SetNextNPCandScript + db $02 + dw $763c + run_command ScriptCommand_EndScriptLoop1 + + ret +; 0xf63c + + INCROM $f63c, $f71f + +Script_Courtney: ; f71f (3:771f) INCROM $f71f, $f72a -SteveNPCScript: ; f72a (3:772a) +Script_Steve: ; f72a (3:772a) INCROM $f72a, $f735 -JackNPCScript: ; f735 (3:7735) +Script_Jack: ; f735 (3:7735) INCROM $f735, $f740 -RodNPCScript: ; f740 (3:7740) - INCROM $f740, $fc2b +Script_Rod: ; f740 (3:7740) + INCROM $f740, $fbdb + +HallOfHonorLoadMap: ; fbdb (3:7bdb) + ld a, SFX_10 + call PlaySFX + ret +; 0xfbe1 + + INCROM $fbe1, $fbf1 + +Script_fbf1: ; fbf1 (3:7bf1) + start_script + run_command ScriptCommand_JumpIfFlagNonzero2 + db EVENT_RECEIVED_LEGENDARY_CARD + dw .ows_fc10 + run_command ScriptCommand_MaxOutFlagValue + db EVENT_RECEIVED_LEGENDARY_CARD + run_command Func_ccdc + tx Text05b8 + run_command ScriptCommand_GiveCard + db ZAPDOS3 + run_command ScriptCommand_GiveCard + db MOLTRES2 + run_command ScriptCommand_GiveCard + db ARTICUNO2 + run_command ScriptCommand_GiveCard + db DRAGONITE1 + run_command ScriptCommand_ShowCardReceivedScreen + db $ff +.ows_fc05 + run_command Func_d38f + db $00 + run_command Func_ccdc + tx Text05b9 +.ows_fc0a + run_command Func_d38f + db $01 + run_command Func_d396 + db $01 + run_command Func_d3b9 + run_command ScriptCommand_QuitScriptFully + +.ows_fc10 + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_71 + db $0f + dw .ows_fc20 + run_command Func_d209 + run_command Func_ccdc + tx Text05ba + run_command ScriptCommand_GiveCard + db $00 + run_command ScriptCommand_ShowCardReceivedScreen + db $00 + run_command ScriptCommand_Jump + dw .ows_fc05 + +.ows_fc20 + run_command Func_ccdc + tx Text05bb + run_command Func_d38f + db $00 + run_command Func_ccdc + tx Text05bc + run_command ScriptCommand_Jump + dw .ows_fc0a Func_fc2b: ; fc2b (3:7c2b) ld a, [wDuelResult] @@ -3501,17 +6591,29 @@ Func_fc2b: ; fc2b (3:7c2b) inc hl ld b, [hl] ld a, $b0 - ld [wd0c8], a + ld [wCurrentNPCNameTx], a ld a, $3 - ld [wd0c9], a - jp Func_c935 + ld [wCurrentNPCNameTx+1], a + jp SetNextScript PointerTable_fc4c: ; fc4c (3:7c4c) dw Unknown_fc64 dw Unknown_fc68 dw Unknown_fc60 - INCROM $fc52, $fc60 +Script_fc52: ; fc52 (3:7c52) + start_script + run_command ScriptCommand_PrintTextString + tx Text06c8 + run_command ScriptCommand_AskQuestionJumpDefaultYes + dw $0000 + dw .ows_fc5e + run_command ScriptCommand_PrintTextQuitFully + tx Text06c9 + +.ows_fc5e + run_command Func_cd76 + run_command ScriptCommand_QuitScriptFully Unknown_fc60: ; fc60 (3:7c60) INCROM $fc60, $fc64 @@ -3520,7 +6622,120 @@ Unknown_fc64: ; fc64 (3:7c64) INCROM $fc64, $fc68 Unknown_fc68: ; fc68 (3:7c68) - INCROM $fc68, $fcad + INCROM $fc68, $fc6c + +; Clerk looks away from you if you can't use infrared +; This is one of the preloads that does not change whether or not they appear +Preload_GiftCenterClerk: ; fc6c (3:7c6c) + ld a, [wConsole] + cp CONSOLE_CGB + jr z, .notCGB + ld a, NORTH + ld [wLoadNPCDirection], a +.notCGB + scf + ret + +Func_fc7a: ; fc7a (3:7c7a) + ld a, [wConsole] + ld c, a + set_flag_value EVENT_FLAG_74 + + start_script + run_command ScriptCommand_JumpIfFlagNotEqual + db EVENT_FLAG_74 + db $02 + dw Func_fcad.ows_fcd5 + run_command ScriptCommand_PrintTextString + tx Text06cd + run_command Func_d39d + db $00 + run_command ScriptCommand_JumpIfFlagNotLessThan + db EVENT_FLAG_72 + db $04 + dw Func_fc7a.ows_fcaa + run_command ScriptCommand_PrintTextString + tx Text06ce + run_command ScriptCommand_AskQuestionJumpDefaultYes + tx Text06cf + dw .ows_fca0 + run_command ScriptCommand_PrintTextString + tx Text06d0 + run_command ScriptCommand_Jump + dw Func_fc7a.ows_fcaa + +.ows_fca0 + run_command Func_d396 + db $00 + run_command ScriptCommand_PlaySFX + db $56 + run_command Func_ccdc + tx Text06d1 + run_command Func_d39d + db $01 + run_command ScriptCommand_QuitScriptFully + +.ows_fcaa + run_command ScriptCommand_PrintTextQuitFully + tx Text06d2 Func_fcad: ; fcad (3:7cad) - INCROM $fcad, $10000 + ld a, [wd10e] + ld c, a + set_flag_value EVENT_FLAG_72 + + start_script + run_command ScriptCommand_PlaySFX + db $56 + run_command Func_d396 + db $00 + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_72 + db $00 + dw .ows_fccc + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_72 + db $02 + dw .ows_fccf + run_command ScriptCommand_JumpIfFlagEqual + db EVENT_FLAG_72 + db $03 + dw .ows_fcd2 + run_command ScriptCommand_Jump + dw Func_fc7a.ows_fcaa + +.ows_fccc + run_command ScriptCommand_PrintTextQuitFully + tx Text06d3 + +.ows_fccf + run_command ScriptCommand_PrintTextQuitFully + tx Text06d4 + +.ows_fcd2 + run_command ScriptCommand_PrintTextQuitFully + tx Text06d5 + +.ows_fcd5 + run_command ScriptCommand_MoveArbitraryNPC + db NPC_GIFT_CENTER_CLERK + dw NPCMovement_fce1 + run_command ScriptCommand_PrintTextString + tx Text06d6 + run_command ScriptCommand_MoveArbitraryNPC + db NPC_GIFT_CENTER_CLERK + dw NPCMovement_fce3 + run_command ScriptCommand_QuitScriptFully + +NPCMovement_fce1: ; fce1 (3:7ce1) + db SOUTH | NO_MOVE + db $ff + +NPCMovement_fce3: ; fce3 (3:7ce3) + db NORTH | NO_MOVE + db $ff +; fce5 + +rept $31b + db $ff +endr diff --git a/src/engine/bank04.asm b/src/engine/bank04.asm index c50c8f1..26181ee 100644 --- a/src/engine/bank04.asm +++ b/src/engine/bank04.asm @@ -92,7 +92,7 @@ Medal_1029e: ; 1029e (4:429e) jr nz, .asm_102e2 ldtx hl, WonTheMedalText call PrintScrollableText_NoTextBoxLabel - call Func_3c96 + call WaitForSongToFinish call ResumeSong pop af ld [wd291], a @@ -149,7 +149,7 @@ BoosterPack_1031b: ; 1031b (4:431b) ldtx hl, AndAnotherBoosterPackText .asm_10373 call PrintScrollableText_NoTextBoxLabel - call Func_3c96 + call WaitForSongToFinish call ResumeSong ldtx hl, CheckedCardsInBoosterPackText call PrintScrollableText_NoTextBoxLabel @@ -224,7 +224,7 @@ Duel_Init: ; 103d3 (4:43d3) lb de, 18, 17 ; x, y call SetCursorParametersForTextBox call WaitForButtonAorB - call Func_3c96 + call WaitForSongToFinish call Func_10ab4 ; fade out pop af ld [wd291], a @@ -239,38 +239,39 @@ Func_10548: ; 10548 (4:4548) Func_10756: ; 10756 (4:4756) INCROM $10756, $10a70 -Func_10a70: ; 10a70 (4:4a70) +; gives the pc pack described in a +TryGivePCPack: ; 10a70 (4:4a70) push hl push bc push de ld b, a - ld c, $f + ld c, $f ; number of packs possible ld hl, wPCPacks -.asm_10a79 +.searchLoop1 ld a, [hli] and $7f cp b - jr z, .asm_10a97 + jr z, .quit dec c - jr nz, .asm_10a79 + jr nz, .searchLoop1 ld c, $f ld hl, wPCPacks -.asm_10a87 +.findFreeSlotLoop ld a, [hl] and $7f - jr z, .asm_10a93 + jr z, .foundFreeSlot inc hl dec c - jr nz, .asm_10a87 + jr nz, .findFreeSlotLoop debug_ret - jr .asm_10a97 + jr .quit -.asm_10a93 +.foundFreeSlot ld a, b - or $80 + or $80 ; mark pack as unopened ld [hl], a -.asm_10a97 +.quit pop de pop bc pop hl @@ -332,7 +333,7 @@ Func_10dba: ; 10dba (4:4dba) push af ld hl, $4df0 call JumpToFunctionInTable - farcall Func_c135 + farcall CloseTextBox call DoFrameIfLCDEnabled pop af ret @@ -344,7 +345,7 @@ Func_10e28: ; 10e28 (4:4e28) INCROM $10e28, $10e55 Func_10e55: ; 10e55 (4:4e55) - ld a, [wd336] + ld a, [wPlayerSpriteIndex] ld [wWhichSprite], a ld a, [wd33e] or a @@ -364,8 +365,8 @@ Func_10e71: ; 10e71 (4:4e71) ldh a, [hKeysPressed] and D_PAD jr z, .asm_10e83 - farcall Func_c5d5 - ld [wd334], a + farcall GetDirectionFromDPad + ld [wPlayerDirection], a call Func_10e97 jr .asm_10e96 .asm_10e83 @@ -387,7 +388,7 @@ Func_10e97: ; 10e97 (4:4e97) rlca rlca ld c, a - ld a, [wd334] + ld a, [wPlayerDirection] add c ld c, a ld b, $0 @@ -457,7 +458,7 @@ Func_10f4a: ; 10f4a (4:4f4a) jr nz, .asm_10f5f ld c, a ld a, $1e - farcall CheckIfEventFlagSet + farcall GetEventFlagValue or a ld a, c jr nz, .asm_10f5f @@ -477,13 +478,13 @@ LoadOverworldMapSelection: ; 10f61 (4:4f61) ld hl, OverworldMapIndexes add hl, bc ld a, [hli] - ld [wd0bb], a + ld [wTempMap], a ld a, [hli] - ld [wd0bc], a + ld [wTempPlayerXCoord], a ld a, [hli] - ld [wd0bd], a + ld [wTempPlayerYCoord], a ld a, $0 - ld [wd0be], a + ld [wTempPlayerDirection], a ld hl, wd0b4 set 4, [hl] pop bc @@ -494,7 +495,7 @@ INCLUDE "data/overworld_indexes.asm" Func_10fbc: ; 10fbc (4:4fbc) ld a, $25 - farcall Func_1299f + farcall CreateSpriteAndAnimBufferEntry ld c, SPRITE_ANIM_COORD_X call GetSpriteAnimBufferProperty ld a, $80 @@ -517,7 +518,7 @@ Func_10fde: ; 10fde (4:4fde) xor a ld [wd33e], a ld a, $25 - call Func_1299f + call CreateSpriteAndAnimBufferEntry ld a, [wWhichSprite] ld [wd33b], a ld b, $35 @@ -530,7 +531,7 @@ Func_10fde: ; 10fde (4:4fde) ld [wd33c], a call Func_12ab5 ld a, $3e - farcall CheckIfEventFlagSet + farcall GetEventFlagValue or a jr nz, .asm_11015 ld c, SPRITE_ANIM_FIELD_0F @@ -550,7 +551,7 @@ Func_11016: ; 11016 (4:5016) Func_11024: ; 11024 (4:5024) ld a, SFX_57 call PlaySFX - ld a, [wd336] + ld a, [wPlayerSpriteIndex] ld [wWhichSprite], a ld c, SPRITE_ANIM_FIELD_0F call GetSpriteAnimBufferProperty @@ -582,7 +583,7 @@ Func_11024: ; 11024 (4:5024) ret Func_11060: ; 11060 (4:5060) - ld a, [wd336] + ld a, [wPlayerSpriteIndex] ld [wWhichSprite], a ld a, [wd341] or a @@ -672,7 +673,7 @@ Func_110a6: ; 110a6 (4:50a6) xor a ld [wd347], a ld [wd348], a - farcall Func_c5e9 + farcall UpdatePlayerSprite pop hl ret @@ -710,7 +711,7 @@ Func_11102: ; 11102 (4:5102) jr z, .asm_1113a ld a, $3 .asm_1113a - ld [wd334], a + ld [wPlayerDirection], a ret Func_1113e: ; 1113e (4:513e) @@ -746,7 +747,7 @@ Func_1113e: ; 1113e (4:513e) jr z, .asm_11175 ld a, $0 .asm_11175 - ld [wd334], a + ld [wPlayerDirection], a ret Func_11179: ; 11179 (4:5179) @@ -818,13 +819,13 @@ Func_1157c: ; 1157c (4:557c) .asm_11586 ld a, $2 - ld [wd0bc], a + ld [wTempPlayerXCoord], a ld a, $4 - ld [wd0bd], a + ld [wTempPlayerYCoord], a ld a, $2 - ld [wd0be], a + ld [wTempPlayerDirection], a ld a, $1 - ld [wd0bb], a + ld [wTempMap], a ld a, $1 ld [wd32e], a @@ -852,12 +853,12 @@ GetNPCHeaderPointer: ; 1184a (4:584a) ld l, a ret -Func_11857: ; 11857 (4:5857) +LoadNPCSpriteData: ; 11857 (4:5857) push hl push bc call GetNPCHeaderPointer ld a, [hli] - ld [wd3ab], a + ld [wTempNPC], a ld a, [hli] ld [wd3b3], a ld a, [hli] @@ -868,7 +869,7 @@ Func_11857: ; 11857 (4:5857) ld [wd3b2], a pop bc ld a, [wConsole] - cp $2 + cp CONSOLE_CGB jr nz, .asm_1187a ld a, b ld [wd3b1], a @@ -877,33 +878,34 @@ Func_11857: ; 11857 (4:5857) pop hl ret -; this appears to find data about the NPC we're talking to -Func_1187d: ; 1187d (4:587d) +; Loads Name into wCurrentNPCNameTx and gets Script ptr into bc +GetNPCNameAndScript: ; 1187d (4:587d) push hl call GetNPCHeaderPointer - ld bc, $5 + ld bc, NPC_DATA_SCRIPT_PTR add hl, bc ld c, [hl] inc hl ld b, [hl] inc hl ld a, [hli] - ld [wd0c8], a + ld [wCurrentNPCNameTx], a ld a, [hli] - ld [wd0c9], a + ld [wCurrentNPCNameTx+1], a pop hl ret -Func_11893: ; 11893 (4:5893) +; Sets Dialog Box title to the name of the npc in 'a' +SetNPCDialogName: ; 11893 (4:5893) push hl push bc call GetNPCHeaderPointer - ld bc, $0007 + ld bc, NPC_DATA_NAME_TEXT add hl, bc ld a, [hli] - ld [wd0c8], a + ld [wCurrentNPCNameTx], a ld a, [hli] - ld [wd0c9], a + ld [wCurrentNPCNameTx+1], a pop bc pop hl ret @@ -967,23 +969,23 @@ Func_11f4e: ; 11f4e (4:5f4e) INCROM $11f4e, $1217b OverworldScriptTable: ; 1217b (4:617b) - dw OWScript_EndScriptLoop1 - dw OWScript_CloseTextBox - dw OWScript_PrintTextString + dw ScriptCommand_EndScriptLoop1 + dw ScriptCommand_CloseAdvancedTextBox + dw ScriptCommand_PrintTextString dw Func_ccdc - dw OWScript_AskQuestionJump - dw OWScript_StartBattle - dw Func_cd83 + dw ScriptCommand_AskQuestionJump + dw ScriptCommand_StartBattle + dw ScriptCommand_PrintVariableText dw Func_cda8 - dw OWScript_PrintTextCloseBox + dw ScriptCommand_PrintTextQuitFully dw Func_cdcb - dw Func_ce26 - dw Func_ce84 - dw OWScript_GiveBoosterPacks + dw ScriptCommand_MoveActiveNPCByDirection + dw ScriptCommand_CloseTextBox + dw ScriptCommand_GiveBoosterPacks dw Func_cf0c dw Func_cf12 - dw Func_cf3f - dw Func_cf4c + dw ScriptCommand_GiveCard + dw ScriptCommand_TakeCard dw Func_cf53 dw Func_cf7b dw Func_cf2d @@ -994,83 +996,83 @@ OverworldScriptTable: ; 1217b (4:617b) dw Func_d025 dw Func_d032 dw Func_d03f - dw OWScript_ScriptJump - dw Func_d04f - dw Func_d055 - dw OWScript_MovePlayer - dw Func_cee2 - dw Func_d080 - dw Func_d088 + dw ScriptCommand_Jump + dw ScriptCommand_TryGiveMedalPCPacks + dw ScriptCommand_SetPlayerDirection + dw ScriptCommand_MovePlayer + dw ScriptCommand_ShowCardReceivedScreen + dw ScriptCommand_SetDialogName + dw ScriptCommand_SetNextNPCandScript dw Func_d095 dw Func_d0be - dw Func_d0ce + dw ScriptCommand_DoFrames dw Func_d0d9 - dw Func_d0f2 - dw Func_ce4a - dw Func_ceba + dw ScriptCommand_JumpIfPlayerCoordMatches + dw ScriptCommand_MoveActiveNPC + dw ScriptCommand_GiveOneOfEachTrainerBooster dw Func_d103 dw Func_d125 dw Func_d135 dw Func_d16b dw Func_cd4f dw Func_cd94 - dw Func_ce52 + dw ScriptCommand_MoveWramNPC dw Func_cdd8 dw Func_cdf5 dw Func_d195 dw Func_d1ad dw Func_d1b3 - dw OWScript_EndScriptCloseText + dw ScriptCommand_QuitScriptFully dw Func_d244 dw Func_d24c - dw OWScript_OpenDeckMachine + dw ScriptCommand_OpenDeckMachine dw Func_d271 - dw Func_d36d - dw Func_ce6f + dw ScriptCommand_EnterMap + dw ScriptCommand_MoveArbitraryNPC dw Func_d209 dw Func_d38f dw Func_d396 dw Func_cd76 dw Func_d39d dw Func_d3b9 - dw Func_d3c9 - dw Func_d3d1 + dw ScriptCommand_TryGivePCPack + dw ScriptCommand_nop dw Func_d3d4 dw Func_d3e0 dw Func_d3fe dw Func_d408 dw Func_d40f - dw Func_d416 - dw Func_d423 - dw Func_d429 + dw ScriptCommand_PlaySFX + dw ScriptCommand_PauseSong + dw ScriptCommand_ResumeSong dw Func_d41d - dw Func_d42f + dw ScriptCommand_WaitForSongToFinish dw Func_d435 - dw Func_cce4 + dw ScriptCommand_AskQuestionJumpDefaultYes dw Func_d2f6 dw Func_d317 dw Func_d43d - dw OWScript_EndScriptLoop2 - dw OWScript_EndScriptLoop3 - dw OWScript_EndScriptLoop4 - dw OWScript_EndScriptLoop5 - dw OWScript_EndScriptLoop6 - dw OWScript_CustomModifyEventFlags - dw Func_d460 - dw OWScript_JumpIfFlagSet - dw Func_d484 - dw Func_d49e - dw Func_d4a6 - dw Func_d4ae - dw OWScript_SetEventFlags - dw Func_d4c3 - dw Func_d4ca - dw OWScript_JumpIfFlagNotSet - dw Func_d452 - dw OWScript_EndScriptLoop7 - dw OWScript_EndScriptLoop8 - dw OWScript_EndScriptLoop9 - dw OWScript_EndScriptLoop10 + dw ScriptCommand_EndScriptLoop2 + dw ScriptCommand_EndScriptLoop3 + dw ScriptCommand_EndScriptLoop4 + dw ScriptCommand_EndScriptLoop5 + dw ScriptCommand_EndScriptLoop6 + dw ScriptCommand_SetFlagValue + dw ScriptCommand_JumpIfFlagZero1 + dw ScriptCommand_JumpIfFlagNonzero1 + dw ScriptCommand_JumpIfFlagEqual + dw ScriptCommand_JumpIfFlagNotEqual + dw ScriptCommand_JumpIfFlagNotLessThan + dw ScriptCommand_JumpIfFlagLessThan + dw ScriptCommand_MaxOutFlagValue + dw ScriptCommand_ZeroOutFlagValue + dw ScriptCommand_JumpIfFlagNonzero2 + dw ScriptCommand_JumpIfFlagZero2 + dw ScriptCommand_IncrementFlagValue + dw ScriptCommand_EndScriptLoop7 + dw ScriptCommand_EndScriptLoop8 + dw ScriptCommand_EndScriptLoop9 + dw ScriptCommand_EndScriptLoop10 INCROM $1224b, $1229f @@ -1229,14 +1231,15 @@ Unknown_128fb: ; 128fb Func_1296e: ; 1296e (4:696e) INCROM $1296e, $1299f -Func_1299f: ; 1299f (4:699f) +; creates a new entry in SpriteAnimBuffer, Alse loads the sprite if need be +CreateSpriteAndAnimBufferEntry: ; 1299f (4:699f) push af ld a, [wd5d7] or a - jr z, .asm_129a8 + jr z, .continue pop af ret -.asm_129a8 +.continue pop af push bc push hl @@ -1244,50 +1247,50 @@ Func_1299f: ; 1299f (4:699f) ld [wd5d3], a xor a ld [wWhichSprite], a - call Func_3db7 - ld bc, $0010 -.asm_129bb + call GetFirstSpriteAnimBufferProperty + ld bc, SPRITE_ANIM_LENGTH +.findFirstEmptyAnimField ld a, [hl] or a - jr z, .asm_129cf + jr z, .foundEmptyAnimField add hl, bc ld a, [wWhichSprite] inc a ld [wWhichSprite], a cp $10 - jr nz, .asm_129bb + jr nz, .findFirstEmptyAnimField debug_ret scf - jr .asm_129d6 -.asm_129cf + jr .quit +.foundEmptyAnimField ld a, $1 ld [hl], a - call Func_129d9 + call FillNewSpriteAnimBufferEntry or a -.asm_129d6 +.quit pop hl pop bc ret -Func_129d9: ; 129d9 (4:69d9) +FillNewSpriteAnimBufferEntry: ; 129d9 (4:69d9) push hl push bc push hl inc hl - ld c, $f + ld c, SPRITE_ANIM_LENGTH - 1 xor a -.asm_129e0 +.clearSpriteAnimBufferEntryLoop ld [hli], a dec c - jr nz, .asm_129e0 + jr nz, .clearSpriteAnimBufferEntryLoop pop hl - ld bc, $0004 + ld bc, SPRITE_ANIM_FIELD_05 - 1 add hl, bc ld a, [wd5d3] ld [hli], a ld a, $ff ld [hl], a - ld bc, $0009 + ld bc, SPRITE_ANIM_MOVEMENT_COUNTER - SPRITE_ANIM_FIELD_05 add hl, bc ld a, $ff ld [hl], a @@ -1322,7 +1325,7 @@ Func_12ab5: ; 12ab5 (4:6ab5) Func_12ae2: ; 12ae2 (4:6ae2) push bc push af - call Func_3db7 + call GetFirstSpriteAnimBufferProperty pop af push hl ld bc, $0005 @@ -1330,15 +1333,15 @@ Func_12ae2: ; 12ae2 (4:6ae2) ld [hli], a push hl ld l, $6 - farcall Func_8020f + farcall GetMapDataPointer farcall Func_80229 pop hl - ld a, [wd4c6] + ld a, [wTempPointerBank] ld [hli], a - ld a, [wd4c4] + ld a, [wTempPointer] ld [hli], a ld c, a - ld a, [wd4c5] + ld a, [wTempPointer + 1] ld [hli], a ld b, a ld a, $3 @@ -1360,20 +1363,20 @@ Func_12b13: ; 12b13 (4:6b13) ld bc, $0006 add hl, bc ld a, [hli] - ld [wd4c6], a + ld [wTempPointerBank], a inc hl inc hl ld a, [hl] - ld [wd4c4], a + ld [wTempPointer], a add $4 ld [hli], a ld a, [hl] - ld [wd4c5], a + ld [wTempPointer + 1], a adc $0 ld [hl], a ld de, wd23e ld bc, $0004 - call Func_3bf5 + call CopyBankedDataToDE pop hl ld de, wd23e ld a, [de] @@ -1421,11 +1424,11 @@ Func_12b6a: ; 12b6a (4:6b6a) ld bc, $0006 add hl, bc ld a, [hli] - ld [wd4c6], a + ld [wTempPointerBank], a ld a, [hli] - ld [wd4c4], a + ld [wTempPointer], a ld a, [hli] - ld [wd4c5], a + ld [wTempPointer + 1], a pop hl call Func_3d72 pop de @@ -1465,6 +1468,8 @@ Func_12ba7: ; 12ba7 (4:6ba7) Func_12bcd: ; 12bcd (4:6bcd) INCROM $12bcd, $12c05 +; gets some value based on the sprite in b and wd5d8 +; loads the sprites data if it doesn't already exist Func_12c05: ; 12c05 (4:6c05) push hl push bc @@ -1475,23 +1480,24 @@ Func_12c05: ; 12c05 (4:6c05) ld c, a ld hl, wd5d8 or a - jr z, .asm_12c22 -.asm_12c15 + jr z, .tryToAddSprite + +.findSpriteMatchLoop inc hl ld a, [hl] cp b - jr z, .asm_12c3a + jr z, .foundSpriteMatch inc hl ld a, [hli] add [hl] ld d, a inc hl dec c - jr nz, .asm_12c15 -.asm_12c22 + jr nz, .findSpriteMatchLoop +.tryToAddSprite ld a, [wd618] cp $10 - jr nc, .asm_12c48 + jr nc, .quitFail inc a ld [wd618], a inc hl @@ -1505,7 +1511,7 @@ Func_12c05: ; 12c05 (4:6c05) pop af ld [hl], a pop hl -.asm_12c3a +.foundSpriteMatch dec hl inc [hl] inc hl @@ -1513,15 +1519,15 @@ Func_12c05: ; 12c05 (4:6c05) ld a, [hli] add [hl] cp $81 - jr nc, .asm_12c48 + jr nc, .quitFail ld a, d or a - jr .asm_12c4b -.asm_12c48 + jr .quitSucceed +.quitFail debug_ret xor a scf -.asm_12c4b +.quitSucceed pop de pop bc pop hl @@ -1555,7 +1561,7 @@ Func_1344d: ; 1344d (4:744d) call PlaySong ldtx hl, DefeatedFiveOpponentsText call PrintScrollableText_NoTextBoxLabel - call Func_3c96 + call WaitForSongToFinish call ResumeSong ret ; 0x13462 @@ -1577,9 +1583,16 @@ Func_13485: ; 13485 (4:7485) call PlaySong ldtx hl, ConsecutiveWinRecordIncreasedText call PrintScrollableText_NoTextBoxLabel - call Func_3c96 + call WaitForSongToFinish call ResumeSong ret ; 0x134b1 - INCROM $134b1, $14000 + INCROM $134b1, $1372f + +INCLUDE "data/npc_map_data.asm" +INCLUDE "data/map_objects.asm" + +rept $119 + db $ff +endr diff --git a/src/engine/bank05.asm b/src/engine/bank05.asm index ee45de4..762d5c8 100644 --- a/src/engine/bank05.asm +++ b/src/engine/bank05.asm @@ -1,89 +1,52 @@ -PointerTable_14000: ; 14000 (05:4000) - dw $47bd ; SAMS_PRACTICE_DECK - dw PointerTable_14668 ; PRACTICE_PLAYER_DECK - dw PointerTable_14668 ; SAMS_NORMAL_DECK - dw PointerTable_14668 ; CHARMANDER_AND_FRIENDS_DECK - dw PointerTable_14668 ; CHARMANDER_EXTRA_DECK - dw PointerTable_14668 ; SQUIRTLE_AND_FRIENDS_DECK - dw PointerTable_14668 ; SQUIRTLE_EXTRA_DECK - dw PointerTable_14668 ; BULBASAUR_AND_FRIENDS_DECK - dw PointerTable_14668 ; BULBASAUR_EXTRA_DECK - dw PointerTable_14668 ; LIGHTNING_AND_FIRE_DECK - dw PointerTable_14668 ; WATER_AND_FIGHTING_DECK - dw PointerTable_14668 ; GRASS_AND_PSYCHIC_DECK - dw $49e8 ; LEGENDARY_MOLTRES_DECK - dw $4b0f ; LEGENDARY_ZAPDOS_DECK - dw $4c0b ; LEGENDARY_ARTICUNO_DECK - dw $4d60 ; LEGENDARY_DRAGONITE_DECK - dw $4e89 ; FIRST_STRIKE_DECK - dw $4f0e ; ROCK_CRUSHER_DECK - dw $4f8f ; GO_GO_RAIN_DANCE_DECK - dw $5019 ; ZAPPING_SELFDESTRUCT_DECK - dw $509b ; FLOWER_POWER_DECK - dw $5122 ; STRANGE_PSYSHOCK_DECK - dw $51ad ; WONDERS_OF_SCIENCE_DECK - dw $5232 ; FIRE_CHARGE_DECK - dw $52bd ; IM_RONALD_DECK - dw $534b ; POWERFUL_RONALD_DECK - dw $53e8 ; INVINCIBLE_RONALD_DECK - dw $546f ; LEGENDARY_RONALD_DECK - dw $48dc ; MUSCLES_FOR_BRAINS_DECK - dw PointerTable_14668 ; HEATED_BATTLE_DECK - dw PointerTable_14668 ; LOVE_TO_BATTLE_DECK - dw PointerTable_14668 ; EXCAVATION_DECK - dw PointerTable_14668 ; BLISTERING_POKEMON_DECK - dw PointerTable_14668 ; HARD_POKEMON_DECK - dw PointerTable_14668 ; WATERFRONT_POKEMON_DECK - dw PointerTable_14668 ; LONELY_FRIENDS_DECK - dw PointerTable_14668 ; SOUND_OF_THE_WAVES_DECK - dw PointerTable_14668 ; PIKACHU_DECK - dw PointerTable_14668 ; BOOM_BOOM_SELFDESTRUCT_DECK - dw PointerTable_14668 ; POWER_GENERATOR_DECK - dw PointerTable_14668 ; ETCETERA_DECK - dw PointerTable_14668 ; FLOWER_GARDEN_DECK - dw PointerTable_14668 ; KALEIDOSCOPE_DECK - dw PointerTable_14668 ; GHOST_DECK - dw PointerTable_14668 ; NAP_TIME_DECK - dw PointerTable_14668 ; STRANGE_POWER_DECK - dw PointerTable_14668 ; FLYIN_POKEMON_DECK - dw PointerTable_14668 ; LOVELY_NIDORAN_DECK - dw PointerTable_14668 ; POISON_DECK - dw PointerTable_14668 ; ANGER_DECK - dw PointerTable_14668 ; FLAMETHROWER_DECK - dw PointerTable_14668 ; RESHUFFLE_DECK - dw $48dc ; IMAKUNI_DECK -; 1406a - -PointerTable_1406a: ; 1406a (5:406a) +INCLUDE "data/deck_ai_pointers.asm" + +AIActionTable_Unreferenced: ; 1406a (5:406a) dw $406c - dw Func_14078 - dw Func_14078 - dw Func_1409e - dw $40a2 - dw $40a6 - dw $40aa - -Func_14078: ; 14078 (5:4078) + dw .do_turn + dw .do_turn + dw .star_duel + dw .forced_switch + dw .ko_switch + dw .take_prize + +.do_turn ; 14078 (5:4078) call AIDecidePlayPokemonCard call AIDecideWhetherToRetreat - jr nc, .asm_14091 + jr nc, .try_attack call AIDecideBenchPokemonToSwitchTo - call AIChooseEnergyToDiscardForRetreatCost + call AITryToRetreat call AIDecideWhetherToRetreat - jr nc, .asm_14091 + jr nc, .try_attack call AIDecideBenchPokemonToSwitchTo - call AIChooseEnergyToDiscardForRetreatCost -.asm_14091 - call AIDecidePlayEnergyCardFromHand - call Func_169f8 + call AITryToRetreat +.try_attack + call AIProcessAndTryToPlayEnergy + call AIProcessAndTryToUseAttack ret c ld a, OPPACTION_FINISH_NO_ATTACK bank1call AIMakeDecision ret ; 0x1409e -Func_1409e: ; 1409e (5:409e) - INCROM $1409e, $140ae +.star_duel ; 1409e (5:409e) + call AIPlayInitialBasicCards + ret +; 0x140a2 + +.forced_switch ; 140a2 (5:40a2) + call AIDecideBenchPokemonToSwitchTo + ret +; 0x140a6 + +.ko_switch ; 140a6 (5:40a6) + call AIDecideBenchPokemonToSwitchTo + ret +; 0x140aa + +.take_prize ; 140aa (5:40aa) + call AIPickPrizeCards + ret +; 0x140ae ; returns carry if damage dealt from any of ; a card's moves KOs defending Pokémon @@ -137,7 +100,7 @@ CheckIfAnyDefendingPokemonAttackDealsSameDamageAsHP: ; 140c5 (5:40c5) ; checks AI scores for all benched Pokémon ; returns the location of the card with highest score -; in hTempPlayAreaLocation_ff9d +; in a and [hTempPlayAreaLocation_ff9d] FindHighestBenchScore: ; 140df (5:40df) ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA call GetTurnDuelistVariable @@ -220,8 +183,44 @@ LoadDefendingPokemonColorWRAndPrizeCards: ; 1411d (5:411d) ret ; 0x14145 -Func_14145: ; 14145 (5:4145) - INCROM $14145, $14184 +; called when AI has chosen its attack. +; executes all effects and damage. +; handles AI choosing parameters for certain attacks as well. +AITryUseAttack: ; 14145 (5:4145) + ld a, [wSelectedAttack] + ldh [hTemp_ffa0], a + ld e, a + ld a, DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + ldh [hTempCardIndex_ff9f], a + ld d, a + call CopyMoveDataAndDamage_FromDeckIndex + ld a, OPPACTION_BEGIN_ATTACK + bank1call AIMakeDecision + ret c + + call AISelectSpecialAttackParameters + jr c, .use_attack + ld a, OPPACTION_BEGIN_ATTACK + call TryExecuteEffectCommandFunction + +.use_attack + ld a, [wSelectedAttack] + ld e, a + ld a, DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + ld d, a + call CopyMoveDataAndDamage_FromDeckIndex + ld a, OPPACTION_USE_ATTACK + bank1call AIMakeDecision + ret c + + ld a, OPPACTION_ATTACK_ANIM_AND_DAMAGE + call TryExecuteEffectCommandFunction + ld a, OPPACTION_ATTACK_ANIM_AND_DAMAGE + bank1call AIMakeDecision + ret +; 0x14184 ; return carry if any of the following is satisfied: ; - deck index in a corresponds to a double colorless energy card; @@ -296,25 +295,100 @@ CheckIfEnergyIsUseful: ; 14184 (5:4184) ret ; 0x141da -Func_141da: ; 141da (5:41da) - INCROM $141da, $14226 +; pick a random Pokemon in the bench. +; output: +; - a = PLAY_AREA_* of Bench Pokemon picked. +PickRandomBenchPokemon: ; 141da (5:41da) + ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA + call GetTurnDuelistVariable + dec a + call Random + inc a + ret +; 0x141e5 -Func_14226: ; 14226 (5:4226) +AIPickPrizeCards: ; 141e5 (5:41e5) + ld a, [wNumberPrizeCardsToTake] + ld b, a +.loop + call .PickPrizeCard + ld a, DUELVARS_PRIZES + call GetTurnDuelistVariable + or a + jr z, .done + dec b + jr nz, .loop +.done + ret +; 0x141f8 + +; picks a prize card at random +; and adds it to the hand. +.PickPrizeCard: ; 141f8 (5:41f8) + ld a, DUELVARS_PRIZES + call GetTurnDuelistVariable + push hl + ld c, a + +; choose a random prize card until +; one is found that isn't taken already. +.loop_pick_prize + ld a, 6 + call Random + ld e, a + ld d, $00 + ld hl, .prize_flags + add hl, de + ld a, [hl] + and c + jr z, .loop_pick_prize ; no prize + +; prize card was found +; remove this prize from wOpponentPrizes + ld a, [hl] + pop hl + cpl + and [hl] + ld [hl], a + +; add this prize card to the hand + ld a, e + add DUELVARS_PRIZE_CARDS + call GetTurnDuelistVariable + call AddCardToHand + ret + +.prize_flags ; 1421e (5:421e) + db $1 << 0 + db $1 << 1 + db $1 << 2 + db $1 << 3 + db $1 << 4 + db $1 << 5 + db $1 << 6 + db $1 << 7 +; 0x14226 + +; routine for AI to play all Basic cards from its hand +; in the beginning of the Duel. +AIPlayInitialBasicCards: ; 14226 (5:4226) call CreateHandCardList ld hl, wDuelTempList .check_for_next_card ld a, [hli] ldh [hTempCardIndex_ff98], a cp $ff - ret z + ret z ; return when done call LoadCardDataToBuffer1_FromDeckIndex ld a, [wLoadedCard1Type] cp TYPE_ENERGY - jr nc, .check_for_next_card + jr nc, .check_for_next_card ; skip if not Pokemon card ld a, [wLoadedCard1Stage] or a - jr nz, .check_for_next_card + jr nz, .check_for_next_card ; skip if not Basic Stage + +; play Basic card from hand push hl ldh a, [hTempCardIndex_ff98] call PutHandPokemonCardInPlayArea @@ -521,7 +595,7 @@ ConvertColorToEnergyCardID: ; 1430f (5:430f) db FIGHTING_ENERGY db PSYCHIC_ENERGY db DOUBLE_COLORLESS_ENERGY - + Func_14323: ; 14323 (5:4323) INCROM $14323, $1433d @@ -1003,13 +1077,13 @@ EstimateDamage_FromDefendingPokemon: ; 1450b (5:450b) ; damage as the receiver CalculateDamage_FromDefendingPokemon: ; 1458c (5:458c) ld hl, wAIMinDamage - call _CalculateDamage_FromDefendingPokemon + call .CalculateDamage ld hl, wAIMaxDamage - call _CalculateDamage_FromDefendingPokemon + call .CalculateDamage ld hl, wDamage -; fallthrough + ; fallthrough -_CalculateDamage_FromDefendingPokemon: ; 1459b (5:459b) +.CalculateDamage ; 1459b (5:459b) ld e, [hl] ld d, $00 push hl @@ -1139,243 +1213,7 @@ AIProcessHandTrainerCards: ; 14663 (5:4663) farcall _AIProcessHandTrainerCards ret -; GENERAL DECK POINTER LIST - Not sure on all of these. -; This is an example of an AI pointer table, there's one for each AI type. -PointerTable_14668: ; 14668 (05:4668) - dw Func_14674 ; not used - dw Func_14674 ; general AI for battles - dw Func_14678 ; basic pokemon placement / cheater shuffling on better AI - dw Func_1467f - dw Func_14683 - dw Func_14687 - -; when battle AI gets called -Func_14674: ; 14674 (5:4674) - call Func_1468b - ret - -Func_14678: ; 14678 (5:4678) - call Func_15636 - call $4226 - ret - -Func_1467f: ; 1467f (5:467f) - call $5b72 - ret - -Func_14683: ; 14683 (5:4683) - call $5b72 - ret - -Func_14687: ; 14687 (5:4687) - call $41e5 - ret - -; AI for general decks i think -Func_1468b: ; 1468b (5:468b) - call Func_15649 - ld a, $1 - call AIProcessHandTrainerCards - farcall $8, $67d3 - jp nc, $4776 - farcall $8, $6790 - farcall $8, $66a3 - farcall $8, $637f - ret c - farcall $8, $662d - ld a, $2 - call AIProcessHandTrainerCards - ld a, $3 - call AIProcessHandTrainerCards - ld a, $4 - call AIProcessHandTrainerCards - call $5eae - ret c - ld a, $5 - call AIProcessHandTrainerCards - ld a, $6 - call AIProcessHandTrainerCards - ld a, $7 - call AIProcessHandTrainerCards - ld a, $8 - call AIProcessHandTrainerCards - call $4786 - ld a, $a - call AIProcessHandTrainerCards - ld a, $b - call AIProcessHandTrainerCards - ld a, $c - call AIProcessHandTrainerCards - ld a, [wAlreadyPlayedEnergy] - or a - jr nz, .asm_146ed - call $64e8 - -.asm_146ed - call $5eae - farcall $8, $66a3 - farcall $8, $637f - ret c - farcall $8, $6790 - ld a, $d - farcall $8, $619b - ld a, $d - call AIProcessHandTrainerCards - ld a, $f - call AIProcessHandTrainerCards - ld a, [wPreviousAIFlags] - and AI_FLAG_USED_PROFESSOR_OAK - jr z, .asm_14776 - ld a, $1 - call AIProcessHandTrainerCards - ld a, $2 - call AIProcessHandTrainerCards - ld a, $3 - call AIProcessHandTrainerCards - ld a, $4 - call AIProcessHandTrainerCards - call $5eae - ret c - ld a, $5 - call AIProcessHandTrainerCards - ld a, $6 - call AIProcessHandTrainerCards - ld a, $7 - call AIProcessHandTrainerCards - ld a, $8 - call AIProcessHandTrainerCards - call $4786 - ld a, $a - call AIProcessHandTrainerCards - ld a, $b - call AIProcessHandTrainerCards - ld a, $c - call AIProcessHandTrainerCards - ld a, [wAlreadyPlayedEnergy] - or a - jr nz, .asm_1475b - call $64e8 - -.asm_1475b - call $5eae - farcall $8, $66a3 - farcall $8, $637f - ret c - farcall $8, $6790 - ld a, $d - farcall $8, $619b - ld a, $d - call AIProcessHandTrainerCards - -.asm_14776 - ld a, $e - farcall $8, $619b - call $69f8 - ret c - ld a, $5 - bank1call AIMakeDecision - ret -; 0x14786 - -Func_14786: ; 14786 (5:4786) - INCROM $14786, $14c91 - -; this routine handles how Legendary Articuno -; prioritises playing energy cards to each Pokémon. -; first, it makes sure that all Lapras have at least -; 3 energy cards before moving on to Articuno, -; and then to Dewgong and Seel -ScoreLegendaryArticunoCards: ; 14c91 (5:4c91) - call SwapTurn - call CountPrizes - call SwapTurn - cp 3 - ret c - -; player prizes >= 3 -; if Lapras has more than half HP and -; can use second move, check next for Articuno -; otherwise, check if Articuno or Dewgong -; have more than half HP and can use second move -; and if so, the next Pokémon to check is Lapras - ld a, LAPRAS - call CheckForBenchIDAtHalfHPAndCanUseSecondMove - jr c, .articuno - ld a, ARTICUNO1 - call CheckForBenchIDAtHalfHPAndCanUseSecondMove - jr c, .lapras - ld a, DEWGONG - call CheckForBenchIDAtHalfHPAndCanUseSecondMove - jr c, .lapras - jr .articuno - -; the following routines check for certain card IDs in bench -; and call RaiseAIScoreToAllMatchingIDsInBench if these are found. -; for Lapras, an additional check is made to its -; attached energy count, which skips calling the routine -; if this count is >= 3 -.lapras - ld a, LAPRAS - ld b, PLAY_AREA_BENCH_1 - call LookForCardIDInPlayArea_Bank5 - jr nc, .articuno - ld e, a - call CountNumberOfEnergyCardsAttached - cp 3 - jr nc, .articuno - ld a, LAPRAS - call RaiseAIScoreToAllMatchingIDsInBench - ret - -.articuno - ld a, ARTICUNO1 - ld b, PLAY_AREA_BENCH_1 - call LookForCardIDInPlayArea_Bank5 - jr nc, .dewgong - ld a, ARTICUNO1 - call RaiseAIScoreToAllMatchingIDsInBench - ret - -.dewgong - ld a, DEWGONG - ld b, PLAY_AREA_BENCH_1 - call LookForCardIDInPlayArea_Bank5 - jr nc, .seel - ld a, DEWGONG - call RaiseAIScoreToAllMatchingIDsInBench - ret - -.seel - ld a, SEEL - ld b, PLAY_AREA_BENCH_1 - call LookForCardIDInPlayArea_Bank5 - ret nc - ld a, SEEL - call RaiseAIScoreToAllMatchingIDsInBench - ret -; 0x14cf7 - -Func_14cf7: ; 14cf7 (5:4cf7) - INCROM $14cf7, $1514f - -; these seem to be lists of card IDs -; for the AI to look up in their hand -Data_1514f: ; 1514f (5:514f) - db KANGASKHAN - db CHANSEY - db SNORLAX - db MR_MIME - db ABRA - db $00 - - db ABRA - db MR_MIME - db KANGASKHAN - db SNORLAX - db CHANSEY - db $00 - - INCROM $1515b, $155d2 +INCLUDE "engine/deck_ai/deck_ai.asm" ; return carry if card ID loaded in a is found in hand ; and outputs in a the deck index of that card @@ -1384,7 +1222,7 @@ Data_1514f: ; 1514f (5:514f) ; input: ; a = card ID ; output: -; a = card deck index, if found +; a = card deck index, if found ; carry set if found LookForCardIDInHandList_Bank5: ; 155d2 (5:55d2) ld [wTempCardIDToLook], a @@ -1444,49 +1282,105 @@ LookForCardIDInPlayArea_Bank5: ; 155ef (5:55ef) ret ; 0x15612 -Func_15612: ; 15612 (5:5612) - INCROM $15612, $15636 +; check if energy card ID in e is in AI hand and, +; if so, attaches it to card ID in d in Play Area. +; input: +; e = Energy card ID +; d = Pokemon card ID +AIAttachEnergyInHandToCardInPlayArea: ; 15612 (5:5612) + ld a, e + push de + call LookForCardIDInHandList_Bank5 + pop de + ret nc ; not in hand + ld b, PLAY_AREA_ARENA + +.attach + ld e, a + ld a, d + call LookForCardIDInPlayArea_Bank5 + ldh [hTempPlayAreaLocation_ffa1], a + ld a, e + ldh [hTemp_ffa0], a + ld a, OPPACTION_PLAY_ENERGY + bank1call AIMakeDecision + ret +; 0x1562b + +; same as AIAttachEnergyInHandToCardInPlayArea but +; only look for card ID in the Bench. +AIAttachEnergyInHandToCardInBench: ; 1562b (5:562b) + ld a, e + push de + call LookForCardIDInHandList_Bank5 + pop de + ret nc + ld b, PLAY_AREA_BENCH_1 + jr AIAttachEnergyInHandToCardInPlayArea.attach +; 0x15636 -Func_15636: ; 15636 (5:5636) +InitAIDuelVars: ; 15636 (5:5636) ld a, $10 ld hl, wcda5 call ClearMemory_Bank5 - ld a, $5 - ld [wcda6], a + ld a, 5 + ld [wAIPokedexCounter], a ld a, $ff ld [wcda5], a ret -Func_15649: ; 15649 (5:5649) - ld a, [wcda6] +; initializes some variables and sets value of wAIBarrierFlagCounter. +; if Player uses Barrier 3 times in a row, AI checks if Player's deck +; has only Mewtwo1 Pokemon cards (running a Mewtwo1 mill deck). +InitAITurnVars: ; 15649 (5:5649) +; increase Pokedex counter by 1 + ld a, [wAIPokedexCounter] inc a - ld [wcda6], a + ld [wAIPokedexCounter], a + xor a ld [wPreviousAIFlags], a ld [wcddb], a ld [wcddc], a - ld [wce03], a + ld [wAIRetreatedThisTurn], a + +; checks if the Player used an attack last turn +; and if it was the second attack of their card. ld a, [wPlayerAttackingMoveIndex] cp $ff - jr z, .asm_156b1 + jr z, .check_flag or a - jr z, .asm_156b1 + jr z, .check_flag ld a, [wPlayerAttackingCardIndex] cp $ff - jr z, .asm_156b1 + jr z, .check_flag + +; if the card is Mewtwo1, it means the Player +; used its second attack, Barrier. call SwapTurn call GetCardIDFromDeckIndex call SwapTurn ld a, e - cp MEWTWO1 ; I believe this is a check for Mewtwo1's Barrier move - jr nz, .asm_156b1 - ld a, [wcda7] + cp MEWTWO1 + jr nz, .check_flag + ; Player used Barrier last turn + +; check if flag was already set, if so, +; reset wAIBarrierFlagCounter to $80. + ld a, [wAIBarrierFlagCounter] bit 7, a - jr nz, .asm_156aa + jr nz, .set_flag + +; if not, increase it by 1 and check if it exceeds 2. inc a - ld [wcda7], a - cp $3 - jr c, .asm_156c2 + ld [wAIBarrierFlagCounter], a + cp 3 + jr c, .done + +; this means that the Player used Barrier +; at least 3 turns in a row. +; check if Player is running Mewtwo1-only deck, +; if so, set wAIBarrierFlagCounter flag. ld a, DUELVARS_ARENA_CARD call GetNonTurnDuelistVariable call SwapTurn @@ -1494,33 +1388,34 @@ Func_15649: ; 15649 (5:5649) call SwapTurn ld a, e cp MEWTWO1 - jr nz, .asm_156a4 - farcall $8, $67a9 - jr nc, .asm_156aa - -.asm_156a4 + jr nz, .reset_1 + farcall CheckIfPlayerHasPokemonOtherThanMewtwo1 + jr nc, .set_flag +.reset_1 +; reset wAIBarrierFlagCounter xor a - ld [wcda7], a - jr .asm_156c2 + ld [wAIBarrierFlagCounter], a + jr .done -.asm_156aa - ld a, $80 - ld [wcda7], a - jr .asm_156c2 +.set_flag + ld a, AI_FLAG_MEWTWO_MILL + 0 + ld [wAIBarrierFlagCounter], a + jr .done -.asm_156b1 - ld a, [wcda7] +.check_flag +; increase counter by 1 if flag is set + ld a, [wAIBarrierFlagCounter] bit 7, a - jr z, .asm_156be + jr z, .reset_2 inc a - ld [wcda7], a - jr .asm_156c2 + ld [wAIBarrierFlagCounter], a + jr .done -.asm_156be +.reset_2 +; reset wAIBarrierFlagCounter xor a - ld [wcda7], a - -.asm_156c2 + ld [wAIBarrierFlagCounter], a +.done ret ; 0x156c3 @@ -1735,6 +1630,8 @@ CountNumberOfEnergyCardsAttached: ; 15787 (5:5787) ; input: ; a = card location to look in; ; e = card ID to look for. +; output: +; a = deck index of card found, if any CheckIfAnyCardIDinLocation: ; 157a3 (5:57a3) ld b, a ld c, e @@ -1856,8 +1753,82 @@ RemoveCardIDInList: ; 157f3 (5:57f3) ret ; 0x1581b -Func_1581b: ; 1581b (5:581b) - INCROM $1581b, $158b2 +; play Pokemon cards from the hand to set the starting +; Play Area of Boss decks. +; each Boss deck has two ID lists in order of preference. +; one list is for the Arena card is the other is for the Bench cards. +; if Arena card could not be set (due to hand not having any card in its list) +; or if list is null, return carry and do not play any cards. +TrySetUpBossStartingPlayArea: ; 1581b (5:581b) + ld de, wAICardListArenaPriority + ld a, d + or a + jr z, .set_carry ; return if null + +; pick Arena card + call CreateHandCardList + ld hl, wDuelTempList + ld de, wAICardListArenaPriority + call .PlayPokemonCardInOrder + ret c + +; play Pokemon cards to Bench until there are +; a maximum of 3 cards in Play Area. +.loop + ld de, wAICardListBenchPriority + call .PlayPokemonCardInOrder + jr c, .done + cp 3 + jr c, .loop + +.done + or a + ret +.set_carry + scf + ret +; 0x1583f + +; runs through input card ID list in de. +; plays to Play Area first card that is found in hand. +; returns carry if none of the cards in the list are found. +; returns number of Pokemon in Play Area in a. +.PlayPokemonCardInOrder ; 1583f (5:583f) + ld a, [de] + ld c, a + inc de + ld a, [de] + ld d, a + ld e, c + +; go in order of the list in de and +; add first card that matches ID. +; returns carry if hand doesn't have any card in list. +.loop_id_list + ld a, [de] + inc de + or a + jr z, .not_found + push de + ld e, a + call RemoveCardIDInList + pop de + jr nc, .loop_id_list + + ; play this card to Play Area and return + push hl + call PutHandPokemonCardInPlayArea + pop hl + or a + ret + +.not_found + scf + ret +; 0x1585b + +Func_1585b: ; 1585b (5:585b) + INCROM $1585b, $158b2 ; determine AI score for retreating ; return carry if AI decides to retreat @@ -2207,7 +2178,7 @@ AIDecideWhetherToRetreat: ; 158b2 (5:58b2) .one_or_none call CheckIfArenaCardIsAtHalfHPCanEvolveAndUseSecondMove jr c, .check_defending_can_ko - call CheckIfBenchCardsAreAtHalfHPCanEvolveAndUseSecondMove + call CountNumberOfSetUpBenchPokemon cp 2 jr c, .check_defending_can_ko call AddToAIScore @@ -2323,8 +2294,9 @@ Func_15b54: ; 15b54 (5:5b54) ; 0x15b72 ; calculates AI score for bench Pokémon -; returns in hTempPlayAreaLocation_ff9d the -; Play Area location of best card to switch to +; returns in a and [hTempPlayAreaLocation_ff9d] the +; Play Area location of best card to switch to. +; returns carry if no Bench Pokemon. AIDecideBenchPokemonToSwitchTo: ; 15b72 (5:5b72) xor a ldh [hTempPlayAreaLocation_ff9d], a @@ -2376,17 +2348,17 @@ AIDecideBenchPokemonToSwitchTo: ; 15b72 (5:5b72) xor a ld [wSelectedAttack], a call CheckIfSelectedMoveIsUnusable - call nc, .calculate_damage + call nc, .HandleAttackDamageScore ld a, $01 ld [wSelectedAttack], a call CheckIfSelectedMoveIsUnusable - call nc, .calculate_damage + call nc, .HandleAttackDamageScore jr .check_energy_card ; adds to AI score depending on amount of damage ; it can inflict to the defending Pokémon ; AI score += floor(Damage / 10) + 1 -.calculate_damage +.HandleAttackDamageScore ld a, [wSelectedAttack] call EstimateDamage_VersusDefendingCard ld a, [wDamage] @@ -2571,40 +2543,40 @@ AIDecideBenchPokemonToSwitchTo: ; 15b72 (5:5b72) cp MYSTERIOUS_FOSSIL jr z, .lower_score_2 cp CLEFAIRY_DOLL - jr nz, .asm_15d0c + jr nz, .ai_score_bonus .lower_score_2 ld a, 10 call SubFromAIScore -.asm_15d0c +.ai_score_bonus ld b, a - ld a, [$cdb1] + ld a, [wAICardListRetreatBonus + 1] or a jr z, .store_score ld h, a - ld a, [$cdb0] + ld a, [wAICardListRetreatBonus] ld l, a -.loop +.loop_ids ld a, [hli] or a - jr z, .store_score + jr z, .store_score ; list is over cp b - jr nz, .asm_15d32 + jr nz, .next_id ld a, [hl] cp $80 - jr c, .asm_15d2b + jr c, .subtract_score sub $80 call AddToAIScore - jr .asm_15d32 -.asm_15d2b + jr .next_id +.subtract_score ld c, a ld a, $80 sub c call SubFromAIScore -.asm_15d32 +.next_id inc hl - jr .loop + jr .loop_ids .store_score ldh a, [hTempPlayAreaLocation_ff9d] @@ -2626,9 +2598,13 @@ AIDecideBenchPokemonToSwitchTo: ; 15b72 (5:5b72) ; 0x15d4f ; handles AI action of retreating Arena Pokémon -; and chooses which energy cards to discard -; if card can't discard, return carry -AIChooseEnergyToDiscardForRetreatCost: ; 15d4f (5:5d4f) +; and chooses which energy cards to discard. +; if card can't discard, return carry. +; in case it's Clefairy Doll or Mysterious Fossil, +; handle its effect to discard itself instead of retreating. +; input: +; - a = Play Area location (PLAY_AREA_*) of card to retreat to. +AITryToRetreat: ; 15d4f (5:5d4f) push af ld a, [wAIPlayEnergyCardForRetreat] or a @@ -2859,7 +2835,7 @@ AIChooseEnergyToDiscardForRetreatCost: ; 15d4f (5:5d4f) ld a, OPPACTION_USE_PKMN_POWER bank1call AIMakeDecision pop af - ldh [hTempPlayAreaLocation_ffa1], a + ldh [hAIPkmnPowerEffectParam], a ld a, OPPACTION_EXECUTE_PKMN_POWER_EFFECT bank1call AIMakeDecision ld a, OPPACTION_DUEL_MAIN_SCENE @@ -3692,25 +3668,25 @@ LookForEnergyNeededForMoveInHand: ; 16311 (5:6311) ; 0x1633f ; goes through $00 terminated list pointed -; by wcdae and compares it to each card in hand. +; by wAICardListPlayFromHandPriority and compares it to each card in hand. ; Sorts the hand in wDuelTempList so that the found card IDs ; are in the same order as the list pointed by de. SortTempHandByIDList: ; 1633f (5:633f) - ld a, [wcdae+1] + ld a, [wAICardListPlayFromHandPriority+1] or a - ret z + ret z ; return if list is empty ; start going down the ID list ld d, a - ld a, [wcdae] + ld a, [wAICardListPlayFromHandPriority] ld e, a ld c, 0 -.next_list_id +.loop_list_id ; get this item's ID ; if $00, list has ended ld a, [de] or a - ret z + ret z ; return when list is over inc de ld hl, wDuelTempList ld b, 0 @@ -3722,7 +3698,7 @@ SortTempHandByIDList: ; 1633f (5:633f) ld a, [hl] ldh [hTempCardIndex_ff98], a cp -1 - jr z, .next_list_id + jr z, .loop_list_id push bc push de call GetCardIDFromDeckIndex @@ -4006,47 +3982,58 @@ CheckForEvolutionInDeck: ; 16451 (5:6451) Func_16488 ; 16488 (5:6488) INCROM $16488, $164a1 -; copies wPlayAreaAIScore to wTempPlayAreaAIScore. -; copies AIScore to wcde3. -; decides which card to get energy card. -Func_164a1: ; 164a1 (5:64a1) - ld a, $03 - ld [wcdd8], a +; have AI choose an energy card to play, but do not play it. +; does not consider whether the cards have evolutions to be played. +; return carry if an energy card is chosen to use in any Play Area card, +; and if so, return its Play Area location in hTempPlayAreaLocation_ff9d. +AIProcessButDontPlayEnergy_SkipEvolution: ; 164a1 (5:64a1) + ld a, AI_ENERGY_FLAG_DONT_PLAY | AI_ENERGY_FLAG_SKIP_EVOLUTION + ld [wAIEnergyAttachLogicFlags], a + +; backup wPlayAreaAIScore in wTempPlayAreaAIScore. ld de, wTempPlayAreaAIScore ld hl, wPlayAreaAIScore ld b, MAX_PLAY_AREA_POKEMON -.loop_play_area +.loop ld a, [hli] ld [de], a inc de dec b - jr nz, .loop_play_area + jr nz, .loop ld a, [wAIScore] ld [de], a - jr AIDecideWhichCardToAttachEnergy -Func_164ba: ; 164ba (5:64ba) - ld a, $83 - ld [wcdd8], a + jr AIProcessEnergyCards + +; have AI choose an energy card to play, but do not play it. +; does not consider whether the cards have evolutions to be played. +; return carry if an energy card is chosen to use in any Bench card, +; and if so, return its Play Area location in hTempPlayAreaLocation_ff9d. +AIProcessButDontPlayEnergy_SkipEvolutionAndArena: ; 164ba (5:64ba) + ld a, AI_ENERGY_FLAG_DONT_PLAY | AI_ENERGY_FLAG_SKIP_EVOLUTION | AI_ENERGY_FLAG_SKIP_ARENA_CARD + ld [wAIEnergyAttachLogicFlags], a + +; backup wPlayAreaAIScore in wTempPlayAreaAIScore. ld de, wTempPlayAreaAIScore ld hl, wPlayAreaAIScore ld b, MAX_PLAY_AREA_POKEMON -.asm_164c7 +.loop ld a, [hli] ld [de], a inc de dec b - jr nz, .asm_164c7 + jr nz, .loop ld a, [wAIScore] ld [de], a - jr AIDecideWhichCardToAttachEnergy + + jr AIProcessEnergyCards ; copies wTempPlayAreaAIScore to wPlayAreaAIScore -; and loads wAIscore with value in wcde3. -; identical to Func_169e3. -Func_164d3: ; 164d3 (5:64d3) +; and loads wAIscore with value in wTempAIScore. +; identical to RetrievePlayAreaAIScoreFromBackup2. +RetrievePlayAreaAIScoreFromBackup1: ; 164d3 (5:64d3) push af ld de, wPlayAreaAIScore ld hl, wTempPlayAreaAIScore @@ -4065,34 +4052,37 @@ Func_164d3: ; 164d3 (5:64d3) ; have AI decide whether to play energy card from hand ; and determine which card is best to attach it. -AIDecidePlayEnergyCardFromHand: ; 164e8 (5:64e8) +AIProcessAndTryToPlayEnergy: ; 164e8 (5:64e8) xor a - ld [wcdd8], a + ld [wAIEnergyAttachLogicFlags], a call CreateEnergyCardListFromHand - jr nc, AIDecideWhichCardToAttachEnergy + jr nc, AIProcessEnergyCards ; no energy - ld a, [wcdd8] + ld a, [wAIEnergyAttachLogicFlags] or a jr z, .exit - jp Func_164d3 + jp RetrievePlayAreaAIScoreFromBackup1 .exit or a ret ; have AI decide whether to play energy card ; and determine which card is best to attach it. -AIDecideWhichCardToAttachEnergy: ; 164fc (5:64fc) +AIProcessEnergyCards: ; 164fc (5:64fc) +; initialize Play Area AI score ld a, $80 ld b, MAX_PLAY_AREA_POKEMON - ld hl, wcde4 + ld hl, wPlayAreaEnergyAIScore .loop ld [hli], a dec b jr nz, .loop +; Legendary Articuno Deck has its own energy card logic call HandleLegendaryArticunoEnergyScoring +; start the main Play Area loop ld b, PLAY_AREA_ARENA ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA call GetTurnDuelistVariable @@ -4106,8 +4096,8 @@ AIDecideWhichCardToAttachEnergy: ; 164fc (5:64fc) ld [wAIScore], a ld a, $ff ld [wTempAI], a - ld a, [wcdd8] - and $02 + ld a, [wAIEnergyAttachLogicFlags] + and AI_ENERGY_FLAG_SKIP_EVOLUTION jr nz, .check_venusaur ; check if energy needed is found in hand @@ -4125,7 +4115,7 @@ AIDecideWhichCardToAttachEnergy: ; 164fc (5:64fc) ld a, [wCurCardCanAttack] call CheckForEvolutionInList jr nc, .no_evolution_in_hand - ld [wTempAI], a + ld [wTempAI], a ; store evolution card found ld a, 2 call AddToAIScore jr .check_venusaur @@ -4137,8 +4127,9 @@ AIDecideWhichCardToAttachEnergy: ; 164fc (5:64fc) ld a, 1 call AddToAIScore -; if there's no Muk in Play Area -; and there's Venusaur2, add to AI score +; if there's no Muk in any Play Area +; and there's Venusaur2 in own Play Area, +; add to AI score .check_venusaur ld a, MUK call CountPokemonIDInBothPlayAreas @@ -4155,29 +4146,32 @@ AIDecideWhichCardToAttachEnergy: ; 164fc (5:64fc) jr nz, .bench ; arena - ld a, [wcda7] + ld a, [wAIBarrierFlagCounter] bit 7, a - jr z, .check_arena_hp + jr z, .add_to_score + +; subtract from score instead +; if Player is running Mewtwo1 mill deck. ld a, 5 call SubFromAIScore jr .check_defending_can_ko -; lower AI score if poison/double poison -; will KO Pokémon between turns -; or if the defending Pokémon can KO -.check_arena_hp +.add_to_score ld a, 4 call AddToAIScore +; lower AI score if poison/double poison +; will KO Pokémon between turns +; or if the defending Pokémon can KO ld a, DUELVARS_ARENA_CARD_HP call GetTurnDuelistVariable call CalculateByteTensDigit cp 3 jr nc, .check_defending_can_ko -; hp < 30 + ; hp < 30 cp 2 jr z, .has_20_hp -; hp = 10 + ; hp = 10 ld a, DUELVARS_ARENA_CARD_STATUS call GetTurnDuelistVariable and POISONED @@ -4194,7 +4188,7 @@ AIDecideWhichCardToAttachEnergy: ; 164fc (5:64fc) jr .check_bench .check_defending_can_ko call CheckIfDefendingPokemonCanKnockOut - jr nc, .asm_165e1 + jr nc, .ai_score_bonus ld a, 10 call SubFromAIScore @@ -4205,10 +4199,10 @@ AIDecideWhichCardToAttachEnergy: ; 164fc (5:64fc) ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA call GetTurnDuelistVariable dec a - jr nz, .asm_165e1 + jr nz, .ai_score_bonus ld a, 6 call AddToAIScore - jr .asm_165e1 + jr .ai_score_bonus ; lower AI score by 3 - (bench HP)/10 ; if bench HP < 30 @@ -4217,20 +4211,20 @@ AIDecideWhichCardToAttachEnergy: ; 164fc (5:64fc) call GetTurnDuelistVariable call CalculateByteTensDigit cp 3 - jr nc, .asm_165e1 + jr nc, .ai_score_bonus ; hp < 30 ld b, a ld a, 3 sub b call SubFromAIScore -; check list in wcdb2 -.asm_165e1 - ld a, [wcdb3] +; check list in wAICardListEnergyBonus +.ai_score_bonus + ld a, [wAICardListEnergyBonus + 1] or a - jr z, .check_boss_deck + jr z, .check_boss_deck ; is null ld h, a - ld a, [wcdb2] + ld a, [wAICardListEnergyBonus] ld l, a push hl @@ -4258,6 +4252,7 @@ AIDecideWhichCardToAttachEnergy: ; 164fc (5:64fc) pop de cp d jr c, .check_id_score + ; already reached target number of energy cards ld a, 10 call SubFromAIScore jr .store_score @@ -4288,11 +4283,12 @@ AIDecideWhichCardToAttachEnergy: ; 164fc (5:64fc) .check_boss_deck call CheckIfNotABossDeckID jr c, .skip_boss_deck + call Func_174f2 ldh a, [hTempPlayAreaLocation_ff9d] ld c, a ld b, $00 - ld hl, wcde4 + ld hl, wPlayAreaEnergyAIScore add hl, bc ld a, [hl] cp $80 @@ -4336,24 +4332,24 @@ AIDecideWhichCardToAttachEnergy: ; 164fc (5:64fc) ; for each card has been calculated. ; now to determine the highest score. call FindPlayAreaCardWithHighestAIScore - jp nc, .asm_1668a + jp nc, .not_found - ld a, [wcdd8] + ld a, [wAIEnergyAttachLogicFlags] or a jr z, .play_card scf - jp Func_164d3 + jp RetrievePlayAreaAIScoreFromBackup1 .play_card call CreateEnergyCardListFromHand jp AITryToPlayEnergyCard -.asm_1668a: ; 1668a (5:668a) - ld a, [wcdd8] +.not_found: ; 1668a (5:668a) + ld a, [wAIEnergyAttachLogicFlags] or a - jr z, .asm_16693 - jp Func_164d3 -.asm_16693 + jr z, .no_carry + jp RetrievePlayAreaAIScoreFromBackup1 +.no_carry or a ret ; 0x16695 @@ -4562,15 +4558,17 @@ DetermineAIScoreOfMoveEnergyRequirement: ; 16695 (5:6695) ; of the card with the highest Play Area AI score, unless ; the highest score is below $85. ; if it succeeds in return a card location, set carry. +; if AI_ENERGY_FLAG_SKIP_ARENA_CARD is set in wAIEnergyAttachLogicFlags +; doesn't include the Arena card and there's no minimum score. FindPlayAreaCardWithHighestAIScore: ; 167b5 (5:67b5) - ld a, [wcdd8] - and $80 - jr nz, .asm_167e1 + ld a, [wAIEnergyAttachLogicFlags] + and AI_ENERGY_FLAG_SKIP_ARENA_CARD + jr nz, .only_bench ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA call GetTurnDuelistVariable ld b, a - ld c, 0 ; PLAY_AREA_ARENA + ld c, PLAY_AREA_ARENA ld e, c ld d, c ld hl, wPlayAreaAIScore @@ -4601,7 +4599,7 @@ FindPlayAreaCardWithHighestAIScore: ; 167b5 (5:67b5) ret ; same as above but only check bench Pokémon scores. -.asm_167e1 +.only_bench ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA call GetTurnDuelistVariable dec a @@ -4624,6 +4622,7 @@ FindPlayAreaCardWithHighestAIScore: ; 167b5 (5:67b5) dec b jr nz, .loop_2 +; in this case, there is no minimum threshold AI score. ld a, d ldh [hTempPlayAreaLocation_ff9d], a scf @@ -4694,16 +4693,16 @@ GetEnergyCardForDiscardOrEnergyBoostAttack: ; 1683b (5:683b) jr z, .first_attack ; check if second attack is Zapdos2's Thunderbolt, -; Charizard's Fire Spin or Exeggcutor's Big Eggsplosion, +; Charizard's Fire Spin or Exeggutor's Big Eggsplosion, ; for these to be treated differently. ; for both attacks, load its energy cost. ld a, b cp ZAPDOS2 jr z, .zapdos2 cp CHARIZARD - jr z, .charizard_or_exeggcutor + jr z, .charizard_or_exeggutor cp EXEGGUTOR - jr z, .charizard_or_exeggcutor + jr z, .charizard_or_exeggutor ld hl, wLoadedCard2Move2EnergyCost jr .fire .first_attack @@ -4758,9 +4757,9 @@ GetEnergyCardForDiscardOrEnergyBoostAttack: ; 1683b (5:683b) or a ret -; Charizard's Fire Spin and Exeggcutor's Big Eggsplosion, +; Charizard's Fire Spin and Exeggutor's Big Eggsplosion, ; return carry. -.charizard_or_exeggcutor +.charizard_or_exeggutor lb bc, $00, $01 scf ret @@ -5019,11 +5018,13 @@ CheckSpecificDecksToAttachDoubleColorless: ; 1696e (5:696e) ret ; 0x169ca -Func_169ca: ; 169ca (5:69ca) +; have AI choose an attack to use, but do not execute it. +; return carry if an attack is chosen. +AIProcessButDontUseAttack: ; 169ca (5:69ca) ld a, $01 - ld [wcdd9], a + ld [wAIExecuteProcessedAttack], a -; copy wPlayAreaAIScore to wTempPlayAreaAIScore. +; backup wPlayAreaAIScore in wTempPlayAreaAIScore. ld de, wTempPlayAreaAIScore ld hl, wPlayAreaAIScore ld b, MAX_PLAY_AREA_POKEMON @@ -5034,15 +5035,15 @@ Func_169ca: ; 169ca (5:69ca) dec b jr nz, .loop -; copies wAIScore to wcde3 +; copies wAIScore to wTempAIScore ld a, [wAIScore] ld [de], a - jr Func_169fc + jr AIProcessAttacks ; copies wTempPlayAreaAIScore to wPlayAreaAIScore -; and loads wAIscore with value in wcde3. -; identical to Func_164d3. -Func_169e3: ; 169e3 (5:69e3) +; and loads wAIscore with value in wTempAIScore. +; identical to RetrievePlayAreaAIScoreFromBackup1. +RetrievePlayAreaAIScoreFromBackup2: ; 169e3 (5:69e3) push af ld de, wPlayAreaAIScore ld hl, wTempPlayAreaAIScore @@ -5060,12 +5061,18 @@ Func_169e3: ; 169e3 (5:69e3) ret ; 0x169f8 -Func_169f8: ; 169f8 (5:69f8) +; have AI choose and execute an attack. +; return carry if an attack was chosen and attempted. +AIProcessAndTryToUseAttack: ; 169f8 (5:69f8) xor a - ld [wcdd9], a + ld [wAIExecuteProcessedAttack], a ; fallthrough -Func_169fc: ; 169fc (5:69fc) +; checks which of the Active card's attacks for AI to use. +; If any of the attacks has enough AI score to be used, +; AI will use it if wAIExecuteProcessedAttack is 0. +; in either case, return carry if an attack is chosen to be used. +AIProcessAttacks: ; 169fc (5:69fc) ; if AI used Pluspower, load its attack index ld a, [wPreviousAIFlags] and AI_FLAG_USED_PLUSPOWER @@ -5075,25 +5082,27 @@ Func_169fc: ; 169fc (5:69fc) jr .attack_chosen .no_pluspower - ld a, [wcda7] - cp $80 - jp z, .asm_16a77 +; if Player is running Mewtwo1 mill deck, +; skip attack if Barrier counter is 0. + ld a, [wAIBarrierFlagCounter] + cp AI_FLAG_MEWTWO_MILL + 0 + jp z, .dont_attack ; determine AI score of both attacks. xor a ; FIRST_ATTACK_OR_PKMN_POWER call GetAIScoreOfAttack ld a, [wAIScore] - ld [wPlayAreaAIScore], a + ld [wFirstAttackAIScore], a ld a, SECOND_ATTACK call GetAIScoreOfAttack ; compare both attack scores ld c, SECOND_ATTACK - ld a, [wPlayAreaAIScore] + ld a, [wFirstAttackAIScore] ld b, a ld a, [wAIScore] cp b - jr nc, .asm_16a30 + jr nc, .check_score ; first attack has higher score dec c ld a, b @@ -5103,9 +5112,9 @@ Func_169fc: ; 169fc (5:69fc) ; first check if chosen attack has at least minimum score. ; then check if first attack is better than second attack ; in case the second one was chosen. -.asm_16a30 +.check_score cp $50 ; minimum score to use attack - jr c, .asm_16a77 + jr c, .dont_attack ; enough score, proceed ld a, c @@ -5115,14 +5124,18 @@ Func_169fc: ; 169fc (5:69fc) call CheckWhetherToSwitchToFirstAttack .attack_chosen - ld a, [wcdd9] +; check whether to execute the attack chosen + ld a, [wAIExecuteProcessedAttack] or a - jr z, .asm_16a48 + jr z, .execute + +; set carry and reset Play Area AI score +; to the previous values. scf - jp Func_169e3 + jp RetrievePlayAreaAIScoreFromBackup2 -.asm_16a48 - ld a, $0e +.execute + ld a, AI_TRAINER_CARD_PHASE_14 call AIProcessHandTrainerCards ; load this attack's damage output against @@ -5134,39 +5147,52 @@ Func_169fc: ; 169fc (5:69fc) ld a, [wDamage] or a - jr z, .asm_16a62 - ; if damage is 0, fallthrough + jr z, .check_damage_bench + ; if damage is not 0, fallthrough -.cannot_damage +.can_damage xor a ld [wcdb4], a - jr .asm_16a6d + jr .use_attack -.asm_16a62 +.check_damage_bench +; check if it can otherwise damage player's bench ld a, MOVE_FLAG1_ADDRESS | DAMAGE_TO_OPPONENT_BENCH_F call CheckLoadedMoveFlag - jr c, .cannot_damage + jr c, .can_damage + +; cannot damage either Defending Pokemon or Bench ld hl, wcdb4 inc [hl] -.asm_16a6d + +; return carry if attack is chosen +; and AI tries to use it. +.use_attack ld a, $01 ld [wcddb], a - call Func_14145 + call AITryUseAttack scf ret -.asm_16a77 - ld a, [wcdd9] + +.dont_attack + ld a, [wAIExecuteProcessedAttack] or a - jr z, .asm_16a80 - jp Func_169e3 -.asm_16a80 + jr z, .failed_to_use + +; reset Play Area AI score +; to the previous values. + jp RetrievePlayAreaAIScoreFromBackup2 + +; return no carry if no viable attack. +.failed_to_use ld hl, wcdb4 inc [hl] or a ret ; 0x16a86 -; determines the AI score of attack index in a. +; determines the AI score of attack index in a +; of card in Play Area location hTempPlayAreaLocation_ff9d. GetAIScoreOfAttack: ; 16a86 (5:6a86) ; initialize AI score. ld [wSelectedAttack], a @@ -5737,7 +5763,7 @@ HandleSpecialAIMoves: ; 16dcd (5:6dcd) cp BELLSPROUT jr z, HandleCallForFamily cp EXEGGUTOR - jp z, HandleExeggcutorTeleport + jp z, HandleExeggutorTeleport cp SCYTHER jp z, HandleSwordsDanceAndFocusEnergy cp KRABBY @@ -5864,7 +5890,7 @@ HandleJigglypuff2FriendshipSong: ; 16ead (5:6ead) ret ; if AI decides to retreat, return a score of $80 + 10. -HandleExeggcutorTeleport: ; 16ec2 (5:6ec2) +HandleExeggutorTeleport: ; 16ec2 (5:6ec2) call AIDecideWhetherToRetreat jp nc, HandleSpecialAIMoves.zero ld a, $8a @@ -5942,14 +5968,14 @@ HandlePorygonConversion: ; 16f18 (5:6f18) jr nz, .conversion_2 ; conversion 1 - call CheckIfBenchCardsAreAtHalfHPCanEvolveAndUseSecondMove + call CountNumberOfSetUpBenchPokemon cp 2 jr c, .low_score ld a, $82 ret .conversion_2 - call CheckIfBenchCardsAreAtHalfHPCanEvolveAndUseSecondMove + call CountNumberOfSetUpBenchPokemon cp 2 jr nc, .low_score ld a, $82 @@ -6097,7 +6123,7 @@ HandleElectrode1EnergySpike: ; 16ff2 (5:6ff2) ld e, LIGHTNING_ENERGY call CheckIfAnyCardIDinLocation jp nc, HandleSpecialAIMoves.zero - call Func_164a1 + call AIProcessButDontPlayEnergy_SkipEvolution jp nc, HandleSpecialAIMoves.zero ld a, $83 ret @@ -6125,7 +6151,7 @@ HandleHyperBeam: ; 17005 (5:7005) CheckWhetherToSwitchToFirstAttack: ; 17019 (5:7019) ; this checks whether the first attack is also viable ; (has more than minimum score to be used) - ld a, [wPlayAreaAIScore] + ld a, [wFirstAttackAIScore] cp $50 jr c, .keep_second_attack @@ -6209,7 +6235,7 @@ CheckIfAnyBasicPokemonInDeck: ; 17057 (5:7057) ; return carry and that card's Play Area location in a. ; output: ; a = card location of Pokémon card, if found; -; cerry set if such a card is found. +; carry set if such a card is found. LookForCardThatIsKnockedOutOnDevolution: ; 17080 (5:7080) ldh a, [hTempPlayAreaLocation_ff9d] push af @@ -6307,15 +6333,16 @@ CheckIfArenaCardIsAtHalfHPCanEvolveAndUseSecondMove: ; 170c9 (5:70c9) ret ; 0x17101 -; returns carry if at least one Pokémon in bench -; meets the following conditions: -; - card HP >= half max HP +; count Pokemon in the Bench that +; meet the following conditions: +; - card HP > half max HP ; - card Unknown2's 4 bit is not set or ; is set but there's no evolution of card in hand/deck ; - card can use second move -; Also outputs the number of Pokémon in bench +; Outputs the number of Pokémon in bench ; that meet these requirements in a -CheckIfBenchCardsAreAtHalfHPCanEvolveAndUseSecondMove: ; 17101 (5:7101) +; and returns carry if at least one is found +CountNumberOfSetUpBenchPokemon: ; 17101 (5:7101) ldh a, [hTempPlayAreaLocation_ff9d] ld d, a ld a, [wSelectedAttack] @@ -6333,17 +6360,24 @@ CheckIfBenchCardsAreAtHalfHPCanEvolveAndUseSecondMove: ; 17101 (5:7101) push hl cp $ff jr z, .done + ld d, a push de push bc call LoadCardDataToBuffer1_FromDeckIndex pop bc + +; compares card's current HP with max HP ld a, c add DUELVARS_ARENA_CARD_HP call GetTurnDuelistVariable ld d, a ld a, [wLoadedCard1HP] rrca + +; a = max HP / 2 +; d = current HP +; jumps if (current HP) <= (max HP / 2) cp d pop de jr nc, .next @@ -6386,8 +6420,138 @@ CheckIfBenchCardsAreAtHalfHPCanEvolveAndUseSecondMove: ; 17101 (5:7101) ret ; 0x17161 -Func_17161 ; 17161 (5:7161) - INCROM $17161, $171fb +; handles AI logic to determine some selections regarding certain attacks, +; if any of these attacks were chosen to be used. +; returns carry if selection was successful, +; and no carry if unable to make one. +; outputs in hTempPlayAreaLocation_ffa1 the chosen parameter. +AISelectSpecialAttackParameters: ; 17161 (5:7161) + ld a, [wSelectedAttack] + push af + call .SelectAttackParameters + pop bc + ld a, b + ld [wSelectedAttack], a + ret +; 0x1716e + +.SelectAttackParameters: ; 1716e (5:716e) + ld a, DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + call GetCardIDFromDeckIndex + ld a, e + cp MEW3 + jr z, .devolution_beam + cp MEWTWO3 + jr z, .energy_absorption + cp MEWTWO2 + jr z, .energy_absorption + cp EXEGGUTOR + jr z, .teleport + cp ELECTRODE1 + jr z, .energy_spike + ; fallthrough + +.no_carry + or a + ret + +.devolution_beam +; in case selected attack is Devolution Beam +; store in hTempPlayAreaLocation_ffa1 +; the location of card to select to devolve + ld a, [wSelectedAttack] + or a + jp z, .no_carry ; can be jr + + ld a, $01 + ldh [hTemp_ffa0], a + call LookForCardThatIsKnockedOutOnDevolution + ldh [hTempPlayAreaLocation_ffa1], a + +.set_carry_1 + scf + ret + +.energy_absorption +; in case selected attack is Energy Absorption +; make list from energy cards in Discard Pile + ld a, [wSelectedAttack] + or a + jp nz, .no_carry ; can be jr + + ld a, $ff + ldh [hTempPlayAreaLocation_ffa1], a + ldh [hTempRetreatCostCards], a + +; search for Psychic energy cards in Discard Pile + ld e, PSYCHIC_ENERGY + ld a, CARD_LOCATION_DISCARD_PILE + call CheckIfAnyCardIDinLocation + ldh [hTemp_ffa0], a + farcall CreateEnergyCardListFromOpponentDiscardPile + +; find any energy card different from +; the one found by CheckIfAnyCardIDinLocation. +; since using this move requires a Psychic energy card, +; and another one is in hTemp_ffa0, +; then any other energy card would account +; for the Energy Cost of Psyburn. + ld hl, wDuelTempList +.loop_energy_cards + ld a, [hli] + cp $ff + jr z, .set_carry_2 + ld b, a + ldh a, [hTemp_ffa0] + cp b + jr z, .loop_energy_cards ; same card, keep looking + +; store the deck index of energy card found + ld a, b + ldh [hTempPlayAreaLocation_ffa1], a + ; fallthrough + +.set_carry_2 + scf + ret + +.teleport +; in case selected attack is Teleport +; decide Bench card to switch to. + ld a, [wSelectedAttack] + or a + jp nz, .no_carry ; can be jr + call AIDecideBenchPokemonToSwitchTo + jr c, .no_carry + ldh [hTemp_ffa0], a + scf + ret + +.energy_spike +; in case selected attack is Energy Spike +; decide basic energy card to fetch from Deck. + ld a, [wSelectedAttack] + or a + jp z, .no_carry ; can be jr + + ld a, CARD_LOCATION_DECK + ld e, LIGHTNING_ENERGY + +; if none were found in Deck, return carry... + call CheckIfAnyCardIDinLocation + ldh [hTemp_ffa0], a + jp nc, .no_carry ; can be jr + +; ...else find a suitable Play Area Pokemon to +; attach the energy card to. + call AIProcessButDontPlayEnergy_SkipEvolution + jp nc, .no_carry ; can be jr + ldh a, [hTempPlayAreaLocation_ff9d] + ldh [hTempPlayAreaLocation_ffa1], a + scf + ret +; 0x171fb ; return carry if Pokémon at play area location ; in hTempPlayAreaLocation_ff9d does not have @@ -6547,8 +6711,175 @@ CheckCardEvolutionInHandOrDeck: ; 17274 (5:7274) ret ; 0x172af -Func_172af ; 172af (5:72af) - INCROM $172af, $17383 +; sets up the inital hand of boss deck. +; always draws at least 2 Basic Pokemon cards and 2 Energy cards. +; also sets up so that the next cards to be drawn have +; some minimum number of Basic Pokemon and Energy cards. +SetUpBossStartingHandAndDeck: ; 172af (5:72af) +; shuffle all hand cards in deck + ld a, DUELVARS_HAND + call GetTurnDuelistVariable + ld b, STARTING_HAND_SIZE +.loop_hand + ld a, [hl] + call RemoveCardFromHand + call ReturnCardToDeck + dec b + jr nz, .loop_hand + jr .count_energy_basic + +.shuffle_deck + call ShuffleDeck + +; count number of Energy and basic Pokemon cards +; in the first STARTING_HAND_SIZE in deck. +.count_energy_basic + xor a + ld [wce06], a + ld [wce08], a + + ld a, DUELVARS_DECK_CARDS + call GetTurnDuelistVariable + ld b, STARTING_HAND_SIZE +.loop_deck_1 + ld a, [hli] + push bc + call LoadCardDataToBuffer1_FromDeckIndex + pop bc + ld a, [wLoadedCard1Type] + cp TYPE_ENERGY + jr c, .pokemon_card_1 + cp TYPE_TRAINER + jr z, .next_card_deck_1 + +; energy card + ld a, [wce08] + inc a + ld [wce08], a + jr .next_card_deck_1 + +.pokemon_card_1 + ld a, [wLoadedCard1Stage] + or a + jr nz, .next_card_deck_1 ; not basic + ld a, [wce06] + inc a + ld [wce06], a + +.next_card_deck_1 + dec b + jr nz, .loop_deck_1 + +; tally the number of Energy and basic Pokemon cards +; and if any of them is smaller than 2, re-shuffle deck. + ld a, [wce06] + cp 2 + jr c, .shuffle_deck + ld a, [wce08] + cp 2 + jr c, .shuffle_deck + +; now check the following 6 cards (prize cards). +; re-shuffle deck if any of these cards is listed in wAICardListAvoidPrize. + ld b, 6 +.check_card_ids + ld a, [hli] + push bc + call .CheckIfIDIsInList + pop bc + jr c, .shuffle_deck + dec b + jr nz, .check_card_ids + +; finally, check 6 cards after that. +; if Energy or Basic Pokemon counter is below 4 +; (counting with the ones found in the initial hand) +; then re-shuffle deck. + ld b, 6 +.loop_deck_2 + ld a, [hli] + push bc + call LoadCardDataToBuffer1_FromDeckIndex + pop bc + ld a, [wLoadedCard1Type] + cp TYPE_ENERGY + jr c, .pokemon_card_2 + cp TYPE_TRAINER + jr z, .next_card_deck_2 + +; energy card + ld a, [wce08] + inc a + ld [wce08], a + jr .next_card_deck_2 + +.pokemon_card_2 + ld a, [wLoadedCard1Stage] + or a + jr nz, .next_card_deck_2 + ld a, [wce06] + inc a + ld [wce06], a + +.next_card_deck_2 + dec b + jr nz, .loop_deck_2 + + ld a, [wce06] + cp 4 + jp c, .shuffle_deck + ld a, [wce08] + cp 4 + jp c, .shuffle_deck + +; draw new set of hand cards + ld a, DUELVARS_DECK_CARDS + call GetTurnDuelistVariable + ld b, STARTING_HAND_SIZE +.draw_loop + ld a, [hli] + call SearchCardInDeckAndAddToHand + call AddCardToHand + dec b + jr nz, .draw_loop + ret +; 0x17366 + +; expectation: return carry if card ID corresponding +; to the input deck index is listed in wAICardListAvoidPrize; +; reality: always returns no carry because when checking terminating +; byte in wAICardListAvoidPrize ($00), it wrongfully uses 'cp a' instead of 'or a', +; so it always ends up returning in the first item in list. +; input: +; - a = deck index of card to check +.CheckIfIDIsInList ; 17366 (5:7366) + ld b, a + ld a, [wAICardListAvoidPrize + 1] + or a + ret z ; null + push hl + ld h, a + ld a, [wAICardListAvoidPrize] + ld l, a + + ld a, b + call GetCardIDFromDeckIndex +.loop_id_list + ld a, [hli] + cp a ; bug, should be 'or a' + jr z, .false + cp e + jr nz, .loop_id_list + +; true + pop hl + scf + ret +.false + pop hl + or a + ret +; 0x17383 ; returns carry if Pokemon at PLAY_AREA* in a ; can damage defending Pokémon with any of its moves @@ -6591,7 +6922,7 @@ CheckIfCanDamageDefendingPokemon: ; 17383 (5:7383) ; sets carry if any on the moves knocks out ; also outputs the largest damage dealt in a ; input: -; [hTempPlayAreaLocation_ff9d] = locaion of card to check +; [hTempPlayAreaLocation_ff9d] = location of card to check ; output: ; a = largest damage of both moves ; carry set if can knock out @@ -6713,8 +7044,8 @@ CheckIfNotABossDeckID: ; 17426 (5:7426) ; - 25% for all other decks; ; - 0% for boss decks. ; used for certain decks to randomly choose -; not to play Trainer card in hand. -ChooseRandomlyNotToPlayTrainerCard: ; 1743b (5:743b) +; not to play Trainer card or use PKMN Power +AIChooseRandomlyNotToDoAction: ; 1743b (5:743b) ; boss decks always use Trainer cards. push hl push de @@ -6825,7 +7156,7 @@ CheckForBenchIDAtHalfHPAndCanUseSecondMove: ; 17474 (5:7474) ret ; 0x174cd -; add 5 to wcde4 AI score corresponding to all cards +; add 5 to wPlayAreaEnergyAIScore AI score corresponding to all cards ; in bench that have same ID as register a ; input: ; a = card ID to look for @@ -6848,7 +7179,7 @@ RaiseAIScoreToAllMatchingIDsInBench: ; 174cd (5:74cd) ld c, e ld b, $00 push hl - ld hl, wcde4 + ld hl, wPlayAreaEnergyAIScore add hl, bc ld a, 5 add [hl] @@ -6860,8 +7191,8 @@ RaiseAIScoreToAllMatchingIDsInBench: ; 174cd (5:74cd) ; goes through each play area Pokémon, and ; for all cards of the same ID, determine which ; card has highest value calculated from Func_17583 -; the card with highest value gets increased wcde4 -; while all others get decreased wcde4 +; the card with highest value gets increased wPlayAreaEnergyAIScore +; while all others get decreased wPlayAreaEnergyAIScore Func_174f2: ; 174f2 (5:74f2) ld a, MAX_PLAY_AREA_POKEMON ld hl, wcdfa @@ -6880,6 +7211,7 @@ Func_174f2: ; 174f2 (5:74f2) ld a, [hli] cp $ff ret z + ld [wcdf9], a push de push hl @@ -6945,11 +7277,11 @@ Func_174f2: ; 174f2 (5:74f2) jr .loop_2 ; c = play area location of highest score -; decrease wcde4 score for all cards with same ID +; decrease wPlayAreaEnergyAIScore score for all cards with same ID ; except for the one with highest score -; increase wcde4 score for card with highest ID +; increase wPlayAreaEnergyAIScore score for card with highest ID .asm_17560 - ld hl, wcde4 + ld hl, wPlayAreaEnergyAIScore ld de, wcdea ld b, PLAY_AREA_ARENA .loop_3 diff --git a/src/engine/bank07.asm b/src/engine/bank07.asm index 7a2d90a..45cc8b1 100644 --- a/src/engine/bank07.asm +++ b/src/engine/bank07.asm @@ -35,13 +35,13 @@ Func_1c056: ; 1c056 (7:4056) inc hl inc hl ld a, [hli] - ld [wd0bb], a + ld [wTempMap], a ld a, [hli] - ld [wd0bc], a + ld [wTempPlayerXCoord], a ld a, [hli] - ld [wd0bd], a - ld a, [wd334] - ld [wd0be], a + ld [wTempPlayerYCoord], a + ld a, [wPlayerDirection] + ld [wTempPlayerDirection], a .asm_1c095 pop de pop bc @@ -93,11 +93,11 @@ INCLUDE "data/map_headers.asm" Func_1c440: ; 1c440 (7:4440) INCROM $1c440, $1c455 -Func_1c455: ; 1c455 (7:4455) +GetNPCDirection: ; 1c455 (7:4455) push hl - ld a, [wd3aa] - ld l, $4 - call Func_39ad + ld a, [wLoadedNPCTempIndex] + ld l, LOADED_NPC_DIRECTION + call GetItemInLoadedNPCIndex ld a, [hl] pop hl ret @@ -106,9 +106,9 @@ Func_1c461: ; 1c461 (7:4461) push hl push bc call Func_1c719 - ld a, [wd3aa] - ld l, $2 - call Func_39ad + ld a, [wLoadedNPCTempIndex] + ld l, LOADED_NPC_COORD_X + call GetItemInLoadedNPCIndex ld a, b ld [hli], a ld [hl], c @@ -119,23 +119,98 @@ Func_1c461: ; 1c461 (7:4461) Func_1c477: ; 1c477 (7:4477) push hl - ld a, [wd3aa] - ld l, $2 - call Func_39ad + ld a, [wLoadedNPCTempIndex] + ld l, LOADED_NPC_COORD_X + call GetItemInLoadedNPCIndex ld a, [hli] ld b, a ld c, [hl] pop hl ret +; Loads NPC Sprite Data Func_1c485: ; 1c485 (7:4485) - INCROM $1c485, $1c50a + push hl + push bc + push de + xor a + ld [wLoadedNPCTempIndex], a + ld b, a + ld c, LOADED_NPC_MAX + ld hl, wLoadedNPCs + ld de, LOADED_NPC_LENGTH +.findEmptyIndexLoop + ld a, [hl] + or a + jr z, .foundEmptyIndex + add hl, de + inc b + dec c + jr nz, .findEmptyIndexLoop + ld hl, wLoadedNPCs + debug_ret + jr .exit +.foundEmptyIndex + ld a, b + ld [wLoadedNPCTempIndex], a + ld a, [wd3b3] + farcall CreateSpriteAndAnimBufferEntry + jr c, .exit + ld a, [wLoadedNPCTempIndex] + call GetLoadedNPCID + push hl + ld a, [wTempNPC] + ld [hli], a + ld a, [wWhichSprite] + ld [hli], a + ld a, [wLoadNPCXPos] + ld [hli], a + ld a, [wLoadNPCYPos] + ld [hli], a + ld a, [wLoadNPCDirection] + ld [hli], a + ld a, [wd3b2] + ld [hli], a + ld a, [wd3b1] + ld [hli], a + ld a, [wLoadNPCDirection] + ld [hli], a + call Func_1c58e + call Func_1c5b9 + ld hl, wd349 + inc [hl] + pop hl + call Func_1c665 + call Func_1c6e3 + ld a, [wTempNPC] + call Func_1c4fa + jr nc, .exit + ld a, $01 + ld [wd3b8], a +.exit + pop de + pop bc + pop hl + ret + +Func_1c4fa: ; 1c4fa (7:44fa) + cp NPC_RONALD1 + jr z, .asm_1c508 + cp NPC_RONALD2 + jr z, .asm_1c508 + cp NPC_RONALD3 + jr z, .asm_1c508 + or a + ret +.asm_1c508 + scf + ret Func_1c50a: ; 1c50a (7:450a) push hl call Func_1c719 - ld a, [wd3aa] - call Func_39a7 + ld a, [wLoadedNPCTempIndex] + call GetLoadedNPCID ld a, [hl] or a jr z, .asm_1c52c @@ -159,9 +234,9 @@ Func_1c50a: ; 1c50a (7:450a) Func_1c52e: ; 1c52e (7:452e) push hl push af - ld a, [wd3aa] - ld l, $7 - call Func_39ad + ld a, [wLoadedNPCTempIndex] + ld l, LOADED_NPC_FIELD_07 + call GetItemInLoadedNPCIndex pop af ld [hl], a call Func_1c5e9 @@ -171,9 +246,9 @@ Func_1c52e: ; 1c52e (7:452e) Func_1c53f: ; 1c53f (7:453f) push hl push bc - ld a, [wd3aa] - ld l, $4 - call Func_39ad + ld a, [wLoadedNPCTempIndex] + ld l, LOADED_NPC_DIRECTION + call GetItemInLoadedNPCIndex ld a, [hl] ld bc, $0003 add hl, bc @@ -188,23 +263,23 @@ Func_1c53f: ; 1c53f (7:453f) Func_1c557: ; 1c557 (7:4557) push bc ld c, a - ld a, [wd3aa] + ld a, [wLoadedNPCTempIndex] push af - ld a, [wd3ab] + ld a, [wTempNPC] push af ld a, c - ld [wd3ab], a + ld [wTempNPC], a ld c, $0 - call Func_39c3 + call FindLoadedNPC jr c, .asm_1c570 call Func_1c53f ld c, a .asm_1c570 pop af - ld [wd3ab], a + ld [wTempNPC], a pop af - ld [wd3aa], a + ld [wLoadedNPCTempIndex], a ld a, c pop bc ret @@ -213,9 +288,9 @@ Func_1c57b: ; 1c57b (7:457b) push hl push bc push af - ld a, [wd3aa] - ld l, $6 - call Func_39ad + ld a, [wLoadedNPCTempIndex] + ld l, LOADED_NPC_FIELD_06 + call GetItemInLoadedNPCIndex pop af ld [hl], a call Func_1c58e @@ -224,13 +299,76 @@ Func_1c57b: ; 1c57b (7:457b) ret Func_1c58e: ; 1c58e (7:458e) - INCROM $1c58e, $1c5e9 + push hl + push bc + ld a, [wWhichSprite] + push af + ld a, [wLoadedNPCTempIndex] + call GetLoadedNPCID + ld a, [hli] + or a + jr z, .quit + ld a, [hl] + ld [wWhichSprite], a + ld bc, LOADED_NPC_FIELD_06 - LOADED_NPC_SPRITE + add hl, bc + ld a, [hld] + bit 4, [hl] + jr nz, .asm_1c5ae + dec hl + add [hl] + inc hl +.asm_1c5ae + farcall Func_12ab5 +.quit + pop af + ld [wWhichSprite], a + pop bc + pop hl + ret +; 0x1c5b9 + +Func_1c5b9: ; 1c5b9 (7:45b9) + INCROM $1c5b9, $1c5e9 Func_1c5e9: ; 1c5e9 (7:45e9) - INCROM $1c5e9, $1c610 + push hl + push bc + ld a, [wLoadedNPCTempIndex] + ld l, LOADED_NPC_FIELD_07 + call GetItemInLoadedNPCIndex + ld a, [hl] + ld bc, $fffd + add hl, bc + ld [hl], a + call Func_1c58e + pop bc + pop hl + ret +; 0x1c5ff + + INCROM $1c5ff, $1c610 Func_1c610: ; 1c610 (7:4610) - INCROM $1c610, $1c6f8 + INCROM $1c610, $1c665 + +Func_1c665: ; 1c665 (7:4665) + INCROM $1c665, $1c6e3 + +Func_1c6e3: ; 1c6e3 (7:46e3) + push hl + push bc + ld a, [wLoadedNPCTempIndex] + ld l, LOADED_NPC_COORD_X + call GetItemInLoadedNPCIndex + ld a, [hli] + ld b, a + ld c, [hl] + ld a, $40 + call SetPermissionOfMapPosition + pop bc + pop hl + ret Func_1c6f8: ; 1c6f8 (7:46f8) INCROM $1c6f8, $1c719 @@ -238,9 +376,9 @@ Func_1c6f8: ; 1c6f8 (7:46f8) Func_1c719: ; 1c719 (7:4719) push hl push bc - ld a, [wd3aa] - ld l, $2 - call Func_39ad + ld a, [wLoadedNPCTempIndex] + ld l, LOADED_NPC_COORD_X + call GetItemInLoadedNPCIndex ld a, [hli] ld b, a ld c, [hl] @@ -250,36 +388,85 @@ Func_1c719: ; 1c719 (7:4719) pop hl ret -Func_1c72e: ; 1c72e (7:472e) - INCROM $1c72e, $1c768 +; Find NPC at coords b (x) c (y) +FindNPCAtLocation: ; 1c72e (7:472e) + push hl + push bc + push de + ld d, $00 + ld e, LOADED_NPC_MAX + ld hl, wLoadedNPC1CoordX +.findValidNPCLoop + ld a, [hli] + cp b + jr nz, .noValidNPCHere + ld a, [hl] + cp c + jr nz, .noValidNPCHere + push hl + inc hl + inc hl + bit 6, [hl] + pop hl + jr nz, .noValidNPCHere + push hl + dec hl + dec hl + ld a, [hl] + or a + pop hl + jr nz, .foundNPCExit +.noValidNPCHere + ld a, LOADED_NPC_LENGTH - 1 + add l + ld l, a + ld a, h + adc $00 + ld h, a + inc d + dec e + jr nz, .findValidNPCLoop + scf + jr .exit +.foundNPCExit + ld a, d + ld [wLoadedNPCTempIndex], a + or a +.exit + pop de + pop bc + pop hl + ret -Func_1c768: ; 1c768 (7:4768) +; Probably needs a new name. Loads data for NPC that the next Script is for +; Sets direction, Loads Image data for it, loads name, and more +SetNewScriptNPC: ; 1c768 (7:4768) push hl - ld a, [wd3aa] - ld l, $04 - call Func_39ad - ld a, [wd334] + ld a, [wLoadedNPCTempIndex] + ld l, LOADED_NPC_DIRECTION + call GetItemInLoadedNPCIndex + ld a, [wPlayerDirection] xor $02 ld [hl], a call Func_1c58e ld a, $02 farcall Func_c29b - ld a, [wd3aa] - call Func_39a7 + ld a, [wLoadedNPCTempIndex] + call GetLoadedNPCID ld a, [hl] - farcall Func_1187d + farcall GetNPCNameAndScript pop hl ret Func_1c78d: ; 1c78d (7:478d) push hl - ld a, [wd3aa] - ld l, $5 - call Func_39ad + ld a, [wLoadedNPCTempIndex] + ld l, LOADED_NPC_FIELD_05 + call GetItemInLoadedNPCIndex set 5, [hl] - ld a, [wd3aa] - ld l, $8 - call Func_39ad + ld a, [wLoadedNPCTempIndex] + ld l, LOADED_NPC_FIELD_08 + call GetItemInLoadedNPCIndex xor a ld [hli], a .asm_1c7a2 @@ -319,9 +506,9 @@ Func_1c78d: ; 1c78d (7:478d) jr .asm_1c7a2 .asm_1c7d2 - ld a, [wd3aa] - ld l, $5 - call Func_39ad + ld a, [wLoadedNPCTempIndex] + ld l, LOADED_NPC_FIELD_05 + call GetItemInLoadedNPCIndex res 5, [hl] .asm_1c7dc @@ -429,7 +616,7 @@ Func_1c8ef: ; 1c8ef (7:48ef) ld c, a pop hl - call PushBC_Ret ; call bc + call CallBC .return pop de pop bc @@ -451,7 +638,7 @@ Func_1c94a: dec c jr nz, .loop ld a, [hli] - farcall Func_1299f + farcall CreateSpriteAndAnimBufferEntry ld a, [wWhichSprite] ld [wAnimationQueue], a ; push an animation to the queue xor a @@ -887,7 +1074,7 @@ Credits_1d6ad: ; 1d6ad (7:56ad) ld a, [wd633] cp $ff jr nz, .asm_1d6c8 - call Func_3c96 + call WaitForSongToFinish ld a, $8 farcall $4, $6863 ld a, MUSIC_STOP diff --git a/src/engine/bank08.asm b/src/engine/bank08.asm index 5a0f535..1bb06a3 100644 --- a/src/engine/bank08.asm +++ b/src/engine/bank08.asm @@ -114,7 +114,7 @@ _AIProcessHandTrainerCards: ; 200e5 (8:40e5) jp c, .next_in_data ; AI can randomly choose not to play card. - farcall ChooseRandomlyNotToPlayTrainerCard + farcall AIChooseRandomlyNotToDoAction jr c, .next_in_data ; call routine to decide whether to play Trainer card @@ -3589,9 +3589,9 @@ AIPlay_Pokedex: ; 212b4 (8:52b4) ; 0x212dc AIDecide_Pokedex: ; 212dc (8:52dc) - ld a, [wcda6] - cp $06 - jr c, .no_carry + ld a, [wAIPokedexCounter] + cp 5 + 1 + jr c, .no_carry ; return if counter hasn't reached 6 yet ; return no carry if number of cards in deck <= 4 ld a, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK @@ -3624,7 +3624,7 @@ AIDecide_Pokedex: ; 212dc (8:52dc) PickPokedexCards_Unreferenced: ; 212ff (8:52ff) ; unreferenced xor a - ld [wcda6], a + ld [wAIPokedexCounter], a ; reset counter ld a, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK call GetTurnDuelistVariable @@ -3756,7 +3756,7 @@ PickPokedexCards_Unreferenced: ; 212ff (8:52ff) ; stores the resulting order in wce1a. PickPokedexCards: ; 2138e (8:538e) xor a - ld [wcda6], a + ld [wAIPokedexCounter], a ; reset counter ; reset counter ld a, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK call GetTurnDuelistVariable @@ -4698,19 +4698,22 @@ AIPlay_Gambler: ; 2182d (8:582d) ; 0x21875 ; checks whether to play Gambler. -; aside from Imakuni, all other opponents only -; play if there's less than 4 cards in the deck. +; aside from Imakuni?, all other opponents only +; play this card if Player is running Mewtwo1-only deck. AIDecide_Gambler: ; 21875 (8:5875) ; Imakuni? has his own routine ld a, [wOpponentDeckID] cp IMAKUNI_DECK_ID jr z, .imakuni - ld a, [wcda7] - and $80 +; check if flag is set for Player using Mewtwo1 only deck + ld a, [wAIBarrierFlagCounter] + and AI_FLAG_MEWTWO_MILL jr z, .no_carry -; set carry if number of cards in deck <= 4 +; set carry if number of cards in deck <= 4. +; this is done to counteract the deck out strategy +; of Mewtwo1 deck, by replenishing the deck with hand cards. ld a, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK call GetTurnDuelistVariable cp DECK_SIZE - 4 @@ -6219,8 +6222,1319 @@ AIDecide_PokemonTrader_Flamethrower: ; 22133 (8:6133) ret ; 0x2219b -Func_2219b: ; 2219b (8:219b) - INCROM $2219b, $227f6 +; handle AI routines for Energy Trans. +; uses AI_ENERGY_TRANS_* constants as input: +; - AI_ENERGY_TRANS_RETREAT: transfers enough Grass Energy cards to +; Arena Pokemon for it to be able to pay the Retreat Cost; +; - AI_ENERGY_TRANS_ATTACK: transfers enough Grass Energy cards to +; Arena Pokemon for it to be able to use its second attack; +; - AI_ENERGY_TRANS_TO_BENCH: transfers all Grass Energy cards from +; Arena Pokemon to Bench in case Arena card will be KO'd. +HandleAIEnergyTrans: ; 2219b (8:619b) + ld [wce06], a + +; choose to randomly return + farcall AIChooseRandomlyNotToDoAction + ret c + + ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA + call GetTurnDuelistVariable + dec a + ret z ; return if no Bench cards + + ld a, VENUSAUR2 + call CountPokemonIDInPlayArea + ret nc ; return if no Venusaur2 found in own Play Area + + ld a, MUK + call CountPokemonIDInBothPlayAreas + ret c ; return if Muk found in any Play Area + + ld a, [wce06] + cp AI_ENERGY_TRANS_RETREAT + jr z, .check_retreat + + cp AI_ENERGY_TRANS_TO_BENCH + jp z, AIEnergyTransTransferEnergyToBench + + ; AI_ENERGY_TRANS_ATTACK + call .CheckEnoughGrassEnergyCardsForAttack + ret nc + jr .TransferEnergyToArena + +.check_retreat + call .CheckEnoughGrassEnergyCardsForRetreatCost + ret nc + +; use Energy Trans to transfer number of Grass energy cards +; equal to input a from the Bench to the Arena card. +.TransferEnergyToArena + ld [wAINumberOfEnergyTransCards], a + +; look for Venusaur2 in Play Area +; so that its PKMN Power can be used. + ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA + call GetTurnDuelistVariable + dec a + ld b, a +.loop_play_area + ld a, DUELVARS_ARENA_CARD + add b + call GetTurnDuelistVariable + ldh [hTempCardIndex_ff9f], a + call GetCardIDFromDeckIndex + ld a, e + cp VENUSAUR2 + jr z, .use_pkmn_power + + ld a, b + or a + ret z ; return when finished Play Area loop + + dec b + jr .loop_play_area + +; use Energy Trans Pkmn Power +.use_pkmn_power + ld a, b + ldh [hTemp_ffa0], a + ld a, OPPACTION_USE_PKMN_POWER + bank1call AIMakeDecision + ld a, OPPACTION_EXECUTE_PKMN_POWER_EFFECT + bank1call AIMakeDecision + + xor a ; PLAY_AREA_ARENA + ldh [hAIEnergyTransPlayAreaLocation], a + ld a, [wAINumberOfEnergyTransCards] + ld d, a + +; look for Grass energy cards that +; are currently attached to a Bench card. + ld e, 0 +.loop_deck_locations + ld a, DUELVARS_CARD_LOCATIONS + add e + call GetTurnDuelistVariable + and %00011111 + cp CARD_LOCATION_BENCH_1 + jr c, .next_card + + and %00001111 + ldh [hTempPlayAreaLocation_ffa1], a + + ld a, e + push de + call GetCardIDFromDeckIndex + ld a, e + pop de + cp GRASS_ENERGY + jr nz, .next_card + + ; store the deck index of energy card + ld a, e + ldh [hAIEnergyTransEnergyCard], a + + push de + ld d, 30 +.small_delay_loop + call DoFrame + dec d + jr nz, .small_delay_loop + + ld a, OPPACTION_6B15 + bank1call AIMakeDecision + pop de + dec d + jr z, .done_transfer + +.next_card + inc e + ld a, DECK_SIZE + cp e + jr nz, .loop_deck_locations + +; transfer is done, perform delay +; and return to main scene. +.done_transfer + ld d, 60 +.big_delay_loop + call DoFrame + dec d + jr nz, .big_delay_loop + ld a, OPPACTION_DUEL_MAIN_SCENE + bank1call AIMakeDecision + ret +; 0x22246 + +; checks if the Arena card needs energy for its second attack, +; and if it does, return carry if transferring Grass energy from Bench +; would be enough to use it. Outputs number of energy cards needed in a. +.CheckEnoughGrassEnergyCardsForAttack ; 22246 (8:6246) + ld a, DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + call GetCardIDFromDeckIndex + ld a, e + cp EXEGGUTOR + jr z, .is_exeggutor + + xor a ; PLAY_AREA_ARENA + ldh [hTempPlayAreaLocation_ff9d], a + ld a, SECOND_ATTACK + ld [wSelectedAttack], a + farcall CheckEnergyNeededForAttack + jr nc, .attack_false ; return if no energy needed + +; check if colorless energy is needed... + ld a, c + or a + jr nz, .count_if_enough + +; ...otherwise check if basic energy card is needed +; and it's grass energy. + ld a, b + or a + jr z, .attack_false + ld a, e + cp GRASS_ENERGY + jr nz, .attack_false + ld c, b + jr .count_if_enough + +.attack_false + or a + ret + +.count_if_enough +; if there's enough Grass energy cards in Bench +; to satisfy the attack energy cost, return carry. + push bc + call .CountGrassEnergyInBench + pop bc + cp c + jr c, .attack_false + ld a, c + scf + ret + +.is_exeggutor +; in case it's Exeggutor in Arena, return carry +; if there are any Grass energy cards in Bench. + call .CountGrassEnergyInBench + or a + jr z, .attack_false + + scf + ret +; 0x22286 + +; outputs in a the number of Grass energy cards +; currently attached to Bench cards. +.CountGrassEnergyInBench ; 22286 (8:6286) + lb de, 0, 0 +.count_loop + ld a, DUELVARS_CARD_LOCATIONS + add e + call GetTurnDuelistVariable + and %00011111 + cp CARD_LOCATION_BENCH_1 + jr c, .count_next + +; is in bench + ld a, e + push de + call GetCardIDFromDeckIndex + ld a, e + pop de + cp GRASS_ENERGY + jr nz, .count_next + inc d +.count_next + inc e + ld a, DECK_SIZE + cp e + jr nz, .count_loop + ld a, d + ret +; 0x222a9 + +; returns carry if there are enough Grass energy cards in Bench +; to satisfy the retreat cost of the Arena card. +; if so, output the number of energy cards still needed in a. +.CheckEnoughGrassEnergyCardsForRetreatCost ; 222a9 (8:62a9) + xor a ; PLAY_AREA_ARENA + ldh [hTempPlayAreaLocation_ff9d], a + call GetPlayAreaCardRetreatCost + ld b, a + ld e, PLAY_AREA_ARENA + farcall CountNumberOfEnergyCardsAttached + cp b + jr nc, .retreat_false ; return if enough to retreat + +; see if there's enough Grass energy cards +; in the Bench to satisfy retreat cost + ld c, a + ld a, b + sub c + ld c, a + push bc + call .CountGrassEnergyInBench + pop bc + cp c + jr c, .retreat_false ; return if less cards than needed + +; output number of cards needed to retreat + ld a, c + scf + ret +.retreat_false + or a + ret +; 0x222ca + +; AI logic to determine whether to use Energy Trans Pkmn Power +; to transfer energy cards attached from the Arena Pokemon to +; some card in the Bench. +AIEnergyTransTransferEnergyToBench: ; 222ca (8:62ca) + xor a ; PLAY_AREA_ARENA + ldh [hTempPlayAreaLocation_ff9d], a + farcall CheckIfDefendingPokemonCanKnockOut + ret nc ; return if Defending can't KO + +; processes attacks and see if any attack would be used by AI. +; if so, return. + farcall AIProcessButDontUseAttack + ret c + +; return if Arena card has no Grass energy cards attached. + ld e, PLAY_AREA_ARENA + call GetPlayAreaCardAttachedEnergies + ld a, [wAttachedEnergies + GRASS] + or a + ret z + +; if no energy card attachment is needed, return. + farcall AIProcessButDontPlayEnergy_SkipEvolutionAndArena + ret nc + +; AI decided that an energy card is needed +; so look for Venusaur2 in Play Area +; so that its PKMN Power can be used. + ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA + call GetTurnDuelistVariable + dec a + ld b, a +.loop_play_area + ld a, DUELVARS_ARENA_CARD + add b + call GetTurnDuelistVariable + ldh [hTempCardIndex_ff9f], a + ld [wAIVenusaur2DeckIndex], a + call GetCardIDFromDeckIndex + ld a, e + cp VENUSAUR2 + jr z, .use_pkmn_power + + ld a, b + or a + ret z ; return when Play Area loop is ended + + dec b + jr .loop_play_area + +; use Energy Trans Pkmn Power +.use_pkmn_power + ld a, b + ldh [hTemp_ffa0], a + ld [wAIVenusaur2PlayAreaLocation], a + ld a, OPPACTION_USE_PKMN_POWER + bank1call AIMakeDecision + ld a, OPPACTION_EXECUTE_PKMN_POWER_EFFECT + bank1call AIMakeDecision + +; loop for each energy cards that are going to be transferred. +.loop_energy + xor a + ldh [hTempPlayAreaLocation_ffa1], a + ld a, [wAIVenusaur2PlayAreaLocation] + ldh [hTemp_ffa0], a + + ; returns when Arena card has no Grass energy cards attached. + ld e, PLAY_AREA_ARENA + call GetPlayAreaCardAttachedEnergies + ld a, [wAttachedEnergies + GRASS] + or a + jr z, .done_transfer + +; look for Grass energy cards that +; are currently attached to Arena card. + ld e, 0 +.loop_deck_locations + ld a, DUELVARS_CARD_LOCATIONS + add e + call GetTurnDuelistVariable + cp CARD_LOCATION_ARENA + jr nz, .next_card + + ld a, e + push de + call GetCardIDFromDeckIndex + ld a, e + pop de + cp GRASS_ENERGY + jr nz, .next_card + + ; store the deck index of energy card + ld a, e + ldh [hAIEnergyTransEnergyCard], a + jr .transfer + +.next_card + inc e + ld a, DECK_SIZE + cp e + jr nz, .loop_deck_locations + jr .done_transfer + +.transfer +; get the Bench card location to transfer Grass energy card to. + farcall AIProcessButDontPlayEnergy_SkipEvolutionAndArena + jr nc, .done_transfer + ldh a, [hTempPlayAreaLocation_ff9d] + ldh [hAIEnergyTransPlayAreaLocation], a + + ld d, 30 +.small_delay_loop + call DoFrame + dec d + jr nz, .small_delay_loop + + ld a, [wAIVenusaur2DeckIndex] + ldh [hTempCardIndex_ff9f], a + ld d, a + ld e, FIRST_ATTACK_OR_PKMN_POWER + call CopyMoveDataAndDamage_FromDeckIndex + ld a, OPPACTION_6B15 + bank1call AIMakeDecision + jr .loop_energy + +; transfer is done, perform delay +; and return to main scene. +.done_transfer + ld d, 60 +.big_delay_loop + call DoFrame + dec d + jr nz, .big_delay_loop + ld a, OPPACTION_DUEL_MAIN_SCENE + bank1call AIMakeDecision + ret +; 0x2237f + +; handles AI logic for using some Pkmn Powers. +; Pkmn Powers handled here are: +; - Heal; +; - Shift; +; - Peek; +; - Strange Behavior; +; - Curse. +; returns carry if turn ended. +HandleAIPkmnPowers: ; 2237f (8:637f) + ld a, MUK + call CountPokemonIDInBothPlayAreas + ccf + ret nc ; return no carry if Muk is in play + + farcall AIChooseRandomlyNotToDoAction + ccf + ret nc ; return no carry if AI randomly decides to + + ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA + call GetTurnDuelistVariable + ld b, a + ld c, PLAY_AREA_ARENA + ld a, DUELVARS_ARENA_CARD_STATUS + call GetTurnDuelistVariable + and CNF_SLP_PRZ + jr nz, .next_2 + +.loop_play_area + ld a, DUELVARS_ARENA_CARD + add c + call GetTurnDuelistVariable + ld [wce08], a + + push af + push bc + ld d, a + ld a, c + ldh [hTempPlayAreaLocation_ff9d], a + ld e, FIRST_ATTACK_OR_PKMN_POWER + call CopyMoveDataAndDamage_FromDeckIndex + ld a, [wLoadedMoveCategory] + cp POKEMON_POWER + jr z, .execute_effect + pop bc + jr .next_3 + +.execute_effect + ld a, EFFECTCMDTYPE_INITIAL_EFFECT_2 + bank1call TryExecuteEffectCommandFunction + pop bc + jr c, .next_3 + +; TryExecuteEffectCommandFunction was successful, +; so check what Pkmn Power this is through card's ID. + pop af + call GetCardIDFromDeckIndex + ld a, e + push bc + +; check heal + cp VILEPLUME + jr nz, .check_shift + call HandleAIHeal + jr .next_1 +.check_shift + cp VENOMOTH + jr nz, .check_peek + call HandleAIShift + jr .next_1 +.check_peek + cp MANKEY + jr nz, .check_strange_behavior + call HandleAIPeek + jr .next_1 +.check_strange_behavior + cp SLOWBRO + jr nz, .check_curse + call HandleAIStrangeBehavior + jr .next_1 +.check_curse + cp GENGAR + jr nz, .next_1 + call z, HandleAICurse + jr c, .done + +.next_1 + pop bc +.next_2 + inc c + ld a, c + cp b + jr nz, .loop_play_area + ret + +.next_3 + pop af + jr .next_2 + +.done + pop bc + ret +; 0x22402 + +; checks whether AI uses Heal on Pokemon in Play Area. +; input: +; c = Play Area location (PLAY_AREA_*) of Vileplume. +HandleAIHeal: ; 22402 (8:6402) + ld a, c + ldh [hTemp_ffa0], a + call .CheckHealTarget + ret nc ; return if no target to heal + push af + ld a, [wce08] + ldh [hTempCardIndex_ff9f], a + ld a, OPPACTION_USE_PKMN_POWER + bank1call AIMakeDecision + pop af + ldh [hAIHealCard], a + ld a, OPPACTION_EXECUTE_PKMN_POWER_EFFECT + bank1call AIMakeDecision + ld a, OPPACTION_DUEL_MAIN_SCENE + bank1call AIMakeDecision + ret +; 0x22422 + +; finds a target suitable for AI to use Heal on. +; only heals Arena card if the Defending Pokemon +; cannot KO it after Heal is used. +; returns carry if target was found and outputs +; in a the Play Area location of that card. +.CheckHealTarget ; 22422 (8:6422) +; check if Arena card has any damage counters, +; if not, check Bench instead. + ld e, PLAY_AREA_ARENA + call GetCardDamage + or a + jr z, .check_bench + + xor a ; PLAY_AREA_ARENA + ldh [hTempPlayAreaLocation_ff9d], a + farcall CheckIfDefendingPokemonCanKnockOut + jr nc, .set_carry ; return carry if can't KO + ld d, a + ld a, DUELVARS_ARENA_CARD_HP + call GetTurnDuelistVariable + ld h, a + ld e, PLAY_AREA_ARENA + call GetCardDamage + ; this seems useless since it was already + ; checked that Arena card has damage, + ; so card damage is at least 10. + cp 10 + 1 + jr c, .check_remaining + ld a, 10 + ; a = min(10, CardDamage) + +; checks if Defending Pokemon can still KO +; if Heal is used on this card. +; if Heal prevents KO, return carry. +.check_remaining + ld l, a + ld a, h ; load remaining HP + add l ; add 1 counter to account for heal + sub d ; subtract damage of strongest opponent attack + jr c, .check_bench + jr z, .check_bench + +.set_carry + xor a ; PLAY_AREA_ARENA + scf + ret + +; check Bench for Pokemon with damage counters +; and find the one with the most damage. +.check_bench + ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA + call GetTurnDuelistVariable + ld d, a + lb bc, 0, 0 + ld e, PLAY_AREA_BENCH_1 +.loop_bench + ld a, e + cp d + jr z, .done + push bc + call GetCardDamage + pop bc + cp b + jr c, .next_bench + jr z, .next_bench + ld b, a ; store this damage + ld c, e ; store this Play Area location +.next_bench + inc e + jr .loop_bench + +; check if a Pokemon with damage counters was found +; in the Bench and, if so, return carry. +.done + ld a, c + or a + jr z, .not_found +; found + scf + ret +.not_found + or a + ret +; 0x22476 + +; checks whether AI uses Shift. +; input: +; c = Play Area location (PLAY_AREA_*) of Venomoth +HandleAIShift: ; 22476 (8:6476) + ld a, c + or a + ret nz ; return if Venomoth is not Arena card + + ldh [hTemp_ffa0], a + call GetArenaCardColor + call TranslateColorToWR + ld b, a + call SwapTurn + call GetArenaCardWeakness + ld [wAIDefendingPokemonWeakness], a + call SwapTurn + or a + ret z ; return if Defending Pokemon has no weakness + and b + ret nz ; return if Venomoth is already Defending card's weakness type + +; check whether there's a card in play with +; the same color as the Player's card weakness + call .CheckWhetherTurnDuelistHasColor + jr c, .found + call SwapTurn + call .CheckWhetherTurnDuelistHasColor + call SwapTurn + ret nc ; return if no color found + +.found + ld a, [wce08] + ldh [hTempCardIndex_ff9f], a + ld a, OPPACTION_USE_PKMN_POWER + bank1call AIMakeDecision + +; converts WR_* to apropriate color + ld a, [wAIDefendingPokemonWeakness] + ld b, 0 +.loop_color + bit 7, a + jr nz, .done + inc b + rlca + jr .loop_color + +; use Pkmn Power effect +.done + ld a, b + ldh [hAIPkmnPowerEffectParam], a + ld a, OPPACTION_EXECUTE_PKMN_POWER_EFFECT + bank1call AIMakeDecision + ld a, OPPACTION_DUEL_MAIN_SCENE + bank1call AIMakeDecision + ret +; 0x224c6 + +; returns carry if turn Duelist has a Pokemon +; with same color as wAIDefendingPokemonWeakness. +.CheckWhetherTurnDuelistHasColor ; 224c6 (8:64c6) + ld a, [wAIDefendingPokemonWeakness] + ld b, a + ld a, DUELVARS_ARENA_CARD + call GetTurnDuelistVariable +.loop_play_area + ld a, [hli] + cp $ff + jr z, .false + push bc + call GetCardIDFromDeckIndex + call GetCardType + call TranslateColorToWR + pop bc + and b + jr z, .loop_play_area +; true + scf + ret +.false + or a + ret +; 0x224e6 + +; checks whether AI uses Peek. +; input: +; c = Play Area location (PLAY_AREA_*) of Mankey. +HandleAIPeek: ; 224e6 (8:64e6) + ld a, c + ldh [hTemp_ffa0], a + ld a, 50 + call Random + cp 3 + ret nc ; return 47 out of 50 times + +; choose what to use Peek on at random + ld a, 3 + call Random + or a + jr z, .check_player_prizes + cp 2 + jr c, .check_player_hand + +; check Player's Deck + ld a, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK + call GetNonTurnDuelistVariable + cp DECK_SIZE - 1 + ret nc ; return if Player has one or no cards in Deck + ld a, $ff + jr .use_peek + +.check_player_prizes + ld a, DUELVARS_PRIZES + call GetTurnDuelistVariable + ld hl, wcda5 + and [hl] + ld [hl], a + or a + ret z ; return if no prizes + + ld c, a + ld b, $1 + ld d, 0 +.loop_prizes + ld a, c + and b + jr nz, .found_prize + sla b + inc d + jr .loop_prizes +.found_prize +; remove this prize's flag from the prize list +; and use Peek on first one in list (lowest bit set) + ld a, c + sub b + ld [hl], a + ld a, $40 + add d + jr .use_peek + +.check_player_hand + call SwapTurn + call CreateHandCardList + call SwapTurn + or a + ret z ; return if no cards in Hand +; shuffle list and pick the first entry to Peek + ld hl, wDuelTempList + call CountCardsInDuelTempList + call ShuffleCards + ld a, [wDuelTempList] + or $80 + +.use_peek + push af + ld a, [wce08] + ldh [hTempCardIndex_ff9f], a + ld a, OPPACTION_USE_PKMN_POWER + bank1call AIMakeDecision + pop af + ldh [hAIPkmnPowerEffectParam], a + ld a, OPPACTION_EXECUTE_PKMN_POWER_EFFECT + bank1call AIMakeDecision + ld a, OPPACTION_DUEL_MAIN_SCENE + bank1call AIMakeDecision + ret +; 0x2255d + +; checks whether AI uses Strange Behavior. +; input: +; c = Play Area location (PLAY_AREA_*) of Slowbro. +HandleAIStrangeBehavior: ; 2255d (8:655d) + ld a, c + or a + ret z ; return if Slowbro is Arena card + + ldh [hTemp_ffa0], a + ld e, PLAY_AREA_ARENA + call GetCardDamage + or a + ret z ; return if Arena card has no damage counters + + ld [wce06], a + ldh a, [hTemp_ffa0] + add DUELVARS_ARENA_CARD_HP + call GetTurnDuelistVariable + sub 10 + ret z ; return if Slowbro has only 10 HP remaining + +; if Slowbro can't receive all damage counters, +; only transfer remaining HP - 10 damage + ld hl, wce06 + cp [hl] + jr c, .use_strange_behavior + ld a, [hl] ; can receive all damage counters + +.use_strange_behavior + push af + ld a, [wce08] + ldh [hTempCardIndex_ff9f], a + ld a, OPPACTION_USE_PKMN_POWER + bank1call AIMakeDecision + xor a + ldh [hAIPkmnPowerEffectParam], a + ld a, OPPACTION_EXECUTE_PKMN_POWER_EFFECT + bank1call AIMakeDecision + pop af + +; loop counters chosen to transfer and use Pkmn Power + call ConvertHPToCounters + ld e, a +.loop_counters + ld d, 30 +.small_delay_loop + call DoFrame + dec d + jr nz, .small_delay_loop + push de + ld a, OPPACTION_6B15 + bank1call AIMakeDecision + pop de + dec e + jr nz, .loop_counters + +; return to main scene + ld d, 60 +.big_delay_loop + call DoFrame + dec d + jr nz, .big_delay_loop + ld a, OPPACTION_DUEL_MAIN_SCENE + bank1call AIMakeDecision + ret +; 0x225b5 + +; checks whether AI uses Curse. +; input: +; c = Play Area location (PLAY_AREA_*) of Gengar. +HandleAICurse: ; 225b5 (8:65b5) + ld a, c + ldh [hTemp_ffa0], a + +; loop Player's Play Area and checks their damage. +; finds the card with lowest remaining HP and +; stores its HP and its Play Area location + ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA + call GetNonTurnDuelistVariable + ld d, a + ld e, PLAY_AREA_ARENA + lb bc, 0, $ff + ld h, PLAY_AREA_ARENA + call SwapTurn +.loop_play_area_1 + push bc + call GetCardDamage + pop bc + or a + jr z, .next_1 + + inc b + ld a, e + add DUELVARS_ARENA_CARD_HP + push hl + call GetTurnDuelistVariable + pop hl + cp c + jr nc, .next_1 + ; lower HP than one stored + ld c, a ; store this HP + ld h, e ; store this Play Area location + +.next_1 + inc e + ld a, e + cp d + jr nz, .loop_play_area_1 ; reached end of Play Area + + ld a, 1 + cp b + jr nc, .failed ; return if less than 2 cards with damage + +; card in Play Area with lowest HP remaining was found. +; look for another card to take damage counter from. + ld a, h + ldh [hTempRetreatCostCards], a + ld b, a + ld a, 10 + cp c + jr z, .hp_10_remaining + ; if has more than 10 HP remaining, + ; skip Arena card in choosing which + ; card to take damage counter from. + ld e, PLAY_AREA_BENCH_1 + jr .second_card + +.hp_10_remaining + ; if Curse can KO, then include + ; Player's Arena card to take + ; damage counter from. + ld e, PLAY_AREA_ARENA + +.second_card + ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA + call GetTurnDuelistVariable + ld d, a +.loop_play_area_2 + ld a, e + cp b + jr z, .next_2 ; skip same Pokemon card + push bc + call GetCardDamage + pop bc + jr nz, .use_curse ; has damage counters, choose this card +.next_2 + inc e + ld a, e + cp d + jr nz, .loop_play_area_2 + +.failed + call SwapTurn + or a + ret + +.use_curse + ld a, e + ldh [hAIPkmnPowerEffectParam], a + call SwapTurn + ld a, [wce08] + ldh [hTempCardIndex_ff9f], a + ld a, OPPACTION_USE_PKMN_POWER + bank1call AIMakeDecision + ld a, OPPACTION_EXECUTE_PKMN_POWER_EFFECT + bank1call AIMakeDecision + ld a, OPPACTION_DUEL_MAIN_SCENE + bank1call AIMakeDecision + ret +; 0x2262d + +; handles AI logic for Cowardice +HandleAICowardice: ; 2262d (8:662d) + ld a, MUK + call CountPokemonIDInBothPlayAreas + ret c ; return if there's Muk in play + + farcall AIChooseRandomlyNotToDoAction + ret c ; randomly return + + ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA + call GetTurnDuelistVariable + cp 1 + ret z ; return if only one Pokemon in Play Area + + ld b, a + ld c, PLAY_AREA_ARENA + ld a, DUELVARS_ARENA_CARD_STATUS + call GetTurnDuelistVariable + and CNF_SLP_PRZ + jr nz, .next +.loop + ld a, DUELVARS_ARENA_CARD + add c + call GetTurnDuelistVariable + ld [wce08], a + call GetCardIDFromDeckIndex + ld a, e + push bc + cp TENTACOOL + call z, .CheckWhetherToUseCowardice + pop bc + jr nc, .next + + dec b ; subtract 1 from number of Pokemon in Play Area + ld a, 1 + cp b + ret z ; return if no longer has Bench Pokemon + ld c, PLAY_AREA_ARENA ; reset back to Arena + jr .loop + +.next + inc c + ld a, c + cp b + jr nz, .loop + ret +; 0x22671 + +; checks whether AI uses Cowardice. +; return carry if Pkmn Power was used. +; input: +; c = Play Area location (PLAY_AREA_*) of Tentacool. +.CheckWhetherToUseCowardice ; 22671 (8:6671) + ld a, c + ldh [hTemp_ffa0], a + ld e, a + call GetCardDamage +.asm_22678 + or a + ret z ; return if has no damage counters + + ldh a, [hTemp_ffa0] + or a + jr nz, .is_benched + + ; this part is buggy if AIDecideBenchPokemonToSwitchTo returns carry + ; but since this was already checked beforehand, this never happens. + ; so jr c, .asm_22678 can be safely removed. + farcall AIDecideBenchPokemonToSwitchTo + jr c, .asm_22678 ; bug, this jumps in the middle of damage checking + jr .use_cowardice +.is_benched + ld a, $ff +.use_cowardice + push af + ld a, [wce08] + ldh [hTempCardIndex_ff9f], a + ld a, OPPACTION_USE_PKMN_POWER + bank1call AIMakeDecision + pop af + ldh [hAIPkmnPowerEffectParam], a + ld a, OPPACTION_EXECUTE_PKMN_POWER_EFFECT + bank1call AIMakeDecision + ld a, OPPACTION_DUEL_MAIN_SCENE + bank1call AIMakeDecision + scf + ret +; 0x226a3 + +; AI logic for Damage Swap to transfer damage from Arena card +; to a card in Bench with more than 10 HP remaining +; and with no energy cards attached. +HandleAIDamageSwap: ; 226a3 (8:66a3) + ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA + call GetTurnDuelistVariable + dec a + ret z ; return if no Bench Pokemon + + farcall AIChooseRandomlyNotToDoAction + ret c + + ld a, ALAKAZAM + call CountPokemonIDInPlayArea + ret nc ; return if no Alakazam + ld a, MUK + call CountPokemonIDInBothPlayAreas + ret c ; return if there's Muk in play + +; only take damage off certain cards in Arena + ld a, DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + call GetCardIDFromDeckIndex + ld a, e + cp ALAKAZAM + jr z, .ok + cp KADABRA + jr z, .ok + cp ABRA + jr z, .ok + cp MR_MIME + ret nz + +.ok + ld e, PLAY_AREA_ARENA + call GetCardDamage + or a + ret z ; return if no damage + + call ConvertHPToCounters + ld [wce06], a + ld a, ALAKAZAM + ld b, PLAY_AREA_BENCH_1 + farcall LookForCardIDInPlayArea_Bank5 + jr c, .is_in_bench + +; Alakazam is Arena card + xor a +.is_in_bench + ld [wce08], a + call .CheckForDamageSwapTargetInBench + ret c ; return if not found + +; use Damage Swap + ld a, [wce08] + add DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + ldh [hTempCardIndex_ff9f], a + ld a, [wce08] + ldh [hTemp_ffa0], a + ld a, OPPACTION_USE_PKMN_POWER + bank1call AIMakeDecision + ld a, OPPACTION_EXECUTE_PKMN_POWER_EFFECT + bank1call AIMakeDecision + + ld a, [wce06] + ld e, a +.loop_damage + ld d, 30 +.small_delay_loop + call DoFrame + dec d + jr nz, .small_delay_loop + + push de + call .CheckForDamageSwapTargetInBench + jr c, .no_more_target + + ldh [hTempRetreatCostCards], a + xor a ; PLAY_AREA_ARENA + ldh [hAIPkmnPowerEffectParam], a + ld a, OPPACTION_6B15 + bank1call AIMakeDecision + pop de + dec e + jr nz, .loop_damage + +.done +; return to main scene + ld d, 60 +.big_delay_loop + call DoFrame + dec d + jr nz, .big_delay_loop + ld a, OPPACTION_DUEL_MAIN_SCENE + bank1call AIMakeDecision + ret + +.no_more_target + pop de + jr .done +; 0x2273c + +; looks for a target in the bench to receive damage counters. +; returns carry if one is found, and outputs remaining HP in a. +.CheckForDamageSwapTargetInBench ; 2273c (8:673c) + ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA + call GetTurnDuelistVariable + ld b, a + ld c, PLAY_AREA_BENCH_1 + lb de, $ff, $ff + +; look for candidates in bench to get the damage counters +; only target specific card IDs. +.loop_bench + ld a, c + add DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + push de + call GetCardIDFromDeckIndex + ld a, e + pop de + cp CHANSEY + jr z, .found_candidate + cp KANGASKHAN + jr z, .found_candidate + cp SNORLAX + jr z, .found_candidate + cp MR_MIME + jr z, .found_candidate + +.next_play_area + inc c + ld a, c + cp b + jr nz, .loop_bench + +; done + ld a, e + cp $ff + jr nz, .no_carry + ld a, d + cp $ff + jr z, .set_carry +.no_carry + or a + ret + +.found_candidate +; found a potential candidate to receive damage counters + ld a, DUELVARS_ARENA_CARD_HP + add c + call GetTurnDuelistVariable + cp 20 + jr c, .next_play_area ; ignore cards with only 10 HP left + + ld d, c ; store damage + push de + push bc + ld e, c + farcall CountNumberOfEnergyCardsAttached + pop bc + pop de + or a + jr nz, .next_play_area ; ignore cards with attached energy + ld e, c ; store deck index + jr .next_play_area + +.set_carry + scf + ret +; 0x22790 + +; handles AI logic for attaching energy cards +; in Go Go Rain Dance deck. +HandleAIGoGoRainDanceEnergy: ; 22790 (8:6790) + ld a, [wOpponentDeckID] + cp GO_GO_RAIN_DANCE_DECK_ID + ret nz ; return if not Go Go Rain Dance deck + + ld a, BLASTOISE + call CountPokemonIDInPlayArea + ret nc ; return if no Blastoise + ld a, MUK + call CountPokemonIDInBothPlayAreas + ret c ; return if there's Muk in play + +; play all the energy cards that is needed. +.loop + farcall AIProcessAndTryToPlayEnergy + jr c, .loop + ret +; 0x227a9 + +; runs through Player's whole deck and +; sets carry if there's any Pokemon other +; than Mewtwo1. +CheckIfPlayerHasPokemonOtherThanMewtwo1: ; 227a9 (8:67a9) + call SwapTurn + ld e, 0 +.loop_deck + ld a, e + push de + call LoadCardDataToBuffer2_FromDeckIndex + pop de + ld a, [wLoadedCard2Type] + cp TYPE_ENERGY + jp nc, .next ; can be a jr + ld a, [wLoadedCard2ID] + cp MEWTWO1 + jr nz, .not_mewtwo1 +.next + inc e + ld a, DECK_SIZE + cp e + jr nz, .loop_deck + +; no carry + call SwapTurn + or a + ret + +.not_mewtwo1 + call SwapTurn + scf + ret +; 0x227d3 + +; returns no carry if, given the Player is using a Mewtwo1 mill deck, +; the AI already has a Bench fully set up, in which case it +; will process some Trainer cards in hand (namely Energy Removals). +; this is used to check whether to skip some normal AI routines +; this turn and jump right to the attacking phase. +HandleAIAntiMewtwoDeckStrategy: ; 227d3 (8:67d3) +; return carry if Player is not playing Mewtwo1 mill deck + ld a, [wAIBarrierFlagCounter] + bit 7, a + jr z, .set_carry + +; else, check if there's been less than 2 turns +; without the Player using Barrier. + cp AI_FLAG_MEWTWO_MILL + 2 + jr c, .count_bench + +; if there has been, reset wAIBarrierFlagCounter +; and return carry. + xor a + ld [wAIBarrierFlagCounter], a + jr .set_carry + +; else, check number of Pokemon that are set up in Bench +; if less than 4, return carry. +.count_bench + farcall CountNumberOfSetUpBenchPokemon + cp 4 + jr c, .set_carry + +; if there's at least 4 Pokemon in the Bench set up, +; process Trainer hand cards of AI_TRAINER_CARD_PHASE_05 + ld a, AI_TRAINER_CARD_PHASE_05 + farcall AIProcessHandTrainerCards + or a + ret + +.set_carry + scf + ret +; 0x227f6 ; lists in wDuelTempList all the basic energy cards ; in card location of a. @@ -7128,7 +8442,7 @@ FindDuplicatePokemonCards: ; 22b6f (8:6b6f) ; return carry flag if move is not high recoil. Func_22bad: ; 22bad (8:6bad) - farcall Func_169ca + farcall AIProcessButDontUseAttack ret nc ld a, [wSelectedAttack] ld e, a diff --git a/src/engine/bank1c.asm b/src/engine/bank1c.asm index 7b5cbc5..7fa5bf4 100644 --- a/src/engine/bank1c.asm +++ b/src/engine/bank1c.asm @@ -4,7 +4,7 @@ Func_70000: ; 70000 (1c:4000) ret nz ld b, $1 ld a, $22 - farcall CheckIfEventFlagSet + farcall GetEventFlagValue or a jr z, .asm_70013 ld b, $2 @@ -294,7 +294,7 @@ Func_70214: ; 70214 (1c:4214) ret nz ld hl, Unknown_7024a ld a, $10 - farcall CheckIfEventFlagSet + farcall GetEventFlagValue ld c, $8 .asm_70227 push bc diff --git a/src/engine/bank20.asm b/src/engine/bank20.asm index d2acf6a..b656f90 100644 --- a/src/engine/bank20.asm +++ b/src/engine/bank20.asm @@ -30,12 +30,12 @@ Func_80077: ; 80077 (20:4077) ld [hl], e inc hl ld [hl], d - call $43b9 - ld a, [wd4c6] + call Func_803b9 + ld a, [wTempPointerBank] ld [wd23d], a ld de, wd23e ld bc, $0006 - call Func_3bf5 + call CopyBankedDataToDE ld l, e ld h, d ld a, [hli] @@ -48,14 +48,163 @@ Func_80077: ; 80077 (20:4077) ld [wd23b], a ld a, [hli] ld [wd23c], a - call $40bd + call Func_800bd pop de pop bc pop hl ret -; 0x800bd - INCROM $800bd, $801a1 +Func_800bd: ; 800bd (20:40bd) + push hl + push bc + push de + ld a, [wTempPointer] + add $05 + ld e, a + ld a, [wTempPointer + 1] + adc $00 + ld d, a + ld b, $c0 + call Func_08bf + ld a, [wd4c2] + ld e, a + ld a, [wd4c3] + ld d, a + call Func_800e0 + pop de + pop bc + pop hl + ret + +Func_800e0: ; 800e0 (20:40e0) + push hl + ld hl, $d28e + ld a, [wd12f] + ld [hl], a + ld a, [wd23c] + or a + jr z, .asm_800f0 + sla [hl] +.asm_800f0 + ld c, $40 + ld hl, wd23e + xor a +.asm_800f6 + ld [hli], a + dec c + jr nz, .asm_800f6 + ld a, [wd130] + ld c, a +.asm_800fe + push bc + push de + ld b, $00 + ld a, [$d28e] + ld c, a + ld de, wd23e + call Func_3be4 + ld a, [wd12f] + ld b, a + pop de + push de + ld hl, wd23e + call Func_8016e + ld a, [wConsole] + cp $02 + jr nz, .asm_8013b + call BankswitchVRAM1 + ld a, [wd12f] + ld c, a + ld b, $00 + ld hl, wd23e + add hl, bc + pop de + push de + ld a, [wd12f] + ld b, a + call Func_80148 + call Func_8016e + call BankswitchVRAM0 +.asm_8013b + pop de + ld hl, $20 + add hl, de + ld e, l + ld d, h + pop bc + dec c + jr nz, .asm_800fe + pop hl + ret +; 0x80148 + +Func_80148: ; 80148 (20:4148) + ld a, [$d291] + or a + ret z + ld a, [$d23c] + or a + jr z, .asm_80162 + push hl + push bc +.asm_80155 + push bc + ld a, [$d291] + add [hl] + ld [hli], a + pop bc + dec b + jr nz, .asm_80155 + pop bc + pop hl + ret +.asm_80162 + push hl + push bc + ld a, [$d291] +.asm_80167 + ld [hli], a + dec b + jr nz, .asm_80167 + pop bc + pop hl + ret + +Func_8016e: ; 8016e (20:416e) + ld a, [wd292] + or a + jp z, SafeCopyDataHLtoDE + push hl + push bc + push de + ldh a, [hBankSRAM] + push af + ld a, $01 + call BankswitchSRAM + push hl + ld hl, $800 + ldh a, [hBankVRAM] + or a + jr z, .asm_8018c + ld hl, $c00 +.asm_8018c + add hl, de + ld e, l + ld d, h + pop hl +.asm_80190 + ld a, [hli] + ld [de], a + inc de + dec b + jr nz, .asm_80190 + pop af + call BankswitchSRAM + call DisableSRAM + pop de + pop bc + pop hl + ret Func_801a1: ; 801a1 (20:41a1) push hl @@ -108,6 +257,7 @@ Func_801a1: ; 801a1 (20:41a1) pop hl ret +; Clears the first x800 bytes of S1:a000 Func_801f1: ; 801f1 (20:41f1) push hl push bc @@ -118,7 +268,7 @@ Func_801f1: ; 801f1 (20:41f1) ld hl, $a000 ld bc, $0800 xor a - call $3c10 + call FillMemoryWithA pop af call BankswitchSRAM call DisableSRAM @@ -126,7 +276,7 @@ Func_801f1: ; 801f1 (20:41f1) pop hl ret -Func_8020f: ; 8020f (20:420f) +GetMapDataPointer: ; 8020f (20:420f) push bc push af ld bc, MapDataPointers @@ -148,12 +298,12 @@ Func_8020f: ; 8020f (20:420f) Func_80229: ; 80229 (20:4229) ld a, [hli] - ld [wd4c4], a + ld [wTempPointer], a ld a, [hli] - ld [wd4c5], a + ld [wTempPointer + 1], a ld a, [hli] add $20 - ld [wd4c6], a + ld [wTempPointerBank], a ret ; 0x80238 @@ -162,7 +312,7 @@ Func_80229: ; 80229 (20:4229) Func_8025b: ; 8025b (20:425b) push hl ld l, $4 - call Func_8020f + call GetMapDataPointer call Func_80229 ld a, [hl] push af @@ -192,7 +342,7 @@ asm_8027c ld e, [hl] inc hl ld d, [hl] - ld hl, wd4c4 + ld hl, wTempPointer ld a, [hli] ld h, [hl] ld l, a @@ -234,7 +384,19 @@ Func_802bb: ; 802bb (20:42bb) ret ; 0x802d4 - INCROM $802d4, $80418 + INCROM $802d4, $803b9 + +Func_803b9: ; 803b9 (20:43b9) + ld l, $00 + ld a, [wd131] + call GetMapDataPointer + call Func_80229 + ld a, [hl] + ld [$d239], a + ret +; 0x803c9 + + INCROM $803c9, $80418 Func_80418: ; 80418 (20:4418) INCROM $80418, $80480 @@ -246,13 +408,37 @@ Func_804d8: ; 804d8 (20:44d8) INCROM $804d8, $80b7a Func_80b7a: ; 80b7a (20:4b7a) - INCROM $80b7a, $80ba4 + INCROM $80b7a, $80b89 + +Func_80b89: ; 80b89 (20:4b89) + push hl + push bc + push af + ld c, a + ld a, $01 + ld [$d292], a + ld b, $00 + ld hl, $d323 + add hl, bc + ld a, [hl] + or a + jr z, .asm_80ba0 + ld a, c + call Func_80baa +.asm_80ba0 + pop af + pop bc + pop hl + ret Func_80ba4: ; 80ba4 (20:4ba4) push af xor a ld [wd292], a pop af +; Fallthrough + +Func_80baa: ; 80baa (20:4baa) push hl push bc push de @@ -332,5 +518,25 @@ Func_80ba4: ; 80ba4 (20:4ba4) Unknown_80e5a: ; 80e5a (20:4e5a) INCROM $80e5a, $80e5d +; might be closer to "screen specific data" than map data MapDataPointers: ; 80e5d (20:4e5d) - INCROM $80e5d, $84000 + dw MapDataPointers_80e67 + dw MapDataPointers_8100f + dw MapDataPointers_8116b + dw MapDataPointers_81333 + dw MapDataPointers_81697 + +MapDataPointers_80e67: ; 80e67 (20:4e67) + INCROM $80e67, $8100f + +MapDataPointers_8100f: ; 8100f (20:500f) + INCROM $8100f, $8116b + +MapDataPointers_8116b: ; 8116b (20:516b) + INCROM $8116b, $81333 + +MapDataPointers_81333: ; 81333 (20:5333) + INCROM $81333, $81697 + +MapDataPointers_81697: ; 81697 (20:5697) + INCROM $81697, $84000 diff --git a/src/engine/deck_ai/deck_ai.asm b/src/engine/deck_ai/deck_ai.asm new file mode 100644 index 0000000..c8b73f3 --- /dev/null +++ b/src/engine/deck_ai/deck_ai.asm @@ -0,0 +1,82 @@ +; AI card retreat score bonus
+; when the AI retreat routine runs through the Bench to choose
+; a Pokemon to switch to, it looks up in this list and if
+; a card ID matches, applies a retreat score bonus to this card.
+; positive (negative) means more (less) likely to switch to this card.
+ai_retreat: MACRO
+ db \1 ; card ID
+ db $80 + \2 ; retreat score (ranges between -128 and 127)
+ENDM
+
+; AI card energy attach score bonus
+; when the AI energy attachment routine runs through the Play Area to choose
+; a Pokemon to attach an energy card, it looks up in this list and if
+; a card ID matches, skips this card if the maximum number of energy
+; cards attached has been reached. If it hasn't been reached, additionally
+; applies a positive (or negative) AI score to attach energy to this card.
+ai_energy: MACRO
+ db \1 ; card ID
+ db \2 ; maximum number of attached cards
+ db $80 + \3 ; energy score (ranges between -128 and 127)
+ENDM
+
+; stores in WRAM pointer to data in argument
+; e.g. store_list_pointer wSomeListPointer, SomeData
+store_list_pointer: MACRO
+ ld hl, \1
+ ld de, \2
+ ld [hl], e
+ inc hl
+ ld [hl], d
+ENDM
+
+; deck AIs are specialized to work on a given deck ID.
+; they decide what happens during a turn, what Pokemon cards
+; to pick during the start of the duel, etc.
+; the different scenarios these are used are listed in AIACTION_* constants.
+; each of these have a pointer table with the following structure:
+; dw .do_turn : never called;
+;
+; dw .do_turn : called to handle the main turn logic, from the beginning
+; of the turn up to the attack (or lack thereof);
+;
+; dw .start_duel : called at the start of the duel to initialize some
+; variables and optionally set up CPU hand and deck;
+;
+; dw .forced_switch : logic to determine what Pokemon to pick when there's
+; an effect that forces AI to switch to Bench card;
+;
+; dw .ko_switch : logic for picking which card to use after a KO;
+;
+; dw .take_prize : logic to decide which prize card to pick.
+
+; optionally, decks can also declare card lists that will add
+; more specialized logic during various generic AI routines,
+; and read during the .start_duel routines.
+; the pointers to these lists are stored in memory:
+; wAICardListAvoidPrize : list of cards to avoid being placed as prize;
+; wAICardListArenaPriority : priority list of Arena card at duel start;
+; wAICardListBenchPriority : priority list of Bench cards at duel start;
+; wAICardListPlayFromHandPriority : priority list of cards to play from hand;
+; wAICardListRetreatBonus : scores given to certain cards for retreat;
+; wAICardListEnergyBonus : max number of energy cards and card scores.
+
+INCLUDE "engine/deck_ai/decks/general.asm"
+INCLUDE "engine/deck_ai/decks/sams_practice.asm"
+INCLUDE "engine/deck_ai/decks/general_no_retreat.asm"
+INCLUDE "engine/deck_ai/decks/legendary_moltres.asm"
+INCLUDE "engine/deck_ai/decks/legendary_zapdos.asm"
+INCLUDE "engine/deck_ai/decks/legendary_articuno.asm"
+INCLUDE "engine/deck_ai/decks/legendary_dragonite.asm"
+INCLUDE "engine/deck_ai/decks/first_strike.asm"
+INCLUDE "engine/deck_ai/decks/rock_crusher.asm"
+INCLUDE "engine/deck_ai/decks/go_go_rain_dance.asm"
+INCLUDE "engine/deck_ai/decks/zapping_selfdestruct.asm"
+INCLUDE "engine/deck_ai/decks/flower_power.asm"
+INCLUDE "engine/deck_ai/decks/strange_psyshock.asm"
+INCLUDE "engine/deck_ai/decks/wonders_of_science.asm"
+INCLUDE "engine/deck_ai/decks/fire_charge.asm"
+INCLUDE "engine/deck_ai/decks/im_ronald.asm"
+INCLUDE "engine/deck_ai/decks/powerful_ronald.asm"
+INCLUDE "engine/deck_ai/decks/invincible_ronald.asm"
+INCLUDE "engine/deck_ai/decks/legendary_ronald.asm"
diff --git a/src/engine/deck_ai/decks/fire_charge.asm b/src/engine/deck_ai/decks/fire_charge.asm new file mode 100644 index 0000000..454f731 --- /dev/null +++ b/src/engine/deck_ai/decks/fire_charge.asm @@ -0,0 +1,86 @@ +AIActionTable_FireCharge: ; 15232 (5:5232)
+ dw .do_turn ; unused
+ dw .do_turn
+ dw .start_duel
+ dw .forced_switch
+ dw .ko_switch
+ dw .take_prize
+
+.do_turn ; 1523e (5:523e)
+ call AIMainTurnLogic
+ ret
+; 0x15242
+
+.start_duel ; 15242 (5:5242)
+ call InitAIDuelVars
+ call .store_list_pointers
+ call SetUpBossStartingHandAndDeck
+ call TrySetUpBossStartingPlayArea
+ ret nc
+ call AIPlayInitialBasicCards
+ ret
+; 0x15253
+
+.forced_switch ; 15253 (5:5253)
+ call AIDecideBenchPokemonToSwitchTo
+ ret
+; 0x15257
+
+.ko_switch ; 15257 (5:5257)
+ call AIDecideBenchPokemonToSwitchTo
+ ret
+; 0x1525b
+
+.take_prize ; 1525b (5:525b)
+ call AIPickPrizeCards
+ ret
+; 0x1525f
+
+.list_arena ; 1525f (5:525f)
+ db JIGGLYPUFF3
+ db CHANSEY
+ db TAUROS
+ db MAGMAR1
+ db JIGGLYPUFF1
+ db GROWLITHE
+ db $00
+
+.list_bench ; 15266 (5:5266)
+ db JIGGLYPUFF3
+ db CHANSEY
+ db GROWLITHE
+ db MAGMAR1
+ db JIGGLYPUFF1
+ db TAUROS
+ db $00
+
+.list_retreat ; 1526e (5:526e)
+ ai_retreat JIGGLYPUFF1, -1
+ ai_retreat CHANSEY, -1
+ ai_retreat GROWLITHE, -1
+ db $00
+
+.list_energy ; 15274 (5:5274)
+ ai_energy GROWLITHE, 3, +0
+ ai_energy ARCANINE2, 4, +0
+ ai_energy MAGMAR1, 3, +0
+ ai_energy JIGGLYPUFF1, 3, +0
+ ai_energy JIGGLYPUFF3, 2, +0
+ ai_energy WIGGLYTUFF, 3, +0
+ ai_energy CHANSEY, 4, +0
+ ai_energy TAUROS, 3, +0
+ db $00
+
+.list_prize ; 1528d (5:528d)
+ db GAMBLER
+ db $00
+
+.store_list_pointers ; 1528f (5:528f)
+ store_list_pointer wAICardListAvoidPrize, .list_prize
+ store_list_pointer wAICardListArenaPriority, .list_arena
+ store_list_pointer wAICardListBenchPriority, .list_bench
+ store_list_pointer wAICardListPlayFromHandPriority, .list_bench
+ ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat
+ store_list_pointer wAICardListEnergyBonus, .list_energy
+ ret
+; 0x152bd
diff --git a/src/engine/deck_ai/decks/first_strike.asm b/src/engine/deck_ai/decks/first_strike.asm new file mode 100644 index 0000000..6d2906c --- /dev/null +++ b/src/engine/deck_ai/decks/first_strike.asm @@ -0,0 +1,82 @@ +AIActionTable_FirstStrike: ; 14e89 (5:4e89)
+ dw .do_turn ; unused
+ dw .do_turn
+ dw .start_duel
+ dw .forced_switch
+ dw .ko_switch
+ dw .take_prize
+
+.do_turn ; 14e95 (5:4e95)
+ call AIMainTurnLogic
+ ret
+; 0x14e99
+
+.start_duel ; 14e99 (5:4e99)
+ call InitAIDuelVars
+ call .store_list_pointers
+ call SetUpBossStartingHandAndDeck
+ call TrySetUpBossStartingPlayArea
+ ret nc
+ call AIPlayInitialBasicCards
+ ret
+; 0x14eaa
+
+.forced_switch ; 14eaa (5:4eaa)
+ call AIDecideBenchPokemonToSwitchTo
+ ret
+; 0x14eae
+
+.ko_switch ; 14eae (5:4eae)
+ call AIDecideBenchPokemonToSwitchTo
+ ret
+; 0x14eb2
+
+.take_prize ; 14eb2 (5:4eb2)
+ call AIPickPrizeCards
+ ret
+; 0x14eb6
+
+.list_arena ; 14eb6 (5:1eb6)
+ db HITMONCHAN
+ db MACHOP
+ db HITMONLEE
+ db MANKEY
+ db $00
+
+.list_bench ; 14ebb (5:1ebb)
+ db MACHOP
+ db HITMONLEE
+ db HITMONCHAN
+ db MANKEY
+ db $00
+
+.list_retreat ; 14ec0 (5:1ec0)
+ ai_retreat MACHOP, -1
+ ai_retreat MACHOKE, -1
+ ai_retreat MANKEY, -2
+ db $00
+
+.list_energy ; 14ec7 (5:1ec7)
+ ai_energy MACHOP, 3, +0
+ ai_energy MACHOKE, 4, +0
+ ai_energy MACHAMP, 4, -1
+ ai_energy HITMONCHAN, 3, +0
+ ai_energy HITMONLEE, 3, +0
+ ai_energy MANKEY, 2, -1
+ ai_energy PRIMEAPE, 3, -1
+ db $00
+
+.list_prize ; 14edd (5:1edd)
+ db HITMONLEE
+ db HITMONCHAN
+ db $00
+
+.store_list_pointers ; 14ee0 (5:4ee0)
+ store_list_pointer wAICardListAvoidPrize, .list_prize
+ store_list_pointer wAICardListArenaPriority, .list_arena
+ store_list_pointer wAICardListBenchPriority, .list_bench
+ store_list_pointer wAICardListPlayFromHandPriority, .list_bench
+ ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat
+ store_list_pointer wAICardListEnergyBonus, .list_energy
+ ret
+; 0x14f0e
diff --git a/src/engine/deck_ai/decks/flower_power.asm b/src/engine/deck_ai/decks/flower_power.asm new file mode 100644 index 0000000..566d064 --- /dev/null +++ b/src/engine/deck_ai/decks/flower_power.asm @@ -0,0 +1,81 @@ +AIActionTable_FlowerPower: ; 1509b (5:509b)
+ dw .do_turn ; unused
+ dw .do_turn
+ dw .start_duel
+ dw .forced_switch
+ dw .ko_switch
+ dw .take_prize
+
+.do_turn ; 150a7 (5:50a7)
+ call AIMainTurnLogic
+ ret
+; 0x150ab
+
+.start_duel ; 150ab (5:50ab)
+ call InitAIDuelVars
+ call .store_list_pointers
+ call SetUpBossStartingHandAndDeck
+ call TrySetUpBossStartingPlayArea
+ ret nc
+ call AIPlayInitialBasicCards
+ ret
+; 0x150bc
+
+.forced_switch ; 150bc (5:50bc)
+ call AIDecideBenchPokemonToSwitchTo
+ ret
+; 0x150c0
+
+.ko_switch ; 150c0 (5:50c0)
+ call AIDecideBenchPokemonToSwitchTo
+ ret
+; 0x150c4
+
+.take_prize ; 150c4 (5:50c4)
+ call AIPickPrizeCards
+ ret
+; 0x150c8
+
+.list_arena ; 150c8 (5:50c8)
+ db ODDISH
+ db EXEGGCUTE
+ db BULBASAUR
+ db $00
+
+.list_bench ; 150cc (5:50cc)
+ db BULBASAUR
+ db EXEGGCUTE
+ db ODDISH
+ db $00
+
+.list_retreat ; 150cf (5:50cf)
+ ai_retreat GLOOM, -2
+ ai_retreat VILEPLUME, -2
+ ai_retreat BULBASAUR, -2
+ ai_retreat IVYSAUR, -2
+ db $00
+
+.list_energy ; 150d9 (5:50d9)
+ ai_energy BULBASAUR, 3, +0
+ ai_energy IVYSAUR, 4, +0
+ ai_energy VENUSAUR2, 4, +0
+ ai_energy ODDISH, 2, +0
+ ai_energy GLOOM, 3, -1
+ ai_energy VILEPLUME, 3, -1
+ ai_energy EXEGGCUTE, 3, +0
+ ai_energy EXEGGUTOR, 22, +0
+ db $00
+
+.list_prize ; 150f2 (5:50f2)
+ db VENUSAUR2
+ db $00
+
+.store_list_pointers ; 150f4 (5:50f4)
+ store_list_pointer wAICardListAvoidPrize, .list_prize
+ store_list_pointer wAICardListArenaPriority, .list_arena
+ store_list_pointer wAICardListBenchPriority, .list_bench
+ store_list_pointer wAICardListPlayFromHandPriority, .list_bench
+ ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat
+ store_list_pointer wAICardListEnergyBonus, .list_energy
+ ret
+; 0x15122
diff --git a/src/engine/deck_ai/decks/general.asm b/src/engine/deck_ai/decks/general.asm new file mode 100644 index 0000000..1bfc3e0 --- /dev/null +++ b/src/engine/deck_ai/decks/general.asm @@ -0,0 +1,196 @@ +; AI logic used by general decks
+AIActionTable_GeneralDecks: ; 14668 (05:4668)
+ dw .do_turn ; unused
+ dw .do_turn
+ dw .start_duel
+ dw .forced_switch
+ dw .ko_switch
+ dw .take_prize
+
+.do_turn ; 14674 (5:4674)
+ call AIMainTurnLogic
+ ret
+
+.start_duel ; 14678 (5:4678)
+ call InitAIDuelVars
+ call AIPlayInitialBasicCards
+ ret
+
+.forced_switch ; 1467f (5:467f)
+ call AIDecideBenchPokemonToSwitchTo
+ ret
+
+.ko_switch ; 14683 (5:4683)
+ call AIDecideBenchPokemonToSwitchTo
+ ret
+
+.take_prize: ; 14687 (5:4687)
+ call AIPickPrizeCards
+ ret
+
+; handle AI routines for a whole turn
+AIMainTurnLogic: ; 1468b (5:468b)
+; initialize variables
+ call InitAITurnVars
+ ld a, AI_TRAINER_CARD_PHASE_01
+ call AIProcessHandTrainerCards
+ farcall HandleAIAntiMewtwoDeckStrategy
+ jp nc, .try_attack
+; handle Pkmn Powers
+ farcall HandleAIGoGoRainDanceEnergy
+ farcall HandleAIDamageSwap
+ farcall HandleAIPkmnPowers
+ ret c ; return if turn ended
+ farcall HandleAICowardice
+; process Trainer cards
+; phase 2 through 4.
+ ld a, AI_TRAINER_CARD_PHASE_02
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_03
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_04
+ call AIProcessHandTrainerCards
+; play Pokemon from hand
+ call AIDecidePlayPokemonCard
+ ret c ; return if turn ended
+; process Trainer cards
+; phase 5 through 12.
+ ld a, AI_TRAINER_CARD_PHASE_05
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_06
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_07
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_08
+ call AIProcessHandTrainerCards
+ call AIProcessRetreat
+ ld a, AI_TRAINER_CARD_PHASE_10
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_11
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_12
+ call AIProcessHandTrainerCards
+; play Energy card if possible
+ ld a, [wAlreadyPlayedEnergy]
+ or a
+ jr nz, .skip_energy_attach_1
+ call AIProcessAndTryToPlayEnergy
+.skip_energy_attach_1
+; play Pokemon from hand again
+ call AIDecidePlayPokemonCard
+; handle Pkmn Powers again
+ farcall HandleAIDamageSwap
+ farcall HandleAIPkmnPowers
+ ret c ; return if turn ended
+ farcall HandleAIGoGoRainDanceEnergy
+ ld a, AI_ENERGY_TRANS_ATTACK
+ farcall HandleAIEnergyTrans
+; process Trainer cards phases 13 and 15
+ ld a, AI_TRAINER_CARD_PHASE_13
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_15
+ call AIProcessHandTrainerCards
+; if used Professor Oak, process new hand
+; if not, then proceed to attack.
+ ld a, [wPreviousAIFlags]
+ and AI_FLAG_USED_PROFESSOR_OAK
+ jr z, .try_attack
+ ld a, AI_TRAINER_CARD_PHASE_01
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_02
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_03
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_04
+ call AIProcessHandTrainerCards
+ call AIDecidePlayPokemonCard
+ ret c ; return if turn ended
+ ld a, AI_TRAINER_CARD_PHASE_05
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_06
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_07
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_08
+ call AIProcessHandTrainerCards
+ call AIProcessRetreat
+ ld a, AI_TRAINER_CARD_PHASE_10
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_11
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_12
+ call AIProcessHandTrainerCards
+ ld a, [wAlreadyPlayedEnergy]
+ or a
+ jr nz, .skip_energy_attach_2
+ call AIProcessAndTryToPlayEnergy
+.skip_energy_attach_2
+ call AIDecidePlayPokemonCard
+ farcall HandleAIDamageSwap
+ farcall HandleAIPkmnPowers
+ ret c ; return if turn ended
+ farcall HandleAIGoGoRainDanceEnergy
+ ld a, AI_ENERGY_TRANS_ATTACK
+ farcall HandleAIEnergyTrans
+ ld a, AI_TRAINER_CARD_PHASE_13
+ call AIProcessHandTrainerCards
+ ; skip AI_TRAINER_CARD_PHASE_15
+.try_attack
+ ld a, AI_ENERGY_TRANS_TO_BENCH
+ farcall HandleAIEnergyTrans
+; attack if possible, if not,
+; finish turn without attacking.
+ call AIProcessAndTryToUseAttack
+ ret c ; return if AI attacked
+ ld a, OPPACTION_FINISH_NO_ATTACK
+ bank1call AIMakeDecision
+ ret
+; 0x14786
+
+; handles AI retreating logic
+AIProcessRetreat: ; 14786 (5:4786)
+ ld a, [wAIRetreatedThisTurn]
+ or a
+ ret nz ; return, already retreated this turn
+
+ call AIDecideWhetherToRetreat
+ ret nc ; return if not retreating
+
+ call AIDecideBenchPokemonToSwitchTo
+ ret c ; return if no Bench Pokemon
+
+; store Play Area to retreat to and
+; set wAIRetreatedThisTurn to true
+ ld [wAIPlayAreaCardToSwitch], a
+ ld a, $01
+ ld [wAIRetreatedThisTurn], a
+
+; if AI can use Switch from hand, use it instead...
+ ld a, AI_TRAINER_CARD_PHASE_09
+ call AIProcessHandTrainerCards
+ ld a, [wPreviousAIFlags]
+ and AI_FLAG_USED_SWITCH
+ jr nz, .used_switch
+; ... else try retreating normally.
+ ld a, [wAIPlayAreaCardToSwitch]
+ call AITryToRetreat
+ ret
+
+.used_switch
+; if AI used switch, unset its AI flag
+ ld a, [wPreviousAIFlags]
+ and ~AI_FLAG_USED_SWITCH ; clear Switch flag
+ ld [wPreviousAIFlags], a
+
+; bug, this doesn't make sense being here, since at this point
+; Switch Trainer card was already used to retreat the Pokemon.
+; what the routine will do is just transfer Energy cards to
+; the Arena Pokemon for the purpose of retreating, and
+; then not actually retreat, resulting in unusual behaviour.
+; this would only work placed right after the AI checks whether
+; they have Switch card in hand to use and doesn't have one.
+; (and probably that was the original intention.)
+ ld a, AI_ENERGY_TRANS_RETREAT ; retreat
+ farcall HandleAIEnergyTrans
+ ret
+; 0x147bd
diff --git a/src/engine/deck_ai/decks/general_no_retreat.asm b/src/engine/deck_ai/decks/general_no_retreat.asm new file mode 100644 index 0000000..e735076 --- /dev/null +++ b/src/engine/deck_ai/decks/general_no_retreat.asm @@ -0,0 +1,146 @@ +; acts just like a general deck AI except never retreats
+AIActionTable_GeneralNoRetreat: ; 148dc (5:48dc)
+ dw .do_turn ; unused
+ dw .do_turn
+ dw .start_duel
+ dw .forced_switch
+ dw .ko_switch
+ dw .take_prize
+
+.do_turn ; 148e8 (5:48e8)
+ call AIDoTurn_GeneralNoRetreat
+ ret
+; 0x148ec
+
+.start_duel ; 148ec (5:48ec)
+ call InitAIDuelVars
+ call AIPlayInitialBasicCards
+ ret
+; 0x148f3
+
+.forced_switch ; 148f3 (5:48f3)
+ call AIDecideBenchPokemonToSwitchTo
+ ret
+; 0x148f7
+
+.ko_switch ; 148f7 (5:48f7)
+ call AIDecideBenchPokemonToSwitchTo
+ ret
+; 0x148fb
+
+.take_prize ; 148fb (5:48fb)
+ call AIPickPrizeCards
+ ret
+; 0x148ff
+
+AIDoTurn_GeneralNoRetreat: ; 148ff (5:48ff)
+; initialize variables
+ call InitAITurnVars
+ ld a, AI_TRAINER_CARD_PHASE_01
+ call AIProcessHandTrainerCards
+ farcall HandleAIAntiMewtwoDeckStrategy
+ jp nc, .try_attack
+; handle Pkmn Powers
+ farcall HandleAIGoGoRainDanceEnergy
+ farcall HandleAIDamageSwap
+ farcall HandleAIPkmnPowers
+ ret c ; return if turn ended
+ farcall HandleAICowardice
+; process Trainer cards
+; phase 2 through 4.
+ ld a, AI_TRAINER_CARD_PHASE_02
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_03
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_04
+ call AIProcessHandTrainerCards
+; play Pokemon from hand
+ call AIDecidePlayPokemonCard
+ ret c ; return if turn ended
+; process Trainer cards
+; phase 5 through 12.
+ ld a, AI_TRAINER_CARD_PHASE_05
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_06
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_07
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_08
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_10
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_11
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_12
+ call AIProcessHandTrainerCards
+; play Energy card if possible
+ ld a, [wAlreadyPlayedEnergy]
+ or a
+ jr nz, .skip_energy_attach_1
+ call AIProcessAndTryToPlayEnergy
+.skip_energy_attach_1
+; play Pokemon from hand again
+ call AIDecidePlayPokemonCard
+; handle Pkmn Powers again
+ farcall HandleAIDamageSwap
+ farcall HandleAIPkmnPowers
+ ret c ; return if turn ended
+ farcall HandleAIGoGoRainDanceEnergy
+ ld a, AI_ENERGY_TRANS_ATTACK
+ farcall HandleAIEnergyTrans
+; process Trainer cards phases 13 and 15
+ ld a, AI_TRAINER_CARD_PHASE_13
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_15
+ call AIProcessHandTrainerCards
+; if used Professor Oak, process new hand
+; if not, then proceed to attack.
+ ld a, [wPreviousAIFlags]
+ and AI_FLAG_USED_PROFESSOR_OAK
+ jr z, .try_attack
+ ld a, AI_TRAINER_CARD_PHASE_01
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_02
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_03
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_04
+ call AIProcessHandTrainerCards
+ call AIDecidePlayPokemonCard
+ ret c ; return if turn ended
+ ld a, AI_TRAINER_CARD_PHASE_05
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_06
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_07
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_08
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_10
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_11
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_12
+ call AIProcessHandTrainerCards
+ ld a, [wAlreadyPlayedEnergy]
+ or a
+ jr nz, .skip_energy_attach_2
+ call AIProcessAndTryToPlayEnergy
+.skip_energy_attach_2
+ call AIDecidePlayPokemonCard
+ farcall HandleAIDamageSwap
+ farcall HandleAIPkmnPowers
+ ret c ; return if turn ended
+ farcall HandleAIGoGoRainDanceEnergy
+ ld a, AI_TRAINER_CARD_PHASE_13
+ call AIProcessHandTrainerCards
+ ; skip AI_TRAINER_CARD_PHASE_15
+.try_attack
+; attack if possible, if not,
+; finish turn without attacking.
+ call AIProcessAndTryToUseAttack
+ ret c ; return if turn ended
+ ld a, OPPACTION_FINISH_NO_ATTACK
+ bank1call AIMakeDecision
+ ret
+; 0x149e8
diff --git a/src/engine/deck_ai/decks/go_go_rain_dance.asm b/src/engine/deck_ai/decks/go_go_rain_dance.asm new file mode 100644 index 0000000..006bbdc --- /dev/null +++ b/src/engine/deck_ai/decks/go_go_rain_dance.asm @@ -0,0 +1,85 @@ +AIActionTable_GoGoRainDance: ; 14f8f (5:4f8f)
+ dw .do_turn ; unused
+ dw .do_turn
+ dw .start_duel
+ dw .forced_switch
+ dw .ko_switch
+ dw .take_prize
+
+.do_turn ; 14f9b (5:4f9b)
+ call AIMainTurnLogic
+ ret
+; 0x14f9f
+
+.start_duel ; 14f9f (5:4f9f)
+ call InitAIDuelVars
+ call .store_list_pointers
+ call SetUpBossStartingHandAndDeck
+ call TrySetUpBossStartingPlayArea
+ ret nc
+ call AIPlayInitialBasicCards
+ ret
+; 0x14fb0
+
+.forced_switch ; 14fb0 (5:4fb0)
+ call AIDecideBenchPokemonToSwitchTo
+ ret
+; 0x14fb4
+
+.ko_switch ; 14fb4 (5:4fb4)
+ call AIDecideBenchPokemonToSwitchTo
+ ret
+; 0x14fb8
+
+.take_prize ; 14fb8 (5:4fb8)
+ call AIPickPrizeCards
+ ret
+; 0x14fbc
+
+.list_arena ; 14fbc (5:4fbc)
+ db LAPRAS
+ db HORSEA
+ db GOLDEEN
+ db SQUIRTLE
+ db $00
+
+.list_bench ; 14fc1 (5:4fc1)
+ db SQUIRTLE
+ db HORSEA
+ db GOLDEEN
+ db LAPRAS
+ db $00
+
+.list_retreat ; 14fc6 (5:4fc6)
+ ai_retreat SQUIRTLE, -3
+ ai_retreat WARTORTLE, -2
+ ai_retreat HORSEA, -1
+ db $00
+
+.list_energy ; 14fcd (5:4fcd)
+ ai_energy SQUIRTLE, 2, +0
+ ai_energy WARTORTLE, 3, +0
+ ai_energy BLASTOISE, 5, +0
+ ai_energy GOLDEEN, 1, +0
+ ai_energy SEAKING, 2, +0
+ ai_energy HORSEA, 2, +0
+ ai_energy SEADRA, 3, +0
+ ai_energy LAPRAS, 3, +0
+ db $00
+
+.list_prize ; 14fe6 (5:4fe6)
+ db GAMBLER
+ db ENERGY_RETRIEVAL
+ db SUPER_ENERGY_RETRIEVAL
+ db BLASTOISE
+ db $00
+
+.store_list_pointers ; 14feb (5:4feb)
+ store_list_pointer wAICardListAvoidPrize, .list_prize
+ store_list_pointer wAICardListArenaPriority, .list_arena
+ store_list_pointer wAICardListBenchPriority, .list_bench
+ store_list_pointer wAICardListPlayFromHandPriority, .list_bench
+ ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat
+ store_list_pointer wAICardListEnergyBonus, .list_energy
+ ret
+; 0x15019
diff --git a/src/engine/deck_ai/decks/im_ronald.asm b/src/engine/deck_ai/decks/im_ronald.asm new file mode 100644 index 0000000..c140f1d --- /dev/null +++ b/src/engine/deck_ai/decks/im_ronald.asm @@ -0,0 +1,86 @@ +AIActionTable_ImRonald: ; 152bd (5:52bd)
+ dw .do_turn ; unused
+ dw .do_turn
+ dw .start_duel
+ dw .forced_switch
+ dw .ko_switch
+ dw .take_prize
+
+.do_turn ; 152c9 (5:52c9)
+ call AIMainTurnLogic
+ ret
+; 0x152cd
+
+.start_duel ; 152cd (5:52cd)
+ call InitAIDuelVars
+ call .store_list_pointers
+ call SetUpBossStartingHandAndDeck
+ call TrySetUpBossStartingPlayArea
+ ret nc
+ call AIPlayInitialBasicCards
+ ret
+; 0x152de
+
+.forced_switch ; 152de (5:52de)
+ call AIDecideBenchPokemonToSwitchTo
+ ret
+; 0x152e2
+
+.ko_switch ; 152e2 (5:52e2)
+ call AIDecideBenchPokemonToSwitchTo
+ ret
+; 0x152e6
+
+.take_prize ; 152e6 (5:52e6)
+ call AIPickPrizeCards
+ ret
+; 0x152ea
+
+.list_arena ; 152ea (5:52ea)
+ db LAPRAS
+ db SEEL
+ db CHARMANDER
+ db CUBONE
+ db SQUIRTLE
+ db GROWLITHE
+ db $00
+
+.list_bench ; 152f1 (5:52f1)
+ db CHARMANDER
+ db SQUIRTLE
+ db SEEL
+ db CUBONE
+ db GROWLITHE
+ db LAPRAS
+ db $00
+
+.list_retreat ; 152f8 (5:52f8)
+ db $00
+
+.list_energy ; 152f9 (5:52f9)
+ ai_energy CHARMANDER, 3, +0
+ ai_energy CHARMELEON, 5, +0
+ ai_energy GROWLITHE, 2, +0
+ ai_energy ARCANINE2, 4, +0
+ ai_energy SQUIRTLE, 2, +0
+ ai_energy WARTORTLE, 3, +0
+ ai_energy SEEL, 3, +0
+ ai_energy DEWGONG, 4, +0
+ ai_energy LAPRAS, 3, +0
+ ai_energy CUBONE, 3, +0
+ ai_energy MAROWAK1, 3, +0
+ db $00
+
+.list_prize ; 1531b (5:531b)
+ db LAPRAS
+ db $00
+
+.store_list_pointers ; 1531d (5:531d)
+ store_list_pointer wAICardListAvoidPrize, .list_prize
+ store_list_pointer wAICardListArenaPriority, .list_arena
+ store_list_pointer wAICardListBenchPriority, .list_bench
+ store_list_pointer wAICardListPlayFromHandPriority, .list_bench
+ ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat
+ store_list_pointer wAICardListEnergyBonus, .list_energy
+ ret
+; 0x1534b
diff --git a/src/engine/deck_ai/decks/invincible_ronald.asm b/src/engine/deck_ai/decks/invincible_ronald.asm new file mode 100644 index 0000000..0a55461 --- /dev/null +++ b/src/engine/deck_ai/decks/invincible_ronald.asm @@ -0,0 +1,84 @@ +AIActionTable_InvincibleRonald: ; 153e8 (5:53e8)
+ dw .do_turn ; unused
+ dw .do_turn
+ dw .start_duel
+ dw .forced_switch
+ dw .ko_switch
+ dw .take_prize
+
+.do_turn ; 153f4 (5:53f4)
+ call AIMainTurnLogic
+ ret
+; 0x153f8
+
+.start_duel ; 153f8 (5:53f8)
+ call InitAIDuelVars
+ call .store_list_pointers
+ call SetUpBossStartingHandAndDeck
+ call TrySetUpBossStartingPlayArea
+ ret nc
+ call AIPlayInitialBasicCards
+ ret
+; 0x15409
+
+.forced_switch ; 15409 (5:5409)
+ call AIDecideBenchPokemonToSwitchTo
+ ret
+; 0x1540d
+
+.ko_switch ; 1540d (5:540d)
+ call AIDecideBenchPokemonToSwitchTo
+ ret
+; 0x15411
+
+.take_prize ; 15411 (5:5411)
+ call AIPickPrizeCards
+ ret
+; 0x15415
+
+.list_arena ; 15415 (5:5415)
+ db KANGASKHAN
+ db MAGMAR2
+ db CHANSEY
+ db GEODUDE
+ db SCYTHER
+ db GRIMER
+ db $00
+
+.list_bench ; 1541c (5:541c)
+ db GRIMER
+ db SCYTHER
+ db GEODUDE
+ db CHANSEY
+ db MAGMAR2
+ db KANGASKHAN
+ db $00
+
+.list_retreat ; 15423 (5:5423)
+ ai_retreat GRIMER, -1
+ db $00
+
+.list_energy ; 15426 (5:5426)
+ ai_energy GRIMER, 1, -1
+ ai_energy MUK, 3, -1
+ ai_energy SCYTHER, 4, +1
+ ai_energy MAGMAR2, 2, +0
+ ai_energy GEODUDE, 2, +0
+ ai_energy GRAVELER, 3, +0
+ ai_energy CHANSEY, 4, +0
+ ai_energy KANGASKHAN, 4, -1
+ db $00
+
+.list_prize ; 1543f (5:543f)
+ db GAMBLER
+ db $00
+
+.store_list_pointers ; 15441 (5:5441)
+ store_list_pointer wAICardListAvoidPrize, .list_prize
+ store_list_pointer wAICardListArenaPriority, .list_arena
+ store_list_pointer wAICardListBenchPriority, .list_bench
+ store_list_pointer wAICardListPlayFromHandPriority, .list_bench
+ ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat
+ store_list_pointer wAICardListEnergyBonus, .list_energy
+ ret
+; 0x1546f
diff --git a/src/engine/deck_ai/decks/legendary_articuno.asm b/src/engine/deck_ai/decks/legendary_articuno.asm new file mode 100644 index 0000000..183ab62 --- /dev/null +++ b/src/engine/deck_ai/decks/legendary_articuno.asm @@ -0,0 +1,217 @@ +AIActionTable_LegendaryArticuno: ; 14c0b (5:4c0b)
+ dw .do_turn ; unused
+ dw .do_turn
+ dw .start_duel
+ dw .forced_switch
+ dw .ko_switch
+ dw .take_prize
+
+.do_turn ; 14c17 (5:4c17)
+ call AIDoTurn_LegendaryArticuno
+ ret
+; 0x14c1b
+
+.start_duel ; 14c1b (5:4c1b)
+ call InitAIDuelVars
+ call .store_list_pointers
+ call SetUpBossStartingHandAndDeck
+ call TrySetUpBossStartingPlayArea
+ ret nc
+ call AIPlayInitialBasicCards
+ ret
+; 0x14c2c
+
+.forced_switch ; 14c2c (5:4c2c)
+ call AIDecideBenchPokemonToSwitchTo
+ ret
+; 0x14c30
+
+.ko_switch ; 14c30 (5:4c30)
+ call AIDecideBenchPokemonToSwitchTo
+ ret
+; 0x14c34
+
+.take_prize ; 14c34 (5:4c34)
+ call AIPickPrizeCards
+ ret
+; 0x14c38
+
+.list_arena ; 14c38 (5:4c38)
+ db CHANSEY
+ db LAPRAS
+ db DITTO
+ db SEEL
+ db ARTICUNO1
+ db ARTICUNO2
+ db $00
+
+.list_bench ; 14c3f (5:4c3f)
+ db ARTICUNO1
+ db SEEL
+ db LAPRAS
+ db CHANSEY
+ db DITTO
+ db $00
+
+.list_retreat ; 14c45 (5:4c45)
+ ai_retreat SEEL, -3
+ ai_retreat DITTO, -3
+ db $00
+
+.list_energy ; 14c4a (5:4c4a)
+ ai_energy SEEL, 3, +1
+ ai_energy DEWGONG, 4, +0
+ ai_energy LAPRAS, 3, +0
+ ai_energy ARTICUNO1, 4, +1
+ ai_energy ARTICUNO2, 3, +0
+ ai_energy CHANSEY, 0, -8
+ ai_energy DITTO, 3, +0
+ db $00
+
+.list_prize ; 14c60 (5:4c60)
+ db GAMBLER
+ db ARTICUNO2
+ db $00
+
+.store_list_pointers ; 14c63 (5:4c63)
+ store_list_pointer wAICardListAvoidPrize, .list_prize
+ store_list_pointer wAICardListArenaPriority, .list_arena
+ store_list_pointer wAICardListBenchPriority, .list_bench
+ store_list_pointer wAICardListPlayFromHandPriority, .list_bench
+ ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat
+ store_list_pointer wAICardListEnergyBonus, .list_energy
+ ret
+; 0x14c91
+
+; this routine handles how Legendary Articuno
+; prioritises playing energy cards to each Pokémon.
+; first, it makes sure that all Lapras have at least
+; 3 energy cards before moving on to Articuno,
+; and then to Dewgong and Seel
+ScoreLegendaryArticunoCards: ; 14c91 (5:4c91)
+ call SwapTurn
+ call CountPrizes
+ call SwapTurn
+ cp 3
+ ret c
+
+; player prizes >= 3
+; if Lapras has more than half HP and
+; can use second move, check next for Articuno
+; otherwise, check if Articuno or Dewgong
+; have more than half HP and can use second move
+; and if so, the next Pokémon to check is Lapras
+ ld a, LAPRAS
+ call CheckForBenchIDAtHalfHPAndCanUseSecondMove
+ jr c, .articuno
+ ld a, ARTICUNO1
+ call CheckForBenchIDAtHalfHPAndCanUseSecondMove
+ jr c, .lapras
+ ld a, DEWGONG
+ call CheckForBenchIDAtHalfHPAndCanUseSecondMove
+ jr c, .lapras
+ jr .articuno
+
+; the following routines check for certain card IDs in bench
+; and call RaiseAIScoreToAllMatchingIDsInBench if these are found.
+; for Lapras, an additional check is made to its
+; attached energy count, which skips calling the routine
+; if this count is >= 3
+.lapras
+ ld a, LAPRAS
+ ld b, PLAY_AREA_BENCH_1
+ call LookForCardIDInPlayArea_Bank5
+ jr nc, .articuno
+ ld e, a
+ call CountNumberOfEnergyCardsAttached
+ cp 3
+ jr nc, .articuno
+ ld a, LAPRAS
+ call RaiseAIScoreToAllMatchingIDsInBench
+ ret
+
+.articuno
+ ld a, ARTICUNO1
+ ld b, PLAY_AREA_BENCH_1
+ call LookForCardIDInPlayArea_Bank5
+ jr nc, .dewgong
+ ld a, ARTICUNO1
+ call RaiseAIScoreToAllMatchingIDsInBench
+ ret
+
+.dewgong
+ ld a, DEWGONG
+ ld b, PLAY_AREA_BENCH_1
+ call LookForCardIDInPlayArea_Bank5
+ jr nc, .seel
+ ld a, DEWGONG
+ call RaiseAIScoreToAllMatchingIDsInBench
+ ret
+
+.seel
+ ld a, SEEL
+ ld b, PLAY_AREA_BENCH_1
+ call LookForCardIDInPlayArea_Bank5
+ ret nc
+ ld a, SEEL
+ call RaiseAIScoreToAllMatchingIDsInBench
+ ret
+; 0x14cf7
+
+AIDoTurn_LegendaryArticuno: ; 14cf7 (5:4cf7)
+; initialize variables
+ call InitAITurnVars
+ ld a, AI_TRAINER_CARD_PHASE_01
+ call AIProcessHandTrainerCards
+ farcall HandleAIAntiMewtwoDeckStrategy
+ jp nc, .try_attack
+; process Trainer cards
+ ld a, AI_TRAINER_CARD_PHASE_02
+ call AIProcessHandTrainerCards
+; play Pokemon from hand
+ call AIDecidePlayPokemonCard
+ ret c ; return if turn ended
+ call AIProcessRetreat
+ ld a, AI_TRAINER_CARD_PHASE_10
+ call AIProcessHandTrainerCards
+; play Energy card if possible
+ ld a, [wAlreadyPlayedEnergy]
+ or a
+ jr nz, .skip_energy_attach_1
+ call AIProcessAndTryToPlayEnergy
+.skip_energy_attach_1
+; play Pokemon from hand again
+ call AIDecidePlayPokemonCard
+; process Trainer cards phases 13 and 15
+ ld a, AI_TRAINER_CARD_PHASE_13
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_15
+ call AIProcessHandTrainerCards
+; if used Professor Oak, process new hand
+ ld a, [wPreviousAIFlags]
+ and AI_FLAG_USED_PROFESSOR_OAK
+ jr z, .try_attack
+ ld a, AI_TRAINER_CARD_PHASE_01
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_02
+ call AIProcessHandTrainerCards
+ call AIDecidePlayPokemonCard
+ ret c ; return if turn ended
+ call AIProcessRetreat
+ ld a, AI_TRAINER_CARD_PHASE_10
+ call AIProcessHandTrainerCards
+ ld a, [wAlreadyPlayedEnergy]
+ or a
+ jr nz, .skip_energy_attach_2
+ call AIProcessAndTryToPlayEnergy
+.skip_energy_attach_2
+ call AIDecidePlayPokemonCard
+.try_attack
+; attack if possible, if not,
+; finish turn without attacking.
+ call AIProcessAndTryToUseAttack
+ ret c ; return if turn ended
+ ld a, OPPACTION_FINISH_NO_ATTACK
+ bank1call AIMakeDecision
+ ret
+; 0x14d60
diff --git a/src/engine/deck_ai/decks/legendary_dragonite.asm b/src/engine/deck_ai/decks/legendary_dragonite.asm new file mode 100644 index 0000000..d320440 --- /dev/null +++ b/src/engine/deck_ai/decks/legendary_dragonite.asm @@ -0,0 +1,173 @@ +AIActionTable_LegendaryDragonite: ; 14d60 (05:4d60)
+ dw .do_turn ; unused
+ dw .do_turn
+ dw .start_duel
+ dw .forced_switch
+ dw .ko_switch
+ dw .take_prize
+
+.do_turn ; 14d6c (5:4d6c)
+ call AIDoTurn_LegendaryDragonite
+ ret
+; 0x14d70
+
+.start_duel ; 14d70 (5:4d70)
+ call InitAIDuelVars
+ call .store_list_pointers
+ call SetUpBossStartingHandAndDeck
+ call TrySetUpBossStartingPlayArea
+ ret nc
+ call AIPlayInitialBasicCards
+ ret
+; 0x14d81
+
+.forced_switch ; 14d81 (5:4d81)
+ call AIDecideBenchPokemonToSwitchTo
+ ret
+; 0x14d85
+
+.ko_switch ; 14d85 (5:4d85)
+ call AIDecideBenchPokemonToSwitchTo
+ ret
+; 0x14d89
+
+.take_prize ; 14d89 (5:4d89)
+ call AIPickPrizeCards
+ ret
+; 0x14d8d
+
+.list_arena ; 14d8d (5:4d8d)
+ db KANGASKHAN
+ db LAPRAS
+ db CHARMANDER
+ db DRATINI
+ db MAGIKARP
+ db $00
+
+.list_bench ; 14d93 (5:4d93)
+ db CHARMANDER
+ db MAGIKARP
+ db DRATINI
+ db LAPRAS
+ db KANGASKHAN
+ db $00
+
+.list_retreat ; 14d99 (5:4d99)
+ ai_retreat CHARMANDER, -1
+ ai_retreat MAGIKARP, -5
+ db $00
+
+.list_energy ; 14d9e (5:4d9e)
+ ai_energy CHARMANDER, 3, +1
+ ai_energy CHARMELEON, 4, +1
+ ai_energy CHARIZARD, 5, +0
+ ai_energy MAGIKARP, 3, +1
+ ai_energy GYARADOS, 4, -1
+ ai_energy DRATINI, 2, +0
+ ai_energy DRAGONAIR, 4, +0
+ ai_energy DRAGONITE1, 3, -1
+ ai_energy KANGASKHAN, 2, -2
+ ai_energy LAPRAS, 3, +0
+ db $00
+
+.list_prize ; 14dbd (5:4dbd)
+ db GAMBLER
+ db DRAGONITE1
+ db KANGASKHAN
+ db $00
+
+.store_list_pointers ; 14dc1 (5:4dc1)
+ store_list_pointer wAICardListAvoidPrize, .list_prize
+ store_list_pointer wAICardListArenaPriority, .list_arena
+ store_list_pointer wAICardListBenchPriority, .list_bench
+ store_list_pointer wAICardListPlayFromHandPriority, .list_bench
+ ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat
+ store_list_pointer wAICardListEnergyBonus, .list_energy
+ ret
+; 0x14def
+
+AIDoTurn_LegendaryDragonite: ; 14def (5:4def)
+; initialize variables
+ call InitAITurnVars
+ ld a, AI_TRAINER_CARD_PHASE_01
+ call AIProcessHandTrainerCards
+ farcall HandleAIAntiMewtwoDeckStrategy
+ jp nc, .try_attack
+; process Trainer cards
+ ld a, AI_TRAINER_CARD_PHASE_02
+ call AIProcessHandTrainerCards
+; play Pokemon from hand
+ call AIDecidePlayPokemonCard
+ ret c ; return if turn ended
+ ld a, AI_TRAINER_CARD_PHASE_07
+ call AIProcessHandTrainerCards
+ call AIProcessRetreat
+ ld a, AI_TRAINER_CARD_PHASE_10
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_11
+ call AIProcessHandTrainerCards
+; play Energy card if possible
+ ld a, [wAlreadyPlayedEnergy]
+ or a
+ jr nz, .skip_energy_attach_1
+
+; if Arena card is Kangaskhan and doens't
+; have Energy cards attached, try attaching from hand.
+; otherwise run normal AI energy attach routine.
+ ld a, DUELVARS_ARENA_CARD
+ call GetTurnDuelistVariable
+ call GetCardIDFromDeckIndex
+ ld a, KANGASKHAN
+ cp e
+ jr nz, .attach_normally
+ call CreateEnergyCardListFromHand
+ jr c, .skip_energy_attach_1
+ ld e, PLAY_AREA_ARENA
+ call CountNumberOfEnergyCardsAttached
+ or a
+ jr nz, .attach_normally
+ xor a
+ ldh [hTempPlayAreaLocation_ff9d], a
+ call AITryToPlayEnergyCard
+ jr c, .skip_energy_attach_1
+.attach_normally
+ call AIProcessAndTryToPlayEnergy
+
+.skip_energy_attach_1
+; play Pokemon from hand again
+ call AIDecidePlayPokemonCard
+ ld a, AI_TRAINER_CARD_PHASE_15
+ call AIProcessHandTrainerCards
+; if used Professor Oak, process new hand
+; if not, then proceed to attack.
+ ld a, [wPreviousAIFlags]
+ and AI_FLAG_USED_PROFESSOR_OAK
+ jr z, .try_attack
+ ld a, AI_TRAINER_CARD_PHASE_01
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_02
+ call AIProcessHandTrainerCards
+ call AIDecidePlayPokemonCard
+ ret c ; return if turn ended
+ ld a, AI_TRAINER_CARD_PHASE_07
+ call AIProcessHandTrainerCards
+ call AIProcessRetreat
+ ld a, AI_TRAINER_CARD_PHASE_10
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_11
+ call AIProcessHandTrainerCards
+ ld a, [wAlreadyPlayedEnergy]
+ or a
+ jr nz, .skip_energy_attach_2
+ call AIProcessAndTryToPlayEnergy
+.skip_energy_attach_2
+ call AIDecidePlayPokemonCard
+.try_attack
+; attack if possible, if not,
+; finish turn without attacking.
+ call AIProcessAndTryToUseAttack
+ ret c ; return if turn ended
+ ld a, OPPACTION_FINISH_NO_ATTACK
+ bank1call AIMakeDecision
+ ret
+; 0x14e89
diff --git a/src/engine/deck_ai/decks/legendary_moltres.asm b/src/engine/deck_ai/decks/legendary_moltres.asm new file mode 100644 index 0000000..cb38668 --- /dev/null +++ b/src/engine/deck_ai/decks/legendary_moltres.asm @@ -0,0 +1,183 @@ +AIActionTable_LegendaryMoltres: ; 149e8 (05:49e8)
+ dw .do_turn ; unused
+ dw .do_turn
+ dw .start_duel
+ dw .forced_switch
+ dw .ko_switch
+ dw .take_prize
+
+.do_turn ; 149f4 (5:49f4)
+ call AIDoTurn_LegendaryMoltres
+ ret
+; 0x149f8
+
+.start_duel ; 149f8 (5:49f8)
+ call InitAIDuelVars
+ call .store_list_pointers
+ call SetUpBossStartingHandAndDeck
+ call TrySetUpBossStartingPlayArea
+ ret nc ; Play Area set up was successful
+ call AIPlayInitialBasicCards
+ ret
+; 0x14a09
+
+.forced_switch ; 14a09 (5:4a09)
+ call AIDecideBenchPokemonToSwitchTo
+ ret
+; 0x14a0d
+
+.ko_switch ; 14a0d (5:4a0d)
+ call AIDecideBenchPokemonToSwitchTo
+ ret
+; 0x14a11
+
+.take_prize ; 14a11 (5:4a11)
+ call AIPickPrizeCards
+ ret
+; 0x14a15
+
+.list_arena ; 14a15 (5:4a15)
+ db MAGMAR2
+ db GROWLITHE
+ db VULPIX
+ db MAGMAR1
+ db MOLTRES1
+ db MOLTRES2
+ db $00
+
+.list_bench ; 14a1c (5:4a1c)
+ db MOLTRES1
+ db VULPIX
+ db GROWLITHE
+ db MAGMAR2
+ db MAGMAR1
+ db $00
+
+.list_play_hand ; 14a22 (5:4a22)
+ db MOLTRES2
+ db MOLTRES1
+ db VULPIX
+ db GROWLITHE
+ db MAGMAR2
+ db MAGMAR1
+ db $00
+
+.list_retreat ; 14a29 (5:4a29)
+ ai_retreat GROWLITHE, -5
+ ai_retreat VULPIX, -5
+ db $00
+
+.list_energy ; 14a2e (5:4a2e)
+ ai_energy VULPIX, 3, +0
+ ai_energy NINETAILS2, 3, +1
+ ai_energy GROWLITHE, 3, +1
+ ai_energy ARCANINE2, 4, +1
+ ai_energy MAGMAR1, 4, -1
+ ai_energy MAGMAR2, 1, -1
+ ai_energy MOLTRES2, 3, +2
+ ai_energy MOLTRES1, 4, +2
+ db $00
+
+.list_prize ; 14a47 (5:4a47)
+ db ENERGY_REMOVAL
+ db MOLTRES2
+ db $00
+
+.store_list_pointers ; 14a4a (5:4a4a)
+ store_list_pointer wAICardListAvoidPrize, .list_prize
+ store_list_pointer wAICardListArenaPriority, .list_arena
+ store_list_pointer wAICardListBenchPriority, .list_bench
+ store_list_pointer wAICardListPlayFromHandPriority, .list_play_hand
+ store_list_pointer wAICardListRetreatBonus, .list_retreat
+ store_list_pointer wAICardListEnergyBonus, .list_energy
+ ret
+; 0x14a81
+
+AIDoTurn_LegendaryMoltres: ; 14a81 (5:4a81)
+; initialize variables
+ call InitAITurnVars
+ farcall HandleAIAntiMewtwoDeckStrategy
+ jp nc, .try_attack
+; process Trainer cards
+; phase 2 through 4.
+ ld a, AI_TRAINER_CARD_PHASE_02
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_04
+ call AIProcessHandTrainerCards
+
+; check if AI can play Moltres2
+; from hand and if so, play it.
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ cp MAX_PLAY_AREA_POKEMON
+ jr nc, .skip_moltres ; skip if bench is full
+ ld a, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK
+ call GetTurnDuelistVariable
+ cp DECK_SIZE - 9
+ jr nc, .skip_moltres ; skip if cards in deck <= 9
+ ld a, MUK
+ call CountPokemonIDInBothPlayAreas
+ jr c, .skip_moltres ; skip if Muk in play
+ ld a, MOLTRES2
+ call LookForCardIDInHandList_Bank5
+ jr nc, .skip_moltres ; skip if no Moltres2 in hand
+ ldh [hTemp_ffa0], a
+ ld a, OPPACTION_PLAY_BASIC_PKMN
+ bank1call AIMakeDecision
+
+.skip_moltres
+; play Pokemon from hand
+ call AIDecidePlayPokemonCard
+ ret c ; return if turn ended
+; process Trainer cards
+ ld a, AI_TRAINER_CARD_PHASE_05
+ call AIProcessHandTrainerCards
+ call AIProcessRetreat
+ ld a, AI_TRAINER_CARD_PHASE_10
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_11
+ call AIProcessHandTrainerCards
+; play Energy card if possible
+ ld a, [wAlreadyPlayedEnergy]
+ or a
+ jr nz, .skip_attach_energy
+
+; if Magmar2 is the Arena card and has no energy attached,
+; try attaching an energy card to it from the hand.
+; otherwise, run normal AI energy attach routine.
+ ld a, DUELVARS_ARENA_CARD
+ call GetTurnDuelistVariable
+ call GetCardIDFromDeckIndex
+ ld a, MAGMAR2
+ cp e
+ jr nz, .attach_normally
+ ; Magmar2 is the Arena card
+ call CreateEnergyCardListFromHand
+ jr c, .skip_attach_energy
+ ld e, PLAY_AREA_ARENA
+ call CountNumberOfEnergyCardsAttached
+ or a
+ jr nz, .attach_normally
+ xor a ; PLAY_AREA_ARENA
+ ldh [hTempPlayAreaLocation_ff9d], a
+ call AITryToPlayEnergyCard
+ jr c, .skip_attach_energy
+
+.attach_normally
+; play Energy card if possible
+ call AIProcessAndTryToPlayEnergy
+.skip_attach_energy
+; try playing Pokemon cards from hand again
+ call AIDecidePlayPokemonCard
+ ld a, AI_TRAINER_CARD_PHASE_13
+ call AIProcessHandTrainerCards
+
+.try_attack
+; attack if possible, if not,
+; finish turn without attacking.
+ call AIProcessAndTryToUseAttack
+ ret c
+ ld a, OPPACTION_FINISH_NO_ATTACK
+ bank1call AIMakeDecision
+ ret
+; 0x14b0f
diff --git a/src/engine/deck_ai/decks/legendary_ronald.asm b/src/engine/deck_ai/decks/legendary_ronald.asm new file mode 100644 index 0000000..2721ba9 --- /dev/null +++ b/src/engine/deck_ai/decks/legendary_ronald.asm @@ -0,0 +1,210 @@ +AIActionTable_LegendaryRonald: ; 1546f (5:546f)
+ dw .do_turn ; unused
+ dw .do_turn
+ dw .start_duel
+ dw .forced_switch
+ dw .ko_switch
+ dw .take_prize
+
+.do_turn ; 1547b (5:547b)
+ call AIDoTurn_LegendaryRonald
+ ret
+; 0x1547f
+
+.start_duel ; 1547f (5:547f)
+ call InitAIDuelVars
+ call .store_list_pointers
+ call SetUpBossStartingHandAndDeck
+ call TrySetUpBossStartingPlayArea
+ ret nc
+ call AIPlayInitialBasicCards
+ ret
+; 0x15490
+
+.forced_switch ; 15490 (5:5490)
+ call AIDecideBenchPokemonToSwitchTo
+ ret
+; 0x15494
+
+.ko_switch ; 15494 (5:5494)
+ call AIDecideBenchPokemonToSwitchTo
+ ret
+; 0x15498
+
+.take_prize ; 15498 (5:5498)
+ call AIPickPrizeCards
+ ret
+; 0x1549c
+
+.list_arena ; 1549c (5:549c)
+ db KANGASKHAN
+ db DRATINI
+ db EEVEE
+ db ZAPDOS3
+ db ARTICUNO2
+ db MOLTRES2
+ db $00
+
+.list_bench ; 154a3 (5:54a3)
+ db KANGASKHAN
+ db DRATINI
+ db EEVEE
+ db $00
+
+.list_play_hand ; 154a7 (5:54a7)
+ db MOLTRES2
+ db ZAPDOS3
+ db KANGASKHAN
+ db DRATINI
+ db EEVEE
+ db ARTICUNO2
+ db $00
+
+.list_retreat ; 154ae (5:54ae)
+ ai_retreat EEVEE, -2
+ db $00
+
+.list_energy ; 154b1 (5:54b1)
+ ai_energy FLAREON1, 3, +0
+ ai_energy MOLTRES2, 3, +0
+ ai_energy VAPOREON1, 3, +0
+ ai_energy ARTICUNO2, 0, -8
+ ai_energy JOLTEON1, 4, +0
+ ai_energy ZAPDOS3, 0, -8
+ ai_energy KANGASKHAN, 4, -1
+ ai_energy EEVEE, 3, +0
+ ai_energy DRATINI, 3, +0
+ ai_energy DRAGONAIR, 4, +0
+ ai_energy DRAGONITE1, 3, +0
+ db $00
+
+.list_prize ; 154d3 (5:54d3)
+ db MOLTRES2
+ db ARTICUNO2
+ db ZAPDOS3
+ db DRAGONITE1
+ db GAMBLER
+ db $00
+
+.store_list_pointers ; 154d9 (5:54d9)
+ store_list_pointer wAICardListAvoidPrize, .list_prize
+ store_list_pointer wAICardListArenaPriority, .list_arena
+ store_list_pointer wAICardListBenchPriority, .list_bench
+ store_list_pointer wAICardListPlayFromHandPriority, .list_play_hand
+ ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat
+ store_list_pointer wAICardListEnergyBonus, .list_energy
+ ret
+; 0x15507
+
+AIDoTurn_LegendaryRonald: ; 15507 (5:5507)
+; initialize variables
+ call InitAITurnVars
+; process Trainer cards
+ ld a, AI_TRAINER_CARD_PHASE_01
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_02
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_04
+ call AIProcessHandTrainerCards
+
+; check if AI can play Moltres2
+; from hand and if so, play it.
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ cp MAX_PLAY_AREA_POKEMON
+ jr nc, .skip_moltres_1 ; skip if bench is full
+ ld a, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK
+ call GetTurnDuelistVariable
+ cp DECK_SIZE - 9
+ jr nc, .skip_moltres_1 ; skip if cards in deck <= 9
+ ld a, MUK
+ call CountPokemonIDInBothPlayAreas
+ jr c, .skip_moltres_1 ; skip if Muk in play
+ ld a, MOLTRES2
+ call LookForCardIDInHandList_Bank5
+ jr nc, .skip_moltres_1 ; skip if no Moltres2 in hand
+ ldh [hTemp_ffa0], a
+ ld a, OPPACTION_PLAY_BASIC_PKMN
+ bank1call AIMakeDecision
+
+.skip_moltres_1
+; play Pokemon from hand
+ call AIDecidePlayPokemonCard
+ ret c ; return if turn ended
+; process Trainer cards
+ ld a, AI_TRAINER_CARD_PHASE_05
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_07
+ call AIProcessHandTrainerCards
+ call AIProcessRetreat
+ ld a, AI_TRAINER_CARD_PHASE_10
+ call AIProcessHandTrainerCards
+; play Energy card if possible
+ ld a, [wAlreadyPlayedEnergy]
+ or a
+ jr nz, .skip_attach_energy_1
+ call AIProcessAndTryToPlayEnergy
+.skip_attach_energy_1
+; try playing Pokemon cards from hand again
+ call AIDecidePlayPokemonCard
+ ret c ; return if turn ended
+ ld a, AI_TRAINER_CARD_PHASE_15
+; if used Professor Oak, process new hand
+; if not, then proceed to attack.
+ call AIProcessHandTrainerCards
+ ld a, [wPreviousAIFlags]
+ and AI_FLAG_USED_PROFESSOR_OAK
+ jr z, .try_attack
+ ld a, AI_TRAINER_CARD_PHASE_01
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_02
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_04
+ call AIProcessHandTrainerCards
+
+; check if AI can play Moltres2
+; from hand and if so, play it.
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ cp MAX_PLAY_AREA_POKEMON
+ jr nc, .skip_moltres_2 ; skip if bench is full
+ ld a, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK
+ call GetTurnDuelistVariable
+ cp DECK_SIZE - 9
+ jr nc, .skip_moltres_2 ; skip if cards in deck <= 9
+ ld a, MUK
+ call CountPokemonIDInBothPlayAreas
+ jr c, .skip_moltres_2 ; skip if Muk in play
+ ld a, MOLTRES2
+ call LookForCardIDInHandList_Bank5
+ jr nc, .skip_moltres_2 ; skip if no Moltres2 in hand
+ ldh [hTemp_ffa0], a
+ ld a, OPPACTION_PLAY_BASIC_PKMN
+ bank1call AIMakeDecision
+
+.skip_moltres_2
+ call AIDecidePlayPokemonCard
+ ret c ; return if turn ended
+ ld a, AI_TRAINER_CARD_PHASE_05
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_07
+ call AIProcessHandTrainerCards
+ call AIProcessRetreat
+ ld a, AI_TRAINER_CARD_PHASE_10
+ call AIProcessHandTrainerCards
+ ld a, [wAlreadyPlayedEnergy]
+ or a
+ jr nz, .skip_attach_energy_2
+ call AIProcessAndTryToPlayEnergy
+.skip_attach_energy_2
+ call AIDecidePlayPokemonCard
+ ret c ; return if turn ended
+.try_attack
+; attack if possible, if not,
+; finish turn without attacking.
+ call AIProcessAndTryToUseAttack
+ ret c ; return if turn ended
+ ld a, OPPACTION_FINISH_NO_ATTACK
+ bank1call AIMakeDecision
+ ret
+; 0x155d2
diff --git a/src/engine/deck_ai/decks/legendary_zapdos.asm b/src/engine/deck_ai/decks/legendary_zapdos.asm new file mode 100644 index 0000000..cfa60be --- /dev/null +++ b/src/engine/deck_ai/decks/legendary_zapdos.asm @@ -0,0 +1,160 @@ +AIActionTable_LegendaryZapdos: ; 14b0f (05:4b0f)
+ dw .do_turn ; unused
+ dw .do_turn
+ dw .start_duel
+ dw .forced_switch
+ dw .ko_switch
+ dw .take_prize
+
+.do_turn ; 14b1b (5:4b1b)
+ call AIDoTurn_LegendaryZapdos
+ ret
+; 0x14b1f
+
+.start_duel ; 14b1f (5:4b1f)
+ call InitAIDuelVars
+ call .store_list_pointers
+ call SetUpBossStartingHandAndDeck
+ call TrySetUpBossStartingPlayArea
+ ret nc
+ call AIPlayInitialBasicCards
+ ret
+; 0x14b30
+
+.forced_switch ; 14b30 (5:4b30)
+ call AIDecideBenchPokemonToSwitchTo
+ ret
+; 0x14b34
+
+.ko_switch ; 14b34 (5:4b34)
+ call AIDecideBenchPokemonToSwitchTo
+ ret
+; 0x14b38
+
+.take_prize ; 14b38 (5:4b38)
+ call AIPickPrizeCards
+ ret
+; 0x14b3c
+
+.list_arena ; 14b3c (5:4b3c)
+ db ELECTABUZZ2
+ db VOLTORB
+ db EEVEE
+ db ZAPDOS1
+ db ZAPDOS2
+ db ZAPDOS3
+ db $00
+
+.list_bench ; 14b43 (5:4b43)
+ db ZAPDOS2
+ db ZAPDOS1
+ db EEVEE
+ db VOLTORB
+ db ELECTABUZZ2
+ db $00
+
+.list_retreat ; 14b49 (5:4b49)
+ ai_retreat EEVEE, -5
+ ai_retreat VOLTORB, -5
+ ai_retreat ELECTABUZZ2, -5
+ db $00
+
+.list_energy ; 14b50 (5:4b50)
+ ai_energy VOLTORB, 1, -1
+ ai_energy ELECTRODE1, 3, +0
+ ai_energy ELECTABUZZ2, 2, -1
+ ai_energy JOLTEON2, 3, +1
+ ai_energy ZAPDOS1, 4, +2
+ ai_energy ZAPDOS2, 4, +2
+ ai_energy ZAPDOS3, 3, +1
+ ai_energy EEVEE, 3, +0
+ db $00
+
+.list_prize ; 14b69 (5:4b69)
+ db GAMBLER
+ db ZAPDOS3
+ db $00
+
+.store_list_pointers ; 14b6c (5:4b6c)
+ store_list_pointer wAICardListAvoidPrize, .list_prize
+ store_list_pointer wAICardListArenaPriority, .list_arena
+ store_list_pointer wAICardListBenchPriority, .list_bench
+ store_list_pointer wAICardListPlayFromHandPriority, .list_bench
+ ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat
+ store_list_pointer wAICardListEnergyBonus, .list_energy
+ ret
+; 0x14b9a
+
+AIDoTurn_LegendaryZapdos: ; 14b9a (5:4b9a)
+; initialize variables
+ call InitAITurnVars
+ farcall HandleAIAntiMewtwoDeckStrategy
+ jp nc, .try_attack
+; process Trainer cards
+ ld a, AI_TRAINER_CARD_PHASE_01
+ call AIProcessHandTrainerCards
+ ld a, AI_TRAINER_CARD_PHASE_04
+ call AIProcessHandTrainerCards
+; play Pokemon from hand
+ call AIDecidePlayPokemonCard
+ ret c ; return if turn ended
+ ld a, AI_TRAINER_CARD_PHASE_07
+ call AIProcessHandTrainerCards
+ call AIProcessRetreat
+ ld a, AI_TRAINER_CARD_PHASE_10
+ call AIProcessHandTrainerCards
+; play Energy card if possible.
+ ld a, [wAlreadyPlayedEnergy]
+ or a
+ jr nz, .skip_energy_attach
+
+; if Arena card is Voltorb and there's Electrode1 in hand,
+; or if it's Electabuzz, try attaching Energy card
+; to the Arena card if it doesn't have any energy attached.
+; Otherwise if Energy card is not needed,
+; go through normal AI energy attach routine.
+ ld a, DUELVARS_ARENA_CARD
+ call GetTurnDuelistVariable
+ call GetCardIDFromDeckIndex
+ ld a, VOLTORB
+ cp e
+ jr nz, .check_electabuzz
+ ld a, ELECTRODE1
+ call LookForCardIDInHandList_Bank5
+ jr nc, .attach_normally
+ jr .voltorb_or_electabuzz
+.check_electabuzz
+ ld a, ELECTABUZZ2
+ cp e
+ jr nz, .attach_normally
+
+.voltorb_or_electabuzz
+ call CreateEnergyCardListFromHand
+ jr c, .skip_energy_attach
+ ld e, PLAY_AREA_ARENA
+ call CountNumberOfEnergyCardsAttached
+ or a
+ jr nz, .attach_normally
+ xor a ; PLAY_AREA_ARENA
+ ldh [hTempPlayAreaLocation_ff9d], a
+ call AITryToPlayEnergyCard
+ jr c, .skip_energy_attach
+
+.attach_normally
+ call AIProcessAndTryToPlayEnergy
+
+.skip_energy_attach
+; play Pokemon from hand again
+ call AIDecidePlayPokemonCard
+ ret c ; return if turn ended
+ ld a, AI_TRAINER_CARD_PHASE_13
+ call AIProcessHandTrainerCards
+.try_attack
+; attack if possible, if not,
+; finish turn without attacking.
+ call AIProcessAndTryToUseAttack
+ ret c ; return if turn ended
+ ld a, OPPACTION_FINISH_NO_ATTACK
+ bank1call AIMakeDecision
+ ret
+; 0x14c0b
diff --git a/src/engine/deck_ai/decks/powerful_ronald.asm b/src/engine/deck_ai/decks/powerful_ronald.asm new file mode 100644 index 0000000..d99f87f --- /dev/null +++ b/src/engine/deck_ai/decks/powerful_ronald.asm @@ -0,0 +1,98 @@ +AIActionTable_PowerfulRonald: ; 1534b (5:534b)
+ dw .do_turn ; unused
+ dw .do_turn
+ dw .start_duel
+ dw .forced_switch
+ dw .ko_switch
+ dw .take_prize
+
+.do_turn ; 15357 (5:5357)
+ call AIMainTurnLogic
+ ret
+; 0x1535b
+
+.start_duel ; 1535b (5:535b)
+ call InitAIDuelVars
+ call .store_list_pointers
+ call SetUpBossStartingHandAndDeck
+ call TrySetUpBossStartingPlayArea
+ ret nc
+ call AIPlayInitialBasicCards
+ ret
+; 0x1536c
+
+.forced_switch ; 1536c (5:536c)
+ call AIDecideBenchPokemonToSwitchTo
+ ret
+; 0x15370
+
+.ko_switch ; 15370 (5:5370)
+ call AIDecideBenchPokemonToSwitchTo
+ ret
+; 0x15374
+
+.take_prize ; 15374 (5:5374)
+ call AIPickPrizeCards
+ ret
+; 0x15378
+
+.list_arena ; 15378 (5:5378)
+ db KANGASKHAN
+ db ELECTABUZZ2
+ db HITMONCHAN
+ db MR_MIME
+ db LICKITUNG
+ db HITMONLEE
+ db TAUROS
+ db JYNX
+ db MEWTWO1
+ db DODUO
+ db $00
+
+.list_bench ; 15383 (5:5383)
+ db KANGASKHAN
+ db HITMONLEE
+ db HITMONCHAN
+ db TAUROS
+ db DODUO
+ db JYNX
+ db MEWTWO1
+ db ELECTABUZZ2
+ db MR_MIME
+ db LICKITUNG
+ db $00
+
+.list_retreat ; 1538e (5:538e)
+ ai_retreat KANGASKHAN, -1
+ ai_retreat DODUO, -1
+ ai_retreat DODRIO, -1
+ db $00
+
+.list_energy ; 15395 (5:5395)
+ ai_energy ELECTABUZZ2, 2, +1
+ ai_energy HITMONLEE, 3, +1
+ ai_energy HITMONCHAN, 3, +1
+ ai_energy MR_MIME, 2, +0
+ ai_energy JYNX, 3, +0
+ ai_energy MEWTWO1, 2, +0
+ ai_energy DODUO, 3, -1
+ ai_energy DODRIO, 3, -1
+ ai_energy LICKITUNG, 2, +0
+ ai_energy KANGASKHAN, 4, -1
+ ai_energy TAUROS, 3, +0
+ db $00
+
+.list_prize ; 153b7 (5:53b7)
+ db GAMBLER
+ db ENERGY_REMOVAL
+ db $00
+
+.store_list_pointers ; 153ba (5:53ba)
+ store_list_pointer wAICardListAvoidPrize, .list_prize
+ store_list_pointer wAICardListArenaPriority, .list_arena
+ store_list_pointer wAICardListBenchPriority, .list_bench
+ store_list_pointer wAICardListPlayFromHandPriority, .list_bench
+ ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat
+ store_list_pointer wAICardListEnergyBonus, .list_energy
+ ret
+; 0x153e8
diff --git a/src/engine/deck_ai/decks/rock_crusher.asm b/src/engine/deck_ai/decks/rock_crusher.asm new file mode 100644 index 0000000..f4e79d8 --- /dev/null +++ b/src/engine/deck_ai/decks/rock_crusher.asm @@ -0,0 +1,80 @@ +AIActionTable_RockCrusher: ; 14f0e (5:4f0e)
+ dw .do_turn ; unused
+ dw .do_turn
+ dw .start_duel
+ dw .forced_switch
+ dw .ko_switch
+ dw .take_prize
+
+.do_turn ; 14f1a (5:4f1a)
+ call AIMainTurnLogic
+ ret
+; 0x14f1e
+
+.start_duel ; 14f1e (5:4f1e)
+ call InitAIDuelVars
+ call .store_list_pointers
+ call SetUpBossStartingHandAndDeck
+ call TrySetUpBossStartingPlayArea
+ ret nc
+ call AIPlayInitialBasicCards
+ ret
+; 0x14f2f
+
+.forced_switch ; 14f2f (5:4f2f)
+ call AIDecideBenchPokemonToSwitchTo
+ ret
+; 0x14f33
+
+.ko_switch ; 14f33 (5:4f33)
+ call AIDecideBenchPokemonToSwitchTo
+ ret
+; 0x14f37
+
+.take_prize ; 14f37 (5:4f37)
+ call AIPickPrizeCards
+ ret
+; 0x14f3b
+
+.list_arena ; 14f3b (5:4f3b)
+ db RHYHORN
+ db ONIX
+ db GEODUDE
+ db DIGLETT
+ db $00
+
+.list_bench ; 14f40 (5:4f40)
+ db DIGLETT
+ db GEODUDE
+ db RHYHORN
+ db ONIX
+ db $00
+
+.list_retreat ; 14f45 (5:4f45)
+ ai_retreat DIGLETT, -1
+ db $00
+
+.list_energy ; 14f48 (5:4f48)
+ ai_energy DIGLETT, 3, +1
+ ai_energy DUGTRIO, 4, +0
+ ai_energy GEODUDE, 2, +1
+ ai_energy GRAVELER, 3, +0
+ ai_energy GOLEM, 4, +0
+ ai_energy ONIX, 2, -1
+ ai_energy RHYHORN, 3, +0
+ db $00
+
+.list_prize ; 14f5e (5:4f5e)
+ db ENERGY_REMOVAL
+ db RHYHORN
+ db $00
+
+.store_list_pointers ; 14f61 (5:4f61)
+ store_list_pointer wAICardListAvoidPrize, .list_prize
+ store_list_pointer wAICardListArenaPriority, .list_arena
+ store_list_pointer wAICardListBenchPriority, .list_bench
+ store_list_pointer wAICardListPlayFromHandPriority, .list_bench
+ ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat
+ store_list_pointer wAICardListEnergyBonus, .list_energy
+ ret
+; 0x14f8f
diff --git a/src/engine/deck_ai/decks/sams_practice.asm b/src/engine/deck_ai/decks/sams_practice.asm new file mode 100644 index 0000000..2ce0060 --- /dev/null +++ b/src/engine/deck_ai/decks/sams_practice.asm @@ -0,0 +1,222 @@ +; AI for Sam's practice duel, which handles his scripted actions.
+; will act as a normal duelist AI after turn 7.
+AIActionTable_SamPractice: ; 147bd (05:47bd)
+ dw .do_turn ; unused
+ dw .do_turn
+ dw .start_duel
+ dw .forced_switch
+ dw .ko_switch
+ dw .take_prize
+
+.do_turn ; 147c9 (5:47c9)
+ call IsAIPracticeScriptedTurn
+ jr nc, .scripted_1
+; not scripted, use AI main turn logic
+ call AIMainTurnLogic
+ ret
+.scripted_1 ; use scripted actions instead
+ call AIPerformSciptedTurn
+ ret
+; 0x147d6
+
+.start_duel ; 147d6 (5:47d6)
+ call SetSamsStartingPlayArea
+ ret
+; 0x147da
+
+.forced_switch ; 147da (5:47da)
+ call IsAIPracticeScriptedTurn
+ jr nc, .scripted_2
+ call AIDecideBenchPokemonToSwitchTo
+ ret
+.scripted_2
+ call PickRandomBenchPokemon
+ ret
+; 0x147e7
+
+.ko_switch: ; 147e7 (5:47e7)
+ call IsAIPracticeScriptedTurn
+ jr nc, .scripted_3
+ call AIDecideBenchPokemonToSwitchTo
+ ret
+.scripted_3
+ call GetPlayAreaLocationOfRaticateOrRattata
+ ret
+; 0x147f4
+
+.take_prize: ; 147f4 (5:47f4)
+ call AIPickPrizeCards
+ ret
+; 0x147f8
+
+; returns carry if number of turns
+; the AI has taken >= 7.
+; used to know whether AI Sam is still
+; doing scripted turns.
+IsAIPracticeScriptedTurn: ; 147f8 (5:47f8)
+ ld a, [wDuelTurns]
+ srl a
+ cp 7
+ ccf
+ ret
+; 0x14801
+
+; places one Machop from the hand to the Play Area
+; and sets the number of prizes to 2.
+SetSamsStartingPlayArea: ; 14801 (5:4801)
+ call CreateHandCardList
+ ld hl, wDuelTempList
+.loop_hand
+ ld a, [hli]
+ ldh [hTempCardIndex_ff98], a
+ cp $ff
+ ret z
+ call LoadCardDataToBuffer1_FromDeckIndex
+ cp MACHOP
+ jr nz, .loop_hand
+ ldh a, [hTempCardIndex_ff98]
+ call PutHandPokemonCardInPlayArea
+ ld a, 2
+ ld [wDuelInitialPrizes], a
+ ret
+; 0x1481f
+
+; outputs in a Play Area location of Raticate or Rattata
+; in the Bench. If neither is found, just output PLAY_AREA_BENCH_1.
+GetPlayAreaLocationOfRaticateOrRattata: ; 1481f (5:481f)
+ ld a, RATICATE
+ ld b, PLAY_AREA_BENCH_1
+ call LookForCardIDInPlayArea_Bank5
+ cp $ff
+ jr nz, .found
+ ld a, RATTATA
+ ld b, PLAY_AREA_BENCH_1
+ call LookForCardIDInPlayArea_Bank5
+ cp $ff
+ jr nz, .found
+ ld a, PLAY_AREA_BENCH_1
+.found
+ ldh [hTempPlayAreaLocation_ff9d], a
+ ret
+; 0x1483a
+
+; has AI execute some scripted actions depending on Duel turn.
+AIPerformSciptedTurn: ; 1483a (5:483a)
+ ld a, [wDuelTurns]
+ srl a
+ ld hl, .scripted_actions_list
+ call JumpToFunctionInTable
+
+; always attack with Arena card's first attack.
+; if it's unusable end turn without attacking.
+ xor a
+ ldh [hTempPlayAreaLocation_ff9d], a
+ ld [wSelectedAttack], a
+ call CheckIfSelectedMoveIsUnusable
+ jr c, .unusable
+ call AITryUseAttack
+ ret
+
+.unusable
+ ld a, OPPACTION_FINISH_NO_ATTACK
+ bank1call AIMakeDecision
+ ret
+; 0x1485a
+
+.scripted_actions_list ; 1485a (05:485a)
+ dw .turn_1
+ dw .turn_2
+ dw .turn_3
+ dw .turn_4
+ dw .turn_5
+ dw .turn_6
+ dw .turn_7
+; 0x14868
+
+.turn_1 ; 14868 (5:4868)
+ ld d, MACHOP
+ ld e, FIGHTING_ENERGY
+ call AIAttachEnergyInHandToCardInPlayArea
+ ret
+; 0x14870
+
+.turn_2 ; 14870 (5:4870)
+ ld a, RATTATA
+ call LookForCardIDInHandList_Bank5
+ ldh [hTemp_ffa0], a
+ ld a, OPPACTION_PLAY_BASIC_PKMN
+ bank1call AIMakeDecision
+ ld d, RATTATA
+ ld e, FIGHTING_ENERGY
+ call AIAttachEnergyInHandToCardInPlayArea
+ ret
+; 0x14884
+
+.turn_3 ; 14884 (5:4884)
+ ld a, RATTATA
+ ld b, PLAY_AREA_ARENA
+ call LookForCardIDInPlayArea_Bank5
+ ldh [hTempPlayAreaLocation_ffa1], a
+ ld a, RATICATE
+ call LookForCardIDInHandList_Bank5
+ ldh [hTemp_ffa0], a
+ ld a, OPPACTION_EVOLVE_PKMN
+ bank1call AIMakeDecision
+ ld d, RATICATE
+ ld e, LIGHTNING_ENERGY
+ call AIAttachEnergyInHandToCardInPlayArea
+ ret
+; 0x148a1
+
+.turn_4 ; 148a1 (5:48a1)
+ ld d, RATICATE
+ ld e, LIGHTNING_ENERGY
+ call AIAttachEnergyInHandToCardInPlayArea
+ ret
+; 0x148a9
+
+.turn_5 ; 148a9 (5:48a9)
+ ld a, MACHOP
+ call LookForCardIDInHandList_Bank5
+ ldh [hTemp_ffa0], a
+ ld a, OPPACTION_PLAY_BASIC_PKMN
+ bank1call AIMakeDecision
+ ld d, MACHOP
+ ld e, FIGHTING_ENERGY
+ call AIAttachEnergyInHandToCardInBench
+
+; this is a bug, it's attempting to compare a card ID with a deck index.
+; the intention was to change the card to switch to depending on whether
+; the first Machop was KO'd at this point in the Duel or not.
+; because of the buggy comparison, this will always jump the
+; 'inc a' instruction and switch to PLAY_AREA_BENCH_1.
+; in a normal Practice Duel following Dr. Mason's instructions,
+; this will always lead to the AI correctly switching Raticate with Machop,
+; but in case of a "Free" Duel where the first Machop is not KO'd,
+; the intention was to switch to PLAY_AREA_BENCH_2 instead.
+; but due to 'inc a' always being skipped, it will switch to Raticate.
+ ld a, DUELVARS_ARENA_CARD
+ call GetTurnDuelistVariable
+ cp MACHOP ; wrong
+ ld a, PLAY_AREA_BENCH_1
+ jr nz, .retreat
+ inc a ; PLAY_AREA_BENCH_2
+
+.retreat
+ call AITryToRetreat
+ ret
+; 0x148cc
+
+.turn_6 ; 148cc (5:48cc)
+ ld d, MACHOP
+ ld e, FIGHTING_ENERGY
+ call AIAttachEnergyInHandToCardInPlayArea
+ ret
+; 0x148d4
+
+.turn_7 ; 148d4 (5:48d4)
+ ld d, MACHOP
+ ld e, FIGHTING_ENERGY
+ call AIAttachEnergyInHandToCardInPlayArea
+ ret
+; 0x148dc
diff --git a/src/engine/deck_ai/decks/strange_psyshock.asm b/src/engine/deck_ai/decks/strange_psyshock.asm new file mode 100644 index 0000000..309ef11 --- /dev/null +++ b/src/engine/deck_ai/decks/strange_psyshock.asm @@ -0,0 +1,87 @@ +AIActionTable_StrangePsyshock: ; 15122 (5:5122)
+ dw .do_turn ; unused
+ dw .do_turn
+ dw .start_duel
+ dw .forced_switch
+ dw .ko_switch
+ dw .take_prize
+
+.do_turn ; 1512e (5:512e)
+ call AIMainTurnLogic
+ ret
+; 0x15132
+
+.start_duel ; 15132 (5:5132)
+ call InitAIDuelVars
+ call .store_list_pointers
+ call SetUpBossStartingHandAndDeck
+ call TrySetUpBossStartingPlayArea
+ ret nc
+ call AIPlayInitialBasicCards
+ ret
+; 0x15143
+
+.forced_switch ; 15143 (5:5143)
+ call AIDecideBenchPokemonToSwitchTo
+ ret
+; 0x15147
+
+.ko_switch ; 15147 (5:5147)
+ call AIDecideBenchPokemonToSwitchTo
+ ret
+; 0x1514b
+
+.take_prize ; 1514b (5:514b)
+ call AIPickPrizeCards
+ ret
+; 0x1514f
+
+.list_arena ; 1514f (5:514f)
+ db KANGASKHAN
+ db CHANSEY
+ db SNORLAX
+ db MR_MIME
+ db ABRA
+ db $00
+
+.list_bench ; 15155 (5:5155)
+ db ABRA
+ db MR_MIME
+ db KANGASKHAN
+ db SNORLAX
+ db CHANSEY
+ db $00
+
+.list_retreat ; 1515b (5:515b)
+ ai_retreat ABRA, -3
+ ai_retreat SNORLAX, -3
+ ai_retreat KANGASKHAN, -1
+ ai_retreat CHANSEY, -1
+ db $00
+
+.list_energy ; 15164 (5:5164)
+ ai_energy ABRA, 3, +1
+ ai_energy KADABRA, 3, +0
+ ai_energy ALAKAZAM, 3, +0
+ ai_energy MR_MIME, 2, +0
+ ai_energy CHANSEY, 2, -2
+ ai_energy KANGASKHAN, 4, -2
+ ai_energy SNORLAX, 0, -8
+ db $00
+
+.list_prize ; 1517a (5:517a)
+ db GAMBLER
+ db MR_MIME
+ db ALAKAZAM
+ db SWITCH
+ db $00
+
+.store_list_pointers ; 1517f (5:517f)
+ store_list_pointer wAICardListAvoidPrize, .list_prize
+ store_list_pointer wAICardListArenaPriority, .list_arena
+ store_list_pointer wAICardListBenchPriority, .list_bench
+ store_list_pointer wAICardListPlayFromHandPriority, .list_bench
+ ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat
+ store_list_pointer wAICardListEnergyBonus, .list_energy
+ ret
+; 0x151ad
diff --git a/src/engine/deck_ai/decks/wonders_of_science.asm b/src/engine/deck_ai/decks/wonders_of_science.asm new file mode 100644 index 0000000..e11a829 --- /dev/null +++ b/src/engine/deck_ai/decks/wonders_of_science.asm @@ -0,0 +1,83 @@ +AIActionTable_WondersOfScience: ; 151ad (5:51ad)
+ dw .do_turn ; unused
+ dw .do_turn
+ dw .start_duel
+ dw .forced_switch
+ dw .ko_switch
+ dw .take_prize
+
+.do_turn ; 151b9 (5:51b9)
+ call AIMainTurnLogic
+ ret
+; 0x151bd
+
+.start_duel ; 151bd (5:51bd)
+ call InitAIDuelVars
+ call .store_list_pointers
+ call SetUpBossStartingHandAndDeck
+ call TrySetUpBossStartingPlayArea
+ ret nc
+ call AIPlayInitialBasicCards
+ ret
+; 0x151ce
+
+.forced_switch ; 151ce (5:51ce)
+ call AIDecideBenchPokemonToSwitchTo
+ ret
+; 0x151d2
+
+.ko_switch ; 151d2 (5:51d2)
+ call AIDecideBenchPokemonToSwitchTo
+ ret
+; 0x151d6
+
+.take_prize ; 151d6 (5:51d6)
+ call AIPickPrizeCards
+ ret
+; 0x151da
+
+.list_arena ; 151da (5:51da)
+ db MEWTWO1
+ db MEWTWO3
+ db MEWTWO2
+ db GRIMER
+ db KOFFING
+ db PORYGON
+ db $00
+
+.list_bench ; 151e1 (5:51e1)
+ db GRIMER
+ db KOFFING
+ db MEWTWO3
+ db MEWTWO2
+ db MEWTWO1
+ db PORYGON
+ db $00
+
+.list_retreat ; 151e8 (5:51e8)
+ db $00
+
+.list_energy ; 151e9 (5:51e9)
+ ai_energy GRIMER, 3, +0
+ ai_energy MUK, 4, +0
+ ai_energy KOFFING, 2, +0
+ ai_energy WEEZING, 3, +0
+ ai_energy MEWTWO1, 2, -1
+ ai_energy MEWTWO3, 2, -1
+ ai_energy MEWTWO2, 2, -1
+ ai_energy PORYGON, 2, -1
+ db $00
+
+.list_prize ; 15202 (5:5202)
+ db MUK
+ db $00
+
+.store_list_pointers ; 15204 (5:5204)
+ store_list_pointer wAICardListAvoidPrize, .list_prize
+ store_list_pointer wAICardListArenaPriority, .list_arena
+ store_list_pointer wAICardListBenchPriority, .list_bench
+ store_list_pointer wAICardListPlayFromHandPriority, .list_bench
+ ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat
+ store_list_pointer wAICardListEnergyBonus, .list_energy
+ ret
+; 0x15232
diff --git a/src/engine/deck_ai/decks/zapping_selfdestruct.asm b/src/engine/deck_ai/decks/zapping_selfdestruct.asm new file mode 100644 index 0000000..6675c52 --- /dev/null +++ b/src/engine/deck_ai/decks/zapping_selfdestruct.asm @@ -0,0 +1,81 @@ +AIActionTable_ZappingSelfdestruct: ; 15019 (5:5019)
+ dw .do_turn ; unused
+ dw .do_turn
+ dw .start_duel
+ dw .forced_switch
+ dw .ko_switch
+ dw .take_prize
+
+.do_turn ; 15025 (5:5025)
+ call AIMainTurnLogic
+ ret
+; 0x15029
+
+.start_duel ; 15029 (5:5029)
+ call InitAIDuelVars
+ call .store_list_pointers
+ call SetUpBossStartingHandAndDeck
+ call TrySetUpBossStartingPlayArea
+ ret nc
+ call AIPlayInitialBasicCards
+ ret
+; 0x1503a
+
+.forced_switch ; 1503a (5:503a)
+ call AIDecideBenchPokemonToSwitchTo
+ ret
+; 0x1503e
+
+.ko_switch ; 1503e (5:503e)
+ call AIDecideBenchPokemonToSwitchTo
+ ret
+; 0x15042
+
+.take_prize ; 15042 (5:5042)
+ call AIPickPrizeCards
+ ret
+; 0x15046
+
+.list_arena ; 15046 (5:5046)
+ db KANGASKHAN
+ db ELECTABUZZ2
+ db TAUROS
+ db MAGNEMITE1
+ db VOLTORB
+ db $00
+
+.list_bench ; 1504c (5:504c)
+ db MAGNEMITE1
+ db VOLTORB
+ db ELECTABUZZ2
+ db TAUROS
+ db KANGASKHAN
+ db $00
+
+.list_retreat ; 15052 (5:5052)
+ ai_retreat VOLTORB, -1
+ db $00
+
+.list_energy ; 15055 (5:5055)
+ ai_energy MAGNEMITE1, 3, +1
+ ai_energy MAGNETON1, 4, +0
+ ai_energy VOLTORB, 3, +1
+ ai_energy ELECTRODE1, 3, +0
+ ai_energy ELECTABUZZ2, 1, +0
+ ai_energy KANGASKHAN, 2, -2
+ ai_energy TAUROS, 3, +0
+ db $00
+
+.list_prize ; 1506b (5:506b)
+ db KANGASKHAN
+ db $00
+
+.store_list_pointers ; 1506d (5:506d)
+ store_list_pointer wAICardListAvoidPrize, .list_prize
+ store_list_pointer wAICardListArenaPriority, .list_arena
+ store_list_pointer wAICardListBenchPriority, .list_bench
+ store_list_pointer wAICardListPlayFromHandPriority, .list_bench
+ ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat
+ store_list_pointer wAICardListEnergyBonus, .list_energy
+ ret
+; 0x1509b
diff --git a/src/engine/effect_functions.asm b/src/engine/effect_functions.asm index 116d545..75b0f76 100644 --- a/src/engine/effect_functions.asm +++ b/src/engine/effect_functions.asm @@ -292,7 +292,9 @@ ApplySubstatus2ToDefendingCard: ; 2c149 (b:4149) ret ; 0x2c166 -Func_2c166: ; 2c166 (b:4166) +; overwrites in wDamage, wAIMinDamage and wAIMaxDamage +; with the value in a. +StoreDamageInfo: ; 2c166 (b:4166) ld [wDamage], a ld [wAIMinDamage], a ld [wAIMaxDamage], a @@ -301,7 +303,181 @@ Func_2c166: ; 2c166 (b:4166) ret ; 0x2c174 - INCROM $2c174, $2c6f0 + INCROM $2c174, $2c1ec + +HandleSwitchDefendingPokemonEffect: ; 2c1ec (b:41ec) + ld e, a + cp $ff + ret z + +; check Defending Pokemon's HP + ld a, DUELVARS_ARENA_CARD_HP + call GetNonTurnDuelistVariable + or a + jr nz, .switch + +; if 0, handle Destiny Bond first + push de + bank1call HandleDestinyBondSubstatus + pop de + +.switch + call .HandleNoDamageOrEffect + ret c + +; attack was successful, switch Defending Pokemon + call SwapTurn + call SwapArenaWithBenchPokemon + call SwapTurn + + xor a + ld [wccc5], a + ld [wDuelDisplayedScreen], a + inc a + ld [wccef], a + ret +; 0x2c216 + +; returns carry if Defending has No Damage or Effect +; if so, print its appropriate text. +.HandleNoDamageOrEffect: ; 2c216 (b:4216) + call CheckNoDamageOrEffect + ret nc + ld a, l + or h + call nz, DrawWideTextBox_PrintText + scf + ret +; 0x2c221 + + INCROM $2c221, $2c2a4 + +; makes a list in wDuelTempList with the deck indices +; of all the energy cards found in opponent's Discard Pile. +; if (c == 0), all energy cards are allowed; +; if (c != 0), double colorless energy cards are not counted. +; returns carry if no energy cards were found. +CreateEnergyCardListFromOpponentDiscardPile: ; 2c2a4 (b:42a4) + ld c, $00 + +; get number of cards in Discard Pile +; and have hl point to the end of the +; Discard Pile list in wOpponentDeckCards. + ld a, DUELVARS_NUMBER_OF_CARDS_IN_DISCARD_PILE + call GetTurnDuelistVariable + ld b, a + add DUELVARS_DECK_CARDS + ld l, a + + ld de, wDuelTempList + inc b + jr .next_card + +.check_energy + ld a, [hl] + call LoadCardDataToBuffer2_FromDeckIndex + ld a, [wLoadedCard2Type] + and TYPE_ENERGY + jr z, .next_card + +; if (c != $00), then we dismiss Double Colorless +; energy cards found. + ld a, c + or a + jr z, .copy + ld a, [wLoadedCard2Type] + cp TYPE_ENERGY_DOUBLE_COLORLESS + jr nc, .next_card + +.copy + ld a, [hl] + ld [de], a + inc de + +; goes through Discard Pile list +; in wOpponentDeckCards in descending order. +.next_card + dec l + dec b + jr nz, .check_energy + +; terminating byte on wDuelTempList + ld a, $ff + ld [de], a + +; check if any energy card was found +; by checking whether the first byte +; in wDuelTempList is $ff. +; if none were found, return carry. + ld a, [wDuelTempList] + cp $ff + jr z, .set_carry + or a + ret + +.set_carry + scf + ret +; 0x2c2e0 + + INCROM $2c2e0, $2c487 + +; handles the selection of a forced switch +; by link/AI opponent or by the player. +; outputs the Play Area location of the chosen +; bench card in hTempPlayAreaLocation_ff9d. +DuelistSelectForcedSwitch: ; 2c487 (b:4487) + ld a, DUELVARS_DUELIST_TYPE + call GetNonTurnDuelistVariable + cp DUELIST_TYPE_LINK_OPP + jr z, .link_opp + + cp DUELIST_TYPE_PLAYER + jr z, .player + +; AI opponent + call SwapTurn + bank1call AIDoAction_ForcedSwitch + call SwapTurn + + ld a, [wPlayerAttackingMoveIndex] + ld e, a + ld a, [wPlayerAttackingCardIndex] + ld d, a + ld a, [wPlayerAttackingCardID] + call CopyMoveDataAndDamage_FromCardID + call Func_16f6 + ret + +.player + ldtx hl, SelectPkmnOnBenchToSwitchWithActiveText + call DrawWideTextBox_WaitForInput + call SwapTurn + bank1call HasAlivePokemonInBench + ld a, $01 + ld [wcbd4], a +.asm_2c4c0 + bank1call OpenPlayAreaScreenForSelection + jr c, .asm_2c4c0 + call SwapTurn + ret + +.link_opp +; get selection from link opponent + ld a, OPPACTION_FORCE_SWITCH_ACTIVE + call SetOppAction_SerialSendDuelData +.loop + call SerialRecvByte + jr nc, .received + halt + nop + jr .loop +.received + ldh [hTempPlayAreaLocation_ff9d], a + ret +; 0x2c4da + + INCROM $2c4da, $2c6f0 SpitPoison_AIEffect: ; 2c6f0 (b:46f0) ld a, 5 @@ -320,7 +496,44 @@ SpitPoison_Poison50PercentEffect: ; 2c6f8 (b:46f8) ret ; 0x2c70a - INCROM $2c70a, $2c730 +; outputs in hTemp_ffa0 the result of the coin toss +; (0 = tails, 1 = heads) and, in case it was heads, +; stores in hTempPlayAreaLocation_ffa1 the location +; of the Bench Pokemon that was selected for switch. +TerrorStrike_50PercentSelectSwitchPokemon: ; 2c70a (b:470a) + xor a + ldh [hTemp_ffa0], a + +; return failure if no Pokemon to switch to + ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA + call GetNonTurnDuelistVariable + cp 2 + ret c + +; toss coin and store whether it was tails (0) +; or heads (1) in hTemp_ffa0 +; return if it was tails. + ldtx de, IfHeadsChangeOpponentsActivePokemonText + call Func_2c08a + ldh [hTemp_ffa0], a + ret nc + + call DuelistSelectForcedSwitch + ldh a, [hTempPlayAreaLocation_ff9d] + ldh [hTempPlayAreaLocation_ffa1], a + ret +; 0x2c726 + +; if coin toss was heads and it's possible, +; switch Defending Pokemon +TerrorStrike_SwitchDefendingPokemon: ; 2c726 (b:4726) + ldh a, [hTemp_ffa0] + or a + ret z + ldh a, [hTempPlayAreaLocation_ffa1] + call HandleSwitchDefendingPokemonEffect + ret +; 0x2c730 PoisonFang_AIEffect: ; 2c730 (b:4730) ld a, 10 @@ -417,7 +630,7 @@ Twineedle_MultiplierEffect: ; 2c7f5 (b:47f5) add a add e call ATimes10 - call Func_2c166 + call StoreDamageInfo ret ; 0x2c80d @@ -538,4 +751,16 @@ Toxic_DoublePoisonEffect: ; 2c994 (b:4994) ret ; 0x2c998 - INCROM $2c998, $30000 + INCROM $2c998, $2cbfb + +Func_2cbfb: ; 2cbfb (b:4bfb) + ldh a, [hAIEnergyTransPlayAreaLocation] + ld e, a + ldh a, [hAIEnergyTransEnergyCard] + call AddCardToHand + call PutHandCardInPlayArea + bank1call PrintPlayAreaCardList_EnableLCD + ret +; 0x2cc0a + + INCROM $2cc0a, $30000 diff --git a/src/engine/home.asm b/src/engine/home.asm index 545995a..78e0bf1 100644 --- a/src/engine/home.asm +++ b/src/engine/home.asm @@ -1552,7 +1552,7 @@ Func_08bf: ; 08bf (0:08bf) ld [hli], a ld [hl], b inc hl - ld [hli], a + ld [hli], a ; 0 ld [hl], $ef ld h, b ld l, $0 @@ -3419,6 +3419,7 @@ CreateArenaOrBenchEnergyCardList: ; 120a (0:120a) ; fill wDuelTempList with the turn holder's hand cards (their 0-59 deck indexes) ; return carry if the turn holder has no cards in hand +; and outputs in a number of cards. CreateHandCardList: ; 123b (0:123b) call FindLastCardInHand inc b @@ -5218,7 +5219,7 @@ Func_1bca: ; 1bca (0:1bca) ret ; 0x1c05 -; return in a the retreat cost of the turn holder's arena or benchx Pokemon +; return in a the retreat cost of the turn holder's arena or bench Pokemon ; given the PLAY_AREA_* value in hTempPlayAreaLocation_ff9d GetPlayAreaCardRetreatCost: ; 1c05 (0:1c05) ldh a, [hTempPlayAreaLocation_ff9d] @@ -8279,56 +8280,70 @@ LoadOpponentDeck: ; 2b78 (0:2b78) ld [hl], a ret -Func_2bbf: ; 2bbf (0:2bbf) - ld a, $1 - jr Func_2bdb +AIDoAction_Turn: ; 2bbf (0:2bbf) + ld a, AIACTION_DO_TURN + jr AIDoAction -Func_2bc3: ; 2bc3 (0:2bc3) - ld a, $2 - jr Func_2bdb +AIDoAction_StartDuel: ; 2bc3 (0:2bc3) + ld a, AIACTION_START_DUEL + jr AIDoAction -Func_2bc7: ; 2bc7 (0:2bc7) - ld a, $3 - call Func_2bdb +AIDoAction_ForcedSwitch: ; 2bc7 (0:2bc7) + ld a, AIACTION_FORCED_SWITCH + call AIDoAction ldh [hTempPlayAreaLocation_ff9d], a ret -Func_2bcf: ; 2bcf (0:2bcf) - ld a, $4 - call Func_2bdb +AIDoAction_KOSwitch: ; 2bcf (0:2bcf) + ld a, AIACTION_KO_SWITCH + call AIDoAction ldh [hTemp_ffa0], a ret -Func_2bd7: ; 2bd7 (0:2bd7) - ld a, $5 - jr Func_2bdb +AIDoAction_TakePrize: ; 2bd7 (0:2bd7) + ld a, AIACTION_TAKE_PRIZE + jr AIDoAction ; this line is not needed -Func_2bdb: ; 2bdb (0:2bdb) +; calls the appropriate AI routine to handle action, +; depending on the deck ID (see engine/deck_ai/deck_ai.asm) +; input: +; - a = AIACTION_* constant +AIDoAction: ; 2bdb (0:2bdb) ld c, a + +; load bank for Opponent Deck pointer table ldh a, [hBankROM] push af - ld a, BANK(PointerTable_14000) + ld a, BANK(DeckAIPointerTable) call BankswitchROM + +; load hl with the corresponding pointer ld a, [wOpponentDeckID] ld l, a ld h, $0 - add hl, hl - ld de, PointerTable_14000 + add hl, hl ; two bytes per deck + ld de, DeckAIPointerTable add hl, de ld a, [hli] ld h, [hl] ld l, a + ld a, c or a - jr nz, .asm_2bfe + jr nz, .not_zero + +; if input was 0, copy deck data of turn player ld e, [hl] inc hl ld d, [hl] call CopyDeckData - jr .asm_2c01 -.asm_2bfe + jr .done + +; jump to corresponding AI routine related to input +.not_zero call JumpToFunctionInTable -.asm_2c01 + +.done ld c, a pop af call BankswitchROM @@ -10800,8 +10815,8 @@ GameEvent_Credits: ; 3911 (0:3911) ret Func_3917: ; 3917 (0:3917) - ld a, $22 - farcall CheckIfEventFlagSet + ld a, EVENT_RECEIVED_LEGENDARY_CARD + farcall GetEventFlagValue call EnableSRAM ld [s0a00a], a call DisableSRAM @@ -10865,7 +10880,7 @@ GetPermissionByteOfMapPosition: ; 3946 (0:3946) Func_395a: ; 395a (0:395a) ldh a, [hBankROM] push af - ld a, [wd4c6] + ld a, [wTempPointerBank] call BankswitchROM call CopyGfxData pop af @@ -10875,8 +10890,8 @@ Func_395a: ; 395a (0:395a) Unknown_396b: ; 396b (0:396b) db $00, -$01, $01, $00, $00, $01, -$01, $00 -; Movement offsets for scripted movements -ScriptedMovementOffsetTable: ; 3973 (0:3973) +; Movement offsets for player movements +PlayerMovementOffsetTable: ; 3973 (0:3973) db 0, -2 ; move 2 tiles up db 2, 0 ; move 2 tiles right db 0, 2 ; move 2 tiles down @@ -10908,15 +10923,16 @@ Func_3997: ; 3997 (0:3997) call BankswitchROM ret -Func_39a7: ; 39a7 (0:39a7) - ld l, $0 - call Func_39ad +; returns in hl a pointer to the first element for the a'th NPC +GetLoadedNPCID: ; 39a7 (0:39a7) + ld l, LOADED_NPC_ID + call GetItemInLoadedNPCIndex ret -; return hl = wd34a + a * $c + l, with a < $8 -Func_39ad: ; 39ad (0:39ad) +; return in hl a pointer to the a'th items element l +GetItemInLoadedNPCIndex: ; 39ad (0:39ad) push bc - cp $8 + cp LOADED_NPC_MAX jr c, .asm_39b4 debug_ret xor a @@ -10929,36 +10945,39 @@ Func_39ad: ; 39ad (0:39ad) add l ld l, a ld h, $0 - ld bc, wd34a + ld bc, wLoadedNPCs add hl, bc pop bc ret -Func_39c3: ; 39c3 (0:39c3) +; Finds the index on wLoadedNPCs table of the npc in wTempNPC +; returns it in a and puts it into wLoadedNPCTempIndex +; c flag set if no npc found +FindLoadedNPC: ; 39c3 (0:39c3) push hl push bc push de xor a - ld [wd3aa], a + ld [wLoadedNPCTempIndex], a ld b, a - ld c, $8 - ld de, $000c - ld hl, wd34a - ld a, [wd3ab] -.asm_39d6 + ld c, LOADED_NPC_MAX + ld de, LOADED_NPC_LENGTH + ld hl, wLoadedNPCs + ld a, [wTempNPC] +.findNPCLoop cp [hl] - jr z, .asm_39e1 + jr z, .foundNPCMatch add hl, de inc b dec c - jr nz, .asm_39d6 + jr nz, .findNPCLoop scf - jr z, .asm_39e6 -.asm_39e1 + jr z, .exit +.foundNPCMatch ld a, b - ld [wd3aa], a + ld [wLoadedNPCTempIndex], a or a -.asm_39e6 +.exit pop de pop bc pop hl @@ -11055,65 +11074,68 @@ Func_3a4f: ; 3a4f (0:3a4f) ret ; 0x3a5e -Func_3a5e: ; 3a5e (0:3a5e) +HandleMoveModeAPress: ; 3a5e (0:3a5e) ldh a, [hBankROM] push af - ld l, $4 - call Func_3abd - jr nc, .asm_3ab3 - ld a, BANK(Func_c653) + ld l, MAP_SCRIPT_OBJECTS + call GetMapScriptPointer + jr nc, .handleSecondAPressScript + ld a, BANK(FindPlayerMovementFromDirection) call BankswitchROM - call Func_c653 - ld a, $4 + call FindPlayerMovementFromDirection + ld a, BANK(MapScripts) call BankswitchROM - ld a, [wd334] + ld a, [wPlayerDirection] ld d, a -.asm_3a79 +.findAPressMatchLoop ld a, [hli] bit 7, a - jr nz, .asm_3ab3 + jr nz, .handleSecondAPressScript push bc push hl cp d - jr nz, .asm_3aab + jr nz, .noMatch ld a, [hli] cp b - jr nz, .asm_3aab + jr nz, .noMatch ld a, [hli] cp c - jr nz, .asm_3aab + jr nz, .noMatch ld a, [hli] - ld [wd0c6], a + ld [wNextScript], a ld a, [hli] - ld [wd0c7], a + ld [wNextScript+1], a ld a, [hli] - ld [wd0ca], a + ld [wDefaultObjectText], a ld a, [hli] - ld [wd0cb], a + ld [wDefaultObjectText+1], a ld a, [hli] - ld [wd0c8], a + ld [wCurrentNPCNameTx], a ld a, [hli] - ld [wd0c9], a + ld [wCurrentNPCNameTx+1], a pop hl pop bc pop af call BankswitchROM scf ret -.asm_3aab +.noMatch pop hl - ld bc, $0008 + ld bc, MAP_OBJECT_SIZE - 1 add hl, bc pop bc - jr .asm_3a79 -.asm_3ab3 + jr .findAPressMatchLoop +.handleSecondAPressScript pop af call BankswitchROM - ld l, $6 - call $49c2 + ld l, MAP_SCRIPT_PRESSED_A + call CallMapScriptPointerIfExists ret -Func_3abd: ; 3abd (0:3abd) +; returns a map script pointer in hl given +; current map in wCurMap and which sub-script in l +; sets c if pointer is found +GetMapScriptPointer: ; 3abd (0:3abd) push bc push hl ld a, [wCurMap] @@ -11152,9 +11174,9 @@ Func_3ae8: ; 3ae8 (0:3ae8) ret ; 0x3aed -; finds an OWScript from the first byte and puts the next two bytes (usually arguments?) into cb +; finds a Script from the first byte and puts the next two bytes (usually arguments?) into cb RunOverworldScript: ; 3aed (0:3aed) - ld hl, wOWScriptPointer + ld hl, wScriptPointer ld a, [hli] ld h, [hl] ld l, a @@ -11321,7 +11343,7 @@ ResetDoFrameFunction: ; 3bdb (0:3bdb) Func_3be4: ; 3be4 (0:3be4) ldh a, [hBankROM] push af - ld a, [wd4c6] + ld a, [wTempPointerBank] call BankswitchROM call Func_08de pop af @@ -11329,15 +11351,16 @@ Func_3be4: ; 3be4 (0:3be4) ret ; 0x3bf5 -Func_3bf5: ; 3bf5 (0:3bf5) +; Copies bc bytes from [wTempPointer] to de +CopyBankedDataToDE: ; 3bf5 (0:3bf5) ldh a, [hBankROM] push af push hl - ld a, [wd4c6] + ld a, [wTempPointerBank] call BankswitchROM - ld a, [wd4c4] + ld a, [wTempPointer] ld l, a - ld a, [wd4c5] + ld a, [wTempPointer + 1] ld h, a call CopyDataHLtoDE_SaveRegisters pop hl @@ -11407,9 +11430,8 @@ CallHL2: ; 3c45 (0:3c45) jp hl ; 0x3c46 -PushBC_Ret: ; 3c46 (0:3c46) - push bc - ret +CallBC: ; 3c46 (0:3c46) + retbc ; 0x3c48 DoFrameIfLCDEnabled: ; 3c48 (0:3c48) @@ -11460,7 +11482,7 @@ DivideBCbyDE: ; 3c5a (0:3c5a) jr nz, .asm_3c63 ret -Func_3c83: ; 3c83 (0:3c83) +CallPlaySong: ; 3c83 (0:3c83) call PlaySong ret ; 0x3c87 @@ -11470,18 +11492,19 @@ Func_3c87: ; 3c87 (0:3c87) call PauseSong pop af call PlaySong - call Func_3c96 + call WaitForSongToFinish call ResumeSong ret ; 0x3c96 -Func_3c96: ; 3c96 (0:3c96) +WaitForSongToFinish: ; 3c96 (0:3c96) call DoFrameIfLCDEnabled call AssertSongFinished or a - jr nz, Func_3c96 + jr nz, WaitForSongToFinish ret +; clear [SOMETHING] - something relating to animations Func_3ca0: ; 3ca0 (0:3ca0) xor a ld [wd5d7], a @@ -11634,11 +11657,11 @@ Func_3d72: ; 3d72 (0:3d72) xor a jr .asm_3da1 .asm_3d84 - ld a, [wd4c4] + ld a, [wTempPointer] ld l, a - ld a, [wd4c5] + ld a, [wTempPointer + 1] ld h, a - ld a, [wd4c6] + ld a, [wTempPointerBank] call BankswitchROM ld a, [hli] push af @@ -11669,7 +11692,7 @@ Func_3d72: ; 3d72 (0:3d72) call BankswitchROM ret -Func_3db7: ; 3db7 (0:3db7) +GetFirstSpriteAnimBufferProperty: ; 3db7 (0:3db7) push bc ld c, SPRITE_ANIM_FIELD_00 call GetSpriteAnimBufferProperty |