Refactors Absorb to use Moveend (#5670)

This commit is contained in:
Alex 2024-11-17 09:59:04 +01:00 committed by GitHub
parent 3481340da8
commit 67c7106fee
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 109 additions and 22 deletions

View file

@ -3012,30 +3012,18 @@ BattleScript_CantMakeAsleep::
orhalfword gMoveResultFlags, MOVE_RESULT_FAILED orhalfword gMoveResultFlags, MOVE_RESULT_FAILED
goto BattleScript_MoveEnd goto BattleScript_MoveEnd
BattleScript_EffectAbsorb:: BattleScript_EffectAbsorbLiquidOoze::
call BattleScript_EffectHit_Ret
jumpifstatus3 BS_ATTACKER, STATUS3_HEAL_BLOCK, BattleScript_AbsorbHealBlock
setdrainedhp
manipulatedamage DMG_BIG_ROOT
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_IGNORE_DISGUISE
jumpifability BS_TARGET, ABILITY_LIQUID_OOZE, BattleScript_AbsorbLiquidOoze
setbyte cMULTISTRING_CHOOSER, B_MSG_ABSORB
goto BattleScript_AbsorbUpdateHp
BattleScript_AbsorbLiquidOoze::
call BattleScript_AbilityPopUpTarget call BattleScript_AbilityPopUpTarget
manipulatedamage DMG_CHANGE_SIGN goto BattleScript_EffectAbsorb
setbyte cMULTISTRING_CHOOSER, B_MSG_ABSORB_OOZE
BattleScript_AbsorbUpdateHp:: BattleScript_EffectAbsorb::
healthbarupdate BS_ATTACKER healthbarupdate BS_ATTACKER
datahpupdate BS_ATTACKER datahpupdate BS_ATTACKER
jumpifmovehadnoeffect BattleScript_AbsorbTryFainting
printfromtable gAbsorbDrainStringIds printfromtable gAbsorbDrainStringIds
waitmessage B_WAIT_TIME_LONG waitmessage B_WAIT_TIME_LONG
BattleScript_AbsorbTryFainting::
tryfaintmon BS_ATTACKER tryfaintmon BS_ATTACKER
BattleScript_AbsorbHealBlock::
tryfaintmon BS_TARGET tryfaintmon BS_TARGET
goto BattleScript_MoveEnd return
BattleScript_EffectExplosion:: BattleScript_EffectExplosion::
attackcanceler attackcanceler

View file

@ -561,6 +561,7 @@ extern const u8 BattleScript_MoveBlockedByDynamax[];
// Battle move scripts // Battle move scripts
extern const u8 BattleScript_EffectSleep[]; extern const u8 BattleScript_EffectSleep[];
extern const u8 BattleScript_EffectAbsorb[]; extern const u8 BattleScript_EffectAbsorb[];
extern const u8 BattleScript_EffectAbsorbLiquidOoze[];
extern const u8 BattleScript_EffectExplosion[]; extern const u8 BattleScript_EffectExplosion[];
extern const u8 BattleScript_EffectDreamEater[]; extern const u8 BattleScript_EffectDreamEater[];
extern const u8 BattleScript_EffectMirrorMove[]; extern const u8 BattleScript_EffectMirrorMove[];

View file

@ -263,6 +263,7 @@ enum MoveEndEffects
{ {
MOVEEND_SUM_DAMAGE, MOVEEND_SUM_DAMAGE,
MOVEEND_PROTECT_LIKE_EFFECT, MOVEEND_PROTECT_LIKE_EFFECT,
MOVEEND_ABSORB,
MOVEEND_RAGE, MOVEEND_RAGE,
MOVEEND_SYNCHRONIZE_TARGET, MOVEEND_SYNCHRONIZE_TARGET,
MOVEEND_ABILITIES, MOVEEND_ABILITIES,

View file

@ -5712,6 +5712,38 @@ static void Cmd_moveend(void)
} }
gBattleScripting.moveendState++; gBattleScripting.moveendState++;
break; break;
case MOVEEND_ABSORB:
if (gMovesInfo[gCurrentMove].effect == EFFECT_ABSORB)
{
if (gStatuses3[gBattlerAttacker] & STATUS3_HEAL_BLOCK && gMovesInfo[gCurrentMove].healingMove)
{
gBattleScripting.moveendState++;
break;
}
else if (IsBattlerAlive(gBattlerAttacker) && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT))
{
gBattleMoveDamage = (gHpDealt * gMovesInfo[gCurrentMove].argument / 100);
if (gBattleMoveDamage == 0)
gBattleMoveDamage = 1;
gBattleMoveDamage = GetDrainedBigRootHp(gBattlerAttacker, gBattleMoveDamage);
gHitMarker |= HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_IGNORE_DISGUISE;
if (GetBattlerAbility(gBattlerTarget) == ABILITY_LIQUID_OOZE)
{
gBattleMoveDamage *= -1;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_ABSORB_OOZE;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_EffectAbsorbLiquidOoze;
}
else
{
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_ABSORB;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_EffectAbsorb;
}
}
}
gBattleScripting.moveendState++;
break;
case MOVEEND_RAGE: // rage check case MOVEEND_RAGE: // rage check
if (gBattleMons[gBattlerTarget].status2 & STATUS2_RAGE if (gBattleMons[gBattlerTarget].status2 & STATUS2_RAGE
&& IsBattlerAlive(gBattlerTarget) && IsBattlerAlive(gBattlerTarget)
@ -11344,12 +11376,12 @@ static void Cmd_manipulatedamage(void)
case DMG_FULL_ATTACKER_HP: case DMG_FULL_ATTACKER_HP:
gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker); gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker);
break; break;
case DMG_CURR_ATTACKER_HP:
gBattleMoveDamage = GetNonDynamaxHP(gBattlerAttacker);
break;
case DMG_BIG_ROOT: case DMG_BIG_ROOT:
gBattleMoveDamage = GetDrainedBigRootHp(gBattlerAttacker, gBattleMoveDamage); gBattleMoveDamage = GetDrainedBigRootHp(gBattlerAttacker, gBattleMoveDamage);
break; break;
case DMG_CURR_ATTACKER_HP:
gBattleMoveDamage = GetNonDynamaxHP(gBattlerAttacker);
break;
case DMG_RECOIL_FROM_IMMUNE: case DMG_RECOIL_FROM_IMMUNE:
gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerTarget) / 2; gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerTarget) / 2;
break; break;

