Skip to content

Check base power before skipping damage calculation

Xillicis edited this page Apr 11, 2023 · 9 revisions

Check base power before skipping damage calculation

DISCLAIMER: The modifications listed in this tutorial have not been fully tested. Unforseen glitches or strange behavior could occur. However, the results seem to be working as intended. Please make a note in this tutorial or let me know on Discord (@Xillicis) if you discover any issues.

The main motivation for this tutorial is to make it easier to implement new moves such as Mud Slap, Fire Lash, Chilling Water, Low Sweep, Mud Shot, etc...

Take for example Mud Slap. The base power is 20 and the move always lowers the targets accuracy (assuming the move didn't miss). In generation 1, moves that always lower a stat like Sand Attack or Tail Whip will automatically skip the damage calculation. Therefore, if we try to implement Mud Slap following this tutorial Add a New Move and use the ACCURACY_DOWN1_EFFECT as the move effect, the move will never deal damage.

We will solve this issue by checking that the base power is not zero. Open up engine/battle/core.asm and make the following change,

...
.next
	ld a, [wPlayerMoveEffect]
	ld hl, ResidualEffects2
	ld de, 1
	call IsInArray
-	jp c, JumpMoveEffect ; done here after executing effects of ResidualEffects2
+	jr nc, .notResidual2Effect
+	ld a, [wPlayerMovePower]
+	and a ; check if zero base power
+	jp z, JumpMoveEffect
+.notResidual2Effect
	ld a, [wMoveMissed]
	and a
	jr z, .moveDidNotMiss
...

Note this is for the players move, so we also need to make a similar change for the enemy's move. Head down a bit farther to about line 5773 and make the change,

...
	ld hl, ResidualEffects2
	ld de, $1
	call IsInArray
-	jp c, JumpMoveEffect
+	jr nc, .notResidual2EffectEnemy
+	ld a, [wEnemyMovePower]
+	and a ; Check if zero base power
+	jp z, JumpMoveEffect
+.notResidual2EffectEnemy
	ld a, [wMoveMissed]
	and a
	jr z, .moveDidNotMiss
...

Damage will now be applied properly; however, if you try the move out, you'll find that the animation will play twice. Once for the damage and once for the stat reduction. There are two corrections that have to be made for this. The first, is if the move increased the user's stat, e.g. Flame Charge. The second is if the move lowered the opponent's stat, e.g. Mud Slap. To correct this, open up engine/battle/effects.asm and make the following change,

...
        call nz, Bankswitch
        pop de
.notMinimize
+       ldh a, [hWhoseTurn]
+       and a
+       ld a, [wPlayerMovePower]
+       jr z, .gotUsersPower1
+       ld a, [wEnemyMovePower]
+.gotUsersPower1
+       and a ; Skip animation if damage dealing move
+       jr nz, .skipAnimation
        call PlayCurrentMoveAnimation
+.skipAnimation
        ld a, [de]
        cp MINIMIZE
        jr nz, .applyBadgeBoostsAndStatusPenalties
...

Go down a bit further and make the following changes,

...
ld a, [de]
        cp $44
        jr nc, .ApplyBadgeBoostsAndStatusPenalties
+       ldh a, [hWhoseTurn] ; check who is using the move
+       and a
+	ld a, [wPlayerMovePower]
+       jr z, .gotUsersPower2
+       ld a, [wEnemyMovePower]
+.gotUsersPower2
+	and a ; Skip animation if damage dealing move
+	jr nz, .ApplyBadgeBoostsAndStatusPenalties
        call PlayCurrentMoveAnimation2
.ApplyBadgeBoostsAndStatusPenalties
...

That's it. Note that these changes should work for any of the stat up or down effects listed in data/battle/residual_effects_2.asm

Clone this wiki locally