Fix destiny knot behavior and add tests (#8174)

This commit is contained in:
FosterProgramming 2025-11-09 15:03:43 +01:00 committed by GitHub
parent c2c0c06a6f
commit bdaf4ae3b3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 77 additions and 22 deletions

View File

@ -1970,12 +1970,6 @@
.4byte \jumpInstr
.endm
.macro infatuatewithbattler battler:req, infatuateWith:req
callnative BS_InfatuateWithBattler
.byte \battler
.byte \infatuateWith
.endm
.macro setlastuseditem battler:req
callnative BS_SetLastUsedItem
.byte \battler

View File

@ -4025,26 +4025,27 @@ BattleScript_FuryCutterHit:
BattleScript_TryDestinyKnotTarget:
jumpifnoholdeffect BS_ATTACKER, HOLD_EFFECT_DESTINY_KNOT, BattleScript_TryDestinyKnotTargetRet
infatuatewithbattler BS_TARGET, BS_ATTACKER
playanimation BS_ATTACKER, B_ANIM_HELD_ITEM_EFFECT
waitanimation
printstring STRINGID_DESTINYKNOTACTIVATES
tryinfatuating BattleScript_ButItFailed
volatileanimation BS_TARGET, VOLATILE_INFATUATION
waitanimation
printstring STRINGID_DESTINYKNOTACTIVATES
waitmessage B_WAIT_TIME_LONG
BattleScript_TryDestinyKnotTargetRet:
return
BattleScript_TryDestinyKnotAttacker:
jumpifnoholdeffect BS_TARGET, HOLD_EFFECT_DESTINY_KNOT, BattleScript_TryDestinyKnotAttackerRet
infatuatewithbattler BS_ATTACKER, BS_TARGET
jumpifnoholdeffect BS_TARGET, HOLD_EFFECT_DESTINY_KNOT, BattleScript_TryDestinyKnotTargetRet
playanimation BS_TARGET, B_ANIM_HELD_ITEM_EFFECT
waitanimation
swapattackerwithtarget
printstring STRINGID_DESTINYKNOTACTIVATES
tryinfatuating BattleScript_SwapTargetAttackerButItFailed
swapattackerwithtarget
volatileanimation BS_ATTACKER, VOLATILE_INFATUATION
waitanimation
printstring STRINGID_DESTINYKNOTACTIVATES
waitmessage B_WAIT_TIME_LONG
BattleScript_TryDestinyKnotAttackerRet:
return
BattleScript_EffectAttract::
@ -4378,6 +4379,9 @@ BattleScript_RestoreAttackerButItFailed:
BattleScript_RestoreTargetButItFailed:
restoretarget
goto BattleScript_ButItFailed
BattleScript_SwapTargetAttackerButItFailed:
swapattackerwithtarget
goto BattleScript_ButItFailed
BattleScript_NotAffected::
pause B_WAIT_TIME_SHORT

View File

@ -705,7 +705,7 @@ const u8 *const gBattleStringsTable[STRINGID_COUNT] =
[STRINGID_RECEIVERABILITYTAKEOVER] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ABILITY} was taken over!"),
[STRINGID_PKNMABSORBINGPOWER] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} is absorbing power!"),
[STRINGID_NOONEWILLBEABLETORUNAWAY] = COMPOUND_STRING("No one will be able to run away during the next turn!"),
[STRINGID_DESTINYKNOTACTIVATES] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} fell in love because of the {B_LAST_ITEM}!"),
[STRINGID_DESTINYKNOTACTIVATES] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} fell in love because of the {B_LAST_ITEM}!"),
[STRINGID_CLOAKEDINAFREEZINGLIGHT] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} became cloaked in a freezing light!"),
[STRINGID_CLEARAMULETWONTLOWERSTATS] = COMPOUND_STRING("The effects of the {B_LAST_ITEM} held by {B_SCR_NAME_WITH_PREFIX2} prevents its stats from being lowered!"),
[STRINGID_FERVENTWISHREACHED] = COMPOUND_STRING("{B_ATK_TRAINER_NAME}'s fervent wish has reached {B_ATK_NAME_WITH_PREFIX2}!"),

View File

@ -16848,15 +16848,6 @@ void BS_JumpIfNoAlly(void)
gBattlescriptCurrInstr = cmd->nextInstr;
}
void BS_InfatuateWithBattler(void)
{
NATIVE_ARGS(u8 battler, u8 infatuateWith);
u32 battler = GetBattlerForBattleScript(cmd->battler);
gBattleScripting.battler = battler;
gBattleMons[battler].volatiles.infatuation = INFATUATED_WITH(GetBattlerForBattleScript(cmd->infatuateWith));
gBattlescriptCurrInstr = cmd->nextInstr;
}
void BS_SetLastUsedItem(void)
{
NATIVE_ARGS(u8 battler);

View File

@ -0,0 +1,66 @@
#include "global.h"
#include "test/battle.h"
ASSUMPTIONS
{
ASSUME(gItemsInfo[ITEM_DESTINY_KNOT].holdEffect == HOLD_EFFECT_DESTINY_KNOT);
}
SINGLE_BATTLE_TEST("Destiny Knot infatuates back when holder is targeted")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET) { Gender(MON_MALE); }
OPPONENT(SPECIES_WOBBUFFET) { Gender(MON_FEMALE); Item(ITEM_DESTINY_KNOT); }
} WHEN {
TURN { MOVE(player, MOVE_ATTRACT); }
} SCENE {
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponent);
MESSAGE("Wobbuffet fell in love because of the Destiny Knot!");
} THEN {
EXPECT(player->volatiles.infatuation);
}
}
SINGLE_BATTLE_TEST("Destiny Knot infatuates back when holder is attacking")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET) { Gender(MON_MALE); Item(ITEM_DESTINY_KNOT);}
OPPONENT(SPECIES_CLEFAIRY) { Gender(MON_FEMALE); Ability(ABILITY_CUTE_CHARM);}
} WHEN {
TURN { MOVE(player, MOVE_TACKLE); }
} SCENE {
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
MESSAGE("The opposing Clefairy fell in love because of the Destiny Knot!");
} THEN {
EXPECT(opponent->volatiles.infatuation);
}
}
SINGLE_BATTLE_TEST("Destiny Knot procs but fails if the target is already infatuated")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET) { Gender(MON_MALE); }
OPPONENT(SPECIES_WOBBUFFET) { Gender(MON_FEMALE); Item(ITEM_DESTINY_KNOT); }
} WHEN {
TURN { MOVE(opponent, MOVE_ATTRACT); MOVE(player, MOVE_ATTRACT, WITH_RNG(RNG_INFATUATION, FALSE)); }
} SCENE {
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponent);
MESSAGE("But it failed!");
}
}
SINGLE_BATTLE_TEST("Destiny Knot procs but fails if the target is oblivious")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET) { Gender(MON_MALE); Ability(ABILITY_OBLIVIOUS); }
OPPONENT(SPECIES_WOBBUFFET) { Gender(MON_FEMALE); Item(ITEM_DESTINY_KNOT); }
} WHEN {
TURN { MOVE(player, MOVE_ATTRACT); }
} SCENE {
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponent);
ABILITY_POPUP(player, ABILITY_OBLIVIOUS);
} THEN {
EXPECT(!player->volatiles.infatuation);
}
}