Combine Simple Beam and Worry Seed into one effect (#8039)

Co-authored-by: PhallenTree <168426989+PhallenTree@users.noreply.github.com>
This commit is contained in:
Alex 2025-10-29 15:20:12 +01:00 committed by GitHub
parent 5873621154
commit dd875b87bc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 51 additions and 107 deletions

View File

@ -1340,7 +1340,7 @@
.byte \trigger
.endm
.macro tryworryseed failInstr:req
.macro tryoverwriteability failInstr:req
.byte 0xfe
.4byte \failInstr
.endm
@ -2161,11 +2161,6 @@
.4byte \failInstr
.endm
.macro setsimplebeam failInstr:req
callnative BS_SetSimpleBeam
.4byte \failInstr
.endm
.macro tryentrainment failInstr:req
callnative BS_TryEntrainment
.4byte \failInstr

View File

@ -1991,23 +1991,6 @@ BattleScript_EffectEntrainment::
tryendneutralizinggas
goto BattleScript_MoveEnd
BattleScript_EffectSimpleBeam::
attackcanceler
accuracycheck BattleScript_MoveMissedPause, ACC_CURR_MOVE
setsimplebeam BattleScript_ButItFailed
attackanimation
waitanimation
copybyte gBattlerAbility, gBattlerTarget
call BattleScript_AbilityPopUpOverwriteThenNormal
recordability BS_TARGET
printstring STRINGID_PKMNACQUIREDSIMPLE
waitmessage B_WAIT_TIME_LONG
trytoclearprimalweather
tryrevertweatherform
flushtextbox
tryendneutralizinggas
goto BattleScript_MoveEnd
BattleScript_EffectLuckyChant::
attackcanceler
setluckychant BattleScript_ButItFailed
@ -2081,10 +2064,10 @@ BattleScript_EffectHealingWishRestore:
waitmessage B_WAIT_TIME_LONG
return
BattleScript_EffectWorrySeed::
BattleScript_EffectOverwriteAbility::
attackcanceler
accuracycheck BattleScript_MoveMissedPause, ACC_CURR_MOVE
tryworryseed BattleScript_ButItFailed
tryoverwriteability BattleScript_ButItFailed
attackanimation
waitanimation
copybyte gBattlerAbility, gBattlerTarget

View File

@ -248,8 +248,8 @@ bool32 AI_IsBattlerAsleepOrComatose(u32 battlerId);
bool32 IsMoxieTypeAbility(enum Ability ability);
bool32 DoesAbilityRaiseStatsWhenLowered(enum Ability ability);
bool32 ShouldTriggerAbility(u32 battlerAtk, u32 battlerDef, enum Ability ability);
bool32 CanEffectChangeAbility(u32 battlerAtk, u32 battlerDef, u32 effect, struct AiLogicData *aiData);
void AbilityChangeScore(u32 battlerAtk, u32 battlerDef, u32 effect, s32 *score, struct AiLogicData *aiData);
bool32 CanEffectChangeAbility(u32 battlerAtk, u32 battlerDef, u32 move, struct AiLogicData *aiData);
void AbilityChangeScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score, struct AiLogicData *aiData);
s32 BattlerBenefitsFromAbilityScore(u32 battler, enum Ability ability, struct AiLogicData *aiData);
// partner logic

View File

@ -678,7 +678,7 @@ extern const u8 BattleScript_EffectSoftboiled[];
extern const u8 BattleScript_EffectStockpile[];
extern const u8 BattleScript_EffectSpitUp[];
extern const u8 BattleScript_EffectSwallow[];
extern const u8 BattleScript_EffectWorrySeed[];
extern const u8 BattleScript_EffectOverwriteAbility[];
extern const u8 BattleScript_EffectHail[];
extern const u8 BattleScript_EffectTorment[];
extern const u8 BattleScript_EffectFlatter[];
@ -739,7 +739,6 @@ extern const u8 BattleScript_EffectGuardSplit[];
extern const u8 BattleScript_EffectStickyWeb[];
extern const u8 BattleScript_EffectMetalBurst[];
extern const u8 BattleScript_EffectLuckyChant[];
extern const u8 BattleScript_EffectSimpleBeam[];
extern const u8 BattleScript_EffectEntrainment[];
extern const u8 BattleScript_EffectHealPulse[];
extern const u8 BattleScript_EffectQuash[];

View File

