Master to upcoming 28/08/25 (#7635)

This commit is contained in:
hedara90 2025-08-28 15:36:03 +02:00 committed by GitHub
commit 7b1430f3a7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 240 additions and 111 deletions

View File

@ -199,12 +199,13 @@ BattleScript_EffectDoodle::
attackstring
ppreduce
trycopyability BS_ATTACKER, BattleScript_ButItFailed
saveattacker
attackanimation
waitanimation
setbyte gBattleCommunication, 0
goto BattleScript_EffectDoodle_AfterCopy
BattleScript_EffectDoodle_CopyAbility:
trycopyability BS_ATTACKER, BattleScript_MoveEnd
trycopyability BS_ATTACKER, BattleScript_EffectDoodleMoveEnd
BattleScript_EffectDoodle_AfterCopy:
.if B_ABILITY_POP_UP == TRUE
copybyte gBattlerAbility, gBattlerAttacker
@ -216,8 +217,10 @@ BattleScript_EffectDoodle_AfterCopy:
switchinabilities BS_ATTACKER
jumpifbyte CMP_NOT_EQUAL, gBattleCommunication, 0x0, BattleScript_MoveEnd
addbyte gBattleCommunication, 1
jumpifnoally BS_ATTACKER, BattleScript_MoveEnd
jumpifnoally BS_ATTACKER, BattleScript_EffectDoodleMoveEnd
setallytonextattacker BattleScript_EffectDoodle_CopyAbility
BattleScript_EffectDoodleMoveEnd:
restoreattacker
goto BattleScript_MoveEnd
BattleScript_EffectGlaiveRush::

View File

@ -279,6 +279,7 @@ void InitBattleControllers(void);
bool32 IsValidForBattle(struct Pokemon *mon);
void TryReceiveLinkBattleData(void);
void PrepareBufferDataTransferLink(u32 battler, u32 bufferId, u16 size, u8 *data);
void UpdateFriendshipFromXItem(u32 battler);
// emitters
void BtlController_EmitGetMonData(u32 battler, u32 bufferId, u8 requestId, u8 monToCheck);

View File

@ -93,4 +93,8 @@
#define ITEM_EFFECT_HEAL_PP 21
#define ITEM_EFFECT_NONE 22
// Since X item stat increases are now handled by battle scripts, the friendship increase effect is now handled by the battle controller in HandleAction_UseItem.
#define X_ITEM_FRIENDSHIP_INCREASE 1 // The amount of friendship gained by using an X item on a Pokémon in battle.
#define X_ITEM_MAX_FRIENDSHIP 200 // Friendship threshold at which Pokémon stop receiving a friendship increase from using X items on them in battle.
#endif // GUARD_CONSTANTS_ITEM_EFFECTS_H

View File

@ -881,6 +881,7 @@ uq4_12_t GetDynamaxLevelHPMultiplier(u32 dynamaxLevel, bool32 inverseMultiplier)
u32 GetRegionalFormByRegion(u32 species, u32 region);
bool32 IsSpeciesForeignRegionalForm(u32 species, u32 currentRegion);
u32 GetTeraTypeFromPersonality(struct Pokemon *mon);
bool8 ShouldSkipFriendshipChange(void);
struct Pokemon *GetSavedPlayerPartyMon(u32 index);
u8 *GetSavedPlayerPartyCount(void);
void SavePlayerPartyMon(u32 index, struct Pokemon *mon);

View File

@ -6863,6 +6863,32 @@ static void TrySwapWishBattlerIds(u32 battlerAtk, u32 battlerPartner)
SWAP(gWishFutureKnock.wishPartyId[battlerAtk], gWishFutureKnock.wishPartyId[battlerPartner], temp);
}
static void TrySwapAttractBattlerIds(u32 battlerAtk, u32 battlerPartner)
{
u32 attractedTo;
// our own infatuation handled with gBattleMons struct data swapping
// if another battler is infatuated with one of us, change to other battler
for (u32 i = 0; i < gBattlersCount; i++)
{
if (i == battlerAtk || i == battlerPartner || !gBattleMons[i].volatiles.infatuation)
continue;
attractedTo = INFATUATED_WITH(i);
if (attractedTo == battlerAtk)
{
gBattleMons[i].volatiles.infatuation = INFATUATED_WITH(battlerPartner);
break;
}
else if (attractedTo == battlerPartner)
{
gBattleMons[i].volatiles.infatuation = INFATUATED_WITH(battlerAtk);
break;
}
}
}
static void SwapBattlerMoveData(u32 battler1, u32 battler2)
{
u32 temp;
@ -6933,6 +6959,7 @@ static void AnimTask_AllySwitchDataSwap(u8 taskId)
TrySwapSkyDropTargets(battlerAtk, battlerPartner);
TrySwapStickyWebBattlerId(battlerAtk, battlerPartner);
TrySwapWishBattlerIds(battlerAtk, battlerPartner);
TrySwapAttractBattlerIds(battlerAtk, battlerPartner);
// For Snipe Shot and abilities Stalwart/Propeller Tail - keep the original target.
for (i = 0; i < gBattlersCount; i++)

View File

@ -12,9 +12,11 @@
#include "battle_tv.h"
#include "cable_club.h"
#include "event_object_movement.h"
#include "item.h"
#include "link.h"
#include "link_rfu.h"
#include "m4a.h"
#include "overworld.h"
#include "palette.h"
#include "party_menu.h"
#include "recorded_battle.h"
@ -25,6 +27,7 @@
#include "util.h"
#include "text.h"
#include "constants/abilities.h"
#include "constants/item_effects.h"
#include "constants/songs.h"
#include "pokemon_animation.h"
@ -3078,3 +3081,46 @@ void BtlController_HandleSwitchInTryShinyAnim(u32 battler)
}
}
}
void UpdateFriendshipFromXItem(u32 battler)
{
struct Pokemon *party = GetBattlerParty(battler);
u8 friendship;
gBattleResources->bufferA[battler][1] = REQUEST_FRIENDSHIP_BATTLE;
GetBattlerMonData(battler, party, gBattlerPartyIndexes[battler], &friendship);
u16 heldItem;
gBattleResources->bufferA[battler][1] = REQUEST_HELDITEM_BATTLE;
GetBattlerMonData(battler, party, gBattlerPartyIndexes[battler], (u8*)&heldItem);
if (friendship < X_ITEM_MAX_FRIENDSHIP)
{
if (GetItemHoldEffect(heldItem) == HOLD_EFFECT_FRIENDSHIP_UP)
friendship += 150 * X_ITEM_FRIENDSHIP_INCREASE / 100;
else
friendship += X_ITEM_FRIENDSHIP_INCREASE;
u8 pokeball;
gBattleResources->bufferA[battler][1] = REQUEST_POKEBALL_BATTLE;
GetBattlerMonData(battler, party, gBattlerPartyIndexes[battler], &pokeball);
if (pokeball == BALL_LUXURY)
friendship++;
u8 metLocation;
gBattleResources->bufferA[battler][1] = REQUEST_MET_LOCATION_BATTLE;
GetBattlerMonData(battler, party, gBattlerPartyIndexes[battler], &metLocation);
if (metLocation == GetCurrentRegionMapSectionId())
friendship++;
if (friendship > MAX_FRIENDSHIP)
friendship = MAX_FRIENDSHIP;
gBattleMons[battler].friendship = friendship;
gBattleResources->bufferA[battler][3] = friendship;
gBattleResources->bufferA[battler][1] = REQUEST_FRIENDSHIP_BATTLE;
SetBattlerMonData(battler, GetBattlerParty(battler), gBattlerPartyIndexes[battler]);
}
}

