Skip to content

Commit

Permalink
Final 1.10 master upcoming merge (#6350)
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexOn1ine authored Feb 26, 2025
2 parents b16aa37 + e9347a0 commit 0a0189d
Show file tree
Hide file tree
Showing 54 changed files with 165 additions and 78 deletions.
2 changes: 2 additions & 0 deletions data/battle_scripts_1.s
Original file line number Diff line number Diff line change
Expand Up @@ -1034,6 +1034,7 @@ BattleScript_EffectCoaching::
setallytonexttarget EffectCoaching_CheckAllyStats
goto BattleScript_ButItFailed
EffectCoaching_CheckAllyStats:
accuracycheck BattleScript_ButItFailed, NO_ACC_CALC_CHECK_LOCK_ON
jumpifstat BS_TARGET, CMP_NOT_EQUAL, STAT_ATK, MAX_STAT_STAGE, BattleScript_CoachingWorks
jumpifstat BS_TARGET, CMP_NOT_EQUAL, STAT_DEF, MAX_STAT_STAGE, BattleScript_CoachingWorks
goto BattleScript_ButItFailed @ ally at max atk, def
Expand Down Expand Up @@ -3776,6 +3777,7 @@ BattleScript_TwoTurnMovesSecondTurn::

BattleScript_TwoTurnMovesSecondTurnRet:
setbyte sB_ANIM_TURN, 1
setbyte sB_ANIM_TARGETS_HIT, 0
clearstatusfromeffect BS_ATTACKER, MOVE_EFFECT_CHARGING
clearsemiinvulnerablebit @ only for moves with EFFECT_SEMI_INVULNERABLE/EFFECT_SKY_DROP
return
Expand Down
1 change: 1 addition & 0 deletions docs/team_procedures/scope.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ Pull Requests that fall into this category are not in scope by default and shoul
2. **Fangame Features**: Adds a popular feature from other fangames
3. **Popular Non-SS Features**: Exceptions can be made for uniquely popular or requested features (Drowsy, PLA Legend Plate, etc.)
4. **External Program**: External programs like poryscript, porymoves, etc.
5. **Intergenerational Feature Compatibility**: Addresses limitations and issues resulting from including all generational behaviours in a GBA native title, and extrapolation of features no longer supported by GameFreak

## Workflow for Proposed Feature Scope Discussion
For the contributor:
Expand Down
Binary file modified graphics/battle_interface/alpha_indicator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified graphics/battle_interface/bug_indicator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified graphics/battle_interface/dark_indicator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified graphics/battle_interface/dragon_indicator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified graphics/battle_interface/dynamax_indicator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified graphics/battle_interface/electric_indicator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified graphics/battle_interface/fairy_indicator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified graphics/battle_interface/fighting_indicator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified graphics/battle_interface/fire_indicator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified graphics/battle_interface/flying_indicator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified graphics/battle_interface/ghost_indicator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified graphics/battle_interface/grass_indicator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified graphics/battle_interface/ground_indicator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified graphics/battle_interface/ice_indicator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified graphics/battle_interface/mega_indicator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified graphics/battle_interface/normal_indicator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified graphics/battle_interface/omega_indicator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified graphics/battle_interface/poison_indicator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified graphics/battle_interface/psychic_indicator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified graphics/battle_interface/rock_indicator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified graphics/battle_interface/steel_indicator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified graphics/battle_interface/stellar_indicator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified graphics/battle_interface/water_indicator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 4 additions & 1 deletion include/battle.h
Original file line number Diff line number Diff line change
Expand Up @@ -829,7 +829,10 @@ struct BattleStruct
u8 calculatedSpreadMoveAccuracy:1;
u8 printedStrongWindsWeakenedAttack:1;
u8 numSpreadTargets:2;
u8 padding3:2;
u8 bypassMoldBreakerChecks:1; // for ABILITYEFFECT_IMMUNITY
u8 padding3:1;
u8 usedEjectItem;
u8 usedMicleBerry;
struct MessageStatus slideMessageStatus;
u8 trainerSlideSpriteIds[MAX_BATTLERS_COUNT];
u8 embodyAspectBoost[NUM_BATTLE_SIDES];
Expand Down
1 change: 1 addition & 0 deletions include/battle_ai_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ bool32 AI_ShouldSetUpHazards(u32 battlerAtk, u32 battlerDef, struct AiLogicData
void IncreaseTidyUpScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score);
bool32 AI_ShouldSpicyExtract(u32 battlerAtk, u32 battlerAtkPartner, u32 move, struct AiLogicData *aiData);
u32 IncreaseSubstituteMoveScore(u32 battlerAtk, u32 battlerDef, u32 move);
bool32 IsBattlerItemEnabled(u32 battler);
bool32 IsBattlerPredictedToSwitch(u32 battler);
bool32 HasLowAccuracyMove(u32 battlerAtk, u32 battlerDef);

Expand Down
2 changes: 1 addition & 1 deletion include/constants/battle.h
Original file line number Diff line number Diff line change
Expand Up @@ -558,7 +558,7 @@ enum MoveEffects

#define MOVE_TARGET_SELECTED 0
#define MOVE_TARGET_DEPENDS (1 << 0)
#define MOVE_TARGET_USER_OR_SELECTED (1 << 1)
#define MOVE_TARGET_OPPONENT (1 << 1)
#define MOVE_TARGET_RANDOM (1 << 2)
#define MOVE_TARGET_BOTH (1 << 3)
#define MOVE_TARGET_USER (1 << 4)
Expand Down
8 changes: 4 additions & 4 deletions include/constants/event_objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,10 +270,10 @@
#define OBJ_EVENT_GFX_VAR_E (OBJ_EVENT_GFX_VARS + 0xE)
#define OBJ_EVENT_GFX_VAR_F (OBJ_EVENT_GFX_VARS + 0xF)

#define OBJ_EVENT_MON (1u << 15)
#define OBJ_EVENT_MON_SHINY (1u << 14)
#define OBJ_EVENT_MON_FEMALE (1u << 13)
#define OBJ_EVENT_MON_SPECIES_MASK (~(7u << 13))
#define OBJ_EVENT_MON (1u << 14)
#define OBJ_EVENT_MON_SHINY (1u << 13)
#define OBJ_EVENT_MON_FEMALE (1u << 12)
#define OBJ_EVENT_MON_SPECIES_MASK (~(7u << 12))

// Used to call a specific species' follower graphics. Useful for static encounters.
#define OBJ_EVENT_GFX_SPECIES(name) (SPECIES_##name + OBJ_EVENT_MON)
Expand Down
20 changes: 11 additions & 9 deletions src/battle_ai_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2349,9 +2349,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
}
break;
case EFFECT_NATURAL_GIFT:
if (aiData->abilities[battlerAtk] == ABILITY_KLUTZ
|| gFieldStatuses & STATUS_FIELD_MAGIC_ROOM
|| GetPocketByItemId(gBattleMons[battlerAtk].item) != POCKET_BERRIES)
if (!IsBattlerItemEnabled(battlerAtk) || GetPocketByItemId(gBattleMons[battlerAtk].item) != POCKET_BERRIES)
ADJUST_SCORE(-10);
break;
case EFFECT_GRASSY_TERRAIN:
Expand Down Expand Up @@ -2458,8 +2456,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
}
break;
case EFFECT_EMBARGO:
if (aiData->abilities[battlerDef] == ABILITY_KLUTZ
|| gFieldStatuses & STATUS_FIELD_MAGIC_ROOM
if (!IsBattlerItemEnabled(battlerAtk)
|| gDisableStructs[battlerDef].embargoTimer != 0
|| PartnerMoveIsSameAsAttacker(BATTLE_PARTNER(battlerAtk), battlerDef, move, aiData->partnerMove))
ADJUST_SCORE(-10);
Expand Down Expand Up @@ -2706,7 +2703,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
} // move effect checks

