Skip to content

Fly and Flash Appear in Party Menu for Pokemon that can Learn

voloved edited this page Feb 8, 2024 · 2 revisions

It's only tested on Red++, but compiles on pokered.
This allows for a Pokemon to use Flash or Fly so long as they can learn it, you have the badge for it, and you have the HM in your bag.
Similar to this hack in Emerald.
It's made because those are the two moves that need a solution in the menu when field moves that can be done on the overworld is done (which Red++ has).
What it does is when looping through moves in a Pokemon, if the move is not a field move, then instead of going to the next move, overwrite it with Fly. If Fly is later found, ignore it. If there's another non-field move, then do the same thing with flash.

------------------------- engine/menus/text_box.asm --------------------------
index cdb8841d..d0442b86 100644
@@ -506,8 +506,15 @@ PokemonMenuEntries:
 	next "SWITCH"
 	next "CANCEL@"
 
 GetMonFieldMoves:
+	xor a
+	ld [wTempCoins1], a
+	; wTempCoins1 holds XXX1 if fly is already in list 
+	;                   XX1X if flash is already in list 
+	;                   X1XX if fly was already checked to be added
+	;                   1XXX if flash was already checked to be added
+	;                   0 at the end of the loop.
 	ld a, [wWhichPokemon]
 	ld hl, wPartyMon1Moves
 	ld bc, wPartyMon2 - wPartyMon1
 	call AddNTimes
@@ -518,26 +525,50 @@ GetMonFieldMoves:
 .loop
 	push hl
 .nextMove
 	dec c
-	jr z, .done
+	jp z, .done
 	ld a, [de] ; move ID
 	and a
-	jr z, .done
+	jp 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
+	jr z, .addFly ; if the move is not a field move
 	cp b
 	jr z, .foundFieldMove
 	inc hl
 	inc hl
 	jr .fieldMoveLoop
 .foundFieldMove
+	push hl
+	ld hl, wTempCoins1
 	ld a, b
+	cp FLY
+	jr z, .foundFly
+	jr .foundFieldMoveChecked
+.foundFly
+	bit 0, [hl]
+	jr nz, .foundFieldMoveCheckFlash
+	set 0, [hl]
+	jr .foundFieldMoveChecked
+.nextMoveCheckedFlyFlash
+	pop hl
+	jp .nextMove
+.foundFieldMoveCheckFlash
+	cp FLASH
+	jr z, .foundFlash
+	jr .foundFieldMoveChecked
+.foundFlash
+	bit 1, [hl]
+	jr nz, .nextMoveCheckedFlyFlash
+	set 1, [hl]
+	jr .foundFieldMoveChecked
+.foundFieldMoveChecked
+	pop hl
 	ld [wLastFieldMoveID], a
 	ld a, [hli] ; field move name index
 	ld b, [hl] ; field move leftmost X coordinate
 	pop hl
@@ -553,9 +584,110 @@ GetMonFieldMoves:
 .skipUpdatingLeftmostXCoord
 	ld a, [wLastFieldMoveID]
 	ld b, a
 	jr .loop
+.addFly
+	ld a, [wTempCoins1]
+	bit 0, a
+	jr nz, .addFlash
+	bit 2, a
+	jr nz, .addFlash
+	set 2, a
+	ld [wTempCoins1], a
+	ld a, [wObtainedBadges]
+	bit BIT_THUNDERBADGE, a
+	jr z, .addFlash
+	push bc
+	push de
+	push hl
+	ld b, HM_FLY
+	predef GetQuantityOfItemInBag
+	ld a, b
+	and a
+	jr nz, .hasTMFly
+	pop hl
+	pop de
+	pop bc
+	jp .nextMove
 .done
 	pop hl
+	xor a
+	ld [wTempCoins1], a 
 	ret
+.hasTMFly
+	ld a, [wWhichPokemon]
+	ld hl, wPartyMon1Species
+	ld bc, wPartyMon2 - wPartyMon1
+	call AddNTimes
+	ld a, [hl]
+	ld [wcf91],a
+	ld a, FLY
+	ld [wMoveNum], a
+	predef CanLearnTM ; check if the pokemon can learn the move
+	ld a,c
+	pop hl
+	pop de
+	pop bc
+	and a
+	jp z, .nextMove
+	push hl
+	ld hl, wTempCoins1
+	set 0, [hl]
+	pop hl
+	ld b, FLY
+	ld a,b
+	ld hl, FieldMoveDisplayData
+	jr .addMoveFindInFieldMoveDisplayData
+.addMoveFindInFieldMoveDisplayData
+	ld a, [hli]
+	cp b
+	jp z, .foundFieldMove
+	jr .addMoveFindInFieldMoveDisplayData
+.addFlash
+	ld a, [wTempCoins1]
+	bit 1, a
+	jp nz, .nextMove
+	bit 3, a
+	jp nz, .nextMove
+	set 3, a
+	ld [wTempCoins1], a
+	ld a, [wObtainedBadges]
+	bit BIT_BOULDERBADGE, a
+	jp z, .nextMove
+	push bc
+	push de
+	push hl
+	ld b, HM_FLASH
+	predef GetQuantityOfItemInBag
+	ld a, b
+	and a
+	jr nz, .hasTMFlash
+	pop hl
+	pop de
+	pop bc
+	jp .nextMove
+.hasTMFlash
+	ld a, [wWhichPokemon]
+	ld hl, wPartyMon1Species
+	ld bc, wPartyMon2 - wPartyMon1
+	call AddNTimes
+	ld a, [hl]
+	ld [wcf91],a
+	ld a, FLASH
+	ld [wMoveNum], a
+	predef CanLearnTM ; check if the pokemon can learn the move
+	ld a,c
+	pop hl
+	pop de
+	pop bc
+	and a
+	jp z, .nextMove
+	push hl
+	ld hl, wTempCoins1
+	set 1, [hl]
+	pop hl
+	ld b, FLASH
+	ld a,b
+	ld hl, FieldMoveDisplayData
+	jr .addMoveFindInFieldMoveDisplayData
 
 INCLUDE "data/moves/field_moves.asm"
Clone this wiki locally