diff options
author | einstein95 <einstein95@users.noreply.github.com> | 2017-08-10 18:35:24 +1200 |
---|---|---|
committer | einstein95 <einstein95@users.noreply.github.com> | 2017-08-10 18:35:24 +1200 |
commit | bfff18f882b325827fbfc892ba4ce5b9e1a51604 (patch) | |
tree | d8db8dc0caa7d42b493d820fd5a0975f5331092a | |
parent | 834fa28551f3f0df9668be8d344c8affaf94c62a (diff) |
Update to latest pokered
103 files changed, 2889 insertions, 2873 deletions
diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..bd38f51b --- /dev/null +++ b/.travis.yml @@ -0,0 +1,24 @@ +language: c +install: + - |- + path="$(pwd)"; cd; + wget https://github.com/rednex/rgbds/archive/v0.2.5.tar.gz -O rgbds.tar.gz && + tar xf rgbds.tar.gz && + cd rgbds-0.2.5 && + sudo make install && + cd - && + rm -rf rgbds && + cd "$path" +before_script: + - |- + function check_status() { + if ! git diff-index --quiet --ignore-submodules=all HEAD --; then + echo 'Uncommitted changes detected:'; + git diff-index HEAD --; + return 1; + fi; + } +script: + - make + - make compare + - check_status @@ -2,8 +2,9 @@ sudo apt-get install make gcc bison git python - git clone https://github.com/bentley/rgbds + git clone https://github.com/rednex/rgbds cd rgbds + git checkout v0.2.5 sudo make install cd .. @@ -26,8 +27,9 @@ In **Terminal**, run: xcode-select --install - git clone https://github.com/bentley/rgbds + git clone https://github.com/rednex/rgbds cd rgbds + git checkout v0.2.5 sudo make install cd .. @@ -43,8 +45,8 @@ To build on Windows, use [**Cygwin**](http://cygwin.com/install.html). Use the d In the installer, select the following packages: `make` `git` `python` `gettext` -Then get the most recent version of [**rgbds**](https://github.com/bentley/rgbds/releases/). -Extract the archive and put `rgbasm.exe`, `rgblink.exe` and `rgbfix.exe` in `C:\cygwin\usr\local\bin`. +Then get [**rgbds 0.2.5**](https://github.com/bentley/rgbds/releases/tag/v0.2.5). +Extract the archive and put `rgbasm.exe`, `rgblink.exe`, `rgbfix.exe` and `rgbgfx.exe` in `C:\cygwin\usr\local\bin`. If your Cygwin installation directory differs, ensure the `bin` directory is present in the PATH variable. In the **Cygwin terminal**: @@ -541,7 +541,7 @@ Music_PokeFluteInBattle:: ; begin playing the "caught mon" sound effect ld a, SFX_CAUGHT_MON call PlaySoundWaitForCurrent - ; then immediately overwrtie the channel pointers + ; then immediately overwrite the channel pointers ld hl, wChannelCommandPointers + Ch4 * 2 ld de, SFX_08_PokeFlute_Ch4 call Audio2_OverwriteChannelPointer diff --git a/constants/hardware_constants.asm b/constants/hardware_constants.asm index 21a3ad93..d6af3584 100644 --- a/constants/hardware_constants.asm +++ b/constants/hardware_constants.asm @@ -68,7 +68,7 @@ rNR34 EQU $ff1e ; Channel 3 Frequency's higher data (R/W) rNR41 EQU $ff20 ; Channel 4 Sound Length (R/W) rNR42 EQU $ff21 ; Channel 4 Volume Envelope (R/W) rNR43 EQU $ff22 ; Channel 4 Polynomial Counter (R/W) -rNR44 EQU $ff23 ; Channel 4 Counter/consecutive; Inital (R/W) +rNR44 EQU $ff23 ; Channel 4 Counter/consecutive; Initial (R/W) rNR50 EQU $ff24 ; Channel control / ON-OFF / Volume (R/W) rNR51 EQU $ff25 ; Selection of Sound output terminal (R/W) rNR52 EQU $ff26 ; Sound on/off diff --git a/constants/misc_constants.asm b/constants/misc_constants.asm index 57b19a37..d4f231b5 100644 --- a/constants/misc_constants.asm +++ b/constants/misc_constants.asm @@ -120,7 +120,7 @@ TMHM_PARTY_MENU EQU 3 SWAP_MONS_PARTY_MENU EQU 4 EVO_STONE_PARTY_MENU EQU 5 -; party memu message IDs +; party menu message IDs ANTIDOTE_MSG EQU $F0 BURN_HEAL_MSG EQU $F1 ICE_HEAL_MSG EQU $F2 diff --git a/constants/music_constants.asm b/constants/music_constants.asm index 57ad230d..5eb05b61 100644 --- a/constants/music_constants.asm +++ b/constants/music_constants.asm @@ -194,7 +194,7 @@ ENDM music_const SFX_SAVE, SFX_Save_1 ; AUDIO_1 - music_const SFX_POKEFLUE, SFX_Pokeflute + music_const SFX_POKEFLUTE, SFX_Pokeflute music_const SFX_SAFARI_ZONE_PA, SFX_Safari_Zone_PA ; AUDIO_2 diff --git a/data/trainer_parties.asm b/data/trainer_parties.asm index 0c586dad..da4f80c9 100755 --- a/data/trainer_parties.asm +++ b/data/trainer_parties.asm @@ -391,18 +391,18 @@ JugglerData: db 29,KADABRA,MR_MIME,0 ; Victory Road 2F db 41,DROWZEE,HYPNO,KADABRA,KADABRA,0 -; Fucshia Gym +; Fuchsia Gym db 31,DROWZEE,DROWZEE,KADABRA,DROWZEE,0 db 34,DROWZEE,HYPNO,0 ; Victory Road 2F db 48,MR_MIME,0 ; Unused db 33,HYPNO,0 -; Fucshia Gym +; Fuchsia Gym db 38,HYPNO,0 db 34,DROWZEE,KADABRA,0 TamerData: -; Fucshia Gym +; Fuchsia Gym db 34,SANDSLASH,ARBOK,0 db 33,ARBOK,SANDSLASH,ARBOK,0 ; Viridian Gym diff --git a/engine/add_mon.asm b/engine/add_mon.asm new file mode 100644 index 00000000..b2feeb12 --- /dev/null +++ b/engine/add_mon.asm @@ -0,0 +1,516 @@ +_AddPartyMon: +; Adds a new mon to the player's or enemy's party. +; [wMonDataLocation] is used in an unusual way in this function. +; If the lower nybble is 0, the mon is added to the player's party, else the enemy's. +; If the entire value is 0, then the player is allowed to name the mon. + ld de, wPartyCount + ld a, [wMonDataLocation] + and $f + jr z, .next + ld de, wEnemyPartyCount +.next + ld a, [de] + inc a + cp PARTY_LENGTH + 1 + ret nc ; return if the party is already full + ld [de], a + ld a, [de] + ld [hNewPartyLength], a + add e + ld e, a + jr nc, .noCarry + inc d +.noCarry + ld a, [wcf91] + ld [de], a ; write species of new mon in party list + inc de + ld a, $ff ; terminator + ld [de], a + ld hl, wPartyMonOT + ld a, [wMonDataLocation] + and $f + jr z, .next2 + ld hl, wEnemyMonOT +.next2 + ld a, [hNewPartyLength] + dec a + call SkipFixedLengthTextEntries + ld d, h + ld e, l + ld hl, wPlayerName + ld bc, NAME_LENGTH + call CopyData + ld a, [wMonDataLocation] + and a + jr nz, .skipNaming + ld hl, wPartyMonNicks + ld a, [hNewPartyLength] + dec a + call SkipFixedLengthTextEntries + ld a, NAME_MON_SCREEN + ld [wNamingScreenType], a + predef AskName +.skipNaming + ld hl, wPartyMons + ld a, [wMonDataLocation] + and $f + jr z, .next3 + ld hl, wEnemyMons +.next3 + ld a, [hNewPartyLength] + dec a + ld bc, wPartyMon2 - wPartyMon1 + call AddNTimes + ld e, l + ld d, h + push hl + ld a, [wcf91] + ld [wd0b5], a + call GetMonHeader + ld hl, wMonHeader + ld a, [hli] + ld [de], a ; species + inc de + pop hl + push hl + ld a, [wMonDataLocation] + and $f + ld a, $98 ; set enemy trainer mon IVs to fixed average values + ld b, $88 + jr nz, .next4 + +; If the mon is being added to the player's party, update the pokedex. + ld a, [wcf91] + ld [wd11e], a + push de + predef IndexToPokedex + pop de + ld a, [wd11e] + dec a + ld c, a + ld b, FLAG_TEST + ld hl, wPokedexOwned + call FlagAction + ld a, c ; whether the mon was already flagged as owned + ld [wUnusedD153], a ; not read + ld a, [wd11e] + dec a + ld c, a + ld b, FLAG_SET + push bc + call FlagAction + pop bc + ld hl, wPokedexSeen + call FlagAction + + pop hl + push hl + + ld a, [wIsInBattle] + and a ; is this a wild mon caught in battle? + jr nz, .copyEnemyMonData + +; Not wild. + call Random ; generate random IVs + ld b, a + call Random + +.next4 + push bc + ld bc, wPartyMon1DVs - wPartyMon1 + add hl, bc + pop bc + ld [hli], a + ld [hl], b ; write IVs + ld bc, (wPartyMon1HPExp - 1) - (wPartyMon1DVs + 1) + add hl, bc + ld a, 1 + ld c, a + xor a + ld b, a + call CalcStat ; calc HP stat (set cur Hp to max HP) + ld a, [H_MULTIPLICAND+1] + ld [de], a + inc de + ld a, [H_MULTIPLICAND+2] + ld [de], a + inc de + xor a + ld [de], a ; box level + inc de + ld [de], a ; status ailments + inc de + jr .copyMonTypesAndMoves +.copyEnemyMonData + ld bc, wEnemyMon1DVs - wEnemyMon1 + add hl, bc + ld a, [wEnemyMonDVs] ; copy IVs from cur enemy mon + ld [hli], a + ld a, [wEnemyMonDVs + 1] + ld [hl], a + ld a, [wEnemyMonHP] ; copy HP from cur enemy mon + ld [de], a + inc de + ld a, [wEnemyMonHP+1] + ld [de], a + inc de + xor a + ld [de], a ; box level + inc de + ld a, [wEnemyMonStatus] ; copy status ailments from cur enemy mon + ld [de], a + inc de +.copyMonTypesAndMoves + ld hl, wMonHTypes + ld a, [hli] ; type 1 + ld [de], a + inc de + ld a, [hli] ; type 2 + ld [de], a + inc de + ld a, [hli] ; catch rate (held item in gen 2) + ld [de], a + ld hl, wMonHMoves + ld a, [hli] + inc de + push de + ld [de], a + ld a, [hli] + inc de + ld [de], a + ld a, [hli] + inc de + ld [de], a + ld a, [hli] + inc de + ld [de], a + push de + dec de + dec de + dec de + xor a + ld [wLearningMovesFromDayCare], a + predef WriteMonMoves + pop de + ld a, [wPlayerID] ; set trainer ID to player ID + inc de + ld [de], a + ld a, [wPlayerID + 1] + inc de + ld [de], a + push de + ld a, [wCurEnemyLVL] + ld d, a + callab CalcExperience + pop de + inc de + ld a, [hExperience] ; write experience + ld [de], a + inc de + ld a, [hExperience + 1] + ld [de], a + inc de + ld a, [hExperience + 2] + ld [de], a + xor a + ld b, NUM_STATS * 2 +.writeEVsLoop ; set all EVs to 0 + inc de + ld [de], a + dec b + jr nz, .writeEVsLoop + inc de + inc de + pop hl + call AddPartyMon_WriteMovePP + inc de + ld a, [wCurEnemyLVL] + ld [de], a + inc de + ld a, [wIsInBattle] + dec a + jr nz, .calcFreshStats + ld hl, wEnemyMonMaxHP + ld bc, $a + call CopyData ; copy stats of cur enemy mon + pop hl + jr .done +.calcFreshStats + pop hl + ld bc, wPartyMon1HPExp - 1 - wPartyMon1 + add hl, bc + ld b, $0 + call CalcStats ; calculate fresh set of stats +.done + scf + ret + +LoadMovePPs: + call GetPredefRegisters + ; fallthrough +AddPartyMon_WriteMovePP: + ld b, NUM_MOVES +.pploop + ld a, [hli] ; read move ID + and a + jr z, .empty + dec a + push hl + push de + push bc + ld hl, Moves + ld bc, MoveEnd - Moves + call AddNTimes + ld de, wcd6d + ld a, BANK(Moves) + call FarCopyData + pop bc + pop de + pop hl + ld a, [wcd6d + 5] ; PP is byte 5 of move data +.empty + inc de + ld [de], a + dec b + jr nz, .pploop ; there are still moves to read + ret + +; adds enemy mon [wcf91] (at position [wWhichPokemon] in enemy list) to own party +; used in the cable club trade center +_AddEnemyMonToPlayerParty: + ld hl, wPartyCount + ld a, [hl] + cp PARTY_LENGTH + scf + ret z ; party full, return failure + inc a + ld [hl], a ; add 1 to party members + ld c, a + ld b, $0 + add hl, bc + ld a, [wcf91] + ld [hli], a ; add mon as last list entry + ld [hl], $ff ; write new sentinel + ld hl, wPartyMons + ld a, [wPartyCount] + dec a + ld bc, wPartyMon2 - wPartyMon1 + call AddNTimes + ld e, l + ld d, h + ld hl, wLoadedMon + call CopyData ; write new mon's data (from wLoadedMon) + ld hl, wPartyMonOT + ld a, [wPartyCount] + dec a + call SkipFixedLengthTextEntries + ld d, h + ld e, l + ld hl, wEnemyMonOT + ld a, [wWhichPokemon] + call SkipFixedLengthTextEntries + ld bc, NAME_LENGTH + call CopyData ; write new mon's OT name (from an enemy mon) + ld hl, wPartyMonNicks + ld a, [wPartyCount] + dec a + call SkipFixedLengthTextEntries + ld d, h + ld e, l + ld hl, wEnemyMonNicks + ld a, [wWhichPokemon] + call SkipFixedLengthTextEntries + ld bc, NAME_LENGTH + call CopyData ; write new mon's nickname (from an enemy mon) + ld a, [wcf91] + ld [wd11e], a + predef IndexToPokedex + ld a, [wd11e] + dec a + ld c, a + ld b, FLAG_SET + ld hl, wPokedexOwned + push bc + call FlagAction ; add to owned pokemon + pop bc + ld hl, wPokedexSeen + call FlagAction ; add to seen pokemon + and a + ret ; return success + +_MoveMon: + ld a, [wMoveMonType] + and a ; BOX_TO_PARTY + jr z, .checkPartyMonSlots + cp DAYCARE_TO_PARTY + jr z, .checkPartyMonSlots + cp PARTY_TO_DAYCARE + ld hl, wDayCareMon + jr z, .findMonDataSrc + ; else it's PARTY_TO_BOX + ld hl, wNumInBox + ld a, [hl] + cp MONS_PER_BOX + jr nz, .partyOrBoxNotFull + jr .boxFull +.checkPartyMonSlots + ld hl, wPartyCount + ld a, [hl] + cp PARTY_LENGTH + jr nz, .partyOrBoxNotFull +.boxFull + scf + ret +.partyOrBoxNotFull + inc a + ld [hl], a ; increment number of mons in party/box + ld c, a + ld b, 0 + add hl, bc + ld a, [wMoveMonType] + cp DAYCARE_TO_PARTY + ld a, [wDayCareMon] + jr z, .copySpecies + ld a, [wcf91] +.copySpecies + ld [hli], a ; write new mon ID + ld [hl], $ff ; write new sentinel +.findMonDataDest + ld a, [wMoveMonType] + dec a + ld hl, wPartyMons + ld bc, wPartyMon2 - wPartyMon1 ; $2c + ld a, [wPartyCount] + jr nz, .addMonOffset + ; if it's PARTY_TO_BOX + ld hl, wBoxMons + ld bc, wBoxMon2 - wBoxMon1 ; $21 + ld a, [wNumInBox] +.addMonOffset + dec a + call AddNTimes +.findMonDataSrc + push hl + ld e, l + ld d, h + ld a, [wMoveMonType] + and a + ld hl, wBoxMons + ld bc, wBoxMon2 - wBoxMon1 ; $21 + jr z, .addMonOffset2 + cp DAYCARE_TO_PARTY + ld hl, wDayCareMon + jr z, .copyMonData + ld hl, wPartyMons + ld bc, wPartyMon2 - wPartyMon1 ; $2c +.addMonOffset2 + ld a, [wWhichPokemon] + call AddNTimes +.copyMonData + push hl + push de + ld bc, wBoxMon2 - wBoxMon1 + call CopyData + pop de + pop hl + ld a, [wMoveMonType] + and a ; BOX_TO_PARTY + jr z, .findOTdest + cp DAYCARE_TO_PARTY + jr z, .findOTdest + ld bc, wBoxMon2 - wBoxMon1 + add hl, bc + ld a, [hl] ; hl = Level + inc de + inc de + inc de + ld [de], a ; de = BoxLevel +.findOTdest + ld a, [wMoveMonType] + cp PARTY_TO_DAYCARE + ld de, wDayCareMonOT + jr z, .findOTsrc + dec a + ld hl, wPartyMonOT + ld a, [wPartyCount] + jr nz, .addOToffset + ld hl, wBoxMonOT + ld a, [wNumInBox] +.addOToffset + dec a + call SkipFixedLengthTextEntries + ld d, h + ld e, l +.findOTsrc + ld hl, wBoxMonOT + ld a, [wMoveMonType] + and a + jr z, .addOToffset2 + ld hl, wDayCareMonOT + cp DAYCARE_TO_PARTY + jr z, .copyOT + ld hl, wPartyMonOT +.addOToffset2 + ld a, [wWhichPokemon] + call SkipFixedLengthTextEntries +.copyOT + ld bc, NAME_LENGTH + call CopyData + ld a, [wMoveMonType] +.findNickDest + cp PARTY_TO_DAYCARE + ld de, wDayCareMonName + jr z, .findNickSrc + dec a + ld hl, wPartyMonNicks + ld a, [wPartyCount] + jr nz, .addNickOffset + ld hl, wBoxMonNicks + ld a, [wNumInBox] +.addNickOffset + dec a + call SkipFixedLengthTextEntries + ld d, h + ld e, l +.findNickSrc + ld hl, wBoxMonNicks + ld a, [wMoveMonType] + and a + jr z, .addNickOffset2 + ld hl, wDayCareMonName + cp DAYCARE_TO_PARTY + jr z, .copyNick + ld hl, wPartyMonNicks +.addNickOffset2 + ld a, [wWhichPokemon] + call SkipFixedLengthTextEntries +.copyNick + ld bc, NAME_LENGTH + call CopyData + pop hl + ld a, [wMoveMonType] + cp PARTY_TO_BOX + jr z, .done + cp PARTY_TO_DAYCARE + jr z, .done + push hl + srl a + add $2 + ld [wMonDataLocation], a + call LoadMonData + callba CalcLevelFromExperience + ld a, d + ld [wCurEnemyLVL], a + pop hl + ld bc, wBoxMon2 - wBoxMon1 + add hl, bc + ld [hli], a + ld d, h + ld e, l + ld bc, -18 + add hl, bc + ld b, $1 + call CalcStats +.done + and a + ret diff --git a/engine/battle/animations.asm b/engine/battle/animations.asm index 373136a8..4964b2cf 100755 --- a/engine/battle/animations.asm +++ b/engine/battle/animations.asm @@ -829,7 +829,7 @@ DoRockSlideSpecialEffects: cp a,1 jp z,AnimationFlashScreen ; if it's the end of the subanimation, flash the screen ret -; if the subaninmation counter is between 8 and 11, shake the screen horizontally and vertically +; if the subanimation counter is between 8 and 11, shake the screen horizontally and vertically .shakeScreen ld b,1 predef PredefShakeScreenHorizontally ; shake horizontally @@ -1516,7 +1516,7 @@ AnimationShowMonPic: jp Delay3 AnimationShowEnemyMonPic: -; Shows the emenmy mon's front sprite. Used in animations like Seismic Toss +; Shows the enemy mon's front sprite. Used in animations like Seismic Toss ; to make the mon's sprite reappear after disappears offscreen. ld hl, AnimationShowMonPic jp CallWithTurnFlipped diff --git a/engine/battle/core.asm b/engine/battle/core.asm index a0c4ba6a..a60fe4a1 100755 --- a/engine/battle/core.asm +++ b/engine/battle/core.asm @@ -406,7 +406,7 @@ MainInBattleLoop: ld a, [wEnemyBattleStatus1] bit UsingTrappingMove, a ; check if enemy is using a multi-turn attack like wrap jr z, .selectPlayerMove ; if not, jump -; enemy is using a mult-turn attack like wrap, so player is trapped and cannot execute a move +; enemy is using a multi-turn attack like wrap, so player is trapped and cannot execute a move ld a, $ff ld [wPlayerSelectedMove], a jr .selectEnemyMove @@ -704,7 +704,7 @@ HandlePoisonBurnLeechSeed_DecreaseOwnHP: ret ; adds bc to enemy HP -; bc isn't updated if HP substracted was capped to prevent overkill +; bc isn't updated if HP subtracted was capped to prevent overkill HandlePoisonBurnLeechSeed_IncreaseEnemyHP: push hl ld hl, wEnemyMonMaxHP @@ -1218,7 +1218,7 @@ ChooseNextMon: ret ; called when player is out of usable mons. -; prints approriate lose message, sets carry flag if player blacked out (special case for initial rival fight) +; prints appropriate lose message, sets carry flag if player blacked out (special case for initial rival fight) HandlePlayerBlackOut: ld a, [wLinkState] cp LINK_STATE_BATTLING @@ -3551,7 +3551,7 @@ CheckPlayerStatusConditions: ld c,[hl] ld hl,wPlayerBideAccumulatedDamage + 1 ld a,[hl] - add c ; acumulate damage taken + add c ; accumulate damage taken ld [hld],a ld a,[hl] adc b @@ -4287,7 +4287,7 @@ GetDamageVarsForPlayerAttack: sla c rl b ; reflect and light screen boosts do not cap the stat at 999, so weird things will happen during stats scaling if -; a Pokemon with 512 or more Defense has ued Reflect, or if a Pokemon with 512 or more Special has used Light Screen +; a Pokemon with 512 or more Defense has used Reflect, or if a Pokemon with 512 or more Special has used Light Screen .specialAttackCritCheck ld hl, wBattleMonSpecial ld a, [wCriticalHitOrOHKO] @@ -4400,7 +4400,7 @@ GetDamageVarsForEnemyAttack: sla c rl b ; reflect and light screen boosts do not cap the stat at 999, so weird things will happen during stats scaling if -; a Pokemon with 512 or more Defense has ued Reflect, or if a Pokemon with 512 or more Special has used Light Screen +; a Pokemon with 512 or more Defense has used Reflect, or if a Pokemon with 512 or more Special has used Light Screen .specialAttackCritCheck ld hl, wEnemyMonSpecial ld a, [wCriticalHitOrOHKO] @@ -7296,16 +7296,16 @@ PoisonEffect: ld de, wEnemyMoveEffect .poisonEffect call CheckTargetSubstitute - jr nz, .noEffect ; can't posion a substitute target + jr nz, .noEffect ; can't poison a substitute target ld a, [hli] ld b, a and a jr nz, .noEffect ; miss if target is already statused ld a, [hli] - cp POISON ; can't posion a poison-type target + cp POISON ; can't poison a poison-type target jr z, .noEffect ld a, [hld] - cp POISON ; can't posion a poison-type target + cp POISON ; can't poison a poison-type target jr z, .noEffect ld a, [de] cp POISON_SIDE_EFFECT1 @@ -7785,7 +7785,7 @@ StatModifierDownEffect: jp nz, MoveMissed ld a, [de] sub ATTACK_DOWN1_EFFECT - cp EVASION_DOWN1_EFFECT + $3 - ATTACK_DOWN1_EFFECT ; covers al -1 effects + cp EVASION_DOWN1_EFFECT + $3 - ATTACK_DOWN1_EFFECT ; covers all -1 effects jr c, .decrementStatMod sub ATTACK_DOWN2_EFFECT - ATTACK_DOWN1_EFFECT ; map -2 effects to corresponding -1 effect .decrementStatMod diff --git a/engine/battle/draw_hud_pokeball_gfx.asm b/engine/battle/draw_hud_pokeball_gfx.asm index f44d64f5..323dd167 100644 --- a/engine/battle/draw_hud_pokeball_gfx.asm +++ b/engine/battle/draw_hud_pokeball_gfx.asm @@ -186,7 +186,7 @@ SetupPlayerAndEnemyPokeballs: ld hl, wOAMBuffer + $18 jp WritePokeballOAMData -; four tiles: pokeball, black pokeball (status ailment), crossed out pokeball (faited) and pokeball slot (no mon) +; four tiles: pokeball, black pokeball (status ailment), crossed out pokeball (fainted) and pokeball slot (no mon) PokeballTileGraphics:: INCBIN "gfx/pokeball.2bpp" PokeballTileGraphicsEnd: diff --git a/engine/battle/moveEffects/haze_effect.asm b/engine/battle/moveEffects/haze_effect.asm index bd20f231..06907bcc 100644 --- a/engine/battle/moveEffects/haze_effect.asm +++ b/engine/battle/moveEffects/haze_effect.asm @@ -12,6 +12,7 @@ HazeEffect_: ld hl, wEnemyMonUnmodifiedAttack ld de, wEnemyMonAttack call ResetStats +; cure non-volatile status, but only for the target ld hl, wEnemyMonStatus ld de, wEnemySelectedMove ld a, [H_WHOSETURN] @@ -46,7 +47,6 @@ HazeEffect_: jp PrintText CureVolatileStatuses: -; only cures statuses of the Pokemon not using Haze res Confused, [hl] inc hl ; BATTSTATUS2 ld a, [hl] diff --git a/engine/battle/moveEffects/heal_effect.asm b/engine/battle/moveEffects/heal_effect.asm index b7d8283f..2e68acc0 100644 --- a/engine/battle/moveEffects/heal_effect.asm +++ b/engine/battle/moveEffects/heal_effect.asm @@ -76,7 +76,7 @@ HealEffect_: ld a, [de] sbc [hl] jr c, .playAnim -; copy max HP to current HP if an overflow ocurred +; copy max HP to current HP if an overflow occurred ld a, [hli] ld [de], a ld [wHPBarNewHP+1], a diff --git a/engine/battle/moveEffects/recoil_effect.asm b/engine/battle/moveEffects/recoil_effect.asm index 7fc90c44..0f2f087b 100644 --- a/engine/battle/moveEffects/recoil_effect.asm +++ b/engine/battle/moveEffects/recoil_effect.asm @@ -25,7 +25,7 @@ RecoilEffect_: jr nz, .updateHP inc c ; minimum recoil damage is 1 .updateHP -; substract HP from user due to the recoil damage +; subtract HP from user due to the recoil damage ld a, [hli] ld [wHPBarMaxHP+1], a ld a, [hl] diff --git a/engine/battle/moveEffects/substitute_effect.asm b/engine/battle/moveEffects/substitute_effect.asm index 03314ebf..6cca3eae 100644 --- a/engine/battle/moveEffects/substitute_effect.asm +++ b/engine/battle/moveEffects/substitute_effect.asm @@ -37,9 +37,9 @@ SubstituteEffect_: sbc 0 pop bc jr c, .notEnoughHP ; underflow means user would be left with negative health - ; bug: since it only brances on carry, it will possibly leave user with 0 HP + ; bug: since it only branches on carry, it will possibly leave user with 0 HP .userHasZeroOrMoreHP - ldi [hl], a ; save resulting HP after substraction into current HP + ldi [hl], a ; save resulting HP after subtraction into current HP ld [hl], d ld h, b ld l, c diff --git a/engine/battle/trainer_ai.asm b/engine/battle/trainer_ai.asm index b175fcaf..cabd4334 100644 --- a/engine/battle/trainer_ai.asm +++ b/engine/battle/trainer_ai.asm @@ -114,7 +114,7 @@ AIMoveChoiceModification1: ld a, [wBattleMonStatus] and a ret z ; return if no status ailment on player's mon - ld hl, wBuffer - 1 ; temp move selection array (-1 byte offest) + ld hl, wBuffer - 1 ; temp move selection array (-1 byte offset) ld de, wEnemyMonMoves ; enemy moves ld b, NUM_MOVES + 1 .nextMove @@ -154,7 +154,7 @@ StatusAilmentMoveEffects: ; slightly encourage moves with specific effects. ; in particular, stat-modifying moves and other move effects -; that fall in-bewteen +; that fall in-between AIMoveChoiceModification2: ld a, [wAILayer2Encouragement] cp $1 @@ -212,7 +212,7 @@ AIMoveChoiceModification3: cp $10 jr z, .nextMove jr c, .notEffectiveMove - dec [hl] ; sligthly encourage this move + dec [hl] ; slightly encourage this move jr .nextMove .notEffectiveMove ; discourages non-effective moves if better moves are available push hl @@ -253,7 +253,7 @@ AIMoveChoiceModification3: pop hl and a jr z, .nextMove - inc [hl] ; sligthly discourage this move + inc [hl] ; slightly discourage this move jr .nextMove AIMoveChoiceModification4: ret diff --git a/engine/bcd.asm b/engine/bcd.asm new file mode 100644 index 00000000..2d0b43df --- /dev/null +++ b/engine/bcd.asm @@ -0,0 +1,214 @@ +DivideBCDPredef:: +DivideBCDPredef2:: +DivideBCDPredef3:: +DivideBCDPredef4:: + call GetPredefRegisters + +DivideBCD:: + xor a + ld [hDivideBCDBuffer], a + ld [hDivideBCDBuffer+1], a + ld [hDivideBCDBuffer+2], a + ld d, $1 +.mulBy10Loop +; multiply the divisor by 10 until the leading digit is nonzero +; to set up the standard long division algorithm + ld a, [hDivideBCDDivisor] + and $f0 + jr nz, .next + inc d + ld a, [hDivideBCDDivisor] + swap a + and $f0 + ld b, a + ld a, [hDivideBCDDivisor+1] + swap a + ld [hDivideBCDDivisor+1], a + and $f + or b + ld [hDivideBCDDivisor], a + ld a, [hDivideBCDDivisor+1] + and $f0 + ld b, a + ld a, [hDivideBCDDivisor+2] + swap a + ld [hDivideBCDDivisor+2], a + and $f + or b + ld [hDivideBCDDivisor+1], a + ld a, [hDivideBCDDivisor+2] + and $f0 + ld [hDivideBCDDivisor+2], a + jr .mulBy10Loop +.next + push de + push de + call DivideBCD_getNextDigit + pop de + ld a, b + swap a + and $f0 + ld [hDivideBCDBuffer], a + dec d + jr z, .next2 + push de + call DivideBCD_divDivisorBy10 + call DivideBCD_getNextDigit + pop de + ld a, [hDivideBCDBuffer] + or b + ld [hDivideBCDBuffer], a + dec d + jr z, .next2 + push de + call DivideBCD_divDivisorBy10 + call DivideBCD_getNextDigit + pop de + ld a, b + swap a + and $f0 + ld [hDivideBCDBuffer+1], a + dec d + jr z, .next2 + push de + call DivideBCD_divDivisorBy10 + call DivideBCD_getNextDigit + pop de + ld a, [hDivideBCDBuffer+1] + or b + ld [hDivideBCDBuffer+1], a + dec d + jr z, .next2 + push de + call DivideBCD_divDivisorBy10 + call DivideBCD_getNextDigit + pop de + ld a, b + swap a + and $f0 + ld [hDivideBCDBuffer+2], a + dec d + jr z, .next2 + push de + call DivideBCD_divDivisorBy10 + call DivideBCD_getNextDigit + pop de + ld a, [hDivideBCDBuffer+2] + or b + ld [hDivideBCDBuffer+2], a +.next2 + ld a, [hDivideBCDBuffer] + ld [hDivideBCDQuotient], a ; the same memory location as hDivideBCDDivisor + ld a, [hDivideBCDBuffer+1] + ld [hDivideBCDQuotient+1], a + ld a, [hDivideBCDBuffer+2] + ld [hDivideBCDQuotient+2], a + pop de + ld a, $6 + sub d + and a + ret z +.divResultBy10loop + push af + call DivideBCD_divDivisorBy10 + pop af + dec a + jr nz, .divResultBy10loop + ret + +DivideBCD_divDivisorBy10: + ld a, [hDivideBCDDivisor+2] + swap a + and $f + ld b, a + ld a, [hDivideBCDDivisor+1] + swap a + ld [hDivideBCDDivisor+1], a + and $f0 + or b + ld [hDivideBCDDivisor+2], a + ld a, [hDivideBCDDivisor+1] + and $f + ld b, a + ld a, [hDivideBCDDivisor] + swap a + ld [hDivideBCDDivisor], a + and $f0 + or b + ld [hDivideBCDDivisor+1], a + ld a, [hDivideBCDDivisor] + and $f + ld [hDivideBCDDivisor], a + ret + +DivideBCD_getNextDigit: + ld bc, $3 +.loop + ld de, hMoney ; the dividend + ld hl, hDivideBCDDivisor + push bc + call StringCmp + pop bc + ret c + inc b + ld de, hMoney+2 ; since SubBCD works starting from the least significant digit + ld hl, hDivideBCDDivisor+2 + push bc + call SubBCD + pop bc + jr .loop + + +AddBCDPredef:: + call GetPredefRegisters + +AddBCD:: + and a + ld b, c +.add + ld a, [de] + adc [hl] + daa + ld [de], a + dec de + dec hl + dec c + jr nz, .add + jr nc, .done + ld a, $99 + inc de +.fill + ld [de], a + inc de + dec b + jr nz, .fill +.done + ret + + +SubBCDPredef:: + call GetPredefRegisters + +SubBCD:: + and a + ld b, c +.sub + ld a, [de] + sbc [hl] + daa + ld [de], a + dec de + dec hl + dec c + jr nz, .sub + jr nc, .done + ld a, $00 + inc de +.fill + ld [de], a + inc de + dec b + jr nz, .fill + scf +.done + ret diff --git a/engine/cable_club.asm b/engine/cable_club.asm index b551ead2..47b260f0 100755 --- a/engine/cable_club.asm +++ b/engine/cable_club.asm @@ -588,7 +588,7 @@ ReturnToCableClubRoom: dec a ld [wDestinationWarpID], a call LoadMapData - callba ClearVariablesAfterLoadingMapData + callba ClearVariablesOnEnterMap pop hl pop af ld [hl], a diff --git a/engine/flag_action.asm b/engine/flag_action.asm new file mode 100644 index 00000000..dc516887 --- /dev/null +++ b/engine/flag_action.asm @@ -0,0 +1,73 @@ +FlagActionPredef: + call GetPredefRegisters + +FlagAction: +; Perform action b on bit c +; in the bitfield at hl. +; 0: reset +; 1: set +; 2: read +; Return the result in c. + + push hl + push de + push bc + + ; bit + ld a, c + ld d, a + and 7 + ld e, a + + ; byte + ld a, d + srl a + srl a + srl a + add l + ld l, a + jr nc, .ok + inc h +.ok + + ; d = 1 << e (bitmask) + inc e + ld d, 1 +.shift + dec e + jr z, .shifted + sla d + jr .shift +.shifted + + ld a, b + and a + jr z, .reset + cp 2 + jr z, .read + +.set + ld b, [hl] + ld a, d + or b + ld [hl], a + jr .done + +.reset + ld b, [hl] + ld a, d + xor $ff + and b + ld [hl], a + jr .done + +.read + ld b, [hl] + ld a, d + and b +.done + pop bc + pop de + pop hl + ld c, a + ret diff --git a/engine/get_bag_item_quantity.asm b/engine/get_bag_item_quantity.asm new file mode 100644 index 00000000..f10df1a0 --- /dev/null +++ b/engine/get_bag_item_quantity.asm @@ -0,0 +1,18 @@ +GetQuantityOfItemInBag: +; In: b = item ID +; Out: b = how many of that item are in the bag + call GetPredefRegisters + ld hl, wNumBagItems +.loop + inc hl + ld a, [hli] + cp $ff + jr z, .notInBag + cp b + jr nz, .loop + ld a, [hl] + ld b, a + ret +.notInBag + ld b, 0 + ret diff --git a/engine/heal_party.asm b/engine/heal_party.asm new file mode 100644 index 00000000..7aaa1bd1 --- /dev/null +++ b/engine/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/hidden_object_functions17.asm b/engine/hidden_object_functions17.asm index dbbb5513..9d84b6a8 100755 --- a/engine/hidden_object_functions17.asm +++ b/engine/hidden_object_functions17.asm @@ -54,7 +54,7 @@ KabutopsFossilText: DisplayMonFrontSpriteInBox: ; Displays a pokemon's front sprite in a pop-up window. -; [wcf91] = pokemon interal id number +; [wcf91] = pokemon internal id number ld a, 1 ld [H_AUTOBGTRANSFERENABLED], a call Delay3 diff --git a/engine/init_player_data.asm b/engine/init_player_data.asm new file mode 100644 index 00000000..c576e65a --- /dev/null +++ b/engine/init_player_data.asm @@ -0,0 +1,55 @@ +InitPlayerData: +InitPlayerData2: + + call Random + ld a, [hRandomSub] + ld [wPlayerID], a + + call Random + ld a, [hRandomAdd] + ld [wPlayerID + 1], a + + ld a, $ff + ld [wUnusedD71B], a + + ld hl, wPartyCount + call InitializeEmptyList + ld hl, wNumInBox + call InitializeEmptyList + ld hl, wNumBagItems + call InitializeEmptyList + ld hl, wNumBoxItems + call InitializeEmptyList + +START_MONEY EQU $3000 + ld hl, wPlayerMoney + 1 + ld a, START_MONEY / $100 + ld [hld], a + xor a + ld [hli], a + inc hl + ld [hl], a + + ld [wMonDataLocation], a + + ld hl, wObtainedBadges + ld [hli], a + + ld [hl], a + + ld hl, wPlayerCoins + ld [hli], a + ld [hl], a + + ld hl, wGameProgressFlags + ld bc, wGameProgressFlagsEnd - wGameProgressFlags + call FillMemory ; clear all game progress flags + + jp InitializeMissableObjectsFlags + +InitializeEmptyList: + xor a ; count + ld [hli], a + dec a ; terminator + ld [hl], a + ret diff --git a/engine/items/inventory.asm b/engine/items/inventory.asm new file mode 100644 index 00000000..1294ed8d --- /dev/null +++ b/engine/items/inventory.asm @@ -0,0 +1,150 @@ +; function to add an item (in varying quantities) to the player's bag or PC box +; INPUT: +; hl = address of inventory (either wNumBagItems or wNumBoxItems) +; [wcf91] = item ID +; [wItemQuantity] = item quantity +; sets carry flag if successful, unsets carry flag if unsuccessful +AddItemToInventory_: + ld a,[wItemQuantity] ; a = item quantity + push af + push bc + push de + push hl + push hl + ld d,PC_ITEM_CAPACITY ; how many items the PC can hold + ld a,wNumBagItems & $FF + cp l + jr nz,.checkIfInventoryFull + ld a,wNumBagItems >> 8 + cp h + jr nz,.checkIfInventoryFull +; if the destination is the bag + ld d,BAG_ITEM_CAPACITY ; how many items the bag can hold +.checkIfInventoryFull + ld a,[hl] + sub d + ld d,a + ld a,[hli] + and a + jr z,.addNewItem +.loop + ld a,[hli] + ld b,a ; b = ID of current item in table + ld a,[wcf91] ; a = ID of item being added + cp b ; does the current item in the table match the item being added? + jp z,.increaseItemQuantity ; if so, increase the item's quantity + inc hl + ld a,[hl] + cp a,$ff ; is it the end of the table? + jr nz,.loop +.addNewItem ; add an item not yet in the inventory + pop hl + ld a,d + and a ; is there room for a new item slot? + jr z,.done +; if there is room + inc [hl] ; increment the number of items in the inventory + ld a,[hl] ; the number of items will be the index of the new item + add a + dec a + ld c,a + ld b,0 + add hl,bc ; hl = address to store the item + ld a,[wcf91] + ld [hli],a ; store item ID + ld a,[wItemQuantity] + ld [hli],a ; store item quantity + ld [hl],$ff ; store terminator + jp .success +.increaseItemQuantity ; increase the quantity of an item already in the inventory + ld a,[wItemQuantity] + ld b,a ; b = quantity to add + ld a,[hl] ; a = existing item quantity + add b ; a = new item quantity + cp a,100 + jp c,.storeNewQuantity ; if the new quantity is less than 100, store it +; if the new quantity is greater than or equal to 100, +; try to max out the current slot and add the rest in a new slot + sub a,99 + ld [wItemQuantity],a ; a = amount left over (to put in the new slot) + ld a,d + and a ; is there room for a new item slot? + jr z,.increaseItemQuantityFailed +; if so, store 99 in the current slot and store the rest in a new slot + ld a,99 + ld [hli],a + jp .loop +.increaseItemQuantityFailed + pop hl + and a + jr .done +.storeNewQuantity + ld [hl],a + pop hl +.success + scf +.done + pop hl + pop de + pop bc + pop bc + ld a,b + ld [wItemQuantity],a ; restore the initial value from when the function was called + ret + +; function to remove an item (in varying quantities) from the player's bag or PC box +; INPUT: +; hl = address of inventory (either wNumBagItems or wNumBoxItems) +; [wWhichPokemon] = index (within the inventory) of the item to remove +; [wItemQuantity] = quantity to remove +RemoveItemFromInventory_: + push hl + inc hl + ld a,[wWhichPokemon] ; index (within the inventory) of the item being removed + sla a + add l + ld l,a + jr nc,.noCarry + inc h +.noCarry + inc hl + ld a,[wItemQuantity] ; quantity being removed + ld e,a + ld a,[hl] ; a = current quantity + sub e + ld [hld],a ; store new quantity + ld [wMaxItemQuantity],a + and a + jr nz,.skipMovingUpSlots +; if the remaining quantity is 0, +; remove the emptied item slot and move up all the following item slots +.moveSlotsUp + ld e,l + ld d,h + inc de + inc de ; de = address of the slot following the emptied one +.loop ; loop to move up the following slots + ld a,[de] + inc de + ld [hli],a + cp a,$ff + jr nz,.loop +; update menu info + xor a + ld [wListScrollOffset],a + ld [wCurrentMenuItem],a + ld [wBagSavedMenuItem],a + ld [wSavedListScrollOffset],a + pop hl + ld a,[hl] ; a = number of items in inventory + dec a ; decrement the number of items + ld [hl],a ; store new number of items + ld [wListCount],a + cp a,2 + jr c,.done + ld [wMaxMenuItem],a + jr .done +.skipMovingUpSlots + pop hl +.done + ret diff --git a/engine/items/items.asm b/engine/items/items.asm index 159f3a45..5c919e50 100755 --- a/engine/items/items.asm +++ b/engine/items/items.asm @@ -863,7 +863,7 @@ ItemUseMedicine: jp nc,.useVitamin ; if it's a vitamin or Rare Candy cp a,FULL_RESTORE jr nc,.healHP ; if it's a Full Restore or one of the potions -; fall through if it's one of the status-specifc healing items +; fall through if it's one of the status-specific healing items .cureStatusAilment ld bc,wPartyMon1Status - wPartyMon1 add hl,bc ; hl now points to status @@ -1846,11 +1846,11 @@ PlayedFluteHadEffectText: ; play out-of-battle pokeflute music ld a,$ff call PlaySound ; turn off music - ld a, SFX_POKEFLUE + ld a, SFX_POKEFLUTE ld c, BANK(SFX_Pokeflute) call PlayMusic .musicWaitLoop ; wait for music to finish playing - ld a,[wChannelSoundIDs + Ch2] + ld a,[wChannelSoundIDs + CH2] cp a, SFX_POKEFLUE jr z,.musicWaitLoop call PlayDefaultMusic ; start playing normal music again diff --git a/engine/learn_move.asm b/engine/learn_move.asm index ba73d4c0..53c7f87e 100755 --- a/engine/learn_move.asm +++ b/engine/learn_move.asm @@ -185,7 +185,7 @@ TryingToLearn: LearnedMove1Text: TX_FAR _LearnedMove1Text - TX_SFX_ITEM_1 ; plays SFX_GET_ITEM_1 in the pary menu (rare candy) and plays SFX_LEVEL_UP in battle + TX_SFX_ITEM_1 ; plays SFX_GET_ITEM_1 in the party menu (rare candy) and plays SFX_LEVEL_UP in battle TX_BLINK db "@" diff --git a/engine/menu/draw_badges.asm b/engine/menu/draw_badges.asm new file mode 100644 index 00000000..9e6262a0 --- /dev/null +++ b/engine/menu/draw_badges.asm @@ -0,0 +1,120 @@ +DrawBadges: +; Draw 4x2 gym leader faces, with the faces replaced by +; badges if they are owned. Used in the player status screen. + +; In Japanese versions, names are displayed above faces. +; Instead of removing relevant code, the name graphics were erased. + +; Tile ids for face/badge graphics. + ld de, wBadgeOrFaceTiles + ld hl, .FaceBadgeTiles + ld bc, 8 + call CopyData + +; Booleans for each badge. + ld hl, wTempObtainedBadgesBooleans + ld bc, 8 + xor a + call FillMemory + +; Alter these based on owned badges. + ld de, wTempObtainedBadgesBooleans + ld hl, wBadgeOrFaceTiles + ld a, [wObtainedBadges] + ld b, a + ld c, 8 +.CheckBadge + srl b + jr nc, .NextBadge + ld a, [hl] + add 4 ; Badge graphics are after each face + ld [hl], a + ld a, 1 + ld [de], a +.NextBadge + inc hl + inc de + dec c + jr nz, .CheckBadge + +; Draw two rows of badges. + ld hl, wBadgeNumberTile + ld a, $d8 ; [1] + ld [hli], a + ld [hl], $60 ; First name + + coord hl, 2, 11 + ld de, wTempObtainedBadgesBooleans + call .DrawBadgeRow + + coord hl, 2, 14 + ld de, wTempObtainedBadgesBooleans + 4 +; call .DrawBadgeRow +; ret + +.DrawBadgeRow +; Draw 4 badges. + + ld c, 4 +.DrawBadge + push de + push hl + +; Badge no. + ld a, [wBadgeNumberTile] + ld [hli], a + inc a + ld [wBadgeNumberTile], a + +; Names aren't printed if the badge is owned. + ld a, [de] + and a + ld a, [wBadgeNameTile] + jr nz, .SkipName + call .PlaceTiles + jr .PlaceBadge + +.SkipName + inc a + inc a + inc hl + +.PlaceBadge + ld [wBadgeNameTile], a + ld de, SCREEN_WIDTH - 1 + add hl, de + ld a, [wBadgeOrFaceTiles] + call .PlaceTiles + add hl, de + call .PlaceTiles + +; Shift badge array back one byte. + push bc + ld hl, wBadgeOrFaceTiles + 1 + ld de, wBadgeOrFaceTiles + ld bc, 8 + call CopyData + pop bc + + pop hl + ld de, 4 + add hl, de + + pop de + inc de + dec c + jr nz, .DrawBadge + ret + +.PlaceTiles + ld [hli], a + inc a + ld [hl], a + inc a + ret + +.FaceBadgeTiles + db $20, $28, $30, $38, $40, $48, $50, $58 + +GymLeaderFaceAndBadgeTileGraphics: + INCBIN "gfx/badges.2bpp" diff --git a/engine/menu/draw_start_menu.asm b/engine/menu/draw_start_menu.asm index 86e68733..914284c4 100644 --- a/engine/menu/draw_start_menu.asm +++ b/engine/menu/draw_start_menu.asm @@ -27,7 +27,7 @@ DrawStartMenu: set 6,[hl] ; no pauses between printing each letter coord hl, 12, 2 CheckEvent EVENT_GOT_POKEDEX -; case for not having pokdex +; case for not having pokedex ld a,$06 jr z,.storeMenuItemCount ; case for having pokedex diff --git a/engine/menu/naming_screen.asm b/engine/menu/naming_screen.asm index 7835be97..58bfc0d7 100755 --- a/engine/menu/naming_screen.asm +++ b/engine/menu/naming_screen.asm @@ -412,7 +412,7 @@ PrintNicknameAndUnderscores: call EraseMenuCursor ld a, $11 ; "ED" x coord ld [wTopMenuItemX], a - ld a, $5 ; "ED" y corrd + ld a, $5 ; "ED" y coord ld [wCurrentMenuItem], a ld a, [wNamingScreenType] cp NAME_MON_SCREEN diff --git a/engine/menu/pokedex.asm b/engine/menu/pokedex.asm index e3f9f1dd..2b66cda1 100755 --- a/engine/menu/pokedex.asm +++ b/engine/menu/pokedex.asm @@ -648,7 +648,7 @@ PokedexToIndex: ret IndexToPokedex: - ; converts the indexédex number at wd11e to a Pokédex number + ; converts the index number at wd11e to a Pokédex number push bc push hl ld a,[wd11e] diff --git a/engine/overworld/clear_variables.asm b/engine/overworld/clear_variables.asm new file mode 100644 index 00000000..9a59cc7c --- /dev/null +++ b/engine/overworld/clear_variables.asm @@ -0,0 +1,20 @@ +ClearVariablesOnEnterMap: + ld a, SCREEN_HEIGHT_PIXELS + ld [hWY], a + ld [rWY], a + xor a + ld [H_AUTOBGTRANSFERENABLED], a + ld [wStepCounter], a + ld [wLoneAttackNo], a + ld [hJoyPressed], a + ld [hJoyReleased], a + ld [hJoyHeld], a + ld [wActionResultOrTookBattleTurn], a + ld [wUnusedD5A3], a + ld hl, wCardKeyDoorY + ld [hli], a + ld [hl], a + ld hl, wWhichTrade + ld bc, wStandingOnWarpPadOrHole - wWhichTrade + call FillMemory + ret diff --git a/engine/overworld/daycare_exp.asm b/engine/overworld/daycare_exp.asm new file mode 100644 index 00000000..dbe4023a --- /dev/null +++ b/engine/overworld/daycare_exp.asm @@ -0,0 +1,18 @@ +IncrementDayCareMonExp: + ld a, [wDayCareInUse] + and a + ret z + ld hl, wDayCareMonExp + 2 + inc [hl] + ret nz + dec hl + inc [hl] + ret nz + dec hl + inc [hl] + ld a, [hl] + cp $50 + ret c + ld a, $50 + ld [hl], a + ret diff --git a/engine/overworld/field_move_messages.asm b/engine/overworld/field_move_messages.asm new file mode 100644 index 00000000..69914bfc --- /dev/null +++ b/engine/overworld/field_move_messages.asm @@ -0,0 +1,57 @@ +PrintStrengthTxt: + ld hl, wd728 + set 0, [hl] + ld hl, UsedStrengthText + call PrintText + ld hl, CanMoveBouldersText + jp PrintText + +UsedStrengthText: + TX_FAR _UsedStrengthText + TX_ASM + ld a, [wcf91] + call PlayCry + call Delay3 + jp TextScriptEnd + +CanMoveBouldersText: + TX_FAR _CanMoveBouldersText + db "@" + +IsSurfingAllowed: +; Returns whether surfing is allowed in bit 1 of wd728. +; Surfing isn't allowed on the Cycling Road or in the lowest level of the +; Seafoam Islands before the current has been slowed with boulders. + ld hl, wd728 + set 1, [hl] + ld a, [wd732] + bit 5, a + jr nz, .forcedToRideBike + ld a, [wCurMap] + cp SEAFOAM_ISLANDS_5 + ret nz + CheckBothEventsSet EVENT_SEAFOAM4_BOULDER1_DOWN_HOLE, EVENT_SEAFOAM4_BOULDER2_DOWN_HOLE + ret z + ld hl, CoordsData_cdf7 + call ArePlayerCoordsInArray + ret nc + ld hl, wd728 + res 1, [hl] + ld hl, CurrentTooFastText + jp PrintText +.forcedToRideBike + ld hl, wd728 + res 1, [hl] + ld hl, CyclingIsFunText + jp PrintText + +CoordsData_cdf7: + db $0B,$07,$FF + +CurrentTooFastText: + TX_FAR _CurrentTooFastText + db "@" + +CyclingIsFunText: + TX_FAR _CyclingIsFunText + db "@" diff --git a/engine/overworld/map_sprites.asm b/engine/overworld/map_sprites.asm index 05588321..2a221c7e 100755 --- a/engine/overworld/map_sprites.asm +++ b/engine/overworld/map_sprites.asm @@ -7,7 +7,7 @@ ; $C1X* and $C2X* are used to denote wSpriteStateData1-wSpriteStateData1 + $ff and wSpriteStateData2 + $00-wSpriteStateData2 + $ff sprite slot ; fields, respectively, within loops. The X is the loop index. ; If there is an inner loop, Y is the inner loop index, i.e. $C1Y* and $C2Y* -; denote fields of the sprite slots interated over in the inner loop. +; denote fields of the sprite slots iterated over in the inner loop. InitMapSprites: call InitOutsideMapSprites ret c ; return if the map is an outside map (already handled by above call) @@ -192,7 +192,7 @@ LoadMapSpriteTilePatterns: pop de call FarCopyData2 ; load tile pattern data for sprite when walking jr .skipSecondLoad -; When reloading the upper half of tile patterns after diplaying text, the LCD +; When reloading the upper half of tile patterns after displaying text, the LCD ; will be on, so CopyVideoData (which writes to VRAM only during V-blank) must ; be used instead of FarCopyData2. .loadWhileLCDOn diff --git a/engine/overworld/missable_objects.asm b/engine/overworld/missable_objects.asm new file mode 100644 index 00000000..8587c0f7 --- /dev/null +++ b/engine/overworld/missable_objects.asm @@ -0,0 +1,215 @@ +MarkTownVisitedAndLoadMissableObjects: + ld a, [wCurMap] + cp ROUTE_1 + jr nc, .notInTown + ld c, a + ld b, FLAG_SET + ld hl, wTownVisitedFlag ; mark town as visited (for flying) + predef FlagActionPredef +.notInTown + ld hl, MapHSPointers + ld a, [wCurMap] + ld b, $0 + ld c, a + add hl, bc + add hl, bc + ld a, [hli] ; load missable objects pointer in hl + ld h, [hl] + ; fall through + +LoadMissableObjects: + ld l, a + push hl + ld de, MapHS00 ; calculate difference between out pointer and the base pointer + ld a, l + sub e + jr nc, .asm_f13c + dec h +.asm_f13c + ld l, a + ld a, h + sub d + ld h, a + ld a, h + ld [H_DIVIDEND], a + ld a, l + ld [H_DIVIDEND+1], a + xor a + ld [H_DIVIDEND+2], a + ld [H_DIVIDEND+3], a + ld a, $3 + ld [H_DIVISOR], a + ld b, $2 + call Divide ; divide difference by 3, resulting in the global offset (number of missable items before ours) + ld a, [wCurMap] + ld b, a + ld a, [H_DIVIDEND+3] + ld c, a ; store global offset in c + ld de, wMissableObjectList + pop hl +.writeMissableObjectsListLoop + ld a, [hli] + cp $ff + jr z, .done ; end of list + cp b + jr nz, .done ; not for current map anymore + ld a, [hli] + inc hl + ld [de], a ; write (map-local) sprite ID + inc de + ld a, c + inc c + ld [de], a ; write (global) missable object index + inc de + jr .writeMissableObjectsListLoop +.done + ld a, $ff + ld [de], a ; write sentinel + ret + +InitializeMissableObjectsFlags: + ld hl, wMissableObjectFlags + ld bc, wMissableObjectFlagsEnd - wMissableObjectFlags + xor a + call FillMemory ; clear missable objects flags + ld hl, MapHS00 + xor a + ld [wMissableObjectCounter], a +.missableObjectsLoop + ld a, [hli] + cp $ff ; end of list + ret z + push hl + inc hl + ld a, [hl] + cp Hide + jr nz, .skip + ld hl, wMissableObjectFlags + ld a, [wMissableObjectCounter] + ld c, a + ld b, FLAG_SET + call MissableObjectFlagAction ; set flag if Item is hidden +.skip + ld hl, wMissableObjectCounter + inc [hl] + pop hl + inc hl + inc hl + jr .missableObjectsLoop + +; tests if current sprite is a missable object that is hidden/has been removed +IsObjectHidden: + ld a, [H_CURRENTSPRITEOFFSET] + swap a + ld b, a + ld hl, wMissableObjectList +.loop + ld a, [hli] + cp $ff + jr z, .notHidden ; not missable -> not hidden + cp b + ld a, [hli] + jr nz, .loop + ld c, a + ld b, FLAG_TEST + ld hl, wMissableObjectFlags + call MissableObjectFlagAction + ld a, c + and a + jr nz, .hidden +.notHidden + xor a +.hidden + ld [$ffe5], a + ret + +; adds missable object (items, leg. pokemon, etc.) to the map +; [wMissableObjectIndex]: index of the missable object to be added (global index) +ShowObject: +ShowObject2: + ld hl, wMissableObjectFlags + ld a, [wMissableObjectIndex] + ld c, a + ld b, FLAG_RESET + call MissableObjectFlagAction ; reset "removed" flag + jp UpdateSprites + +; removes missable object (items, leg. pokemon, etc.) from the map +; [wMissableObjectIndex]: index of the missable object to be removed (global index) +HideObject: + ld hl, wMissableObjectFlags + ld a, [wMissableObjectIndex] + ld c, a + ld b, FLAG_SET + call MissableObjectFlagAction ; set "removed" flag + jp UpdateSprites + +MissableObjectFlagAction: +; identical to FlagAction + + push hl + push de + push bc + + ; bit + ld a, c + ld d, a + and 7 + ld e, a + + ; byte + ld a, d + srl a + srl a + srl a + add l + ld l, a + jr nc, .ok + inc h +.ok + + ; d = 1 << e (bitmask) + inc e + ld d, 1 +.shift + dec e + jr z, .shifted + sla d + jr .shift +.shifted + + ld a, b + and a + jr z, .reset + cp 2 + jr z, .read + +.set + ld a, [hl] + ld b, a + ld a, d + or b + ld [hl], a + jr .done + +.reset + ld a, [hl] + ld b, a + ld a, d + xor $ff + and b + ld [hl], a + jr .done + +.read + ld a, [hl] + ld b, a + ld a, d + and b + +.done + pop bc + pop de + pop hl + ld c, a + ret diff --git a/engine/overworld/movement.asm b/engine/overworld/movement.asm index e2003d12..3b351e58 100644 --- a/engine/overworld/movement.asm +++ b/engine/overworld/movement.asm @@ -331,9 +331,9 @@ UpdateSpriteInWalkingAnimation: ld a, [H_CURRENTSPRITEOFFSET] ld l, a inc h - ld a, [hl] ; c2x0 (walk animantion counter) + ld a, [hl] ; c2x0 (walk animation counter) dec a - ld [hl], a ; update walk animantion counter + ld [hl], a ; update walk animation counter ret nz ld a, $6 ; walking finished, update state add l @@ -447,7 +447,7 @@ InitializeSpriteStatus: call InitializeSpriteScreenPosition ; could have done fallthrough here ret -; calculates the spprite's scrren position form its map position and the player position +; calculates the sprite's screen position form its map position and the player position InitializeSpriteScreenPosition: ld h, wSpriteStateData2 / $100 ld a, [H_CURRENTSPRITEOFFSET] @@ -698,7 +698,7 @@ CanWalkOntoTile: scf ; set carry (marking failure to walk) ret -; calculates the tile pointer pointing to the tile the current sprite stancs on +; calculates the tile pointer pointing to the tile the current sprite stands on ; this is always the lower left tile of the 2x2 tile blocks all sprites are snapped to ; hl: output pointer GetTileSpriteStandsOn: diff --git a/engine/overworld/player_state.asm b/engine/overworld/player_state.asm new file mode 100644 index 00000000..79f755b9 --- /dev/null +++ b/engine/overworld/player_state.asm @@ -0,0 +1,463 @@ +; only used for setting bit 2 of wd736 upon entering a new map +IsPlayerStandingOnWarp: + ld a, [wNumberOfWarps] + and a + ret z + ld c, a + ld hl, wWarpEntries +.loop + ld a, [wYCoord] + cp [hl] + jr nz, .nextWarp1 + inc hl + ld a, [wXCoord] + cp [hl] + jr nz, .nextWarp2 + inc hl + ld a, [hli] ; target warp + ld [wDestinationWarpID], a + ld a, [hl] ; target map + ld [hWarpDestinationMap], a + ld hl, wd736 + set 2, [hl] ; standing on warp flag + ret +.nextWarp1 + inc hl +.nextWarp2 + inc hl + inc hl + inc hl + dec c + jr nz, .loop + ret + +CheckForceBikeOrSurf: + ld hl, wd732 + bit 5, [hl] + ret nz + ld hl, ForcedBikeOrSurfMaps + ld a, [wYCoord] + ld b, a + ld a, [wXCoord] + ld c, a + ld a, [wCurMap] + ld d, a +.loop + ld a, [hli] + cp $ff + ret z ;if we reach FF then it's not part of the list + cp d ;compare to current map + jr nz, .incorrectMap + ld a, [hli] + cp b ;compare y-coord + jr nz, .incorrectY + ld a, [hli] + cp c ;compare x-coord + jr nz, .loop ; incorrect x-coord, check next item + ld a, [wCurMap] + cp SEAFOAM_ISLANDS_4 + ld a, $2 + ld [wSeafoamIslands4CurScript], a + jr z, .forceSurfing + ld a, [wCurMap] + cp SEAFOAM_ISLANDS_5 + ld a, $2 + ld [wSeafoamIslands5CurScript], a + jr z, .forceSurfing + ;force bike riding + ld hl, wd732 + set 5, [hl] + ld a, $1 + ld [wWalkBikeSurfState], a + ld [wWalkBikeSurfStateCopy], a + jp ForceBikeOrSurf +.incorrectMap + inc hl +.incorrectY + inc hl + jr .loop +.forceSurfing + ld a, $2 + ld [wWalkBikeSurfState], a + ld [wWalkBikeSurfStateCopy], a + jp ForceBikeOrSurf + +INCLUDE "data/force_bike_surf.asm" + +IsPlayerFacingEdgeOfMap: + push hl + push de + push bc + ld a, [wSpriteStateData1 + 9] ; player sprite's facing direction + srl a + ld c, a + ld b, $0 + ld hl, .functionPointerTable + add hl, bc + ld a, [hli] + ld h, [hl] + ld l, a + ld a, [wYCoord] + ld b, a + ld a, [wXCoord] + ld c, a + ld de, .asm_c41e + push de + jp [hl] +.asm_c41e + pop bc + pop de + pop hl + ret + +.functionPointerTable + dw .facingDown + dw .facingUp + dw .facingLeft + dw .facingRight + +.facingDown + ld a, [wCurMapHeight] + add a + dec a + cp b + jr z, .setCarry + jr .resetCarry + +.facingUp + ld a, b + and a + jr z, .setCarry + jr .resetCarry + +.facingLeft + ld a, c + and a + jr z, .setCarry + jr .resetCarry + +.facingRight + ld a, [wCurMapWidth] + add a + dec a + cp c + jr z, .setCarry + jr .resetCarry +.resetCarry + and a + ret +.setCarry + scf + ret + +IsWarpTileInFrontOfPlayer: + push hl + push de + push bc + call _GetTileAndCoordsInFrontOfPlayer + ld a, [wCurMap] + cp SS_ANNE_5 + jr z, .ssAnne5 + ld a, [wSpriteStateData1 + 9] ; player sprite's facing direction + srl a + ld c, a + ld b, 0 + ld hl, .warpTileListPointers + add hl, bc + ld a, [hli] + ld h, [hl] + ld l, a + ld a, [wTileInFrontOfPlayer] + ld de, $1 + call IsInArray +.done + pop bc + pop de + pop hl + ret + +.warpTileListPointers: + dw .facingDownWarpTiles + dw .facingUpWarpTiles + dw .facingLeftWarpTiles + dw .facingRightWarpTiles + +.facingDownWarpTiles + db $01,$12,$17,$3D,$04,$18,$33,$FF + +.facingUpWarpTiles + db $01,$5C,$FF + +.facingLeftWarpTiles + db $1A,$4B,$FF + +.facingRightWarpTiles + db $0F,$4E,$FF + +.ssAnne5 + ld a, [wTileInFrontOfPlayer] + cp $15 + jr nz, .notSSAnne5Warp + scf + jr .done +.notSSAnne5Warp + and a + jr .done + +IsPlayerStandingOnDoorTileOrWarpTile: + push hl + push de + push bc + callba IsPlayerStandingOnDoorTile + jr c, .done + ld a, [wCurMapTileset] + add a + ld c, a + ld b, $0 + ld hl, WarpTileIDPointers + add hl, bc + ld a, [hli] + ld h, [hl] + ld l, a + ld de, $1 + aCoord 8, 9 + call IsInArray + jr nc, .done + ld hl, wd736 + res 2, [hl] +.done + pop bc + pop de + pop hl + ret + +INCLUDE "data/warp_tile_ids.asm" + +PrintSafariZoneSteps: + ld a, [wCurMap] + cp SAFARI_ZONE_EAST + ret c + cp UNKNOWN_DUNGEON_2 + ret nc + coord hl, 0, 0 + ld b, 3 + ld c, 7 + call TextBoxBorder + coord hl, 1, 1 + ld de, wSafariSteps + lb bc, 2, 3 + call PrintNumber + coord hl, 4, 1 + ld de, SafariSteps + call PlaceString + coord hl, 1, 3 + ld de, SafariBallText + call PlaceString + ld a, [wNumSafariBalls] + cp 10 + jr nc, .asm_c56d + coord hl, 5, 3 + ld a, " " + ld [hl], a +.asm_c56d + coord hl, 6, 3 + ld de, wNumSafariBalls + lb bc, 1, 2 + jp PrintNumber + +SafariSteps: + db "/500@" + +SafariBallText: + db "BALL×× @" + +GetTileAndCoordsInFrontOfPlayer: + call GetPredefRegisters + +_GetTileAndCoordsInFrontOfPlayer: + ld a, [wYCoord] + ld d, a + ld a, [wXCoord] + ld e, a + ld a, [wSpriteStateData1 + 9] ; player's sprite facing direction + and a ; cp SPRITE_FACING_DOWN + jr nz, .notFacingDown +; facing down + aCoord 8, 11 + inc d + jr .storeTile +.notFacingDown + cp SPRITE_FACING_UP + jr nz, .notFacingUp +; facing up + aCoord 8, 7 + dec d + jr .storeTile +.notFacingUp + cp SPRITE_FACING_LEFT + jr nz, .notFacingLeft +; facing left + aCoord 6, 9 + dec e + jr .storeTile +.notFacingLeft + cp SPRITE_FACING_RIGHT + jr nz, .storeTile +; facing right + aCoord 10, 9 + inc e +.storeTile + ld c, a + ld [wTileInFrontOfPlayer], a + ret + +GetTileTwoStepsInFrontOfPlayer: + xor a + ld [$ffdb], a + ld hl, wYCoord + ld a, [hli] + ld d, a + ld e, [hl] + ld a, [wSpriteStateData1 + 9] ; player's sprite facing direction + and a ; cp SPRITE_FACING_DOWN + jr nz, .notFacingDown +; facing down + ld hl, $ffdb + set 0, [hl] + aCoord 8, 13 + inc d + jr .storeTile +.notFacingDown + cp SPRITE_FACING_UP + jr nz, .notFacingUp +; facing up + ld hl, $ffdb + set 1, [hl] + aCoord 8, 5 + dec d + jr .storeTile +.notFacingUp + cp SPRITE_FACING_LEFT + jr nz, .notFacingLeft +; facing left + ld hl, $ffdb + set 2, [hl] + aCoord 4, 9 + dec e + jr .storeTile +.notFacingLeft + cp SPRITE_FACING_RIGHT + jr nz, .storeTile +; facing right + ld hl, $ffdb + set 3, [hl] + aCoord 12, 9 + inc e +.storeTile + ld c, a + ld [wTileInFrontOfBoulderAndBoulderCollisionResult], a + ld [wTileInFrontOfPlayer], a + ret + +CheckForCollisionWhenPushingBoulder: + call GetTileTwoStepsInFrontOfPlayer + ld hl, wTilesetCollisionPtr + ld a, [hli] + ld h, [hl] + ld l, a +.loop + ld a, [hli] + cp $ff + jr z, .done ; if the tile two steps ahead is not passable + cp c + jr nz, .loop + ld hl, TilePairCollisionsLand + call CheckForTilePairCollisions2 + ld a, $ff + jr c, .done ; if there is an elevation difference between the current tile and the one two steps ahead + ld a, [wTileInFrontOfBoulderAndBoulderCollisionResult] + cp $15 ; stairs tile + ld a, $ff + jr z, .done ; if the tile two steps ahead is stairs + call CheckForBoulderCollisionWithSprites +.done + ld [wTileInFrontOfBoulderAndBoulderCollisionResult], a + ret + +; sets a to $ff if there is a collision and $00 if there is no collision +CheckForBoulderCollisionWithSprites: + ld a, [wBoulderSpriteIndex] + dec a + swap a + ld d, 0 + ld e, a + ld hl, wSpriteStateData2 + $14 + add hl, de + ld a, [hli] ; map Y position + ld [$ffdc], a + ld a, [hl] ; map X position + ld [$ffdd], a + ld a, [wNumSprites] + ld c, a + ld de, $f + ld hl, wSpriteStateData2 + $14 + ld a, [$ffdb] + and $3 ; facing up or down? + jr z, .pushingHorizontallyLoop +.pushingVerticallyLoop + inc hl + ld a, [$ffdd] + cp [hl] + jr nz, .nextSprite1 ; if X coordinates don't match + dec hl + ld a, [hli] + ld b, a + ld a, [$ffdb] + rrca + jr c, .pushingDown +; pushing up + ld a, [$ffdc] + dec a + jr .compareYCoords +.pushingDown + ld a, [$ffdc] + inc a +.compareYCoords + cp b + jr z, .failure +.nextSprite1 + dec c + jr z, .success + add hl, de + jr .pushingVerticallyLoop +.pushingHorizontallyLoop + ld a, [hli] + ld b, a + ld a, [$ffdc] + cp b + jr nz, .nextSprite2 + ld b, [hl] + ld a, [$ffdb] + bit 2, a + jr nz, .pushingLeft +; pushing right + ld a, [$ffdd] + inc a + jr .compareXCoords +.pushingLeft + ld a, [$ffdd] + dec a +.compareXCoords + cp b + jr z, .failure +.nextSprite2 + dec c + jr z, .success + add hl, de + jr .pushingHorizontallyLoop +.failure + ld a, $ff + ret +.success + xor a + ret diff --git a/engine/overworld/poison.asm b/engine/overworld/poison.asm new file mode 100644 index 00000000..5d8eb9fd --- /dev/null +++ b/engine/overworld/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/overworld/push_boulder.asm b/engine/overworld/push_boulder.asm new file mode 100644 index 00000000..c91605a8 --- /dev/null +++ b/engine/overworld/push_boulder.asm @@ -0,0 +1,105 @@ +TryPushingBoulder: + ld a, [wd728] + bit 0, a ; using Strength? + ret z + ld a, [wFlags_0xcd60] + bit 1, a ; has boulder dust animation from previous push played yet? + ret nz + xor a + ld [hSpriteIndexOrTextID], a + call IsSpriteInFrontOfPlayer + ld a, [hSpriteIndexOrTextID] + ld [wBoulderSpriteIndex], a + and a + jp z, ResetBoulderPushFlags + ld hl, wSpriteStateData1 + 1 + ld d, $0 + ld a, [hSpriteIndexOrTextID] + swap a + ld e, a + add hl, de + res 7, [hl] + call GetSpriteMovementByte2Pointer + ld a, [hl] + cp BOULDER_MOVEMENT_BYTE_2 + jp nz, ResetBoulderPushFlags + ld hl, wFlags_0xcd60 + bit 6, [hl] + set 6, [hl] ; indicate that the player has tried pushing + ret z ; the player must try pushing twice before the boulder will move + ld a, [hJoyHeld] + and D_RIGHT | D_LEFT | D_UP | D_DOWN + ret z + predef CheckForCollisionWhenPushingBoulder + ld a, [wTileInFrontOfBoulderAndBoulderCollisionResult] + and a ; was there a collision? + jp nz, ResetBoulderPushFlags + ld a, [hJoyHeld] + ld b, a + ld a, [wSpriteStateData1 + 9] ; player's sprite facing direction + cp SPRITE_FACING_UP + jr z, .pushBoulderUp + cp SPRITE_FACING_LEFT + jr z, .pushBoulderLeft + cp SPRITE_FACING_RIGHT + jr z, .pushBoulderRight +.pushBoulderDown + bit 7, b + ret z + ld de, PushBoulderDownMovementData + jr .done +.pushBoulderUp + bit 6, b + ret z + ld de, PushBoulderUpMovementData + jr .done +.pushBoulderLeft + bit 5, b + ret z + ld de, PushBoulderLeftMovementData + jr .done +.pushBoulderRight + bit 4, b + ret z + ld de, PushBoulderRightMovementData +.done + call MoveSprite + ld a, SFX_PUSH_BOULDER + call PlaySound + ld hl, wFlags_0xcd60 + set 1, [hl] + ret + +PushBoulderUpMovementData: + db NPC_MOVEMENT_UP,$FF + +PushBoulderDownMovementData: + db NPC_MOVEMENT_DOWN,$FF + +PushBoulderLeftMovementData: + db NPC_MOVEMENT_LEFT,$FF + +PushBoulderRightMovementData: + db NPC_MOVEMENT_RIGHT,$FF + +DoBoulderDustAnimation: + ld a, [wd730] + bit 0, a + ret nz + callab AnimateBoulderDust + call DiscardButtonPresses + ld [wJoyIgnore], a + call ResetBoulderPushFlags + set 7, [hl] + ld a, [wBoulderSpriteIndex] + ld [H_SPRITEINDEX], a + call GetSpriteMovementByte2Pointer + ld [hl], $10 + ld a, SFX_CUT + jp PlaySound + +ResetBoulderPushFlags: + ld hl, wFlags_0xcd60 + res 1, [hl] + res 6, [hl] + ret diff --git a/engine/overworld/tileset_header.asm b/engine/overworld/tileset_header.asm new file mode 100644 index 00000000..6e33974f --- /dev/null +++ b/engine/overworld/tileset_header.asm @@ -0,0 +1,60 @@ +LoadTilesetHeader: + call GetPredefRegisters + push hl + ld d, 0 + ld a, [wCurMapTileset] + add a + add a + ld b, a + add a + add b ; a = tileset * 12 + jr nc, .noCarry + inc d +.noCarry + ld e, a + ld hl, Tilesets + add hl, de + ld de, wTilesetBank + ld c, $b +.copyTilesetHeaderLoop + ld a, [hli] + ld [de], a + inc de + dec c + jr nz, .copyTilesetHeaderLoop + ld a, [hl] + ld [hTilesetType], a + xor a + ld [$ffd8], a + pop hl + ld a, [wCurMapTileset] + push hl + push de + ld hl, DungeonTilesets + ld de, $1 + call IsInArray + pop de + pop hl + jr c, .asm_c797 + ld a, [wCurMapTileset] + ld b, a + ld a, [hPreviousTileset] + cp b + jr z, .done +.asm_c797 + ld a, [wDestinationWarpID] + cp $ff + jr z, .done + call LoadDestinationWarpPosition + ld a, [wYCoord] + and $1 + ld [wYBlockCoord], a + ld a, [wXCoord] + and $1 + ld [wXBlockCoord], a +.done + ret + +INCLUDE "data/dungeon_tilesets.asm" + +INCLUDE "data/tileset_headers.asm" diff --git a/engine/overworld/update_map.asm b/engine/overworld/update_map.asm new file mode 100644 index 00000000..8577b9e7 --- /dev/null +++ b/engine/overworld/update_map.asm @@ -0,0 +1,126 @@ +; replaces a tile block with the one specified in [wNewTileBlockID] +; and redraws the map view if necessary +; b = Y +; c = X +ReplaceTileBlock: + call GetPredefRegisters + ld hl, wOverworldMap + ld a, [wCurMapWidth] + add $6 + ld e, a + ld d, $0 + add hl, de + add hl, de + add hl, de + ld e, $3 + add hl, de + ld e, a + ld a, b + and a + jr z, .addX +; add width * Y +.addWidthYTimesLoop + add hl, de + dec b + jr nz, .addWidthYTimesLoop +.addX + add hl, bc ; add X + ld a, [wNewTileBlockID] + ld [hl], a + ld a, [wCurrentTileBlockMapViewPointer] + ld c, a + ld a, [wCurrentTileBlockMapViewPointer + 1] + ld b, a + call CompareHLWithBC + ret c ; return if the replaced tile block is below the map view in memory + push hl + ld l, e + ld h, $0 + ld e, $6 + ld d, h + add hl, hl + add hl, hl + add hl, de + add hl, bc + pop bc + call CompareHLWithBC + ret c ; return if the replaced tile block is above the map view in memory + +RedrawMapView: + ld a, [wIsInBattle] + inc a + ret z + ld a, [H_AUTOBGTRANSFERENABLED] + push af + ld a, [hTilesetType] + push af + xor a + ld [H_AUTOBGTRANSFERENABLED], a + ld [hTilesetType], a ; no flower/water BG tile animations + call LoadCurrentMapView + call RunDefaultPaletteCommand + ld hl, wMapViewVRAMPointer + ld a, [hli] + ld h, [hl] + ld l, a + ld de, -2 * 32 + add hl, de + ld a, h + and $3 + or $98 + ld a, l + ld [wBuffer], a + ld a, h + ld [wBuffer + 1], a ; this copy of the address is not used + ld a, 2 + ld [$ffbe], a + ld c, 9 ; number of rows of 2x2 tiles (this covers the whole screen) +.redrawRowLoop + push bc + push hl + push hl + ld hl, wTileMap - 2 * SCREEN_WIDTH + ld de, SCREEN_WIDTH + ld a, [$ffbe] +.calcWRAMAddrLoop + add hl, de + dec a + jr nz, .calcWRAMAddrLoop + call CopyToRedrawRowOrColumnSrcTiles + pop hl + ld de, $20 + ld a, [$ffbe] + ld c, a +.calcVRAMAddrLoop + add hl, de + ld a, h + and $3 + or $98 + dec c + jr nz, .calcVRAMAddrLoop + ld [hRedrawRowOrColumnDest + 1], a + ld a, l + ld [hRedrawRowOrColumnDest], a + ld a, REDRAW_ROW + ld [hRedrawRowOrColumnMode], a + call DelayFrame + ld hl, $ffbe + inc [hl] + inc [hl] + pop hl + pop bc + dec c + jr nz, .redrawRowLoop + pop af + ld [hTilesetType], a + pop af + ld [H_AUTOBGTRANSFERENABLED], a + ret + +CompareHLWithBC: + ld a, h + sub b + ret nz + ld a, l + sub c + ret diff --git a/engine/overworld/wild_mons.asm b/engine/overworld/wild_mons.asm new file mode 100644 index 00000000..6444ab7e --- /dev/null +++ b/engine/overworld/wild_mons.asm @@ -0,0 +1,33 @@ +LoadWildData: + ld hl,WildDataPointers + ld a,[wCurMap] + + ; get wild data for current map + ld c,a + ld b,0 + add hl,bc + add hl,bc + ld a,[hli] + ld h,[hl] + ld l,a ; hl now points to wild data for current map + ld a,[hli] + ld [wGrassRate],a + and a + jr z,.NoGrassData ; if no grass data, skip to surfing data + push hl + ld de,wGrassMons ; otherwise, load grass data + ld bc,$0014 + call CopyData + pop hl + ld bc,$0014 + add hl,bc +.NoGrassData + ld a,[hli] + ld [wWaterRate],a + and a + ret z ; if no water data, we're done + ld de,wWaterMons ; otherwise, load surfing data + ld bc,$0014 + jp CopyData + +INCLUDE "data/wild_mons.asm" diff --git a/engine/pathfinding.asm b/engine/pathfinding.asm new file mode 100644 index 00000000..ba052d38 --- /dev/null +++ b/engine/pathfinding.asm @@ -0,0 +1,201 @@ +FindPathToPlayer: + xor a + ld hl, hFindPathNumSteps + ld [hli], a ; hFindPathNumSteps + ld [hli], a ; hFindPathFlags + ld [hli], a ; hFindPathYProgress + ld [hl], a ; hFindPathXProgress + ld hl, wNPCMovementDirections2 + ld de, $0 +.loop + ld a, [hFindPathYProgress] + ld b, a + ld a, [hNPCPlayerYDistance] ; Y distance in steps + call CalcDifference + ld d, a + and a + jr nz, .asm_f8da + ld a, [hFindPathFlags] + set 0, a ; current end of path matches the player's Y coordinate + ld [hFindPathFlags], a +.asm_f8da + ld a, [hFindPathXProgress] + ld b, a + ld a, [hNPCPlayerXDistance] ; X distance in steps + call CalcDifference + ld e, a + and a + jr nz, .asm_f8ec + ld a, [hFindPathFlags] + set 1, a ; current end of path matches the player's X coordinate + ld [hFindPathFlags], a +.asm_f8ec + ld a, [hFindPathFlags] + cp $3 ; has the end of the path reached the player's position? + jr z, .done +; Compare whether the X distance between the player and the current of the path +; is greater or if the Y distance is. Then, try to reduce whichever is greater. + ld a, e + cp d + jr c, .yDistanceGreater +; x distance is greater + ld a, [hNPCPlayerRelativePosFlags] + bit 1, a + jr nz, .playerIsLeftOfNPC + ld d, NPC_MOVEMENT_RIGHT + jr .next1 +.playerIsLeftOfNPC + ld d, NPC_MOVEMENT_LEFT +.next1 + ld a, [hFindPathXProgress] + add 1 + ld [hFindPathXProgress], a + jr .storeDirection +.yDistanceGreater + ld a, [hNPCPlayerRelativePosFlags] + bit 0, a + jr nz, .playerIsAboveNPC + ld d, NPC_MOVEMENT_DOWN + jr .next2 +.playerIsAboveNPC + ld d, NPC_MOVEMENT_UP +.next2 + ld a, [hFindPathYProgress] + add 1 + ld [hFindPathYProgress], a +.storeDirection + ld a, d + ld [hli], a + ld a, [hFindPathNumSteps] + inc a + ld [hFindPathNumSteps], a + jp .loop +.done + ld [hl], $ff + ret + +CalcPositionOfPlayerRelativeToNPC: + xor a + ld [hNPCPlayerRelativePosFlags], a + ld a, [wSpriteStateData1 + 4] ; player's sprite screen Y position in pixels + ld d, a + ld a, [wSpriteStateData1 + 6] ; player's sprite screen X position in pixels + ld e, a + ld hl, wSpriteStateData1 + ld a, [hNPCSpriteOffset] + add l + add $4 + ld l, a + jr nc, .noCarry + inc h +.noCarry + ld a, d + ld b, a + ld a, [hli] ; NPC sprite screen Y position in pixels + call CalcDifference + jr nc, .NPCSouthOfOrAlignedWithPlayer +.NPCNorthOfPlayer + push hl + ld hl, hNPCPlayerRelativePosFlags + bit 0, [hl] + set 0, [hl] + pop hl + jr .divideYDistance +.NPCSouthOfOrAlignedWithPlayer + push hl + ld hl, hNPCPlayerRelativePosFlags + bit 0, [hl] + res 0, [hl] + pop hl +.divideYDistance + push hl + ld hl, hDividend2 + ld [hli], a + ld a, 16 + ld [hli], a + call DivideBytes ; divide Y absolute distance by 16 + ld a, [hl] ; quotient + ld [hNPCPlayerYDistance], a + pop hl + inc hl + ld b, e + ld a, [hl] ; NPC sprite screen X position in pixels + call CalcDifference + jr nc, .NPCEastOfOrAlignedWithPlayer +.NPCWestOfPlayer + push hl + ld hl, hNPCPlayerRelativePosFlags + bit 1, [hl] + set 1, [hl] + pop hl + jr .divideXDistance +.NPCEastOfOrAlignedWithPlayer + push hl + ld hl, hNPCPlayerRelativePosFlags + bit 1, [hl] + res 1, [hl] + pop hl +.divideXDistance + ld [hDividend2], a + ld a, 16 + ld [hDivisor2], a + call DivideBytes ; divide X absolute distance by 16 + ld a, [hQuotient2] + ld [hNPCPlayerXDistance], a + ld a, [hNPCPlayerRelativePosPerspective] + and a + ret z + ld a, [hNPCPlayerRelativePosFlags] + cpl + and $3 + ld [hNPCPlayerRelativePosFlags], a + ret + +ConvertNPCMovementDirectionsToJoypadMasks: + ld a, [hNPCMovementDirections2Index] + ld [wNPCMovementDirections2Index], a + dec a + ld de, wSimulatedJoypadStatesEnd + ld hl, wNPCMovementDirections2 + add l + ld l, a + jr nc, .loop + inc h +.loop + ld a, [hld] + call ConvertNPCMovementDirectionToJoypadMask + ld [de], a + inc de + ld a, [hNPCMovementDirections2Index] + dec a + ld [hNPCMovementDirections2Index], a + jr nz, .loop + ret + +ConvertNPCMovementDirectionToJoypadMask: + push hl + ld b, a + ld hl, NPCMovementDirectionsToJoypadMasksTable +.loop + ld a, [hli] + cp $ff + jr z, .done + cp b + jr z, .loadJoypadMask + inc hl + jr .loop +.loadJoypadMask + ld a, [hl] +.done + pop hl + ret + +NPCMovementDirectionsToJoypadMasksTable: + db NPC_MOVEMENT_UP, D_UP + db NPC_MOVEMENT_DOWN, D_DOWN + db NPC_MOVEMENT_LEFT, D_LEFT + db NPC_MOVEMENT_RIGHT, D_RIGHT + db $ff + +; unreferenced + ret diff --git a/engine/predefs.asm b/engine/predefs.asm index d689318d..605cba3a 100755 --- a/engine/predefs.asm +++ b/engine/predefs.asm @@ -58,10 +58,7 @@ PredefPointers:: add_predef ScaleSpriteByTwo add_predef LoadMonBackPic add_predef CopyDownscaledMonTiles -; add_predef LoadMissableObjects -; For some reason this points to the middle of the "ld de, wMissableObjectList" instruction in LoadMissableObjects - db 3 - dw $714D + dbw $03,JumpMoveEffect ; wrong bank add_predef HealParty add_predef MoveAnimation add_predef DivideBCDPredef @@ -208,7 +208,7 @@ DrawHPBar:: and a jr nz, .fill - ; If c iz nonzero, draw a pixel anyway. + ; If c is nonzero, draw a pixel anyway. ld a, c and a jr z, .done @@ -2095,7 +2095,7 @@ DisableWaitingAfterTextDisplay:: ; [wcf91] = item ID ; OUTPUT: ; [wActionResultOrTookBattleTurn] = success -; 00: unsucessful +; 00: unsuccessful ; 01: successful ; 02: not able to be used right now, no extra menu displayed (only certain items use this) UseItem:: @@ -2540,7 +2540,7 @@ EngageMapTrainer:: ld a, [hli] ; load trainer class ld [wEngagedTrainerClass], a ld a, [hl] ; load trainer mon set - ld [wEnemyMonAttackMod], a + ld [wEngagedTrainerSet], a jp PlayTrainerMusic PrintEndBattleText:: @@ -3394,7 +3394,7 @@ CopyString:: ; this function is used when lower button sensitivity is wanted (e.g. menus) ; OUTPUT: [hJoy5] = pressed buttons in usual format ; there are two flags that control its functionality, [hJoy6] and [hJoy7] -; there are esentially three modes of operation +; there are essentially three modes of operation ; 1. Get newly pressed buttons only ; ([hJoy7] == 0, [hJoy6] == any) ; Just copies [hJoyPressed] to [hJoy5]. @@ -3742,7 +3742,7 @@ CalcStat:: ld a, b add e jr nc, .noCarry2 - inc d ; da = (Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4 + inc d ; de = (Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4 .noCarry2 ld [H_MULTIPLICAND+2], a ld a, d @@ -4125,7 +4125,7 @@ EraseMenuCursor:: ; The reason is that most functions that call this initialize H_DOWNARROWBLINKCNT1 to 0. ; The effect is that if the tile at hl is initialized with a down arrow, ; this function will toggle that down arrow on and off, but if the tile isn't -; initliazed with a down arrow, this function does nothing. +; initialized with a down arrow, this function does nothing. ; That allows this to be called without worrying about if a down arrow should ; be blinking. HandleDownArrowBlinkTiming:: diff --git a/home/overworld.asm b/home/overworld.asm index fe763b43..ec8f1925 100644 --- a/home/overworld.asm +++ b/home/overworld.asm @@ -8,7 +8,7 @@ EnterMap:: ld a, $ff ld [wJoyIgnore], a call LoadMapData - callba ClearVariablesAfterLoadingMapData + callba ClearVariablesOnEnterMap ld hl, wd72c bit 0, [hl] ; has the player already made 3 steps since the last battle? jr z, .skipGivingThreeStepsOfNoRandomBattles @@ -98,7 +98,7 @@ hSwapTemp EQU $FF95 hExperience EQU $FF96 ; 3 bytes, big endian -; Multiplcation and division variables are meant +; Multiplication and division variables are meant ; to overlap for back-to-back usage. Big endian. H_MULTIPLICAND EQU $FF96 ; 3 bytes @@ -155,6 +155,7 @@ hCoins EQU $FFA0 ; 2-byte BCD number hDivideBCDDivisor EQU $FFA2 ; 3-byte BCD number hDivideBCDQuotient EQU $FFA2 ; 3-byte BCD number +hDivideBCDBuffer EQU $FFA5 ; 3-byte BCD number hSerialReceivedNewData EQU $FFA9 diff --git a/macros/data_macros.asm b/macros/data_macros.asm index e24ae20e..4c6457be 100755 --- a/macros/data_macros.asm +++ b/macros/data_macros.asm @@ -146,7 +146,7 @@ ENDM ;\6 (flag) = add 3 to width of connection strip (why?) SOUTH_MAP_CONNECTION: MACRO db \2 ; map id - dw \5 + \4 ; "Conection Strip" location + dw \5 + \4 ; "Connection Strip" location dw wOverworldMap + 3 + (\1_HEIGHT + 3) * (\1_WIDTH + 6) + \3 ; current map position IF (\1_WIDTH < \2_WIDTH) IF (_NARG > 5) @@ -11,7 +11,6 @@ PICS_3 EQU $B PICS_4 EQU $C PICS_5 EQU $D - INCLUDE "home.asm" @@ -95,2692 +94,39 @@ INCLUDE "data/map_songs.asm" INCLUDE "data/map_header_banks.asm" -ClearVariablesAfterLoadingMapData: - ld a, SCREEN_HEIGHT_PIXELS - ld [hWY], a - ld [rWY], a - xor a - ld [H_AUTOBGTRANSFERENABLED], a - ld [wStepCounter], a - ld [wLoneAttackNo], a - ld [hJoyPressed], a - ld [hJoyReleased], a - ld [hJoyHeld], a - ld [wActionResultOrTookBattleTurn], a - ld [wUnusedD5A3], a - ld hl, wCardKeyDoorY - ld [hli], a - ld [hl], a - ld hl, wWhichTrade - ld bc, wStandingOnWarpPadOrHole - wWhichTrade - call FillMemory - ret - -; only used for setting bit 2 of wd736 upon entering a new map -IsPlayerStandingOnWarp: - ld a, [wNumberOfWarps] - and a - ret z - ld c, a - ld hl, wWarpEntries -.loop - ld a, [wYCoord] - cp [hl] - jr nz, .nextWarp1 - inc hl - ld a, [wXCoord] - cp [hl] - jr nz, .nextWarp2 - inc hl - ld a, [hli] ; target warp - ld [wDestinationWarpID], a - ld a, [hl] ; target map - ld [hWarpDestinationMap], a - ld hl, wd736 - set 2, [hl] ; standing on warp flag - ret -.nextWarp1 - inc hl -.nextWarp2 - inc hl - inc hl - inc hl - dec c - jr nz, .loop - ret - -CheckForceBikeOrSurf: - ld hl, wd732 - bit 5, [hl] - ret nz - ld hl, ForcedBikeOrSurfMaps - ld a, [wYCoord] - ld b, a - ld a, [wXCoord] - ld c, a - ld a, [wCurMap] - ld d, a -.loop - ld a, [hli] - cp $ff - ret z ;if we reach FF then it's not part of the list - cp d ;compare to current map - jr nz, .incorrectMap - ld a, [hli] - cp b ;compare y-coord - jr nz, .incorrectY - ld a, [hli] - cp c ;compare x-coord - jr nz, .loop ; incorrect x-coord, check next item - ld a, [wCurMap] - cp SEAFOAM_ISLANDS_4 - ld a, $2 - ld [wSeafoamIslands4CurScript], a - jr z, .forceSurfing - ld a, [wCurMap] - cp SEAFOAM_ISLANDS_5 - ld a, $2 - ld [wSeafoamIslands5CurScript], a - jr z, .forceSurfing - ;force bike riding - ld hl, wd732 - set 5, [hl] - ld a, $1 - ld [wWalkBikeSurfState], a - ld [wWalkBikeSurfStateCopy], a - jp ForceBikeOrSurf -.incorrectMap - inc hl -.incorrectY - inc hl - jr .loop -.forceSurfing - ld a, $2 - ld [wWalkBikeSurfState], a - ld [wWalkBikeSurfStateCopy], a - jp ForceBikeOrSurf - -INCLUDE "data/force_bike_surf.asm" - -IsPlayerFacingEdgeOfMap: - push hl - push de - push bc - ld a, [wSpriteStateData1 + 9] ; player sprite's facing direction - srl a - ld c, a - ld b, $0 - ld hl, .functionPointerTable - add hl, bc - ld a, [hli] - ld h, [hl] - ld l, a - ld a, [wYCoord] - ld b, a - ld a, [wXCoord] - ld c, a - ld de, .asm_c41e - push de - jp [hl] -.asm_c41e - pop bc - pop de - pop hl - ret - -.functionPointerTable - dw .facingDown - dw .facingUp - dw .facingLeft - dw .facingRight - -.facingDown - ld a, [wCurMapHeight] - add a - dec a - cp b - jr z, .setCarry - jr .resetCarry - -.facingUp - ld a, b - and a - jr z, .setCarry - jr .resetCarry - -.facingLeft - ld a, c - and a - jr z, .setCarry - jr .resetCarry - -.facingRight - ld a, [wCurMapWidth] - add a - dec a - cp c - jr z, .setCarry - jr .resetCarry -.resetCarry - and a - ret -.setCarry - scf - ret - -IsWarpTileInFrontOfPlayer: - push hl - push de - push bc - call _GetTileAndCoordsInFrontOfPlayer - ld a, [wCurMap] - cp SS_ANNE_5 - jr z, .ssAnne5 - ld a, [wSpriteStateData1 + 9] ; player sprite's facing direction - srl a - ld c, a - ld b, 0 - ld hl, .warpTileListPointers - add hl, bc - ld a, [hli] - ld h, [hl] - ld l, a - ld a, [wTileInFrontOfPlayer] - ld de, $1 - call IsInArray -.done - pop bc - pop de - pop hl - ret - -.warpTileListPointers: - dw .facingDownWarpTiles - dw .facingUpWarpTiles - dw .facingLeftWarpTiles - dw .facingRightWarpTiles - -.facingDownWarpTiles - db $01,$12,$17,$3D,$04,$18,$33,$FF - -.facingUpWarpTiles - db $01,$5C,$FF - -.facingLeftWarpTiles - db $1A,$4B,$FF - -.facingRightWarpTiles - db $0F,$4E,$FF - -.ssAnne5 - ld a, [wTileInFrontOfPlayer] - cp $15 - jr nz, .notSSAnne5Warp - scf - jr .done -.notSSAnne5Warp - and a - jr .done - -IsPlayerStandingOnDoorTileOrWarpTile: - push hl - push de - push bc - callba IsPlayerStandingOnDoorTile - jr c, .done - ld a, [wCurMapTileset] - add a - ld c, a - ld b, $0 - ld hl, WarpTileIDPointers - add hl, bc - ld a, [hli] - ld h, [hl] - ld l, a - ld de, $1 - aCoord 8, 9 - call IsInArray - jr nc, .done - ld hl, wd736 - res 2, [hl] -.done - pop bc - pop de - pop hl - ret - -INCLUDE "data/warp_tile_ids.asm" - -PrintSafariZoneSteps: - ld a, [wCurMap] - cp SAFARI_ZONE_EAST - ret c - cp UNKNOWN_DUNGEON_2 - ret nc - coord hl, 0, 0 - ld b, 3 - ld c, 7 - call TextBoxBorder - coord hl, 1, 1 - ld de, wSafariSteps - lb bc, 2, 3 - call PrintNumber - coord hl, 4, 1 - ld de, SafariSteps - call PlaceString - coord hl, 1, 3 - ld de, SafariBallText - call PlaceString - ld a, [wNumSafariBalls] - cp 10 - jr nc, .asm_c56d - coord hl, 5, 3 - ld a, " " - ld [hl], a -.asm_c56d - coord hl, 6, 3 - ld de, wNumSafariBalls - lb bc, 1, 2 - jp PrintNumber - -SafariSteps: - db "/500@" - -SafariBallText: - db "BALL×× @" - -GetTileAndCoordsInFrontOfPlayer: - call GetPredefRegisters - -_GetTileAndCoordsInFrontOfPlayer: - ld a, [wYCoord] - ld d, a - ld a, [wXCoord] - ld e, a - ld a, [wSpriteStateData1 + 9] ; player's sprite facing direction - and a ; cp SPRITE_FACING_DOWN - jr nz, .notFacingDown -; facing down - aCoord 8, 11 - inc d - jr .storeTile -.notFacingDown - cp SPRITE_FACING_UP - jr nz, .notFacingUp -; facing up - aCoord 8, 7 - dec d - jr .storeTile -.notFacingUp - cp SPRITE_FACING_LEFT - jr nz, .notFacingLeft -; facing left - aCoord 6, 9 - dec e - jr .storeTile -.notFacingLeft - cp SPRITE_FACING_RIGHT - jr nz, .storeTile -; facing right - aCoord 10, 9 - inc e -.storeTile - ld c, a - ld [wTileInFrontOfPlayer], a - ret - -GetTileTwoStepsInFrontOfPlayer: - xor a - ld [$ffdb], a - ld hl, wYCoord - ld a, [hli] - ld d, a - ld e, [hl] - ld a, [wSpriteStateData1 + 9] ; player's sprite facing direction - and a ; cp SPRITE_FACING_DOWN - jr nz, .notFacingDown -; facing down - ld hl, $ffdb - set 0, [hl] - aCoord 8, 13 - inc d - jr .storeTile -.notFacingDown - cp SPRITE_FACING_UP - jr nz, .notFacingUp -; facing up - ld hl, $ffdb - set 1, [hl] - aCoord 8, 5 - dec d - jr .storeTile -.notFacingUp - cp SPRITE_FACING_LEFT - jr nz, .notFacingLeft -; facing left - ld hl, $ffdb - set 2, [hl] - aCoord 4, 9 - dec e - jr .storeTile -.notFacingLeft - cp SPRITE_FACING_RIGHT - jr nz, .storeTile -; facing right - ld hl, $ffdb - set 3, [hl] - aCoord 12, 9 - inc e -.storeTile - ld c, a - ld [wTileInFrontOfBoulderAndBoulderCollisionResult], a - ld [wTileInFrontOfPlayer], a - ret - -CheckForCollisionWhenPushingBoulder: - call GetTileTwoStepsInFrontOfPlayer - ld hl, wTilesetCollisionPtr - ld a, [hli] - ld h, [hl] - ld l, a -.loop - ld a, [hli] - cp $ff - jr z, .done ; if the tile two steps ahead is not passable - cp c - jr nz, .loop - ld hl, TilePairCollisionsLand - call CheckForTilePairCollisions2 - ld a, $ff - jr c, .done ; if there is an elevation difference between the current tile and the one two steps ahead - ld a, [wTileInFrontOfBoulderAndBoulderCollisionResult] - cp $15 ; stairs tile - ld a, $ff - jr z, .done ; if the tile two steps ahead is stairs - call CheckForBoulderCollisionWithSprites -.done - ld [wTileInFrontOfBoulderAndBoulderCollisionResult], a - ret - -; sets a to $ff if there is a collision and $00 if there is no collision -CheckForBoulderCollisionWithSprites: - ld a, [wBoulderSpriteIndex] - dec a - swap a - ld d, 0 - ld e, a - ld hl, wSpriteStateData2 + $14 - add hl, de - ld a, [hli] ; map Y position - ld [$ffdc], a - ld a, [hl] ; map X position - ld [$ffdd], a - ld a, [wNumSprites] - ld c, a - ld de, $f - ld hl, wSpriteStateData2 + $14 - ld a, [$ffdb] - and $3 ; facing up or down? - jr z, .pushingHorizontallyLoop -.pushingVerticallyLoop - inc hl - ld a, [$ffdd] - cp [hl] - jr nz, .nextSprite1 ; if X coordinates don't match - dec hl - ld a, [hli] - ld b, a - ld a, [$ffdb] - rrca - jr c, .pushingDown -; pushing up - ld a, [$ffdc] - dec a - jr .compareYCoords -.pushingDown - ld a, [$ffdc] - inc a -.compareYCoords - cp b - jr z, .failure -.nextSprite1 - dec c - jr z, .success - add hl, de - jr .pushingVerticallyLoop -.pushingHorizontallyLoop - ld a, [hli] - ld b, a - ld a, [$ffdc] - cp b - jr nz, .nextSprite2 - ld b, [hl] - ld a, [$ffdb] - bit 2, a - jr nz, .pushingLeft -; pushing right - ld a, [$ffdd] - inc a - jr .compareXCoords -.pushingLeft - ld a, [$ffdd] - dec a -.compareXCoords - cp b - jr z, .failure -.nextSprite2 - dec c - jr z, .success - add hl, de - jr .pushingHorizontallyLoop -.failure - ld a, $ff - ret -.success - xor a - ret - -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, $d0 - 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, $d1 - ld [hSpriteIndexOrTextID], a - call DisplayTextID - ld hl, wd72e - set 5, [hl] - ld a, $ff - jr .done -.noBlackOut - xor a -.done - ld [wOutOfBattleBlackout], a - ret - -LoadTilesetHeader: - call GetPredefRegisters - push hl - ld d, 0 - ld a, [wCurMapTileset] - add a - add a - ld b, a - add a - add b ; a = tileset * 12 - jr nc, .noCarry - inc d -.noCarry - ld e, a - ld hl, Tilesets - add hl, de - ld de, wTilesetBank - ld c, $b -.copyTilesetHeaderLoop - ld a, [hli] - ld [de], a - inc de - dec c - jr nz, .copyTilesetHeaderLoop - ld a, [hl] - ld [hTilesetType], a - xor a - ld [$ffd8], a - pop hl - ld a, [wCurMapTileset] - push hl - push de - ld hl, DungeonTilesets - ld de, $1 - call IsInArray - pop de - pop hl - jr c, .asm_c797 - ld a, [wCurMapTileset] - ld b, a - ld a, [hPreviousTileset] - cp b - jr z, .done -.asm_c797 - ld a, [wDestinationWarpID] - cp $ff - jr z, .done - call LoadDestinationWarpPosition - ld a, [wYCoord] - and $1 - ld [wYBlockCoord], a - ld a, [wXCoord] - and $1 - ld [wXBlockCoord], a -.done - ret - -INCLUDE "data/dungeon_tilesets.asm" - -INCLUDE "data/tileset_headers.asm" - -IncrementDayCareMonExp: - ld a, [wDayCareInUse] - and a - ret z - ld hl, wDayCareMonExp + 2 - inc [hl] - ret nz - dec hl - inc [hl] - ret nz - dec hl - inc [hl] - ld a, [hl] - cp $50 - ret c - ld a, $50 - ld [hl], a - ret +INCLUDE "engine/overworld/clear_variables.asm" +INCLUDE "engine/overworld/player_state.asm" +INCLUDE "engine/overworld/poison.asm" +INCLUDE "engine/overworld/tileset_header.asm" +INCLUDE "engine/overworld/daycare_exp.asm" INCLUDE "data/hide_show_data.asm" -PrintStrengthTxt: - ld hl, wd728 - set 0, [hl] - ld hl, UsedStrengthText - call PrintText - ld hl, CanMoveBouldersText - jp PrintText - -UsedStrengthText: - TX_FAR _UsedStrengthText - TX_ASM - ld a, [wcf91] - call PlayCry - call Delay3 - jp TextScriptEnd - -CanMoveBouldersText: - TX_FAR _CanMoveBouldersText - db "@" - -IsSurfingAllowed: -; Returns whether surfing is allowed in bit 1 of wd728. -; Surfing isn't allowed on the Cycling Road or in the lowest level of the -; Seafoam Islands before the current has been slowed with boulders. - ld hl, wd728 - set 1, [hl] - ld a, [wd732] - bit 5, a - jr nz, .forcedToRideBike - ld a, [wCurMap] - cp SEAFOAM_ISLANDS_5 - ret nz - CheckBothEventsSet EVENT_SEAFOAM4_BOULDER1_DOWN_HOLE, EVENT_SEAFOAM4_BOULDER2_DOWN_HOLE - ret z - ld hl, CoordsData_cdf7 - call ArePlayerCoordsInArray - ret nc - ld hl, wd728 - res 1, [hl] - ld hl, CurrentTooFastText - jp PrintText -.forcedToRideBike - ld hl, wd728 - res 1, [hl] - ld hl, CyclingIsFunText - jp PrintText - -CoordsData_cdf7: - db $0B,$07,$FF - -CurrentTooFastText: - TX_FAR _CurrentTooFastText - db "@" - -CyclingIsFunText: - TX_FAR _CyclingIsFunText - db "@" - -; function to add an item (in varying quantities) to the player's bag or PC box -; INPUT: -; hl = address of inventory (either wNumBagItems or wNumBoxItems) -; [wcf91] = item ID -; [wItemQuantity] = item quantity -; sets carry flag if successful, unsets carry flag if unsuccessful -AddItemToInventory_: - ld a,[wItemQuantity] ; a = item quantity - push af - push bc - push de - push hl - push hl - ld d,PC_ITEM_CAPACITY ; how many items the PC can hold - ld a,wNumBagItems & $FF - cp l - jr nz,.checkIfInventoryFull - ld a,wNumBagItems >> 8 - cp h - jr nz,.checkIfInventoryFull -; if the destination is the bag - ld d,BAG_ITEM_CAPACITY ; how many items the bag can hold -.checkIfInventoryFull - ld a,[hl] - sub d - ld d,a - ld a,[hli] - and a - jr z,.addNewItem -.loop - ld a,[hli] - ld b,a ; b = ID of current item in table - ld a,[wcf91] ; a = ID of item being added - cp b ; does the current item in the table match the item being added? - jp z,.increaseItemQuantity ; if so, increase the item's quantity - inc hl - ld a,[hl] - cp a,$ff ; is it the end of the table? - jr nz,.loop -.addNewItem ; add an item not yet in the inventory - pop hl - ld a,d - and a ; is there room for a new item slot? - jr z,.done -; if there is room - inc [hl] ; increment the number of items in the inventory - ld a,[hl] ; the number of items will be the index of the new item - add a - dec a - ld c,a - ld b,0 - add hl,bc ; hl = address to store the item - ld a,[wcf91] - ld [hli],a ; store item ID - ld a,[wItemQuantity] - ld [hli],a ; store item quantity - ld [hl],$ff ; store terminator - jp .success -.increaseItemQuantity ; increase the quantity of an item already in the inventory - ld a,[wItemQuantity] - ld b,a ; b = quantity to add - ld a,[hl] ; a = existing item quantity - add b ; a = new item quantity - cp a,100 - jp c,.storeNewQuantity ; if the new quantity is less than 100, store it -; if the new quantity is greater than or equal to 100, -; try to max out the current slot and add the rest in a new slot - sub a,99 - ld [wItemQuantity],a ; a = amount left over (to put in the new slot) - ld a,d - and a ; is there room for a new item slot? - jr z,.increaseItemQuantityFailed -; if so, store 99 in the current slot and store the rest in a new slot - ld a,99 - ld [hli],a - jp .loop -.increaseItemQuantityFailed - pop hl - and a - jr .done -.storeNewQuantity - ld [hl],a - pop hl -.success - scf -.done - pop hl - pop de - pop bc - pop bc - ld a,b - ld [wItemQuantity],a ; restore the initial value from when the function was called - ret - -; function to remove an item (in varying quantities) from the player's bag or PC box -; INPUT: -; hl = address of inventory (either wNumBagItems or wNumBoxItems) -; [wWhichPokemon] = index (within the inventory) of the item to remove -; [wItemQuantity] = quantity to remove -RemoveItemFromInventory_: - push hl - inc hl - ld a,[wWhichPokemon] ; index (within the inventory) of the item being removed - sla a - add l - ld l,a - jr nc,.noCarry - inc h -.noCarry - inc hl - ld a,[wItemQuantity] ; quantity being removed - ld e,a - ld a,[hl] ; a = current quantity - sub e - ld [hld],a ; store new quantity - ld [wMaxItemQuantity],a - and a - jr nz,.skipMovingUpSlots -; if the remaining quantity is 0, -; remove the emptied item slot and move up all the following item slots -.moveSlotsUp - ld e,l - ld d,h - inc de - inc de ; de = address of the slot following the emptied one -.loop ; loop to move up the following slots - ld a,[de] - inc de - ld [hli],a - cp a,$ff - jr nz,.loop -; update menu info - xor a - ld [wListScrollOffset],a - ld [wCurrentMenuItem],a - ld [wBagSavedMenuItem],a - ld [wSavedListScrollOffset],a - pop hl - ld a,[hl] ; a = number of items in inventory - dec a ; decrement the number of items - ld [hl],a ; store new number of items - ld [wListCount],a - cp a,2 - jr c,.done - ld [wMaxMenuItem],a - jr .done -.skipMovingUpSlots - pop hl -.done - ret - -; wild pokemon data: from 4EB8 to 55C7 - -LoadWildData: - ld hl,WildDataPointers - ld a,[wCurMap] - - ; get wild data for current map - ld c,a - ld b,0 - add hl,bc - add hl,bc - ld a,[hli] - ld h,[hl] - ld l,a ; hl now points to wild data for current map - ld a,[hli] - ld [wGrassRate],a - and a - jr z,.NoGrassData ; if no grass data, skip to surfing data - push hl - ld de,wGrassMons ; otherwise, load grass data - ld bc,$0014 - call CopyData - pop hl - ld bc,$0014 - add hl,bc -.NoGrassData - ld a,[hli] - ld [wWaterRate],a - and a - ret z ; if no water data, we're done - ld de,wWaterMons ; otherwise, load surfing data - ld bc,$0014 - jp CopyData - -INCLUDE "data/wild_mons.asm" +INCLUDE "engine/overworld/field_move_messages.asm" -INCLUDE "engine/items/items.asm" +INCLUDE "engine/items/inventory.asm" -DrawBadges: -; Draw 4x2 gym leader faces, with the faces replaced by -; badges if they are owned. Used in the player status screen. - -; In Japanese versions, names are displayed above faces. -; Instead of removing relevant code, the name graphics were erased. - -; Tile ids for face/badge graphics. - ld de, wBadgeOrFaceTiles - ld hl, .FaceBadgeTiles - ld bc, 8 - call CopyData - -; Booleans for each badge. - ld hl, wTempObtainedBadgesBooleans - ld bc, 8 - xor a - call FillMemory - -; Alter these based on owned badges. - ld de, wTempObtainedBadgesBooleans - ld hl, wBadgeOrFaceTiles - ld a, [wObtainedBadges] - ld b, a - ld c, 8 -.CheckBadge - srl b - jr nc, .NextBadge - ld a, [hl] - add 4 ; Badge graphics are after each face - ld [hl], a - ld a, 1 - ld [de], a -.NextBadge - inc hl - inc de - dec c - jr nz, .CheckBadge - -; Draw two rows of badges. - ld hl, wBadgeNumberTile - ld a, $d8 ; [1] - ld [hli], a - ld [hl], $60 ; First name - - coord hl, 2, 11 - ld de, wTempObtainedBadgesBooleans - call .DrawBadgeRow - - coord hl, 2, 14 - ld de, wTempObtainedBadgesBooleans + 4 -; call .DrawBadgeRow -; ret - -.DrawBadgeRow -; Draw 4 badges. - - ld c, 4 -.DrawBadge - push de - push hl - -; Badge no. - ld a, [wBadgeNumberTile] - ld [hli], a - inc a - ld [wBadgeNumberTile], a - -; Names aren't printed if the badge is owned. - ld a, [de] - and a - ld a, [wBadgeNameTile] - jr nz, .SkipName - call .PlaceTiles - jr .PlaceBadge - -.SkipName - inc a - inc a - inc hl - -.PlaceBadge - ld [wBadgeNameTile], a - ld de, SCREEN_WIDTH - 1 - add hl, de - ld a, [wBadgeOrFaceTiles] - call .PlaceTiles - add hl, de - call .PlaceTiles - -; Shift badge array back one byte. - push bc - ld hl, wBadgeOrFaceTiles + 1 - ld de, wBadgeOrFaceTiles - ld bc, 8 - call CopyData - pop bc - - pop hl - ld de, 4 - add hl, de - - pop de - inc de - dec c - jr nz, .DrawBadge - ret - -.PlaceTiles - ld [hli], a - inc a - ld [hl], a - inc a - ret - -.FaceBadgeTiles - db $20, $28, $30, $38, $40, $48, $50, $58 - -GymLeaderFaceAndBadgeTileGraphics: - INCBIN "gfx/badges.2bpp" - -; replaces a tile block with the one specified in [wNewTileBlockID] -; and redraws the map view if necessary -; b = Y -; c = X -ReplaceTileBlock: - call GetPredefRegisters - ld hl, wOverworldMap - ld a, [wCurMapWidth] - add $6 - ld e, a - ld d, $0 - add hl, de - add hl, de - add hl, de - ld e, $3 - add hl, de - ld e, a - ld a, b - and a - jr z, .addX -; add width * Y -.addWidthYTimesLoop - add hl, de - dec b - jr nz, .addWidthYTimesLoop -.addX - add hl, bc ; add X - ld a, [wNewTileBlockID] - ld [hl], a - ld a, [wCurrentTileBlockMapViewPointer] - ld c, a - ld a, [wCurrentTileBlockMapViewPointer + 1] - ld b, a - call CompareHLWithBC - ret c ; return if the replaced tile block is below the map view in memory - push hl - ld l, e - ld h, $0 - ld e, $6 - ld d, h - add hl, hl - add hl, hl - add hl, de - add hl, bc - pop bc - call CompareHLWithBC - ret c ; return if the replaced tile block is above the map view in memory - -RedrawMapView: - ld a, [wIsInBattle] - inc a - ret z - ld a, [H_AUTOBGTRANSFERENABLED] - push af - ld a, [hTilesetType] - push af - xor a - ld [H_AUTOBGTRANSFERENABLED], a - ld [hTilesetType], a ; no flower/water BG tile animations - call LoadCurrentMapView - call RunDefaultPaletteCommand - ld hl, wMapViewVRAMPointer - ld a, [hli] - ld h, [hl] - ld l, a - ld de, -2 * 32 - add hl, de - ld a, h - and $3 - or $98 - ld a, l - ld [wBuffer], a - ld a, h - ld [wBuffer + 1], a ; this copy of the address is not used - ld a, 2 - ld [$ffbe], a - ld c, 9 ; number of rows of 2x2 tiles (this covers the whole screen) -.redrawRowLoop - push bc - push hl - push hl - ld hl, wTileMap - 2 * SCREEN_WIDTH - ld de, SCREEN_WIDTH - ld a, [$ffbe] -.calcWRAMAddrLoop - add hl, de - dec a - jr nz, .calcWRAMAddrLoop - call CopyToRedrawRowOrColumnSrcTiles - pop hl - ld de, $20 - ld a, [$ffbe] - ld c, a -.calcVRAMAddrLoop - add hl, de - ld a, h - and $3 - or $98 - dec c - jr nz, .calcVRAMAddrLoop - ld [hRedrawRowOrColumnDest + 1], a - ld a, l - ld [hRedrawRowOrColumnDest], a - ld a, REDRAW_ROW - ld [hRedrawRowOrColumnMode], a - call DelayFrame - ld hl, $ffbe - inc [hl] - inc [hl] - pop hl - pop bc - dec c - jr nz, .redrawRowLoop - pop af - ld [hTilesetType], a - pop af - ld [H_AUTOBGTRANSFERENABLED], a - ret - -CompareHLWithBC: - ld a, h - sub b - ret nz - ld a, l - sub c - ret +INCLUDE "engine/overworld/wild_mons.asm" -INCLUDE "engine/overworld/cut.asm" +INCLUDE "engine/items/items.asm" -MarkTownVisitedAndLoadMissableObjects: - ld a, [wCurMap] - cp ROUTE_1 - jr nc, .notInTown - ld c, a - ld b, FLAG_SET - ld hl, wTownVisitedFlag ; mark town as visited (for flying) - predef FlagActionPredef -.notInTown - ld hl, MapHSPointers - ld a, [wCurMap] - ld b, $0 - ld c, a - add hl, bc - add hl, bc - ld a, [hli] ; load missable objects pointer in hl - ld h, [hl] - ; fall through - -LoadMissableObjects: - ld l, a - push hl - ld de, MapHS00 ; calculate difference between out pointer and the base pointer - ld a, l - sub e - jr nc, .asm_f13c - dec h -.asm_f13c - ld l, a - ld a, h - sub d - ld h, a - ld a, h - ld [H_DIVIDEND], a - ld a, l - ld [H_DIVIDEND+1], a - xor a - ld [H_DIVIDEND+2], a - ld [H_DIVIDEND+3], a - ld a, $3 - ld [H_DIVISOR], a - ld b, $2 - call Divide ; divide difference by 3, resulting in the global offset (number of missable items before ours) - ld a, [wCurMap] - ld b, a - ld a, [H_DIVIDEND+3] - ld c, a ; store global offset in c - ld de, wMissableObjectList - pop hl -.writeMissableObjectsListLoop - ld a, [hli] - cp $ff - jr z, .done ; end of list - cp b - jr nz, .done ; not for current map anymore - ld a, [hli] - inc hl - ld [de], a ; write (map-local) sprite ID - inc de - ld a, c - inc c - ld [de], a ; write (global) missable object index - inc de - jr .writeMissableObjectsListLoop -.done - ld a, $ff - ld [de], a ; write sentinel - ret - -InitializeMissableObjectsFlags: - ld hl, wMissableObjectFlags - ld bc, wMissableObjectFlagsEnd - wMissableObjectFlags - xor a - call FillMemory ; clear missable objects flags - ld hl, MapHS00 - xor a - ld [wMissableObjectCounter], a -.missableObjectsLoop - ld a, [hli] - cp $ff ; end of list - ret z - push hl - inc hl - ld a, [hl] - cp Hide - jr nz, .skip - ld hl, wMissableObjectFlags - ld a, [wMissableObjectCounter] - ld c, a - ld b, FLAG_SET - call MissableObjectFlagAction ; set flag if Item is hidden -.skip - ld hl, wMissableObjectCounter - inc [hl] - pop hl - inc hl - inc hl - jr .missableObjectsLoop - -; tests if current sprite is a missable object that is hidden/has been removed -IsObjectHidden: - ld a, [H_CURRENTSPRITEOFFSET] - swap a - ld b, a - ld hl, wMissableObjectList -.loop - ld a, [hli] - cp $ff - jr z, .notHidden ; not missable -> not hidden - cp b - ld a, [hli] - jr nz, .loop - ld c, a - ld b, FLAG_TEST - ld hl, wMissableObjectFlags - call MissableObjectFlagAction - ld a, c - and a - jr nz, .hidden -.notHidden - xor a -.hidden - ld [$ffe5], a - ret - -; adds missable object (items, leg. pokemon, etc.) to the map -; [wMissableObjectIndex]: index of the missable object to be added (global index) -ShowObject: -ShowObject2: - ld hl, wMissableObjectFlags - ld a, [wMissableObjectIndex] - ld c, a - ld b, FLAG_RESET - call MissableObjectFlagAction ; reset "removed" flag - jp UpdateSprites - -; removes missable object (items, leg. pokemon, etc.) from the map -; [wMissableObjectIndex]: index of the missable object to be removed (global index) -HideObject: - ld hl, wMissableObjectFlags - ld a, [wMissableObjectIndex] - ld c, a - ld b, FLAG_SET - call MissableObjectFlagAction ; set "removed" flag - jp UpdateSprites - -MissableObjectFlagAction: -; identical to FlagAction - - push hl - push de - push bc - - ; bit - ld a, c - ld d, a - and 7 - ld e, a - - ; byte - ld a, d - srl a - srl a - srl a - add l - ld l, a - jr nc, .ok - inc h -.ok - - ; d = 1 << e (bitmask) - inc e - ld d, 1 -.shift - dec e - jr z, .shifted - sla d - jr .shift -.shifted - - ld a, b - and a - jr z, .reset - cp 2 - jr z, .read - -.set - ld a, [hl] - ld b, a - ld a, d - or b - ld [hl], a - jr .done - -.reset - ld a, [hl] - ld b, a - ld a, d - xor $ff - and b - ld [hl], a - jr .done - -.read - ld a, [hl] - ld b, a - ld a, d - and b - -.done - pop bc - pop de - pop hl - ld c, a - ret - -TryPushingBoulder: - ld a, [wd728] - bit 0, a ; using Strength? - ret z - ld a, [wFlags_0xcd60] - bit 1, a ; has boulder dust animation from previous push played yet? - ret nz - xor a - ld [hSpriteIndexOrTextID], a - call IsSpriteInFrontOfPlayer - ld a, [hSpriteIndexOrTextID] - ld [wBoulderSpriteIndex], a - and a - jp z, ResetBoulderPushFlags - ld hl, wSpriteStateData1 + 1 - ld d, $0 - ld a, [hSpriteIndexOrTextID] - swap a - ld e, a - add hl, de - res 7, [hl] - call GetSpriteMovementByte2Pointer - ld a, [hl] - cp BOULDER_MOVEMENT_BYTE_2 - jp nz, ResetBoulderPushFlags - ld hl, wFlags_0xcd60 - bit 6, [hl] - set 6, [hl] ; indicate that the player has tried pushing - ret z ; the player must try pushing twice before the boulder will move - ld a, [hJoyHeld] - and D_RIGHT | D_LEFT | D_UP | D_DOWN - ret z - predef CheckForCollisionWhenPushingBoulder - ld a, [wTileInFrontOfBoulderAndBoulderCollisionResult] - and a ; was there a collision? - jp nz, ResetBoulderPushFlags - ld a, [hJoyHeld] - ld b, a - ld a, [wSpriteStateData1 + 9] ; player's sprite facing direction - cp SPRITE_FACING_UP - jr z, .pushBoulderUp - cp SPRITE_FACING_LEFT - jr z, .pushBoulderLeft - cp SPRITE_FACING_RIGHT - jr z, .pushBoulderRight -.pushBoulderDown - bit 7, b - ret z - ld de, PushBoulderDownMovementData - jr .done -.pushBoulderUp - bit 6, b - ret z - ld de, PushBoulderUpMovementData - jr .done -.pushBoulderLeft - bit 5, b - ret z - ld de, PushBoulderLeftMovementData - jr .done -.pushBoulderRight - bit 4, b - ret z - ld de, PushBoulderRightMovementData -.done - call MoveSprite - ld a, SFX_PUSH_BOULDER - call PlaySound - ld hl, wFlags_0xcd60 - set 1, [hl] - ret - -PushBoulderUpMovementData: - db NPC_MOVEMENT_UP,$FF - -PushBoulderDownMovementData: - db NPC_MOVEMENT_DOWN,$FF - -PushBoulderLeftMovementData: - db NPC_MOVEMENT_LEFT,$FF - -PushBoulderRightMovementData: - db NPC_MOVEMENT_RIGHT,$FF - -DoBoulderDustAnimation: - ld a, [wd730] - bit 0, a - ret nz - callab AnimateBoulderDust - call DiscardButtonPresses - ld [wJoyIgnore], a - call ResetBoulderPushFlags - set 7, [hl] - ld a, [wBoulderSpriteIndex] - ld [H_SPRITEINDEX], a - call GetSpriteMovementByte2Pointer - ld [hl], $10 - ld a, SFX_CUT - jp PlaySound - -ResetBoulderPushFlags: - ld hl, wFlags_0xcd60 - res 1, [hl] - res 6, [hl] - ret - -_AddPartyMon: -; Adds a new mon to the player's or enemy's party. -; [wMonDataLocation] is used in an unusual way in this function. -; If the lower nybble is 0, the mon is added to the player's party, else the enemy's. -; If the entire value is 0, then the player is allowed to name the mon. - ld de, wPartyCount - ld a, [wMonDataLocation] - and $f - jr z, .next - ld de, wEnemyPartyCount -.next - ld a, [de] - inc a - cp PARTY_LENGTH + 1 - ret nc ; return if the party is already full - ld [de], a - ld a, [de] - ld [hNewPartyLength], a - add e - ld e, a - jr nc, .noCarry - inc d -.noCarry - ld a, [wcf91] - ld [de], a ; write species of new mon in party list - inc de - ld a, $ff ; terminator - ld [de], a - ld hl, wPartyMonOT - ld a, [wMonDataLocation] - and $f - jr z, .next2 - ld hl, wEnemyMonOT -.next2 - ld a, [hNewPartyLength] - dec a - call SkipFixedLengthTextEntries - ld d, h - ld e, l - ld hl, wPlayerName - ld bc, NAME_LENGTH - call CopyData - ld a, [wMonDataLocation] - and a - jr nz, .skipNaming - ld hl, wPartyMonNicks - ld a, [hNewPartyLength] - dec a - call SkipFixedLengthTextEntries - ld a, NAME_MON_SCREEN - ld [wNamingScreenType], a - predef AskName -.skipNaming - ld hl, wPartyMons - ld a, [wMonDataLocation] - and $f - jr z, .next3 - ld hl, wEnemyMons -.next3 - ld a, [hNewPartyLength] - dec a - ld bc, wPartyMon2 - wPartyMon1 - call AddNTimes - ld e, l - ld d, h - push hl - ld a, [wcf91] - ld [wd0b5], a - call GetMonHeader - ld hl, wMonHeader - ld a, [hli] - ld [de], a ; species - inc de - pop hl - push hl - ld a, [wMonDataLocation] - and $f - ld a, $98 ; set enemy trainer mon IVs to fixed average values - ld b, $88 - jr nz, .next4 - -; If the mon is being added to the player's party, update the pokedex. - ld a, [wcf91] - ld [wd11e], a - push de - predef IndexToPokedex - pop de - ld a, [wd11e] - dec a - ld c, a - ld b, FLAG_TEST - ld hl, wPokedexOwned - call FlagAction - ld a, c ; whether the mon was already flagged as owned - ld [wUnusedD153], a ; not read - ld a, [wd11e] - dec a - ld c, a - ld b, FLAG_SET - push bc - call FlagAction - pop bc - ld hl, wPokedexSeen - call FlagAction - - pop hl - push hl - - ld a, [wIsInBattle] - and a ; is this a wild mon caught in battle? - jr nz, .copyEnemyMonData - -; Not wild. - call Random ; generate random IVs - ld b, a - call Random - -.next4 - push bc - ld bc, wPartyMon1DVs - wPartyMon1 - add hl, bc - pop bc - ld [hli], a - ld [hl], b ; write IVs - ld bc, (wPartyMon1HPExp - 1) - (wPartyMon1DVs + 1) - add hl, bc - ld a, 1 - ld c, a - xor a - ld b, a - call CalcStat ; calc HP stat (set cur Hp to max HP) - ld a, [H_MULTIPLICAND+1] - ld [de], a - inc de - ld a, [H_MULTIPLICAND+2] - ld [de], a - inc de - xor a - ld [de], a ; box level - inc de - ld [de], a ; status ailments - inc de - jr .copyMonTypesAndMoves -.copyEnemyMonData - ld bc, wEnemyMon1DVs - wEnemyMon1 - add hl, bc - ld a, [wEnemyMonDVs] ; copy IVs from cur enemy mon - ld [hli], a - ld a, [wEnemyMonDVs + 1] - ld [hl], a - ld a, [wEnemyMonHP] ; copy HP from cur enemy mon - ld [de], a - inc de - ld a, [wEnemyMonHP+1] - ld [de], a - inc de - xor a - ld [de], a ; box level - inc de - ld a, [wEnemyMonStatus] ; copy status ailments from cur enemy mon - ld [de], a - inc de -.copyMonTypesAndMoves - ld hl, wMonHTypes - ld a, [hli] ; type 1 - ld [de], a - inc de - ld a, [hli] ; type 2 - ld [de], a - inc de - ld a, [hli] ; catch rate (held item in gen 2) - ld [de], a - ld hl, wMonHMoves - ld a, [hli] - inc de - push de - ld [de], a - ld a, [hli] - inc de - ld [de], a - ld a, [hli] - inc de - ld [de], a - ld a, [hli] - inc de - ld [de], a - push de - dec de - dec de - dec de - xor a - ld [wLearningMovesFromDayCare], a - predef WriteMonMoves - pop de - ld a, [wPlayerID] ; set trainer ID to player ID - inc de - ld [de], a - ld a, [wPlayerID + 1] - inc de - ld [de], a - push de - ld a, [wCurEnemyLVL] - ld d, a - callab CalcExperience - pop de - inc de - ld a, [hExperience] ; write experience - ld [de], a - inc de - ld a, [hExperience + 1] - ld [de], a - inc de - ld a, [hExperience + 2] - ld [de], a - xor a - ld b, NUM_STATS * 2 -.writeEVsLoop ; set all EVs to 0 - inc de - ld [de], a - dec b - jr nz, .writeEVsLoop - inc de - inc de - pop hl - call AddPartyMon_WriteMovePP - inc de - ld a, [wCurEnemyLVL] - ld [de], a - inc de - ld a, [wIsInBattle] - dec a - jr nz, .calcFreshStats - ld hl, wEnemyMonMaxHP - ld bc, $a - call CopyData ; copy stats of cur enemy mon - pop hl - jr .done -.calcFreshStats - pop hl - ld bc, wPartyMon1HPExp - 1 - wPartyMon1 - add hl, bc - ld b, $0 - call CalcStats ; calculate fresh set of stats -.done - scf - ret - -LoadMovePPs: - call GetPredefRegisters - ; fallthrough -AddPartyMon_WriteMovePP: - ld b, NUM_MOVES -.pploop - ld a, [hli] ; read move ID - and a - jr z, .empty - dec a - push hl - push de - push bc - ld hl, Moves - ld bc, MoveEnd - Moves - call AddNTimes - ld de, wcd6d - ld a, BANK(Moves) - call FarCopyData - pop bc - pop de - pop hl - ld a, [wcd6d + 5] ; PP is byte 5 of move data -.empty - inc de - ld [de], a - dec b - jr nz, .pploop ; there are still moves to read - ret - -; adds enemy mon [wcf91] (at position [wWhichPokemon] in enemy list) to own party -; used in the cable club trade center -_AddEnemyMonToPlayerParty: - ld hl, wPartyCount - ld a, [hl] - cp PARTY_LENGTH - scf - ret z ; party full, return failure - inc a - ld [hl], a ; add 1 to party members - ld c, a - ld b, $0 - add hl, bc - ld a, [wcf91] - ld [hli], a ; add mon as last list entry - ld [hl], $ff ; write new sentinel - ld hl, wPartyMons - ld a, [wPartyCount] - dec a - ld bc, wPartyMon2 - wPartyMon1 - call AddNTimes - ld e, l - ld d, h - ld hl, wLoadedMon - call CopyData ; write new mon's data (from wLoadedMon) - ld hl, wPartyMonOT - ld a, [wPartyCount] - dec a - call SkipFixedLengthTextEntries - ld d, h - ld e, l - ld hl, wEnemyMonOT - ld a, [wWhichPokemon] - call SkipFixedLengthTextEntries - ld bc, NAME_LENGTH - call CopyData ; write new mon's OT name (from an enemy mon) - ld hl, wPartyMonNicks - ld a, [wPartyCount] - dec a - call SkipFixedLengthTextEntries - ld d, h - ld e, l - ld hl, wEnemyMonNicks - ld a, [wWhichPokemon] - call SkipFixedLengthTextEntries - ld bc, NAME_LENGTH - call CopyData ; write new mon's nickname (from an enemy mon) - ld a, [wcf91] - ld [wd11e], a - predef IndexToPokedex - ld a, [wd11e] - dec a - ld c, a - ld b, FLAG_SET - ld hl, wPokedexOwned - push bc - call FlagAction ; add to owned pokemon - pop bc - ld hl, wPokedexSeen - call FlagAction ; add to seen pokemon - and a - ret ; return success - -_MoveMon: - ld a, [wMoveMonType] - and a - jr z, .checkPartyMonSlots - cp DAYCARE_TO_PARTY - jr z, .checkPartyMonSlots - cp PARTY_TO_DAYCARE - ld hl, wDayCareMon - jr z, .asm_f575 - ld hl, wNumInBox - ld a, [hl] - cp MONS_PER_BOX - jr nz, .partyOrBoxNotFull - jr .boxFull -.checkPartyMonSlots - ld hl, wPartyCount - ld a, [hl] - cp PARTY_LENGTH - jr nz, .partyOrBoxNotFull -.boxFull - scf - ret -.partyOrBoxNotFull - inc a - ld [hl], a ; increment number of mons in party/box - ld c, a - ld b, 0 - add hl, bc - ld a, [wMoveMonType] - cp DAYCARE_TO_PARTY - ld a, [wDayCareMon] - jr z, .asm_f556 - ld a, [wcf91] -.asm_f556 - ld [hli], a ; write new mon ID - ld [hl], $ff ; write new sentinel - ld a, [wMoveMonType] - dec a - ld hl, wPartyMons - ld bc, wPartyMon2 - wPartyMon1 ; $2c - ld a, [wPartyCount] - jr nz, .skipToNewMonEntry - ld hl, wBoxMons - ld bc, wBoxMon2 - wBoxMon1 ; $21 - ld a, [wNumInBox] -.skipToNewMonEntry - dec a - call AddNTimes -.asm_f575 - push hl - ld e, l - ld d, h - ld a, [wMoveMonType] - and a - ld hl, wBoxMons - ld bc, wBoxMon2 - wBoxMon1 ; $21 - jr z, .asm_f591 - cp DAYCARE_TO_PARTY - ld hl, wDayCareMon - jr z, .asm_f597 - ld hl, wPartyMons - ld bc, wPartyMon2 - wPartyMon1 ; $2c -.asm_f591 - ld a, [wWhichPokemon] - call AddNTimes -.asm_f597 - push hl - push de - ld bc, wBoxMon2 - wBoxMon1 - call CopyData - pop de - pop hl - ld a, [wMoveMonType] - and a - jr z, .asm_f5b4 - cp DAYCARE_TO_PARTY - jr z, .asm_f5b4 - ld bc, wBoxMon2 - wBoxMon1 - add hl, bc - ld a, [hl] - inc de - inc de - inc de - ld [de], a -.asm_f5b4 - ld a, [wMoveMonType] - cp PARTY_TO_DAYCARE - ld de, wDayCareMonOT - jr z, .asm_f5d3 - dec a - ld hl, wPartyMonOT - ld a, [wPartyCount] - jr nz, .asm_f5cd - ld hl, wBoxMonOT - ld a, [wNumInBox] -.asm_f5cd - dec a - call SkipFixedLengthTextEntries - ld d, h - ld e, l -.asm_f5d3 - ld hl, wBoxMonOT - ld a, [wMoveMonType] - and a - jr z, .asm_f5e6 - ld hl, wDayCareMonOT - cp DAYCARE_TO_PARTY - jr z, .asm_f5ec - ld hl, wPartyMonOT -.asm_f5e6 - ld a, [wWhichPokemon] - call SkipFixedLengthTextEntries -.asm_f5ec - ld bc, NAME_LENGTH - call CopyData - ld a, [wMoveMonType] - cp PARTY_TO_DAYCARE - ld de, wDayCareMonName - jr z, .asm_f611 - dec a - ld hl, wPartyMonNicks - ld a, [wPartyCount] - jr nz, .asm_f60b - ld hl, wBoxMonNicks - ld a, [wNumInBox] -.asm_f60b - dec a - call SkipFixedLengthTextEntries - ld d, h - ld e, l -.asm_f611 - ld hl, wBoxMonNicks - ld a, [wMoveMonType] - and a - jr z, .asm_f624 - ld hl, wDayCareMonName - cp DAYCARE_TO_PARTY - jr z, .asm_f62a - ld hl, wPartyMonNicks -.asm_f624 - ld a, [wWhichPokemon] - call SkipFixedLengthTextEntries -.asm_f62a - ld bc, NAME_LENGTH - call CopyData - pop hl - ld a, [wMoveMonType] - cp PARTY_TO_BOX - jr z, .asm_f664 - cp PARTY_TO_DAYCARE - jr z, .asm_f664 - push hl - srl a - add $2 - ld [wMonDataLocation], a - call LoadMonData - callba CalcLevelFromExperience - ld a, d - ld [wCurEnemyLVL], a - pop hl - ld bc, wBoxMon2 - wBoxMon1 - add hl, bc - ld [hli], a - ld d, h - ld e, l - ld bc, -18 - add hl, bc - ld b, $1 - call CalcStats -.asm_f664 - and a - ret - - -FlagActionPredef: - call GetPredefRegisters - -FlagAction: -; Perform action b on bit c -; in the bitfield at hl. -; 0: reset -; 1: set -; 2: read -; Return the result in c. - - push hl - push de - push bc - - ; bit - ld a, c - ld d, a - and 7 - ld e, a - - ; byte - ld a, d - srl a - srl a - srl a - add l - ld l, a - jr nc, .ok - inc h -.ok - - ; d = 1 << e (bitmask) - inc e - ld d, 1 -.shift - dec e - jr z, .shifted - sla d - jr .shift -.shifted - - ld a, b - and a - jr z, .reset - cp 2 - jr z, .read - -.set - ld b, [hl] - ld a, d - or b - ld [hl], a - jr .done - -.reset - ld b, [hl] - ld a, d - xor $ff - and b - ld [hl], a - jr .done - -.read - ld b, [hl] - ld a, d - and b -.done - pop bc - pop de - pop hl - ld c, a - ret - - -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 - - -DivideBCDPredef:: -DivideBCDPredef2:: -DivideBCDPredef3:: -DivideBCDPredef4:: - call GetPredefRegisters - -DivideBCD:: - xor a - ld [$ffa5], a - ld [$ffa6], a - ld [$ffa7], a - ld d, $1 -.asm_f72a - ld a, [$ffa2] - and $f0 - jr nz, .asm_f75b - inc d - ld a, [$ffa2] - swap a - and $f0 - ld b, a - ld a, [$ffa3] - swap a - ld [$ffa3], a - and $f - or b - ld [$ffa2], a - ld a, [$ffa3] - and $f0 - ld b, a - ld a, [$ffa4] - swap a - ld [$ffa4], a - and $f - or b - ld [$ffa3], a - ld a, [$ffa4] - and $f0 - ld [$ffa4], a - jr .asm_f72a -.asm_f75b - push de - push de - call DivideBCD_f800 - pop de - ld a, b - swap a - and $f0 - ld [$ffa5], a - dec d - jr z, .asm_f7bc - push de - call DivideBCD_f7d7 - call DivideBCD_f800 - pop de - ld a, [$ffa5] - or b - ld [$ffa5], a - dec d - jr z, .asm_f7bc - push de - call DivideBCD_f7d7 - call DivideBCD_f800 - pop de - ld a, b - swap a - and $f0 - ld [$ffa6], a - dec d - jr z, .asm_f7bc - push de - call DivideBCD_f7d7 - call DivideBCD_f800 - pop de - ld a, [$ffa6] - or b - ld [$ffa6], a - dec d - jr z, .asm_f7bc - push de - call DivideBCD_f7d7 - call DivideBCD_f800 - pop de - ld a, b - swap a - and $f0 - ld [$ffa7], a - dec d - jr z, .asm_f7bc - push de - call DivideBCD_f7d7 - call DivideBCD_f800 - pop de - ld a, [$ffa7] - or b - ld [$ffa7], a -.asm_f7bc - ld a, [$ffa5] - ld [$ffa2], a - ld a, [$ffa6] - ld [$ffa3], a - ld a, [$ffa7] - ld [$ffa4], a - pop de - ld a, $6 - sub d - and a - ret z -.asm_f7ce - push af - call DivideBCD_f7d7 - pop af - dec a - jr nz, .asm_f7ce - ret - -DivideBCD_f7d7: - ld a, [$ffa4] - swap a - and $f - ld b, a - ld a, [$ffa3] - swap a - ld [$ffa3], a - and $f0 - or b - ld [$ffa4], a - ld a, [$ffa3] - and $f - ld b, a - ld a, [$ffa2] - swap a - ld [$ffa2], a - and $f0 - or b - ld [$ffa3], a - ld a, [$ffa2] - and $f - ld [$ffa2], a - ret - -DivideBCD_f800: - ld bc, $3 -.asm_f803 - ld de, $ff9f - ld hl, $ffa2 - push bc - call StringCmp - pop bc - ret c - inc b - ld de, $ffa1 - ld hl, $ffa4 - push bc - call SubBCD - pop bc - jr .asm_f803 - - -AddBCDPredef:: - call GetPredefRegisters - -AddBCD:: - and a - ld b, c -.add - ld a, [de] - adc [hl] - daa - ld [de], a - dec de - dec hl - dec c - jr nz, .add - jr nc, .done - ld a, $99 - inc de -.fill - ld [de], a - inc de - dec b - jr nz, .fill -.done - ret - - -SubBCDPredef:: - call GetPredefRegisters - -SubBCD:: - and a - ld b, c -.sub - ld a, [de] - sbc [hl] - daa - ld [de], a - dec de - dec hl - dec c - jr nz, .sub - jr nc, .done - ld a, $00 - inc de -.fill - ld [de], a - inc de - dec b - jr nz, .fill - scf -.done - ret - - -InitPlayerData: -InitPlayerData2: - - call Random - ld a, [hRandomSub] - ld [wPlayerID], a - - call Random - ld a, [hRandomAdd] - ld [wPlayerID + 1], a - - ld a, $ff - ld [wUnusedD71B], a - - ld hl, wPartyCount - call InitializeEmptyList - ld hl, wNumInBox - call InitializeEmptyList - ld hl, wNumBagItems - call InitializeEmptyList - ld hl, wNumBoxItems - call InitializeEmptyList - -START_MONEY EQU $3000 - ld hl, wPlayerMoney + 1 - ld a, START_MONEY / $100 - ld [hld], a - xor a - ld [hli], a - inc hl - ld [hl], a - - ld [wMonDataLocation], a - - ld hl, wObtainedBadges - ld [hli], a - - ld [hl], a - - ld hl, wPlayerCoins - ld [hli], a - ld [hl], a - - ld hl, wGameProgressFlags - ld bc, wGameProgressFlagsEnd - wGameProgressFlags - call FillMemory ; clear all game progress flags - - jp InitializeMissableObjectsFlags - -InitializeEmptyList: - xor a ; count - ld [hli], a - dec a ; terminator - ld [hl], a - ret - - -GetQuantityOfItemInBag: -; In: b = item ID -; Out: b = how many of that item are in the bag - call GetPredefRegisters - ld hl, wNumBagItems -.loop - inc hl - ld a, [hli] - cp $ff - jr z, .notInBag - cp b - jr nz, .loop - ld a, [hl] - ld b, a - ret -.notInBag - ld b, 0 - ret - -FindPathToPlayer: - xor a - ld hl, hFindPathNumSteps - ld [hli], a ; hFindPathNumSteps - ld [hli], a ; hFindPathFlags - ld [hli], a ; hFindPathYProgress - ld [hl], a ; hFindPathXProgress - ld hl, wNPCMovementDirections2 - ld de, $0 -.loop - ld a, [hFindPathYProgress] - ld b, a - ld a, [hNPCPlayerYDistance] ; Y distance in steps - call CalcDifference - ld d, a - and a - jr nz, .asm_f8da - ld a, [hFindPathFlags] - set 0, a ; current end of path matches the player's Y coordinate - ld [hFindPathFlags], a -.asm_f8da - ld a, [hFindPathXProgress] - ld b, a - ld a, [hNPCPlayerXDistance] ; X distance in steps - call CalcDifference - ld e, a - and a - jr nz, .asm_f8ec - ld a, [hFindPathFlags] - set 1, a ; current end of path matches the player's X coordinate - ld [hFindPathFlags], a -.asm_f8ec - ld a, [hFindPathFlags] - cp $3 ; has the end of the path reached the player's position? - jr z, .done -; Compare whether the X distance between the player and the current of the path -; is greater or if the Y distance is. Then, try to reduce whichever is greater. - ld a, e - cp d - jr c, .yDistanceGreater -; x distance is greater - ld a, [hNPCPlayerRelativePosFlags] - bit 1, a - jr nz, .playerIsLeftOfNPC - ld d, NPC_MOVEMENT_RIGHT - jr .next1 -.playerIsLeftOfNPC - ld d, NPC_MOVEMENT_LEFT -.next1 - ld a, [hFindPathXProgress] - add 1 - ld [hFindPathXProgress], a - jr .storeDirection -.yDistanceGreater - ld a, [hNPCPlayerRelativePosFlags] - bit 0, a - jr nz, .playerIsAboveNPC - ld d, NPC_MOVEMENT_DOWN - jr .next2 -.playerIsAboveNPC - ld d, NPC_MOVEMENT_UP -.next2 - ld a, [hFindPathYProgress] - add 1 - ld [hFindPathYProgress], a -.storeDirection - ld a, d - ld [hli], a - ld a, [hFindPathNumSteps] - inc a - ld [hFindPathNumSteps], a - jp .loop -.done - ld [hl], $ff - ret - -CalcPositionOfPlayerRelativeToNPC: - xor a - ld [hNPCPlayerRelativePosFlags], a - ld a, [wSpriteStateData1 + 4] ; player's sprite screen Y position in pixels - ld d, a - ld a, [wSpriteStateData1 + 6] ; player's sprite screen X position in pixels - ld e, a - ld hl, wSpriteStateData1 - ld a, [hNPCSpriteOffset] - add l - add $4 - ld l, a - jr nc, .noCarry - inc h -.noCarry - ld a, d - ld b, a - ld a, [hli] ; NPC sprite screen Y position in pixels - call CalcDifference - jr nc, .NPCSouthOfOrAlignedWithPlayer -.NPCNorthOfPlayer - push hl - ld hl, hNPCPlayerRelativePosFlags - bit 0, [hl] - set 0, [hl] - pop hl - jr .divideYDistance -.NPCSouthOfOrAlignedWithPlayer - push hl - ld hl, hNPCPlayerRelativePosFlags - bit 0, [hl] - res 0, [hl] - pop hl -.divideYDistance - push hl - ld hl, hDividend2 - ld [hli], a - ld a, 16 - ld [hli], a - call DivideBytes ; divide Y absolute distance by 16 - ld a, [hl] ; quotient - ld [hNPCPlayerYDistance], a - pop hl - inc hl - ld b, e - ld a, [hl] ; NPC sprite screen X position in pixels - call CalcDifference - jr nc, .NPCEastOfOrAlignedWithPlayer -.NPCWestOfPlayer - push hl - ld hl, hNPCPlayerRelativePosFlags - bit 1, [hl] - set 1, [hl] - pop hl - jr .divideXDistance -.NPCEastOfOrAlignedWithPlayer - push hl - ld hl, hNPCPlayerRelativePosFlags - bit 1, [hl] - res 1, [hl] - pop hl -.divideXDistance - ld [hDividend2], a - ld a, 16 - ld [hDivisor2], a - call DivideBytes ; divide X absolute distance by 16 - ld a, [hQuotient2] - ld [hNPCPlayerXDistance], a - ld a, [hNPCPlayerRelativePosPerspective] - and a - ret z - ld a, [hNPCPlayerRelativePosFlags] - cpl - and $3 - ld [hNPCPlayerRelativePosFlags], a - ret - -ConvertNPCMovementDirectionsToJoypadMasks: - ld a, [hNPCMovementDirections2Index] - ld [wNPCMovementDirections2Index], a - dec a - ld de, wSimulatedJoypadStatesEnd - ld hl, wNPCMovementDirections2 - add l - ld l, a - jr nc, .loop - inc h -.loop - ld a, [hld] - call ConvertNPCMovementDirectionToJoypadMask - ld [de], a - inc de - ld a, [hNPCMovementDirections2Index] - dec a - ld [hNPCMovementDirections2Index], a - jr nz, .loop - ret - -ConvertNPCMovementDirectionToJoypadMask: - push hl - ld b, a - ld hl, NPCMovementDirectionsToJoypadMasksTable -.loop - ld a, [hli] - cp $ff - jr z, .done - cp b - jr z, .loadJoypadMask - inc hl - jr .loop -.loadJoypadMask - ld a, [hl] -.done - pop hl - ret - -NPCMovementDirectionsToJoypadMasksTable: - db NPC_MOVEMENT_UP, D_UP - db NPC_MOVEMENT_DOWN, D_DOWN - db NPC_MOVEMENT_LEFT, D_LEFT - db NPC_MOVEMENT_RIGHT, D_RIGHT - db $ff - -; unreferenced - ret +INCLUDE "engine/menu/draw_badges.asm" +INCLUDE "engine/overworld/update_map.asm" +INCLUDE "engine/overworld/cut.asm" +INCLUDE "engine/overworld/missable_objects.asm" +INCLUDE "engine/overworld/push_boulder.asm" + +INCLUDE "engine/add_mon.asm" +INCLUDE "engine/flag_action.asm" +INCLUDE "engine/heal_party.asm" +INCLUDE "engine/bcd.asm" +INCLUDE "engine/init_player_data.asm" +INCLUDE "engine/get_bag_item_quantity.asm" +INCLUDE "engine/pathfinding.asm" INCLUDE "engine/hp_bar.asm" - INCLUDE "engine/hidden_object_functions3.asm" - SECTION "NPC Sprites 1", ROMX, BANK[NPC_SPRITES_1] OakAideSprite: INCBIN "gfx/sprites/oak_aide.2bpp" diff --git a/scripts/oakslab.asm b/scripts/oakslab.asm index b91abd43..e73d7cf8 100755 --- a/scripts/oakslab.asm +++ b/scripts/oakslab.asm @@ -712,7 +712,7 @@ OaksLabScript_1d02b: ret OaksLabScript_1d076: - ld hl, OaksLabTextPointers + $36 ; starts at OaksLabText28 + ld hl, OaksLabTextPointers2 ld a, l ld [wMapTextPtr], a ld a, h @@ -747,19 +747,20 @@ OaksLabTextPointers: dw OaksLabText25 dw OaksLabText26 dw OaksLabText27 - dw OaksLabText28 - dw OaksLabText29 - dw OaksLabText30 - dw OaksLabText31 - dw OaksLabText32 - dw OaksLabText33 - dw OaksLabText34 - dw OaksLabText35 - dw OaksLabText36 - dw OaksLabText37 - dw OaksLabText38 - -OaksLabText28: + +OaksLabTextPointers2: + dw OaksLabText1 + dw OaksLabText2 + dw OaksLabText3 + dw OaksLabText4 + dw OaksLabText5 + dw OaksLabText6 + dw OaksLabText7 + dw OaksLabText8 + dw OaksLabText9 + dw OaksLabText10 + dw OaksLabText11 + OaksLabText1: TX_ASM CheckEvent EVENT_FOLLOWED_OAK_INTO_LAB_2 @@ -791,7 +792,6 @@ OaksLabText41: TX_FAR _OaksLabText41 db "@" -OaksLabText29: OaksLabText2: TX_ASM ld a, STARTER2 @@ -802,7 +802,6 @@ OaksLabText2: ld b, $2 jr OaksLabScript_1d133 -OaksLabText30: OaksLabText3: TX_ASM ld a, STARTER3 @@ -813,7 +812,6 @@ OaksLabText3: ld b, $3 jr OaksLabScript_1d133 -OaksLabText31: OaksLabText4: TX_ASM ld a, STARTER1 @@ -1070,8 +1068,6 @@ OaksLabText_1d31d: TX_FAR _OaksLabText_1d31d db "@" -OaksLabText34: -OaksLabText33: OaksLabText7: OaksLabText6: TX_ASM @@ -1083,12 +1079,10 @@ OaksLabText_1d32c: TX_FAR _OaksLabText_1d32c db "@" -OaksLabText35: OaksLabText8: TX_FAR _OaksLabText8 db "@" -OaksLabText36: OaksLabText9: TX_ASM ld hl, OaksLabText_1d340 @@ -1227,8 +1221,6 @@ OaksLabText27: TX_FAR _OaksLabText27 db "@" -OaksLabText38: -OaksLabText37: OaksLabText11: OaksLabText10: TX_ASM @@ -2325,7 +2325,7 @@ _CoinsScatteredText:: prompt _GettingPumpedText:: - text $5a + text "<USER>" line "accroît sa force!" prompt diff --git a/text/maps/agatha.asm b/text/maps/agatha.asm index 639d45cc..9a273d80 100644 --- a/text/maps/agatha.asm +++ b/text/maps/agatha.asm @@ -22,7 +22,7 @@ _AgathaBeforeBattleText:: cont "#MON servent" cont "à combattre!" - para $52,"! Je vais" + para "<PLAYER>! Je vais" line "te montrer" cont "comment les" cont "grands dresseurs" diff --git a/text/maps/bills_house.asm b/text/maps/bills_house.asm index 10283bd7..730e542c 100644 --- a/text/maps/bills_house.asm +++ b/text/maps/bills_house.asm @@ -56,7 +56,7 @@ _BillThankYouText:: prompt _SSTicketReceivedText:: - text $52," obtient:" + text "<PLAYER> obtient:" line "@" TX_RAM wcf50 text "!@@" diff --git a/text/maps/blues_house.asm b/text/maps/blues_house.asm index 697f71ce..7e178b71 100644 --- a/text/maps/blues_house.asm +++ b/text/maps/blues_house.asm @@ -1,6 +1,6 @@ _DaisyInitialText:: - text "Salut ",$52,"!" - line $53," est dans" + text "Salut <PLAYER>!" + line "<RIVAL> est dans" cont "le labo de pépé! " done @@ -12,7 +12,7 @@ _DaisyOfferMapText:: prompt _GotMapText:: - text $52," obtient:" + text "<PLAYER> obtient:" line "@" TX_RAM wcf50 text "!@@" diff --git a/text/maps/bruno.asm b/text/maps/bruno.asm index 2266c7f8..4829cbdd 100644 --- a/text/maps/bruno.asm +++ b/text/maps/bruno.asm @@ -12,7 +12,7 @@ _BrunoBeforeBattleText:: cont "rien de tel qu'un" cont "corps de rêve!" - para $52,"!" + para "<PLAYER>!" para "Ton équipe..." line "J'vais en faire" diff --git a/text/maps/celadon_city.asm b/text/maps/celadon_city.asm index f5634975..09724030 100644 --- a/text/maps/celadon_city.asm +++ b/text/maps/celadon_city.asm @@ -43,7 +43,7 @@ _TM41PreText:: prompt _ReceivedTM41Text:: - text $52, " reçoit:" + text "<PLAYER> reçoit:" line "@" TX_RAM wcf50 text "!@@" diff --git a/text/maps/celadon_dept_store_roof.asm b/text/maps/celadon_dept_store_roof.asm index bbd0145f..5efe04cb 100644 --- a/text/maps/celadon_dept_store_roof.asm +++ b/text/maps/celadon_dept_store_roof.asm @@ -14,7 +14,7 @@ _CeladonMartRoofText_484f3:: line "pour toi!@@" _CeladonMartRoofText_484f9:: - text $52," reçoit" + text "<PLAYER> reçoit" line "@" TX_RAM wcf50 text "!@@" @@ -41,7 +41,7 @@ _CeladonMartRoofText_48504:: para "Tiens, prends ça!@@" _CeladonMartRoofText_4850a:: - text $52," reçoit" + text "<PLAYER> reçoit" line "@" TX_RAM wcf50 text "!@@" @@ -68,7 +68,7 @@ _CeladonMartRoofText_48515:: para "V'là pour toi!@@" _ReceivedTM49Text:: - text $52," reçoit:" + text "<PLAYER> reçoit:" line "CT49!@@" _CeladonMartRoofText_48520:: diff --git a/text/maps/celadon_diner.asm b/text/maps/celadon_diner.asm index f76d37f8..cf2b5fb0 100644 --- a/text/maps/celadon_diner.asm +++ b/text/maps/celadon_diner.asm @@ -43,7 +43,7 @@ _CeladonDinerText_491a7:: prompt _ReceivedCoinCaseText:: - text $52," reçoit" + text "<PLAYER> reçoit" line "@" TX_RAM wcf50 text "!@@" diff --git a/text/maps/celadon_game_corner.asm b/text/maps/celadon_game_corner.asm index 6f321bfb..82c9d324 100644 --- a/text/maps/celadon_game_corner.asm +++ b/text/maps/celadon_game_corner.asm @@ -64,7 +64,7 @@ _CeladonGameCornerText_48d9c:: prompt _Received10CoinsText:: - text $52," reçoit" + text "<PLAYER> reçoit" line "10 jetons!@@" _CeladonGameCornerText_48da7:: @@ -126,7 +126,7 @@ _CeladonGameCornerText_48e26:: prompt _Received20CoinsText:: - text $52," reçoit" + text "<PLAYER> reçoit" line "20 jetons!@@" _CeladonGameCornerText_48e31:: @@ -150,7 +150,7 @@ _CeladonGameCornerText_48e88:: prompt _CeladonGameCornerText_48e8d:: - text $52," reçoit" + text "<PLAYER> reçoit" line "20 jetons!@@" _CeladonGameCornerText_48e93:: diff --git a/text/maps/celadon_gym.asm b/text/maps/celadon_gym.asm index f0e2f5e7..c6abbe4a 100644 --- a/text/maps/celadon_gym.asm +++ b/text/maps/celadon_gym.asm @@ -68,7 +68,7 @@ _CeladonGymText9:: done _ReceivedTM21Text:: - text $52," reçoit" + text "<PLAYER> reçoit" line "@" TX_RAM wcf50 text "!@@" diff --git a/text/maps/cerulean_city.asm b/text/maps/cerulean_city.asm index db232c1c..89ee1f26 100644 --- a/text/maps/cerulean_city.asm +++ b/text/maps/cerulean_city.asm @@ -1,6 +1,6 @@ _CeruleanCityText_19668:: - text $53, ": Yo!" - line $52, "!" + text "<RIVAL>: Yo!" + line "<PLAYER>!" para "Alors tu t'en" line "sors?" @@ -29,7 +29,7 @@ _CeruleanCityText_19672:: prompt _CeruleanCityText_19677:: - text $53, ": Hé!" + text "<RIVAL: Hé!" line "Tu sais quoi?" para "Chuis allé chez" @@ -69,7 +69,7 @@ _CeruleanCityText_196d9:: done _ReceivedTM28Text:: - text $52, " récupère" + text "<PLAYER> récupère" line "CT28!@@" _ReceivedTM28Text2:: diff --git a/text/maps/cerulean_gym.asm b/text/maps/cerulean_gym.asm index 56bffff2..a5615280 100644 --- a/text/maps/cerulean_gym.asm +++ b/text/maps/cerulean_gym.asm @@ -52,7 +52,7 @@ _CeruleanGymText_5c7c8:: done _ReceivedTM11Text:: - text $52," reçoit" + text "<PLAYER> reçoit" line "la CT11!@@" _CeruleanGymText_5c7d3:: diff --git a/text/maps/champion.asm b/text/maps/champion.asm index 55ce26c2..f3ac6639 100644 --- a/text/maps/champion.asm +++ b/text/maps/champion.asm @@ -1,10 +1,10 @@ _GaryChampionIntroText:: - text $53,":" + text "<RIVAL>:" line "Bonjour minable." para "Je t'attends" line "depuis une bonne" - cont "plombe, ",$52,"!" + cont "plombe, <PLAYER>!" para "Ton devoir en" line "tant que rival" @@ -91,7 +91,7 @@ _GaryText_76103:: done _GaryText2:: - text "CHEN: ",$52,"!" + text "CHEN: <PLAYER>!" done _GaryText_76120:: @@ -107,12 +107,12 @@ _GaryText_76120:: TX_RAM wcd6d text "!" - para $52,", tu es" + para "<PLAYER>, tu es" line "grand maintenant!" done _GaryText_76125:: - text "CHEN: ",$53,"!" + text "CHEN: <RIVAL>!" line "Je suis... déçu!" para "Apprenant que tu" @@ -127,7 +127,7 @@ _GaryText_76125:: cont "déjà perdu..." cont "C'est dingue!" - para $53,"! As-tu" + para "<RIVAL>! As-tu" line "compris pourquoi" cont "ton équipe s'est" cont "fait moucher?" @@ -144,7 +144,7 @@ _GaryText_76125:: done _GaryText_7612a:: - text "CHEN: ",$52,"!" + text "CHEN: <PLAYER>!" para "Cette victoire..." line "Tu ne la dois pas" @@ -157,6 +157,6 @@ _GaryText_7612a:: para "Et ça... " line "C'est bien. " - cont $52,"!" + cont "<PLAYER>!" cont "Suis-moi!" done diff --git a/text/maps/cinnabar_gym.asm b/text/maps/cinnabar_gym.asm index 35d23c70..5ace3daa 100644 --- a/text/maps/cinnabar_gym.asm +++ b/text/maps/cinnabar_gym.asm @@ -50,7 +50,7 @@ _BlaineBadgeText:: done _ReceivedTM38Text:: - text $52," obtient:" + text "<PLAYER> obtient:" line "@" TX_RAM wcf50 text "!@@" @@ -244,6 +244,6 @@ _CinnabarGymText_75ac2:: done _CinnabarGymText_75ac7:: - text $52,"! Tu as" - line "battu AUGUSTE!" + text $52, "! You beat" + line "that fire brand!" done diff --git a/text/maps/cinnabar_lab_fossil_room.asm b/text/maps/cinnabar_lab_fossil_room.asm index 637bc10f..5690530b 100644 --- a/text/maps/cinnabar_lab_fossil_room.asm +++ b/text/maps/cinnabar_lab_fossil_room.asm @@ -64,7 +64,7 @@ _Lab4Text_610b3:: text "Tu te grouilles," line "file-moi ça!" - para $52," donne:" + para "<PLAYER> donne:" line "@" TX_RAM wcd6d text "!" diff --git a/text/maps/cinnabar_lab_metronome_room.asm b/text/maps/cinnabar_lab_metronome_room.asm index 3c01f449..79ed6068 100644 --- a/text/maps/cinnabar_lab_metronome_room.asm +++ b/text/maps/cinnabar_lab_metronome_room.asm @@ -8,7 +8,7 @@ _TM35PreReceiveText:: prompt _ReceivedTM35Text:: - text $52," reçoit:" + text "<PLAYER> reçoit:" line "@" TX_RAM wcf50 text "!@@" diff --git a/text/maps/copycats_house_2f.asm b/text/maps/copycats_house_2f.asm index 992b28df..b6ae8ca3 100644 --- a/text/maps/copycats_house_2f.asm +++ b/text/maps/copycats_house_2f.asm @@ -1,13 +1,13 @@ _CopycatsHouse2FText_5ccd4:: - text $52,": Salut!" + text "<PLAYER>: Salut!" line "tu aimes les" cont "#MON?" - para $52,": Bwoarf!" + para "<PLAYER>: Bwoarf!" line "J'disais ça comme" cont "ça!" - para $52,": Hein?" + para "<PLAYER>: Hein?" line "T'es bizarre toi!" para "COPIEUSE: Hmm?" @@ -29,7 +29,7 @@ _TM31PreReceiveText:: prompt _ReceivedTM31Text:: - text $52," obtient:" + text "<PLAYER> obtient:" line "@" TX_RAM wcf50 text "!@@" @@ -43,13 +43,13 @@ _TM31ExplanationText1:: line "bon #MON!@@" _TM31ExplanationText2:: - text $52,": Salut!" + text "<PLAYER>: Salut!" line "Merci pour la" cont "CT31!" - para $52,": Pardon?" + para "<PLAYER>: Pardon?" - para $52,": Heu..." + para "<PLAYER>: Heu..." line "C'est aussi cool" cont "que ça de" cont "m'imiter?" diff --git a/text/maps/daycare_1.asm b/text/maps/daycare_1.asm index 82edaf8c..55c63a57 100644 --- a/text/maps/daycare_1.asm +++ b/text/maps/daycare_1.asm @@ -47,7 +47,7 @@ _DayCareOweMoneyText:: done _DayCareGotMonBackText:: - text $52," récupère" + text "<PLAYER> récupère" line "@" TX_RAM wDayCareMonName text "!" diff --git a/text/maps/fuchsia_fishing_house.asm b/text/maps/fuchsia_fishing_house.asm index 217648fb..5c6ec60d 100644 --- a/text/maps/fuchsia_fishing_house.asm +++ b/text/maps/fuchsia_fishing_house.asm @@ -19,7 +19,7 @@ _FuchsiaHouse3Text_561c2:: cont "Pêche soit avec" cont "toi, p'tit!" - para $52," reçoit" + para "<PLAYER> reçoit" line "une @" TX_RAM wcf50 text "!@@" @@ -31,7 +31,7 @@ _FuchsiaHouse3Text_56212:: _FuchsiaHouse3Text_56217:: text "Salut," - line $52,"!" + line "<PLAYER>!" para "Ca mord?" done diff --git a/text/maps/fuchsia_gym_2.asm b/text/maps/fuchsia_gym_2.asm index fbb8982f..b51038fe 100644 --- a/text/maps/fuchsia_gym_2.asm +++ b/text/maps/fuchsia_gym_2.asm @@ -23,7 +23,7 @@ _FuchsiaGymText9:: done _ReceivedTM06Text:: - text $52," reçoit:" + text "<PLAYER> reçoit:" line "@" TX_RAM wcf50 text "!@@" diff --git a/text/maps/fujis_house.asm b/text/maps/fujis_house.asm index 65dd4c53..bb68e29f 100644 --- a/text/maps/fujis_house.asm +++ b/text/maps/fujis_house.asm @@ -38,7 +38,7 @@ _LavenderHouse1Text4:: text "NIDORINO: Nido!@@" _LavenderHouse1Text_1d94c:: - text "MR.FUJI: ",$52,"." + text "MR.FUJI: <PLAYER>." para "Ta quête pour" line "compléter ton" @@ -51,7 +51,7 @@ _LavenderHouse1Text_1d94c:: prompt _ReceivedFluteText:: - text $52," obtient:" + text "<PLAYER> obtient:" line "@" TX_RAM wcf50 text "!@@" diff --git a/text/maps/lance.asm b/text/maps/lance.asm index 086dcfaa..7d68bad3 100644 --- a/text/maps/lance.asm +++ b/text/maps/lance.asm @@ -44,7 +44,7 @@ _LanceAfterBattleText:: line "dragons ont-ils" cont "pu succomber à" cont "tes attaques," - cont $52,"?" + cont "<PLAYER>?" para "Tu es désormais" line "champion de la" @@ -60,7 +60,7 @@ _LanceAfterBattleText:: line "t'attend. Son nom" cont "est..." - para $53,"!" + para "<RIVAL>!" line "Il a vaincu le" cont "CONSEIL des 4" cont "avant toi!" diff --git a/text/maps/mr_psychics_house.asm b/text/maps/mr_psychics_house.asm index 1ed93333..aed6e0fe 100644 --- a/text/maps/mr_psychics_house.asm +++ b/text/maps/mr_psychics_house.asm @@ -6,7 +6,7 @@ _TM29PreReceiveText:: prompt _ReceivedTM29Text:: - text $52," obtient:" + text "<PLAYER> obtient:" line "@" TX_RAM wcf50 text "!@@" diff --git a/text/maps/mt_moon_b2f.asm b/text/maps/mt_moon_b2f.asm index ef68032d..b5215af2 100644 --- a/text/maps/mt_moon_b2f.asm +++ b/text/maps/mt_moon_b2f.asm @@ -9,7 +9,7 @@ _MtMoon3Text_49f64:: done _MtMoon3Text_49f6f:: - text $52, " obtient" + text "<PLAYER> obtient" line "@" TX_RAM wcf50 text "!@@" diff --git a/text/maps/oaks_lab.asm b/text/maps/oaks_lab.asm index fdcbe55d..8e948ab7 100644 --- a/text/maps/oaks_lab.asm +++ b/text/maps/oaks_lab.asm @@ -10,7 +10,7 @@ _OaksLabText40:: cont "comme toi!" para "Allez, choisis," - line $52,"!" + line "<PLAYER>!" done _OaksLabText41:: @@ -50,7 +50,7 @@ _OaksLabMonEnergeticText:: prompt _OaksLabReceivedMonText:: - text $52," obtient:" + text "<PLAYER> obtient:" line "@" TX_RAM wcd6d text "!@@" diff --git a/text/maps/pallet_town.asm b/text/maps/pallet_town.asm index 61a096c7..e69ebfe0 100644 --- a/text/maps/pallet_town.asm +++ b/text/maps/pallet_town.asm @@ -52,10 +52,10 @@ _PalletTownText5:: _PalletTownText6:: text "Maison de" - line $52 + line "<PLAYER>" done _PalletTownText7:: text "Maison de" - line $53 + line "<RIVAL>" done diff --git a/text/maps/pewter_gym_2.asm b/text/maps/pewter_gym_2.asm index dcd86226..588aa27d 100644 --- a/text/maps/pewter_gym_2.asm +++ b/text/maps/pewter_gym_2.asm @@ -20,8 +20,8 @@ _TM34PreReceiveText:: done _ReceivedTM34Text:: - text $52," reçoit" - line "la CT34!@@" + text "<PLAYER> received" + line "TM34!@@" _TM34ExplanationText:: text "" @@ -62,7 +62,7 @@ _PewterGymText_5c4bc:: cont "voici le BADGE" cont "ROCHE!" - para $52," reçoit" + para "<PLAYER> reçoit" line "le BADGE ROCHE!@@" _PewterGymText_5c4c1:: diff --git a/text/maps/pokemon_tower_2f.asm b/text/maps/pokemon_tower_2f.asm index a00fb655..0cbb6f34 100644 --- a/text/maps/pokemon_tower_2f.asm +++ b/text/maps/pokemon_tower_2f.asm @@ -1,6 +1,6 @@ _PokemonTower2Text_6062d:: - text $53,": Hé," - line $52,"!" + text "<RIVAL>: Hé," + line "<PLAYER>!" cont "Kesstu fais là?" cont "Tes #MON sont" cont "pas morts!" @@ -20,7 +20,7 @@ _PokemonTower2Text_60632:: prompt _PokemonTower2Text_60637:: - text $53,": Haha," + text "<RIVAL>: Haha," line "Tes #MON sont" cont "minables..." cont "Comme toi!" diff --git a/text/maps/pokemon_tower_5f.asm b/text/maps/pokemon_tower_5f.asm index db6a75a0..8b1926e6 100644 --- a/text/maps/pokemon_tower_5f.asm +++ b/text/maps/pokemon_tower_5f.asm @@ -76,6 +76,6 @@ _PokemonTower5Text7:: cont "sanctuaire!" para "Les #MON de" - line $52," sont" + line "<PLAYER> sont" cont "soignés!" done diff --git a/text/maps/route_1.asm b/text/maps/route_1.asm index 4f4f0562..3f7127c9 100644 --- a/text/maps/route_1.asm +++ b/text/maps/route_1.asm @@ -14,7 +14,7 @@ _Route1ViridianMartSampleText:: prompt _Route1Text_1cae8:: - text $52," obtient:" + text "<PLAYER> obtient:" line "@" TX_RAM wcf50 text "!@@" diff --git a/text/maps/route_12_gate_upstairs.asm b/text/maps/route_12_gate_upstairs.asm index 130b30a9..4607102b 100644 --- a/text/maps/route_12_gate_upstairs.asm +++ b/text/maps/route_12_gate_upstairs.asm @@ -10,7 +10,7 @@ _TM39PreReceiveText:: prompt _ReceivedTM39Text:: - text $52," obtient" + text "<PLAYER> obtient" line "CT39!@@" _TM39ExplanationText:: diff --git a/text/maps/route_12_house.asm b/text/maps/route_12_house.asm index 3ec95295..c6e2217c 100644 --- a/text/maps/route_12_house.asm +++ b/text/maps/route_12_house.asm @@ -18,7 +18,7 @@ _Route12HouseText_564c5:: line "canne à pêche," cont "mon frère!" - para $52," obtient:" + para "<PLAYER> obtient:" line "@" TX_RAM wcf50 text "!@@" @@ -42,7 +42,7 @@ _Route12HouseText_564cf:: _Route12HouseText_564d4:: text "Salut," - line $52,"!" + line "<PLAYER>!" para "Avec cette MEGA" line "CANNE, tu vas" diff --git a/text/maps/route_16_house.asm b/text/maps/route_16_house.asm index 3adf948b..044e4e34 100644 --- a/text/maps/route_16_house.asm +++ b/text/maps/route_16_house.asm @@ -9,7 +9,7 @@ _Route16HouseText3:: prompt _ReceivedHM02Text:: - text $52," obtient:" + text "<PLAYER> obtient:" line "CS02!@@" _HM02ExplanationText:: diff --git a/text/maps/route_22.asm b/text/maps/route_22.asm index 81639998..ccb39133 100644 --- a/text/maps/route_22.asm +++ b/text/maps/route_22.asm @@ -1,6 +1,6 @@ _Route22RivalBeforeBattleText1:: - text $53,": Hé!" - line $52,"!" + text "<RIVAL>: Hé!" + line "<PLAYER>!" para "Tu vas à la" line "LIGUE #MON?" @@ -45,7 +45,7 @@ _Route22RivalDefeatedText1:: prompt _Route22Text_511bc:: - text $53,": Quoi?" + text "<RIVAL>: Quoi?" line "Pourquoi j'ai 2" cont "#MON?" @@ -56,8 +56,8 @@ _Route22Text_511bc:: prompt _Route22RivalBeforeBattleText2:: - text $53,": Tiens?" - line $52,"! Quelle" + text "<RIVAL>: Tiens?" + line "<PLAYER>! Quelle" cont "bonne surprise," cont "tu es là aussi?!" @@ -87,7 +87,7 @@ _Route22RivalAfterBattleText2:: cont "chaud pour la" cont "LIGUE #MON!" - para $52,", t'es" + para "<PLAYER>, t'es" line "vraiment un" cont "minable!" diff --git a/text/maps/route_24_1.asm b/text/maps/route_24_1.asm index 46ead89d..5da8dbe3 100644 --- a/text/maps/route_24_1.asm +++ b/text/maps/route_24_1.asm @@ -11,7 +11,7 @@ _Route24Text_51515:: prompt _Route24Text_5151a:: - text $52," obtient:" + text "<PLAYER> obtient:" line "@" TX_RAM wcf50 text "!@@" diff --git a/text/maps/safari_zone_entrance.asm b/text/maps/safari_zone_entrance.asm index d5c6677b..71256382 100644 --- a/text/maps/safari_zone_entrance.asm +++ b/text/maps/safari_zone_entrance.asm @@ -20,7 +20,7 @@ SafariZoneEntranceText_9e747:: line "type de # BALL" cont "est utilisé ici." - para $52," reçoit" + para "<PLAYER> reçoit" line "30 SAFARI BALL!@@" _SafariZoneEntranceText_75360:: diff --git a/text/maps/safari_zone_secret_house.asm b/text/maps/safari_zone_secret_house.asm index 99c12f98..8a0c2a07 100644 --- a/text/maps/safari_zone_secret_house.asm +++ b/text/maps/safari_zone_secret_house.asm @@ -14,7 +14,7 @@ _SecretHouseText_4a350:: prompt _ReceivedHM03Text:: - text $52, " obtient:" + text "<PLAYER> obtient:" line "@" TX_RAM wcf50 text "!@@" diff --git a/text/maps/saffron_gym.asm b/text/maps/saffron_gym.asm index a8c9ad4c..8f8e379e 100644 --- a/text/maps/saffron_gym.asm +++ b/text/maps/saffron_gym.asm @@ -64,7 +64,7 @@ _SaffronGymText_5d173:: done ReceivedTM46Text:: - text $52," obtient:" + text "<PLAYER> obtient:" line "CT46!@@" _TM46ExplanationText:: diff --git a/text/maps/silph_co_11f.asm b/text/maps/silph_co_11f.asm index 2746032f..d321f70e 100644 --- a/text/maps/silph_co_11f.asm +++ b/text/maps/silph_co_11f.asm @@ -19,7 +19,7 @@ _SilphCoPresidentText:: prompt _ReceivedSilphCoMasterBallText:: - text $52, " obtient:" + text "<PLAYER> obtient:" line "@" TX_RAM wcf50 text "!@@" @@ -89,7 +89,7 @@ _SilphCo10Text_62335:: line "ROCKET est" cont "invincible!" - para $52,"! N'oublie" + para "<PLAYER>! N'oublie" line "jamais que tous" cont "les #MON sont" cont "pour la TEAM" diff --git a/text/maps/silph_co_2f.asm b/text/maps/silph_co_2f.asm index f217917e..19ed7668 100644 --- a/text/maps/silph_co_2f.asm +++ b/text/maps/silph_co_2f.asm @@ -9,7 +9,7 @@ _SilphCo2Text_59ded:: prompt _ReceivedTM36Text:: - text $52, " obtient" + text "<PLAYER> obtient" line "@" TX_RAM wcf50 text "!@@" diff --git a/text/maps/silph_co_3f.asm b/text/maps/silph_co_3f.asm index 653b2eba..3b2e700a 100644 --- a/text/maps/silph_co_3f.asm +++ b/text/maps/silph_co_3f.asm @@ -5,7 +5,7 @@ _SilphCo3Text_59ff9:: done _SilphCo3Text_59ffe:: - text $52, "! Toi et" + text "<PLAYER>! Toi et" line "tes #MON," cont "vous nous avez" cont "sauvés!" diff --git a/text/maps/silph_co_7f.asm b/text/maps/silph_co_7f.asm index eee18137..ff386c49 100644 --- a/text/maps/silph_co_7f.asm +++ b/text/maps/silph_co_7f.asm @@ -153,12 +153,12 @@ _SilphCo7AfterBattleText4:: done _SilphCo7Text_51ebe:: - text $53, ": C'que tu" - line "es lent, ",$52,"!" + text "<RIVAL>: C'que tu" + line "es lent, <PLAYER>!" done _SilphCo7Text_51ec3:: - text $53, ": Hahaha!" + text "<RIVAL>: Hahaha!" line "J'étais sûr que" cont "tu passerais par" cont "là!" @@ -182,7 +182,7 @@ _SilphCo7Text_51ec8:: prompt _SilphCo7Text_51ecd:: - text $53, ": Quelle" + text "<RIVAL>: Quelle" line "perte de temps!" para "Va jouer dans ton" @@ -190,7 +190,7 @@ _SilphCo7Text_51ecd:: prompt _SilphCo7Text_51ed2:: - text "OK, ",$52,"!" + text "OK, <PLAYER>!" para "Je décampe!" @@ -212,7 +212,7 @@ _SilphCo7Text_51ed2:: cont "monde!" para "Bonne chance," - line $52,"!" + line "<PLAYER>!" cont "Tu en auras" cont "besoin, minable!" done diff --git a/text/maps/ss_anne_2.asm b/text/maps/ss_anne_2.asm index be8d7d7f..2da39005 100644 --- a/text/maps/ss_anne_2.asm +++ b/text/maps/ss_anne_2.asm @@ -10,13 +10,13 @@ _SSAnne2Text1:: done _SSAnneRivalBeforeBattleText:: - text $53, ": Salut!" - line $52, "!" + text "<RIVAL>: Salut!" + line "<PLAYER>!" para "Toi! Ici!" line "Sans blague!" - para $52, ", as-tu" + para "<PLAYER>, as-tu" line "vraiment été" cont "invité?" @@ -43,7 +43,7 @@ _SSAnneRivalDefeatedText:: prompt _SSAnneRivalWonText:: - text $52, "! Tu as" + text "<PLAYER>! Tu as" line "le mal de mer?" para "Tu devrais te" @@ -52,7 +52,7 @@ _SSAnneRivalWonText:: prompt _SSAnneRivalCaptainText:: - text $53, ": Il y" + text "<RIVAL>: Il y" line "a le maître de la" cont "technique COUPE" cont "à bord." diff --git a/text/maps/ss_anne_7.asm b/text/maps/ss_anne_7.asm index fa35124d..ac1c41dc 100644 --- a/text/maps/ss_anne_7.asm +++ b/text/maps/ss_anne_7.asm @@ -3,7 +3,7 @@ _SSAnne7RubText:: line "J'suis pas bien." cont "Beurp..." - para $52, " masse" + para "<PLAYER> masse" line "le dos du" cont "CAPITAINE!" @@ -35,7 +35,7 @@ _ReceivingHM01Text:: prompt _ReceivedHM01Text:: - text $52, " obtient" + text "<PLAYER> obtient" line "@" TX_RAM wcf50 text "!@@" diff --git a/text/maps/vermilion_fishing_house.asm b/text/maps/vermilion_fishing_house.asm index 0cd073fe..b9bc928f 100644 --- a/text/maps/vermilion_fishing_house.asm +++ b/text/maps/vermilion_fishing_house.asm @@ -16,7 +16,7 @@ _VermilionHouse2Text_560b6:: para "Prends ça et..." line "Pêche! Pêche!" - para $52," reçoit" + para "<PLAYER> reçoit" line "@" TX_RAM wcf50 text "!@@" @@ -41,7 +41,7 @@ _VermilionHouse2Text_560c0:: _VermilionHouse2Text_560c5:: text "B'jour à toi," - line $52,"!" + line "<PLAYER>!" para "Ca mord?" line "Hein? Hein?" diff --git a/text/maps/vermilion_gym_2.asm b/text/maps/vermilion_gym_2.asm index 502904af..b7bd4864 100644 --- a/text/maps/vermilion_gym_2.asm +++ b/text/maps/vermilion_gym_2.asm @@ -27,7 +27,7 @@ _VermilionGymText_5cb77:: done _ReceivedTM24Text:: - text $52," reçoit:" + text "<PLAYER> reçoit:" line "@" TX_RAM wcf50 text "!@@" diff --git a/text/maps/victory_road_2f.asm b/text/maps/victory_road_2f.asm index 072caef3..55b13c6b 100644 --- a/text/maps/victory_road_2f.asm +++ b/text/maps/victory_road_2f.asm @@ -30,7 +30,7 @@ _VictoryRoad2EndBattleText2:: prompt _VictoryRoad2AfterBattleText2:: - text $53," est aussi" + text "<RIVAL> est aussi" line "arrivé ici!" done diff --git a/text/maps/viridian_city.asm b/text/maps/viridian_city.asm index 97a07e8f..52e9c57b 100644 --- a/text/maps/viridian_city.asm +++ b/text/maps/viridian_city.asm @@ -85,7 +85,7 @@ _ViridianCityText_191ca:: prompt _ReceivedTM42Text:: - text $52, " reçoit:" + text "<PLAYER> reçoit:" line "CT42!@@" _TM42Explanation:: diff --git a/text/maps/viridian_gym.asm b/text/maps/viridian_gym.asm index 687a7a48..c2cfb170 100644 --- a/text/maps/viridian_gym.asm +++ b/text/maps/viridian_gym.asm @@ -74,7 +74,7 @@ _ViridianGymText12:: done _ReceivedTM27Text:: - text $52," reçoit" + text "<PLAYER> reçoit" line "CT27!@@" _TM27ExplanationText:: diff --git a/text/maps/viridian_mart.asm b/text/maps/viridian_mart.asm index e57ea9be..d0b5324a 100644 --- a/text/maps/viridian_mart.asm +++ b/text/maps/viridian_mart.asm @@ -18,7 +18,7 @@ ViridianMartParcelQuestText:: cont "Peux-tu la lui" cont "apporter?" - para $52," obtient" + para "<PLAYER> obtient" line "le COLIS DE CHEN!@@" _ViridianMartText2:: @@ -32,4 +32,3 @@ _ViridianMartText3:: line "Nous sommes en" cont "rupture de stock." done - diff --git a/text/maps/wardens_house.asm b/text/maps/wardens_house.asm index 46719d2d..09ded152 100644 --- a/text/maps/wardens_house.asm +++ b/text/maps/wardens_house.asm @@ -18,7 +18,7 @@ _WardenGibberishText3:: done _WardenTeethText1:: - text $52," donne la" + text "<PLAYER> donne la" line "DENT D'OR au" cont "GARDIEN!@@" @@ -44,7 +44,7 @@ _WardenThankYouText:: prompt _ReceivedHM04Text:: - text $52," reçoit" + text "<PLAYER> reçoit" line "@" TX_RAM wcf50 text "!@@" diff --git a/text/oakspeech.asm b/text/oakspeech.asm index 3fd86a0a..1096ed58 100644 --- a/text/oakspeech.asm +++ b/text/oakspeech.asm @@ -51,7 +51,7 @@ _IntroduceRivalText:: prompt _OakSpeechText3:: - text $52,"!" + text "<PLAYER>!" para "Ta quête des" line "#MON est sur" @@ -1416,7 +1416,7 @@ wStatusScreenHPBarColor:: ; cf25 ds 7 -wCopyingSGBTileData:: ; c2fd +wCopyingSGBTileData:: ; cf2d wWhichPartyMenuHPBar:: ; cf2d @@ -1738,7 +1738,7 @@ wPlayerBattleStatus3:: ; d064 ; bit 0 - toxic ; bit 1 - light screen ; bit 2 - reflect -; bit 3 - tranformed +; bit 3 - transformed ds 1 wEnemyStatsToDouble:: ; d065 @@ -2049,7 +2049,7 @@ wPredefBank:: ; d0b7 wMonHeader:: ; d0b8 wMonHIndex:: ; d0b8 -; In the ROM base stats data stucture, this is the dex number, but it is +; In the ROM base stats data structure, this is the dex number, but it is ; overwritten with the internal index number after the header is copied to WRAM. ds 1 @@ -3060,7 +3060,7 @@ wd732:: ; d732 ; bit 1: remnant of debug mode? not set by the game code. ; if it is set ; 1. skips most of Prof. Oak's speech, and uses NINTEN as the player's name and SONY as the rival's name -; 2. does not have the player start in floor two of the playyer's house (instead sending them to [wLastMap]) +; 2. does not have the player start in floor two of the player's house (instead sending them to [wLastMap]) ; 3. allows wild battles to be avoided by holding down B ; bit 2: the target warp is a fly warp (bit 3 set or blacked out) or a dungeon warp (bit 4 set) ; bit 3: used warp pad, escape rope, dig, teleport, or fly, so the target warp is a "fly warp" @@ -3088,7 +3088,7 @@ wd736:: ; d736 ; bit 1: the player is currently stepping down from a door ; bit 2: standing on a warp ; bit 6: jumping down a ledge / fishing animation -; bit 7: player sprite spinning due to spin tiles (Rocket hidehout / Viridian Gym) +; bit 7: player sprite spinning due to spin tiles (Rocket hideout / Viridian Gym) ds 1 wCompletedInGameTradeFlags:: ; d737 @@ -3173,7 +3173,7 @@ wUnusedDA38:: ; da38 wCurMapScript:: ; da39 ; index of current map script, mostly used as index for function pointer array -; mostly copied from map-specific map script pointer and wirtten back later +; mostly copied from map-specific map script pointer and written back later ds 1 ds 7 @@ -3225,9 +3225,9 @@ wBoxMonNicksEnd:: ; dee2 wBoxDataEnd:: -SECTION "Stack", WRAMX[$dfff], BANK[1] +SECTION "Stack", WRAMX[$df00], BANK[1] + ds $ff wStack:: ; dfff - ds -$100 INCLUDE "sram.asm" |