View File

@ -5524,28 +5524,6 @@ static inline bool32 IsProtectivePadsProtected(u32 battler, enum ItemHoldEffect
return TRUE;
}
static inline bool32 IsProtectEffectAffected(u32 battler, u32 move)
{
enum ItemHoldEffect holdEffect = GetBattlerHoldEffect(gBattlerAttacker, TRUE);
if (IsProtectivePadsProtected(battler, holdEffect))
return TRUE;
if (holdEffect == HOLD_EFFECT_CLEAR_AMULET)
{
RecordItemEffectBattle(battler, holdEffect);
return TRUE;
}
u32 ability = GetBattlerAbility(gBattlerAttacker);
if (CanAbilityPreventStatLoss(ability))
{
RecordAbilityBattle(battler, ability);
return TRUE;
}
return FALSE;
}
static inline bool32 CanEjectButtonTrigger(u32 battlerAtk, u32 battlerDef, enum BattleMoveEffects moveEffect)
{
if (GetBattlerHoldEffect(battlerDef, TRUE) == HOLD_EFFECT_EJECT_BUTTON

View File

@ -44,6 +44,7 @@
#include "constants/battle_string_ids.h"
#include "constants/hold_effects.h"
#include "constants/items.h"
#include "constants/item_effects.h"
#include "constants/moves.h"
#include "constants/songs.h"
#include "constants/species.h"
@ -598,6 +599,11 @@ void HandleAction_UseItem(void)
ClearVariousBattlerFlags(gBattlerAttacker);
gLastUsedItem = gBattleResources->bufferB[gBattlerAttacker][1] | (gBattleResources->bufferB[gBattlerAttacker][2] << 8);
if (X_ITEM_FRIENDSHIP_INCREASE > 0
&& GetItemEffectType(gLastUsedItem) == ITEM_EFFECT_X_ITEM
&& !ShouldSkipFriendshipChange())
UpdateFriendshipFromXItem(gBattlerAttacker);
gBattlescriptCurrInstr = gBattlescriptsForUsingItem[GetItemBattleUsage(gLastUsedItem) - 1];
gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT;
}
@ -873,11 +879,11 @@ void HandleAction_NothingIsFainted(void)
gCurrentTurnActionNumber++;
gCurrentActionFuncId = gActionsByTurnOrder[gCurrentTurnActionNumber];
gBattleStruct->synchronizeMoveEffect = MOVE_EFFECT_NONE;
gHitMarker &= ~(HITMARKER_DESTINYBOND
| HITMARKER_IGNORE_SUBSTITUTE
gHitMarker &= ~(HITMARKER_DESTINYBOND
| HITMARKER_IGNORE_SUBSTITUTE
| HITMARKER_ATTACKSTRING_PRINTED
| HITMARKER_NO_PPDEDUCT
| HITMARKER_STATUS_ABILITY_EFFECT
| HITMARKER_NO_PPDEDUCT
| HITMARKER_STATUS_ABILITY_EFFECT
| HITMARKER_PASSIVE_HP_UPDATE
| HITMARKER_OBEYS);
}
@ -890,13 +896,13 @@ void HandleAction_ActionFinished(void)
gCurrentTurnActionNumber++;
gCurrentActionFuncId = gActionsByTurnOrder[gCurrentTurnActionNumber];
SpecialStatusesClear();
gHitMarker &= ~(HITMARKER_DESTINYBOND
| HITMARKER_IGNORE_SUBSTITUTE
gHitMarker &= ~(HITMARKER_DESTINYBOND
| HITMARKER_IGNORE_SUBSTITUTE
| HITMARKER_ATTACKSTRING_PRINTED
| HITMARKER_NO_PPDEDUCT
| HITMARKER_STATUS_ABILITY_EFFECT
| HITMARKER_NO_PPDEDUCT
| HITMARKER_STATUS_ABILITY_EFFECT
| HITMARKER_PASSIVE_HP_UPDATE
| HITMARKER_OBEYS
| HITMARKER_OBEYS
| HITMARKER_IGNORE_DISGUISE);
ClearDamageCalcResults();
@ -8776,6 +8782,14 @@ static inline u32 CalcAttackStat(struct DamageContext *ctx)
RecordAbilityBattle(battlerDef, ABILITY_THICK_FAT);
}
break;
case ABILITY_PURIFYING_SALT:
if (moveType == TYPE_GHOST)
{
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(0.5));
if (ctx->updateFlags)
RecordAbilityBattle(battlerDef, ABILITY_PURIFYING_SALT);
}
break;
}
// ally's abilities
@ -8858,31 +8872,38 @@ static inline u32 CalcDefenseStat(struct DamageContext *ctx)
uq4_12_t modifier;
u32 battlerDef = ctx->battlerDef;
u32 move = ctx->move;
u32 moveType = ctx->moveType;
enum BattleMoveEffects moveEffect = GetMoveEffect(move);
if (gFieldStatuses & STATUS_FIELD_WONDER_ROOM) // the defense stats are swapped
{
def = gBattleMons[battlerDef].spDefense;
spDef = gBattleMons[battlerDef].defense;
}
else
{
def = gBattleMons[battlerDef].defense;
spDef = gBattleMons[battlerDef].spDefense;
}
def = gBattleMons[battlerDef].defense;
spDef = gBattleMons[battlerDef].spDefense;
if (moveEffect == EFFECT_PSYSHOCK || IsBattleMovePhysical(move)) // uses defense stat instead of sp.def
{
defStat = def;
if (gFieldStatuses & STATUS_FIELD_WONDER_ROOM) // the defense stats are swapped
{
defStat = spDef;
usesDefStat = FALSE;
}
else
{
defStat = def;
usesDefStat = TRUE;
}
defStage = gBattleMons[battlerDef].statStages[STAT_DEF];
usesDefStat = TRUE;
}
else // is special
{
defStat = spDef;
if (gFieldStatuses & STATUS_FIELD_WONDER_ROOM) // the defense stats are swapped
{
defStat = def;
usesDefStat = TRUE;
}
else
{
defStat = spDef;
usesDefStat = FALSE;
}
defStage = gBattleMons[battlerDef].statStages[STAT_SPDEF];
usesDefStat = FALSE;
}
// Self-destruct / Explosion cut defense in half
@ -8937,10 +8958,6 @@ static inline u32 CalcDefenseStat(struct DamageContext *ctx)
if (gBattleMons[battlerDef].species == SPECIES_CHERRIM_SUNSHINE && IsBattlerWeatherAffected(battlerDef, B_WEATHER_SUN) && !usesDefStat)
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.5));
break;
case ABILITY_PURIFYING_SALT:
if (moveType == TYPE_GHOST)
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(2.0));
break;
}
// ally's abilities

