From 5207a14af34f9b84a9e40cc1d4988a0858a4a4e6 Mon Sep 17 00:00:00 2001 From: dannye Date: Wed, 27 Jul 2016 22:08:13 -0500 Subject: Redo audio header macro --- engine/battle/core.asm | 6 +++--- engine/battle/end_of_battle.asm | 2 +- engine/evolution.asm | 2 +- engine/hidden_object_functions7.asm | 2 +- engine/items/items.asm | 6 +++--- engine/overworld/elevator.asm | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) (limited to 'engine') diff --git a/engine/battle/core.asm b/engine/battle/core.asm index 9241ce6b..01c12347 100755 --- a/engine/battle/core.asm +++ b/engine/battle/core.asm @@ -872,7 +872,7 @@ FaintEnemyPokemon: ld a, SFX_FAINT_FALL call PlaySoundWaitForCurrent .sfxwait - ld a, [wChannelSoundIDs + CH4] + ld a, [wChannelSoundIDs + Ch4] cp SFX_FAINT_FALL jr z, .sfxwait ld a, SFX_FAINT_THUD @@ -956,7 +956,7 @@ EndLowHealthAlarm: ; the low health alarm and prevents it from reactivating until the next battle. xor a ld [wLowHealthAlarm], a ; turn off low health alarm - ld [wChannelSoundIDs + CH4], a + ld [wChannelSoundIDs + Ch4], a inc a ld [wLowHealthAlarmDisabled], a ; prevent it from reactivating ret @@ -1954,7 +1954,7 @@ DrawPlayerHUDAndHPBar: ld [hl], $0 ret z xor a - ld [wChannelSoundIDs + CH4], a + ld [wChannelSoundIDs + Ch4], a ret .setLowHealthAlarm ld hl, wLowHealthAlarm diff --git a/engine/battle/end_of_battle.asm b/engine/battle/end_of_battle.asm index 2d6ab2e9..c77e3b39 100755 --- a/engine/battle/end_of_battle.asm +++ b/engine/battle/end_of_battle.asm @@ -46,7 +46,7 @@ EndOfBattle: .resetVariables xor a ld [wLowHealthAlarm], a ;disable low health alarm - ld [wChannelSoundIDs + CH4], a + ld [wChannelSoundIDs + Ch4], a ld [wIsInBattle], a ld [wBattleType], a ld [wMoveMissed], a diff --git a/engine/evolution.asm b/engine/evolution.asm index c0a3434a..a2c52765 100755 --- a/engine/evolution.asm +++ b/engine/evolution.asm @@ -8,7 +8,7 @@ EvolveMon: push af xor a ld [wLowHealthAlarm], a - ld [wChannelSoundIDs + CH4], a + ld [wChannelSoundIDs + Ch4], a dec a ld [wNewSoundID], a call PlaySound diff --git a/engine/hidden_object_functions7.asm b/engine/hidden_object_functions7.asm index c5ae3f10..f04c1deb 100755 --- a/engine/hidden_object_functions7.asm +++ b/engine/hidden_object_functions7.asm @@ -71,7 +71,7 @@ SafariZoneGameOver: ld a, SFX_SAFARI_ZONE_PA call PlayMusic .waitForMusicToPlay - ld a, [wChannelSoundIDs + CH4] + ld a, [wChannelSoundIDs + Ch4] cp SFX_SAFARI_ZONE_PA jr nz, .waitForMusicToPlay ld a, TEXT_SAFARI_GAME_OVER diff --git a/engine/items/items.asm b/engine/items/items.asm index 42d05981..aaddc396 100755 --- a/engine/items/items.asm +++ b/engine/items/items.asm @@ -990,7 +990,7 @@ ItemUseMedicine: .notFullHP ; if the pokemon's current HP doesn't equal its max HP xor a ld [wLowHealthAlarm],a ;disable low health alarm - ld [wChannelSoundIDs + CH4],a + ld [wChannelSoundIDs + Ch4],a push hl push de ld bc,wPartyMon1MaxHP - (wPartyMon1HP + 1) @@ -1777,7 +1777,7 @@ ItemUsePokeflute: call WaitForSoundToFinish ; wait for sound to end callba Music_PokeFluteInBattle ; play in-battle pokeflute music .musicWaitLoop ; wait for music to finish playing - ld a,[wChannelSoundIDs + CH6] + ld a,[wChannelSoundIDs + Ch6] and a ; music off? jr nz,.musicWaitLoop .skipMusic @@ -1850,7 +1850,7 @@ PlayedFluteHadEffectText: 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/overworld/elevator.asm b/engine/overworld/elevator.asm index 929e4f22..7ff4ff71 100755 --- a/engine/overworld/elevator.asm +++ b/engine/overworld/elevator.asm @@ -33,7 +33,7 @@ ShakeElevator: ld a, SFX_SAFARI_ZONE_PA call PlayMusic .musicLoop - ld a, [wChannelSoundIDs + CH4] + ld a, [wChannelSoundIDs + Ch4] cp SFX_SAFARI_ZONE_PA jr z, .musicLoop call UpdateSprites -- cgit v1.2.3 From 52bb07ca18f5475eb9a11c69bf8fee75bcb1abff Mon Sep 17 00:00:00 2001 From: dannye Date: Wed, 27 Jul 2016 22:33:48 -0500 Subject: Replace unnecessary tabs with spaces --- engine/battle/core.asm | 14 +++++++------- engine/items/items.asm | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'engine') diff --git a/engine/battle/core.asm b/engine/battle/core.asm index 01c12347..d1fd27f1 100755 --- a/engine/battle/core.asm +++ b/engine/battle/core.asm @@ -4502,10 +4502,10 @@ GetEnemyMonStat: CalculateDamage: ; input: -; b: attack -; c: opponent defense -; d: base power -; e: level +; b: attack +; c: opponent defense +; d: base power +; e: level ld a, [H_WHOSETURN] ; whose turn? and a @@ -7512,7 +7512,7 @@ FrozenText: CheckDefrost: ; any fire-type move that has a chance inflict burn (all but Fire Spin) will defrost a frozen target - and a, 1 << FRZ ; are they frozen? + and a, 1 << FRZ ; are they frozen? ret z ; return if so ld a, [H_WHOSETURN] and a @@ -7521,7 +7521,7 @@ CheckDefrost: ld a, [wPlayerMoveType] sub a, FIRE ret nz ; return if type of move used isn't fire - ld [wEnemyMonStatus], a ; set opponent status to 00 ["defrost" a frozen monster] + ld [wEnemyMonStatus], a ; set opponent status to 00 ["defrost" a frozen monster] ld hl, wEnemyMon1Status ld a, [wEnemyMonPartyPos] ld bc, wEnemyMon2 - wEnemyMon1 @@ -7531,7 +7531,7 @@ CheckDefrost: ld hl, FireDefrostedText jr .common .opponent - ld a, [wEnemyMoveType] ; same as above with addresses swapped + ld a, [wEnemyMoveType] ; same as above with addresses swapped sub a, FIRE ret nz ld [wBattleMonStatus], a diff --git a/engine/items/items.asm b/engine/items/items.asm index aaddc396..f8873a6e 100755 --- a/engine/items/items.asm +++ b/engine/items/items.asm @@ -1,7 +1,7 @@ UseItem_: ld a,1 ld [wActionResultOrTookBattleTurn],a ; initialise to success value - ld a,[wcf91] ;contains item_ID + ld a,[wcf91] ;contains item_ID cp a,HM_01 jp nc,ItemUseTMHM ld hl,ItemUsePtrTable @@ -235,7 +235,7 @@ ItemUseBall: ld b,a .skipAilmentValueSubtraction - push bc ; save (Rand1 - Status) + push bc ; save (Rand1 - Status) ; Calculate MaxHP * 255. xor a -- cgit v1.2.3 From 6f1ac06e03cd046f61fb2370ff7379a29932bbb1 Mon Sep 17 00:00:00 2001 From: YamaArashi Date: Sat, 17 Sep 2016 17:37:32 -0700 Subject: pull some bank 1 code out of main.asm --- engine/cable_club.asm | 6 + engine/load_mon_data.asm | 49 ++++ engine/overworld/map_sprite_functions1.asm | 356 +++++++++++++++++++++++++++++ engine/print_waiting_text.asm | 20 ++ engine/test_battle.asm | 45 ++++ engine/titlescreen.asm | 3 + 6 files changed, 479 insertions(+) create mode 100644 engine/load_mon_data.asm create mode 100644 engine/overworld/map_sprite_functions1.asm create mode 100644 engine/print_waiting_text.asm create mode 100644 engine/test_battle.asm (limited to 'engine') diff --git a/engine/cable_club.asm b/engine/cable_club.asm index ab18f32b..137e8406 100755 --- a/engine/cable_club.asm +++ b/engine/cable_club.asm @@ -969,3 +969,9 @@ CableClub_DrawHorizontalLine: dec d jr nz, .loop ret + +LoadTrainerInfoTextBoxTiles: + ld de, TrainerInfoTextBoxTileGraphics + ld hl, vChars2 + $760 + lb bc, BANK(TrainerInfoTextBoxTileGraphics), (TrainerInfoTextBoxTileGraphicsEnd - TrainerInfoTextBoxTileGraphics) / $10 + jp CopyVideoData diff --git a/engine/load_mon_data.asm b/engine/load_mon_data.asm new file mode 100644 index 00000000..a71a81c5 --- /dev/null +++ b/engine/load_mon_data.asm @@ -0,0 +1,49 @@ +LoadMonData_: +; Load monster [wWhichPokemon] from list [wMonDataLocation]: +; 0: partymon +; 1: enemymon +; 2: boxmon +; 3: daycaremon +; Return monster id at wcf91 and its data at wLoadedMon. +; Also load base stats at wMonHeader for convenience. + + ld a, [wDayCareMonSpecies] + ld [wcf91], a + ld a, [wMonDataLocation] + cp DAYCARE_DATA + jr z, .GetMonHeader + + ld a, [wWhichPokemon] + ld e, a + callab GetMonSpecies + +.GetMonHeader + ld a, [wcf91] + ld [wd0b5], a ; input for GetMonHeader + call GetMonHeader + + ld hl, wPartyMons + ld bc, wPartyMon2 - wPartyMon1 + ld a, [wMonDataLocation] + cp ENEMY_PARTY_DATA + jr c, .getMonEntry + + ld hl, wEnemyMons + jr z, .getMonEntry + + cp 2 + ld hl, wBoxMons + ld bc, wBoxMon2 - wBoxMon1 + jr z, .getMonEntry + + ld hl, wDayCareMon + jr .copyMonData + +.getMonEntry + ld a, [wWhichPokemon] + call AddNTimes + +.copyMonData + ld de, wLoadedMon + ld bc, wPartyMon2 - wPartyMon1 + jp CopyData diff --git a/engine/overworld/map_sprite_functions1.asm b/engine/overworld/map_sprite_functions1.asm new file mode 100644 index 00000000..d1a411fa --- /dev/null +++ b/engine/overworld/map_sprite_functions1.asm @@ -0,0 +1,356 @@ +_UpdateSprites: + ld h, $c1 + inc h + ld a, $e ; wSpriteStateData2 + $0e +.spriteLoop + ld l, a + sub $e + ld c, a + ld [H_CURRENTSPRITEOFFSET], a + ld a, [hl] + and a + jr z, .skipSprite ; tests $c2Xe + push hl + push de + push bc + call .updateCurrentSprite + pop bc + pop de + pop hl +.skipSprite + ld a, l + add $10 ; move to next sprite + cp $e ; test for overflow (back at $0e) + jr nz, .spriteLoop + ret +.updateCurrentSprite + cp $1 + jp nz, UpdateNonPlayerSprite + jp UpdatePlayerSprite + +UpdateNonPlayerSprite: + dec a + swap a + ld [$ff93], a ; $10 * sprite# + ld a, [wNPCMovementScriptSpriteOffset] ; some sprite offset? + ld b, a + ld a, [H_CURRENTSPRITEOFFSET] + cp b + jr nz, .unequal + jp DoScriptedNPCMovement +.unequal + jp UpdateNPCSprite + +; This detects if the current sprite (whose offset is at H_CURRENTSPRITEOFFSET) +; is going to collide with another sprite by looping over the other sprites. +; The current sprite's offset will be labelled with i (e.g. $c1i0). +; The loop sprite's offset will labelled with j (e.g. $c1j0). +; +; Note that the Y coordinate of the sprite (in [$c1k4]) is one of the following +; 9 values when the sprite is aligned with the grid: $fc, $0c, $1c, $2c, ..., $7c. +; The reason that 4 is added below to the coordinate is to make it align with a +; multiple of $10 to make comparisons easier. +DetectCollisionBetweenSprites: + nop + + ld h, wSpriteStateData1 / $100 + ld a, [H_CURRENTSPRITEOFFSET] + add wSpriteStateData1 % $100 + ld l, a + + ld a, [hl] ; a = [$c1i0] (picture) (0 if slot is unused) + and a ; is this sprite slot slot used? + ret z ; return if not used + + ld a, l + add 3 + ld l, a + + ld a, [hli] ; a = [$c1i3] (delta Y) (-1, 0, or 1) + call SetSpriteCollisionValues + + ld a, [hli] ; a = [$C1i4] (Y screen coordinate) + add 4 ; align with multiple of $10 + +; The effect of the following 3 lines is to +; add 7 to a if moving south or +; subtract 7 from a if moving north. + add b + and $f0 + or c + + ld [$ff90], a ; store Y coordinate adjusted for direction of movement + + ld a, [hli] ; a = [$c1i5] (delta X) (-1, 0, or 1) + call SetSpriteCollisionValues + ld a, [hl] ; a = [$C1i6] (X screen coordinate) + +; The effect of the following 3 lines is to +; add 7 to a if moving east or +; subtract 7 from a if moving west. + add b + and $f0 + or c + + ld [$ff91], a ; store X coordinate adjusted for direction of movement + + ld a, l + add 7 + ld l, a + + xor a + ld [hld], a ; zero [$c1id] XXX what's [$c1id] for? + ld [hld], a ; zero [$c1ic] (directions in which collisions occurred) + + ld a, [$ff91] + ld [hld], a ; [$c1ib] = adjusted X coordinate + ld a, [$ff90] + ld [hl], a ; [$c1ia] = adjusted Y coordinate + + xor a ; zero the loop counter + +.loop + ld [$ff8f], a ; store loop counter + swap a + ld e, a + ld a, [H_CURRENTSPRITEOFFSET] + cp e ; does the loop sprite match the current sprite? + jp z, .next ; go to the next sprite if they match + + ld d, h + ld a, [de] ; a = [$c1j0] (picture) (0 if slot is unused) + and a ; is this sprite slot slot used? + jp z, .next ; go the next sprite if not used + + inc e + inc e + ld a, [de] ; a = [$c1j2] ($ff means the sprite is offscreen) + inc a + jp z, .next ; go the next sprite if offscreen + + ld a, [H_CURRENTSPRITEOFFSET] + add 10 + ld l, a + + inc e + ld a, [de] ; a = [$c1j3] (delta Y) + call SetSpriteCollisionValues + + inc e + ld a, [de] ; a = [$C1j4] (Y screen coordinate) + add 4 ; align with multiple of $10 + +; The effect of the following 3 lines is to +; add 7 to a if moving south or +; subtract 7 from a if moving north. + add b + and $f0 + or c + + sub [hl] ; subtract the adjusted Y coordinate of sprite i ([$c1ia]) from that of sprite j + +; calculate the absolute value of the difference to get the distance + jr nc, .noCarry1 + cpl + inc a +.noCarry1 + ld [$ff90], a ; store the distance between the two sprites' adjusted Y values + +; Use the carry flag set by the above subtraction to determine which sprite's +; Y coordinate is larger. This information is used later to set [$c1ic], +; which stores which direction the collision occurred in. +; The following 5 lines set the lowest 2 bits of c, which are later shifted left by 2. +; If sprite i's Y is larger, set lowest 2 bits of c to 10. +; If sprite j's Y is larger or both are equal, set lowest 2 bits of c to 01. + push af + rl c + pop af + ccf + rl c + +; If sprite i's delta Y is 0, then b = 7, else b = 9. + ld b, 7 + ld a, [hl] ; a = [$c1ia] (adjusted Y coordinate) + and $f + jr z, .next1 + ld b, 9 + +.next1 + ld a, [$ff90] ; a = distance between adjusted Y coordinates + sub b + ld [$ff92], a ; store distance adjusted using sprite i's direction + ld a, b + ld [$ff90], a ; store 7 or 9 depending on sprite i's delta Y + jr c, .checkXDistance + +; If sprite j's delta Y is 0, then b = 7, else b = 9. + ld b, 7 + dec e + ld a, [de] ; a = [$c1j3] (delta Y) + inc e + and a + jr z, .next2 + ld b, 9 + +.next2 + ld a, [$ff92] ; a = distance adjusted using sprite i's direction + sub b ; adjust distance using sprite j's direction + jr z, .checkXDistance + jr nc, .next ; go to next sprite if distance is still positive after both adjustments + +.checkXDistance + inc e + inc l + ld a, [de] ; a = [$c1j5] (delta X) + + push bc + + call SetSpriteCollisionValues + inc e + ld a, [de] ; a = [$c1j6] (X screen coordinate) + +; The effect of the following 3 lines is to +; add 7 to a if moving east or +; subtract 7 from a if moving west. + add b + and $f0 + or c + + pop bc + + sub [hl] ; subtract the adjusted X coordinate of sprite i ([$c1ib]) from that of sprite j + +; calculate the absolute value of the difference to get the distance + jr nc, .noCarry2 + cpl + inc a +.noCarry2 + ld [$ff91], a ; store the distance between the two sprites' adjusted X values + +; Use the carry flag set by the above subtraction to determine which sprite's +; X coordinate is larger. This information is used later to set [$c1ic], +; which stores which direction the collision occurred in. +; The following 5 lines set the lowest 2 bits of c. +; If sprite i's X is larger, set lowest 2 bits of c to 10. +; If sprite j's X is larger or both are equal, set lowest 2 bits of c to 01. + push af + rl c + pop af + ccf + rl c + +; If sprite i's delta X is 0, then b = 7, else b = 9. + ld b, 7 + ld a, [hl] ; a = [$c1ib] (adjusted X coordinate) + and $f + jr z, .next3 + ld b, 9 + +.next3 + ld a, [$ff91] ; a = distance between adjusted X coordinates + sub b + ld [$ff92], a ; store distance adjusted using sprite i's direction + ld a, b + ld [$ff91], a ; store 7 or 9 depending on sprite i's delta X + jr c, .collision + +; If sprite j's delta X is 0, then b = 7, else b = 9. + ld b, 7 + dec e + ld a, [de] ; a = [$c1j5] (delta X) + inc e + and a + jr z, .next4 + ld b, 9 + +.next4 + ld a, [$ff92] ; a = distance adjusted using sprite i's direction + sub b ; adjust distance using sprite j's direction + jr z, .collision + jr nc, .next ; go to next sprite if distance is still positive after both adjustments + +.collision + ld a, [$ff91] ; a = 7 or 9 depending on sprite i's delta X + ld b, a + ld a, [$ff90] ; a = 7 or 9 depending on sprite i's delta Y + inc l + +; If delta X isn't 0 and delta Y is 0, then b = %0011, else b = %1100. +; (note that normally if delta X isn't 0, then delta Y must be 0 and vice versa) + cp b + jr c, .next5 + ld b, %1100 + jr .next6 +.next5 + ld b, %0011 + +.next6 + ld a, c ; c has 2 bits set (one of bits 0-1 is set for the X axis and one of bits 2-3 for the Y axis) + and b ; we select either the bit in bits 0-1 or bits 2-3 based on the calculation immediately above + or [hl] ; or with existing collision direction bits in [$c1ic] + ld [hl], a ; store new value + ld a, c ; useless code because a is overwritten before being used again + +; set bit in [$c1ie] or [$c1if] to indicate which sprite the collision occurred with + inc l + inc l + ld a, [$ff8f] ; a = loop counter + ld de, SpriteCollisionBitTable + add a + add e + ld e, a + jr nc, .noCarry3 + inc d +.noCarry3 + ld a, [de] + or [hl] + ld [hli], a + inc de + ld a, [de] + or [hl] + ld [hl], a + +.next + ld a, [$ff8f] ; a = loop counter + inc a + cp $10 + jp nz, .loop + ret + +; takes delta X or delta Y in a +; b = delta X/Y +; c = 0 if delta X/Y is 0 +; c = 7 if delta X/Y is 1 +; c = 9 if delta X/Y is -1 +SetSpriteCollisionValues: + and a + ld b, 0 + ld c, 0 + jr z, .done + ld c, 9 + cp -1 + jr z, .ok + ld c, 7 + ld a, 0 +.ok + ld b, a +.done + ret + +SpriteCollisionBitTable: + db %00000000,%00000001 + db %00000000,%00000010 + db %00000000,%00000100 + db %00000000,%00001000 + db %00000000,%00010000 + db %00000000,%00100000 + db %00000000,%01000000 + db %00000000,%10000000 + db %00000001,%00000000 + db %00000010,%00000000 + db %00000100,%00000000 + db %00001000,%00000000 + db %00010000,%00000000 + db %00100000,%00000000 + db %01000000,%00000000 + db %10000000,%00000000 diff --git a/engine/print_waiting_text.asm b/engine/print_waiting_text.asm new file mode 100644 index 00000000..7a95da2a --- /dev/null +++ b/engine/print_waiting_text.asm @@ -0,0 +1,20 @@ +PrintWaitingText: + coord hl, 3, 10 + ld b, $1 + ld c, $b + ld a, [wIsInBattle] + and a + jr z, .asm_4c17 + call TextBoxBorder + jr .asm_4c1a +.asm_4c17 + call CableClub_TextBoxBorder +.asm_4c1a + coord hl, 4, 11 + ld de, WaitingText + call PlaceString + ld c, 50 + jp DelayFrames + +WaitingText: + db "Waiting...!@" diff --git a/engine/test_battle.asm b/engine/test_battle.asm new file mode 100644 index 00000000..d9dcf1fa --- /dev/null +++ b/engine/test_battle.asm @@ -0,0 +1,45 @@ +TestBattle: + ret + +.loop + call GBPalNormal + + ; Don't mess around + ; with obedience. + ld a, %10000000 ; EARTHBADGE + ld [wObtainedBadges], a + + ld hl, wFlags_D733 + set BIT_TEST_BATTLE, [hl] + + ; Reset the party. + ld hl, wPartyCount + xor a + ld [hli], a + dec a + ld [hl], a + + ; Give the player a + ; level 20 Rhydon. + ld a, RHYDON + ld [wcf91], a + ld a, 20 + ld [wCurEnemyLVL], a + xor a + ld [wMonDataLocation], a + ld [wCurMap], a + call AddPartyMon + + ; Fight against a + ; level 20 Rhydon. + ld a, RHYDON + ld [wCurOpponent], a + + predef InitOpponent + + ; When the battle ends, + ; do it all again. + ld a, 1 + ld [wUpdateSpritesEnabled], a + ld [H_AUTOBGTRANSFERENABLED], a + jr .loop diff --git a/engine/titlescreen.asm b/engine/titlescreen.asm index e1a6e015..f4cce5b4 100755 --- a/engine/titlescreen.asm +++ b/engine/titlescreen.asm @@ -398,3 +398,6 @@ ENDC IF DEF(_BLUE) db $61,$62,$63,$64,$65,$66,$67,$68,"@" ; "Blue Version" ENDC + +NintenText: db "NINTEN@" +SonyText: db "SONY@" -- cgit v1.2.3 From c2381bb3e624e966c323610df762a299468a1728 Mon Sep 17 00:00:00 2001 From: YamaArashi Date: Sat, 17 Sep 2016 18:17:57 -0700 Subject: split bank 1 into files --- engine/black_out.asm | 46 ++ engine/debug1.asm | 33 ++ engine/display_pokedex.asm | 19 + engine/display_text_id_init.asm | 78 ++++ engine/menu/draw_start_menu.asm | 89 ++++ engine/menu/swap_items.asm | 149 +++++++ engine/menu/text_box.asm | 767 ++++++++++++++++++++++++++++++++++ engine/overworld/set_blackout_map.asm | 29 ++ engine/remove_pokemon.asm | 95 +++++ engine/special_warps.asm | 149 +++++++ engine/subtract_paid_money.asm | 17 + 11 files changed, 1471 insertions(+) create mode 100644 engine/black_out.asm create mode 100644 engine/debug1.asm create mode 100644 engine/display_pokedex.asm create mode 100644 engine/display_text_id_init.asm create mode 100644 engine/menu/draw_start_menu.asm create mode 100644 engine/menu/swap_items.asm create mode 100644 engine/menu/text_box.asm create mode 100644 engine/overworld/set_blackout_map.asm create mode 100644 engine/remove_pokemon.asm create mode 100644 engine/special_warps.asm create mode 100644 engine/subtract_paid_money.asm (limited to 'engine') diff --git a/engine/black_out.asm b/engine/black_out.asm new file mode 100644 index 00000000..6c358ce3 --- /dev/null +++ b/engine/black_out.asm @@ -0,0 +1,46 @@ +ResetStatusAndHalveMoneyOnBlackout:: +; Reset player status on blackout. + xor a + ld [wBattleResult], a + ld [wWalkBikeSurfState], a + ld [wIsInBattle], a + ld [wMapPalOffset], a + ld [wNPCMovementScriptFunctionNum], a + ld [hJoyHeld], a + ld [wNPCMovementScriptPointerTableNum], a + ld [wFlags_0xcd60], a + + ld [hMoney], a + ld [hMoney + 1], a + ld [hMoney + 2], a + call HasEnoughMoney + jr c, .lostmoney ; never happens + + ; Halve the player's money. + ld a, [wPlayerMoney] + ld [hMoney], a + ld a, [wPlayerMoney + 1] + ld [hMoney + 1], a + ld a, [wPlayerMoney + 2] + ld [hMoney + 2], a + xor a + ld [hDivideBCDDivisor], a + ld [hDivideBCDDivisor + 1], a + ld a, 2 + ld [hDivideBCDDivisor + 2], a + predef DivideBCDPredef3 + ld a, [hDivideBCDQuotient] + ld [wPlayerMoney], a + ld a, [hDivideBCDQuotient + 1] + ld [wPlayerMoney + 1], a + ld a, [hDivideBCDQuotient + 2] + ld [wPlayerMoney + 2], a + +.lostmoney + ld hl, wd732 + set 2, [hl] + res 3, [hl] + set 6, [hl] + ld a, %11111111 + ld [wJoyIgnore], a + predef_jump HealParty diff --git a/engine/debug1.asm b/engine/debug1.asm new file mode 100644 index 00000000..a5eb7dde --- /dev/null +++ b/engine/debug1.asm @@ -0,0 +1,33 @@ +; This function appears to never be used. +; It is likely a debugging feature to give the player Tsunekazu Ishihara's +; favorite Pokemon. This is indicated by the overpowered Exeggutor, which +; Ishihara (president of Creatures Inc.) said was his favorite Pokemon in an ABC +; interview on February 8, 2000. +; "Exeggutor is my favorite. That's because I was always using this character +; while I was debugging the program." +; http://www.ign.com/articles/2000/02/09/abc-news-pokamon-chat-transcript + +SetIshiharaTeam: + ld de, IshiharaTeam +.loop + ld a, [de] + cp $ff + ret z + ld [wcf91], a + inc de + ld a, [de] + ld [wCurEnemyLVL], a + inc de + call AddPartyMon + jr .loop + +IshiharaTeam: + db EXEGGUTOR,90 + db MEW,20 + db JOLTEON,56 + db DUGTRIO,56 + db ARTICUNO,57 + db $FF + +EmptyFunc: + ret diff --git a/engine/display_pokedex.asm b/engine/display_pokedex.asm new file mode 100644 index 00000000..96a2dd6c --- /dev/null +++ b/engine/display_pokedex.asm @@ -0,0 +1,19 @@ +_DisplayPokedex: + ld hl, wd730 + set 6, [hl] + predef ShowPokedexData + ld hl, wd730 + res 6, [hl] + call ReloadMapData + ld c, 10 + call DelayFrames + predef IndexToPokedex + ld a, [wd11e] + dec a + ld c, a + ld b, FLAG_SET + ld hl, wPokedexSeen + predef FlagActionPredef + ld a, $1 + ld [wDoNotWaitForButtonPressAfterDisplayingText], a + ret diff --git a/engine/display_text_id_init.asm b/engine/display_text_id_init.asm new file mode 100644 index 00000000..312d6329 --- /dev/null +++ b/engine/display_text_id_init.asm @@ -0,0 +1,78 @@ +; function that performs initialization for DisplayTextID +DisplayTextIDInit: + xor a + ld [wListMenuID],a + ld a,[wAutoTextBoxDrawingControl] + bit 0,a + jr nz,.skipDrawingTextBoxBorder + ld a,[hSpriteIndexOrTextID] ; text ID (or sprite ID) + and a + jr nz,.notStartMenu +; if text ID is 0 (i.e. the start menu) +; Note that the start menu text border is also drawn in the function directly +; below this, so this seems unnecessary. + CheckEvent EVENT_GOT_POKEDEX +; start menu with pokedex + coord hl, 10, 0 + ld b,$0e + ld c,$08 + jr nz,.drawTextBoxBorder +; start menu without pokedex + coord hl, 10, 0 + ld b,$0c + ld c,$08 + jr .drawTextBoxBorder +; if text ID is not 0 (i.e. not the start menu) then do a standard dialogue text box +.notStartMenu + coord hl, 0, 12 + ld b,$04 + ld c,$12 +.drawTextBoxBorder + call TextBoxBorder +.skipDrawingTextBoxBorder + ld hl,wFontLoaded + set 0,[hl] + ld hl,wFlags_0xcd60 + bit 4,[hl] + res 4,[hl] + jr nz,.skipMovingSprites + call UpdateSprites +.skipMovingSprites +; loop to copy C1X9 (direction the sprite is facing) to C2X9 for each sprite +; this is done because when you talk to an NPC, they turn to look your way +; the original direction they were facing must be restored after the dialogue is over + ld hl,wSpriteStateData1 + $19 + ld c,$0f + ld de,$0010 +.spriteFacingDirectionCopyLoop + ld a,[hl] + inc h + ld [hl],a + dec h + add hl,de + dec c + jr nz,.spriteFacingDirectionCopyLoop +; loop to force all the sprites in the middle of animation to stand still +; (so that they don't like they're frozen mid-step during the dialogue) + ld hl,wSpriteStateData1 + 2 + ld de,$0010 + ld c,e +.spriteStandStillLoop + ld a,[hl] + cp a,$ff ; is the sprite visible? + jr z,.nextSprite +; if it is visible + and a,$fc + ld [hl],a +.nextSprite + add hl,de + dec c + jr nz,.spriteStandStillLoop + ld b,$9c ; window background address + call CopyScreenTileBufferToVRAM ; transfer background in WRAM to VRAM + xor a + ld [hWY],a ; put the window on the screen + call LoadFontTilePatterns + ld a,$01 + ld [H_AUTOBGTRANSFERENABLED],a ; enable continuous WRAM to VRAM transfer each V-blank + ret diff --git a/engine/menu/draw_start_menu.asm b/engine/menu/draw_start_menu.asm new file mode 100644 index 00000000..4df9de27 --- /dev/null +++ b/engine/menu/draw_start_menu.asm @@ -0,0 +1,89 @@ +; function that displays the start menu +DrawStartMenu: + CheckEvent EVENT_GOT_POKEDEX +; menu with pokedex + coord hl, 10, 0 + ld b,$0e + ld c,$08 + jr nz,.drawTextBoxBorder +; shorter menu if the player doesn't have the pokedex + coord hl, 10, 0 + ld b,$0c + ld c,$08 +.drawTextBoxBorder + call TextBoxBorder + ld a,D_DOWN | D_UP | START | B_BUTTON | A_BUTTON + ld [wMenuWatchedKeys],a + ld a,$02 + ld [wTopMenuItemY],a ; Y position of first menu choice + ld a,$0b + ld [wTopMenuItemX],a ; X position of first menu choice + ld a,[wBattleAndStartSavedMenuItem] ; remembered menu selection from last time + ld [wCurrentMenuItem],a + ld [wLastMenuItem],a + xor a + ld [wMenuWatchMovingOutOfBounds],a + ld hl,wd730 + set 6,[hl] ; no pauses between printing each letter + coord hl, 12, 2 + CheckEvent EVENT_GOT_POKEDEX +; case for not having pokdex + ld a,$06 + jr z,.storeMenuItemCount +; case for having pokedex + ld de,StartMenuPokedexText + call PrintStartMenuItem + ld a,$07 +.storeMenuItemCount + ld [wMaxMenuItem],a ; number of menu items + ld de,StartMenuPokemonText + call PrintStartMenuItem + ld de,StartMenuItemText + call PrintStartMenuItem + ld de,wPlayerName ; player's name + call PrintStartMenuItem + ld a,[wd72e] + bit 6,a ; is the player using the link feature? +; case for not using link feature + ld de,StartMenuSaveText + jr z,.printSaveOrResetText +; case for using link feature + ld de,StartMenuResetText +.printSaveOrResetText + call PrintStartMenuItem + ld de,StartMenuOptionText + call PrintStartMenuItem + ld de,StartMenuExitText + call PlaceString + ld hl,wd730 + res 6,[hl] ; turn pauses between printing letters back on + ret + +StartMenuPokedexText: + db "POKéDEX@" + +StartMenuPokemonText: + db "POKéMON@" + +StartMenuItemText: + db "ITEM@" + +StartMenuSaveText: + db "SAVE@" + +StartMenuResetText: + db "RESET@" + +StartMenuExitText: + db "EXIT@" + +StartMenuOptionText: + db "OPTION@" + +PrintStartMenuItem: + push hl + call PlaceString + pop hl + ld de,SCREEN_WIDTH * 2 + add hl,de + ret diff --git a/engine/menu/swap_items.asm b/engine/menu/swap_items.asm new file mode 100644 index 00000000..b1fa78be --- /dev/null +++ b/engine/menu/swap_items.asm @@ -0,0 +1,149 @@ +HandleItemListSwapping: + ld a,[wListMenuID] + cp a,ITEMLISTMENU + jp nz,DisplayListMenuIDLoop ; only rearrange item list menus + push hl + ld hl,wListPointer + ld a,[hli] + ld h,[hl] + ld l,a + inc hl ; hl = beginning of list entries + ld a,[wCurrentMenuItem] + ld b,a + ld a,[wListScrollOffset] + add b + add a + ld c,a + ld b,0 + add hl,bc ; hl = address of currently selected item entry + ld a,[hl] + pop hl + inc a + jp z,DisplayListMenuIDLoop ; ignore attempts to swap the Cancel menu item + ld a,[wMenuItemToSwap] ; ID of item chosen for swapping (counts from 1) + and a ; has the first item to swap already been chosen? + jr nz,.swapItems +; if not, set the currently selected item as the first item + ld a,[wCurrentMenuItem] + inc a + ld b,a + ld a,[wListScrollOffset] ; index of top (visible) menu item within the list + add b + ld [wMenuItemToSwap],a ; ID of item chosen for swapping (counts from 1) + ld c,20 + call DelayFrames + jp DisplayListMenuIDLoop +.swapItems + ld a,[wCurrentMenuItem] + inc a + ld b,a + ld a,[wListScrollOffset] + add b + ld b,a + ld a,[wMenuItemToSwap] ; ID of item chosen for swapping (counts from 1) + cp b ; is the currently selected item the same as the first item to swap? + jp z,DisplayListMenuIDLoop ; ignore attempts to swap an item with itself + dec a + ld [wMenuItemToSwap],a ; ID of item chosen for swapping (counts from 1) + ld c,20 + call DelayFrames + push hl + push de + ld hl,wListPointer + ld a,[hli] + ld h,[hl] + ld l,a + inc hl ; hl = beginning of list entries + ld d,h + ld e,l ; de = beginning of list entries + ld a,[wCurrentMenuItem] + ld b,a + ld a,[wListScrollOffset] + add b + add a + ld c,a + ld b,0 + add hl,bc ; hl = address of currently selected item entry + ld a,[wMenuItemToSwap] ; ID of item chosen for swapping (counts from 1) + add a + add e + ld e,a + jr nc,.noCarry + inc d +.noCarry ; de = address of first item to swap + ld a,[de] + ld b,a + ld a,[hli] + cp b + jr z,.swapSameItemType +.swapDifferentItems + ld [$ff95],a ; [$ff95] = second item ID + ld a,[hld] + ld [$ff96],a ; [$ff96] = second item quantity + ld a,[de] + ld [hli],a ; put first item ID in second item slot + inc de + ld a,[de] + ld [hl],a ; put first item quantity in second item slot + ld a,[$ff96] + ld [de],a ; put second item quantity in first item slot + dec de + ld a,[$ff95] + ld [de],a ; put second item ID in first item slot + xor a + ld [wMenuItemToSwap],a ; 0 means no item is currently being swapped + pop de + pop hl + jp DisplayListMenuIDLoop +.swapSameItemType + inc de + ld a,[hl] + ld b,a + ld a,[de] + add b ; a = sum of both item quantities + cp a,100 ; is the sum too big for one item slot? + jr c,.combineItemSlots +; swap enough items from the first slot to max out the second slot if they can't be combined + sub a,99 + ld [de],a + ld a,99 + ld [hl],a + jr .done +.combineItemSlots + ld [hl],a ; put the sum in the second item slot + ld hl,wListPointer + ld a,[hli] + ld h,[hl] + ld l,a + dec [hl] ; decrease the number of items + ld a,[hl] + ld [wListCount],a ; update number of items variable + cp a,1 + jr nz,.skipSettingMaxMenuItemID + ld [wMaxMenuItem],a ; if the number of items is only one now, update the max menu item ID +.skipSettingMaxMenuItemID + dec de + ld h,d + ld l,e + inc hl + inc hl ; hl = address of item after first item to swap +.moveItemsUpLoop ; erase the first item slot and move up all the following item slots to fill the gap + ld a,[hli] + ld [de],a + inc de + inc a ; reached the $ff terminator? + jr z,.afterMovingItemsUp + ld a,[hli] + ld [de],a + inc de + jr .moveItemsUpLoop +.afterMovingItemsUp + xor a + ld [wListScrollOffset],a + ld [wCurrentMenuItem],a +.done + xor a + ld [wMenuItemToSwap],a ; 0 means no item is currently being swapped + pop de + pop hl + jp DisplayListMenuIDLoop diff --git a/engine/menu/text_box.asm b/engine/menu/text_box.asm new file mode 100644 index 00000000..12067dd4 --- /dev/null +++ b/engine/menu/text_box.asm @@ -0,0 +1,767 @@ +; function to draw various text boxes +DisplayTextBoxID_: + ld a,[wTextBoxID] + cp a,TWO_OPTION_MENU + jp z,DisplayTwoOptionMenu + ld c,a + ld hl,TextBoxFunctionTable + ld de,3 + call SearchTextBoxTable + jr c,.functionTableMatch + ld hl,TextBoxCoordTable + ld de,5 + call SearchTextBoxTable + jr c,.coordTableMatch + ld hl,TextBoxTextAndCoordTable + ld de,9 + call SearchTextBoxTable + jr c,.textAndCoordTableMatch +.done + ret +.functionTableMatch + ld a,[hli] + ld h,[hl] + ld l,a ; hl = address of function + ld de,.done + push de + jp [hl] ; jump to the function +.coordTableMatch + call GetTextBoxIDCoords + call GetAddressOfScreenCoords + call TextBoxBorder + ret +.textAndCoordTableMatch + call GetTextBoxIDCoords + push hl + call GetAddressOfScreenCoords + call TextBoxBorder + pop hl + call GetTextBoxIDText + ld a,[wd730] + push af + ld a,[wd730] + set 6,a ; no pauses between printing each letter + ld [wd730],a + call PlaceString + pop af + ld [wd730],a + call UpdateSprites + ret + +; function to search a table terminated with $ff for a byte matching c in increments of de +; sets carry flag if a match is found and clears carry flag if not +SearchTextBoxTable: + dec de +.loop + ld a,[hli] + cp a,$ff + jr z,.notFound + cp c + jr z,.found + add hl,de + jr .loop +.found + scf +.notFound + ret + +; function to load coordinates from the TextBoxCoordTable or the TextBoxTextAndCoordTable +; INPUT: +; hl = address of coordinates +; OUTPUT: +; b = height +; c = width +; d = row of upper left corner +; e = column of upper left corner +GetTextBoxIDCoords: + ld a,[hli] ; column of upper left corner + ld e,a + ld a,[hli] ; row of upper left corner + ld d,a + ld a,[hli] ; column of lower right corner + sub e + dec a + ld c,a ; c = width + ld a,[hli] ; row of lower right corner + sub d + dec a + ld b,a ; b = height + ret + +; function to load a text address and text coordinates from the TextBoxTextAndCoordTable +GetTextBoxIDText: + ld a,[hli] + ld e,a + ld a,[hli] + ld d,a ; de = address of text + push de ; save text address + ld a,[hli] + ld e,a ; column of upper left corner of text + ld a,[hl] + ld d,a ; row of upper left corner of text + call GetAddressOfScreenCoords + pop de ; restore text address + ret + +; function to point hl to the screen coordinates +; INPUT: +; d = row +; e = column +; OUTPUT: +; hl = address of upper left corner of text box +GetAddressOfScreenCoords: + push bc + coord hl, 0, 0 + ld bc,20 +.loop ; loop to add d rows to the base address + ld a,d + and a + jr z,.addedRows + add hl,bc + dec d + jr .loop +.addedRows + pop bc + add hl,de + ret + +; Format: +; 00: text box ID +; 01-02: function address +TextBoxFunctionTable: + dbw MONEY_BOX, DisplayMoneyBox + dbw BUY_SELL_QUIT_MENU, DoBuySellQuitMenu + dbw FIELD_MOVE_MON_MENU, DisplayFieldMoveMonMenu + db $ff ; terminator + +; Format: +; 00: text box ID +; 01: column of upper left corner +; 02: row of upper left corner +; 03: column of lower right corner +; 04: row of lower right corner +TextBoxCoordTable: + db MESSAGE_BOX, 0, 12, 19, 17 + db $03, 0, 0, 19, 14 + db $07, 0, 0, 11, 6 + db LIST_MENU_BOX, 4, 2, 19, 12 + db $10, 7, 0, 19, 17 + db MON_SPRITE_POPUP, 6, 4, 14, 13 + db $ff ; terminator + +; Format: +; 00: text box ID +; 01: column of upper left corner +; 02: row of upper left corner +; 03: column of lower right corner +; 04: row of lower right corner +; 05-06: address of text +; 07: column of beginning of text +; 08: row of beginning of text +; table of window positions and corresponding text [key, start column, start row, end column, end row, text pointer [2 bytes], text column, text row] +TextBoxTextAndCoordTable: + db JP_MOCHIMONO_MENU_TEMPLATE + db 0,0,14,17 ; text box coordinates + dw JapaneseMochimonoText + db 3,0 ; text coordinates + + db USE_TOSS_MENU_TEMPLATE + db 13,10,19,14 ; text box coordinates + dw UseTossText + db 15,11 ; text coordinates + + db JP_SAVE_MESSAGE_MENU_TEMPLATE + db 0,0,7,5 ; text box coordinates + dw JapaneseSaveMessageText + db 2,2 ; text coordinates + + db JP_SPEED_OPTIONS_MENU_TEMPLATE + db 0,6,5,10 ; text box coordinates + dw JapaneseSpeedOptionsText + db 2,7 ; text coordinates + + db BATTLE_MENU_TEMPLATE + db 8,12,19,17 ; text box coordinates + dw BattleMenuText + db 10,14 ; text coordinates + + db SAFARI_BATTLE_MENU_TEMPLATE + db 0,12,19,17 ; text box coordinates + dw SafariZoneBattleMenuText + db 2,14 ; text coordinates + + db SWITCH_STATS_CANCEL_MENU_TEMPLATE + db 11,11,19,17 ; text box coordinates + dw SwitchStatsCancelText + db 13,12 ; text coordinates + + db BUY_SELL_QUIT_MENU_TEMPLATE + db 0,0,10,6 ; text box coordinates + dw BuySellQuitText + db 2,1 ; text coordinates + + db MONEY_BOX_TEMPLATE + db 11,0,19,2 ; text box coordinates + dw MoneyText + db 13,0 ; text coordinates + + db JP_AH_MENU_TEMPLATE + db 7,6,11,10 ; text box coordinates + dw JapaneseAhText + db 8,8 ; text coordinates + + db JP_POKEDEX_MENU_TEMPLATE + db 11,8,19,17 ; text box coordinates + dw JapanesePokedexMenu + db 12,10 ; text coordinates + +; note that there is no terminator + +BuySellQuitText: + db "BUY" + next "SELL" + next "QUIT@@" + +UseTossText: + db "USE" + next "TOSS@" + +JapaneseSaveMessageText: + db "きろく" + next "メッセージ@" + +JapaneseSpeedOptionsText: + db "はやい" + next "おそい@" + +MoneyText: + db "MONEY@" + +JapaneseMochimonoText: + db "もちもの@" + +JapaneseMainMenuText: + db "つづきから" + next "さいしょから@" + +BattleMenuText: + db "FIGHT ",$E1,$E2 + next "ITEM RUN@" + +SafariZoneBattleMenuText: + db "BALL× BAIT" + next "THROW ROCK RUN@" + +SwitchStatsCancelText: + db "SWITCH" + next "STATS" + next "CANCEL@" + +JapaneseAhText: + db "アッ!@" + +JapanesePokedexMenu: + db "データをみる" + next "なきごえ" + next "ぶんぷをみる" + next "キャンセル@" + +DisplayMoneyBox: + ld hl, wd730 + set 6, [hl] + ld a, MONEY_BOX_TEMPLATE + ld [wTextBoxID], a + call DisplayTextBoxID + coord hl, 13, 1 + ld b, 1 + ld c, 6 + call ClearScreenArea + coord hl, 12, 1 + ld de, wPlayerMoney + ld c, $a3 + call PrintBCDNumber + ld hl, wd730 + res 6, [hl] + ret + +CurrencyString: + db " ¥@" + +DoBuySellQuitMenu: + ld a, [wd730] + set 6, a ; no printing delay + ld [wd730], a + xor a + ld [wChosenMenuItem], a + ld a, BUY_SELL_QUIT_MENU_TEMPLATE + ld [wTextBoxID], a + call DisplayTextBoxID + ld a, A_BUTTON | B_BUTTON + ld [wMenuWatchedKeys], a + ld a, $2 + ld [wMaxMenuItem], a + ld a, $1 + ld [wTopMenuItemY], a + ld a, $1 + ld [wTopMenuItemX], a + xor a + ld [wCurrentMenuItem], a + ld [wLastMenuItem], a + ld [wMenuWatchMovingOutOfBounds], a + ld a, [wd730] + res 6, a ; turn on the printing delay + ld [wd730], a + call HandleMenuInput + call PlaceUnfilledArrowMenuCursor + bit 0, a ; was A pressed? + jr nz, .pressedA + bit 1, a ; was B pressed? (always true since only A/B are watched) + jr z, .pressedA + ld a, CANCELLED_MENU + ld [wMenuExitMethod], a + jr .quit +.pressedA + ld a, CHOSE_MENU_ITEM + ld [wMenuExitMethod], a + ld a, [wCurrentMenuItem] + ld [wChosenMenuItem], a + ld b, a + ld a, [wMaxMenuItem] + cp b + jr z, .quit + ret +.quit + ld a, CANCELLED_MENU + ld [wMenuExitMethod], a + ld a, [wCurrentMenuItem] + ld [wChosenMenuItem], a + scf + ret + +; displays a menu with two options to choose from +; b = Y of upper left corner of text region +; c = X of upper left corner of text region +; hl = address where the text box border should be drawn +DisplayTwoOptionMenu: + push hl + ld a, [wd730] + set 6, a ; no printing delay + ld [wd730], a + +; pointless because both values are overwritten before they are read + xor a + ld [wChosenMenuItem], a + ld [wMenuExitMethod], a + + ld a, A_BUTTON | B_BUTTON + ld [wMenuWatchedKeys], a + ld a, $1 + ld [wMaxMenuItem], a + ld a, b + ld [wTopMenuItemY], a + ld a, c + ld [wTopMenuItemX], a + xor a + ld [wLastMenuItem], a + ld [wMenuWatchMovingOutOfBounds], a + push hl + ld hl, wTwoOptionMenuID + bit 7, [hl] ; select second menu item by default? + res 7, [hl] + jr z, .storeCurrentMenuItem + inc a +.storeCurrentMenuItem + ld [wCurrentMenuItem], a + pop hl + push hl + push hl + call TwoOptionMenu_SaveScreenTiles + ld a, [wTwoOptionMenuID] + ld hl, TwoOptionMenuStrings + ld e, a + ld d, $0 + ld a, $5 +.menuStringLoop + add hl, de + dec a + jr nz, .menuStringLoop + ld a, [hli] + ld c, a + ld a, [hli] + ld b, a + ld e, l + ld d, h + pop hl + push de + ld a, [wTwoOptionMenuID] + cp TRADE_CANCEL_MENU + jr nz, .notTradeCancelMenu + call CableClub_TextBoxBorder + jr .afterTextBoxBorder +.notTradeCancelMenu + call TextBoxBorder +.afterTextBoxBorder + call UpdateSprites + pop hl + ld a, [hli] + and a ; put blank line before first menu item? + ld bc, 20 + 2 + jr z, .noBlankLine + ld bc, 2 * 20 + 2 +.noBlankLine + ld a, [hli] + ld e, a + ld a, [hli] + ld d, a + pop hl + add hl, bc + call PlaceString + ld hl, wd730 + res 6, [hl] ; turn on the printing delay + ld a, [wTwoOptionMenuID] + cp NO_YES_MENU + jr nz, .notNoYesMenu +; No/Yes menu +; this menu type ignores the B button +; it only seems to be used when confirming the deletion of a save file + xor a + ld [wTwoOptionMenuID], a + ld a, [wFlags_0xcd60] + push af + push hl + ld hl, wFlags_0xcd60 + bit 5, [hl] + set 5, [hl] ; don't play sound when A or B is pressed in menu + pop hl +.noYesMenuInputLoop + call HandleMenuInput + bit 1, a ; A button pressed? + jr nz, .noYesMenuInputLoop ; try again if A was not pressed + pop af + pop hl + ld [wFlags_0xcd60], a + ld a, SFX_PRESS_AB + call PlaySound + jr .pressedAButton +.notNoYesMenu + xor a + ld [wTwoOptionMenuID], a + call HandleMenuInput + pop hl + bit 1, a ; A button pressed? + jr nz, .choseSecondMenuItem ; automatically choose the second option if B is pressed +.pressedAButton + ld a, [wCurrentMenuItem] + ld [wChosenMenuItem], a + and a + jr nz, .choseSecondMenuItem +; chose first menu item + ld a, CHOSE_FIRST_ITEM + ld [wMenuExitMethod], a + ld c, 15 + call DelayFrames + call TwoOptionMenu_RestoreScreenTiles + and a + ret +.choseSecondMenuItem + ld a, 1 + ld [wCurrentMenuItem], a + ld [wChosenMenuItem], a + ld a, CHOSE_SECOND_ITEM + ld [wMenuExitMethod], a + ld c, 15 + call DelayFrames + call TwoOptionMenu_RestoreScreenTiles + scf + ret + +; Some of the wider/taller two option menus will not have the screen areas +; they cover be fully saved/restored by the two functions below. +; The bottom and right edges of the menu may remain after the function returns. + +TwoOptionMenu_SaveScreenTiles: + ld de, wBuffer + lb bc, 5, 6 +.loop + ld a, [hli] + ld [de], a + inc de + dec c + jr nz, .loop + push bc + ld bc, SCREEN_WIDTH - 6 + add hl, bc + pop bc + ld c, $6 + dec b + jr nz, .loop + ret + +TwoOptionMenu_RestoreScreenTiles: + ld de, wBuffer + lb bc, 5, 6 +.loop + ld a, [de] + inc de + ld [hli], a + dec c + jr nz, .loop + push bc + ld bc, SCREEN_WIDTH - 6 + add hl, bc + pop bc + ld c, 6 + dec b + jr nz, .loop + call UpdateSprites + ret + +; Format: +; 00: byte width +; 01: byte height +; 02: byte put blank line before first menu item +; 03: word text pointer +TwoOptionMenuStrings: + db 4,3,0 + dw .YesNoMenu + db 6,3,0 + dw .NorthWestMenu + db 6,3,0 + dw .SouthEastMenu + db 6,3,0 + dw .YesNoMenu + db 6,3,0 + dw .NorthEastMenu + db 7,3,0 + dw .TradeCancelMenu + db 7,4,1 + dw .HealCancelMenu + db 4,3,0 + dw .NoYesMenu + +.NoYesMenu + db "NO" + next "YES@" +.YesNoMenu + db "YES" + next "NO@" +.NorthWestMenu + db "NORTH" + next "WEST@" +.SouthEastMenu + db "SOUTH" + next "EAST@" +.NorthEastMenu + db "NORTH" + next "EAST@" +.TradeCancelMenu + db "TRADE" + next "CANCEL@" +.HealCancelMenu + db "HEAL" + next "CANCEL@" + +DisplayFieldMoveMonMenu: + xor a + ld hl, wFieldMoves + ld [hli], a ; wFieldMoves + ld [hli], a ; wFieldMoves + 1 + ld [hli], a ; wFieldMoves + 2 + ld [hli], a ; wFieldMoves + 3 + ld [hli], a ; wNumFieldMoves + ld [hl], 12 ; wFieldMovesLeftmostXCoord + call GetMonFieldMoves + ld a, [wNumFieldMoves] + and a + jr nz, .fieldMovesExist + +; no field moves + coord hl, 11, 11 + ld b, 5 + ld c, 7 + call TextBoxBorder + call UpdateSprites + ld a, 12 + ld [hFieldMoveMonMenuTopMenuItemX], a + coord hl, 13, 12 + ld de, PokemonMenuEntries + jp PlaceString + +.fieldMovesExist + push af + +; Calculate the text box position and dimensions based on the leftmost X coord +; of the field move names before adjusting for the number of field moves. + coord hl, 0, 11 + ld a, [wFieldMovesLeftmostXCoord] + dec a + ld e, a + ld d, 0 + add hl, de + ld b, 5 + ld a, 18 + sub e + ld c, a + pop af + +; For each field move, move the top of the text box up 2 rows while the leaving +; the bottom of the text box at the bottom of the screen. + ld de, -SCREEN_WIDTH * 2 +.textBoxHeightLoop + add hl, de + inc b + inc b + dec a + jr nz, .textBoxHeightLoop + +; Make space for an extra blank row above the top field move. + ld de, -SCREEN_WIDTH + add hl, de + inc b + + call TextBoxBorder + call UpdateSprites + +; Calculate the position of the first field move name to print. + coord hl, 0, 12 + ld a, [wFieldMovesLeftmostXCoord] + inc a + ld e, a + ld d, 0 + add hl, de + ld de, -SCREEN_WIDTH * 2 + ld a, [wNumFieldMoves] +.calcFirstFieldMoveYLoop + add hl, de + dec a + jr nz, .calcFirstFieldMoveYLoop + + xor a + ld [wNumFieldMoves], a + ld de, wFieldMoves +.printNamesLoop + push hl + ld hl, FieldMoveNames + ld a, [de] + and a + jr z, .donePrintingNames + inc de + ld b, a ; index of name +.skipNamesLoop ; skip past names before the name we want + dec b + jr z, .reachedName +.skipNameLoop ; skip past current name + ld a, [hli] + cp "@" + jr nz, .skipNameLoop + jr .skipNamesLoop +.reachedName + ld b, h + ld c, l + pop hl + push de + ld d, b + ld e, c + call PlaceString + ld bc, SCREEN_WIDTH * 2 + add hl, bc + pop de + jr .printNamesLoop + +.donePrintingNames + pop hl + ld a, [wFieldMovesLeftmostXCoord] + ld [hFieldMoveMonMenuTopMenuItemX], a + coord hl, 0, 12 + ld a, [wFieldMovesLeftmostXCoord] + inc a + ld e, a + ld d, 0 + add hl, de + ld de, PokemonMenuEntries + jp PlaceString + +FieldMoveNames: + db "CUT@" + db "FLY@" + db "@" + db "SURF@" + db "STRENGTH@" + db "FLASH@" + db "DIG@" + db "TELEPORT@" + db "SOFTBOILED@" + +PokemonMenuEntries: + db "STATS" + next "SWITCH" + next "CANCEL@" + +GetMonFieldMoves: + ld a, [wWhichPokemon] + ld hl, wPartyMon1Moves + ld bc, wPartyMon2 - wPartyMon1 + call AddNTimes + ld d, h + ld e, l + ld c, NUM_MOVES + 1 + ld hl, wFieldMoves +.loop + push hl +.nextMove + dec c + jr z, .done + ld a, [de] ; move ID + and a + jr z, .done + ld b, a + inc de + ld hl, FieldMoveDisplayData +.fieldMoveLoop + ld a, [hli] + cp $ff + jr z, .nextMove ; if the move is not a field move + cp b + jr z, .foundFieldMove + inc hl + inc hl + jr .fieldMoveLoop +.foundFieldMove + ld a, b + ld [wLastFieldMoveID], a + ld a, [hli] ; field move name index + ld b, [hl] ; field move leftmost X coordinate + pop hl + ld [hli], a ; store name index in wFieldMoves + ld a, [wNumFieldMoves] + inc a + ld [wNumFieldMoves], a + ld a, [wFieldMovesLeftmostXCoord] + cp b + jr c, .skipUpdatingLeftmostXCoord + ld a, b + ld [wFieldMovesLeftmostXCoord], a +.skipUpdatingLeftmostXCoord + ld a, [wLastFieldMoveID] + ld b, a + jr .loop +.done + pop hl + ret + +; Format: [Move id], [name index], [leftmost tile] +; Move id = id of move +; Name index = index of name in FieldMoveNames +; Leftmost tile = -1 + tile column in which the first letter of the move's name should be displayed +; "SOFTBOILED" is $08 because it has 4 more letters than "SURF", for example, whose value is $0C +FieldMoveDisplayData: + db CUT, $01, $0C + db FLY, $02, $0C + db $B4, $03, $0C ; unused field move + db SURF, $04, $0C + db STRENGTH, $05, $0A + db FLASH, $06, $0C + db DIG, $07, $0C + db TELEPORT, $08, $0A + db SOFTBOILED, $09, $08 + db $ff ; list terminator diff --git a/engine/overworld/set_blackout_map.asm b/engine/overworld/set_blackout_map.asm new file mode 100644 index 00000000..9bfe82bd --- /dev/null +++ b/engine/overworld/set_blackout_map.asm @@ -0,0 +1,29 @@ +SetLastBlackoutMap: +; Set the map to return to when +; blacking out or using Teleport or Dig. +; Safari rest houses don't count. + + push hl + ld hl, SafariZoneRestHouses + ld a, [wCurMap] + ld b, a +.loop + ld a, [hli] + cp -1 + jr z, .notresthouse + cp b + jr nz, .loop + jr .done + +.notresthouse + ld a, [wLastMap] + ld [wLastBlackoutMap], a +.done + pop hl + ret + +SafariZoneRestHouses: + db SAFARI_ZONE_REST_HOUSE_2 + db SAFARI_ZONE_REST_HOUSE_3 + db SAFARI_ZONE_REST_HOUSE_4 + db -1 diff --git a/engine/remove_pokemon.asm b/engine/remove_pokemon.asm new file mode 100644 index 00000000..1fcb5d09 --- /dev/null +++ b/engine/remove_pokemon.asm @@ -0,0 +1,95 @@ +_RemovePokemon: + ld hl, wPartyCount + ld a, [wRemoveMonFromBox] + and a + jr z, .asm_7b74 + ld hl, wNumInBox +.asm_7b74 + ld a, [hl] + dec a + ld [hli], a + ld a, [wWhichPokemon] + ld c, a + ld b, $0 + add hl, bc + ld e, l + ld d, h + inc de +.asm_7b81 + ld a, [de] + inc de + ld [hli], a + inc a + jr nz, .asm_7b81 + ld hl, wPartyMonOT + ld d, $5 + ld a, [wRemoveMonFromBox] + and a + jr z, .asm_7b97 + ld hl, wBoxMonOT + ld d, $13 +.asm_7b97 + ld a, [wWhichPokemon] + call SkipFixedLengthTextEntries + ld a, [wWhichPokemon] + cp d + jr nz, .asm_7ba6 + ld [hl], $ff + ret +.asm_7ba6 + ld d, h + ld e, l + ld bc, NAME_LENGTH + add hl, bc + ld bc, wPartyMonNicks + ld a, [wRemoveMonFromBox] + and a + jr z, .asm_7bb8 + ld bc, wBoxMonNicks +.asm_7bb8 + call CopyDataUntil + ld hl, wPartyMons + ld bc, wPartyMon2 - wPartyMon1 + ld a, [wRemoveMonFromBox] + and a + jr z, .asm_7bcd + ld hl, wBoxMons + ld bc, wBoxMon2 - wBoxMon1 +.asm_7bcd + ld a, [wWhichPokemon] + call AddNTimes + ld d, h + ld e, l + ld a, [wRemoveMonFromBox] + and a + jr z, .asm_7be4 + ld bc, wBoxMon2 - wBoxMon1 + add hl, bc + ld bc, wBoxMonOT + jr .asm_7beb +.asm_7be4 + ld bc, wPartyMon2 - wPartyMon1 + add hl, bc + ld bc, wPartyMonOT +.asm_7beb + call CopyDataUntil + ld hl, wPartyMonNicks + ld a, [wRemoveMonFromBox] + and a + jr z, .asm_7bfa + ld hl, wBoxMonNicks +.asm_7bfa + ld bc, NAME_LENGTH + ld a, [wWhichPokemon] + call AddNTimes + ld d, h + ld e, l + ld bc, NAME_LENGTH + add hl, bc + ld bc, wPokedexOwned + ld a, [wRemoveMonFromBox] + and a + jr z, .asm_7c15 + ld bc, wBoxMonNicksEnd +.asm_7c15 + jp CopyDataUntil diff --git a/engine/special_warps.asm b/engine/special_warps.asm new file mode 100644 index 00000000..de00a817 --- /dev/null +++ b/engine/special_warps.asm @@ -0,0 +1,149 @@ +SpecialWarpIn: + call LoadSpecialWarpData + predef LoadTilesetHeader + ld hl,wd732 + bit 2,[hl] ; dungeon warp or fly warp? + res 2,[hl] + jr z,.next +; if dungeon warp or fly warp + ld a,[wDestinationMap] + jr .next2 +.next + bit 1,[hl] + jr z,.next3 + call EmptyFunc +.next3 + ld a,0 +.next2 + ld b,a + ld a,[wd72d] + and a + jr nz,.next4 + ld a,b +.next4 + ld hl,wd732 + bit 4,[hl] ; dungeon warp? + ret nz +; if not dungeon warp + ld [wLastMap],a + ret + +; gets the map ID, tile block map view pointer, tileset, and coordinates +LoadSpecialWarpData: + ld a, [wd72d] + cp TRADE_CENTER + jr nz, .notTradeCenter + ld hl, TradeCenterSpec1 + ld a, [hSerialConnectionStatus] + cp USING_INTERNAL_CLOCK ; which gameboy is clocking determines who is on the left and who is on the right + jr z, .copyWarpData + ld hl, TradeCenterSpec2 + jr .copyWarpData +.notTradeCenter + cp COLOSSEUM + jr nz, .notColosseum + ld hl, ColosseumSpec1 + ld a, [hSerialConnectionStatus] + cp USING_INTERNAL_CLOCK + jr z, .copyWarpData + ld hl, ColosseumSpec2 + jr .copyWarpData +.notColosseum + ld a, [wd732] + bit 1, a + jr nz, .notFirstMap + bit 2, a + jr nz, .notFirstMap + ld hl, FirstMapSpec +.copyWarpData + ld de, wCurMap + ld c, $7 +.copyWarpDataLoop + ld a, [hli] + ld [de], a + inc de + dec c + jr nz, .copyWarpDataLoop + ld a, [hli] + ld [wCurMapTileset], a + xor a + jr .done +.notFirstMap + ld a, [wLastMap] ; this value is overwritten before it's ever read + ld hl, wd732 + bit 4, [hl] ; used dungeon warp (jumped down hole/waterfall)? + jr nz, .usedDunegonWarp + bit 6, [hl] ; return to last pokemon center (or player's house)? + res 6, [hl] + jr z, .otherDestination +; return to last pokemon center or player's house + ld a, [wLastBlackoutMap] + jr .usedFlyWarp +.usedDunegonWarp + ld hl, wd72d + res 4, [hl] + ld a, [wDungeonWarpDestinationMap] + ld b, a + ld [wCurMap], a + ld a, [wWhichDungeonWarp] + ld c, a + ld hl, DungeonWarpList + ld de, 0 + ld a, 6 + ld [wDungeonWarpDataEntrySize], a +.dungeonWarpListLoop + ld a, [hli] + cp b + jr z, .matchedDungeonWarpDestinationMap + inc hl + jr .nextDungeonWarp +.matchedDungeonWarpDestinationMap + ld a, [hli] + cp c + jr z, .matchedDungeonWarpID +.nextDungeonWarp + ld a, [wDungeonWarpDataEntrySize] + add e + ld e, a + jr .dungeonWarpListLoop +.matchedDungeonWarpID + ld hl, DungeonWarpData + add hl, de + jr .copyWarpData2 +.otherDestination + ld a, [wDestinationMap] +.usedFlyWarp + ld b, a + ld [wCurMap], a + ld hl, FlyWarpDataPtr +.flyWarpDataPtrLoop + ld a, [hli] + inc hl + cp b + jr z, .foundFlyWarpMatch + inc hl + inc hl + jr .flyWarpDataPtrLoop +.foundFlyWarpMatch + ld a, [hli] + ld h, [hl] + ld l, a +.copyWarpData2 + ld de, wCurrentTileBlockMapViewPointer + ld c, $6 +.copyWarpDataLoop2 + ld a, [hli] + ld [de], a + inc de + dec c + jr nz, .copyWarpDataLoop2 + xor a ; OVERWORLD + ld [wCurMapTileset], a +.done + ld [wYOffsetSinceLastSpecialWarp], a + ld [wXOffsetSinceLastSpecialWarp], a + ld a, $ff ; the player's coordinates have already been updated using a special warp, so don't use any of the normal warps + ld [wDestinationWarpID], a + ret + +INCLUDE "data/special_warps.asm" diff --git a/engine/subtract_paid_money.asm b/engine/subtract_paid_money.asm new file mode 100644 index 00000000..2888c3fb --- /dev/null +++ b/engine/subtract_paid_money.asm @@ -0,0 +1,17 @@ +; subtracts the amount the player paid from their money +; sets carry flag if there is enough money and unsets carry flag if not +SubtractAmountPaidFromMoney_: + ld de,wPlayerMoney + ld hl,hMoney ; total price of items + ld c,3 ; length of money in bytes + call StringCmp + ret c + ld de,wPlayerMoney + 2 + ld hl,hMoney + 2 ; total price of items + ld c,3 ; length of money in bytes + predef SubBCDPredef ; subtract total price from money + ld a,MONEY_BOX + ld [wTextBoxID],a + call DisplayTextBoxID ; redraw money text box + and a + ret -- cgit v1.2.3 From d1162fec71ca789cae66dfe826aa0eae0e134b53 Mon Sep 17 00:00:00 2001 From: YamaArashi Date: Sun, 16 Oct 2016 22:30:32 -0700 Subject: correct comments about teleport effect --- engine/battle/core.asm | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'engine') diff --git a/engine/battle/core.asm b/engine/battle/core.asm index d1fd27f1..508e250c 100755 --- a/engine/battle/core.asm +++ b/engine/battle/core.asm @@ -8047,9 +8047,8 @@ SwitchAndTeleportEffect: cp c ; get a random number between 0 and c jr nc, .rejectionSampleLoop1 srl b - srl b ; b = enemy level * 4 -; bug: does not account for overflow, so levels above 63 can lead to erroneousness results - cp b ; is rand[0, playerLevel + enemyLevel] > enemyLevel? + srl b ; b = enemyLevel / 4 + cp b ; is rand[0, playerLevel + enemyLevel) >= (enemyLevel / 4)? jr nc, .playerMoveWasSuccessful ; if so, allow teleporting ld c, 50 call DelayFrames -- cgit v1.2.3 From bb1bf5e6a7536378dffc2b995384d6dc8692bea8 Mon Sep 17 00:00:00 2001 From: YamaArashi Date: Sat, 29 Oct 2016 01:44:13 -0700 Subject: link battle action constants --- engine/battle/core.asm | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'engine') diff --git a/engine/battle/core.asm b/engine/battle/core.asm index 508e250c..cc5a6de7 100755 --- a/engine/battle/core.asm +++ b/engine/battle/core.asm @@ -432,13 +432,13 @@ MainInBattleLoop: jr nz, .noLinkBattle ; link battle ld a, [wSerialExchangeNybbleReceiveData] - cp $f + cp LINKBATTLE_RUN jp z, EnemyRan - cp $e + cp LINKBATTLE_STRUGGLE jr z, .noLinkBattle - cp $d + cp LINKBATTLE_NO_ACTION jr z, .noLinkBattle - sub $4 + sub 4 jr c, .noLinkBattle ; the link battle enemy has switched mons ld a, [wPlayerBattleStatus1] @@ -990,7 +990,7 @@ ReplaceFaintedEnemyMon: ; link battle call LinkBattleExchangeData ld a, [wSerialExchangeNybbleReceiveData] - cp $f + cp LINKBATTLE_RUN ret z call LoadScreenTilesFromBuffer1 .notLinkBattle @@ -1679,12 +1679,12 @@ TryRunningFromBattle: call SaveScreenTilesToBuffer1 xor a ld [wActionResultOrTookBattleTurn], a - ld a, $f + ld a, LINKBATTLE_RUN ld [wPlayerMoveListIndex], a call LinkBattleExchangeData call LoadScreenTilesFromBuffer1 ld a, [wSerialExchangeNybbleReceiveData] - cp $f + cp LINKBATTLE_RUN ld a, $2 jr z, .playSound dec a @@ -2999,16 +2999,16 @@ SelectEnemyMove: call LinkBattleExchangeData call LoadScreenTilesFromBuffer1 ld a, [wSerialExchangeNybbleReceiveData] - cp $e + cp LINKBATTLE_STRUGGLE jp z, .linkedOpponentUsedStruggle - cp $d + cp LINKBATTLE_NO_ACTION jr z, .unableToSelectMove - cp $4 + cp 4 ret nc ld [wEnemyMoveListIndex], a ld c, a ld hl, wEnemyMonMoves - ld b, $0 + ld b, 0 add hl, bc ld a, [hl] jr .done @@ -3087,7 +3087,7 @@ LinkBattleExchangeData: ld a, $ff ld [wSerialExchangeNybbleReceiveData], a ld a, [wPlayerMoveListIndex] - cp $f ; is the player running from battle? + cp LINKBATTLE_RUN ; is the player running from battle? jr z, .doExchange ld a, [wActionResultOrTookBattleTurn] and a ; is the player switching in another mon? @@ -3095,7 +3095,7 @@ LinkBattleExchangeData: ; the player used a move ld a, [wPlayerSelectedMove] cp STRUGGLE - ld b, $e + ld b, LINKBATTLE_STRUGGLE jr z, .next dec b inc a @@ -5676,9 +5676,9 @@ ExecuteEnemyMove: jr nz, .executeEnemyMove ld b, $1 ld a, [wSerialExchangeNybbleReceiveData] - cp $e + cp LINKBATTLE_STRUGGLE jr z, .executeEnemyMove - cp $4 + cp 4 ret nc .executeEnemyMove ld hl, wAILayer2Encouragement -- cgit v1.2.3 From 4d61c351726b38b22e0606df23bd2fdfb13640cc Mon Sep 17 00:00:00 2001 From: YamaArashi Date: Sat, 29 Oct 2016 02:04:48 -0700 Subject: correct mistaken comments --- engine/battle/core.asm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'engine') diff --git a/engine/battle/core.asm b/engine/battle/core.asm index cc5a6de7..d921fd15 100755 --- a/engine/battle/core.asm +++ b/engine/battle/core.asm @@ -3097,8 +3097,8 @@ LinkBattleExchangeData: cp STRUGGLE ld b, LINKBATTLE_STRUGGLE jr z, .next - dec b - inc a + dec b ; LINKBATTLE_NO_ACTION + inc a ; does move equal -1 (i.e. no action)? jr z, .next ld a, [wPlayerMoveListIndex] jr .doExchange -- cgit v1.2.3 From 77c3e22a4ecd3dc81918f00c548cef7c634f3419 Mon Sep 17 00:00:00 2001 From: YamaArashi Date: Sat, 29 Oct 2016 10:32:03 -0700 Subject: use more HRAM constants --- engine/battle/core.asm | 4 ++-- engine/battle/experience.asm | 6 +++--- engine/cable_club.asm | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'engine') diff --git a/engine/battle/core.asm b/engine/battle/core.asm index d921fd15..153a9048 100755 --- a/engine/battle/core.asm +++ b/engine/battle/core.asm @@ -488,8 +488,8 @@ MainInBattleLoop: jr nc, .playerMovesFirst ; if player is faster jr .enemyMovesFirst ; if enemy is faster .speedEqual ; 50/50 chance for both players - ld a, [$ffaa] - cp $2 + ld a, [hSerialConnectionStatus] + cp USING_INTERNAL_CLOCK jr z, .invertOutcome call BattleRandom cp $80 diff --git a/engine/battle/experience.asm b/engine/battle/experience.asm index 9aee8bd7..24748338 100644 --- a/engine/battle/experience.asm +++ b/engine/battle/experience.asm @@ -119,11 +119,11 @@ GainExperience: ld d, MAX_LEVEL callab CalcExperience ; get max exp ; compare max exp with current exp - ld a, [$ff96] + ld a, [hExperience] ld b, a - ld a, [$ff97] + ld a, [hExperience + 1] ld c, a - ld a, [$ff98] + ld a, [hExperience + 2] ld d, a pop hl ld a, [hld] diff --git a/engine/cable_club.asm b/engine/cable_club.asm index 137e8406..fa99215e 100755 --- a/engine/cable_club.asm +++ b/engine/cable_club.asm @@ -551,7 +551,7 @@ TradeCenter_SelectMon: Coorda 1, 16 .cancelMenuItem_JoypadLoop call JoypadLowSensitivity - ld a, [$ffb5] + ld a, [hJoy5] and a ; pressed anything? jr z, .cancelMenuItem_JoypadLoop bit 0, a ; A button pressed? @@ -914,7 +914,7 @@ CableClub_Run: ld [wGrassRate], a inc a ; LINK_STATE_IN_CABLE_CLUB ld [wLinkState], a - ld [$ffb5], a + ld [hJoy5], a ld a, 10 ld [wAudioFadeOutControl], a ld a, BANK(Music_Celadon) -- cgit v1.2.3 From bf67f7174d8e3f1348c786618ee5a3a076d1eff8 Mon Sep 17 00:00:00 2001 From: YamaArashi Date: Sat, 31 Dec 2016 17:23:54 -0800 Subject: split code out of main.asm --- engine/add_mon.asm | 512 +++++++++++++++++++++++++++++++ engine/bcd.asm | 212 +++++++++++++ engine/cable_club.asm | 2 +- engine/flag_action.asm | 73 +++++ engine/get_bag_item_quantity.asm | 18 ++ engine/heal_party.asm | 99 ++++++ engine/init_player_data.asm | 55 ++++ engine/items/inventory.asm | 150 +++++++++ engine/menu/draw_badges.asm | 120 ++++++++ engine/overworld/clear_variables.asm | 20 ++ engine/overworld/daycare_exp.asm | 18 ++ engine/overworld/field_move_messages.asm | 57 ++++ engine/overworld/missable_objects.asm | 215 +++++++++++++ engine/overworld/player_state.asm | 463 ++++++++++++++++++++++++++++ engine/overworld/poison.asm | 112 +++++++ engine/overworld/push_boulder.asm | 105 +++++++ engine/overworld/tileset_header.asm | 60 ++++ engine/overworld/update_map.asm | 126 ++++++++ engine/overworld/wild_mons.asm | 33 ++ engine/pathfinding.asm | 201 ++++++++++++ 20 files changed, 2650 insertions(+), 1 deletion(-) create mode 100644 engine/add_mon.asm create mode 100644 engine/bcd.asm create mode 100644 engine/flag_action.asm create mode 100644 engine/get_bag_item_quantity.asm create mode 100644 engine/heal_party.asm create mode 100644 engine/init_player_data.asm create mode 100644 engine/items/inventory.asm create mode 100644 engine/menu/draw_badges.asm create mode 100644 engine/overworld/clear_variables.asm create mode 100644 engine/overworld/daycare_exp.asm create mode 100644 engine/overworld/field_move_messages.asm create mode 100644 engine/overworld/missable_objects.asm create mode 100644 engine/overworld/player_state.asm create mode 100644 engine/overworld/poison.asm create mode 100644 engine/overworld/push_boulder.asm create mode 100644 engine/overworld/tileset_header.asm create mode 100644 engine/overworld/update_map.asm create mode 100644 engine/overworld/wild_mons.asm create mode 100644 engine/pathfinding.asm (limited to 'engine') diff --git a/engine/add_mon.asm b/engine/add_mon.asm new file mode 100644 index 00000000..19d03942 --- /dev/null +++ b/engine/add_mon.asm @@ -0,0 +1,512 @@ +_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 diff --git a/engine/bcd.asm b/engine/bcd.asm new file mode 100644 index 00000000..3e693e1f --- /dev/null +++ b/engine/bcd.asm @@ -0,0 +1,212 @@ +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 diff --git a/engine/cable_club.asm b/engine/cable_club.asm index fa99215e..474dbd11 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/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/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/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/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/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..75f68568 --- /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, $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 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 -- cgit v1.2.3 From 3068ab2e19497ace112eb9608975944ebb3ae210 Mon Sep 17 00:00:00 2001 From: YamaArashi Date: Sat, 31 Dec 2016 17:36:05 -0800 Subject: use text constants in poison.asm --- engine/overworld/poison.asm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'engine') diff --git a/engine/overworld/poison.asm b/engine/overworld/poison.asm index 75f68568..5d8eb9fd 100644 --- a/engine/overworld/poison.asm +++ b/engine/overworld/poison.asm @@ -51,7 +51,7 @@ ApplyOutOfBattlePoisonDamage: xor a ld [wJoyIgnore], a call EnableAutoTextBoxDrawing - ld a, $d0 + ld a, TEXT_MON_FAINTED ld [hSpriteIndexOrTextID], a call DisplayTextID pop de @@ -98,7 +98,7 @@ ApplyOutOfBattlePoisonDamage: and a jr nz, .noBlackOut call EnableAutoTextBoxDrawing - ld a, $d1 + ld a, TEXT_BLACKED_OUT ld [hSpriteIndexOrTextID], a call DisplayTextID ld hl, wd72e -- cgit v1.2.3 From 7c3a90bf0181127fab4cd98ad4a3173a2984f51e Mon Sep 17 00:00:00 2001 From: YamaArashi Date: Sat, 7 Jan 2017 11:13:52 -0800 Subject: use actual predef label --- engine/predefs.asm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engine') diff --git a/engine/predefs.asm b/engine/predefs.asm index 7b0be1e9..605cba3a 100755 --- a/engine/predefs.asm +++ b/engine/predefs.asm @@ -58,7 +58,7 @@ PredefPointers:: add_predef ScaleSpriteByTwo add_predef LoadMonBackPic add_predef CopyDownscaledMonTiles - add_predef LoadMissableObjects + dbw $03,JumpMoveEffect ; wrong bank add_predef HealParty add_predef MoveAnimation add_predef DivideBCDPredef -- cgit v1.2.3 From 46fbe5531b370a2f932e3f204de1e7527a5a3b6d Mon Sep 17 00:00:00 2001 From: YamaArashi Date: Mon, 16 Jan 2017 14:42:15 -0800 Subject: fix incorrect comment --- engine/battle/moveEffects/haze_effect.asm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engine') 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] -- cgit v1.2.3 From ce35f2f7a1d72c3404e3c7953cdaa10a0cff00e8 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Sun, 19 Mar 2017 20:35:40 +0000 Subject: Gave the labels in _MoveMon more descriptive names and added a few comments --- engine/add_mon.asm | 78 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 41 insertions(+), 37 deletions(-) (limited to 'engine') diff --git a/engine/add_mon.asm b/engine/add_mon.asm index 19d03942..b2feeb12 100644 --- a/engine/add_mon.asm +++ b/engine/add_mon.asm @@ -340,13 +340,14 @@ _AddEnemyMonToPlayerParty: _MoveMon: ld a, [wMoveMonType] - and a + and a ; BOX_TO_PARTY jr z, .checkPartyMonSlots cp DAYCARE_TO_PARTY jr z, .checkPartyMonSlots cp PARTY_TO_DAYCARE ld hl, wDayCareMon - jr z, .asm_f575 + jr z, .findMonDataSrc + ; else it's PARTY_TO_BOX ld hl, wNumInBox ld a, [hl] cp MONS_PER_BOX @@ -369,24 +370,26 @@ _MoveMon: ld a, [wMoveMonType] cp DAYCARE_TO_PARTY ld a, [wDayCareMon] - jr z, .asm_f556 + jr z, .copySpecies ld a, [wcf91] -.asm_f556 +.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, .skipToNewMonEntry + jr nz, .addMonOffset + ; if it's PARTY_TO_BOX ld hl, wBoxMons ld bc, wBoxMon2 - wBoxMon1 ; $21 ld a, [wNumInBox] -.skipToNewMonEntry +.addMonOffset dec a call AddNTimes -.asm_f575 +.findMonDataSrc push hl ld e, l ld d, h @@ -394,16 +397,16 @@ _MoveMon: and a ld hl, wBoxMons ld bc, wBoxMon2 - wBoxMon1 ; $21 - jr z, .asm_f591 + jr z, .addMonOffset2 cp DAYCARE_TO_PARTY ld hl, wDayCareMon - jr z, .asm_f597 + jr z, .copyMonData ld hl, wPartyMons ld bc, wPartyMon2 - wPartyMon1 ; $2c -.asm_f591 +.addMonOffset2 ld a, [wWhichPokemon] call AddNTimes -.asm_f597 +.copyMonData push hl push de ld bc, wBoxMon2 - wBoxMon1 @@ -411,84 +414,85 @@ _MoveMon: pop de pop hl ld a, [wMoveMonType] - and a - jr z, .asm_f5b4 + and a ; BOX_TO_PARTY + jr z, .findOTdest cp DAYCARE_TO_PARTY - jr z, .asm_f5b4 + jr z, .findOTdest ld bc, wBoxMon2 - wBoxMon1 add hl, bc - ld a, [hl] + ld a, [hl] ; hl = Level inc de inc de inc de - ld [de], a -.asm_f5b4 + ld [de], a ; de = BoxLevel +.findOTdest ld a, [wMoveMonType] cp PARTY_TO_DAYCARE ld de, wDayCareMonOT - jr z, .asm_f5d3 - dec a + jr z, .findOTsrc + dec a ld hl, wPartyMonOT ld a, [wPartyCount] - jr nz, .asm_f5cd + jr nz, .addOToffset ld hl, wBoxMonOT ld a, [wNumInBox] -.asm_f5cd +.addOToffset dec a call SkipFixedLengthTextEntries ld d, h ld e, l -.asm_f5d3 +.findOTsrc ld hl, wBoxMonOT ld a, [wMoveMonType] and a - jr z, .asm_f5e6 + jr z, .addOToffset2 ld hl, wDayCareMonOT cp DAYCARE_TO_PARTY - jr z, .asm_f5ec + jr z, .copyOT ld hl, wPartyMonOT -.asm_f5e6 +.addOToffset2 ld a, [wWhichPokemon] call SkipFixedLengthTextEntries -.asm_f5ec +.copyOT ld bc, NAME_LENGTH call CopyData ld a, [wMoveMonType] +.findNickDest cp PARTY_TO_DAYCARE ld de, wDayCareMonName - jr z, .asm_f611 + jr z, .findNickSrc dec a ld hl, wPartyMonNicks ld a, [wPartyCount] - jr nz, .asm_f60b + jr nz, .addNickOffset ld hl, wBoxMonNicks ld a, [wNumInBox] -.asm_f60b +.addNickOffset dec a call SkipFixedLengthTextEntries ld d, h ld e, l -.asm_f611 +.findNickSrc ld hl, wBoxMonNicks ld a, [wMoveMonType] and a - jr z, .asm_f624 + jr z, .addNickOffset2 ld hl, wDayCareMonName cp DAYCARE_TO_PARTY - jr z, .asm_f62a + jr z, .copyNick ld hl, wPartyMonNicks -.asm_f624 +.addNickOffset2 ld a, [wWhichPokemon] call SkipFixedLengthTextEntries -.asm_f62a +.copyNick ld bc, NAME_LENGTH call CopyData pop hl ld a, [wMoveMonType] cp PARTY_TO_BOX - jr z, .asm_f664 + jr z, .done cp PARTY_TO_DAYCARE - jr z, .asm_f664 + jr z, .done push hl srl a add $2 @@ -507,6 +511,6 @@ _MoveMon: add hl, bc ld b, $1 call CalcStats -.asm_f664 +.done and a ret -- cgit v1.2.3 From 39d31cecb263498e286c1fba3b8e0c6d439244b9 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Sun, 19 Mar 2017 21:09:24 +0000 Subject: Gave names to the functions and labels and adresses used in DivideBCD and added a few comments --- engine/bcd.asm | 146 +++++++++++++++++++++++++++++---------------------------- 1 file changed, 74 insertions(+), 72 deletions(-) (limited to 'engine') diff --git a/engine/bcd.asm b/engine/bcd.asm index 3e693e1f..2d0b43df 100644 --- a/engine/bcd.asm +++ b/engine/bcd.asm @@ -6,155 +6,157 @@ DivideBCDPredef4:: DivideBCD:: xor a - ld [$ffa5], a - ld [$ffa6], a - ld [$ffa7], a + ld [hDivideBCDBuffer], a + ld [hDivideBCDBuffer+1], a + ld [hDivideBCDBuffer+2], a ld d, $1 -.asm_f72a - ld a, [$ffa2] +.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, .asm_f75b + jr nz, .next inc d - ld a, [$ffa2] + ld a, [hDivideBCDDivisor] swap a and $f0 ld b, a - ld a, [$ffa3] + ld a, [hDivideBCDDivisor+1] swap a - ld [$ffa3], a + ld [hDivideBCDDivisor+1], a and $f or b - ld [$ffa2], a - ld a, [$ffa3] + ld [hDivideBCDDivisor], a + ld a, [hDivideBCDDivisor+1] and $f0 ld b, a - ld a, [$ffa4] + ld a, [hDivideBCDDivisor+2] swap a - ld [$ffa4], a + ld [hDivideBCDDivisor+2], a and $f or b - ld [$ffa3], a - ld a, [$ffa4] + ld [hDivideBCDDivisor+1], a + ld a, [hDivideBCDDivisor+2] and $f0 - ld [$ffa4], a - jr .asm_f72a -.asm_f75b + ld [hDivideBCDDivisor+2], a + jr .mulBy10Loop +.next push de push de - call DivideBCD_f800 + call DivideBCD_getNextDigit pop de ld a, b swap a and $f0 - ld [$ffa5], a + ld [hDivideBCDBuffer], a dec d - jr z, .asm_f7bc + jr z, .next2 push de - call DivideBCD_f7d7 - call DivideBCD_f800 + call DivideBCD_divDivisorBy10 + call DivideBCD_getNextDigit pop de - ld a, [$ffa5] + ld a, [hDivideBCDBuffer] or b - ld [$ffa5], a + ld [hDivideBCDBuffer], a dec d - jr z, .asm_f7bc + jr z, .next2 push de - call DivideBCD_f7d7 - call DivideBCD_f800 + call DivideBCD_divDivisorBy10 + call DivideBCD_getNextDigit pop de ld a, b swap a and $f0 - ld [$ffa6], a + ld [hDivideBCDBuffer+1], a dec d - jr z, .asm_f7bc + jr z, .next2 push de - call DivideBCD_f7d7 - call DivideBCD_f800 + call DivideBCD_divDivisorBy10 + call DivideBCD_getNextDigit pop de - ld a, [$ffa6] + ld a, [hDivideBCDBuffer+1] or b - ld [$ffa6], a + ld [hDivideBCDBuffer+1], a dec d - jr z, .asm_f7bc + jr z, .next2 push de - call DivideBCD_f7d7 - call DivideBCD_f800 + call DivideBCD_divDivisorBy10 + call DivideBCD_getNextDigit pop de ld a, b swap a and $f0 - ld [$ffa7], a + ld [hDivideBCDBuffer+2], a dec d - jr z, .asm_f7bc + jr z, .next2 push de - call DivideBCD_f7d7 - call DivideBCD_f800 + call DivideBCD_divDivisorBy10 + call DivideBCD_getNextDigit pop de - ld a, [$ffa7] + ld a, [hDivideBCDBuffer+2] 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 + 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 + ld a, $6 sub d and a ret z -.asm_f7ce +.divResultBy10loop push af - call DivideBCD_f7d7 + call DivideBCD_divDivisorBy10 pop af dec a - jr nz, .asm_f7ce + jr nz, .divResultBy10loop ret -DivideBCD_f7d7: - ld a, [$ffa4] +DivideBCD_divDivisorBy10: + ld a, [hDivideBCDDivisor+2] swap a and $f ld b, a - ld a, [$ffa3] + ld a, [hDivideBCDDivisor+1] swap a - ld [$ffa3], a + ld [hDivideBCDDivisor+1], a and $f0 or b - ld [$ffa4], a - ld a, [$ffa3] + ld [hDivideBCDDivisor+2], a + ld a, [hDivideBCDDivisor+1] and $f ld b, a - ld a, [$ffa2] + ld a, [hDivideBCDDivisor] swap a - ld [$ffa2], a + ld [hDivideBCDDivisor], a and $f0 or b - ld [$ffa3], a - ld a, [$ffa2] + ld [hDivideBCDDivisor+1], a + ld a, [hDivideBCDDivisor] and $f - ld [$ffa2], a + ld [hDivideBCDDivisor], a ret -DivideBCD_f800: +DivideBCD_getNextDigit: ld bc, $3 -.asm_f803 - ld de, $ff9f - ld hl, $ffa2 +.loop + ld de, hMoney ; the dividend + ld hl, hDivideBCDDivisor push bc call StringCmp pop bc ret c inc b - ld de, $ffa1 - ld hl, $ffa4 + ld de, hMoney+2 ; since SubBCD works starting from the least significant digit + ld hl, hDivideBCDDivisor+2 push bc call SubBCD pop bc - jr .asm_f803 + jr .loop AddBCDPredef:: -- cgit v1.2.3 From e9f33ce19c3f573cc7fb312d6869e711d5d9de4f Mon Sep 17 00:00:00 2001 From: dannye Date: Mon, 8 May 2017 02:54:20 -0500 Subject: =?UTF-8?q?Typo:=20SFX=5FPOKEFLUE=20=E2=86=92=20SFX=5FPOKEFLUTE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- engine/items/items.asm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'engine') diff --git a/engine/items/items.asm b/engine/items/items.asm index f8873a6e..057595df 100755 --- a/engine/items/items.asm +++ b/engine/items/items.asm @@ -1846,12 +1846,12 @@ 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] - cp a, SFX_POKEFLUE + cp a, SFX_POKEFLUTE jr z,.musicWaitLoop call PlayDefaultMusic ; start playing normal music again .done -- cgit v1.2.3 From 9ea25bc8cd32df5b3bcf6333c3d2582e1b11f2dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20Ni=C3=B1o=20D=C3=ADaz?= Date: Fri, 9 Jun 2017 22:54:09 +0100 Subject: Replace deprecated mnemonics by the correct ones MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The old mnemonics generate warnings with new versions of rgbds. This patch replaces them by the correct ones. Signed-off-by: Antonio Niño Díaz --- engine/battle/animations.asm | 8 ++++---- engine/battle/battle_transitions.asm | 2 +- engine/battle/core.asm | 6 +++--- engine/battle/trainer_ai.asm | 4 ++-- engine/cable_club.asm | 2 +- engine/items/items.asm | 2 +- engine/menu/start_sub_menus.asm | 2 +- engine/menu/text_box.asm | 2 +- engine/overworld/player_state.asm | 2 +- engine/overworld/ssanne.asm | 2 +- engine/palettes.asm | 2 +- engine/slot_machine.asm | 2 +- engine/trade.asm | 2 +- 13 files changed, 19 insertions(+), 19 deletions(-) (limited to 'engine') diff --git a/engine/battle/animations.asm b/engine/battle/animations.asm index 373136a8..4992b84a 100755 --- a/engine/battle/animations.asm +++ b/engine/battle/animations.asm @@ -213,7 +213,7 @@ PlayAnimation: ld h,a ld de,.nextAnimationCommand push de - jp [hl] ; jump to special effect function + jp hl ; jump to special effect function .playSubanimation ld c,a and a,%00111111 @@ -457,7 +457,7 @@ PlayApplyingAttackAnimation: ld a,[hli] ld h,[hl] ld l,a - jp [hl] + jp hl AnimationTypePointerTable: dw ShakeScreenVertically ; enemy mon has used a damaging move without a side effect @@ -642,7 +642,7 @@ DoSpecialEffectByAnimationId: ld l,a ld de,.done push de - jp [hl] + jp hl .done pop bc pop de @@ -1080,7 +1080,7 @@ CallWithTurnFlipped: ld [H_WHOSETURN],a ld de,.returnAddress push de - jp [hl] + jp hl .returnAddress pop af ld [H_WHOSETURN],a diff --git a/engine/battle/battle_transitions.asm b/engine/battle/battle_transitions.asm index 9e02c56f..985a1eb2 100644 --- a/engine/battle/battle_transitions.asm +++ b/engine/battle/battle_transitions.asm @@ -62,7 +62,7 @@ BattleTransition: ld a, [hli] ld h, [hl] ld l, a - jp [hl] + jp hl ; the three GetBattleTransitionID functions set the first ; three bits of c, which determines what transition animation diff --git a/engine/battle/core.asm b/engine/battle/core.asm index 153a9048..4835e8cf 100755 --- a/engine/battle/core.asm +++ b/engine/battle/core.asm @@ -3150,7 +3150,7 @@ ExecutePlayerMove: jp z, ExecutePlayerMoveDone call CheckPlayerStatusConditions jr nz, .playerHasNoSpecialCondition - jp [hl] + jp hl .playerHasNoSpecialCondition call GetCurrentMove ld hl, wPlayerBattleStatus1 @@ -5690,7 +5690,7 @@ ExecuteEnemyMove: ld [wDamageMultipliers], a call CheckEnemyStatusConditions jr nz, .enemyHasNoSpecialConditions - jp [hl] + jp hl .enemyHasNoSpecialConditions ld hl, wEnemyBattleStatus1 bit ChargingUp, [hl] ; is the enemy charging up for attack? @@ -7139,7 +7139,7 @@ _JumpMoveEffect: ld a, [hli] ld h, [hl] ld l, a - jp [hl] ; jump to special effect handler + jp hl ; jump to special effect handler MoveEffectPointerTable: dw SleepEffect ; unused effect diff --git a/engine/battle/trainer_ai.asm b/engine/battle/trainer_ai.asm index b175fcaf..d78079e8 100644 --- a/engine/battle/trainer_ai.asm +++ b/engine/battle/trainer_ai.asm @@ -51,7 +51,7 @@ AIEnemyTrainerChooseMoves: ld l, a ld de, .nextMoveChoiceModification ; set return address push de - jp [hl] ; execute modification function + jp hl ; execute modification function .loopFindMinimumEntries ; all entries will be decremented sequentially until one of them is zero ld hl, wBuffer ; temp move selection array ld de, wEnemyMonMoves ; enemy moves @@ -366,7 +366,7 @@ TrainerAI: ld h,[hl] ld l,a call Random - jp [hl] + jp hl TrainerAIPointers: ; one entry per trainer class diff --git a/engine/cable_club.asm b/engine/cable_club.asm index 474dbd11..3e72daa9 100755 --- a/engine/cable_club.asm +++ b/engine/cable_club.asm @@ -304,7 +304,7 @@ CallCurrentTradeCenterFunction: ld a, [hli] ld h, [hl] ld l, a - jp [hl] + jp hl TradeCenter_SelectMon: call ClearScreen diff --git a/engine/items/items.asm b/engine/items/items.asm index 057595df..f334e384 100755 --- a/engine/items/items.asm +++ b/engine/items/items.asm @@ -13,7 +13,7 @@ UseItem_: ld a,[hli] ld h,[hl] ld l,a - jp [hl] + jp hl ItemUsePtrTable: dw ItemUseBall ; MASTER_BALL diff --git a/engine/menu/start_sub_menus.asm b/engine/menu/start_sub_menus.asm index 251d7ae4..8c10266b 100755 --- a/engine/menu/start_sub_menus.asm +++ b/engine/menu/start_sub_menus.asm @@ -118,7 +118,7 @@ StartMenu_Pokemon: ld h,[hl] ld l,a ld a,[wObtainedBadges] ; badges obtained - jp [hl] + jp hl .outOfBattleMovePointers dw .cut dw .fly diff --git a/engine/menu/text_box.asm b/engine/menu/text_box.asm index 12067dd4..90c35d25 100644 --- a/engine/menu/text_box.asm +++ b/engine/menu/text_box.asm @@ -24,7 +24,7 @@ DisplayTextBoxID_: ld l,a ; hl = address of function ld de,.done push de - jp [hl] ; jump to the function + jp hl ; jump to the function .coordTableMatch call GetTextBoxIDCoords call GetAddressOfScreenCoords diff --git a/engine/overworld/player_state.asm b/engine/overworld/player_state.asm index 79f755b9..b8d734f2 100644 --- a/engine/overworld/player_state.asm +++ b/engine/overworld/player_state.asm @@ -103,7 +103,7 @@ IsPlayerFacingEdgeOfMap: ld c, a ld de, .asm_c41e push de - jp [hl] + jp hl .asm_c41e pop bc pop de diff --git a/engine/overworld/ssanne.asm b/engine/overworld/ssanne.asm index 712c53ed..ea4747ce 100755 --- a/engine/overworld/ssanne.asm +++ b/engine/overworld/ssanne.asm @@ -16,7 +16,7 @@ AnimateBoulderDust: ld bc, .returnAddress push bc ld c, 4 - jp [hl] + jp hl .returnAddress ld a, [rOBP1] xor %01100100 diff --git a/engine/palettes.asm b/engine/palettes.asm index 4785ade2..6a798860 100755 --- a/engine/palettes.asm +++ b/engine/palettes.asm @@ -17,7 +17,7 @@ _RunPaletteCommand: ld l, a ld de, SendSGBPackets push de - jp [hl] + jp hl SetPal_BattleBlack: ld hl, PalPacket_Black diff --git a/engine/slot_machine.asm b/engine/slot_machine.asm index 2dfcffde..3a46687f 100755 --- a/engine/slot_machine.asm +++ b/engine/slot_machine.asm @@ -451,7 +451,7 @@ SlotMachine_CheckForMatches: pop hl ld de, .flashScreenLoop push de - jp [hl] + jp hl .flashScreenLoop ld a, [rBGP] diff --git a/engine/trade.asm b/engine/trade.asm index c3913a7e..8bc8e3bc 100755 --- a/engine/trade.asm +++ b/engine/trade.asm @@ -46,7 +46,7 @@ TradeAnimCommon: ld l, a ld de, .loop push de - jp [hl] ; call trade func, which will return to the top of the loop + jp hl ; call trade func, which will return to the top of the loop .done pop af ld [hSCX], a -- cgit v1.2.3 From 7a9a1b1e55f4a7f6c339a86d8cdb7fbf1bee7838 Mon Sep 17 00:00:00 2001 From: dannye Date: Sat, 24 Jun 2017 15:01:43 -0500 Subject: Fix typos in comments --- engine/battle/animations.asm | 4 ++-- engine/battle/core.asm | 20 ++++++++++---------- engine/battle/draw_hud_pokeball_gfx.asm | 2 +- engine/battle/moveEffects/heal_effect.asm | 2 +- engine/battle/moveEffects/recoil_effect.asm | 2 +- engine/battle/moveEffects/substitute_effect.asm | 4 ++-- engine/battle/trainer_ai.asm | 8 ++++---- engine/hidden_object_functions17.asm | 2 +- engine/items/items.asm | 2 +- engine/learn_move.asm | 2 +- engine/menu/draw_start_menu.asm | 2 +- engine/menu/naming_screen.asm | 2 +- engine/menu/pokedex.asm | 2 +- engine/overworld/map_sprites.asm | 4 ++-- engine/overworld/movement.asm | 8 ++++---- 15 files changed, 33 insertions(+), 33 deletions(-) (limited to 'engine') 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 153a9048..4e21f6de 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 @@ -3550,7 +3550,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 @@ -4286,7 +4286,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] @@ -4399,7 +4399,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] @@ -7291,16 +7291,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 @@ -7780,7 +7780,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/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/hidden_object_functions17.asm b/engine/hidden_object_functions17.asm index 1b571d35..c1fa5aa4 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/items/items.asm b/engine/items/items.asm index 057595df..f46261b6 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 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_start_menu.asm b/engine/menu/draw_start_menu.asm index 4df9de27..83a81aac 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 2628da48..64065c4d 100755 --- a/engine/menu/naming_screen.asm +++ b/engine/menu/naming_screen.asm @@ -409,7 +409,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 2da3a0f6..bf8afaa9 100755 --- a/engine/menu/pokedex.asm +++ b/engine/menu/pokedex.asm @@ -647,7 +647,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/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/movement.asm b/engine/overworld/movement.asm index 6d05859e..bbfbbc39 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 @@ -446,7 +446,7 @@ InitializeSpriteStatus: ld [hl], a ; $c2x3: set X displacement to 8 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] @@ -685,7 +685,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: -- cgit v1.2.3