View file

@ -24,7 +24,7 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] =
[EFFECT_ABSORB] = [EFFECT_ABSORB] =
{ {
.battleScript = BattleScript_EffectAbsorb, .battleScript = BattleScript_EffectHit,
.battleTvScore = 4, .battleTvScore = 4,
}, },

View file

@ -1874,6 +1874,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED, .target = MOVE_TARGET_SELECTED,
.priority = 0, .priority = 0,
.category = DAMAGE_CATEGORY_SPECIAL, .category = DAMAGE_CATEGORY_SPECIAL,
.argument = 50,
.ignoresKingsRock = (B_UPDATED_MOVE_FLAGS == GEN_3 || B_UPDATED_MOVE_FLAGS == GEN_4), .ignoresKingsRock = (B_UPDATED_MOVE_FLAGS == GEN_3 || B_UPDATED_MOVE_FLAGS == GEN_4),
.healingMove = B_HEAL_BLOCKING >= GEN_6, .healingMove = B_HEAL_BLOCKING >= GEN_6,
.contestEffect = CONTEST_EFFECT_STARTLE_PREV_MON, .contestEffect = CONTEST_EFFECT_STARTLE_PREV_MON,
@ -1895,6 +1896,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED, .target = MOVE_TARGET_SELECTED,
.priority = 0, .priority = 0,
.category = DAMAGE_CATEGORY_SPECIAL, .category = DAMAGE_CATEGORY_SPECIAL,
.argument = 50,
.zMove = { .powerOverride = 120 }, .zMove = { .powerOverride = 120 },
.ignoresKingsRock = (B_UPDATED_MOVE_FLAGS == GEN_3 || B_UPDATED_MOVE_FLAGS == GEN_4), .ignoresKingsRock = (B_UPDATED_MOVE_FLAGS == GEN_3 || B_UPDATED_MOVE_FLAGS == GEN_4),
.healingMove = B_HEAL_BLOCKING >= GEN_6, .healingMove = B_HEAL_BLOCKING >= GEN_6,
@ -3620,6 +3622,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED, .target = MOVE_TARGET_SELECTED,
.priority = 0, .priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL, .category = DAMAGE_CATEGORY_PHYSICAL,
.argument = 50,
.makesContact = TRUE, .makesContact = TRUE,
.ignoresKingsRock = (B_UPDATED_MOVE_FLAGS == GEN_3 || B_UPDATED_MOVE_FLAGS == GEN_4), .ignoresKingsRock = (B_UPDATED_MOVE_FLAGS == GEN_3 || B_UPDATED_MOVE_FLAGS == GEN_4),
.healingMove = B_HEAL_BLOCKING >= GEN_6, .healingMove = B_HEAL_BLOCKING >= GEN_6,
@ -5152,6 +5155,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED, .target = MOVE_TARGET_SELECTED,
.priority = 0, .priority = 0,
.category = DAMAGE_CATEGORY_SPECIAL, .category = DAMAGE_CATEGORY_SPECIAL,
.argument = 50,
.ignoresKingsRock = (B_UPDATED_MOVE_FLAGS == GEN_3 || B_UPDATED_MOVE_FLAGS == GEN_4), .ignoresKingsRock = (B_UPDATED_MOVE_FLAGS == GEN_3 || B_UPDATED_MOVE_FLAGS == GEN_4),
.healingMove = B_HEAL_BLOCKING >= GEN_6, .healingMove = B_HEAL_BLOCKING >= GEN_6,
.contestEffect = CONTEST_EFFECT_STARTLE_MON_WITH_JUDGES_ATTENTION, .contestEffect = CONTEST_EFFECT_STARTLE_MON_WITH_JUDGES_ATTENTION,
@ -10264,6 +10268,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED, .target = MOVE_TARGET_SELECTED,
.priority = 0, .priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL, .category = DAMAGE_CATEGORY_PHYSICAL,
.argument = 50,
.makesContact = TRUE, .makesContact = TRUE,
.punchingMove = TRUE, .punchingMove = TRUE,
.healingMove = B_HEAL_BLOCKING >= GEN_6, .healingMove = B_HEAL_BLOCKING >= GEN_6,
@ -13244,6 +13249,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED, .target = MOVE_TARGET_SELECTED,
.priority = 0, .priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL, .category = DAMAGE_CATEGORY_PHYSICAL,
.argument = 50,
.makesContact = TRUE, .makesContact = TRUE,
.healingMove = B_HEAL_BLOCKING >= GEN_6, .healingMove = B_HEAL_BLOCKING >= GEN_6,
.contestEffect = CONTEST_EFFECT_STARTLE_MON_WITH_JUDGES_ATTENTION, .contestEffect = CONTEST_EFFECT_STARTLE_MON_WITH_JUDGES_ATTENTION,
@ -14200,6 +14206,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_FOES_AND_ALLY, .target = MOVE_TARGET_FOES_AND_ALLY,
.priority = 0, .priority = 0,
.category = DAMAGE_CATEGORY_SPECIAL, .category = DAMAGE_CATEGORY_SPECIAL,
.argument = 50,
.healingMove = B_HEAL_BLOCKING >= GEN_6, .healingMove = B_HEAL_BLOCKING >= GEN_6,
.contestEffect = CONTEST_EFFECT_STARTLE_MON_WITH_JUDGES_ATTENTION, .contestEffect = CONTEST_EFFECT_STARTLE_MON_WITH_JUDGES_ATTENTION,
.contestCategory = CONTEST_CATEGORY_BEAUTY, .contestCategory = CONTEST_CATEGORY_BEAUTY,
@ -20021,6 +20028,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED, .target = MOVE_TARGET_SELECTED,
.priority = 0, .priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL, .category = DAMAGE_CATEGORY_PHYSICAL,
.argument = 50,
.makesContact = TRUE, .makesContact = TRUE,
.slicingMove = TRUE, .slicingMove = TRUE,
.healingMove = TRUE, .healingMove = TRUE,
@ -20322,6 +20330,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_BOTH, .target = MOVE_TARGET_BOTH,
.priority = 0, .priority = 0,
.category = DAMAGE_CATEGORY_SPECIAL, .category = DAMAGE_CATEGORY_SPECIAL,
.argument = 50,
.thawsUser = TRUE, .thawsUser = TRUE,
.metronomeBanned = TRUE, .metronomeBanned = TRUE,
.healingMove = B_EXTRAPOLATED_MOVE_FLAGS, .healingMove = B_EXTRAPOLATED_MOVE_FLAGS,

