updated Cmd_dofaintanimation and Cmd_cleareffectsonfaint

This commit is contained in:
cawtds
2024-04-30 21:20:14 +02:00
parent e50ed33157
commit afbda761c3
5 changed files with 400 additions and 227 deletions

View File

@@ -354,10 +354,23 @@ struct SideTimer
// pokeemerald
u8 retaliateTimer;
u8 stealthRockAmount;
u8 stickyWebBattlerId;
};
extern struct SideTimer gSideTimers[];
struct FieldTimer
{
u8 mudSportTimer;
u8 waterSportTimer;
u8 wonderRoomTimer;
u8 magicRoomTimer;
u8 trickRoomTimer;
u8 terrainTimer;
u8 gravityTimer;
u8 fairyLockTimer;
};
struct WishFutureKnock
{
u8 futureSightCounter[MAX_BATTLERS_COUNT];
@@ -478,6 +491,24 @@ struct LinkBattlerHeader
struct BattleEnigmaBerry battleEnigmaBerry;
};
struct MegaEvolutionData
{
u8 toEvolve; // As flags using gBitTable.
bool8 alreadyEvolved[4]; // Array id is used for mon position.
u8 battlerId;
bool8 playerSelect;
u8 triggerSpriteId;
};
struct UltraBurstData
{
u8 toBurst; // As flags using gBitTable.
bool8 alreadyBursted[4]; // Array id is used for mon position.
u8 battlerId;
bool8 playerSelect;
u8 triggerSpriteId;
};
struct Illusion
{
u8 on;
@@ -487,6 +518,25 @@ struct Illusion
struct Pokemon *mon;
};
struct ZMoveData
{
u8 viable:1; // current move can become a z move
u8 viewing:1; // if player is viewing the z move name instead of regular moves
u8 active:1; // is z move being used this turn
u8 zStatusActive:1;
u8 healReplacement:1;
u8 activeCategory:2; // active z move category
u8 zUnused:1;
u8 triggerSpriteId;
u8 possibleZMoves[MAX_BATTLERS_COUNT];
u16 chosenZMove; // z move of move cursor is on
u8 effect;
u8 used[MAX_BATTLERS_COUNT]; //one per bank for multi-battles
u16 toBeUsed[MAX_BATTLERS_COUNT]; // z moves per battler to be used
u16 baseMoves[MAX_BATTLERS_COUNT];
u8 categories[MAX_BATTLERS_COUNT];
};
struct LostItem
{
u16 originalItem:15;
@@ -525,8 +575,8 @@ struct BattleStruct
u8 runTries;
u8 caughtMonNick[POKEMON_NAME_LENGTH + 1];
u8 field_78; // unused
u8 safariRockThrowCounter;
u8 safariBaitThrowCounter;
u8 safariRockThrowCounter; // safariGoNearCounter in pokeemerald
u8 safariBaitThrowCounter; // safariPkblThrowCounter in pokeemerald
u8 safariEscapeFactor;
u8 safariCatchFactor;
u8 linkBattleVsSpriteId_V;
@@ -556,7 +606,7 @@ struct BattleStruct
u8 multiplayerId;
u8 overworldWeatherDone;
u8 atkCancellerTracker;
u16 usedHeldItems[MAX_BATTLERS_COUNT];
u16 usedHeldItems[PARTY_SIZE][NUM_BATTLE_SIDES]; // For each party member and side. For harvest, recycle
u8 chosenItem[MAX_BATTLERS_COUNT]; // why is this an u8?
u8 AI_itemType[2];
u8 AI_itemFlags[2];
@@ -568,7 +618,7 @@ struct BattleStruct
u8 turnSideTracker;
u8 fillerDC[0xDF-0xDC];
u8 givenExpMons;
u8 lastTakenMoveFrom[MAX_BATTLERS_COUNT * MAX_BATTLERS_COUNT * 2];
u8 lastTakenMoveFrom[MAX_BATTLERS_COUNT][MAX_BATTLERS_COUNT];
u16 castformPalette[MAX_BATTLERS_COUNT][16];
u8 wishPerishSongState;
u8 wishPerishSongBattlerId;
@@ -612,6 +662,12 @@ struct BattleStruct
struct LostItem itemLost[PARTY_SIZE]; // Player's team that had items consumed or stolen (two bytes per party member)
u8 savedBattlerTarget;
u8 ateBerry[2]; // array id determined by side, each party pokemon as bit
u16 overwrittenAbilities[MAX_BATTLERS_COUNT]; // abilities overwritten during battle (keep separate from battle history in case of switching)
struct MegaEvolutionData mega;
struct UltraBurstData burst;
struct ZMoveData zmove;
u8 appearedInBattle; // Bitfield to track which Pokemon appeared in battle. Used for Burmy's form change
bool8 allowedToChangeFormInWeather[PARTY_SIZE][NUM_BATTLE_SIDES]; // For each party member and side, used by Ice Face.
}; // size == 0x200 bytes
extern struct BattleStruct *gBattleStruct;
@@ -848,6 +904,12 @@ struct PokedudeBattlerState
u8 saved_bg0y;
};
struct QueuedStatBoost
{
u8 stats; // bitfield for each battle stat that is set if the stat changes
s8 statChanges[NUM_BATTLE_STATS - 1]; // highest bit being set decreases the stat
}; /* size = 8 */
extern u16 gBattle_BG0_X;
extern u16 gBattle_BG0_Y;
extern u16 gBattle_BG1_X;
@@ -952,6 +1014,10 @@ extern s32 gBideDmg[MAX_BATTLERS_COUNT];
extern u8 gBideTarget[MAX_BATTLERS_COUNT];
extern u16 gLastUsedMove;
extern u8 gIsCriticalHit;
extern struct FieldTimer gFieldTimers;
extern bool8 gHasFetchedBall;
extern u8 gLastUsedBall;
extern struct QueuedStatBoost gQueuedStatBoosts[MAX_BATTLERS_COUNT];
static inline u32 GetBattlerPosition(u32 battler)
{

View File

@@ -79,8 +79,8 @@ void SpriteCB_PlayerThrowInit(struct Sprite *sprite);
void UpdatePlayerPosInThrowAnim(struct Sprite *sprite);
void BeginBattleIntroDummy(void);
void BeginBattleIntro(void);
void SwitchInClearSetData(void);
void FaintClearSetData(void);
void SwitchInClearSetData(u32 battler);
const u8* FaintClearSetData(u32 battler);
void BattleTurnPassed(void);
u8 IsRunningFromBattleImpossible(void);
void UpdatePartyOwnerOnSwitch_NonMulti(u8 battler);
@@ -93,5 +93,6 @@ s8 GetMovePriority(u32 battlerId, u16 move);
s8 GetChosenMovePriority(u32 battlerId);
u32 GetBattlerTotalSpeedStatArgs(u32 battler, u32 ability, u32 holdEffect);
u32 GetBattlerTotalSpeedStat(u32 battler);
void SpecialStatusesClear(void);
#endif // GUARD_BATTLE_MAIN_H

View File

@@ -1877,7 +1877,7 @@ static void Cmd_get_used_held_item(void)
else
battlerId = gBattlerTarget;
AI_THINKING_STRUCT->funcResult = ((u8 *)gBattleStruct->usedHeldItems)[battlerId * 2];
AI_THINKING_STRUCT->funcResult = gBattleStruct->usedHeldItems[battlerId][GetBattlerSide(battlerId)];
sAIScriptPtr += 2;
}

