Complete Inverse implementation, fix type matchups

Issues occurred resulting from an incomplete implementation of Inverse Battles from Commit #e59cc2b3292f3da336e89ef23b15b234bf469368.

Attempts to fix have been made through completing the implementation, which also accounts for proto-Fairy.

Additionally, some semi-invulnerable glitches have attempts made to resolve them, involving a generic list and 16bitification of the compare commands.

Damage processing seems iffy but this needs more testing. Type matchups function correctly, though.
This commit is contained in:
Llinos Evans 2025-01-11 06:33:35 +00:00
parent 90fe97fcb1
commit a14e978b98
4 changed files with 425 additions and 181 deletions

View file

@ -96,6 +96,7 @@ DEF SPDSPCDV_SHINY EQU $AA
const BATTLETYPE_FORCEITEM const BATTLETYPE_FORCEITEM
const BATTLETYPE_CELEBI const BATTLETYPE_CELEBI
const BATTLETYPE_SUICUNE const BATTLETYPE_SUICUNE
const BATTLETYPE_INVERSE
; BattleVarPairs indexes (see home/battle_vars.asm) ; BattleVarPairs indexes (see home/battle_vars.asm)
const_def const_def

View file

@ -130,3 +130,124 @@ TypeMatchups:
db FIGHTING, GHOST, NO_EFFECT db FIGHTING, GHOST, NO_EFFECT
db -1 ; end db -1 ; end
InverseTypeMatchups:
; attacker, defender, *=
db NORMAL, ROCK, SUPER_EFFECTIVE
db NORMAL, STEEL, SUPER_EFFECTIVE
db FIRE, FIRE, SUPER_EFFECTIVE
db FIRE, WATER, SUPER_EFFECTIVE
db FIRE, GRASS, NOT_VERY_EFFECTIVE
db FIRE, ICE, NOT_VERY_EFFECTIVE
db FIRE, BUG, NOT_VERY_EFFECTIVE
db FIRE, ROCK, SUPER_EFFECTIVE
db FIRE, DRAGON, SUPER_EFFECTIVE
db FIRE, STEEL, NOT_VERY_EFFECTIVE
db WATER, FIRE, NOT_VERY_EFFECTIVE
db WATER, WATER, SUPER_EFFECTIVE
db WATER, GRASS, SUPER_EFFECTIVE
db WATER, GROUND, NOT_VERY_EFFECTIVE
db WATER, ROCK, NOT_VERY_EFFECTIVE
db WATER, DRAGON, SUPER_EFFECTIVE
db ELECTRIC, WATER, NOT_VERY_EFFECTIVE
db ELECTRIC, ELECTRIC, SUPER_EFFECTIVE
db ELECTRIC, GRASS, SUPER_EFFECTIVE
db ELECTRIC, GROUND, SUPER_EFFECTIVE
db ELECTRIC, FLYING, NOT_VERY_EFFECTIVE
db ELECTRIC, DRAGON, SUPER_EFFECTIVE
db GRASS, FIRE, SUPER_EFFECTIVE
db GRASS, WATER, NOT_VERY_EFFECTIVE
db GRASS, GRASS, SUPER_EFFECTIVE
db GRASS, POISON, SUPER_EFFECTIVE
db GRASS, GROUND, NOT_VERY_EFFECTIVE
db GRASS, FLYING, SUPER_EFFECTIVE
db GRASS, BUG, SUPER_EFFECTIVE
db GRASS, ROCK, NOT_VERY_EFFECTIVE
db GRASS, DRAGON, SUPER_EFFECTIVE
db GRASS, STEEL, SUPER_EFFECTIVE
db ICE, WATER, SUPER_EFFECTIVE
db ICE, GRASS, NOT_VERY_EFFECTIVE
db ICE, ICE, SUPER_EFFECTIVE
db ICE, GROUND, NOT_VERY_EFFECTIVE
db ICE, FLYING, NOT_VERY_EFFECTIVE
db ICE, DRAGON, NOT_VERY_EFFECTIVE
db ICE, STEEL, SUPER_EFFECTIVE
db ICE, FIRE, SUPER_EFFECTIVE
db FIGHTING, NORMAL, NOT_VERY_EFFECTIVE
db FIGHTING, ICE, NOT_VERY_EFFECTIVE
db FIGHTING, POISON, SUPER_EFFECTIVE
db FIGHTING, FLYING, SUPER_EFFECTIVE
db FIGHTING, PSYCHIC_TYPE, SUPER_EFFECTIVE
db FIGHTING, BUG, SUPER_EFFECTIVE
db FIGHTING, ROCK, NOT_VERY_EFFECTIVE
db FIGHTING, DARK, NOT_VERY_EFFECTIVE
db FIGHTING, STEEL, NOT_VERY_EFFECTIVE
db POISON, GRASS, NOT_VERY_EFFECTIVE
db POISON, POISON, SUPER_EFFECTIVE
db POISON, GROUND, SUPER_EFFECTIVE
db POISON, ROCK, SUPER_EFFECTIVE
db POISON, GHOST, SUPER_EFFECTIVE
db POISON, STEEL, SUPER_EFFECTIVE
db GROUND, FIRE, NOT_VERY_EFFECTIVE
db GROUND, ELECTRIC, NOT_VERY_EFFECTIVE
db GROUND, GRASS, SUPER_EFFECTIVE
db GROUND, POISON, NOT_VERY_EFFECTIVE
db GROUND, FLYING, SUPER_EFFECTIVE
db GROUND, BUG, SUPER_EFFECTIVE
db GROUND, ROCK, NOT_VERY_EFFECTIVE
db GROUND, STEEL, NOT_VERY_EFFECTIVE
db FLYING, ELECTRIC, SUPER_EFFECTIVE
db FLYING, GRASS, NOT_VERY_EFFECTIVE
db FLYING, FIGHTING, NOT_VERY_EFFECTIVE
db FLYING, BUG, NOT_VERY_EFFECTIVE
db FLYING, ROCK, SUPER_EFFECTIVE
db FLYING, STEEL, SUPER_EFFECTIVE
db PSYCHIC_TYPE, FIGHTING, NOT_VERY_EFFECTIVE
db PSYCHIC_TYPE, POISON, NOT_VERY_EFFECTIVE
db PSYCHIC_TYPE, PSYCHIC_TYPE, SUPER_EFFECTIVE
db PSYCHIC_TYPE, DARK, SUPER_EFFECTIVE
db PSYCHIC_TYPE, STEEL, SUPER_EFFECTIVE
db BUG, FIRE, SUPER_EFFECTIVE
db BUG, GRASS, NOT_VERY_EFFECTIVE
db BUG, FIGHTING, SUPER_EFFECTIVE
db BUG, POISON, SUPER_EFFECTIVE
db BUG, FLYING, SUPER_EFFECTIVE
db BUG, PSYCHIC_TYPE, NOT_VERY_EFFECTIVE
db BUG, GHOST, SUPER_EFFECTIVE
db BUG, DARK, NOT_VERY_EFFECTIVE
db BUG, STEEL, SUPER_EFFECTIVE
db ROCK, FIRE, NOT_VERY_EFFECTIVE
db ROCK, ICE, NOT_VERY_EFFECTIVE
db ROCK, FIGHTING, SUPER_EFFECTIVE
db ROCK, GROUND, SUPER_EFFECTIVE
db ROCK, FLYING, NOT_VERY_EFFECTIVE
db ROCK, BUG, NOT_VERY_EFFECTIVE
db ROCK, STEEL, SUPER_EFFECTIVE
db GHOST, NORMAL, SUPER_EFFECTIVE
db GHOST, PSYCHIC_TYPE, NOT_VERY_EFFECTIVE
db GHOST, DARK, SUPER_EFFECTIVE
db GHOST, STEEL, SUPER_EFFECTIVE
db GHOST, GHOST, NOT_VERY_EFFECTIVE
db DRAGON, DRAGON, NOT_VERY_EFFECTIVE
db DRAGON, STEEL, SUPER_EFFECTIVE
db DARK, FIGHTING, SUPER_EFFECTIVE
db DARK, PSYCHIC_TYPE, NOT_VERY_EFFECTIVE
db DARK, GHOST, NOT_VERY_EFFECTIVE
db DARK, DARK, SUPER_EFFECTIVE
db DARK, STEEL, SUPER_EFFECTIVE
db STEEL, FIRE, SUPER_EFFECTIVE
db STEEL, WATER, SUPER_EFFECTIVE
db STEEL, ELECTRIC, SUPER_EFFECTIVE
db STEEL, ICE, NOT_VERY_EFFECTIVE
db STEEL, ROCK, NOT_VERY_EFFECTIVE
db STEEL, STEEL, SUPER_EFFECTIVE
db NORMAL, GHOST, SUPER_EFFECTIVE
db FIGHTING, GHOST, SUPER_EFFECTIVE
db FAIRY, FIRE, SUPER_EFFECTIVE
db FAIRY, BUG, NOT_VERY_EFFECTIVE
db FAIRY, FIGHTING, NOT_VERY_EFFECTIVE
db FAIRY, ICE, SUPER_EFFECTIVE
db FAIRY, DRAGON, NOT_VERY_EFFECTIVE
db FAIRY, DARK, NOT_VERY_EFFECTIVE
db FAIRY, STEEL, SUPER_EFFECTIVE
db -1 ; end