View file

@ -24,6 +24,25 @@ SINGLE_BATTLE_TEST("Absorb recovers 50% of the damage dealt")
} }
} }
SINGLE_BATTLE_TEST("Absorb deals 50% of the damage dealt to user agains Liquid Ooze")
{
s16 damage;
s16 healed;
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_TENTACOOL) { Ability(ABILITY_LIQUID_OOZE); }
} WHEN {
TURN { MOVE(player, MOVE_ABSORB); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_ABSORB, player);
HP_BAR(opponent, captureDamage: &damage);
HP_BAR(player, captureDamage: &healed);
MESSAGE("Wobbuffet sucked up the liquid ooze!");
} THEN {
EXPECT_MUL_EQ(damage, Q_4_12(0.5), healed);
}
}
SINGLE_BATTLE_TEST("Absorb fails if Heal Block applies") SINGLE_BATTLE_TEST("Absorb fails if Heal Block applies")
{ {
GIVEN { GIVEN {
@ -69,5 +88,42 @@ DOUBLE_BATTLE_TEST("Matcha Gatcha recovers 50% of the damage dealt from both tar
} }
} }
DOUBLE_BATTLE_TEST("Matcha Gatcha will faint the pokemon if Liquid Ooze drain deals enough damage")
{
GIVEN {
ASSUME(gMovesInfo[MOVE_MATCHA_GOTCHA].effect == EFFECT_ABSORB);
PLAYER(SPECIES_WOBBUFFET) { HP(1); }
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_TENTACOOL) { Ability(ABILITY_LIQUID_OOZE); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(playerLeft, MOVE_MATCHA_GOTCHA); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_MATCHA_GOTCHA, playerLeft);
HP_BAR(opponentLeft);
HP_BAR(playerLeft);
MESSAGE("Wobbuffet sucked up the liquid ooze!");
MESSAGE("Wobbuffet fainted!");
}
}
SINGLE_BATTLE_TEST("Draining Kiss recovers 75% of the damage dealt")
{
s16 damage;
s16 healed;
GIVEN {
PLAYER(SPECIES_WOBBUFFET) { HP(1); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_DRAINING_KISS); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAINING_KISS, player);
HP_BAR(opponent, captureDamage: &damage);
HP_BAR(player, captureDamage: &healed);
} THEN {
EXPECT_MUL_EQ(damage, Q_4_12(-0.75), healed);
}
}
TO_DO_BATTLE_TEST("Absorb recovers 50% of the damage dealt to a Substitute"); TO_DO_BATTLE_TEST("Absorb recovers 50% of the damage dealt to a Substitute");
TO_DO_BATTLE_TEST("Draining Kiss recovers 75% of the damage dealt"); // Tests .argument 's implementation