From 1ea0500b955c385010b3b728f61e10893f28872b Mon Sep 17 00:00:00 2001 From: psf <77138753+pkmnsnfrn@users.noreply.github.com> Date: Sun, 23 Nov 2025 22:55:30 -0800 Subject: [PATCH] Fixed broken friendship from items in battle test and added new test for opposite case (#7872) --- include/constants/item_effects.h | 3 ++ include/pokemon.h | 2 ++ src/battle_controllers.c | 19 +--------- src/pokemon.c | 48 ++++++++++++------------- test/battle/item_effect/increase_stat.c | 28 +++++++++++++-- 5 files changed, 56 insertions(+), 44 deletions(-) diff --git a/include/constants/item_effects.h b/include/constants/item_effects.h index dbe322beac..037f28c4bc 100644 --- a/include/constants/item_effects.h +++ b/include/constants/item_effects.h @@ -93,6 +93,9 @@ #define ITEM_EFFECT_HEAL_PP 21 #define ITEM_EFFECT_NONE 22 +#define ITEM_FRIENDSHIP_MAPSEC_BONUS 1 // The amount of bonus friendship gained when an item is used on a Pokémon whose met location matches the current map section. +#define ITEM_FRIENDSHIP_LUXURY_BONUS 1 // The amount of bonus friendship gained when a Pokémon is in the Luxury Ball. + // 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. diff --git a/include/pokemon.h b/include/pokemon.h index 8852ba3c97..bee162b4f7 100644 --- a/include/pokemon.h +++ b/include/pokemon.h @@ -6,6 +6,7 @@ #include "constants/battle.h" #include "constants/cries.h" #include "constants/form_change_types.h" +#include "constants/hold_effects.h" #include "constants/items.h" #include "constants/map_groups.h" #include "constants/regions.h" @@ -825,6 +826,7 @@ s32 GetBattlerMultiplayerId(u16 id); u8 GetTrainerEncounterMusicId(u16 trainerOpponentId); u16 ModifyStatByNature(u8 nature, u16 stat, u8 statIndex); void AdjustFriendship(struct Pokemon *mon, u8 event); +u8 CalculateFriendshipBonuses(struct Pokemon *mon, u32 modifier, enum ItemHoldEffect itemHoldEffect); void MonGainEVs(struct Pokemon *mon, u16 defeatedSpecies); u16 GetMonEVCount(struct Pokemon *mon); void RandomlyGivePartyPokerus(struct Pokemon *party); diff --git a/src/battle_controllers.c b/src/battle_controllers.c index 79828d065d..3b416afe5b 100644 --- a/src/battle_controllers.c +++ b/src/battle_controllers.c @@ -3106,24 +3106,7 @@ void UpdateFriendshipFromXItem(u32 battler) 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++; + friendship += CalculateFriendshipBonuses(GetBattlerMon(battler), X_ITEM_FRIENDSHIP_INCREASE, GetItemHoldEffect(heldItem)); if (friendship > MAX_FRIENDSHIP) friendship = MAX_FRIENDSHIP; diff --git a/src/pokemon.c b/src/pokemon.c index 2e9d766185..a2aad772df 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -3741,17 +3741,7 @@ bool8 ExecuteTableBasedItemEffect(struct Pokemon *mon, u16 item, u8 partyIndex, { \ friendshipChange = itemEffect[itemEffectParam]; \ friendship = GetMonData(mon, MON_DATA_FRIENDSHIP, NULL); \ - if (friendshipChange > 0 && holdEffect == HOLD_EFFECT_FRIENDSHIP_UP) \ - friendship += 150 * friendshipChange / 100; \ - else \ - friendship += friendshipChange; \ - if (friendshipChange > 0) \ - { \ - if (GetMonData(mon, MON_DATA_POKEBALL, NULL) == ITEM_LUXURY_BALL) \ - friendship++; \ - if (GetMonData(mon, MON_DATA_MET_LOCATION, NULL) == GetCurrentRegionMapSectionId()) \ - friendship++; \ - } \ + friendship += CalculateFriendshipBonuses(mon,friendshipChange,holdEffect); \ if (friendship < 0) \ friendship = 0; \ if (friendship > MAX_FRIENDSHIP) \ @@ -5279,7 +5269,7 @@ void AdjustFriendship(struct Pokemon *mon, u8 event) if (species && species != SPECIES_EGG) { u8 friendshipLevel = 0; - s16 friendship = GetMonData(mon, MON_DATA_FRIENDSHIP, 0); + s32 friendship = GetMonData(mon, MON_DATA_FRIENDSHIP, 0); enum TrainerClassID opponentTrainerClass = GetTrainerClassFromId(TRAINER_BATTLE_PARAM.opponentA); if (friendship > 99) @@ -5305,18 +5295,7 @@ void AdjustFriendship(struct Pokemon *mon, u8 event) } mod = sFriendshipEventModifiers[event][friendshipLevel]; - if (mod > 0 && holdEffect == HOLD_EFFECT_FRIENDSHIP_UP) - // 50% increase, rounding down - mod = (150 * mod) / 100; - - friendship += mod; - if (mod > 0) - { - if (GetMonData(mon, MON_DATA_POKEBALL, NULL) == ITEM_LUXURY_BALL) - friendship++; - if (GetMonData(mon, MON_DATA_MET_LOCATION, NULL) == GetCurrentRegionMapSectionId()) - friendship++; - } + friendship += CalculateFriendshipBonuses(mon,mod,holdEffect); if (friendship < 0) friendship = 0; @@ -5327,6 +5306,27 @@ void AdjustFriendship(struct Pokemon *mon, u8 event) } } +u8 CalculateFriendshipBonuses(struct Pokemon *mon, u32 modifier, enum ItemHoldEffect itemHoldEffect) +{ + u32 bonus = 0; + + if ((modifier > 0) && (itemHoldEffect == HOLD_EFFECT_FRIENDSHIP_UP)) + bonus += 150 * modifier / 100; + else + bonus += modifier; + + if (modifier == 0) + return bonus; + + if (GetMonData(mon, MON_DATA_POKEBALL, NULL) == ITEM_LUXURY_BALL) + bonus += ITEM_FRIENDSHIP_LUXURY_BONUS; + + if (GetMonData(mon, MON_DATA_MET_LOCATION, NULL) == GetCurrentRegionMapSectionId()) + bonus += ITEM_FRIENDSHIP_MAPSEC_BONUS; + + return bonus; +} + void MonGainEVs(struct Pokemon *mon, u16 defeatedSpecies) { u8 evs[NUM_STATS]; diff --git a/test/battle/item_effect/increase_stat.c b/test/battle/item_effect/increase_stat.c index b56f1a2b84..227a638c6a 100644 --- a/test/battle/item_effect/increase_stat.c +++ b/test/battle/item_effect/increase_stat.c @@ -1,4 +1,5 @@ #include "global.h" +#include "overworld.h" #include "test/battle.h" #include "constants/item_effects.h" @@ -262,12 +263,13 @@ 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; + u8 metLocation = GetCurrentRegionMapSectionId() + 1; + 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 + // Set met location to currentMapSec + 1 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); @@ -280,3 +282,25 @@ SINGLE_BATTLE_TEST("Using X items in battle raises Friendship", s16 damage) EXPECT_EQ(player->friendship, X_ITEM_FRIENDSHIP_INCREASE); } } + +SINGLE_BATTLE_TEST("Using X items in battle where Pokemon was met raises Friendship with a bonus", s16 damage) +{ + u32 startingFriendship; + u8 metLocation = GetCurrentRegionMapSectionId(); + + PARAMETRIZE { startingFriendship = 0; } + PARAMETRIZE { startingFriendship = X_ITEM_MAX_FRIENDSHIP; } + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Friendship(startingFriendship); }; + // Set met location to currentMapSec to get the friendship boost + 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, (ITEM_FRIENDSHIP_MAPSEC_BONUS + X_ITEM_FRIENDSHIP_INCREASE)); + } +}