View File

@@ -86,7 +86,6 @@ static void SpriteCB_PlayerThrowUpdate(struct Sprite *sprite);
static void BattleStartClearSetData(void);
static void BattleIntroGetMonsData(void);
static void TurnValuesCleanUp(bool8 var0);
static void SpecialStatusesClear(void);
static void BattleIntroPrepareBackgroundSlide(void);
static void BattleIntroDrawTrainersOrMonsSprites(void);
static void BattleIntroDrawPartySummaryScreens(void);
@@ -227,6 +226,10 @@ EWRAM_DATA s32 gBideDmg[MAX_BATTLERS_COUNT] = {0};
EWRAM_DATA u8 gBideTarget[MAX_BATTLERS_COUNT] = {0};
EWRAM_DATA u16 gLastUsedMove = 0;
EWRAM_DATA u8 gIsCriticalHit = FALSE;
EWRAM_DATA struct FieldTimer gFieldTimers = {0};
EWRAM_DATA bool8 gHasFetchedBall = FALSE;
EWRAM_DATA u8 gLastUsedBall = 0;
EWRAM_DATA struct QueuedStatBoost gQueuedStatBoosts[MAX_BATTLERS_COUNT] = {0};
void (*gPreBattleCallback1)(void);
void (*gBattleMainFunc)(void);
@@ -2223,26 +2226,37 @@ static void BattleMainCB1(void)
gBattlerControllerFuncs[gActiveBattler]();
}
static void ClearSetBScriptingStruct(void)
{
// windowsType is set up earlier in BattleInitBgsAndWindows, so we need to save the value
u32 temp = gBattleScripting.windowsType;
memset(&gBattleScripting, 0, sizeof(gBattleScripting));
gBattleScripting.windowsType = temp;
gBattleScripting.battleStyle = gSaveBlock2Ptr->optionsBattleStyle;
gBattleScripting.expOnCatch = (B_EXP_CATCH >= GEN_6);
}
static void BattleStartClearSetData(void)
{
s32 i;
u32 j;
u8 *dataPtr;
TurnValuesCleanUp(FALSE);
SpecialStatusesClear();
memset(&gDisableStructs, 0, sizeof(gDisableStructs));
memset(&gFieldTimers, 0, sizeof(gFieldTimers));
memset(&gSideStatuses, 0, sizeof(gSideStatuses));
memset(&gSideTimers, 0, sizeof(gSideTimers));
memset(&gWishFutureKnock, 0, sizeof(gWishFutureKnock));
memset(&gBattleResults, 0, sizeof(gBattleResults));
ClearSetBScriptingStruct();
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
{
gStatuses3[i] = 0;
gStatuses4[i] = 0;
dataPtr = (u8 *)&gDisableStructs[i];
for (j = 0; j < sizeof(struct DisableStruct); j++)
dataPtr[j] = 0;
gDisableStructs[i].isFirstTurn = 2;
sUnusedBattlersArray[i] = 0;
gLastMoves[i] = MOVE_NONE;
gLastLandedMoves[i] = MOVE_NONE;
gLastHitByType[i] = 0;
@@ -2251,32 +2265,34 @@ static void BattleStartClearSetData(void)
gLockedMoves[i] = MOVE_NONE;
gLastPrintedMoves[i] = MOVE_NONE;
gBattleResources->flags->flags[i] = 0;
gBattleStruct->lastTakenMove[i] = MOVE_NONE;
gBattleStruct->choicedMove[i] = MOVE_NONE;
gBattleStruct->changedItems[i] = 0;
gBattleStruct->lastTakenMoveFrom[i][0] = MOVE_NONE;
gBattleStruct->lastTakenMoveFrom[i][1] = MOVE_NONE;
gBattleStruct->lastTakenMoveFrom[i][2] = MOVE_NONE;
gBattleStruct->lastTakenMoveFrom[i][3] = MOVE_NONE;
gBattleStruct->AI_monToSwitchIntoId[i] = PARTY_SIZE;
gBattleStruct->skyDropTargets[i] = 0xFF;
gBattleStruct->overwrittenAbilities[i] = ABILITY_NONE;
}
for (i = 0; i < 2; i++)
{
gSideStatuses[i] = 0;
gLastUsedMove = 0;
gFieldStatuses = 0;
dataPtr = (u8 *)&gSideTimers[i];
for (j = 0; j < sizeof(struct SideTimer); j++)
dataPtr[j] = 0;
}
gHasFetchedBall = FALSE;
gLastUsedBall = 0;
gBattlerAttacker = 0;
gBattlerTarget = 0;
gEffectBattler = 0;
gBattlerAbility = 0;
gBattleWeather = 0;
dataPtr = (u8 *)&gWishFutureKnock;
for (i = 0; i < sizeof(struct WishFutureKnock); i++)
dataPtr[i] = 0;
gHitMarker = 0;
if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_POKEDUDE)) && gSaveBlock2Ptr->optionsBattleSceneOff)
gHitMarker |= HITMARKER_NO_ANIMATIONS;
gBattleScripting.battleStyle = gSaveBlock2Ptr->optionsBattleStyle;
gMultiHitCounter = 0;
gBattleOutcome = 0;
gBattleControllerExecFlags = 0;
@@ -2290,63 +2306,45 @@ static void BattleStartClearSetData(void)
gPauseCounterBattle = 0;
gBattleMoveDamage = 0;
gIntroSlideFlags = 0;
gBattleScripting.animTurn = 0;
gBattleScripting.animTargetsHit = 0;
gLeveledUpInBattle = 0;
gAbsentBattlerFlags = 0;
gBattleStruct->runTries = 0;
gBattleStruct->safariRockThrowCounter = 0;
gBattleStruct->safariBaitThrowCounter = 0;
*(&gBattleStruct->safariCatchFactor) = gSpeciesInfo[GetMonData(&gEnemyParty[0], MON_DATA_SPECIES)].catchRate * 100 / 1275;
*(&gBattleStruct->safariEscapeFactor) = gSpeciesInfo[GetMonData(&gEnemyParty[0], MON_DATA_SPECIES)].safariZoneFleeRate * 100 / 1275;
if (gBattleStruct->safariEscapeFactor <= 1)
gBattleStruct->safariEscapeFactor = 2;
gBattleStruct->safariCatchFactor = gSpeciesInfo[GetMonData(&gEnemyParty[0], MON_DATA_SPECIES)].catchRate * 100 / 1275;
gBattleStruct->safariEscapeFactor = 3;
gBattleStruct->wildVictorySong = 0;
gBattleStruct->moneyMultiplier = 1;
for (i = 0; i < 8; i++)
gBattleStruct->givenExpMons = 0;
gBattleResults.shinyWildMon = IsMonShiny(&gEnemyParty[0]);
gBattleStruct->mega.triggerSpriteId = 0xFF;
gBattleStruct->burst.triggerSpriteId = 0xFF;
for (i = 0; i < ARRAY_COUNT(gSideTimers); i++)
{
*((u8 *)gBattleStruct->lastTakenMove + i) = MOVE_NONE;
*((u8 *)gBattleStruct->usedHeldItems + i) = ITEM_NONE;
*((u8 *)gBattleStruct->choicedMove + i) = MOVE_NONE;
*((u8 *)gBattleStruct->changedItems + i) = ITEM_NONE;
*(i + 0 * 8 + (u8 *)(gBattleStruct->lastTakenMoveFrom) + 0) = 0;
*(i + 1 * 8 + (u8 *)(gBattleStruct->lastTakenMoveFrom) + 0) = 0;
*(i + 2 * 8 + (u8 *)(gBattleStruct->lastTakenMoveFrom) + 0) = 0;
*(i + 3 * 8 + (u8 *)(gBattleStruct->lastTakenMoveFrom) + 0) = 0;
gSideTimers[i].stickyWebBattlerId = 0xFF;
}
*(gBattleStruct->AI_monToSwitchIntoId + 0) = PARTY_SIZE;
*(gBattleStruct->AI_monToSwitchIntoId + 1) = PARTY_SIZE;
*(&gBattleStruct->givenExpMons) = 0;
for (i = 0; i < 11; i++)
gBattleResults.catchAttempts[i] = 0;
gBattleResults.battleTurnCounter = 0;
gBattleResults.playerFaintCounter = 0;
gBattleResults.opponentFaintCounter = 0;
gBattleResults.playerSwitchesCounter = 0;
gBattleResults.numHealingItemsUsed = 0;
gBattleResults.numRevivesUsed = 0;
gBattleResults.playerMonWasDamaged = FALSE;
gBattleResults.usedMasterBall = FALSE;
gBattleResults.lastOpponentSpecies = SPECIES_NONE;
gBattleResults.lastUsedMovePlayer = MOVE_NONE;
gBattleResults.lastUsedMoveOpponent = MOVE_NONE;
gBattleResults.playerMon1Species = SPECIES_NONE;
gBattleResults.playerMon2Species = SPECIES_NONE;
gBattleResults.caughtMonSpecies = SPECIES_NONE;
for (i = 0; i < POKEMON_NAME_LENGTH; ++i)
gBattleStruct->appearedInBattle = 0;
gBattleStruct->beatUpSlot = 0;
for (i = 0; i < PARTY_SIZE; i++)
{
gBattleResults.playerMon1Name[i] = 0;
gBattleResults.playerMon2Name[i] = 0;
gBattleResults.caughtMonNick[i] = 0;
gBattleStruct->usedHeldItems[i][B_SIDE_PLAYER] = 0;
gBattleStruct->usedHeldItems[i][B_SIDE_OPPONENT] = 0;
gBattleStruct->itemLost[i].originalItem = GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM);
gPartyCriticalHits[i] = 0;
gBattleStruct->allowedToChangeFormInWeather[i][B_SIDE_PLAYER] = FALSE;
gBattleStruct->allowedToChangeFormInWeather[i][B_SIDE_OPPONENT] = FALSE;
}
for (i = 0; i < PARTY_SIZE; i++) {
gPartyCriticalHits[i] = 0;
}
gBattleStruct->swapDamageCategory = FALSE; // Photon Geyser, Shell Side Arm, Light That Burns the Sky
gSelectedMonPartyId = PARTY_SIZE; // Revival Blessing
}
void SwitchInClearSetData(void)
void SwitchInClearSetData(u32 battler)
{
struct DisableStruct disableStructCopy = gDisableStructs[gActiveBattler];
s32 i;
@@ -2355,12 +2353,12 @@ void SwitchInClearSetData(void)
if (gMovesInfo[gCurrentMove].effect != EFFECT_BATON_PASS)
{
for (i = 0; i < NUM_BATTLE_STATS; i++)
gBattleMons[gActiveBattler].statStages[i] = DEFAULT_STAT_STAGE;
gBattleMons[battler].statStages[i] = DEFAULT_STAT_STAGE;
for (i = 0; i < gBattlersCount; i++)
{
if ((gBattleMons[i].status2 & STATUS2_ESCAPE_PREVENTION) && gDisableStructs[i].battlerPreventingEscape == gActiveBattler)
if ((gBattleMons[i].status2 & STATUS2_ESCAPE_PREVENTION) && gDisableStructs[i].battlerPreventingEscape == battler)
gBattleMons[i].status2 &= ~STATUS2_ESCAPE_PREVENTION;
if ((gStatuses3[i] & STATUS3_ALWAYS_HITS) && gDisableStructs[i].battlerWithSureHit == gActiveBattler)
if ((gStatuses3[i] & STATUS3_ALWAYS_HITS) && gDisableStructs[i].battlerWithSureHit == battler)
{
gStatuses3[i] &= ~STATUS3_ALWAYS_HITS;
gDisableStructs[i].battlerWithSureHit = 0;
@@ -2369,173 +2367,268 @@ void SwitchInClearSetData(void)
}
if (gMovesInfo[gCurrentMove].effect == EFFECT_BATON_PASS)
{
gBattleMons[gActiveBattler].status2 &= (STATUS2_CONFUSION | STATUS2_FOCUS_ENERGY | STATUS2_SUBSTITUTE | STATUS2_ESCAPE_PREVENTION | STATUS2_CURSED);
gStatuses3[gActiveBattler] &= (STATUS3_LEECHSEED_BATTLER | STATUS3_LEECHSEED | STATUS3_ALWAYS_HITS | STATUS3_PERISH_SONG | STATUS3_ROOTED);
gStatuses4[gActiveBattler] &= (STATUS4_MUD_SPORT | STATUS4_WATER_SPORT);
gBattleMons[battler].status2 &= (STATUS2_CONFUSION | STATUS2_FOCUS_ENERGY_ANY | STATUS2_SUBSTITUTE | STATUS2_ESCAPE_PREVENTION | STATUS2_CURSED);
gStatuses3[battler] &= (STATUS3_LEECHSEED_BATTLER | STATUS3_LEECHSEED | STATUS3_ALWAYS_HITS | STATUS3_PERISH_SONG | STATUS3_ROOTED
| STATUS3_GASTRO_ACID | STATUS3_EMBARGO | STATUS3_TELEKINESIS | STATUS3_MAGNET_RISE | STATUS3_HEAL_BLOCK
| STATUS3_AQUA_RING | STATUS3_POWER_TRICK);
gStatuses4[battler] &= (STATUS4_MUD_SPORT | STATUS4_WATER_SPORT | STATUS4_INFINITE_CONFUSION);
for (i = 0; i < gBattlersCount; i++)
{
if (GetBattlerSide(gActiveBattler) != GetBattlerSide(i)
if (GetBattlerSide(battler) != GetBattlerSide(i)
&& (gStatuses3[i] & STATUS3_ALWAYS_HITS) != 0
&& (gDisableStructs[i].battlerWithSureHit == gActiveBattler))
&& (gDisableStructs[i].battlerWithSureHit == battler))
{
gStatuses3[i] &= ~STATUS3_ALWAYS_HITS;
gStatuses3[i] |= STATUS3_ALWAYS_HITS_TURN(2);
}
}
if (gStatuses3[battler] & STATUS3_POWER_TRICK)
SWAP(gBattleMons[battler].attack, gBattleMons[battler].defense, i);
}
else
{
gBattleMons[gActiveBattler].status2 = 0;
gStatuses3[gActiveBattler] = 0;
gStatuses4[gActiveBattler] = 0;
gBattleMons[battler].status2 = 0;
gStatuses3[battler] = 0;
gStatuses4[battler] = 0;
}
for (i = 0; i < gBattlersCount; i++)
{
if (gBattleMons[i].status2 & STATUS2_INFATUATED_WITH(gActiveBattler))
gBattleMons[i].status2 &= ~STATUS2_INFATUATED_WITH(gActiveBattler);
if ((gBattleMons[i].status2 & STATUS2_WRAPPED) && *(gBattleStruct->wrappedBy + i) == gActiveBattler)
if (gBattleMons[i].status2 & STATUS2_INFATUATED_WITH(battler))
gBattleMons[i].status2 &= ~STATUS2_INFATUATED_WITH(battler);
if ((gBattleMons[i].status2 & STATUS2_WRAPPED) && *(gBattleStruct->wrappedBy + i) == battler)
gBattleMons[i].status2 &= ~STATUS2_WRAPPED;
if ((gStatuses4[i] & STATUS4_SYRUP_BOMB) && *(gBattleStruct->stickySyrupdBy + i) == battler)
gStatuses4[i] &= ~STATUS4_SYRUP_BOMB;
}
gActionSelectionCursor[gActiveBattler] = 0;
gMoveSelectionCursor[gActiveBattler] = 0;
gActionSelectionCursor[battler] = 0;
gMoveSelectionCursor[battler] = 0;
ptr = (u8 *)&gDisableStructs[gActiveBattler];
for (i = 0; i < sizeof(struct DisableStruct); i++)
ptr[i] = 0;
memset(&gDisableStructs[battler], 0, sizeof(struct DisableStruct));
if (gMovesInfo[gCurrentMove].effect == EFFECT_BATON_PASS)
{
gDisableStructs[gActiveBattler].substituteHP = disableStructCopy.substituteHP;
gDisableStructs[gActiveBattler].battlerWithSureHit = disableStructCopy.battlerWithSureHit;
gDisableStructs[gActiveBattler].perishSongTimer = disableStructCopy.perishSongTimer;
// gDisableStructs[gActiveBattler].perishSongTimerStartValue = disableStructCopy.perishSongTimerStartValue;
gDisableStructs[gActiveBattler].battlerPreventingEscape = disableStructCopy.battlerPreventingEscape;
gDisableStructs[battler].substituteHP = disableStructCopy.substituteHP;
gDisableStructs[battler].battlerWithSureHit = disableStructCopy.battlerWithSureHit;
gDisableStructs[battler].perishSongTimer = disableStructCopy.perishSongTimer;
gDisableStructs[battler].battlerPreventingEscape = disableStructCopy.battlerPreventingEscape;
gDisableStructs[battler].embargoTimer = disableStructCopy.embargoTimer;
}
else if (gMovesInfo[gCurrentMove].effect == EFFECT_SHED_TAIL)
{
gBattleMons[battler].status2 |= STATUS2_SUBSTITUTE;
gDisableStructs[battler].substituteHP = disableStructCopy.substituteHP;
}
gMoveResultFlags = 0;
gDisableStructs[gActiveBattler].isFirstTurn = 2;
gLastMoves[gActiveBattler] = MOVE_NONE;
gLastLandedMoves[gActiveBattler] = MOVE_NONE;
gLastHitByType[gActiveBattler] = 0;
gLastResultingMoves[gActiveBattler] = MOVE_NONE;
gLastPrintedMoves[gActiveBattler] = MOVE_NONE;
gLastHitBy[gActiveBattler] = 0xFF;
gDisableStructs[battler].isFirstTurn = 2;
gDisableStructs[battler].truantSwitchInHack = disableStructCopy.truantSwitchInHack;
gLastMoves[battler] = MOVE_NONE;
gLastLandedMoves[battler] = MOVE_NONE;
gLastHitByType[battler] = 0;
gLastResultingMoves[battler] = MOVE_NONE;
gLastPrintedMoves[battler] = MOVE_NONE;
gLastHitBy[battler] = 0xFF;
*(gBattleStruct->lastTakenMove + gActiveBattler * 2 + 0) = MOVE_NONE;
*(gBattleStruct->lastTakenMove + gActiveBattler * 2 + 1) = MOVE_NONE;
*(0 * 2 + gActiveBattler * 8 + (u8 *)(gBattleStruct->lastTakenMoveFrom) + 0) = 0;
*(0 * 2 + gActiveBattler * 8 + (u8 *)(gBattleStruct->lastTakenMoveFrom) + 1) = 0;
*(1 * 2 + gActiveBattler * 8 + (u8 *)(gBattleStruct->lastTakenMoveFrom) + 0) = 0;
*(1 * 2 + gActiveBattler * 8 + (u8 *)(gBattleStruct->lastTakenMoveFrom) + 1) = 0;
*(2 * 2 + gActiveBattler * 8 + (u8 *)(gBattleStruct->lastTakenMoveFrom) + 0) = 0;
*(2 * 2 + gActiveBattler * 8 + (u8 *)(gBattleStruct->lastTakenMoveFrom) + 1) = 0;
*(3 * 2 + gActiveBattler * 8 + (u8 *)(gBattleStruct->lastTakenMoveFrom) + 0) = 0;
*(3 * 2 + gActiveBattler * 8 + (u8 *)(gBattleStruct->lastTakenMoveFrom) + 1) = 0;
gBattleStruct->lastTakenMove[battler] = 0;
gBattleStruct->sameMoveTurns[battler] = 0;
gBattleStruct->lastTakenMoveFrom[battler][0] = 0;
gBattleStruct->lastTakenMoveFrom[battler][1] = 0;
gBattleStruct->lastTakenMoveFrom[battler][2] = 0;
gBattleStruct->lastTakenMoveFrom[battler][3] = 0;
gBattleStruct->lastMoveFailed &= ~(gBitTable[battler]);
for (i = 0; i < ARRAY_COUNT(gSideTimers); i++)
{
// Switched into sticky web user slot, so reset stored battler ID
if (gSideTimers[i].stickyWebBattlerId == battler)
gSideTimers[i].stickyWebBattlerId = 0xFF;
}
for (i = 0; i < gBattlersCount; i++)
{
if (i != gActiveBattler)
{
*(gBattleStruct->lastTakenMove + i * 2 + 0) = MOVE_NONE;
*(gBattleStruct->lastTakenMove + i * 2 + 1) = MOVE_NONE;
}
*(i * 8 + gActiveBattler * 2 + (u8 *)(gBattleStruct->lastTakenMoveFrom) + 0) = 0;
*(i * 8 + gActiveBattler * 2 + (u8 *)(gBattleStruct->lastTakenMoveFrom) + 1) = 0;
if (i != battler && GetBattlerSide(i) != GetBattlerSide(battler))
gBattleStruct->lastTakenMove[i] = MOVE_NONE;
gBattleStruct->lastTakenMoveFrom[i][battler] = 0;
}
*((u8 *)(&gBattleStruct->choicedMove[gActiveBattler]) + 0) = MOVE_NONE;
*((u8 *)(&gBattleStruct->choicedMove[gActiveBattler]) + 1) = MOVE_NONE;
gBattleResources->flags->flags[gActiveBattler] = 0;
gBattleStruct->choicedMove[battler] = MOVE_NONE;
gBattleResources->flags->flags[battler] = 0;
gCurrentMove = MOVE_NONE;
// Reset damage to prevent things like red card activating if the switched-in mon is holding it
gSpecialStatuses[battler].physicalDmg = 0;
gSpecialStatuses[battler].specialDmg = 0;
// Reset G-Max Chi Strike boosts.
gBattleStruct->bonusCritStages[battler] = 0;
// TODO: Dynamax
// Reset Dynamax flags.
// UndoDynamax(battler);
gBattleStruct->overwrittenAbilities[battler] = ABILITY_NONE;
// Clear selected party ID so Revival Blessing doesn't get confused.
gSelectedMonPartyId = PARTY_SIZE;
// TODO: AI
// Ai_UpdateSwitchInData(battler);
}
void FaintClearSetData(void)
const u8* FaintClearSetData(u32 battler)
{
s32 i;
u8 *ptr;
const u8 *result = NULL;
u8 battlerSide = GetBattlerSide(battler);
for (i = 0; i < NUM_BATTLE_STATS; i++)
gBattleMons[gActiveBattler].statStages[i] = DEFAULT_STAT_STAGE;
gBattleMons[battler].statStages[i] = DEFAULT_STAT_STAGE;
gBattleMons[gActiveBattler].status2 = 0;
gStatuses3[gActiveBattler] = 0;
gStatuses4[gActiveBattler] = 0;
gBattleMons[battler].status2 = 0;
gStatuses3[battler] &= STATUS3_GASTRO_ACID; // Edge case: Keep Gastro Acid if pokemon's ability can have effect after fainting, for example Innards Out.
gStatuses4[battler] = 0;
for (i = 0; i < gBattlersCount; i++)
{
if ((gBattleMons[i].status2 & STATUS2_ESCAPE_PREVENTION) && gDisableStructs[i].battlerPreventingEscape == gActiveBattler)
if ((gBattleMons[i].status2 & STATUS2_ESCAPE_PREVENTION) && gDisableStructs[i].battlerPreventingEscape == battler)
gBattleMons[i].status2 &= ~STATUS2_ESCAPE_PREVENTION;
if (gBattleMons[i].status2 & STATUS2_INFATUATED_WITH(gActiveBattler))
gBattleMons[i].status2 &= ~STATUS2_INFATUATED_WITH(gActiveBattler);
if ((gBattleMons[i].status2 & STATUS2_WRAPPED) && *(gBattleStruct->wrappedBy + i) == gActiveBattler)
if (gBattleMons[i].status2 & STATUS2_INFATUATED_WITH(battler))
gBattleMons[i].status2 &= ~STATUS2_INFATUATED_WITH(battler);
if ((gBattleMons[i].status2 & STATUS2_WRAPPED) && *(gBattleStruct->wrappedBy + i) == battler)
gBattleMons[i].status2 &= ~STATUS2_WRAPPED;
if ((gStatuses4[i] & STATUS4_SYRUP_BOMB) && *(gBattleStruct->stickySyrupdBy + i) == battler)
gStatuses4[i] &= ~STATUS4_SYRUP_BOMB;
}
gActionSelectionCursor[gActiveBattler] = 0;
gMoveSelectionCursor[gActiveBattler] = 0;
gActionSelectionCursor[battler] = 0;
gMoveSelectionCursor[battler] = 0;
ptr = (u8 *)&gDisableStructs[gActiveBattler];
for (i = 0; i < sizeof(struct DisableStruct); i++)
ptr[i] = 0;
memset(&gDisableStructs[battler], 0, sizeof(struct DisableStruct));
gProtectStructs[gActiveBattler].protected = FALSE;
gProtectStructs[gActiveBattler].endured = FALSE;
gProtectStructs[gActiveBattler].noValidMoves = FALSE;
gProtectStructs[gActiveBattler].helpingHand = FALSE;
gProtectStructs[gActiveBattler].bounceMove = FALSE;
gProtectStructs[gActiveBattler].stealMove = FALSE;
gProtectStructs[gActiveBattler].prlzImmobility = FALSE;
gProtectStructs[gActiveBattler].confusionSelfDmg = FALSE;
gProtectStructs[gActiveBattler].targetNotAffected = FALSE;
gProtectStructs[gActiveBattler].chargingTurn = FALSE;
gProtectStructs[gActiveBattler].fleeType = 0;
gProtectStructs[gActiveBattler].usedImprisonedMove = FALSE;
gProtectStructs[gActiveBattler].loveImmobility = FALSE;
gProtectStructs[gActiveBattler].usedDisabledMove = FALSE;
gProtectStructs[gActiveBattler].usedTauntedMove = FALSE;
gProtectStructs[gActiveBattler].flag2Unknown = FALSE;
gProtectStructs[gActiveBattler].flinchImmobility = FALSE;
gProtectStructs[gActiveBattler].notFirstStrike = FALSE;
gProtectStructs[battler].protected = FALSE;
gProtectStructs[battler].spikyShielded = FALSE;
gProtectStructs[battler].kingsShielded = FALSE;
gProtectStructs[battler].banefulBunkered = FALSE;
gProtectStructs[battler].quash = FALSE;
gProtectStructs[battler].obstructed = FALSE;
gProtectStructs[battler].silkTrapped = FALSE;
gProtectStructs[battler].burningBulwarked = FALSE;
gProtectStructs[battler].endured = FALSE;
gProtectStructs[battler].noValidMoves = FALSE;
gProtectStructs[battler].helpingHand = FALSE;
gProtectStructs[battler].bounceMove = FALSE;
gProtectStructs[battler].stealMove = FALSE;
gProtectStructs[battler].prlzImmobility = FALSE;
gProtectStructs[battler].confusionSelfDmg = FALSE;
gProtectStructs[battler].targetAffected = FALSE;
gProtectStructs[battler].chargingTurn = FALSE;
gProtectStructs[battler].fleeType = 0;
gProtectStructs[battler].usedImprisonedMove = FALSE;
gProtectStructs[battler].loveImmobility = FALSE;
gProtectStructs[battler].usedDisabledMove = FALSE;
gProtectStructs[battler].usedTauntedMove = FALSE;
gProtectStructs[battler].flag2Unknown = FALSE;
gProtectStructs[battler].flinchImmobility = FALSE;
gProtectStructs[battler].notFirstStrike = FALSE;
gProtectStructs[battler].usedHealBlockedMove = FALSE;
gProtectStructs[battler].usesBouncedMove = FALSE;
gProtectStructs[battler].usedGravityPreventedMove = FALSE;
gProtectStructs[battler].usedThroatChopPreventedMove = FALSE;
gProtectStructs[battler].statRaised = FALSE;
gProtectStructs[battler].statFell = FALSE;
gProtectStructs[battler].pranksterElevated = FALSE;
gDisableStructs[gActiveBattler].isFirstTurn = 2;
gDisableStructs[battler].isFirstTurn = 2;
gLastMoves[gActiveBattler] = MOVE_NONE;
gLastLandedMoves[gActiveBattler] = MOVE_NONE;
gLastHitByType[gActiveBattler] = 0;
gLastResultingMoves[gActiveBattler] = MOVE_NONE;
gLastPrintedMoves[gActiveBattler] = MOVE_NONE;
gLastHitBy[gActiveBattler] = 0xFF;
gLastMoves[battler] = MOVE_NONE;
gLastLandedMoves[battler] = MOVE_NONE;
gLastHitByType[battler] = 0;
gLastResultingMoves[battler] = MOVE_NONE;
gLastPrintedMoves[battler] = MOVE_NONE;
gLastHitBy[battler] = 0xFF;
*((u8 *)(&gBattleStruct->choicedMove[gActiveBattler]) + 0) = MOVE_NONE;
*((u8 *)(&gBattleStruct->choicedMove[gActiveBattler]) + 1) = MOVE_NONE;
gBattleStruct->choicedMove[battler] = MOVE_NONE;
gBattleStruct->sameMoveTurns[battler] = 0;
gBattleStruct->lastTakenMove[battler] = MOVE_NONE;
gBattleStruct->lastTakenMoveFrom[battler][0] = 0;
gBattleStruct->lastTakenMoveFrom[battler][1] = 0;
gBattleStruct->lastTakenMoveFrom[battler][2] = 0;
gBattleStruct->lastTakenMoveFrom[battler][3] = 0;
*(gBattleStruct->lastTakenMove + gActiveBattler * 2 + 0) = MOVE_NONE;
*(gBattleStruct->lastTakenMove + gActiveBattler * 2 + 1) = MOVE_NONE;
*(0 * 2 + gActiveBattler * 8 + (u8 *)(gBattleStruct->lastTakenMoveFrom) + 0) = 0;
*(0 * 2 + gActiveBattler * 8 + (u8 *)(gBattleStruct->lastTakenMoveFrom) + 1) = 0;
*(1 * 2 + gActiveBattler * 8 + (u8 *)(gBattleStruct->lastTakenMoveFrom) + 0) = 0;
*(1 * 2 + gActiveBattler * 8 + (u8 *)(gBattleStruct->lastTakenMoveFrom) + 1) = 0;
*(2 * 2 + gActiveBattler * 8 + (u8 *)(gBattleStruct->lastTakenMoveFrom) + 0) = 0;
*(2 * 2 + gActiveBattler * 8 + (u8 *)(gBattleStruct->lastTakenMoveFrom) + 1) = 0;
*(3 * 2 + gActiveBattler * 8 + (u8 *)(gBattleStruct->lastTakenMoveFrom) + 0) = 0;
*(3 * 2 + gActiveBattler * 8 + (u8 *)(gBattleStruct->lastTakenMoveFrom) + 1) = 0;
for (i = 0; i < ARRAY_COUNT(gSideTimers); i++)
{
// User of sticky web fainted, so reset the stored battler ID
if (gSideTimers[i].stickyWebBattlerId == battler)
gSideTimers[i].stickyWebBattlerId = 0xFF;
}
for (i = 0; i < gBattlersCount; i++)
{
if (i != gActiveBattler)
{
*(gBattleStruct->lastTakenMove + i * 2 + 0) = MOVE_NONE;
*(gBattleStruct->lastTakenMove + i * 2 + 1) = MOVE_NONE;
}
*(i * 8 + gActiveBattler * 2 + (u8 *)(gBattleStruct->lastTakenMoveFrom) + 0) = 0;
*(i * 8 + gActiveBattler * 2 + (u8 *)(gBattleStruct->lastTakenMoveFrom) + 1) = 0;
if (i != battler && GetBattlerSide(i) != battlerSide)
gBattleStruct->lastTakenMove[i] = MOVE_NONE;
gBattleStruct->lastTakenMoveFrom[i][battler] = 0;
}
gBattleResources->flags->flags[gActiveBattler] = 0;
gBattleMons[gActiveBattler].type1 = gSpeciesInfo[gBattleMons[gActiveBattler].species].types[0];
gBattleMons[gActiveBattler].type2 = gSpeciesInfo[gBattleMons[gActiveBattler].species].types[1];
gBattleResources->flags->flags[battler] = 0;
gBattleMons[battler].type1 = gSpeciesInfo[gBattleMons[battler].species].types[0];
gBattleMons[battler].type2 = gSpeciesInfo[gBattleMons[battler].species].types[1];
gBattleMons[battler].type3 = TYPE_MYSTERY;
// TODO: AI
// Ai_UpdateFaintData(battler);
TryBattleFormChange(battler, FORM_CHANGE_FAINT);
gBattleStruct->overwrittenAbilities[battler] = ABILITY_NONE;
// If the fainted mon was involved in a Sky Drop
if (gBattleStruct->skyDropTargets[battler] != 0xFF)
{
// Get battler id of the other Pokemon involved in this Sky Drop
u8 otherSkyDropper = gBattleStruct->skyDropTargets[battler];
// Clear Sky Drop data
gBattleStruct->skyDropTargets[battler] = 0xFF;
gBattleStruct->skyDropTargets[otherSkyDropper] = 0xFF;
// If the other Pokemon involved in this Sky Drop was the target, not the attacker
if (gStatuses3[otherSkyDropper] & STATUS3_SKY_DROPPED)
{
// Release the target and take them out of the semi-invulnerable state
gStatuses3[otherSkyDropper] &= ~(STATUS3_SKY_DROPPED | STATUS3_ON_AIR);
// Make the target's sprite visible
gSprites[gBattlerSpriteIds[otherSkyDropper]].invisible = FALSE;
// If the target was sky dropped in the middle of using Outrage/Petal Dance/Thrash,
// confuse them upon release and print "confused via fatigue" message and animation.
if (gBattleMons[otherSkyDropper].status2 & STATUS2_LOCK_CONFUSE)
{
gBattleMons[otherSkyDropper].status2 &= ~(STATUS2_LOCK_CONFUSE);
// If the released mon can be confused, do so.
// Don't use CanBeConfused here, since it can cause issues in edge cases.
if (!(GetBattlerAbility(otherSkyDropper) == ABILITY_OWN_TEMPO
|| gBattleMons[otherSkyDropper].status2 & STATUS2_CONFUSION
|| IsBattlerTerrainAffected(otherSkyDropper, STATUS_FIELD_MISTY_TERRAIN)))
{
gBattleMons[otherSkyDropper].status2 |= STATUS2_CONFUSION_TURN(((Random()) % 4) + 2);
gBattlerAttacker = otherSkyDropper;
result = BattleScript_ThrashConfuses;
}
}
}
}
// Clear Z-Move data
gBattleStruct->zmove.active = FALSE;
gBattleStruct->zmove.toBeUsed[battler] = MOVE_NONE;
gBattleStruct->zmove.effect = EFFECT_HIT;
return result;
}
static void BattleIntroGetMonsData(void)
@@ -3646,47 +3739,52 @@ static void SetActionsAndBattlersTurnOrder(void)
static void TurnValuesCleanUp(bool8 var0)
{
s32 i;
u8 *dataPtr;
for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++)
for (i = 0; i < gBattlersCount; i++)
{
if (var0)
{
gProtectStructs[gActiveBattler].protected = FALSE;
gProtectStructs[gActiveBattler].endured = FALSE;
gProtectStructs[i].protected = FALSE;
gProtectStructs[i].spikyShielded = FALSE;
gProtectStructs[i].kingsShielded = FALSE;
gProtectStructs[i].banefulBunkered = FALSE;
gProtectStructs[i].quash = FALSE;
gProtectStructs[i].usedCustapBerry = FALSE;
gProtectStructs[i].quickDraw = FALSE;
memset(&gQueuedStatBoosts[i], 0, sizeof(struct QueuedStatBoost));
}
else
{
dataPtr = (u8 *)(&gProtectStructs[gActiveBattler]);
for (i = 0; i < sizeof(struct ProtectStruct); i++)
dataPtr[i] = 0;
if (gDisableStructs[gActiveBattler].isFirstTurn)
--gDisableStructs[gActiveBattler].isFirstTurn;
if (gDisableStructs[gActiveBattler].rechargeTimer)
memset(&gProtectStructs[i], 0, sizeof(struct ProtectStruct));
if (gDisableStructs[i].isFirstTurn)
gDisableStructs[i].isFirstTurn--;
if (gDisableStructs[i].rechargeTimer)
{
--gDisableStructs[gActiveBattler].rechargeTimer;
if (gDisableStructs[gActiveBattler].rechargeTimer == 0)
gBattleMons[gActiveBattler].status2 &= ~(STATUS2_RECHARGE);
gDisableStructs[i].rechargeTimer--;
if (gDisableStructs[i].rechargeTimer == 0)
gBattleMons[i].status2 &= ~STATUS2_RECHARGE;
}
}
if (gDisableStructs[gActiveBattler].substituteHP == 0)
gBattleMons[gActiveBattler].status2 &= ~(STATUS2_SUBSTITUTE);
if (gDisableStructs[i].substituteHP == 0)
gBattleMons[i].status2 &= ~STATUS2_SUBSTITUTE;
gSpecialStatuses[i].parentalBondState = PARENTAL_BOND_OFF;
}
gSideTimers[0].followmeTimer = 0;
gSideTimers[1].followmeTimer = 0;
gSideStatuses[B_SIDE_PLAYER] &= ~(SIDE_STATUS_QUICK_GUARD | SIDE_STATUS_WIDE_GUARD | SIDE_STATUS_CRAFTY_SHIELD | SIDE_STATUS_MAT_BLOCK);
gSideStatuses[B_SIDE_OPPONENT] &= ~(SIDE_STATUS_QUICK_GUARD | SIDE_STATUS_WIDE_GUARD | SIDE_STATUS_CRAFTY_SHIELD | SIDE_STATUS_MAT_BLOCK);
gSideTimers[B_SIDE_PLAYER].followmeTimer = 0;
gSideTimers[B_SIDE_OPPONENT].followmeTimer = 0;
gBattleStruct->pledgeMove = FALSE; // combined pledge move may not have been used due to a canceller
}
static void SpecialStatusesClear(void)
void SpecialStatusesClear(void)
{
for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++)
{
s32 i;
u8 *dataPtr = (u8 *)(&gSpecialStatuses[gActiveBattler]);
for (i = 0; i < sizeof(struct SpecialStatus); i++)
dataPtr[i] = 0;
}
memset(&gSpecialStatuses, 0, sizeof(gSpecialStatuses));
}
static void CheckFocusPunch_ClearVarsBeforeTurnStarts(void)