// Choice items
if (HOLD_EFFECT_CHOICE(aiData->holdEffects[battlerAtk]) && gBattleMons[battlerAtk].ability != ABILITY_KLUTZ)
if (HOLD_EFFECT_CHOICE(aiData->holdEffects[battlerAtk]) && IsBattlerItemEnabled(battlerAtk))
{
// Don't use user-target moves ie. Swords Dance, with exceptions
if ((moveTarget & MOVE_TARGET_USER)
Expand Down Expand Up @@ -3369,6 +3366,12 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
if (aiData->holdEffects[battlerAtk] == HOLD_EFFECT_BIG_ROOT && effectiveness >= UQ_4_12(1.0))
ADJUST_SCORE(DECENT_EFFECT);
break;
case EFFECT_DREAM_EATER:
case EFFECT_STRENGTH_SAP:
case EFFECT_AQUA_RING:
if (aiData->holdEffects[battlerAtk] == HOLD_EFFECT_BIG_ROOT)
ADJUST_SCORE(DECENT_EFFECT);
break;
case EFFECT_EXPLOSION:
case EFFECT_MEMENTO:
if (AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_WILL_SUICIDE && gBattleMons[battlerDef].statStages[STAT_EVASION] < 7)
Expand Down Expand Up @@ -3590,8 +3593,6 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
case EFFECT_MOONLIGHT:
if (ShouldRecover(battlerAtk, battlerDef, move, 50))
ADJUST_SCORE(GOOD_EFFECT);
if (aiData->holdEffects[battlerAtk] == HOLD_EFFECT_BIG_ROOT)
ADJUST_SCORE(DECENT_EFFECT);
break;
case EFFECT_TOXIC:
case EFFECT_POISON:
Expand Down Expand Up @@ -3667,7 +3668,8 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
|| aiData->abilities[battlerDef] == ABILITY_MAGIC_GUARD)
break;
ADJUST_SCORE(GOOD_EFFECT);
if (!HasDamagingMove(battlerDef) || IsBattlerTrapped(battlerDef, FALSE))
if (!HasDamagingMove(battlerDef) || IsBattlerTrapped(battlerDef, FALSE)
|| aiData->holdEffects[battlerAtk] == HOLD_EFFECT_BIG_ROOT)
ADJUST_SCORE(DECENT_EFFECT);
break;
case EFFECT_DO_NOTHING:
Expand Down
6 changes: 3 additions & 3 deletions src/battle_ai_switch_items.c
Original file line number Diff line number Diff line change
Expand Up @@ -966,7 +966,7 @@ static bool32 ShouldSwitchIfBadChoiceLock(u32 battler)
{
u32 holdEffect = GetBattlerHoldEffect(battler, FALSE);

if (HOLD_EFFECT_CHOICE(holdEffect) && gBattleMons[battler].ability != ABILITY_KLUTZ)
if (HOLD_EFFECT_CHOICE(holdEffect) && IsBattlerItemEnabled(battler))
{
if (GetMoveCategory(AI_DATA->lastUsedMove[battler]) == DAMAGE_CATEGORY_STATUS && RandomPercentage(RNG_AI_SWITCH_CHOICE_LOCKED, GetSwitchChance(SHOULD_SWITCH_CHOICE_LOCKED)))
return SetSwitchinAndSwitch(battler, PARTY_SIZE);
Expand Down Expand Up @@ -1379,10 +1379,10 @@ bool32 IsMonGrounded(u16 heldItemEffect, u32 ability, u8 type1, u8 type2)
{
// List that makes mon not grounded
if (type1 == TYPE_FLYING || type2 == TYPE_FLYING || ability == ABILITY_LEVITATE
|| (heldItemEffect == HOLD_EFFECT_AIR_BALLOON && ability != ABILITY_KLUTZ))
|| (heldItemEffect == HOLD_EFFECT_AIR_BALLOON && !(ability == ABILITY_KLUTZ || (gFieldStatuses & STATUS_FIELD_MAGIC_ROOM))))
{
// List that overrides being off the ground
if ((heldItemEffect == HOLD_EFFECT_IRON_BALL && ability != ABILITY_KLUTZ) || (gFieldStatuses & STATUS_FIELD_GRAVITY) || (gFieldStatuses & STATUS_FIELD_MAGIC_ROOM))
if ((heldItemEffect == HOLD_EFFECT_IRON_BALL && !(ability == ABILITY_KLUTZ || (gFieldStatuses & STATUS_FIELD_MAGIC_ROOM))) || (gFieldStatuses & STATUS_FIELD_GRAVITY) || (gFieldStatuses & STATUS_FIELD_MAGIC_ROOM))
return TRUE;
else
return FALSE;
Expand Down
24 changes: 14 additions & 10 deletions src/battle_ai_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -423,15 +423,6 @@ static inline s32 DmgRoll(s32 dmg)
bool32 IsDamageMoveUnusable(u32 battlerAtk, u32 battlerDef, u32 move, u32 moveType)
{
struct AiLogicData *aiData = AI_DATA;
u32 battlerDefAbility;

if (DoesBattlerIgnoreAbilityChecks(battlerAtk, aiData->abilities[battlerAtk], move))
battlerDefAbility = ABILITY_NONE;
else
battlerDefAbility = aiData->abilities[battlerDef];

if (battlerDef == BATTLE_PARTNER(battlerAtk))
battlerDefAbility = aiData->abilities[battlerDef];

if (gBattleStruct->battlerState[battlerDef].commandingDondozo)
return TRUE;
Expand Down Expand Up @@ -470,7 +461,7 @@ bool32 IsDamageMoveUnusable(u32 battlerAtk, u32 battlerDef, u32 move, u32 moveTy
return TRUE;
break;
case EFFECT_POLTERGEIST:
if (AI_DATA->items[battlerDef] == ITEM_NONE || gFieldStatuses & STATUS_FIELD_MAGIC_ROOM || battlerDefAbility == ABILITY_KLUTZ)
if (AI_DATA->items[battlerDef] == ITEM_NONE || !IsBattlerItemEnabled(battlerDef))
return TRUE;
break;
case EFFECT_FIRST_TURN_ONLY:
Expand Down Expand Up @@ -4296,3 +4287,16 @@ bool32 HasLowAccuracyMove(u32 battlerAtk, u32 battlerDef)
}
return FALSE;
}

bool32 IsBattlerItemEnabled(u32 battler)
{
if (AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_NEGATE_UNAWARE)
return TRUE;
if (gFieldStatuses & STATUS_FIELD_MAGIC_ROOM)
return FALSE;
if (gStatuses3[battler] & STATUS3_EMBARGO)
return FALSE;
if (gBattleMons[battler].ability == ABILITY_KLUTZ && !(gStatuses3[battler] & STATUS3_GASTRO_ACID))
return FALSE;
return TRUE;
}
4 changes: 2 additions & 2 deletions src/battle_controller_opponent.c
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,7 @@ static void OpponentHandleChooseMove(u32 battler)
default:
{
u16 chosenMove = moveInfo->moves[chosenMoveId];
if (GetBattlerMoveTargetType(battler, chosenMove) & (MOVE_TARGET_USER_OR_SELECTED | MOVE_TARGET_USER))
if (GetBattlerMoveTargetType(battler, chosenMove) & MOVE_TARGET_USER)
gBattlerTarget = battler;
if (GetBattlerMoveTargetType(battler, chosenMove) & MOVE_TARGET_BOTH)
{
Expand Down Expand Up @@ -595,7 +595,7 @@ static void OpponentHandleChooseMove(u32 battler)
move = moveInfo->moves[chosenMoveId];
} while (move == MOVE_NONE);

if (GetBattlerMoveTargetType(battler, move) & (MOVE_TARGET_USER_OR_SELECTED | MOVE_TARGET_USER))
if (GetBattlerMoveTargetType(battler, move) & MOVE_TARGET_USER)
BtlController_EmitTwoReturnValues(battler, BUFFER_B, 10, (chosenMoveId) | (battler << 8));
else if (IsDoubleBattle())
{
Expand Down
21 changes: 7 additions & 14 deletions src/battle_controller_player.c
Original file line number Diff line number Diff line change
Expand Up @@ -495,8 +495,6 @@ void HandleInputChooseTarget(u32 battler)
case B_POSITION_PLAYER_RIGHT:
if (battler != gMultiUsePlayerCursor)
i++;
else if (moveTarget & MOVE_TARGET_USER_OR_SELECTED)
i++;
break;
case B_POSITION_OPPONENT_LEFT:
case B_POSITION_OPPONENT_RIGHT:
Expand All @@ -505,7 +503,8 @@ void HandleInputChooseTarget(u32 battler)
}

if (gAbsentBattlerFlags & (1u << gMultiUsePlayerCursor)
|| !CanTargetBattler(battler, gMultiUsePlayerCursor, move))
|| !CanTargetBattler(battler, gMultiUsePlayerCursor, move)
|| (moveTarget & MOVE_TARGET_OPPONENT && GetBattlerSide(gMultiUsePlayerCursor) == B_SIDE_PLAYER))
i = 0;
} while (i == 0);
}
Expand Down Expand Up @@ -545,8 +544,6 @@ void HandleInputChooseTarget(u32 battler)
case B_POSITION_PLAYER_RIGHT:
if (battler != gMultiUsePlayerCursor)
i++;
else if (moveTarget & MOVE_TARGET_USER_OR_SELECTED)
i++;
break;
case B_POSITION_OPPONENT_LEFT:
case B_POSITION_OPPONENT_RIGHT:
Expand All @@ -555,7 +552,8 @@ void HandleInputChooseTarget(u32 battler)
}

if (gAbsentBattlerFlags & (1u << gMultiUsePlayerCursor)
|| !CanTargetBattler(battler, gMultiUsePlayerCursor, move))
|| !CanTargetBattler(battler, gMultiUsePlayerCursor, move)
|| (moveTarget & MOVE_TARGET_OPPONENT && GetBattlerSide(gMultiUsePlayerCursor) == B_SIDE_PLAYER))
i = 0;
} while (i == 0);
}
Expand Down Expand Up @@ -690,12 +688,7 @@ void HandleInputChooseMove(u32 battler)
else
gMultiUsePlayerCursor = GetOpposingSideBattler(battler);