View file

@ -359,7 +359,7 @@ CantMove:
ld a, BATTLE_VARS_MOVE_ANIM ld a, BATTLE_VARS_MOVE_ANIM
call GetBattleVar call GetBattleVar
push hl push hl
ld hl, .fly_dig_moves ld hl, FlyDigMoves
call CheckMoveInList call CheckMoveInList
pop hl pop hl
ret nc ret nc
@ -371,13 +371,6 @@ CantMove:
res SUBSTATUS_UNDERWATER, [hl] res SUBSTATUS_UNDERWATER, [hl]
jp AppearUserRaiseSub jp AppearUserRaiseSub
.fly_dig_moves
dw FLY
dw DIG
dw BOUNCE
dw WATER_SPORT
dw -1
OpponentCantMove: OpponentCantMove:
call BattleCommand_SwitchTurn call BattleCommand_SwitchTurn
call CantMove call CantMove
@ -1370,7 +1363,13 @@ BattleCommand_Stab:
ld a, BATTLE_VARS_MOVE_TYPE ld a, BATTLE_VARS_MOVE_TYPE
call GetBattleVar call GetBattleVar
ld b, a ld b, a
ld a, [wBattleType]
cp BATTLETYPE_INVERSE
jr z, .inverse
ld hl, TypeMatchups ld hl, TypeMatchups
jr .TypesLoop
.inverse
ld hl, InverseTypeMatchups
.TypesLoop: .TypesLoop:
; ld a, [hli] ; ld a, [hli]
@ -1497,7 +1496,13 @@ CheckTypeMatchup:
ld c, [hl] ld c, [hl]
ld a, EFFECTIVE ld a, EFFECTIVE
ld [wTypeMatchup], a ld [wTypeMatchup], a
ld a, [wBattleType]
cp BATTLETYPE_INVERSE
jr z, .inverse
ld hl, TypeMatchups ld hl, TypeMatchups
jr .TypesLoop
.inverse
ld hl, InverseTypeMatchups
.TypesLoop: .TypesLoop:
; ld a, [hli] ; ld a, [hli]
call GetNextTypeMatchupsByte call GetNextTypeMatchupsByte
@ -1511,7 +1516,6 @@ CheckTypeMatchup:
bit SUBSTATUS_IDENTIFIED, a bit SUBSTATUS_IDENTIFIED, a
jr nz, .End jr nz, .End
jr .TypesLoop jr .TypesLoop
.Next: .Next:
cp d cp d
jr nz, .Nope jr nz, .Nope
@ -1788,6 +1792,7 @@ BattleCommand_CheckHit:
call GetBattleVar call GetBattleVar
and 1 << SUBSTATUS_FLYING | 1 << SUBSTATUS_UNDERGROUND and 1 << SUBSTATUS_FLYING | 1 << SUBSTATUS_UNDERGROUND
jr nz, .flying_or_underground jr nz, .flying_or_underground
ld a, BATTLE_VARS_SUBSTATUS4_OPP ld a, BATTLE_VARS_SUBSTATUS4_OPP
call GetBattleVar call GetBattleVar
and 1 << SUBSTATUS_UNDERWATER and 1 << SUBSTATUS_UNDERWATER
@ -1795,12 +1800,34 @@ BattleCommand_CheckHit:
ld a, BATTLE_VARS_MOVE_ANIM ld a, BATTLE_VARS_MOVE_ANIM
call GetBattleVar call GetBattleVar
cp SURF ld hl, SURF
call GetMoveIDFromIndex
ld a, h
if HIGH(SURF)
cp HIGH(SURF)
else
and a
endc
ld a, l
pop hl
ret nz
cp LOW(SURF)
ret z ret z
cp WHIRLPOOL ld hl, WHIRLPOOL
call GetMoveIDFromIndex
ld a, h
if HIGH(WHIRLPOOL)
cp HIGH(WHIRLPOOL)
else
and a
endc
ld a, l
pop hl
ret nz
cp LOW(WHIRLPOOL)
ret ret
.flying_or_underground
.flying_or_underground
bit SUBSTATUS_FLYING, a bit SUBSTATUS_FLYING, a
ld hl, .FlyMoves ld hl, .FlyMoves
jr z, .check_move_in_list jr z, .check_move_in_list
@ -2071,18 +2098,11 @@ BattleCommand_MoveAnimNoSub:
ld a, BATTLE_VARS_MOVE_ANIM ld a, BATTLE_VARS_MOVE_ANIM
call GetBattleVar call GetBattleVar
ld hl, .fly_dig_moves ld hl, FlyDigMoves
call CheckMoveInList call CheckMoveInList
ret nc ret nc
jp AppearUserLowerSub jp AppearUserLowerSub
.fly_dig_moves
dw FLY
dw DIG
dw BOUNCE
dw WATER_SPORT
dw -1
.alternate_anim .alternate_anim
ld a, [wBattleAnimParam] ld a, [wBattleAnimParam]
and 1 and 1
@ -2167,7 +2187,7 @@ BattleCommand_FailureText:
call GetBattleVarAddr call GetBattleVarAddr
push hl push hl
ld hl, .fly_dig_moves ld hl, FlyDigMoves
call CheckMoveInList call CheckMoveInList
pop hl pop hl
jr c, .fly_dig jr c, .fly_dig
@ -2200,13 +2220,6 @@ BattleCommand_FailureText:
call AppearUserRaiseSub call AppearUserRaiseSub
jp EndMoveEffect jp EndMoveEffect
.fly_dig_moves
dw FLY
dw DIG
dw WATER_SPORT
dw BOUNCE
dw -1
BattleCommand_ApplyDamage: BattleCommand_ApplyDamage:
ld a, BATTLE_VARS_SUBSTATUS1_OPP ld a, BATTLE_VARS_SUBSTATUS1_OPP
call GetBattleVar call GetBattleVar
@ -5645,26 +5658,134 @@ BattleCommand_Charge:
call LoadMoveAnim call LoadMoveAnim
ld a, BATTLE_VARS_MOVE_ANIM ld a, BATTLE_VARS_MOVE_ANIM
call GetBattleVar call GetBattleVar
ld hl, WATER_SPORT
ld hl, .fly_dig_moves ; attempt to resolve 16-bit issue with bounce and water sport - this can probably be made more efficient with a farcallable list call GetMoveIDFromIndex
call CheckMoveInList ld a, h
pop hl if HIGH(WATER_SPORT)
jr c, .got_move_type cp HIGH(WATER_SPORT)
call BattleCommand_RaiseSub else
xor a
.got_move_type
; a will contain the substatus 3 bit to set (1 << bit), or 0 if none (not flying/digging underground)
and a and a
ld l, a endc
push hl ld a, l
call nz, DisappearUser pop hl
ret nz
cp LOW(WATER_SPORT)
jp z, .set_diving
ld hl, FLY
call GetMoveIDFromIndex
ld a, h
if HIGH(FLY)
cp HIGH(FLY)
else
and a
endc
ld a, l
pop hl
ret nz
cp LOW(FLY)
jr z, .set_flying
ld hl, BOUNCE
call GetMoveIDFromIndex
ld a, h
if HIGH(BOUNCE)
cp HIGH(BOUNCE)
else
and a
endc
ld a, l
pop hl
ret nz
cp LOW(BOUNCE)
jr z, .set_flying
ld hl, DIG
call GetMoveIDFromIndex
ld a, h
if HIGH(DIG)
cp HIGH(DIG)
else
and a
endc
ld a, l
pop hl
ret nz
cp LOW(DIG)
jr z, .set_flying
call BattleCommand_RaiseSub
jr .not_flying
.flying
call DisappearUser
.not_flying
ld a, BATTLE_VARS_SUBSTATUS3 ld a, BATTLE_VARS_SUBSTATUS3
call GetBattleVarAddr call GetBattleVarAddr
pop bc ld a, BATTLE_VARS_MOVE_ANIM
ld a, c call GetBattleVar
or [hl] ld b, a
ld [hl], a ld hl, WATER_SPORT
call GetMoveIDFromIndex
ld a, h
if HIGH(WATER_SPORT)
cp HIGH(WATER_SPORT)
else
and a
endc
ld a, l
pop hl
ret nz
cp LOW(WATER_SPORT)
jr z, .set_diving
ld hl, FLY
call GetMoveIDFromIndex
ld a, h
if HIGH(FLY)
cp HIGH(FLY)
else
and a
endc
ld a, l
pop hl
ret nz
cp LOW(FLY)
jr z, .set_flying
ld hl, BOUNCE
call GetMoveIDFromIndex
ld a, h
if HIGH(BOUNCE)
cp HIGH(BOUNCE)
else
and a
endc
ld a, l
pop hl
ret nz
cp LOW(BOUNCE)
jr z, .set_flying
ld hl, DIG
call GetMoveIDFromIndex
ld a, h
if HIGH(DIG)
cp HIGH(DIG)
else
and a
endc
ld a, l
pop hl
ret nz
cp LOW(DIG)
jr z, .set_flying
jr nz, .dont_set_digging
set SUBSTATUS_UNDERGROUND, [hl]
jr .dont_set_digging
.set_diving
ld a, BATTLE_VARS_SUBSTATUS4
call GetBattleVarAddr
set SUBSTATUS_UNDERWATER, [hl]
jr .dont_set_digging
.set_flying
set SUBSTATUS_FLYING, [hl]
.dont_set_digging
call CheckUserIsCharging call CheckUserIsCharging
jr nz, .mimic jr nz, .mimic
ld a, BATTLE_VARS_LAST_COUNTER_MOVE ld a, BATTLE_VARS_LAST_COUNTER_MOVE
@ -5750,13 +5871,6 @@ BattleCommand_Charge:
text_jump HidUnderwaterText text_jump HidUnderwaterText
db "@" db "@"
.fly_dig_moves
dw FLY
dw DIG
dw BOUNCE
dw WATER_SPORT
dw -1
BattleCommand_TrapTarget: BattleCommand_TrapTarget:
ld a, [wAttackMissed] ld a, [wAttackMissed]
and a and a
@ -6132,6 +6246,7 @@ BattleCommand_DoubleUnderwaterDamage:
ld a, BATTLE_VARS_SUBSTATUS4_OPP ld a, BATTLE_VARS_SUBSTATUS4_OPP
call GetBattleVar call GetBattleVar
bit SUBSTATUS_UNDERWATER, a bit SUBSTATUS_UNDERWATER, a
ret z
; fallthrough ; fallthrough
DoubleDamage: DoubleDamage:
@ -6952,3 +7067,10 @@ CheckMoveInList:
pop de pop de
pop bc pop bc
ret ret
FlyDigMoves:
dw FLY
dw DIG
dw BOUNCE
dw WATER_SPORT
dw -1

