Master to upcoming 28/08/25 (#7635)
This commit is contained in:
commit
7b1430f3a7
@ -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::
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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++)
|
||||
|
||||
@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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] = {
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user