if (!gBattleResources->bufferA[battler][1]) // not a double battle
{
if (moveTarget & MOVE_TARGET_USER_OR_SELECTED && !gBattleResources->bufferA[battler][2])
canSelectTarget = 1;
}
else // double battle
if (gBattleResources->bufferA[battler][1]) // a double battle
{
if (!(moveTarget & (MOVE_TARGET_RANDOM | MOVE_TARGET_BOTH | MOVE_TARGET_DEPENDS | MOVE_TARGET_FOES_AND_ALLY | MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_USER | MOVE_TARGET_ALLY)))
canSelectTarget = 1; // either selected or user
Expand All @@ -706,7 +699,7 @@ void HandleInputChooseMove(u32 battler)
{
canSelectTarget = 0;
}
else if (!(moveTarget & (MOVE_TARGET_USER | MOVE_TARGET_USER_OR_SELECTED)) && CountAliveMonsInBattle(BATTLE_ALIVE_EXCEPT_BATTLER, battler) <= 1)
else if (!(moveTarget & MOVE_TARGET_USER) && CountAliveMonsInBattle(BATTLE_ALIVE_EXCEPT_BATTLER, battler) <= 1)
{
gMultiUsePlayerCursor = GetDefaultMoveTarget(battler);
canSelectTarget = 0;
Expand Down Expand Up @@ -749,7 +742,7 @@ void HandleInputChooseMove(u32 battler)
case 1:
gBattlerControllerFuncs[battler] = HandleInputChooseTarget;

if (moveTarget & (MOVE_TARGET_USER | MOVE_TARGET_USER_OR_SELECTED))
if (moveTarget & MOVE_TARGET_USER)
gMultiUsePlayerCursor = battler;
else if (gAbsentBattlerFlags & (1u << GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT)))
gMultiUsePlayerCursor = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT);
Expand Down
2 changes: 1 addition & 1 deletion src/battle_controller_player_partner.c
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ static void PlayerPartnerHandleChooseMove(u32 battler)
gBattlerTarget = gBattleStruct->aiChosenTarget[battler];
u32 moveTarget = GetBattlerMoveTargetType(battler, moveInfo->moves[chosenMoveId]);