View File

@@ -394,8 +394,8 @@ void (* const gBattleScriptingCommandsTable[])(void) =
Cmd_seteffectsecondary, //0x17 // done
Cmd_clearstatusfromeffect, //0x18 // done
Cmd_tryfaintmon, //0x19 // done
Cmd_dofaintanimation, //0x1A
Cmd_cleareffectsonfaint, //0x1B
Cmd_dofaintanimation, //0x1A // done
Cmd_cleareffectsonfaint, //0x1B // done
Cmd_jumpifstatus, //0x1C
Cmd_jumpifstatus2, //0x1D
Cmd_jumpifability, //0x1E
@@ -4092,27 +4092,35 @@ static void Cmd_tryfaintmon(void)
static void Cmd_dofaintanimation(void)
{
CMD_ARGS(u8 battler);
if (gBattleControllerExecFlags == 0)
{
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
u32 battler = gActiveBattler = GetBattlerForBattleScript(cmd->battler);
BtlController_EmitFaintAnimation(BUFFER_A);
MarkBattlerForControllerExec(gActiveBattler);
gBattlescriptCurrInstr += 2;
MarkBattlerForControllerExec(battler);
gBattlescriptCurrInstr = cmd->nextInstr;
}
}
static void Cmd_cleareffectsonfaint(void)
{
CMD_ARGS(u8 battler);
if (gBattleControllerExecFlags == 0)
{
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
u32 battler = gActiveBattler = GetBattlerForBattleScript(cmd->battler);
const u8 *clearDataResult = NULL;
gBattleMons[gActiveBattler].status1 = 0;
BtlController_EmitSetMonData(BUFFER_A, REQUEST_STATUS_BATTLE, 0, sizeof(gBattleMons[gActiveBattler].status1), &gBattleMons[gActiveBattler].status1);
MarkBattlerForControllerExec(gActiveBattler);
gBattleMons[battler].status1 = 0;
BtlController_EmitSetMonData(BUFFER_A, REQUEST_STATUS_BATTLE, 0, sizeof(gBattleMons[battler].status1), &gBattleMons[battler].status1);
MarkBattlerForControllerExec(battler);
FaintClearSetData(); // Effects like attractions, trapping, etc.
gBattlescriptCurrInstr += 2;
clearDataResult = FaintClearSetData(battler); // Effects like attractions, trapping, etc.
if (clearDataResult)
gBattlescriptCurrInstr = clearDataResult;
else
gBattlescriptCurrInstr = cmd->nextInstr;
}
}
@@ -5706,7 +5714,7 @@ static void Cmd_switchindataupdate(void)
gBattleMons[gActiveBattler].status2 = oldData.status2;
}
SwitchInClearSetData();
SwitchInClearSetData(gActiveBattler);
gBattleScripting.battler = gActiveBattler;
@@ -6851,7 +6859,7 @@ static void Cmd_removeitem(void)
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
usedHeldItem = &gBattleStruct->usedHeldItems[gActiveBattler];
usedHeldItem = &gBattleStruct->usedHeldItems[gActiveBattler][GetBattlerSide(gActiveBattler)];
*usedHeldItem = gBattleMons[gActiveBattler].item;
gBattleMons[gActiveBattler].item = ITEM_NONE;
@@ -7719,7 +7727,7 @@ static void Cmd_trymirrormove(void)
{
if (i != gBattlerAttacker)
{
move = T1_READ_16(i * 2 + gBattlerAttacker * 8 + gBattleStruct->lastTakenMoveFrom);
move = gBattleStruct->lastTakenMoveFrom[gBattlerAttacker][i];
if (move != MOVE_NONE && move != MOVE_UNAVAILABLE)
{
@@ -10740,7 +10748,7 @@ static void Cmd_tryrecycleitem(void)
u16 *usedHeldItem;
gActiveBattler = gBattlerAttacker;
usedHeldItem = &gBattleStruct->usedHeldItems[gActiveBattler];
usedHeldItem = &gBattleStruct->usedHeldItems[gActiveBattler][GetBattlerSide(gActiveBattler)];
if (*usedHeldItem != ITEM_NONE && gBattleMons[gActiveBattler].item == ITEM_NONE)
{
gLastUsedItem = *usedHeldItem;