View File

@ -334,14 +334,8 @@ const u8 gItemEffect_PPMax[9] = {
VITAMIN_FRIENDSHIP_CHANGE(6),
};
#define STAT_BOOST_FRIENDSHIP_CHANGE \
[6] = 1, /* Friendship change, low */ \
[7] = 1 /* Friendship change, mid */
const u8 gItemEffect_GuardSpec[8] = {
[3] = ITEM3_GUARD_SPEC,
[5] = ITEM5_FRIENDSHIP_LOW | ITEM5_FRIENDSHIP_MID,
STAT_BOOST_FRIENDSHIP_CHANGE,
};
// The first item effect value for the stat boost items
@ -350,44 +344,30 @@ const u8 gItemEffect_GuardSpec[8] = {
const u8 gItemEffect_DireHit[8] = {
[0] = 1 << 5, // ITEM0_DIRE_HIT
[5] = ITEM5_FRIENDSHIP_LOW | ITEM5_FRIENDSHIP_MID,
STAT_BOOST_FRIENDSHIP_CHANGE,
};
const u8 gItemEffect_XAttack[8] = {
[1] = ITEM1_X_ATTACK,
[5] = ITEM5_FRIENDSHIP_LOW | ITEM5_FRIENDSHIP_MID,
STAT_BOOST_FRIENDSHIP_CHANGE,
};
const u8 gItemEffect_XDefense[8] = {
[1] = ITEM1_X_DEFENSE,
[5] = ITEM5_FRIENDSHIP_LOW | ITEM5_FRIENDSHIP_MID,
STAT_BOOST_FRIENDSHIP_CHANGE,
};
const u8 gItemEffect_XSpeed[8] = {
[1] = ITEM1_X_SPEED,
[5] = ITEM5_FRIENDSHIP_LOW | ITEM5_FRIENDSHIP_MID,
STAT_BOOST_FRIENDSHIP_CHANGE,
};
const u8 gItemEffect_XAccuracy[8] = {
[1] = ITEM1_X_ACCURACY,
[5] = ITEM5_FRIENDSHIP_LOW | ITEM5_FRIENDSHIP_MID,
STAT_BOOST_FRIENDSHIP_CHANGE,
};
const u8 gItemEffect_XSpecialAttack[8] = {
[1] = ITEM1_X_SPATK,
[5] = ITEM5_FRIENDSHIP_LOW | ITEM5_FRIENDSHIP_MID,
STAT_BOOST_FRIENDSHIP_CHANGE,
};
const u8 gItemEffect_XSpecialDefense[8] = {
[1] = ITEM1_X_SPDEF,
[5] = ITEM5_FRIENDSHIP_LOW | ITEM5_FRIENDSHIP_MID,
STAT_BOOST_FRIENDSHIP_CHANGE,
};
const u8 gItemEffect_EvoItem[6] = {

View File

@ -82,7 +82,6 @@ static union PokemonSubstruct *GetSubstruct(struct BoxPokemon *boxMon, u32 perso
static void EncryptBoxMon(struct BoxPokemon *boxMon);
static void DecryptBoxMon(struct BoxPokemon *boxMon);
static void Task_PlayMapChosenOrBattleBGM(u8 taskId);
static bool8 ShouldSkipFriendshipChange(void);
void TrySpecialOverworldEvo();
EWRAM_DATA static u8 sLearningMoveTableID = 0;
@ -6358,7 +6357,7 @@ bool8 HasTwoFramesAnimation(u16 species)
&& !gTestRunnerHeadless;
}
static bool8 ShouldSkipFriendshipChange(void)
bool8 ShouldSkipFriendshipChange(void)
{
if (gMain.inBattle && gBattleTypeFlags & (BATTLE_TYPE_FRONTIER))
return TRUE;

View File

@ -529,7 +529,6 @@ void ClearRematchMovementByTrainerId(void)
TryGetObjectEventIdByLocalIdAndMap(objectEventTemplates[i].localId, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, &objEventId);
objectEvent = &gObjectEvents[objEventId];
GetRandomFaceDirectionMovementType(&objectEventTemplates[i]);
TryOverrideTemplateCoordsForObjectEvent(objectEvent, sFaceDirectionMovementTypeByFacingDirection[objectEvent->facingDirection]);
if (gSelectedObjectEvent == objEventId)
@ -705,22 +704,11 @@ static u8 GetResponseMovementTypeFromTrainerGraphicsId(u8 graphicsId)
#endif //FREE_MATCH_CALL
static u16 GetTrainerFlagFromScript(const u8 *script)
/*
* The trainer flag is a little-endian short located +2 from
* the script pointer, assuming the trainerbattle command is
* first in the script. Because scripts are unaligned, and
* because the ARM processor requires shorts to be 16-bit
* aligned, this function needs to perform explicit bitwise
* operations to get the correct flag.
*
* 5c XX YY ZZ ...
* -- --
*/
{
u16 trainerFlag;
script += 2;
trainerFlag = script[0];
// The trainer flag is located 3 bytes (command + flags + localIdA) from the script pointer, assuming the trainerbattle command is first in the script.
// Because scripts are unaligned, and because the ARM processor requires shorts to be 16-bit aligned, this function needs to perform explicit bitwise operations to get the correct flag.
script += 3;
u16 trainerFlag = script[0];
trainerFlag |= script[1] << 8;
return trainerFlag;
}

View File

@ -1,5 +1,6 @@
#include "global.h"
#include "test/battle.h"
#include "constants/item_effects.h"
SINGLE_BATTLE_TEST("X Attack sharply raises battler's Attack stat", s16 damage)
{
@ -257,3 +258,25 @@ SINGLE_BATTLE_TEST("Max Mushrooms raises battler's Speed stat", s16 damage)
}
}
}
SINGLE_BATTLE_TEST("Using X items in battle raises Friendship", s16 damage)
{
u32 startingFriendship;
u8 metLocation = MAPSEC_NONE;
PARAMETRIZE { startingFriendship = 0; }
PARAMETRIZE { startingFriendship = X_ITEM_MAX_FRIENDSHIP; }
GIVEN {
PLAYER(SPECIES_WOBBUFFET) { Friendship(startingFriendship); };
// Set met location to MAPSEC_NONE to avoid getting the friendship boost
// from being met in the current map section
SetMonData(&PLAYER_PARTY[0], MON_DATA_MET_LOCATION, &metLocation);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { USE_ITEM(player, ITEM_X_ACCURACY); MOVE(opponent, MOVE_CELEBRATE); }
} THEN {
if (startingFriendship == X_ITEM_MAX_FRIENDSHIP)
EXPECT_EQ(player->friendship, X_ITEM_MAX_FRIENDSHIP);
else
EXPECT_EQ(player->friendship, X_ITEM_FRIENDSHIP_INCREASE);
}
}

View File

@ -348,5 +348,63 @@ DOUBLE_BATTLE_TEST("Ally switch updates last used moves for Mimic")
}
}
DOUBLE_BATTLE_TEST("Ally Switch does not update leech seed battler")
{
GIVEN {
PLAYER(SPECIES_WYNAUT);
PLAYER(SPECIES_SOLOSIS);
OPPONENT(SPECIES_BULBASAUR) { HP(50); MaxHP(100); }
OPPONENT(SPECIES_RALTS) { HP(50); MaxHP(100); }
} WHEN {
TURN { MOVE(opponentLeft, MOVE_LEECH_SEED, target: playerLeft); }
TURN { MOVE(opponentRight, MOVE_ALLY_SWITCH); }
TURN { ; }
} SCENE {
// turn 1
MESSAGE("The opposing Bulbasaur used Leech Seed!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_LEECH_SEED, opponentLeft);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_LEECH_SEED_DRAIN, playerLeft);
HP_BAR(playerLeft);
HP_BAR(opponentLeft);
MESSAGE("The opposing Ralts used Ally Switch!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_ALLY_SWITCH, opponentRight);
MESSAGE("The opposing Ralts and the opposing Bulbasaur switched places!");
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_LEECH_SEED_DRAIN, playerLeft);
HP_BAR(playerLeft);
HP_BAR(opponentLeft); // Ralts now gets hp gain
} THEN {
EXPECT_GT(opponentLeft->hp, 50);
EXPECT_GT(opponentRight->hp, 50);
}
}
DOUBLE_BATTLE_TEST("Ally Switch updates attract battler")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET) { Speed(100); Gender(MON_MALE); }
PLAYER(SPECIES_SOLOSIS) { Speed(50); }
OPPONENT(SPECIES_CLEFAIRY) { Speed(20); Gender(MON_FEMALE); Ability(ABILITY_CUTE_CHARM); }
OPPONENT(SPECIES_RALTS) { Speed(30); }
} WHEN {
TURN { MOVE(playerLeft, MOVE_TACKLE, target: opponentLeft); }
TURN { MOVE(opponentRight, MOVE_ALLY_SWITCH); }
TURN { ; }
} SCENE {
// turn 1
MESSAGE("Wobbuffet used Tackle!");
HP_BAR(opponentLeft);
ABILITY_POPUP(opponentLeft, ABILITY_CUTE_CHARM);
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_INFATUATION, playerLeft);
MESSAGE("The opposing Clefairy's Cute Charm infatuated Wobbuffet!");
// turn 2
MESSAGE("The opposing Ralts used Ally Switch!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_ALLY_SWITCH, opponentRight);
MESSAGE("The opposing Ralts and the opposing Clefairy switched places!");
// turn 3
MESSAGE("Wobbuffet is in love with the opposing Clefairy!"); // tracks attract battler
}
}
// Triple Battles required to test
//TO_DO_BATTLE_TEST("Ally Switch fails if the user is in the middle of the field in a Triple Battle");