@ -133,7 +133,7 @@ enum __attribute__((packed)) BattleMoveEffects
EFFECT_STOCKPILE,
EFFECT_SPIT_UP,
EFFECT_SWALLOW,
EFFECT_WORRY_SEED,
EFFECT_OVERWRITE_ABILITY,
EFFECT_HAIL,
EFFECT_TORMENT,
EFFECT_FLATTER,
@ -218,7 +218,6 @@ enum __attribute__((packed)) BattleMoveEffects
EFFECT_METAL_BURST,
EFFECT_LUCKY_CHANT,
EFFECT_SUCKER_PUNCH,
EFFECT_SIMPLE_BEAM,
EFFECT_ENTRAINMENT,
EFFECT_HEAL_PULSE,
EFFECT_QUASH,

View File

@ -149,6 +149,7 @@ struct MoveInfo
u32 absorbPercentage;
u32 recoilPercentage;
u32 nonVolatileStatus;
u32 overwriteAbility;
} argument;
// primary/secondary effects
@ -564,6 +565,11 @@ static inline u32 GetMoveDamagePercentage(u32 move)
return gMovesInfo[SanitizeMoveId(move)].argument.damagePercentage;
}
static inline u32 GetMoveOverwriteAbility(u32 move)
{
return gMovesInfo[SanitizeMoveId(move)].argument.overwriteAbility;
}
static inline const struct AdditionalEffect *GetMoveAdditionalEffectById(u32 moveId, u32 effect)
{
return &gMovesInfo[SanitizeMoveId(moveId)].additionalEffects[effect];

View File

@ -2473,10 +2473,9 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
case EFFECT_ENTRAINMENT:
case EFFECT_GASTRO_ACID:
case EFFECT_ROLE_PLAY:
case EFFECT_SIMPLE_BEAM:
case EFFECT_SKILL_SWAP:
case EFFECT_WORRY_SEED:
if (!CanEffectChangeAbility(battlerAtk, battlerDef, moveEffect, aiData)
case EFFECT_OVERWRITE_ABILITY:
if (!CanEffectChangeAbility(battlerAtk, battlerDef, move, aiData)
|| DoesPartnerHaveSameMoveEffect(BATTLE_PARTNER(battlerAtk), battlerDef, move, aiData->partnerMove))
ADJUST_AND_RETURN_SCORE(NO_DAMAGE_OR_FAILS);
break;
@ -3600,10 +3599,9 @@ static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
case EFFECT_ENTRAINMENT:
case EFFECT_GASTRO_ACID:
case EFFECT_ROLE_PLAY:
case EFFECT_SIMPLE_BEAM:
case EFFECT_SKILL_SWAP:
case EFFECT_WORRY_SEED:
AbilityChangeScore(battlerAtk, battlerAtkPartner, effect, &score, aiData);
case EFFECT_OVERWRITE_ABILITY:
AbilityChangeScore(battlerAtk, battlerAtkPartner, move, &score, aiData);
return score;
case EFFECT_SPICY_EXTRACT:
if (AI_ShouldSpicyExtract(battlerAtk, battlerAtkPartner, move, aiData))
@ -5088,10 +5086,9 @@ static s32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move, stru
case EFFECT_ENTRAINMENT:
case EFFECT_GASTRO_ACID:
case EFFECT_ROLE_PLAY:
case EFFECT_SIMPLE_BEAM:
case EFFECT_SKILL_SWAP:
case EFFECT_WORRY_SEED:
AbilityChangeScore(battlerAtk, battlerDef, moveEffect, &score, aiData);
case EFFECT_OVERWRITE_ABILITY:
AbilityChangeScore(battlerAtk, battlerDef, move, &score, aiData);
return score;
case EFFECT_IMPRISON:
if (predictedMove != MOVE_NONE && HasMove(battlerAtk, predictedMove))

View File

@ -4185,9 +4185,8 @@ static u32 GetAIEffectGroup(enum BattleMoveEffects effect)
case EFFECT_ENTRAINMENT:
case EFFECT_GASTRO_ACID:
case EFFECT_ROLE_PLAY:
case EFFECT_SIMPLE_BEAM:
case EFFECT_SKILL_SWAP:
case EFFECT_WORRY_SEED:
case EFFECT_OVERWRITE_ABILITY:
aiEffect |= AI_EFFECT_CHANGE_ABILITY;
break;
default:
@ -5757,8 +5756,10 @@ bool32 ShouldTriggerAbility(u32 battlerAtk, u32 battlerDef, enum Ability ability
// Used by CheckBadMove; this is determining purely if the effect CAN change an ability, not if it SHOULD.
// At the moment, the parts about Mummy and Wandering Spirit are not actually used.
bool32 CanEffectChangeAbility(u32 battlerAtk, u32 battlerDef, u32 effect, struct AiLogicData *aiData)
bool32 CanEffectChangeAbility(u32 battlerAtk, u32 battlerDef, u32 move, struct AiLogicData *aiData)
{
u32 effect = GetMoveEffect(move);
// Dynamaxed Pokemon are immune to some ability-changing effects.
if (GetActiveGimmick(battlerDef) == GIMMICK_DYNAMAX)
{
@ -5834,13 +5835,8 @@ bool32 CanEffectChangeAbility(u32 battlerAtk, u32 battlerDef, u32 effect, struct
return FALSE;
break;
case EFFECT_SIMPLE_BEAM:
if (defAbility == ABILITY_SIMPLE || gAbilitiesInfo[defAbility].cantBeOverwritten)
return FALSE;
break;
case EFFECT_WORRY_SEED:
if (defAbility == ABILITY_INSOMNIA || gAbilitiesInfo[defAbility].cantBeOverwritten)
case EFFECT_OVERWRITE_ABILITY:
if (defAbility == GetMoveOverwriteAbility(move) || gAbilitiesInfo[defAbility].cantBeOverwritten)
return FALSE;
break;
@ -5855,9 +5851,8 @@ bool32 CanEffectChangeAbility(u32 battlerAtk, u32 battlerDef, u32 effect, struct
case EFFECT_ENTRAINMENT:
case EFFECT_GASTRO_ACID:
case EFFECT_ROLE_PLAY:
case EFFECT_SIMPLE_BEAM:
case EFFECT_SKILL_SWAP:
case EFFECT_WORRY_SEED:
case EFFECT_OVERWRITE_ABILITY:
return FALSE;
default:
break;
@ -5886,17 +5881,17 @@ bool32 DoesEffectReplaceTargetAbility(u32 effect)
{
case EFFECT_ENTRAINMENT:
case EFFECT_GASTRO_ACID:
case EFFECT_SIMPLE_BEAM:
case EFFECT_SKILL_SWAP:
case EFFECT_WORRY_SEED:
case EFFECT_OVERWRITE_ABILITY:
return TRUE;
default:
return FALSE;
}
}
void AbilityChangeScore(u32 battlerAtk, u32 battlerDef, u32 effect, s32 *score, struct AiLogicData *aiData)
void AbilityChangeScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score, struct AiLogicData *aiData)
{
u32 effect = GetMoveEffect(move);
bool32 isTargetingPartner = IsTargetingPartner(battlerAtk, battlerDef);
enum Ability abilityAtk = aiData->abilities[battlerAtk];
enum Ability abilityDef = aiData->abilities[battlerDef];
@ -5914,10 +5909,8 @@ void AbilityChangeScore(u32 battlerAtk, u32 battlerDef, u32 effect, s32 *score,
if (effect == EFFECT_GASTRO_ACID)
abilityAtk = ABILITY_NONE;
else if (effect == EFFECT_SIMPLE_BEAM)
abilityAtk = ABILITY_SIMPLE;
else if (effect == EFFECT_WORRY_SEED)
abilityAtk = ABILITY_INSOMNIA;
else if (effect == EFFECT_OVERWRITE_ABILITY)
abilityAtk = GetMoveOverwriteAbility(move);
if (effect == EFFECT_DOODLE || effect == EFFECT_ROLE_PLAY || effect == EFFECT_SKILL_SWAP)
{

View File

@ -592,7 +592,7 @@ static void Cmd_swapstatstages(void);
static void Cmd_averagestats(void);
static void Cmd_jumpifcaptivateaffected(void);
static void Cmd_setnonvolatilestatus(void);
static void Cmd_tryworryseed(void);
static void Cmd_tryoverwriteability(void);
static void Cmd_callnative(void);
void (*const gBattleScriptingCommandsTable[])(void) =
@ -851,7 +851,7 @@ void (*const gBattleScriptingCommandsTable[])(void) =
Cmd_averagestats, //0xFB
Cmd_jumpifcaptivateaffected, //0xFC
Cmd_setnonvolatilestatus, //0xFD
Cmd_tryworryseed, //0xFE
Cmd_tryoverwriteability, //0xFE
Cmd_callnative, //0xFF
};
@ -14320,12 +14320,12 @@ static void Cmd_setnonvolatilestatus(void)
}
}
static void Cmd_tryworryseed(void)
static void Cmd_tryoverwriteability(void)
{
CMD_ARGS(const u8 *failInstr);
if (gAbilitiesInfo[gBattleMons[gBattlerTarget].ability].cantBeOverwritten
|| gBattleMons[gBattlerTarget].ability == ABILITY_INSOMNIA)
|| gBattleMons[gBattlerTarget].ability == GetMoveOverwriteAbility(gCurrentMove))
{
RecordAbilityBattle(gBattlerTarget, gBattleMons[gBattlerTarget].ability);
gBattlescriptCurrInstr = cmd->failInstr;
@ -14342,7 +14342,7 @@ static void Cmd_tryworryseed(void)
RemoveAbilityFlags(gBattlerTarget);
gBattleScripting.abilityPopupOverwrite = gBattleMons[gBattlerTarget].ability;
gBattleMons[gBattlerTarget].ability = gDisableStructs[gBattlerTarget].overwrittenAbility = ABILITY_INSOMNIA;
gBattleMons[gBattlerTarget].ability = gDisableStructs[gBattlerTarget].overwrittenAbility = GetMoveOverwriteAbility(gCurrentMove);
gBattlescriptCurrInstr = cmd->nextInstr;
}
}
@ -17145,32 +17145,6 @@ void BS_SetLuckyChant(void)
}
}
void BS_SetSimpleBeam(void)
{
NATIVE_ARGS(const u8 *failInstr);
if (gAbilitiesInfo[gBattleMons[gBattlerTarget].ability].cantBeOverwritten
|| gBattleMons[gBattlerTarget].ability == ABILITY_SIMPLE)
{
RecordAbilityBattle(gBattlerTarget, gBattleMons[gBattlerTarget].ability);
gBattlescriptCurrInstr = cmd->failInstr;
}
else if (CanAbilityShieldActivateForBattler(gBattlerTarget))
{
gBattlescriptCurrInstr = BattleScript_MoveEnd;
BattleScriptCall(BattleScript_AbilityShieldProtects);
}
else
{
if (gBattleMons[gBattlerTarget].ability == ABILITY_NEUTRALIZING_GAS)
gSpecialStatuses[gBattlerTarget].neutralizingGasRemoved = TRUE;
RemoveAbilityFlags(gBattlerTarget);
gBattleScripting.abilityPopupOverwrite = gBattleMons[gBattlerTarget].ability;
gBattleMons[gBattlerTarget].ability = gDisableStructs[gBattlerTarget].overwrittenAbility = ABILITY_SIMPLE;
gBattlescriptCurrInstr = cmd->nextInstr;
}
}
void BS_TryEntrainment(void)
{
NATIVE_ARGS(const u8 *failInstr);

View File

@ -851,9 +851,9 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] =
.encourageEncore = TRUE,
},
[EFFECT_WORRY_SEED] =
[EFFECT_OVERWRITE_ABILITY] =
{
.battleScript = BattleScript_EffectWorrySeed,
.battleScript = BattleScript_EffectOverwriteAbility,
.battleTvScore = 0, // TODO: Assign points
.encourageEncore = TRUE,
},
@ -1395,13 +1395,7 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] =
.battleScript = BattleScript_EffectHit,
.battleTvScore = 0, // TODO: Assign points
},
[EFFECT_SIMPLE_BEAM] =
{
.battleScript = BattleScript_EffectSimpleBeam,
.battleTvScore = 0, // TODO: Assign points
},
[EFFECT_ENTRAINMENT] =
{
.battleScript = BattleScript_EffectEntrainment,

View File

@ -10146,7 +10146,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] =
.description = COMPOUND_STRING(
"Plants a seed on the foe\n"
"giving it Insomnia."),
.effect = EFFECT_WORRY_SEED,
.effect = EFFECT_OVERWRITE_ABILITY,
.power = 0,
.type = TYPE_GRASS,
.accuracy = 100,
@ -10154,6 +10154,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_STATUS,
.argument = { .overwriteAbility = ABILITY_INSOMNIA },
.zMove = { .effect = Z_EFFECT_SPD_UP_1 },
.magicCoatAffected = TRUE,
.contestEffect = CONTEST_EFFECT_MAKE_FOLLOWING_MONS_NERVOUS,
@ -12714,7 +12715,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] =
.description = COMPOUND_STRING(
"A beam that changes the\n"
"foe's Ability to Simple."),
.effect = EFFECT_SIMPLE_BEAM,
.effect = EFFECT_OVERWRITE_ABILITY,
.power = 0,
.type = TYPE_NORMAL,
.accuracy = 100,
@ -12722,6 +12723,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_STATUS,
.argument = { .overwriteAbility = ABILITY_SIMPLE },
.zMove = { .effect = Z_EFFECT_SPATK_UP_1 },
.magicCoatAffected = TRUE,
.contestEffect = CONTEST_EFFECT_APPEAL_AS_GOOD_AS_PREV_ONES,

