diff options
Diffstat (limited to 'engine/events')
28 files changed, 3855 insertions, 0 deletions
diff --git a/engine/events/black_out.asm b/engine/events/black_out.asm new file mode 100644 index 00000000..6c358ce3 --- /dev/null +++ b/engine/events/black_out.asm @@ -0,0 +1,46 @@ +ResetStatusAndHalveMoneyOnBlackout:: +; Reset player status on blackout. + xor a + ld [wBattleResult], a + ld [wWalkBikeSurfState], a + ld [wIsInBattle], a + ld [wMapPalOffset], a + ld [wNPCMovementScriptFunctionNum], a + ld [hJoyHeld], a + ld [wNPCMovementScriptPointerTableNum], a + ld [wFlags_0xcd60], a + + ld [hMoney], a + ld [hMoney + 1], a + ld [hMoney + 2], a + call HasEnoughMoney + jr c, .lostmoney ; never happens + + ; Halve the player's money. + ld a, [wPlayerMoney] + ld [hMoney], a + ld a, [wPlayerMoney + 1] + ld [hMoney + 1], a + ld a, [wPlayerMoney + 2] + ld [hMoney + 2], a + xor a + ld [hDivideBCDDivisor], a + ld [hDivideBCDDivisor + 1], a + ld a, 2 + ld [hDivideBCDDivisor + 2], a + predef DivideBCDPredef3 + ld a, [hDivideBCDQuotient] + ld [wPlayerMoney], a + ld a, [hDivideBCDQuotient + 1] + ld [wPlayerMoney + 1], a + ld a, [hDivideBCDQuotient + 2] + ld [wPlayerMoney + 2], a + +.lostmoney + ld hl, wd732 + set 2, [hl] + res 3, [hl] + set 6, [hl] + ld a, %11111111 + ld [wJoyIgnore], a + predef_jump HealParty diff --git a/engine/events/card_key.asm b/engine/events/card_key.asm new file mode 100755 index 00000000..c77d5fcd --- /dev/null +++ b/engine/events/card_key.asm @@ -0,0 +1,112 @@ +PrintCardKeyText: + ld hl, SilphCoMapList + ld a, [wCurMap] + ld b, a +.silphCoMapListLoop + ld a, [hli] + cp $ff + ret z + cp b + jr nz, .silphCoMapListLoop + predef GetTileAndCoordsInFrontOfPlayer + ld a, [wTileInFrontOfPlayer] + cp $18 + jr z, .cardKeyDoorInFrontOfPlayer + cp $24 + jr z, .cardKeyDoorInFrontOfPlayer + ld b, a + ld a, [wCurMap] + cp SILPH_CO_11F + ret nz + ld a, b + cp $5e + ret nz +.cardKeyDoorInFrontOfPlayer + ld b, CARD_KEY + call IsItemInBag + jr z, .noCardKey + call GetCoordsInFrontOfPlayer + push de + tx_pre_id CardKeySuccessText + ld [hSpriteIndexOrTextID], a + call PrintPredefTextID + pop de + srl d + ld a, d + ld b, a + ld [wCardKeyDoorY], a + srl e + ld a, e + ld c, a + ld [wCardKeyDoorX], a + ld a, [wCurMap] + cp SILPH_CO_11F + jr nz, .notSilphCo11F + ld a, $3 + jr .replaceCardKeyDoorTileBlock +.notSilphCo11F + ld a, $e +.replaceCardKeyDoorTileBlock + ld [wNewTileBlockID], a + predef ReplaceTileBlock + ld hl, wCurrentMapScriptFlags + set 5, [hl] + ld a, SFX_GO_INSIDE + jp PlaySound +.noCardKey + tx_pre_id CardKeyFailText + ld [hSpriteIndexOrTextID], a + jp PrintPredefTextID + +SilphCoMapList: + db SILPH_CO_2F + db SILPH_CO_3F + db SILPH_CO_4F + db SILPH_CO_5F + db SILPH_CO_6F + db SILPH_CO_7F + db SILPH_CO_8F + db SILPH_CO_9F + db SILPH_CO_10F + db SILPH_CO_11F + db $FF + +CardKeySuccessText:: + TX_FAR _CardKeySuccessText1 + TX_SFX_ITEM_1 + TX_FAR _CardKeySuccessText2 + db "@" + +CardKeyFailText:: + TX_FAR _CardKeyFailText + db "@" + +; d = Y +; e = X +GetCoordsInFrontOfPlayer: + ld a, [wYCoord] + ld d, a + ld a, [wXCoord] + ld e, a + ld a, [wSpriteStateData1 + 9] ; player's sprite facing direction + and a + jr nz, .notFacingDown +; facing down + inc d + ret +.notFacingDown + cp SPRITE_FACING_UP + jr nz, .notFacingUp +; facing up + dec d + ret +.notFacingUp + cp SPRITE_FACING_LEFT + jr nz, .notFacingLeft +; facing left + dec e + ret +.notFacingLeft +; facing right + inc e + ret diff --git a/engine/events/cinnabar_lab.asm b/engine/events/cinnabar_lab.asm new file mode 100755 index 00000000..e642840d --- /dev/null +++ b/engine/events/cinnabar_lab.asm @@ -0,0 +1,123 @@ +GiveFossilToCinnabarLab:: + ld hl, wd730 + set 6, [hl] + xor a + ld [wCurrentMenuItem], a + ld a, A_BUTTON | B_BUTTON + ld [wMenuWatchedKeys], a + ld a, [wFilteredBagItemsCount] + dec a + ld [wMaxMenuItem], a + ld a, 2 + ld [wTopMenuItemY], a + ld a, 1 + ld [wTopMenuItemX], a + ld a, [wFilteredBagItemsCount] + dec a + ld bc, 2 + ld hl, 3 + call AddNTimes + dec l + ld b, l + ld c, $d + coord hl, 0, 0 + call TextBoxBorder + call UpdateSprites + call PrintFossilsInBag + ld hl, wd730 + res 6, [hl] + call HandleMenuInput + bit 1, a ; pressed B? + jr nz, .cancelledGivingFossil + ld hl, wFilteredBagItems + ld a, [wCurrentMenuItem] + ld d, 0 + ld e, a + add hl, de + ld a, [hl] + ld [$ffdb], a + cp DOME_FOSSIL + jr z, .choseDomeFossil + cp HELIX_FOSSIL + jr z, .choseHelixFossil + ld b, AERODACTYL + jr .fossilSelected +.choseHelixFossil + ld b, OMANYTE + jr .fossilSelected +.choseDomeFossil + ld b, KABUTO +.fossilSelected + ld [wFossilItem], a + ld a, b + ld [wFossilMon], a + call LoadFossilItemAndMonName + ld hl, LabFossil_610ae + call PrintText + call YesNoChoice + ld a, [wCurrentMenuItem] + and a + jr nz, .cancelledGivingFossil + ld hl, LabFossil_610b3 + call PrintText + ld a, [wFossilItem] + ld [hItemToRemoveID], a + callba RemoveItemByID + ld hl, LabFossil_610b8 + call PrintText + SetEvents EVENT_GAVE_FOSSIL_TO_LAB, EVENT_LAB_STILL_REVIVING_FOSSIL + ret +.cancelledGivingFossil + ld hl, LabFossil_610bd + call PrintText + ret + +LabFossil_610ae: + TX_FAR _Lab4Text_610ae + db "@" + +LabFossil_610b3: + TX_FAR _Lab4Text_610b3 + db "@" + +LabFossil_610b8: + TX_FAR _Lab4Text_610b8 + db "@" + +LabFossil_610bd: + TX_FAR _Lab4Text_610bd + db "@" + +PrintFossilsInBag: +; Prints each fossil in the player's bag on a separate line in the menu. + ld hl, wFilteredBagItems + xor a + ld [hItemCounter], a +.loop + ld a, [hli] + cp $ff + ret z + push hl + ld [wd11e], a + call GetItemName + coord hl, 2, 2 + ld a, [hItemCounter] + ld bc, SCREEN_WIDTH * 2 + call AddNTimes + ld de, wcd6d + call PlaceString + ld hl, hItemCounter + inc [hl] + pop hl + jr .loop + +; loads the names of the fossil item and the resulting mon +LoadFossilItemAndMonName:: + ld a, [wFossilMon] + ld [wd11e], a + call GetMonName + call CopyStringToCF4B + ld a, [wFossilItem] + ld [wd11e], a + call GetItemName + ret diff --git a/engine/events/diploma.asm b/engine/events/diploma.asm new file mode 100755 index 00000000..e53ef58f --- /dev/null +++ b/engine/events/diploma.asm @@ -0,0 +1,113 @@ +DisplayDiploma:: + call SaveScreenTilesToBuffer2 + call GBPalWhiteOutWithDelay3 + call ClearScreen + xor a + ld [wUpdateSpritesEnabled], a + ld hl, wd730 + set 6, [hl] + call DisableLCD + ld hl, CircleTile + ld de, vChars2 + $700 + ld bc, $0010 + ld a, BANK(CircleTile) + call FarCopyData2 + coord hl, 0, 0 + lb bc, 16, 18 + predef Diploma_TextBoxBorder + ld hl, DiplomaTextPointersAndCoords + ld c, $5 +.asm_56715 + push bc + ld a, [hli] + ld e, a + ld a, [hli] + ld d, a + ld a, [hli] + push hl + ld h, [hl] + ld l, a + call PlaceString + pop hl + inc hl + pop bc + dec c + jr nz, .asm_56715 + coord hl, 10, 4 + ld de, wPlayerName + call PlaceString + callba DrawPlayerCharacter + +; Move the player 33 pixels right and set the priority bit so he appears +; behind the background layer. + ld hl, wOAMBuffer + $01 + lb bc, $80, $28 +.adjustPlayerGfxLoop + ld a, [hl] ; X + add 33 + ld [hli], a + inc hl + ld a, b + ld [hli], a ; attributes + inc hl + dec c + jr nz, .adjustPlayerGfxLoop + + call EnableLCD + callba LoadTrainerInfoTextBoxTiles + ld b, SET_PAL_GENERIC + call RunPaletteCommand + call Delay3 + call GBPalNormal + ld a, $90 + ld [rOBP0], a + call WaitForTextScrollButtonPress + ld hl, wd730 + res 6, [hl] + call GBPalWhiteOutWithDelay3 + call RestoreScreenTilesAndReloadTilePatterns + call Delay3 + jp GBPalNormal + +UnusedPlayerNameLengthFunc: +; Unused function that does a calculation involving the length of the player's +; name. + ld hl, wPlayerName + ld bc, $ff00 +.loop + ld a, [hli] + cp "@" + ret z + dec c + jr .loop + +DiplomaTextPointersAndCoords: + dw DiplomaText + dwCoord 5, 2 + dw DiplomaPlayer + dwCoord 3, 4 + dw DiplomaEmptyText + dwCoord 15, 4 + dw DiplomaCongrats + dwCoord 2, 6 + dw DiplomaGameFreak + dwCoord 9, 16 + +DiplomaText: + db $70,"Diploma",$70,"@" + +DiplomaPlayer: + db "Player@" + +DiplomaEmptyText: + db "@" + +DiplomaCongrats: + db "Congrats! This" + next "diploma certifies" + next "that you have" + next "completed your" + next "#DEX.@" + +DiplomaGameFreak: + db "GAME FREAK@" diff --git a/engine/events/display_pokedex.asm b/engine/events/display_pokedex.asm new file mode 100644 index 00000000..d657ea85 --- /dev/null +++ b/engine/events/display_pokedex.asm @@ -0,0 +1,19 @@ +_DisplayPokedex:: + ld hl, wd730 + set 6, [hl] + predef ShowPokedexData + ld hl, wd730 + res 6, [hl] + call ReloadMapData + ld c, 10 + call DelayFrames + predef IndexToPokedex + ld a, [wd11e] + dec a + ld c, a + ld b, FLAG_SET + ld hl, wPokedexSeen + predef FlagActionPredef + ld a, $1 + ld [wDoNotWaitForButtonPressAfterDisplayingText], a + ret diff --git a/engine/events/elevator.asm b/engine/events/elevator.asm new file mode 100755 index 00000000..752bdd1a --- /dev/null +++ b/engine/events/elevator.asm @@ -0,0 +1,48 @@ +DisplayElevatorFloorMenu: + ld hl, WhichFloorText + call PrintText + ld hl, wItemList + ld a, l + ld [wListPointer], a + ld a, h + ld [wListPointer + 1], a + ld a, [wListScrollOffset] + push af + xor a + ld [wCurrentMenuItem], a + ld [wListScrollOffset], a + ld [wPrintItemPrices], a + ld a, SPECIALLISTMENU + ld [wListMenuID], a + call DisplayListMenuID + pop bc + ld a, b + ld [wListScrollOffset], a + ret c + ld hl, wCurrentMapScriptFlags + set 7, [hl] + ld hl, wElevatorWarpMaps + ld a, [wWhichPokemon] + add a + ld d, 0 + ld e, a + add hl, de + ld a, [hli] + ld b, a + ld a, [hl] + ld c, a + ld hl, wWarpEntries + call .UpdateWarp + +.UpdateWarp + inc hl + inc hl + ld a, b + ld [hli], a ; destination warp ID + ld a, c + ld [hli], a ; destination map ID + ret + +WhichFloorText: + TX_FAR _WhichFloorText + db "@" diff --git a/engine/events/evolve_trade.asm b/engine/events/evolve_trade.asm new file mode 100755 index 00000000..e17fc05c --- /dev/null +++ b/engine/events/evolve_trade.asm @@ -0,0 +1,44 @@ +EvolveTradeMon: +; Verify the TradeMon's species name before +; attempting to initiate a trade evolution. + +; The names of the trade evolutions in Blue (JP) +; are checked. In that version, TradeMons that +; can evolve are Graveler and Haunter. + +; In localization, this check was translated +; before monster names were finalized. +; Then, Haunter's name was "Spectre". +; Since its name no longer starts with +; "SP", it is prevented from evolving. + +; This may have been why Red/Green's trades +; were used instead, where none can evolve. + +; This was fixed in Yellow. + + ld a, [wInGameTradeReceiveMonName] + + ; GRAVELER + cp "G" + jr z, .ok + + ; "SPECTRE" (HAUNTER) + cp "S" + ret nz + ld a, [wInGameTradeReceiveMonName + 1] + cp "P" + ret nz + +.ok + ld a, [wPartyCount] + dec a + ld [wWhichPokemon], a + ld a, $1 + ld [wForceEvolution], a + ld a, LINK_STATE_TRADING + ld [wLinkState], a + callab TryEvolvingMon + xor a ; LINK_STATE_NONE + ld [wLinkState], a + jp PlayDefaultMusic diff --git a/engine/events/give_pokemon.asm b/engine/events/give_pokemon.asm new file mode 100755 index 00000000..03177e60 --- /dev/null +++ b/engine/events/give_pokemon.asm @@ -0,0 +1,82 @@ +_GivePokemon:: +; returns success in carry +; and whether the mon was added to the party in [wAddedToParty] + call EnableAutoTextBoxDrawing + xor a + ld [wAddedToParty], a + ld a, [wPartyCount] + cp PARTY_LENGTH + jr c, .addToParty + ld a, [wNumInBox] + cp MONS_PER_BOX + jr nc, .boxFull +; add to box + xor a + ld [wEnemyBattleStatus3], a + ld a, [wcf91] + ld [wEnemyMonSpecies2], a + callab LoadEnemyMonData + call SetPokedexOwnedFlag + callab SendNewMonToBox + ld hl, wcf4b + ld a, [wCurrentBoxNum] + and $7f + cp 9 + jr c, .singleDigitBoxNum + sub 9 + ld [hl], "1" + inc hl + add "0" + jr .next +.singleDigitBoxNum + add "1" +.next + ld [hli], a + ld [hl], "@" + ld hl, SentToBoxText + call PrintText + scf + ret +.boxFull + ld hl, BoxIsFullText + call PrintText + and a + ret +.addToParty + call SetPokedexOwnedFlag + call AddPartyMon + ld a, 1 + ld [wDoNotWaitForButtonPressAfterDisplayingText], a + ld [wAddedToParty], a + scf + ret + +SetPokedexOwnedFlag: + ld a, [wcf91] + push af + ld [wd11e], a + predef IndexToPokedex + ld a, [wd11e] + dec a + ld c, a + ld hl, wPokedexOwned + ld b, FLAG_SET + predef FlagActionPredef + pop af + ld [wd11e], a + call GetMonName + ld hl, GotMonText + jp PrintText + +GotMonText: + TX_FAR _GotMonText + TX_SFX_ITEM_1 + db "@" + +SentToBoxText: + TX_FAR _SentToBoxText + db "@" + +BoxIsFullText: + TX_FAR _BoxIsFullText + db "@" diff --git a/engine/events/heal_party.asm b/engine/events/heal_party.asm new file mode 100644 index 00000000..7aaa1bd1 --- /dev/null +++ b/engine/events/heal_party.asm @@ -0,0 +1,99 @@ +HealParty: +; Restore HP and PP. + + ld hl, wPartySpecies + ld de, wPartyMon1HP +.healmon + ld a, [hli] + cp $ff + jr z, .done + + push hl + push de + + ld hl, wPartyMon1Status - wPartyMon1HP + add hl, de + xor a + ld [hl], a + + push de + ld b, NUM_MOVES ; A Pokémon has 4 moves +.pp + ld hl, wPartyMon1Moves - wPartyMon1HP + add hl, de + + ld a, [hl] + and a + jr z, .nextmove + + dec a + ld hl, wPartyMon1PP - wPartyMon1HP + add hl, de + + push hl + push de + push bc + + ld hl, Moves + ld bc, MoveEnd - Moves + call AddNTimes + ld de, wcd6d + ld a, BANK(Moves) + call FarCopyData + ld a, [wcd6d + 5] ; PP is byte 5 of move data + + pop bc + pop de + pop hl + + inc de + push bc + ld b, a + ld a, [hl] + and $c0 + add b + ld [hl], a + pop bc + +.nextmove + dec b + jr nz, .pp + pop de + + ld hl, wPartyMon1MaxHP - wPartyMon1HP + add hl, de + ld a, [hli] + ld [de], a + inc de + ld a, [hl] + ld [de], a + + pop de + pop hl + + push hl + ld bc, wPartyMon2 - wPartyMon1 + ld h, d + ld l, e + add hl, bc + ld d, h + ld e, l + pop hl + jr .healmon + +.done + xor a + ld [wWhichPokemon], a + ld [wd11e], a + + ld a, [wPartyCount] + ld b, a +.ppup + push bc + call RestoreBonusPP + pop bc + ld hl, wWhichPokemon + inc [hl] + dec b + jr nz, .ppup + ret diff --git a/engine/events/hidden_items.asm b/engine/events/hidden_items.asm new file mode 100755 index 00000000..e40b0ac7 --- /dev/null +++ b/engine/events/hidden_items.asm @@ -0,0 +1,161 @@ +HiddenItems: + ld hl, HiddenItemCoords + call FindHiddenItemOrCoinsIndex + ld [wHiddenItemOrCoinsIndex], a + ld hl, wObtainedHiddenItemsFlags + ld a, [wHiddenItemOrCoinsIndex] + ld c, a + ld b, FLAG_TEST + predef FlagActionPredef + ld a, c + and a + ret nz + call EnableAutoTextBoxDrawing + ld a, 1 + ld [wDoNotWaitForButtonPressAfterDisplayingText], a + ld a, [wHiddenObjectFunctionArgument] ; item ID + ld [wd11e], a + call GetItemName + tx_pre_jump FoundHiddenItemText + +INCLUDE "data/hidden_item_coords.asm" + +FoundHiddenItemText:: + TX_FAR _FoundHiddenItemText + TX_ASM + ld a, [wHiddenObjectFunctionArgument] ; item ID + ld b, a + ld c, 1 + call GiveItem + jr nc, .bagFull + ld hl, wObtainedHiddenItemsFlags + ld a, [wHiddenItemOrCoinsIndex] + ld c, a + ld b, FLAG_SET + predef FlagActionPredef + ld a, SFX_GET_ITEM_2 + call PlaySoundWaitForCurrent + call WaitForSoundToFinish + jp TextScriptEnd +.bagFull + call WaitForTextScrollButtonPress ; wait for button press + xor a + ld [wDoNotWaitForButtonPressAfterDisplayingText], a + ld hl, HiddenItemBagFullText + call PrintText + jp TextScriptEnd + +HiddenItemBagFullText:: + TX_FAR _HiddenItemBagFullText + db "@" + +HiddenCoins: + ld b, COIN_CASE + predef GetQuantityOfItemInBag + ld a, b + and a + ret z + ld hl, HiddenCoinCoords + call FindHiddenItemOrCoinsIndex + ld [wHiddenItemOrCoinsIndex], a + ld hl, wObtainedHiddenCoinsFlags + ld a, [wHiddenItemOrCoinsIndex] + ld c, a + ld b, FLAG_TEST + predef FlagActionPredef + ld a, c + and a + ret nz + xor a + ld [hUnusedCoinsByte], a + ld [hCoins], a + ld [hCoins + 1], a + ld a, [wHiddenObjectFunctionArgument] + sub COIN + cp 10 + jr z, .bcd10 + cp 20 + jr z, .bcd20 + cp 40 + jr z, .bcd20 ; should be bcd40 + jr .bcd100 +.bcd10 + ld a, $10 + ld [hCoins + 1], a + jr .bcdDone +.bcd20 + ld a, $20 + ld [hCoins + 1], a + jr .bcdDone +.bcd40 ; due to a typo, this is never used + ld a, $40 + ld [hCoins + 1], a + jr .bcdDone +.bcd100 + ld a, $1 + ld [hCoins], a +.bcdDone + ld de, wPlayerCoins + 1 + ld hl, hCoins + 1 + ld c, $2 + predef AddBCDPredef + ld hl, wObtainedHiddenCoinsFlags + ld a, [wHiddenItemOrCoinsIndex] + ld c, a + ld b, FLAG_SET + predef FlagActionPredef + call EnableAutoTextBoxDrawing + ld a, [wPlayerCoins] + cp $99 + jr nz, .roomInCoinCase + ld a, [wPlayerCoins + 1] + cp $99 + jr nz, .roomInCoinCase + tx_pre_id DroppedHiddenCoinsText + jr .done +.roomInCoinCase + tx_pre_id FoundHiddenCoinsText +.done + jp PrintPredefTextID + +INCLUDE "data/hidden_coins.asm" + +FoundHiddenCoinsText:: + TX_FAR _FoundHiddenCoinsText + TX_SFX_ITEM_2 + db "@" + +DroppedHiddenCoinsText:: + TX_FAR _FoundHiddenCoins2Text + TX_SFX_ITEM_2 + TX_FAR _DroppedHiddenCoinsText + db "@" + +FindHiddenItemOrCoinsIndex: + ld a, [wHiddenObjectY] + ld d, a + ld a, [wHiddenObjectX] + ld e, a + ld a, [wCurMap] + ld b, a + ld c, -1 +.loop + inc c + ld a, [hli] + cp $ff ; end of the list? + ret z ; if so, we're done here + cp b + jr nz, .next1 + ld a, [hli] + cp d + jr nz, .next2 + ld a, [hli] + cp e + jr nz, .loop + ld a, c + ret +.next1 + inc hl +.next2 + inc hl + jr .loop diff --git a/engine/events/hidden_object_functions14.asm b/engine/events/hidden_object_functions14.asm new file mode 100755 index 00000000..9e14c6a7 --- /dev/null +++ b/engine/events/hidden_object_functions14.asm @@ -0,0 +1,100 @@ +PrintNotebookText: + call EnableAutoTextBoxDrawing + ld a, $1 + ld [wDoNotWaitForButtonPressAfterDisplayingText], a + ld a, [wHiddenObjectFunctionArgument] + jp PrintPredefTextID + +TMNotebook:: + TX_FAR TMNotebookText + TX_WAIT + db "@" + +ViridianSchoolNotebook:: + TX_ASM + ld hl, ViridianSchoolNotebookText1 + call PrintText + call TurnPageSchoolNotebook + jr nz, .doneReading + ld hl, ViridianSchoolNotebookText2 + call PrintText + call TurnPageSchoolNotebook + jr nz, .doneReading + ld hl, ViridianSchoolNotebookText3 + call PrintText + call TurnPageSchoolNotebook + jr nz, .doneReading + ld hl, ViridianSchoolNotebookText4 + call PrintText + ld hl, ViridianSchoolNotebookText5 + call PrintText +.doneReading + jp TextScriptEnd + +TurnPageSchoolNotebook: + ld hl, TurnPageText + call PrintText + call YesNoChoice + ld a, [wCurrentMenuItem] + and a + ret + +TurnPageText: + TX_FAR _TurnPageText + db "@" + +ViridianSchoolNotebookText5: + TX_FAR _ViridianSchoolNotebookText5 + TX_WAIT + db "@" + +ViridianSchoolNotebookText1: + TX_FAR _ViridianSchoolNotebookText1 + db "@" + +ViridianSchoolNotebookText2: + TX_FAR _ViridianSchoolNotebookText2 + db "@" + +ViridianSchoolNotebookText3: + TX_FAR _ViridianSchoolNotebookText3 + db "@" + +ViridianSchoolNotebookText4: + TX_FAR _ViridianSchoolNotebookText4 + db "@" + +PrintFightingDojoText2: + call EnableAutoTextBoxDrawing + tx_pre_jump EnemiesOnEverySideText + +EnemiesOnEverySideText:: + TX_FAR _EnemiesOnEverySideText + db "@" + +PrintFightingDojoText3: + call EnableAutoTextBoxDrawing + tx_pre_jump WhatGoesAroundComesAroundText + +WhatGoesAroundComesAroundText:: + TX_FAR _WhatGoesAroundComesAroundText + db "@" + +PrintFightingDojoText: + call EnableAutoTextBoxDrawing + tx_pre_jump FightingDojoText + +FightingDojoText:: + TX_FAR _FightingDojoText + db "@" + +PrintIndigoPlateauHQText: + ld a, [wSpriteStateData1 + 9] + cp SPRITE_FACING_UP + ret nz + call EnableAutoTextBoxDrawing + tx_pre_jump IndigoPlateauHQText + +IndigoPlateauHQText:: + TX_FAR _IndigoPlateauHQText + db "@" diff --git a/engine/events/hidden_object_functions17.asm b/engine/events/hidden_object_functions17.asm new file mode 100755 index 00000000..bb2a358c --- /dev/null +++ b/engine/events/hidden_object_functions17.asm @@ -0,0 +1,475 @@ +PrintRedSNESText: + call EnableAutoTextBoxDrawing + tx_pre_jump RedBedroomSNESText + +RedBedroomSNESText:: + TX_FAR _RedBedroomSNESText + db "@" + +OpenRedsPC: + call EnableAutoTextBoxDrawing + tx_pre_jump RedBedroomPCText + +RedBedroomPCText:: + TX_PLAYERS_PC + +Route15GateLeftBinoculars: + ld a, [wSpriteStateData1 + 9] + cp SPRITE_FACING_UP + ret nz + call EnableAutoTextBoxDrawing + tx_pre Route15UpstairsBinocularsText + ld a, ARTICUNO + ld [wcf91], a + call PlayCry + jp DisplayMonFrontSpriteInBox + +Route15UpstairsBinocularsText:: + TX_FAR _Route15UpstairsBinocularsText + db "@" + +AerodactylFossil: + ld a, FOSSIL_AERODACTYL + ld [wcf91], a + call DisplayMonFrontSpriteInBox + call EnableAutoTextBoxDrawing + tx_pre AerodactylFossilText + ret + +AerodactylFossilText:: + TX_FAR _AerodactylFossilText + db "@" + +KabutopsFossil: + ld a, FOSSIL_KABUTOPS + ld [wcf91], a + call DisplayMonFrontSpriteInBox + call EnableAutoTextBoxDrawing + tx_pre KabutopsFossilText + ret + +KabutopsFossilText:: + TX_FAR _KabutopsFossilText + db "@" + +DisplayMonFrontSpriteInBox: +; Displays a pokemon's front sprite in a pop-up window. +; [wcf91] = pokemon internal id number + ld a, 1 + ld [H_AUTOBGTRANSFERENABLED], a + call Delay3 + xor a + ld [hWY], a + call SaveScreenTilesToBuffer1 + ld a, MON_SPRITE_POPUP + ld [wTextBoxID], a + call DisplayTextBoxID + call UpdateSprites + ld a, [wcf91] + ld [wd0b5], a + call GetMonHeader + ld de, vChars1 + $310 + call LoadMonFrontSprite + ld a, $80 + ld [hStartTileID], a + coord hl, 10, 11 + predef AnimateSendingOutMon + call WaitForTextScrollButtonPress + call LoadScreenTilesFromBuffer1 + call Delay3 + ld a, $90 + ld [hWY], a + ret + +PrintBlackboardLinkCableText: + call EnableAutoTextBoxDrawing + ld a, $1 + ld [wDoNotWaitForButtonPressAfterDisplayingText], a + ld a, [wHiddenObjectFunctionArgument] + call PrintPredefTextID + ret + +LinkCableHelp:: + TX_ASM + call SaveScreenTilesToBuffer1 + ld hl, LinkCableHelpText1 + call PrintText + xor a + ld [wMenuItemOffset], a ; not used + ld [wCurrentMenuItem], a + ld [wLastMenuItem], a + ld a, A_BUTTON | B_BUTTON + ld [wMenuWatchedKeys], a + ld a, 3 + ld [wMaxMenuItem], a + ld a, 2 + ld [wTopMenuItemY], a + ld a, 1 + ld [wTopMenuItemX], a +.linkHelpLoop + ld hl, wd730 + set 6, [hl] + coord hl, 0, 0 + ld b, 8 + ld c, 13 + call TextBoxBorder + coord hl, 2, 2 + ld de, HowToLinkText + call PlaceString + ld hl, LinkCableHelpText2 + call PrintText + call HandleMenuInput + bit 1, a ; pressed b + jr nz, .exit + ld a, [wCurrentMenuItem] + cp 3 ; pressed a on "STOP READING" + jr z, .exit + ld hl, wd730 + res 6, [hl] + ld hl, LinkCableInfoTexts + add a + ld d, 0 + ld e, a + add hl, de + ld a, [hli] + ld h, [hl] + ld l, a + call PrintText + jp .linkHelpLoop +.exit + ld hl, wd730 + res 6, [hl] + call LoadScreenTilesFromBuffer1 + jp TextScriptEnd + +LinkCableHelpText1: + TX_FAR _LinkCableHelpText1 + db "@" + +LinkCableHelpText2: + TX_FAR _LinkCableHelpText2 + db "@" + +HowToLinkText: + db "HOW TO LINK" + next "COLOSSEUM" + next "TRADE CENTER" + next "STOP READING@" + +LinkCableInfoTexts: + dw LinkCableInfoText1 + dw LinkCableInfoText2 + dw LinkCableInfoText3 + +LinkCableInfoText1: + TX_FAR _LinkCableInfoText1 + db "@" + +LinkCableInfoText2: + TX_FAR _LinkCableInfoText2 + db "@" + +LinkCableInfoText3: + TX_FAR _LinkCableInfoText3 + db "@" + +ViridianSchoolBlackboard:: + TX_ASM + call SaveScreenTilesToBuffer1 + ld hl, ViridianSchoolBlackboardText1 + call PrintText + xor a + ld [wMenuItemOffset], a + ld [wCurrentMenuItem], a + ld [wLastMenuItem], a + ld a, D_LEFT | D_RIGHT | A_BUTTON | B_BUTTON + ld [wMenuWatchedKeys], a + ld a, 2 + ld [wMaxMenuItem], a + ld a, 2 + ld [wTopMenuItemY], a + ld a, 1 + ld [wTopMenuItemX], a +.blackboardLoop + ld hl, wd730 + set 6, [hl] + coord hl, 0, 0 + lb bc, 6, 10 + call TextBoxBorder + coord hl, 1, 2 + ld de, StatusAilmentText1 + call PlaceString + coord hl, 6, 2 + ld de, StatusAilmentText2 + call PlaceString + ld hl, ViridianSchoolBlackboardText2 + call PrintText + call HandleMenuInput ; pressing up and down is handled in here + bit 1, a ; pressed b + jr nz, .exitBlackboard + bit 4, a ; pressed right + jr z, .didNotPressRight + ; move cursor to right column + ld a, 2 + ld [wMaxMenuItem], a + ld a, 2 + ld [wTopMenuItemY], a + ld a, 6 + ld [wTopMenuItemX], a + ld a, 3 ; in the the right column, use an offset to prevent overlap + ld [wMenuItemOffset], a + jr .blackboardLoop +.didNotPressRight + bit 5, a ; pressed left + jr z, .didNotPressLeftOrRight + ; move cursor to left column + ld a, 2 + ld [wMaxMenuItem], a + ld a, 2 + ld [wTopMenuItemY], a + ld a, 1 + ld [wTopMenuItemX], a + xor a + ld [wMenuItemOffset], a + jr .blackboardLoop +.didNotPressLeftOrRight + ld a, [wCurrentMenuItem] + ld b, a + ld a, [wMenuItemOffset] + add b + cp 5 ; cursor is pointing to "QUIT" + jr z, .exitBlackboard + ; we must have pressed a on a status condition + ; so print the text + ld hl, wd730 + res 6, [hl] + ld hl, ViridianBlackboardStatusPointers + add a + ld d, 0 + ld e, a + add hl, de + ld a, [hli] + ld h, [hl] + ld l, a + call PrintText + jp .blackboardLoop +.exitBlackboard + ld hl, wd730 + res 6, [hl] + call LoadScreenTilesFromBuffer1 + jp TextScriptEnd + +ViridianSchoolBlackboardText1: + TX_FAR _ViridianSchoolBlackboardText1 + db "@" + +ViridianSchoolBlackboardText2: + TX_FAR _ViridianSchoolBlackboardText2 + db "@" + +StatusAilmentText1: + db " SLP" + next " PSN" + next " PAR@" + +StatusAilmentText2: + db " BRN" + next " FRZ" + next " QUIT@@" + +ViridianBlackboardStatusPointers: + dw ViridianBlackboardSleepText + dw ViridianBlackboardPoisonText + dw ViridianBlackboardPrlzText + dw ViridianBlackboardBurnText + dw ViridianBlackboardFrozenText + +ViridianBlackboardSleepText: + TX_FAR _ViridianBlackboardSleepText + db "@" + +ViridianBlackboardPoisonText: + TX_FAR _ViridianBlackboardPoisonText + db "@" + +ViridianBlackboardPrlzText: + TX_FAR _ViridianBlackboardPrlzText + db "@" + +ViridianBlackboardBurnText: + TX_FAR _ViridianBlackboardBurnText + db "@" + +ViridianBlackboardFrozenText: + TX_FAR _ViridianBlackboardFrozenText + db "@" + +PrintTrashText: + call EnableAutoTextBoxDrawing + tx_pre_jump VermilionGymTrashText + +VermilionGymTrashText:: + TX_FAR _VermilionGymTrashText + db "@" + +GymTrashScript: + call EnableAutoTextBoxDrawing + ld a, [wHiddenObjectFunctionArgument] + ld [wGymTrashCanIndex], a + +; Don't do the trash can puzzle if it's already been done. + CheckEvent EVENT_2ND_LOCK_OPENED + jr z, .ok + + tx_pre_jump VermilionGymTrashText + +.ok + CheckEventReuseA EVENT_1ST_LOCK_OPENED + jr nz, .trySecondLock + + ld a, [wFirstLockTrashCanIndex] + ld b, a + ld a, [wGymTrashCanIndex] + cp b + jr z, .openFirstLock + + tx_pre_id VermilionGymTrashText + jr .done + +.openFirstLock +; Next can is trying for the second switch. + SetEvent EVENT_1ST_LOCK_OPENED + + ld hl, GymTrashCans + ld a, [wGymTrashCanIndex] + ; * 5 + ld b, a + add a + add a + add b + + ld d, 0 + ld e, a + add hl, de + ld a, [hli] + +; There is a bug in this code. It should calculate a value in the range [0, 3] +; but if the mask and random number don't have any 1 bits in common, then +; the result of the AND will be 0. When 1 is subtracted from that, the value +; will become $ff. This will result in 255 being added to hl, which will cause +; hl to point to one of the zero bytes that pad the end of the ROM bank. +; Trash can 0 was intended to be able to have the second lock only when the +; first lock was in trash can 1 or 3. However, due to this bug, trash can 0 can +; have the second lock regardless of which trash can had the first lock. + + ld [hGymTrashCanRandNumMask], a + push hl + call Random + swap a + ld b, a + ld a, [hGymTrashCanRandNumMask] + and b + dec a + pop hl + + ld d, 0 + ld e, a + add hl, de + ld a, [hl] + and $f + ld [wSecondLockTrashCanIndex], a + + tx_pre_id VermilionGymTrashSuccessText1 + jr .done + +.trySecondLock + ld a, [wSecondLockTrashCanIndex] + ld b, a + ld a, [wGymTrashCanIndex] + cp b + jr z, .openSecondLock + +; Reset the cans. + ResetEvent EVENT_1ST_LOCK_OPENED + call Random + + and $e + ld [wFirstLockTrashCanIndex], a + + tx_pre_id VermilionGymTrashFailText + jr .done + +.openSecondLock +; Completed the trash can puzzle. + SetEvent EVENT_2ND_LOCK_OPENED + ld hl, wCurrentMapScriptFlags + set 6, [hl] + + tx_pre_id VermilionGymTrashSuccessText3 + +.done + jp PrintPredefTextID + +GymTrashCans: +; byte 0: mask for random number +; bytes 1-4: indices of the trash cans that can have the second lock +; (but see the comment above explaining a bug regarding this) +; Note that the mask is simply the number of valid trash can indices that +; follow. The remaining bytes are filled with 0 to pad the length of each entry +; to 5 bytes. + db 2, 1, 3, 0, 0 ; 0 + db 3, 0, 2, 4, 0 ; 1 + db 2, 1, 5, 0, 0 ; 2 + db 3, 0, 4, 6, 0 ; 3 + db 4, 1, 3, 5, 7 ; 4 + db 3, 2, 4, 8, 0 ; 5 + db 3, 3, 7, 9, 0 ; 6 + db 4, 4, 6, 8, 10 ; 7 + db 3, 5, 7, 11, 0 ; 8 + db 3, 6, 10, 12, 0 ; 9 + db 4, 7, 9, 11, 13 ; 10 + db 3, 8, 10, 14, 0 ; 11 + db 2, 9, 13, 0, 0 ; 12 + db 3, 10, 12, 14, 0 ; 13 + db 2, 11, 13, 0, 0 ; 14 + +VermilionGymTrashSuccessText1:: + TX_FAR _VermilionGymTrashSuccessText1 + TX_ASM + call WaitForSoundToFinish + ld a, SFX_SWITCH + call PlaySound + call WaitForSoundToFinish + jp TextScriptEnd + +; unused +VermilionGymTrashSuccessText2:: + TX_FAR _VermilionGymTrashSuccessText2 + db "@" + +; unused +VermilionGymTrashSuccesPlaySfx: + TX_ASM + call WaitForSoundToFinish + ld a, SFX_SWITCH + call PlaySound + call WaitForSoundToFinish + jp TextScriptEnd + +VermilionGymTrashSuccessText3:: + TX_FAR _VermilionGymTrashSuccessText3 + TX_ASM + call WaitForSoundToFinish + ld a, SFX_GO_INSIDE + call PlaySound + call WaitForSoundToFinish + jp TextScriptEnd + +VermilionGymTrashFailText:: + TX_FAR _VermilionGymTrashFailText + TX_ASM + call WaitForSoundToFinish + ld a, SFX_DENIED + call PlaySound + call WaitForSoundToFinish + jp TextScriptEnd diff --git a/engine/events/hidden_object_functions18.asm b/engine/events/hidden_object_functions18.asm new file mode 100755 index 00000000..c0e5aa34 --- /dev/null +++ b/engine/events/hidden_object_functions18.asm @@ -0,0 +1,198 @@ +GymStatues: +; if in a gym and have the corresponding badge, a = GymStatueText2_id and jp PrintPredefTextID +; if in a gym and don’t have the corresponding badge, a = GymStatueText1_id and jp PrintPredefTextID +; else ret + call EnableAutoTextBoxDrawing + ld a, [wSpriteStateData1 + 9] + cp SPRITE_FACING_UP + ret nz + ld hl, .BadgeFlags + ld a, [wCurMap] + ld b, a +.loop + ld a, [hli] + cp $ff + ret z + cp b + jr z, .match + inc hl + jr .loop +.match + ld b, [hl] + ld a, [wBeatGymFlags] + and b + cp b + tx_pre_id GymStatueText2 + jr z, .haveBadge + tx_pre_id GymStatueText1 +.haveBadge + jp PrintPredefTextID + +.BadgeFlags: + db PEWTER_GYM, %00000001 + db CERULEAN_GYM, %00000010 + db VERMILION_GYM,%00000100 + db CELADON_GYM, %00001000 + db FUCHSIA_GYM, %00010000 + db SAFFRON_GYM, %00100000 + db CINNABAR_GYM, %01000000 + db VIRIDIAN_GYM, %10000000 + db $ff + +GymStatueText1:: + TX_FAR _GymStatueText1 + db "@" + +GymStatueText2:: + TX_FAR _GymStatueText2 + db "@" + +PrintBenchGuyText: + call EnableAutoTextBoxDrawing + ld hl, BenchGuyTextPointers + ld a, [wCurMap] + ld b, a +.loop + ld a, [hli] + cp $ff + ret z + cp b + jr z, .match + inc hl + inc hl + jr .loop +.match + ld a, [hli] + ld b, a + ld a, [wSpriteStateData1 + 9] + cp b + jr nz, .loop ; player isn't facing left at the bench guy + ld a, [hl] + jp PrintPredefTextID + +; format: db map id, player sprite facing direction, text id of PredefTextIDPointerTable +BenchGuyTextPointers: + db VIRIDIAN_POKECENTER, SPRITE_FACING_LEFT + db_tx_pre ViridianCityPokecenterBenchGuyText + db PEWTER_POKECENTER, SPRITE_FACING_LEFT + db_tx_pre PewterCityPokecenterBenchGuyText + db CERULEAN_POKECENTER, SPRITE_FACING_LEFT + db_tx_pre CeruleanCityPokecenterBenchGuyText + db LAVENDER_POKECENTER, SPRITE_FACING_LEFT + db_tx_pre LavenderCityPokecenterBenchGuyText + db VERMILION_POKECENTER, SPRITE_FACING_LEFT + db_tx_pre VermilionCityPokecenterBenchGuyText + db CELADON_POKECENTER, SPRITE_FACING_LEFT + db_tx_pre CeladonCityPokecenterBenchGuyText + db CELADON_HOTEL, SPRITE_FACING_LEFT + db_tx_pre CeladonCityHotelText + db FUCHSIA_POKECENTER, SPRITE_FACING_LEFT + db_tx_pre FuchsiaCityPokecenterBenchGuyText + db CINNABAR_POKECENTER, SPRITE_FACING_LEFT + db_tx_pre CinnabarIslandPokecenterBenchGuyText + db SAFFRON_POKECENTER, SPRITE_FACING_LEFT + db_tx_pre SaffronCityPokecenterBenchGuyText + db MT_MOON_POKECENTER, SPRITE_FACING_LEFT + db_tx_pre MtMoonPokecenterBenchGuyText + db ROCK_TUNNEL_POKECENTER,SPRITE_FACING_LEFT + db_tx_pre RockTunnelPokecenterBenchGuyText + db $FF + +ViridianCityPokecenterBenchGuyText:: + TX_FAR _ViridianCityPokecenterGuyText + db "@" + +PewterCityPokecenterBenchGuyText:: + TX_FAR _PewterCityPokecenterGuyText + db "@" + +CeruleanCityPokecenterBenchGuyText:: + TX_FAR _CeruleanPokecenterGuyText + db "@" + +LavenderCityPokecenterBenchGuyText:: + TX_FAR _LavenderPokecenterGuyText + db "@" + +MtMoonPokecenterBenchGuyText:: + TX_FAR _MtMoonPokecenterBenchGuyText + db "@" + +RockTunnelPokecenterBenchGuyText:: + TX_FAR _RockTunnelPokecenterGuyText + db "@" + +UnusedBenchGuyText1:: + TX_FAR _UnusedBenchGuyText1 + db "@" + +UnusedBenchGuyText2:: + TX_FAR _UnusedBenchGuyText2 + db "@" + +UnusedBenchGuyText3:: + TX_FAR _UnusedBenchGuyText3 + db "@" + +VermilionCityPokecenterBenchGuyText:: + TX_FAR _VermilionPokecenterGuyText + db "@" + +CeladonCityPokecenterBenchGuyText:: + TX_FAR _CeladonCityPokecenterGuyText + db "@" + +FuchsiaCityPokecenterBenchGuyText:: + TX_FAR _FuchsiaCityPokecenterGuyText + db "@" + +CinnabarIslandPokecenterBenchGuyText:: + TX_FAR _CinnabarPokecenterGuyText + db "@" + +SaffronCityPokecenterBenchGuyText:: + TX_ASM + CheckEvent EVENT_BEAT_SILPH_CO_GIOVANNI + ld hl, SaffronCityPokecenterBenchGuyText2 + jr nz, .asm_624f2 + ld hl, SaffronCityPokecenterBenchGuyText1 +.asm_624f2 + call PrintText + jp TextScriptEnd + +SaffronCityPokecenterBenchGuyText1: + TX_FAR _SaffronCityPokecenterGuyText1 + db "@" + +SaffronCityPokecenterBenchGuyText2: + TX_FAR _SaffronCityPokecenterGuyText2 + db "@" + +CeladonCityHotelText:: + TX_FAR _CeladonCityHotelText + db "@" + + ret + +UnusedPredefText:: + db "@" + +PrintBookcaseText: + call EnableAutoTextBoxDrawing + tx_pre_jump BookcaseText + +BookcaseText:: + TX_FAR _BookcaseText + db "@" + +OpenPokemonCenterPC: + ld a, [wSpriteStateData1 + 9] + cp SPRITE_FACING_UP ; check to see if player is facing up + ret nz + call EnableAutoTextBoxDrawing + ld a, $1 + ld [wAutoTextBoxDrawingControl], a + tx_pre_jump PokemonCenterPCText + +PokemonCenterPCText:: + TX_POKECENTER_PC diff --git a/engine/events/hidden_object_functions3.asm b/engine/events/hidden_object_functions3.asm new file mode 100755 index 00000000..1237e960 --- /dev/null +++ b/engine/events/hidden_object_functions3.asm @@ -0,0 +1,117 @@ +; prints text for bookshelves in buildings without sign events +PrintBookshelfText:: + ld a, [wSpriteStateData1 + 9] ; player's sprite facing direction + cp SPRITE_FACING_UP + jr nz, .noMatch +; facing up + ld a, [wCurMapTileset] + ld b, a + aCoord 8, 7 + ld c, a + ld hl, BookshelfTileIDs +.loop + ld a, [hli] + cp $ff + jr z, .noMatch + cp b + jr nz, .nextBookshelfEntry1 + ld a, [hli] + cp c + jr nz, .nextBookshelfEntry2 + ld a, [hl] + push af + call EnableAutoTextBoxDrawing + pop af + call PrintPredefTextID + xor a + ld [$ffdb], a + ret +.nextBookshelfEntry1 + inc hl +.nextBookshelfEntry2 + inc hl + jr .loop +.noMatch + ld a, $ff + ld [$ffdb], a + jpba PrintCardKeyText + +INCLUDE "data/bookshelf_tile_ids.asm" + +IndigoPlateauStatues:: + TX_ASM + ld hl, IndigoPlateauStatuesText1 + call PrintText + ld a, [wXCoord] + bit 0, a + ld hl, IndigoPlateauStatuesText2 + jr nz, .ok + ld hl, IndigoPlateauStatuesText3 +.ok + call PrintText + jp TextScriptEnd + +IndigoPlateauStatuesText1: + TX_FAR _IndigoPlateauStatuesText1 + db "@" + +IndigoPlateauStatuesText2: + TX_FAR _IndigoPlateauStatuesText2 + db "@" + +IndigoPlateauStatuesText3: + TX_FAR _IndigoPlateauStatuesText3 + db "@" + +BookOrSculptureText:: + TX_ASM + ld hl, PokemonBooksText + ld a, [wCurMapTileset] + cp MANSION ; Celadon Mansion tileset + jr nz, .ok + aCoord 8, 6 + cp $38 + jr nz, .ok + ld hl, DiglettSculptureText +.ok + call PrintText + jp TextScriptEnd + +PokemonBooksText: + TX_FAR _PokemonBooksText + db "@" + +DiglettSculptureText: + TX_FAR _DiglettSculptureText + db "@" + +ElevatorText:: + TX_FAR _ElevatorText + db "@" + +TownMapText:: + TX_FAR _TownMapText + TX_BLINK + TX_ASM + ld a, $1 + ld [wDoNotWaitForButtonPressAfterDisplayingText], a + ld hl, wd730 + set 6, [hl] + call GBPalWhiteOutWithDelay3 + xor a + ld [hWY], a + inc a + ld [H_AUTOBGTRANSFERENABLED], a + call LoadFontTilePatterns + callba DisplayTownMap + ld hl, wd730 + res 6, [hl] + ld de, TextScriptEnd + push de + ld a, [H_LOADEDROMBANK] + push af + jp CloseTextDisplay + +PokemonStuffText:: + TX_FAR _PokemonStuffText + db "@" diff --git a/engine/events/hidden_object_functions7.asm b/engine/events/hidden_object_functions7.asm new file mode 100755 index 00000000..e18b9570 --- /dev/null +++ b/engine/events/hidden_object_functions7.asm @@ -0,0 +1,467 @@ +PrintNewBikeText: + call EnableAutoTextBoxDrawing + tx_pre_jump NewBicycleText + +NewBicycleText:: + TX_FAR _NewBicycleText + db "@" + +DisplayOakLabLeftPoster: + call EnableAutoTextBoxDrawing + tx_pre_jump PushStartText + +PushStartText:: + TX_FAR _PushStartText + db "@" + +DisplayOakLabRightPoster: + call EnableAutoTextBoxDrawing + ld hl, wPokedexOwned + ld b, wPokedexOwnedEnd - wPokedexOwned + call CountSetBits + ld a, [wNumSetBits] + cp 2 + tx_pre_id SaveOptionText + jr c, .ownLessThanTwo + ; own two or more mon + tx_pre_id StrengthsAndWeaknessesText +.ownLessThanTwo + jp PrintPredefTextID + +SaveOptionText:: + TX_FAR _SaveOptionText + db "@" + +StrengthsAndWeaknessesText:: + TX_FAR _StrengthsAndWeaknessesText + db "@" + +SafariZoneCheck:: + CheckEventHL EVENT_IN_SAFARI_ZONE ; if we are not in the Safari Zone, + jr z, SafariZoneGameStillGoing ; don't bother printing game over text + ld a, [wNumSafariBalls] + and a + jr z, SafariZoneGameOver + jr SafariZoneGameStillGoing + +SafariZoneCheckSteps:: + ld a, [wSafariSteps] + ld b, a + ld a, [wSafariSteps + 1] + ld c, a + or b + jr z, SafariZoneGameOver + dec bc + ld a, b + ld [wSafariSteps], a + ld a, c + ld [wSafariSteps + 1], a +SafariZoneGameStillGoing: + xor a + ld [wSafariZoneGameOver], a + ret + +SafariZoneGameOver: + call EnableAutoTextBoxDrawing + xor a + ld [wAudioFadeOutControl], a + dec a + call PlaySound + ld c, BANK(SFX_Safari_Zone_PA) + ld a, SFX_SAFARI_ZONE_PA + call PlayMusic +.waitForMusicToPlay + ld a, [wChannelSoundIDs + Ch5] + cp SFX_SAFARI_ZONE_PA + jr nz, .waitForMusicToPlay + ld a, TEXT_SAFARI_GAME_OVER + ld [hSpriteIndexOrTextID], a + call DisplayTextID + xor a + ld [wPlayerMovingDirection], a + ld a, SAFARI_ZONE_GATE + ld [hWarpDestinationMap], a + ld a, $3 + ld [wDestinationWarpID], a + ld a, $5 + ld [wSafariZoneGateCurScript], a + SetEvent EVENT_SAFARI_GAME_OVER + ld a, 1 + ld [wSafariZoneGameOver], a + ret + +PrintSafariGameOverText:: + xor a + ld [wJoyIgnore], a + ld hl, SafariGameOverText + jp PrintText + +SafariGameOverText: + TX_ASM + ld a, [wNumSafariBalls] + and a + jr z, .noMoreSafariBalls + ld hl, TimesUpText + call PrintText +.noMoreSafariBalls + ld hl, GameOverText + call PrintText + jp TextScriptEnd + +TimesUpText: + TX_FAR _TimesUpText + db "@" + +GameOverText: + TX_FAR _GameOverText + db "@" + +PrintCinnabarQuiz: + ld a, [wSpriteStateData1 + 9] + cp SPRITE_FACING_UP + ret nz + call EnableAutoTextBoxDrawing + tx_pre_jump CinnabarGymQuiz + +CinnabarGymQuiz:: + TX_ASM + xor a + ld [wOpponentAfterWrongAnswer], a + ld a, [wHiddenObjectFunctionArgument] + push af + and $f + ld [hGymGateIndex], a + pop af + and $f0 + swap a + ld [$ffdc], a + ld hl, CinnabarGymQuizIntroText + call PrintText + ld a, [hGymGateIndex] + dec a + add a + ld d, 0 + ld e, a + ld hl, CinnabarQuizQuestions + add hl, de + ld a, [hli] + ld h, [hl] + ld l, a + call PrintText + ld a, 1 + ld [wDoNotWaitForButtonPressAfterDisplayingText], a + call CinnabarGymQuiz_1ea92 + jp TextScriptEnd + +CinnabarGymQuizIntroText: + TX_FAR _CinnabarGymQuizIntroText + db "@" + +CinnabarQuizQuestions: + dw CinnabarQuizQuestionsText1 + dw CinnabarQuizQuestionsText2 + dw CinnabarQuizQuestionsText3 + dw CinnabarQuizQuestionsText4 + dw CinnabarQuizQuestionsText5 + dw CinnabarQuizQuestionsText6 + +CinnabarQuizQuestionsText1: + TX_FAR _CinnabarQuizQuestionsText1 + db "@" + +CinnabarQuizQuestionsText2: + TX_FAR _CinnabarQuizQuestionsText2 + db "@" + +CinnabarQuizQuestionsText3: + TX_FAR _CinnabarQuizQuestionsText3 + db "@" + +CinnabarQuizQuestionsText4: + TX_FAR _CinnabarQuizQuestionsText4 + db "@" + +CinnabarQuizQuestionsText5: + TX_FAR _CinnabarQuizQuestionsText5 + db "@" + +CinnabarQuizQuestionsText6: + TX_FAR _CinnabarQuizQuestionsText6 + db "@" + +CinnabarGymGateFlagAction: + EventFlagAddress hl, EVENT_CINNABAR_GYM_GATE0_UNLOCKED + predef_jump FlagActionPredef + +CinnabarGymQuiz_1ea92: + call YesNoChoice + ld a, [$ffdc] + ld c, a + ld a, [wCurrentMenuItem] + cp c + jr nz, .wrongAnswer + ld hl, wCurrentMapScriptFlags + set 5, [hl] + ld a, [hGymGateIndex] + ld [$ffe0], a + ld hl, CinnabarGymQuizCorrectText + call PrintText + ld a, [$ffe0] + AdjustEventBit EVENT_CINNABAR_GYM_GATE0_UNLOCKED, 0 + ld c, a + ld b, FLAG_SET + call CinnabarGymGateFlagAction + jp UpdateCinnabarGymGateTileBlocks_ +.wrongAnswer + call WaitForSoundToFinish + ld a, SFX_DENIED + call PlaySound + call WaitForSoundToFinish + ld hl, CinnabarGymQuizIncorrectText + call PrintText + ld a, [hGymGateIndex] + add $2 + AdjustEventBit EVENT_BEAT_CINNABAR_GYM_TRAINER_0, 2 + ld c, a + ld b, FLAG_TEST + EventFlagAddress hl, EVENT_BEAT_CINNABAR_GYM_TRAINER_0 + predef FlagActionPredef + ld a, c + and a + ret nz + ld a, [hGymGateIndex] + add $2 + ld [wOpponentAfterWrongAnswer], a + ret + +CinnabarGymQuizCorrectText: + TX_SFX_ITEM_1 + TX_FAR _CinnabarGymQuizCorrectText + TX_BLINK + TX_ASM + + ld a, [$ffe0] + AdjustEventBit EVENT_CINNABAR_GYM_GATE0_UNLOCKED, 0 + ld c, a + ld b, FLAG_TEST + call CinnabarGymGateFlagAction + ld a, c + and a + jp nz, TextScriptEnd + call WaitForSoundToFinish + ld a, SFX_GO_INSIDE + call PlaySound + call WaitForSoundToFinish + jp TextScriptEnd + +CinnabarGymQuizIncorrectText: + TX_FAR _CinnabarGymQuizIncorrectText + db "@" + +UpdateCinnabarGymGateTileBlocks_:: +; Update the overworld map with open floor blocks or locked gate blocks +; depending on event flags. + ld a, 6 + ld [hGymGateIndex], a +.loop + ld a, [hGymGateIndex] + dec a + add a + add a + ld d, 0 + ld e, a + ld hl, CinnabarGymGateCoords + add hl, de + ld a, [hli] + ld b, [hl] + ld c, a + inc hl + ld a, [hl] + ld [wGymGateTileBlock], a + push bc + ld a, [hGymGateIndex] + ld [$ffe0], a + AdjustEventBit EVENT_CINNABAR_GYM_GATE0_UNLOCKED, 0 + ld c, a + ld b, FLAG_TEST + call CinnabarGymGateFlagAction + ld a, c + and a + jr nz, .unlocked + ld a, [wGymGateTileBlock] + jr .next +.unlocked + ld a, $e +.next + pop bc + ld [wNewTileBlockID], a + predef ReplaceTileBlock + ld hl, hGymGateIndex + dec [hl] + jr nz, .loop + ret + +CinnabarGymGateCoords: + ; format: x-coord, y-coord, direction, padding + ; direction: $54 = horizontal gate, $5f = vertical gate + db $09,$03,$54,$00 + db $06,$03,$54,$00 + db $06,$06,$54,$00 + db $03,$08,$5f,$00 + db $02,$06,$54,$00 + db $02,$03,$54,$00 + +PrintMagazinesText: + call EnableAutoTextBoxDrawing + tx_pre MagazinesText + ret + +MagazinesText:: + TX_FAR _MagazinesText + db "@" + +BillsHousePC: + call EnableAutoTextBoxDrawing + ld a, [wSpriteStateData1 + 9] + cp SPRITE_FACING_UP + ret nz + CheckEvent EVENT_LEFT_BILLS_HOUSE_AFTER_HELPING + jr nz, .displayBillsHousePokemonList + CheckEventReuseA EVENT_USED_CELL_SEPARATOR_ON_BILL + jr nz, .displayBillsHouseMonitorText + CheckEventReuseA EVENT_BILL_SAID_USE_CELL_SEPARATOR + jr nz, .doCellSeparator +.displayBillsHouseMonitorText + tx_pre_jump BillsHouseMonitorText +.doCellSeparator + ld a, $1 + ld [wDoNotWaitForButtonPressAfterDisplayingText], a + tx_pre BillsHouseInitiatedText + ld c, 32 + call DelayFrames + ld a, SFX_TINK + call PlaySound + call WaitForSoundToFinish + ld c, 80 + call DelayFrames + ld a, SFX_SHRINK + call PlaySound + call WaitForSoundToFinish + ld c, 48 + call DelayFrames + ld a, SFX_TINK + call PlaySound + call WaitForSoundToFinish + ld c, 32 + call DelayFrames + ld a, SFX_GET_ITEM_1 + call PlaySound + call WaitForSoundToFinish + call PlayDefaultMusic + SetEvent EVENT_USED_CELL_SEPARATOR_ON_BILL + ret +.displayBillsHousePokemonList + ld a, $1 + ld [wDoNotWaitForButtonPressAfterDisplayingText], a + tx_pre BillsHousePokemonList + ret + +BillsHouseMonitorText:: + TX_FAR _BillsHouseMonitorText + db "@" + +BillsHouseInitiatedText:: + TX_FAR _BillsHouseInitiatedText + TX_BLINK + TX_ASM + ld a, $ff + ld [wNewSoundID], a + call PlaySound + ld c, 16 + call DelayFrames + ld a, SFX_SWITCH + call PlaySound + call WaitForSoundToFinish + ld c, 60 + call DelayFrames + jp TextScriptEnd + +BillsHousePokemonList:: + TX_ASM + call SaveScreenTilesToBuffer1 + ld hl, BillsHousePokemonListText1 + call PrintText + xor a + ld [wMenuItemOffset], a ; not used + ld [wCurrentMenuItem], a + ld [wLastMenuItem], a + ld a, A_BUTTON | B_BUTTON + ld [wMenuWatchedKeys], a + ld a, 4 + ld [wMaxMenuItem], a + ld a, 2 + ld [wTopMenuItemY], a + ld a, 1 + ld [wTopMenuItemX], a +.billsPokemonLoop + ld hl, wd730 + set 6, [hl] + coord hl, 0, 0 + ld b, 10 + ld c, 9 + call TextBoxBorder + coord hl, 2, 2 + ld de, BillsMonListText + call PlaceString + ld hl, BillsHousePokemonListText2 + call PrintText + call SaveScreenTilesToBuffer2 + call HandleMenuInput + bit 1, a ; pressed b + jr nz, .cancel + ld a, [wCurrentMenuItem] + add EEVEE + cp EEVEE + jr z, .displayPokedex + cp FLAREON + jr z, .displayPokedex + cp JOLTEON + jr z, .displayPokedex + cp VAPOREON + jr z, .displayPokedex + jr .cancel +.displayPokedex + call DisplayPokedex + call LoadScreenTilesFromBuffer2 + jr .billsPokemonLoop +.cancel + ld hl, wd730 + res 6, [hl] + call LoadScreenTilesFromBuffer2 + jp TextScriptEnd + +BillsHousePokemonListText1: + TX_FAR _BillsHousePokemonListText1 + db "@" + +BillsMonListText: + db "EEVEE" + next "FLAREON" + next "JOLTEON" + next "VAPOREON" + next "CANCEL@" + +BillsHousePokemonListText2: + TX_FAR _BillsHousePokemonListText2 + db "@" + +DisplayOakLabEmailText: + ld a, [wSpriteStateData1 + 9] + cp SPRITE_FACING_UP + ret nz + call EnableAutoTextBoxDrawing + tx_pre_jump OakLabEmailText + +OakLabEmailText:: + TX_FAR _OakLabEmailText + db "@" diff --git a/engine/events/in_game_trades.asm b/engine/events/in_game_trades.asm new file mode 100755 index 00000000..c01bc3c3 --- /dev/null +++ b/engine/events/in_game_trades.asm @@ -0,0 +1,330 @@ +DoInGameTradeDialogue: +; trigger the trade offer/action specified by wWhichTrade + call SaveScreenTilesToBuffer2 + ld hl, TradeMons + ld a, [wWhichTrade] + ld b, a + swap a + sub b + sub b + ld c, a + ld b, 0 + add hl, bc + ld a, [hli] + ld [wInGameTradeGiveMonSpecies], a + ld a, [hli] + ld [wInGameTradeReceiveMonSpecies], a + ld a, [hli] + push af + ld de, wInGameTradeMonNick + ld bc, NAME_LENGTH + call CopyData + pop af + ld l, a + ld h, 0 + ld de, InGameTradeTextPointers + add hl, hl + add hl, de + ld a, [hli] + ld [wInGameTradeTextPointerTablePointer], a + ld a, [hl] + ld [wInGameTradeTextPointerTablePointer + 1], a + ld a, [wInGameTradeGiveMonSpecies] + ld de, wInGameTradeGiveMonName + call InGameTrade_GetMonName + ld a, [wInGameTradeReceiveMonSpecies] + ld de, wInGameTradeReceiveMonName + call InGameTrade_GetMonName + ld hl, wCompletedInGameTradeFlags + ld a, [wWhichTrade] + ld c, a + ld b, FLAG_TEST + predef FlagActionPredef + ld a, c + and a + ld a, $4 + ld [wInGameTradeTextPointerTableIndex], a + jr nz, .printText +; if the trade hasn't been done yet + xor a + ld [wInGameTradeTextPointerTableIndex], a + call .printText + ld a, $1 + ld [wInGameTradeTextPointerTableIndex], a + call YesNoChoice + ld a, [wCurrentMenuItem] + and a + jr nz, .printText + call InGameTrade_DoTrade + jr c, .printText + ld hl, TradedForText + call PrintText +.printText + ld hl, wInGameTradeTextPointerTableIndex + ld a, [hld] ; wInGameTradeTextPointerTableIndex + ld e, a + ld d, 0 + ld a, [hld] ; wInGameTradeTextPointerTablePointer + 1 + ld l, [hl] ; wInGameTradeTextPointerTablePointer + ld h, a + add hl, de + add hl, de + ld a, [hli] + ld h, [hl] + ld l, a + jp PrintText + +; copies name of species a to hl +InGameTrade_GetMonName: + push de + ld [wd11e], a + call GetMonName + ld hl, wcd6d + pop de + ld bc, NAME_LENGTH + jp CopyData + +INCLUDE "data/trades.asm" + +InGameTrade_DoTrade: + xor a ; NORMAL_PARTY_MENU + ld [wPartyMenuTypeOrMessageID], a + dec a + ld [wUpdateSpritesEnabled], a + call DisplayPartyMenu + push af + call InGameTrade_RestoreScreen + pop af + ld a, $1 + jp c, .tradeFailed ; jump if the player didn't select a pokemon + ld a, [wInGameTradeGiveMonSpecies] + ld b, a + ld a, [wcf91] + cp b + ld a, $2 + jr nz, .tradeFailed ; jump if the selected mon's species is not the required one + ld a, [wWhichPokemon] + ld hl, wPartyMon1Level + ld bc, wPartyMon2 - wPartyMon1 + call AddNTimes + ld a, [hl] + ld [wCurEnemyLVL], a + ld hl, wCompletedInGameTradeFlags + ld a, [wWhichTrade] + ld c, a + ld b, FLAG_SET + predef FlagActionPredef + ld hl, ConnectCableText + call PrintText + ld a, [wWhichPokemon] + push af + ld a, [wCurEnemyLVL] + push af + call LoadHpBarAndStatusTilePatterns + call InGameTrade_PrepareTradeData + predef InternalClockTradeAnim + pop af + ld [wCurEnemyLVL], a + pop af + ld [wWhichPokemon], a + ld a, [wInGameTradeReceiveMonSpecies] + ld [wcf91], a + xor a + ld [wMonDataLocation], a ; not used + ld [wRemoveMonFromBox], a + call RemovePokemon + ld a, $80 ; prevent the player from naming the mon + ld [wMonDataLocation], a + call AddPartyMon + call InGameTrade_CopyDataToReceivedMon + callab EvolveTradeMon + call ClearScreen + call InGameTrade_RestoreScreen + callba RedrawMapView + and a + ld a, $3 + jr .tradeSucceeded +.tradeFailed + scf +.tradeSucceeded + ld [wInGameTradeTextPointerTableIndex], a + ret + +InGameTrade_RestoreScreen: + call GBPalWhiteOutWithDelay3 + call RestoreScreenTilesAndReloadTilePatterns + call ReloadTilesetTilePatterns + call LoadScreenTilesFromBuffer2 + call Delay3 + call LoadGBPal + ld c, 10 + call DelayFrames + jpba LoadWildData + +InGameTrade_PrepareTradeData: + ld hl, wTradedPlayerMonSpecies + ld a, [wInGameTradeGiveMonSpecies] + ld [hli], a ; wTradedPlayerMonSpecies + ld a, [wInGameTradeReceiveMonSpecies] + ld [hl], a ; wTradedEnemyMonSpecies + ld hl, wPartyMonOT + ld bc, NAME_LENGTH + ld a, [wWhichPokemon] + call AddNTimes + ld de, wTradedPlayerMonOT + ld bc, NAME_LENGTH + call InGameTrade_CopyData + ld hl, InGameTrade_TrainerString + ld de, wTradedEnemyMonOT + call InGameTrade_CopyData + ld de, wLinkEnemyTrainerName + call InGameTrade_CopyData + ld hl, wPartyMon1OTID + ld bc, wPartyMon2 - wPartyMon1 + ld a, [wWhichPokemon] + call AddNTimes + ld de, wTradedPlayerMonOTID + ld bc, $2 + call InGameTrade_CopyData + call Random + ld hl, hRandomAdd + ld de, wTradedEnemyMonOTID + jp CopyData + +InGameTrade_CopyData: + push hl + push bc + call CopyData + pop bc + pop hl + ret + +InGameTrade_CopyDataToReceivedMon: + ld hl, wPartyMonNicks + ld bc, NAME_LENGTH + call InGameTrade_GetReceivedMonPointer + ld hl, wInGameTradeMonNick + ld bc, NAME_LENGTH + call CopyData + ld hl, wPartyMonOT + ld bc, NAME_LENGTH + call InGameTrade_GetReceivedMonPointer + ld hl, InGameTrade_TrainerString + ld bc, NAME_LENGTH + call CopyData + ld hl, wPartyMon1OTID + ld bc, wPartyMon2 - wPartyMon1 + call InGameTrade_GetReceivedMonPointer + ld hl, wTradedEnemyMonOTID + ld bc, $2 + jp CopyData + +; the received mon's index is (partyCount - 1), +; so this adds bc to hl (partyCount - 1) times and moves the result to de +InGameTrade_GetReceivedMonPointer: + ld a, [wPartyCount] + dec a + call AddNTimes + ld e, l + ld d, h + ret + +InGameTrade_TrainerString: + ; "TRAINER@@@@@@@@@@" + db $5d, "@@@@@@@@@@" + +InGameTradeTextPointers: + dw TradeTextPointers1 + dw TradeTextPointers2 + dw TradeTextPointers3 + +TradeTextPointers1: + dw WannaTrade1Text + dw NoTrade1Text + dw WrongMon1Text + dw Thanks1Text + dw AfterTrade1Text + +TradeTextPointers2: + dw WannaTrade2Text + dw NoTrade2Text + dw WrongMon2Text + dw Thanks2Text + dw AfterTrade2Text + +TradeTextPointers3: + dw WannaTrade3Text + dw NoTrade3Text + dw WrongMon3Text + dw Thanks3Text + dw AfterTrade3Text + +ConnectCableText: + TX_FAR _ConnectCableText + db "@" + +TradedForText: + TX_FAR _TradedForText + TX_SFX_KEY_ITEM + TX_DELAY + db "@" + +WannaTrade1Text: + TX_FAR _WannaTrade1Text + db "@" + +NoTrade1Text: + TX_FAR _NoTrade1Text + db "@" + +WrongMon1Text: + TX_FAR _WrongMon1Text + db "@" + +Thanks1Text: + TX_FAR _Thanks1Text + db "@" + +AfterTrade1Text: + TX_FAR _AfterTrade1Text + db "@" + +WannaTrade2Text: + TX_FAR _WannaTrade2Text + db "@" + +NoTrade2Text: + TX_FAR _NoTrade2Text + db "@" + +WrongMon2Text: + TX_FAR _WrongMon2Text + db "@" + +Thanks2Text: + TX_FAR _Thanks2Text + db "@" + +AfterTrade2Text: + TX_FAR _AfterTrade2Text + db "@" + +WannaTrade3Text: + TX_FAR _WannaTrade3Text + db "@" + +NoTrade3Text: + TX_FAR _NoTrade3Text + db "@" + +WrongMon3Text: + TX_FAR _WrongMon3Text + db "@" + +Thanks3Text: + TX_FAR _Thanks3Text + db "@" + +AfterTrade3Text: + TX_FAR _AfterTrade3Text + db "@" diff --git a/engine/events/oaks_aide.asm b/engine/events/oaks_aide.asm new file mode 100755 index 00000000..f5068fda --- /dev/null +++ b/engine/events/oaks_aide.asm @@ -0,0 +1,71 @@ +OaksAideScript: + ld hl, OaksAideHiText + call PrintText + call YesNoChoice + ld a, [wCurrentMenuItem] + and a + jr nz, .choseNo + ld hl, wPokedexOwned + ld b, wPokedexOwnedEnd - wPokedexOwned + call CountSetBits + ld a, [wNumSetBits] + ld [hOaksAideNumMonsOwned], a + ld b, a + ld a, [hOaksAideRequirement] + cp b + jr z, .giveItem + jr nc, .notEnoughOwnedMons +.giveItem + ld hl, OaksAideHereYouGoText + call PrintText + ld a, [hOaksAideRewardItem] + ld b, a + ld c, 1 + call GiveItem + jr nc, .bagFull + ld hl, OaksAideGotItemText + call PrintText + ld a, $1 + jr .done +.bagFull + ld hl, OaksAideNoRoomText + call PrintText + xor a + jr .done +.notEnoughOwnedMons + ld hl, OaksAideUhOhText + call PrintText + ld a, $80 + jr .done +.choseNo + ld hl, OaksAideComeBackText + call PrintText + ld a, $ff +.done + ld [hOaksAideResult], a + ret + +OaksAideHiText: + TX_FAR _OaksAideHiText + db "@" + +OaksAideUhOhText: + TX_FAR _OaksAideUhOhText + db "@" + +OaksAideComeBackText: + TX_FAR _OaksAideComeBackText + db "@" + +OaksAideHereYouGoText: + TX_FAR _OaksAideHereYouGoText + db "@" + +OaksAideGotItemText: + TX_FAR _OaksAideGotItemText + TX_SFX_ITEM_1 + db "@" + +OaksAideNoRoomText: + TX_FAR _OaksAideNoRoomText + db "@" diff --git a/engine/events/pewter_guys.asm b/engine/events/pewter_guys.asm new file mode 100755 index 00000000..532fa4bf --- /dev/null +++ b/engine/events/pewter_guys.asm @@ -0,0 +1,102 @@ +PewterGuys: + ld hl, wSimulatedJoypadStatesEnd + ld a, [wSimulatedJoypadStatesIndex] + dec a ; this decrement causes it to overwrite the last byte before $FF in the list + ld [wSimulatedJoypadStatesIndex], a + ld d, 0 + ld e, a + add hl, de + ld d, h + ld e, l + ld hl, PointerTable_37ce6 + ld a, [wWhichPewterGuy] + add a + ld b, 0 + ld c, a + add hl, bc + ld a, [hli] + ld h, [hl] + ld l, a + ld a, [wYCoord] + ld b, a + ld a, [wXCoord] + ld c, a +.findMatchingCoordsLoop + ld a, [hli] + cp b + jr nz, .nextEntry1 + ld a, [hli] + cp c + jr nz, .nextEntry2 + ld a, [hli] + ld h, [hl] + ld l, a +.copyMovementDataLoop + ld a, [hli] + cp $ff + ret z + ld [de], a + inc de + ld a, [wSimulatedJoypadStatesIndex] + inc a + ld [wSimulatedJoypadStatesIndex], a + jr .copyMovementDataLoop +.nextEntry1 + inc hl +.nextEntry2 + inc hl + inc hl + jr .findMatchingCoordsLoop + +PointerTable_37ce6: + dw PewterMuseumGuyCoords + dw PewterGymGuyCoords + +; these are the four coordinates of the spaces below, above, to the left and +; to the right of the museum guy, and pointers to different movements for +; the player to make to get positioned before the main movement. +PewterMuseumGuyCoords: + db 18, 27 + dw .down + db 16, 27 + dw .up + db 17, 26 + dw .left + db 17, 28 + dw .right + +.down + db D_UP, D_UP, $ff +.up + db D_RIGHT, D_LEFT, $ff +.left + db D_UP, D_RIGHT, $ff +.right + db D_UP, D_LEFT, $ff + +; these are the five coordinates which trigger the gym guy and pointers to +; different movements for the player to make to get positioned before the +; main movement +; $00 is a pause +PewterGymGuyCoords: + db 16, 34 + dw .one + db 17, 35 + dw .two + db 18, 37 + dw .three + db 19, 37 + dw .four + db 17, 36 + dw .five + +.one + db D_LEFT, D_DOWN, D_DOWN, D_RIGHT, $ff +.two + db D_LEFT, D_DOWN, D_RIGHT, D_LEFT, $ff +.three + db D_LEFT, D_LEFT, D_LEFT, $00, $00, $00, $00, $00, $00, $00, $00, $ff +.four + db D_LEFT, D_LEFT, D_UP, D_LEFT, $ff +.five + db D_LEFT, D_DOWN, D_LEFT, $00, $00, $00, $00, $00, $00, $00, $00, $ff diff --git a/engine/events/pick_up_item.asm b/engine/events/pick_up_item.asm new file mode 100644 index 00000000..9f19100a --- /dev/null +++ b/engine/events/pick_up_item.asm @@ -0,0 +1,54 @@ +PickUpItem: + call EnableAutoTextBoxDrawing + + ld a, [hSpriteIndexOrTextID] + ld b, a + ld hl, wMissableObjectList +.missableObjectsListLoop + ld a, [hli] + cp $ff + ret z + cp b + jr z, .isMissable + inc hl + jr .missableObjectsListLoop + +.isMissable + ld a, [hl] + ld [$ffdb], a + + ld hl, wMapSpriteExtraData + ld a, [hSpriteIndexOrTextID] + dec a + add a + ld d, 0 + ld e, a + add hl, de + ld a, [hl] + ld b, a ; item + ld c, 1 ; quantity + call GiveItem + jr nc, .BagFull + + ld a, [$ffdb] + ld [wMissableObjectIndex], a + predef HideObject + ld a, 1 + ld [wDoNotWaitForButtonPressAfterDisplayingText], a + ld hl, FoundItemText + jr .print + +.BagFull + ld hl, NoMoreRoomForItemText +.print + call PrintText + ret + +FoundItemText: + TX_FAR _FoundItemText + TX_SFX_ITEM_1 + db "@" + +NoMoreRoomForItemText: + TX_FAR _NoMoreRoomForItemText + db "@" diff --git a/engine/events/poison.asm b/engine/events/poison.asm new file mode 100644 index 00000000..5d8eb9fd --- /dev/null +++ b/engine/events/poison.asm @@ -0,0 +1,112 @@ +ApplyOutOfBattlePoisonDamage: + ld a, [wd730] + add a + jp c, .noBlackOut ; no black out if joypad states are being simulated + ld a, [wPartyCount] + and a + jp z, .noBlackOut + call IncrementDayCareMonExp + ld a, [wStepCounter] + and $3 ; is the counter a multiple of 4? + jp nz, .noBlackOut ; only apply poison damage every fourth step + ld [wWhichPokemon], a + ld hl, wPartyMon1Status + ld de, wPartySpecies +.applyDamageLoop + ld a, [hl] + and (1 << PSN) + jr z, .nextMon2 ; not poisoned + dec hl + dec hl + ld a, [hld] + ld b, a + ld a, [hli] + or b + jr z, .nextMon ; already fainted +; subtract 1 from HP + ld a, [hl] + dec a + ld [hld], a + inc a + jr nz, .noBorrow +; borrow 1 from upper byte of HP + dec [hl] + inc hl + jr .nextMon +.noBorrow + ld a, [hli] + or [hl] + jr nz, .nextMon ; didn't faint from damage +; the mon fainted from the damage + push hl + inc hl + inc hl + ld [hl], a + ld a, [de] + ld [wd11e], a + push de + ld a, [wWhichPokemon] + ld hl, wPartyMonNicks + call GetPartyMonName + xor a + ld [wJoyIgnore], a + call EnableAutoTextBoxDrawing + ld a, TEXT_MON_FAINTED + ld [hSpriteIndexOrTextID], a + call DisplayTextID + pop de + pop hl +.nextMon + inc hl + inc hl +.nextMon2 + inc de + ld a, [de] + inc a + jr z, .applyDamageLoopDone + ld bc, wPartyMon2 - wPartyMon1 + add hl, bc + push hl + ld hl, wWhichPokemon + inc [hl] + pop hl + jr .applyDamageLoop +.applyDamageLoopDone + ld hl, wPartyMon1Status + ld a, [wPartyCount] + ld d, a + ld e, 0 +.countPoisonedLoop + ld a, [hl] + and (1 << PSN) + or e + ld e, a + ld bc, wPartyMon2 - wPartyMon1 + add hl, bc + dec d + jr nz, .countPoisonedLoop + ld a, e + and a ; are any party members poisoned? + jr z, .skipPoisonEffectAndSound + ld b, $2 + predef ChangeBGPalColor0_4Frames ; change BG white to dark grey for 4 frames + ld a, SFX_POISONED + call PlaySound +.skipPoisonEffectAndSound + predef AnyPartyAlive + ld a, d + and a + jr nz, .noBlackOut + call EnableAutoTextBoxDrawing + ld a, TEXT_BLACKED_OUT + ld [hSpriteIndexOrTextID], a + call DisplayTextID + ld hl, wd72e + set 5, [hl] + ld a, $ff + jr .done +.noBlackOut + xor a +.done + ld [wOutOfBattleBlackout], a + ret diff --git a/engine/events/pokecenter.asm b/engine/events/pokecenter.asm new file mode 100755 index 00000000..f340e06d --- /dev/null +++ b/engine/events/pokecenter.asm @@ -0,0 +1,68 @@ +DisplayPokemonCenterDialogue_:: + call SaveScreenTilesToBuffer1 ; save screen + ld hl, PokemonCenterWelcomeText + call PrintText + ld hl, wd72e + bit 2, [hl] + set 1, [hl] + set 2, [hl] + jr nz, .skipShallWeHealYourPokemon + ld hl, ShallWeHealYourPokemonText + call PrintText +.skipShallWeHealYourPokemon + call YesNoChoicePokeCenter ; yes/no menu + ld a, [wCurrentMenuItem] + and a + jr nz, .declinedHealing ; if the player chose No + call SetLastBlackoutMap + call LoadScreenTilesFromBuffer1 ; restore screen + ld hl, NeedYourPokemonText + call PrintText + ld a, $18 + ld [wSpriteStateData1 + $12], a ; make the nurse turn to face the machine + call Delay3 + predef HealParty + callba AnimateHealingMachine ; do the healing machine animation + xor a + ld [wAudioFadeOutControl], a + ld a, [wAudioSavedROMBank] + ld [wAudioROMBank], a + ld a, [wMapMusicSoundID] + ld [wLastMusicSoundID], a + ld [wNewSoundID], a + call PlaySound + ld hl, PokemonFightingFitText + call PrintText + ld a, $14 + ld [wSpriteStateData1 + $12], a ; make the nurse bow + ld c, a + call DelayFrames + jr .done +.declinedHealing + call LoadScreenTilesFromBuffer1 ; restore screen +.done + ld hl, PokemonCenterFarewellText + call PrintText + jp UpdateSprites + +PokemonCenterWelcomeText: + TX_FAR _PokemonCenterWelcomeText + db "@" + +ShallWeHealYourPokemonText: + TX_DELAY + TX_FAR _ShallWeHealYourPokemonText + db "@" + +NeedYourPokemonText: + TX_FAR _NeedYourPokemonText + db "@" + +PokemonFightingFitText: + TX_FAR _PokemonFightingFitText + db "@" + +PokemonCenterFarewellText: + TX_DELAY + TX_FAR _PokemonCenterFarewellText + db "@" diff --git a/engine/events/pokedex_rating.asm b/engine/events/pokedex_rating.asm new file mode 100755 index 00000000..f1aaf618 --- /dev/null +++ b/engine/events/pokedex_rating.asm @@ -0,0 +1,154 @@ +DisplayDexRating: + ld hl, wPokedexSeen + ld b, wPokedexSeenEnd - wPokedexSeen + call CountSetBits + ld a, [wNumSetBits] + ld [hDexRatingNumMonsSeen], a + ld hl, wPokedexOwned + ld b, wPokedexOwnedEnd - wPokedexOwned + call CountSetBits + ld a, [wNumSetBits] + ld [hDexRatingNumMonsOwned], a + ld hl, DexRatingsTable +.findRating + ld a, [hli] + ld b, a + ld a, [hDexRatingNumMonsOwned] + cp b + jr c, .foundRating + inc hl + inc hl + jr .findRating +.foundRating + ld a, [hli] + ld h, [hl] + ld l, a ; load text pointer into hl + CheckAndResetEventA EVENT_HALL_OF_FAME_DEX_RATING + jr nz, .hallOfFame + push hl + ld hl, PokedexRatingText_441cc + call PrintText + pop hl + call PrintText + callba PlayPokedexRatingSfx + jp WaitForTextScrollButtonPress +.hallOfFame + ld de, wDexRatingNumMonsSeen + ld a, [hDexRatingNumMonsSeen] + ld [de], a + inc de + ld a, [hDexRatingNumMonsOwned] + ld [de], a + inc de +.copyRatingTextLoop + ld a, [hli] + cp "@" + jr z, .doneCopying + ld [de], a + inc de + jr .copyRatingTextLoop +.doneCopying + ld [de], a + ret + +PokedexRatingText_441cc: + TX_FAR _OaksLabText_441cc + db "@" + +DexRatingsTable: + db 10 + dw PokedexRatingText_44201 + db 20 + dw PokedexRatingText_44206 + db 30 + dw PokedexRatingText_4420b + db 40 + dw PokedexRatingText_44210 + db 50 + dw PokedexRatingText_44215 + db 60 + dw PokedexRatingText_4421a + db 70 + dw PokedexRatingText_4421f + db 80 + dw PokedexRatingText_44224 + db 90 + dw PokedexRatingText_44229 + db 100 + dw PokedexRatingText_4422e + db 110 + dw PokedexRatingText_44233 + db 120 + dw PokedexRatingText_44238 + db 130 + dw PokedexRatingText_4423d + db 140 + dw PokedexRatingText_44242 + db 150 + dw PokedexRatingText_44247 + db NUM_POKEMON + 1 + dw PokedexRatingText_4424c + +PokedexRatingText_44201: + TX_FAR _OaksLabText_44201 + db "@" + +PokedexRatingText_44206: + TX_FAR _OaksLabText_44206 + db "@" + +PokedexRatingText_4420b: + TX_FAR _OaksLabText_4420b + db "@" + +PokedexRatingText_44210: + TX_FAR _OaksLabText_44210 + db "@" + +PokedexRatingText_44215: + TX_FAR _OaksLabText_44215 + db "@" + +PokedexRatingText_4421a: + TX_FAR _OaksLabText_4421a + db "@" + +PokedexRatingText_4421f: + TX_FAR _OaksLabText_4421f + db "@" + +PokedexRatingText_44224: + TX_FAR _OaksLabText_44224 + db "@" + +PokedexRatingText_44229: + TX_FAR _OaksLabText_44229 + db "@" + +PokedexRatingText_4422e: + TX_FAR _OaksLabText_4422e + db "@" + +PokedexRatingText_44233: + TX_FAR _OaksLabText_44233 + db "@" + +PokedexRatingText_44238: + TX_FAR _OaksLabText_44238 + db "@" + +PokedexRatingText_4423d: + TX_FAR _OaksLabText_4423d + db "@" + +PokedexRatingText_44242: + TX_FAR _OaksLabText_44242 + db "@" + +PokedexRatingText_44247: + TX_FAR _OaksLabText_44247 + db "@" + +PokedexRatingText_4424c: + TX_FAR _OaksLabText_4424c + db "@" diff --git a/engine/events/pokemart.asm b/engine/events/pokemart.asm new file mode 100755 index 00000000..177e8a09 --- /dev/null +++ b/engine/events/pokemart.asm @@ -0,0 +1,272 @@ +DisplayPokemartDialogue_:: + ld a, [wListScrollOffset] + ld [wSavedListScrollOffset], a + call UpdateSprites + xor a + ld [wBoughtOrSoldItemInMart], a +.loop + xor a + ld [wListScrollOffset], a + ld [wCurrentMenuItem], a + ld [wPlayerMonNumber], a + inc a + ld [wPrintItemPrices], a + ld a, MONEY_BOX + ld [wTextBoxID], a + call DisplayTextBoxID + ld a, BUY_SELL_QUIT_MENU + ld [wTextBoxID], a + call DisplayTextBoxID + +; This code is useless. It copies the address of the pokemart's inventory to hl, +; but the address is never used. + ld hl, wItemListPointer + ld a, [hli] + ld l, [hl] + ld h, a + + ld a, [wMenuExitMethod] + cp CANCELLED_MENU + jp z, .done + ld a, [wChosenMenuItem] + and a ; buying? + jp z, .buyMenu + dec a ; selling? + jp z, .sellMenu + dec a ; quitting? + jp z, .done +.sellMenu + +; the same variables are set again below, so this code has no effect + xor a + ld [wPrintItemPrices], a + ld a, INIT_BAG_ITEM_LIST + ld [wInitListType], a + callab InitList + + ld a, [wNumBagItems] + and a + jp z, .bagEmpty + ld hl, PokemonSellingGreetingText + call PrintText + call SaveScreenTilesToBuffer1 ; save screen +.sellMenuLoop + call LoadScreenTilesFromBuffer1 ; restore saved screen + ld a, MONEY_BOX + ld [wTextBoxID], a + call DisplayTextBoxID ; draw money text box + ld hl, wNumBagItems + ld a, l + ld [wListPointer], a + ld a, h + ld [wListPointer + 1], a + xor a + ld [wPrintItemPrices], a + ld [wCurrentMenuItem], a + ld a, ITEMLISTMENU + ld [wListMenuID], a + call DisplayListMenuID + jp c, .returnToMainPokemartMenu ; if the player closed the menu +.confirmItemSale ; if the player is trying to sell a specific item + call IsKeyItem + ld a, [wIsKeyItem] + and a + jr nz, .unsellableItem + ld a, [wcf91] + call IsItemHM + jr c, .unsellableItem + ld a, PRICEDITEMLISTMENU + ld [wListMenuID], a + ld [hHalveItemPrices], a ; halve prices when selling + call DisplayChooseQuantityMenu + inc a + jr z, .sellMenuLoop ; if the player closed the choose quantity menu with the B button + ld hl, PokemartTellSellPriceText + lb bc, 14, 1 ; location that PrintText always prints to, this is useless + call PrintText + coord hl, 14, 7 + lb bc, 8, 15 + ld a, TWO_OPTION_MENU + ld [wTextBoxID], a + call DisplayTextBoxID ; yes/no menu + ld a, [wMenuExitMethod] + cp CHOSE_SECOND_ITEM + jr z, .sellMenuLoop ; if the player chose No or pressed the B button + +; The following code is supposed to check if the player chose No, but the above +; check already catches it. + ld a, [wChosenMenuItem] + dec a + jr z, .sellMenuLoop + +.sellItem + ld a, [wBoughtOrSoldItemInMart] + and a + jr nz, .skipSettingFlag1 + inc a + ld [wBoughtOrSoldItemInMart], a +.skipSettingFlag1 + call AddAmountSoldToMoney + ld hl, wNumBagItems + call RemoveItemFromInventory + jp .sellMenuLoop +.unsellableItem + ld hl, PokemartUnsellableItemText + call PrintText + jp .returnToMainPokemartMenu +.bagEmpty + ld hl, PokemartItemBagEmptyText + call PrintText + call SaveScreenTilesToBuffer1 + jp .returnToMainPokemartMenu +.buyMenu + +; the same variables are set again below, so this code has no effect + ld a, 1 + ld [wPrintItemPrices], a + ld a, INIT_OTHER_ITEM_LIST + ld [wInitListType], a + callab InitList + + ld hl, PokemartBuyingGreetingText + call PrintText + call SaveScreenTilesToBuffer1 +.buyMenuLoop + call LoadScreenTilesFromBuffer1 + ld a, MONEY_BOX + ld [wTextBoxID], a + call DisplayTextBoxID + ld hl, wItemList + ld a, l + ld [wListPointer], a + ld a, h + ld [wListPointer + 1], a + xor a + ld [wCurrentMenuItem], a + inc a + ld [wPrintItemPrices], a + inc a ; a = 2 (PRICEDITEMLISTMENU) + ld [wListMenuID], a + call DisplayListMenuID + jr c, .returnToMainPokemartMenu ; if the player closed the menu + ld a, 99 + ld [wMaxItemQuantity], a + xor a + ld [hHalveItemPrices], a ; don't halve item prices when buying + call DisplayChooseQuantityMenu + inc a + jr z, .buyMenuLoop ; if the player closed the choose quantity menu with the B button + ld a, [wcf91] ; item ID + ld [wd11e], a ; store item ID for GetItemName + call GetItemName + call CopyStringToCF4B ; copy name to wcf4b + ld hl, PokemartTellBuyPriceText + call PrintText + coord hl, 14, 7 + lb bc, 8, 15 + ld a, TWO_OPTION_MENU + ld [wTextBoxID], a + call DisplayTextBoxID ; yes/no menu + ld a, [wMenuExitMethod] + cp CHOSE_SECOND_ITEM + jp z, .buyMenuLoop ; if the player chose No or pressed the B button + +; The following code is supposed to check if the player chose No, but the above +; check already catches it. + ld a, [wChosenMenuItem] + dec a + jr z, .buyMenuLoop + +.buyItem + call .isThereEnoughMoney + jr c, .notEnoughMoney + ld hl, wNumBagItems + call AddItemToInventory + jr nc, .bagFull + call SubtractAmountPaidFromMoney + ld a, [wBoughtOrSoldItemInMart] + and a + jr nz, .skipSettingFlag2 + ld a, 1 + ld [wBoughtOrSoldItemInMart], a +.skipSettingFlag2 + ld a, SFX_PURCHASE + call PlaySoundWaitForCurrent + call WaitForSoundToFinish + ld hl, PokemartBoughtItemText + call PrintText + jp .buyMenuLoop +.returnToMainPokemartMenu + call LoadScreenTilesFromBuffer1 + ld a, MONEY_BOX + ld [wTextBoxID], a + call DisplayTextBoxID + ld hl, PokemartAnythingElseText + call PrintText + jp .loop +.isThereEnoughMoney + ld de, wPlayerMoney + ld hl, hMoney + ld c, 3 ; length of money in bytes + jp StringCmp +.notEnoughMoney + ld hl, PokemartNotEnoughMoneyText + call PrintText + jr .returnToMainPokemartMenu +.bagFull + ld hl, PokemartItemBagFullText + call PrintText + jr .returnToMainPokemartMenu +.done + ld hl, PokemartThankYouText + call PrintText + ld a, 1 + ld [wUpdateSpritesEnabled], a + call UpdateSprites + ld a, [wSavedListScrollOffset] + ld [wListScrollOffset], a + ret + +PokemartBuyingGreetingText: + TX_FAR _PokemartBuyingGreetingText + db "@" + +PokemartTellBuyPriceText: + TX_FAR _PokemartTellBuyPriceText + db "@" + +PokemartBoughtItemText: + TX_FAR _PokemartBoughtItemText + db "@" + +PokemartNotEnoughMoneyText: + TX_FAR _PokemartNotEnoughMoneyText + db "@" + +PokemartItemBagFullText: + TX_FAR _PokemartItemBagFullText + db "@" + +PokemonSellingGreetingText: + TX_FAR _PokemonSellingGreetingText + db "@" + +PokemartTellSellPriceText: + TX_FAR _PokemartTellSellPriceText + db "@" + +PokemartItemBagEmptyText: + TX_FAR _PokemartItemBagEmptyText + db "@" + +PokemartUnsellableItemText: + TX_FAR _PokemartUnsellableItemText + db "@" + +PokemartThankYouText: + TX_FAR _PokemartThankYouText + db "@" + +PokemartAnythingElseText: + TX_FAR _PokemartAnythingElseText + db "@" diff --git a/engine/events/prize_menu.asm b/engine/events/prize_menu.asm new file mode 100755 index 00000000..5e08bb8f --- /dev/null +++ b/engine/events/prize_menu.asm @@ -0,0 +1,306 @@ +CeladonPrizeMenu:: + ld b, COIN_CASE + call IsItemInBag + jr nz, .havingCoinCase + ld hl, RequireCoinCaseTextPtr + jp PrintText +.havingCoinCase + ld hl, wd730 + set 6, [hl] ; disable letter-printing delay + ld hl, ExchangeCoinsForPrizesTextPtr + call PrintText +; the following are the menu settings + xor a + ld [wCurrentMenuItem], a + ld [wLastMenuItem], a + ld a, A_BUTTON | B_BUTTON + ld [wMenuWatchedKeys], a + ld a, $03 + ld [wMaxMenuItem], a + ld a, $04 + ld [wTopMenuItemY], a + ld a, $01 + ld [wTopMenuItemX], a + call PrintPrizePrice + coord hl, 0, 2 + ld b, 8 + ld c, 16 + call TextBoxBorder + call GetPrizeMenuId + call UpdateSprites + ld hl, WhichPrizeTextPtr + call PrintText + call HandleMenuInput ; menu choice handler + bit 1, a ; keypress = B (Cancel) + jr nz, .noChoice + ld a, [wCurrentMenuItem] + cp 3 ; "NO,THANKS" choice + jr z, .noChoice + call HandlePrizeChoice +.noChoice + ld hl, wd730 + res 6, [hl] + ret + +RequireCoinCaseTextPtr: + TX_FAR _RequireCoinCaseText + TX_WAIT + db "@" + +ExchangeCoinsForPrizesTextPtr: + TX_FAR _ExchangeCoinsForPrizesText + db "@" + +WhichPrizeTextPtr: + TX_FAR _WhichPrizeText + db "@" + +GetPrizeMenuId: +; determine which one among the three +; prize-texts has been selected +; using the text ID (stored in [hSpriteIndexOrTextID]) +; load the three prizes at wd13d-wd13f +; load the three prices at wd141-wd146 +; display the three prizes' names +; (distinguishing between Pokemon names +; and Items (specifically TMs) names) + ld a, [hSpriteIndexOrTextID] + sub 3 ; prize-texts' id are 3, 4 and 5 + ld [wWhichPrizeWindow], a ; prize-texts' id (relative, i.e. 0, 1 or 2) + add a + add a + ld d, 0 + ld e, a + ld hl, PrizeDifferentMenuPtrs + add hl, de + ld a, [hli] + ld d, [hl] + ld e, a + inc hl + push hl + ld hl, wPrize1 + call CopyString + pop hl + ld a, [hli] + ld h, [hl] + ld l, a + ld de, wPrize1Price + ld bc, 6 + call CopyData + ld a, [wWhichPrizeWindow] + cp 2 ;is TM_menu? + jr nz, .putMonName + ld a, [wPrize1] + ld [wd11e], a + call GetItemName + coord hl, 2, 4 + call PlaceString + ld a, [wPrize2] + ld [wd11e], a + call GetItemName + coord hl, 2, 6 + call PlaceString + ld a, [wPrize3] + ld [wd11e], a + call GetItemName + coord hl, 2, 8 + call PlaceString + jr .putNoThanksText +.putMonName + ld a, [wPrize1] + ld [wd11e], a + call GetMonName + coord hl, 2, 4 + call PlaceString + ld a, [wPrize2] + ld [wd11e], a + call GetMonName + coord hl, 2, 6 + call PlaceString + ld a, [wPrize3] + ld [wd11e], a + call GetMonName + coord hl, 2, 8 + call PlaceString +.putNoThanksText + coord hl, 2, 10 + ld de, NoThanksText + call PlaceString +; put prices on the right side of the textbox + ld de, wPrize1Price + coord hl, 13, 5 +; reg. c: +; [low nybble] number of bytes +; [bit 765 = %100] space-padding (not zero-padding) + ld c, (1 << 7 | 2) +; Function $15CD displays BCD value (same routine +; used by text-command $02) + call PrintBCDNumber + ld de, wPrize2Price + coord hl, 13, 7 + ld c, (1 << 7 | 2) + call PrintBCDNumber + ld de, wPrize3Price + coord hl, 13, 9 + ld c, (1 << 7 | 2) + jp PrintBCDNumber + +INCLUDE "data/prizes.asm" + +PrintPrizePrice: + coord hl, 11, 0 + ld b, 1 + ld c, 7 + call TextBoxBorder + call UpdateSprites + coord hl, 12, 0 + ld de, .CoinString + call PlaceString + coord hl, 13, 1 + ld de, .SixSpacesString + call PlaceString + coord hl, 13, 1 + ld de, wPlayerCoins + ld c, %10000010 + call PrintBCDNumber + ret + +.CoinString: + db "COIN@" + +.SixSpacesString: + db " @" + +LoadCoinsToSubtract: + ld a, [wWhichPrize] + add a + ld d, 0 + ld e, a + ld hl, wPrize1Price + add hl, de ; get selected prize's price + xor a + ld [hUnusedCoinsByte], a + ld a, [hli] + ld [hCoins], a + ld a, [hl] + ld [hCoins + 1], a + ret + +HandlePrizeChoice: + ld a, [wCurrentMenuItem] + ld [wWhichPrize], a + ld d, 0 + ld e, a + ld hl, wPrize1 + add hl, de + ld a, [hl] + ld [wd11e], a + ld a, [wWhichPrizeWindow] + cp 2 ; is prize a TM? + jr nz, .getMonName + call GetItemName + jr .givePrize +.getMonName + call GetMonName +.givePrize + ld hl, SoYouWantPrizeTextPtr + call PrintText + call YesNoChoice + ld a, [wCurrentMenuItem] ; yes/no answer (Y=0, N=1) + and a + jr nz, .printOhFineThen + call LoadCoinsToSubtract + call HasEnoughCoins + jr c, .notEnoughCoins + ld a, [wWhichPrizeWindow] + cp $02 + jr nz, .giveMon + ld a, [wd11e] + ld b, a + ld a, 1 + ld c, a + call GiveItem + jr nc, .bagFull + jr .subtractCoins +.giveMon + ld a, [wd11e] + ld [wcf91], a + push af + call GetPrizeMonLevel + ld c, a + pop af + ld b, a + call GivePokemon + +; If either the party or box was full, wait after displaying message. + push af + ld a, [wAddedToParty] + and a + call z, WaitForTextScrollButtonPress + pop af + +; If the mon couldn't be given to the player (because both the party and box +; were full), return without subtracting coins. + ret nc + +.subtractCoins + call LoadCoinsToSubtract + ld hl, hCoins + 1 + ld de, wPlayerCoins + 1 + ld c, $02 ; how many bytes + predef SubBCDPredef + jp PrintPrizePrice +.bagFull + ld hl, PrizeRoomBagIsFullTextPtr + jp PrintText +.notEnoughCoins + ld hl, SorryNeedMoreCoinsText + jp PrintText +.printOhFineThen + ld hl, OhFineThenTextPtr + jp PrintText + +UnknownPrizeData: +; XXX what's this? + db $00,$01,$00,$01,$00,$01,$00,$00,$01 + +HereYouGoTextPtr: + TX_FAR _HereYouGoText + TX_WAIT + db "@" + +SoYouWantPrizeTextPtr: + TX_FAR _SoYouWantPrizeText + db "@" + +SorryNeedMoreCoinsText: + TX_FAR _SorryNeedMoreCoinsText + TX_WAIT + db "@" + +PrizeRoomBagIsFullTextPtr: + TX_FAR _OopsYouDontHaveEnoughRoomText + TX_WAIT + db "@" + +OhFineThenTextPtr: + TX_FAR _OhFineThenText + TX_WAIT + db "@" + +GetPrizeMonLevel: + ld a, [wcf91] + ld b, a + ld hl, PrizeMonLevelDictionary +.loop + ld a, [hli] + cp b + jr z, .matchFound + inc hl + jr .loop +.matchFound + ld a, [hl] + ld [wCurEnemyLVL], a + ret + +INCLUDE "data/prize_mon_levels.asm" diff --git a/engine/events/saffron_guards.asm b/engine/events/saffron_guards.asm new file mode 100755 index 00000000..091cfa1a --- /dev/null +++ b/engine/events/saffron_guards.asm @@ -0,0 +1,15 @@ +RemoveGuardDrink:: + ld hl, GuardDrinksList +.drinkLoop + ld a, [hli] + ld [$ffdb], a + and a + ret z + push hl + ld b, a + call IsItemInBag + pop hl + jr z, .drinkLoop + jpba RemoveItemByID + +INCLUDE "data/guard_drink_items.asm" diff --git a/engine/events/set_blackout_map.asm b/engine/events/set_blackout_map.asm new file mode 100644 index 00000000..14f0ba28 --- /dev/null +++ b/engine/events/set_blackout_map.asm @@ -0,0 +1,25 @@ +SetLastBlackoutMap: +; Set the map to return to when +; blacking out or using Teleport or Dig. +; Safari rest houses don't count. + + push hl + ld hl, SafariZoneRestHouses + ld a, [wCurMap] + ld b, a +.loop + ld a, [hli] + cp -1 + jr z, .notresthouse + cp b + jr nz, .loop + jr .done + +.notresthouse + ld a, [wLastMap] + ld [wLastBlackoutMap], a +.done + pop hl + ret + +INCLUDE "data/rest_house_maps.asm" diff --git a/engine/events/starter_dex.asm b/engine/events/starter_dex.asm new file mode 100755 index 00000000..21289c6a --- /dev/null +++ b/engine/events/starter_dex.asm @@ -0,0 +1,9 @@ +; this function temporarily makes the starters (and Ivysaur) seen +; so that the full Pokedex information gets displayed in Oak's lab +StarterDex: + ld a, %01001011 ; set starter flags + ld [wPokedexOwned], a + predef ShowPokedexData + xor a ; unset starter flags + ld [wPokedexOwned], a + ret diff --git a/engine/events/vending_machine.asm b/engine/events/vending_machine.asm new file mode 100755 index 00000000..554c5d4f --- /dev/null +++ b/engine/events/vending_machine.asm @@ -0,0 +1,133 @@ +VendingMachineMenu:: + ld hl, VendingMachineText1 + call PrintText + ld a, MONEY_BOX + ld [wTextBoxID], a + call DisplayTextBoxID + xor a + ld [wCurrentMenuItem], a + ld [wLastMenuItem], a + ld a, A_BUTTON | B_BUTTON + ld [wMenuWatchedKeys], a + ld a, 3 + ld [wMaxMenuItem], a + ld a, 5 + ld [wTopMenuItemY], a + ld a, 1 + ld [wTopMenuItemX], a + ld hl, wd730 + set 6, [hl] + coord hl, 0, 3 + ld b, 8 + ld c, 12 + call TextBoxBorder + call UpdateSprites + coord hl, 2, 5 + ld de, DrinkText + call PlaceString + coord hl, 9, 6 + ld de, DrinkPriceText + call PlaceString + ld hl, wd730 + res 6, [hl] + call HandleMenuInput + bit 1, a ; pressed B? + jr nz, .notThirsty + ld a, [wCurrentMenuItem] + cp 3 ; chose Cancel? + jr z, .notThirsty + xor a + ld [hMoney], a + ld [hMoney + 2], a + ld a, $2 + ld [hMoney + 1], a + call HasEnoughMoney + jr nc, .enoughMoney + ld hl, VendingMachineText4 + jp PrintText +.enoughMoney + call LoadVendingMachineItem + ld a, [hVendingMachineItem] + ld b, a + ld c, 1 + call GiveItem + jr nc, .BagFull + + ld b, 60 ; number of times to play the "brrrrr" sound +.playDeliverySound + ld c, 2 + call DelayFrames + push bc + ld a, SFX_PUSH_BOULDER + call PlaySound + pop bc + dec b + jr nz, .playDeliverySound + + ld hl, VendingMachineText5 + call PrintText + ld hl, hVendingMachinePrice + 2 + ld de, wPlayerMoney + 2 + ld c, $3 + predef SubBCDPredef + ld a, MONEY_BOX + ld [wTextBoxID], a + jp DisplayTextBoxID +.BagFull + ld hl, VendingMachineText6 + jp PrintText +.notThirsty + ld hl, VendingMachineText7 + jp PrintText + +VendingMachineText1: + TX_FAR _VendingMachineText1 + db "@" + +DrinkText: + db "FRESH WATER" + next "SODA POP" + next "LEMONADE" + next "CANCEL@" + +DrinkPriceText: + db "¥200" + next "¥300" + next "¥350" + next "@" + +VendingMachineText4: + TX_FAR _VendingMachineText4 + db "@" + +VendingMachineText5: + TX_FAR _VendingMachineText5 + db "@" + +VendingMachineText6: + TX_FAR _VendingMachineText6 + db "@" + +VendingMachineText7: + TX_FAR _VendingMachineText7 + db "@" + +LoadVendingMachineItem: + ld hl, VendingPrices + ld a, [wCurrentMenuItem] + add a + add a + ld d, 0 + ld e, a + add hl, de + ld a, [hli] + ld [hVendingMachineItem], a + ld a, [hli] + ld [hVendingMachinePrice], a + ld a, [hli] + ld [hVendingMachinePrice + 1], a + ld a, [hl] + ld [hVendingMachinePrice + 2], a + ret + +INCLUDE "data/vending_prices.asm" |