View File

@ -114,28 +114,32 @@ SINGLE_BATTLE_TEST("Embargo negates a held item's Speed reduction")
}
}
WILD_BATTLE_TEST("Embargo doesn't block held item effects that affect friendship")
{
u32 initialFriendship;
u32 finalFriendship;
// This is a useful test, but under the current circumstances, we can't actually test this without modifying
// X_ITEM_FRIENDSHIP_INCREASE. Since HOLD_EFFECT_FRIENDSHIP_UP applies a 1.5x modifier, and the stock
// Friendship increase is 1, the held item effect actually does not affect the Friendship gained.
//
// WILD_BATTLE_TEST("Embargo doesn't block held item effects that affect friendship")
// {
// u32 initialFriendship;
// u32 finalFriendship;
KNOWN_FAILING; // Pokémon are currently not obtaining Friendship for using items in battle.
GIVEN {
ASSUME(gItemsInfo[ITEM_X_ACCURACY].battleUsage == EFFECT_ITEM_INCREASE_STAT);
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_SOOTHE_BELL); };
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { USE_ITEM(player, ITEM_X_ACCURACY); }
TURN { MOVE(player, MOVE_SING); }
} SCENE {
MESSAGE("Wobbuffet used Sing!");
MESSAGE("Wild Wobbuffet fell asleep!");
} THEN {
initialFriendship = GetMonData(&PLAYER_PARTY[0], MON_DATA_FRIENDSHIP);
finalFriendship = GetMonData(&gPlayerParty[0], MON_DATA_FRIENDSHIP);
EXPECT_EQ(finalFriendship, initialFriendship + 2);
}
}
// KNOWN_FAILING; // Pokémon are currently not obtaining Friendship for using items in battle.
// GIVEN {
// ASSUME(gItemsInfo[ITEM_X_ACCURACY].battleUsage == EFFECT_ITEM_INCREASE_STAT);
// PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_SOOTHE_BELL); };
// OPPONENT(SPECIES_WOBBUFFET);
// } WHEN {
// TURN { USE_ITEM(player, ITEM_X_ACCURACY); }
// TURN { MOVE(player, MOVE_SING); }
// } SCENE {
// MESSAGE("Wobbuffet used Sing!");
// MESSAGE("Wild Wobbuffet fell asleep!");
// } THEN {
// initialFriendship = GetMonData(&PLAYER_PARTY[0], MON_DATA_FRIENDSHIP);
// finalFriendship = GetMonData(&gPlayerParty[0], MON_DATA_FRIENDSHIP);
// EXPECT_EQ(finalFriendship, initialFriendship + 2);
// }
// }
SINGLE_BATTLE_TEST("Embargo doesn't block a held item's form-changing effect, but it does block its other effects", s16 damage)
{