if (moveTarget & (MOVE_TARGET_USER | MOVE_TARGET_USER_OR_SELECTED))
if (moveTarget & MOVE_TARGET_USER)
gBattlerTarget = battler;
else if (moveTarget & MOVE_TARGET_BOTH)
{
Expand Down
2 changes: 1 addition & 1 deletion src/battle_gfx_sfx_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ static u8 GetBattlePalaceMoveGroup(u8 battler, u16 move)
switch (GetBattlerMoveTargetType(battler, move))
{
case MOVE_TARGET_SELECTED:
case MOVE_TARGET_USER_OR_SELECTED:
case MOVE_TARGET_OPPONENT:
case MOVE_TARGET_RANDOM:
case MOVE_TARGET_BOTH:
case MOVE_TARGET_FOES_AND_ALLY:
Expand Down
8 changes: 4 additions & 4 deletions src/battle_gimmick.c
Original file line number Diff line number Diff line change
Expand Up @@ -371,10 +371,10 @@ void UpdateIndicatorLevelData(u32 healthboxId, u32 level)

static const s8 sIndicatorPositions[][2] =
{
[B_POSITION_PLAYER_LEFT] = {53, -9},
[B_POSITION_OPPONENT_LEFT] = {44, -9},
[B_POSITION_PLAYER_RIGHT] = {52, -9},
[B_POSITION_OPPONENT_RIGHT] = {44, -9},
[B_POSITION_PLAYER_LEFT] = {49, -9},
[B_POSITION_OPPONENT_LEFT] = {40, -9},
[B_POSITION_PLAYER_RIGHT] = {48, -9},
[B_POSITION_OPPONENT_RIGHT] = {40, -9},
};

void CreateIndicatorSprite(u32 battler)
Expand Down
3 changes: 3 additions & 0 deletions src/battle_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3205,6 +3205,9 @@ void SwitchInClearSetData(u32 battler)
gCurrentMove = MOVE_NONE;
gBattleStruct->arenaTurnCounter = 0xFF;

// Restore struct member so replacement does not miss timing
gSpecialStatuses[battler].switchInAbilityDone = FALSE;

// 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;
Expand Down
9 changes: 7 additions & 2 deletions src/battle_script_commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -1197,6 +1197,9 @@ static void Cmd_attackcanceler(void)

if (AbilityBattleEffects(ABILITYEFFECT_MOVES_BLOCK, gBattlerTarget, 0, 0, 0))
return;
if (gMovesInfo[gCurrentMove].effect == EFFECT_PARALYZE && AbilityBattleEffects(ABILITYEFFECT_ABSORBING, gBattlerTarget, 0, 0, gCurrentMove))
return;

if (!gBattleMons[gBattlerAttacker].pp[gCurrMovePos] && gCurrentMove != MOVE_STRUGGLE
&& !(gHitMarker & (HITMARKER_ALLOW_NO_PP | HITMARKER_NO_ATTACKSTRING | HITMARKER_NO_PPDEDUCT))
&& !(gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS))
Expand Down Expand Up @@ -3884,7 +3887,7 @@ void SetMoveEffect(bool32 primary, bool32 certain)
gProtectStructs[gBattlerTarget].banefulBunkered = FALSE;
gProtectStructs[gBattlerTarget].obstructed = FALSE;
gProtectStructs[gBattlerTarget].silkTrapped = FALSE;
gProtectStructs[gBattlerAttacker].burningBulwarked = FALSE;
gProtectStructs[gBattlerTarget].burningBulwarked = FALSE;
BattleScriptPush(gBattlescriptCurrInstr + 1);
if (gCurrentMove == MOVE_HYPERSPACE_FURY)
gBattlescriptCurrInstr = BattleScript_HyperspaceFuryRemoveProtect;
Expand Down Expand Up @@ -6360,6 +6363,7 @@ static void Cmd_moveend(void)
else if (moveRecoil > 0
&& !(gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NO_EFFECT)
&& IsBattlerAlive(gBattlerAttacker)
&& IsBattlerTurnDamaged(gBattlerTarget)
&& gBattleScripting.savedDmg != 0) // Some checks may be redundant alongside this one
{
gBattleStruct->moveDamage[gBattlerAttacker] = max(1, gBattleScripting.savedDmg * max(1, moveRecoil) / 100);
Expand Down Expand Up @@ -11605,7 +11609,8 @@ static void TryResetProtectUseCounter(u32 battler)
u32 lastEffect = GetMoveEffect(lastMove);
if (lastMove == MOVE_UNAVAILABLE
|| (!gBattleMoveEffects[lastEffect].usesProtectCounter
&& (B_ALLY_SWITCH_FAIL_CHANCE >= GEN_9 && lastEffect != EFFECT_ALLY_SWITCH)))
&& ((B_ALLY_SWITCH_FAIL_CHANCE >= GEN_9 && lastEffect != EFFECT_ALLY_SWITCH)
|| B_ALLY_SWITCH_FAIL_CHANCE < GEN_9)))
gDisableStructs[battler].protectUses = 0;
}

Expand Down
Loading

0 comments on commit 0a0189d

Please sign in to comment.