View File

@ -102,7 +102,7 @@ SINGLE_BATTLE_TEST("Illusion breaks if affected by Gastro Acid")
SINGLE_BATTLE_TEST("Illusion breaks if user loses Illusion due to Worry Seed")
{
GIVEN {
ASSUME(GetMoveEffect(MOVE_WORRY_SEED) == EFFECT_WORRY_SEED);
ASSUME(GetMoveEffect(MOVE_WORRY_SEED) == EFFECT_OVERWRITE_ABILITY);
PLAYER(SPECIES_ZOROARK);
PLAYER(SPECIES_WYNAUT);
OPPONENT(SPECIES_WOBBUFFET);

View File

@ -39,7 +39,7 @@ DOUBLE_BATTLE_TEST("Teraform Zero can be supressed")
SINGLE_BATTLE_TEST("Teraform Zero can be replaced")
{
GIVEN {
ASSUME(GetMoveEffect(MOVE_WORRY_SEED) == EFFECT_WORRY_SEED);
ASSUME(GetMoveEffect(MOVE_WORRY_SEED) == EFFECT_OVERWRITE_ABILITY);
ASSUME(GetMoveEffect(MOVE_REST) == EFFECT_REST);
PLAYER(SPECIES_TERAPAGOS);
OPPONENT(SPECIES_WHIMSICOTT) { Ability(ABILITY_PRANKSTER); }

View File

@ -84,8 +84,8 @@ SINGLE_BATTLE_TEST("Gastro Acid, Worry Seed, and Simple Beam fail if the target
GIVEN {
ASSUME(GetMoveEffect(MOVE_GASTRO_ACID) == EFFECT_GASTRO_ACID);
ASSUME(GetMoveEffect(MOVE_WORRY_SEED) == EFFECT_WORRY_SEED);
ASSUME(GetMoveEffect(MOVE_SIMPLE_BEAM) == EFFECT_SIMPLE_BEAM);
ASSUME(GetMoveEffect(MOVE_WORRY_SEED) == EFFECT_OVERWRITE_ABILITY);
ASSUME(GetMoveEffect(MOVE_SIMPLE_BEAM) == EFFECT_OVERWRITE_ABILITY);
PLAYER(SPECIES_PALAFIN_ZERO) { Ability(ABILITY_ZERO_TO_HERO); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {

View File

@ -3,7 +3,8 @@
ASSUMPTIONS
{
ASSUME(GetMoveEffect(MOVE_SIMPLE_BEAM) == EFFECT_SIMPLE_BEAM);
ASSUME(GetMoveEffect(MOVE_SIMPLE_BEAM) == EFFECT_OVERWRITE_ABILITY);
ASSUME(GetMoveOverwriteAbility(MOVE_SIMPLE_BEAM) == ABILITY_SIMPLE);
}
SINGLE_BATTLE_TEST("Simple Beam replaces target's ability with Simple")

View File

@ -3,7 +3,8 @@
ASSUMPTIONS
{
ASSUME(GetMoveEffect(MOVE_WORRY_SEED) == EFFECT_WORRY_SEED);
ASSUME(GetMoveEffect(MOVE_WORRY_SEED) == EFFECT_OVERWRITE_ABILITY);
ASSUME(GetMoveOverwriteAbility(MOVE_WORRY_SEED) == ABILITY_INSOMNIA);
}
SINGLE_BATTLE_TEST("Worry Seed replaces target's ability with Insomnia")