View file

@ -8,12 +8,12 @@ DebugRoom_MapScripts:
DebugPokemon1Script: DebugPokemon1Script:
opentext opentext
getmonname STRING_BUFFER_3, AZUMARILL getmonname STRING_BUFFER_3, BIPULLA
writetext ReceivedDebugPokemonText writetext ReceivedDebugPokemonText
playsound SFX_CAUGHT_MON playsound SFX_CAUGHT_MON
waitsfx waitsfx
promptbutton promptbutton
givepoke AZUMARILL, 4, HM_WATER_SPORT givepoke BIPULLA, 15, HM_WATER_SPORT
closetext closetext
end end
@ -39,11 +39,11 @@ DebugPokemon3Script:
faceplayer faceplayer
opentext opentext
writetext DebugTextA writetext DebugTextA
cry STROMEN cry BELLSPROUT
pause 15 pause 15
closetext closetext
loadvar VAR_BATTLETYPE, BATTLETYPE_SHINY loadvar VAR_BATTLETYPE, BATTLETYPE_INVERSE
loadwildmon COATL, 75 loadwildmon BELLSPROUT, 10
startbattle startbattle
reloadmapafterbattle reloadmapafterbattle
end end
@ -56,11 +56,11 @@ DebugPokemon4Script:
faceplayer faceplayer
opentext opentext
writetext DebugTextB writetext DebugTextB
cry STROMEN cry BELLSPROUT
pause 15 pause 15
closetext closetext
loadvar VAR_BATTLETYPE, BATTLETYPE_SUICUNE loadvar VAR_BATTLETYPE, BATTLETYPE_SUICUNE
loadwildmon COATL, 75 loadwildmon BELLSPROUT, 10
startbattle startbattle
reloadmapafterbattle reloadmapafterbattle
end end