mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2024-12-26 03:34:15 +01:00
Merge branch 'battle_engine' into bug_bite
This commit is contained in:
commit
21837b659a
@ -1830,6 +1830,20 @@
|
||||
various BS_ATTACKER, VARIOUS_TRY_TO_CLEAR_PRIMAL_WEATHER
|
||||
.endm
|
||||
|
||||
.macro getrototillertargets ptr:req
|
||||
various BS_ATTACKER, VARIOUS_GET_ROTOTILLER_TARGETS
|
||||
.4byte \ptr
|
||||
.endm
|
||||
|
||||
.macro jumpifnotrototilleraffected battler:req, ptr:req
|
||||
various \battler, VARIOUS_JUMP_IF_NOT_ROTOTILLER_AFFECTED
|
||||
.4byte \ptr
|
||||
.endm
|
||||
|
||||
.macro tryactivatebattlebond battler:req
|
||||
various \battler, VARIOUS_TRY_ACTIVATE_BATTLE_BOND
|
||||
.endm
|
||||
|
||||
@ helpful macros
|
||||
.macro setstatchanger stat:req, stages:req, down:req
|
||||
setbyte sSTATCHANGER \stat | \stages << 3 | \down << 7
|
||||
|
@ -976,27 +976,24 @@ BattleScript_FlowerShieldMoveTargetEnd:
|
||||
moveendto MOVEEND_NEXT_TARGET
|
||||
jumpifnexttargetvalid BattleScript_FlowerShieldLoop
|
||||
end
|
||||
|
||||
|
||||
BattleScript_EffectRototiller:
|
||||
attackcanceler
|
||||
attackstring
|
||||
ppreduce
|
||||
selectfirstvalidtarget
|
||||
BattleScript_RototillerLoop:
|
||||
movevaluescleanup
|
||||
jumpifnotgrounded BS_TARGET, BattleScript_RototillerNoEffect
|
||||
jumpiftype BS_TARGET, TYPE_GRASS, BattleScript_RototillerLoop2
|
||||
BattleScript_RototillerNoEffect:
|
||||
pause B_WAIT_TIME_SHORT
|
||||
printstring STRINGID_NOEFFECTONTARGET
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_RototillerMoveTargetEnd
|
||||
BattleScript_RototillerLoop2:
|
||||
jumpifstat BS_TARGET, CMP_LESS_THAN, STAT_ATK, MAX_STAT_STAGE, BattleScript_RototillerDoMoveAnim
|
||||
jumpifstat BS_TARGET, CMP_EQUAL, STAT_SPATK, MAX_STAT_STAGE, BattleScript_RototillerCantRaiseMultipleStats
|
||||
BattleScript_RototillerDoMoveAnim::
|
||||
getrototillertargets BattleScript_ButItFailed
|
||||
@ at least one battler is affected
|
||||
attackanimation
|
||||
waitanimation
|
||||
savetarget
|
||||
setbyte gBattlerTarget, 0
|
||||
BattleScript_RototillerLoop:
|
||||
movevaluescleanup
|
||||
jumpifstat BS_TARGET, CMP_LESS_THAN, STAT_ATK, MAX_STAT_STAGE, BattleScript_RototillerCheckAffected
|
||||
jumpifstat BS_TARGET, CMP_EQUAL, STAT_SPATK, MAX_STAT_STAGE, BattleScript_RototillerCantRaiseMultipleStats
|
||||
BattleScript_RototillerCheckAffected:
|
||||
jumpifnotrototilleraffected BS_TARGET, BattleScript_RototillerNoEffect
|
||||
BattleScript_RototillerAffected:
|
||||
setbyte sSTAT_ANIM_PLAYED, FALSE
|
||||
playstatchangeanimation BS_TARGET, BIT_ATK | BIT_SPATK, 0
|
||||
setstatchanger STAT_ATK, 1, FALSE
|
||||
@ -1012,13 +1009,22 @@ BattleScript_RototillerTrySpAtk::
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
BattleScript_RototillerMoveTargetEnd:
|
||||
moveendto MOVEEND_NEXT_TARGET
|
||||
jumpifnexttargetvalid BattleScript_RototillerLoop
|
||||
addbyte gBattlerTarget, 1
|
||||
jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_RototillerLoop
|
||||
end
|
||||
|
||||
BattleScript_RototillerCantRaiseMultipleStats:
|
||||
copybyte gBattlerAttacker, gBattlerTarget
|
||||
printstring STRINGID_STATSWONTINCREASE2
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_RototillerMoveTargetEnd
|
||||
|
||||
BattleScript_RototillerNoEffect:
|
||||
pause B_WAIT_TIME_SHORT
|
||||
printstring STRINGID_NOEFFECTONTARGET
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_RototillerMoveTargetEnd
|
||||
|
||||
BattleScript_EffectBestow:
|
||||
attackcanceler
|
||||
accuracycheck BattleScript_PrintMoveMissed, NO_ACC_CALC_CHECK_LOCK_ON
|
||||
@ -5317,6 +5323,7 @@ BattleScript_FaintTarget::
|
||||
tryactivatemoxie BS_ATTACKER @ and chilling neigh, as one ice rider
|
||||
tryactivatebeastboost BS_ATTACKER
|
||||
tryactivategrimneigh BS_ATTACKER @ and as one shadow rider
|
||||
tryactivatebattlebond BS_ATTACKER
|
||||
trytrainerslidefirstdownmsg BS_TARGET
|
||||
return
|
||||
|
||||
@ -7552,6 +7559,7 @@ BattleScript_MoveStatDrain::
|
||||
waitanimation
|
||||
printstring STRINGID_TARGETABILITYSTATRAISE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
clearsemiinvulnerablebit
|
||||
tryfaintmon BS_ATTACKER, FALSE, NULL
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
|
@ -175,6 +175,7 @@ struct SpecialStatus
|
||||
u8 instructedChosenTarget:3;
|
||||
u8 berryReduced:1;
|
||||
u8 gemBoost:1;
|
||||
u8 rototillerAffected:1; // to be affected by rototiller
|
||||
u8 gemParam;
|
||||
u8 damagedMons:4; // Mons that have been damaged directly by using a move, includes substitute.
|
||||
u8 dancerUsedMove:1;
|
||||
|
@ -154,7 +154,7 @@ bool32 CompareStat(u8 battlerId, u8 statId, u8 cmpTo, u8 cmpKind);
|
||||
bool32 TryRoomService(u8 battlerId);
|
||||
void BufferStatChange(u8 battlerId, u8 statId, u8 stringId);
|
||||
void DoBurmyFormChange(u32 monId);
|
||||
bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u8 battlerDef);
|
||||
bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u8 battlerDef, bool32 checkTarget);
|
||||
|
||||
// ability checks
|
||||
bool32 IsRolePlayBannedAbilityAtk(u16 ability);
|
||||
|
@ -387,4 +387,6 @@
|
||||
#define MOVE_TARGET_OPPONENTS_FIELD 0x40
|
||||
#define MOVE_TARGET_ALLY 0x80
|
||||
|
||||
#define MOVE_TARGET_ALL_BATTLERS (MOVE_TARGET_BOTH | MOVE_TARGET_OPPONENTS_FIELD)
|
||||
|
||||
#endif // GUARD_CONSTANTS_BATTLE_H
|
||||
|
@ -186,7 +186,10 @@
|
||||
#define VARIOUS_REMOVE_TERRAIN 113
|
||||
#define VARIOUS_JUMP_IF_PRANKSTER_BLOCKED 114
|
||||
#define VARIOUS_TRY_TO_CLEAR_PRIMAL_WEATHER 115
|
||||
#define VARIOUS_CONSUME_BERRY 116
|
||||
#define VARIOUS_GET_ROTOTILLER_TARGETS 116
|
||||
#define VARIOUS_JUMP_IF_NOT_ROTOTILLER_AFFECTED 117
|
||||
#define VARIOUS_TRY_ACTIVATE_BATTLE_BOND 118
|
||||
#define VARIOUS_CONSUME_BERRY 119
|
||||
|
||||
// Cmd_manipulatedamage
|
||||
#define DMG_CHANGE_SIGN 0
|
||||
|
@ -496,6 +496,19 @@ static void HandleInputChooseTarget(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void HideAllTargets(void)
|
||||
{
|
||||
s32 i;
|
||||
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
|
||||
{
|
||||
if (IsBattlerAlive(i) && gBattleSpritesDataPtr->healthBoxesData[i].healthboxIsBouncing)
|
||||
{
|
||||
gSprites[gBattlerSpriteIds[i]].callback = SpriteCb_HideAsMoveTarget;
|
||||
EndBounceEffect(i, BOUNCE_HEALTHBOX);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void HideShownTargets(void)
|
||||
{
|
||||
s32 i;
|
||||
@ -509,6 +522,34 @@ static void HideShownTargets(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void HandleInputShowEntireFieldTargets(void)
|
||||
{
|
||||
if (JOY_HELD(DPAD_ANY) && gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_L_EQUALS_A)
|
||||
gPlayerDpadHoldFrames++;
|
||||
else
|
||||
gPlayerDpadHoldFrames = 0;
|
||||
|
||||
if (JOY_NEW(A_BUTTON))
|
||||
{
|
||||
PlaySE(SE_SELECT);
|
||||
HideAllTargets();
|
||||
if (gBattleStruct->mega.playerSelect)
|
||||
BtlController_EmitTwoReturnValues(1, 10, gMoveSelectionCursor[gActiveBattler] | RET_MEGA_EVOLUTION | (gMultiUsePlayerCursor << 8));
|
||||
else
|
||||
BtlController_EmitTwoReturnValues(1, 10, gMoveSelectionCursor[gActiveBattler] | (gMultiUsePlayerCursor << 8));
|
||||
HideMegaTriggerSprite();
|
||||
PlayerBufferExecCompleted();
|
||||
}
|
||||
else if (gMain.newKeys & B_BUTTON || gPlayerDpadHoldFrames > 59)
|
||||
{
|
||||
PlaySE(SE_SELECT);
|
||||
HideAllTargets();
|
||||
gBattlerControllerFuncs[gActiveBattler] = HandleInputChooseMove;
|
||||
DoBounceEffect(gActiveBattler, BOUNCE_HEALTHBOX, 7, 1);
|
||||
DoBounceEffect(gActiveBattler, BOUNCE_MON, 7, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void HandleInputShowTargets(void)
|
||||
{
|
||||
if (JOY_HELD(DPAD_ANY) && gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_L_EQUALS_A)
|
||||
@ -601,18 +642,31 @@ static void HandleInputChooseMove(void)
|
||||
}
|
||||
|
||||
// Show all available targets for multi-target moves
|
||||
if (B_SHOW_TARGETS && moveTarget & (MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY))
|
||||
if (B_SHOW_TARGETS)
|
||||
{
|
||||
TryShowAsTarget(gMultiUsePlayerCursor);
|
||||
TryShowAsTarget(BATTLE_PARTNER(gMultiUsePlayerCursor));
|
||||
if (moveTarget & MOVE_TARGET_FOES_AND_ALLY)
|
||||
TryShowAsTarget(BATTLE_PARTNER(gActiveBattler));
|
||||
canSelectTarget = 2;
|
||||
if ((moveTarget & MOVE_TARGET_ALL_BATTLERS) == MOVE_TARGET_ALL_BATTLERS)
|
||||
{
|
||||
u32 i = 0;
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
TryShowAsTarget(i);
|
||||
|
||||
canSelectTarget = 3;
|
||||
}
|
||||
else if (moveTarget & (MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY))
|
||||
{
|
||||
TryShowAsTarget(gMultiUsePlayerCursor);
|
||||
TryShowAsTarget(BATTLE_PARTNER(gMultiUsePlayerCursor));
|
||||
if (moveTarget & MOVE_TARGET_FOES_AND_ALLY)
|
||||
TryShowAsTarget(BATTLE_PARTNER(gActiveBattler));
|
||||
canSelectTarget = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (canSelectTarget == 0)
|
||||
|
||||
switch (canSelectTarget)
|
||||
{
|
||||
case 0:
|
||||
default:
|
||||
if (gBattleStruct->mega.playerSelect)
|
||||
BtlController_EmitTwoReturnValues(1, 10, gMoveSelectionCursor[gActiveBattler] | RET_MEGA_EVOLUTION | (gMultiUsePlayerCursor << 8));
|
||||
else
|
||||
@ -620,9 +674,8 @@ static void HandleInputChooseMove(void)
|
||||
HideMegaTriggerSprite();
|
||||
TryHideLastUsedBall();
|
||||
PlayerBufferExecCompleted();
|
||||
}
|
||||
else if (canSelectTarget == 1)
|
||||
{
|
||||
break;
|
||||
case 1:
|
||||
gBattlerControllerFuncs[gActiveBattler] = HandleInputChooseTarget;
|
||||
|
||||
if (moveTarget & (MOVE_TARGET_USER | MOVE_TARGET_USER_OR_SELECTED))
|
||||
@ -633,10 +686,13 @@ static void HandleInputChooseMove(void)
|
||||
gMultiUsePlayerCursor = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
|
||||
|
||||
gSprites[gBattlerSpriteIds[gMultiUsePlayerCursor]].callback = SpriteCb_ShowAsMoveTarget;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
case 2:
|
||||
gBattlerControllerFuncs[gActiveBattler] = HandleInputShowTargets;
|
||||
break;
|
||||
case 3: // Entire field
|
||||
gBattlerControllerFuncs[gActiveBattler] = HandleInputShowEntireFieldTargets;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (JOY_NEW(B_BUTTON) || gPlayerDpadHoldFrames > 59)
|
||||
|
@ -1437,7 +1437,7 @@ static void Cmd_attackcanceler(void)
|
||||
gProtectStructs[gBattlerTarget].bounceMove = 0;
|
||||
gProtectStructs[gBattlerTarget].usesBouncedMove = 1;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
|
||||
if (BlocksPrankster(gCurrentMove, gBattlerTarget, gBattlerAttacker))
|
||||
if (BlocksPrankster(gCurrentMove, gBattlerTarget, gBattlerAttacker, TRUE))
|
||||
{
|
||||
// Opponent used a prankster'd magic coat -> reflected status move should fail against a dark-type attacker
|
||||
gBattlerTarget = gBattlerAttacker;
|
||||
@ -4533,12 +4533,13 @@ static void Cmd_endselectionscript(void)
|
||||
static void Cmd_playanimation(void)
|
||||
{
|
||||
const u16* argumentPtr;
|
||||
u8 animId = gBattlescriptCurrInstr[2];
|
||||
|
||||
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
|
||||
argumentPtr = T2_READ_PTR(gBattlescriptCurrInstr + 3);
|
||||
|
||||
#if B_TERRAIN_BG_CHANGE == FALSE
|
||||
if (gBattlescriptCurrInstr[2] == B_ANIM_RESTORE_BG)
|
||||
if (animId == B_ANIM_RESTORE_BG)
|
||||
{
|
||||
// workaround for .if not working
|
||||
gBattlescriptCurrInstr += 7;
|
||||
@ -4546,28 +4547,28 @@ static void Cmd_playanimation(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (gBattlescriptCurrInstr[2] == B_ANIM_STATS_CHANGE
|
||||
|| gBattlescriptCurrInstr[2] == B_ANIM_SNATCH_MOVE
|
||||
|| gBattlescriptCurrInstr[2] == B_ANIM_MEGA_EVOLUTION
|
||||
|| gBattlescriptCurrInstr[2] == B_ANIM_ILLUSION_OFF
|
||||
|| gBattlescriptCurrInstr[2] == B_ANIM_FORM_CHANGE
|
||||
|| gBattlescriptCurrInstr[2] == B_ANIM_SUBSTITUTE_FADE)
|
||||
if (animId == B_ANIM_STATS_CHANGE
|
||||
|| animId == B_ANIM_SNATCH_MOVE
|
||||
|| animId == B_ANIM_MEGA_EVOLUTION
|
||||
|| animId == B_ANIM_ILLUSION_OFF
|
||||
|| animId == B_ANIM_FORM_CHANGE
|
||||
|| animId == B_ANIM_SUBSTITUTE_FADE)
|
||||
{
|
||||
BtlController_EmitBattleAnimation(0, gBattlescriptCurrInstr[2], *argumentPtr);
|
||||
BtlController_EmitBattleAnimation(0, animId, *argumentPtr);
|
||||
MarkBattlerForControllerExec(gActiveBattler);
|
||||
gBattlescriptCurrInstr += 7;
|
||||
}
|
||||
else if (gHitMarker & HITMARKER_NO_ANIMATIONS)
|
||||
else if (gHitMarker & HITMARKER_NO_ANIMATIONS && animId != B_ANIM_RESTORE_BG)
|
||||
{
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 7);
|
||||
gBattlescriptCurrInstr = BattleScript_Pausex20;
|
||||
}
|
||||
else if (gBattlescriptCurrInstr[2] == B_ANIM_RAIN_CONTINUES
|
||||
|| gBattlescriptCurrInstr[2] == B_ANIM_SUN_CONTINUES
|
||||
|| gBattlescriptCurrInstr[2] == B_ANIM_SANDSTORM_CONTINUES
|
||||
|| gBattlescriptCurrInstr[2] == B_ANIM_HAIL_CONTINUES)
|
||||
else if (animId == B_ANIM_RAIN_CONTINUES
|
||||
|| animId == B_ANIM_SUN_CONTINUES
|
||||
|| animId == B_ANIM_SANDSTORM_CONTINUES
|
||||
|| animId == B_ANIM_HAIL_CONTINUES)
|
||||
{
|
||||
BtlController_EmitBattleAnimation(0, gBattlescriptCurrInstr[2], *argumentPtr);
|
||||
BtlController_EmitBattleAnimation(0, animId, *argumentPtr);
|
||||
MarkBattlerForControllerExec(gActiveBattler);
|
||||
gBattlescriptCurrInstr += 7;
|
||||
}
|
||||
@ -4577,7 +4578,7 @@ static void Cmd_playanimation(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
BtlController_EmitBattleAnimation(0, gBattlescriptCurrInstr[2], *argumentPtr);
|
||||
BtlController_EmitBattleAnimation(0, animId, *argumentPtr);
|
||||
MarkBattlerForControllerExec(gActiveBattler);
|
||||
gBattlescriptCurrInstr += 7;
|
||||
}
|
||||
@ -7382,6 +7383,21 @@ static u32 GetHighestStatId(u32 battlerId)
|
||||
return highestId;
|
||||
}
|
||||
|
||||
static bool32 IsRototillerAffected(u32 battlerId)
|
||||
{
|
||||
if (!IsBattlerAlive(battlerId))
|
||||
return FALSE;
|
||||
if (!IsBattlerGrounded(battlerId))
|
||||
return FALSE; // Only grounded battlers affected
|
||||
if (!IS_BATTLER_OF_TYPE(battlerId, TYPE_GRASS))
|
||||
return FALSE; // Only grass types affected
|
||||
if (gStatuses3[battlerId] & STATUS3_SEMI_INVULNERABLE)
|
||||
return FALSE; // Rototiller doesn't affected semi-invulnerable battlers
|
||||
if (BlocksPrankster(MOVE_ROTOTILLER, gBattlerAttacker, battlerId, FALSE))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void Cmd_various(void)
|
||||
{
|
||||
struct Pokemon *mon;
|
||||
@ -8790,7 +8806,7 @@ static void Cmd_various(void)
|
||||
gFieldStatuses &= ~STATUS_FIELD_TERRAIN_ANY; // remove the terrain
|
||||
break;
|
||||
case VARIOUS_JUMP_IF_PRANKSTER_BLOCKED:
|
||||
if (BlocksPrankster(gCurrentMove, gBattlerAttacker, gActiveBattler))
|
||||
if (BlocksPrankster(gCurrentMove, gBattlerAttacker, gActiveBattler, TRUE))
|
||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
|
||||
else
|
||||
gBattlescriptCurrInstr += 7;
|
||||
@ -8828,6 +8844,50 @@ static void Cmd_various(void)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VARIOUS_GET_ROTOTILLER_TARGETS:
|
||||
// Gets the battlers to be affected by rototiller. If there are none, print 'But it failed!'
|
||||
{
|
||||
u32 count = 0;
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
gSpecialStatuses[i].rototillerAffected = FALSE;
|
||||
if (IsRototillerAffected(i))
|
||||
{
|
||||
gSpecialStatuses[i].rototillerAffected = TRUE;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (count == 0)
|
||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); // Rototiller fails
|
||||
else
|
||||
gBattlescriptCurrInstr += 7;
|
||||
}
|
||||
return;
|
||||
case VARIOUS_JUMP_IF_NOT_ROTOTILLER_AFFECTED:
|
||||
if (gSpecialStatuses[gActiveBattler].rototillerAffected)
|
||||
{
|
||||
gSpecialStatuses[gActiveBattler].rototillerAffected = FALSE;
|
||||
gBattlescriptCurrInstr += 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); // Unaffected by rototiller - print STRINGID_NOEFFECTONTARGET
|
||||
}
|
||||
return;
|
||||
case VARIOUS_TRY_ACTIVATE_BATTLE_BOND:
|
||||
if (gBattleMons[gBattlerAttacker].species == SPECIES_GRENINJA_BATTLE_BOND
|
||||
&& HasAttackerFaintedTarget()
|
||||
&& CalculateEnemyPartyCount() > 1)
|
||||
{
|
||||
PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[gBattlerAttacker].species);
|
||||
gBattleStruct->changedSpecies[gBattlerPartyIndexes[gBattlerAttacker]] = gBattleMons[gBattlerAttacker].species;
|
||||
gBattleMons[gBattlerAttacker].species = SPECIES_GRENINJA_ASH;
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_BattleBondActivatesOnMoveEndAttacker;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case VARIOUS_CONSUME_BERRY:
|
||||
if (ItemId_GetHoldEffect(gBattleMons[gActiveBattler].item) == HOLD_EFFECT_NONE)
|
||||
{
|
||||
@ -11010,7 +11070,7 @@ static void Cmd_trysetperishsong(void)
|
||||
{
|
||||
if (gStatuses3[i] & STATUS3_PERISH_SONG
|
||||
|| GetBattlerAbility(i) == ABILITY_SOUNDPROOF
|
||||
|| BlocksPrankster(gCurrentMove, gBattlerAttacker, i))
|
||||
|| BlocksPrankster(gCurrentMove, gBattlerAttacker, i, TRUE))
|
||||
{
|
||||
notAffectedCount++;
|
||||
}
|
||||
@ -11547,7 +11607,7 @@ static void Cmd_jumpifattackandspecialattackcannotfall(void) // memento
|
||||
&& gBattleMons[gBattlerTarget].statStages[STAT_SPATK] == MIN_STAT_STAGE
|
||||
&& gBattleCommunication[MISS_TYPE] != B_MSG_PROTECTED)
|
||||
#else
|
||||
if (gBattleCommunication[MISS_TYPE] != B_MSG_PROTECTED
|
||||
if (gBattleCommunication[MISS_TYPE] == B_MSG_PROTECTED
|
||||
|| gStatuses3[gBattlerTarget] & STATUS3_SEMI_INVULNERABLE
|
||||
|| IsBattlerProtected(gBattlerTarget, gCurrentMove)
|
||||
|| DoesSubstituteBlockMove(gBattlerAttacker, gBattlerTarget, gCurrentMove))
|
||||
|
@ -2251,7 +2251,7 @@ u8 DoFieldEndTurnEffects(void)
|
||||
break;
|
||||
case ENDTURN_ELECTRIC_TERRAIN:
|
||||
if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN
|
||||
&& ((!gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.electricTerrainTimer == 0))
|
||||
&& (!(gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.electricTerrainTimer == 0))
|
||||
{
|
||||
gFieldStatuses &= ~(STATUS_FIELD_ELECTRIC_TERRAIN | STATUS_FIELD_TERRAIN_PERMANENT);
|
||||
BattleScriptExecute(BattleScript_ElectricTerrainEnds);
|
||||
@ -2261,7 +2261,7 @@ u8 DoFieldEndTurnEffects(void)
|
||||
break;
|
||||
case ENDTURN_MISTY_TERRAIN:
|
||||
if (gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN
|
||||
&& ((!gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.mistyTerrainTimer == 0))
|
||||
&& (!(gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.mistyTerrainTimer == 0))
|
||||
{
|
||||
gFieldStatuses &= ~(STATUS_FIELD_MISTY_TERRAIN);
|
||||
BattleScriptExecute(BattleScript_MistyTerrainEnds);
|
||||
@ -2283,7 +2283,7 @@ u8 DoFieldEndTurnEffects(void)
|
||||
break;
|
||||
case ENDTURN_PSYCHIC_TERRAIN:
|
||||
if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN
|
||||
&& ((!gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.psychicTerrainTimer == 0))
|
||||
&& (!(gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.psychicTerrainTimer == 0))
|
||||
{
|
||||
gFieldStatuses &= ~(STATUS_FIELD_PSYCHIC_TERRAIN);
|
||||
BattleScriptExecute(BattleScript_PsychicTerrainEnds);
|
||||
@ -3453,7 +3453,7 @@ u8 AtkCanceller_UnableToUseMove(void)
|
||||
gBattleStruct->atkCancellerTracker++;
|
||||
break;
|
||||
case CANCELLER_PRANKSTER:
|
||||
if (BlocksPrankster(gCurrentMove, gBattlerAttacker, gBattlerTarget)
|
||||
if (BlocksPrankster(gCurrentMove, gBattlerAttacker, gBattlerTarget, TRUE)
|
||||
&& !(IS_MOVE_STATUS(gCurrentMove) && GetBattlerAbility(gBattlerTarget) == ABILITY_MAGIC_BOUNCE))
|
||||
{
|
||||
if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE) || !(gBattleMoves[gCurrentMove].target & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY)))
|
||||
@ -5164,18 +5164,6 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
|
||||
effect++;
|
||||
}
|
||||
break;
|
||||
case ABILITY_BATTLE_BOND:
|
||||
if (gBattleMons[gBattlerAttacker].species == SPECIES_GRENINJA_BATTLE_BOND
|
||||
&& gBattleResults.opponentFaintCounter != 0
|
||||
&& CalculateEnemyPartyCount() > 1)
|
||||
{
|
||||
PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[gBattlerAttacker].species);
|
||||
gBattleStruct->changedSpecies[gBattlerPartyIndexes[gBattlerAttacker]] = gBattleMons[gBattlerAttacker].species;
|
||||
gBattleMons[gBattlerAttacker].species = SPECIES_GRENINJA_ASH;
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_BattleBondActivatesOnMoveEndAttacker;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ABILITYEFFECT_MOVE_END_OTHER: // Abilities that activate on *another* battler's moveend: Dancer, Soul-Heart, Receiver, Symbiosis
|
||||
@ -8869,6 +8857,7 @@ void UndoFormChange(u32 monId, u32 side, bool32 isSwitchingOut)
|
||||
static const u16 species[][2] = // changed form id, default form id
|
||||
{
|
||||
{SPECIES_MIMIKYU_BUSTED, SPECIES_MIMIKYU},
|
||||
{SPECIES_GRENINJA_ASH, SPECIES_GRENINJA_BATTLE_BOND},
|
||||
{SPECIES_AEGISLASH_BLADE, SPECIES_AEGISLASH},
|
||||
{SPECIES_DARMANITAN_ZEN_MODE, SPECIES_DARMANITAN},
|
||||
{SPECIES_MINIOR, SPECIES_MINIOR_CORE_RED},
|
||||
@ -8881,11 +8870,10 @@ void UndoFormChange(u32 monId, u32 side, bool32 isSwitchingOut)
|
||||
{SPECIES_WISHIWASHI_SCHOOL, SPECIES_WISHIWASHI},
|
||||
{SPECIES_CRAMORANT_GORGING, SPECIES_CRAMORANT},
|
||||
{SPECIES_CRAMORANT_GULPING, SPECIES_CRAMORANT},
|
||||
{SPECIES_GRENINJA_ASH, SPECIES_GRENINJA_BATTLE_BOND},
|
||||
};
|
||||
|
||||
if (isSwitchingOut) // Don't revert Mimikyu Busted when switching out
|
||||
i = 1;
|
||||
if (isSwitchingOut) // Don't revert Mimikyu Busted or Ash-Greninja when switching out
|
||||
i = 2;
|
||||
else
|
||||
i = 0;
|
||||
|
||||
@ -9467,16 +9455,21 @@ void DoBurmyFormChange(u32 monId)
|
||||
}
|
||||
}
|
||||
|
||||
bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u8 battlerDef)
|
||||
bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u8 battlerDef, bool32 checkTarget)
|
||||
{
|
||||
#if B_PRANKSTER_DARK_TYPES >= GEN_7
|
||||
if (gProtectStructs[battlerPrankster].pranksterElevated
|
||||
&& GetBattlerSide(battlerPrankster) != GetBattlerSide(battlerDef)
|
||||
&& !(gBattleMoves[gCurrentMove].target & (MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_DEPENDS)) // Don't block hazards, assist-type moves
|
||||
&& IS_BATTLER_OF_TYPE(battlerDef, TYPE_DARK) // Only Dark-types can block Prankster'd
|
||||
&& !(gStatuses3[battlerDef] & STATUS3_SEMI_INVULNERABLE))
|
||||
return TRUE;
|
||||
else
|
||||
#endif
|
||||
if (!gProtectStructs[battlerPrankster].pranksterElevated)
|
||||
return FALSE;
|
||||
if (GetBattlerSide(battlerPrankster) == GetBattlerSide(battlerDef))
|
||||
return FALSE;
|
||||
if (checkTarget && (gBattleMoves[move].target & (MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_DEPENDS)))
|
||||
return FALSE;
|
||||
if (!IS_BATTLER_OF_TYPE(battlerDef, TYPE_DARK))
|
||||
return FALSE;
|
||||
if (gStatuses3[battlerDef] & STATUS3_SEMI_INVULNERABLE)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
#endif
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -1789,7 +1789,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
.accuracy = 0,
|
||||
.pp = 30,
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_USER,
|
||||
.target = MOVE_TARGET_ALL_BATTLERS,
|
||||
.priority = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_STATUS,
|
||||
@ -3101,7 +3101,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
.accuracy = 0,
|
||||
.pp = 5,
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_USER,
|
||||
.target = MOVE_TARGET_ALL_BATTLERS,
|
||||
.priority = 0,
|
||||
.flags = FLAG_SOUND,
|
||||
.split = SPLIT_STATUS,
|
||||
@ -3205,7 +3205,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
.accuracy = 0,
|
||||
.pp = 10,
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_USER,
|
||||
.target = MOVE_TARGET_ALL_BATTLERS,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.split = SPLIT_STATUS,
|
||||
@ -3809,7 +3809,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
.accuracy = 0,
|
||||
.pp = 5,
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_USER,
|
||||
.target = MOVE_TARGET_ALL_BATTLERS,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.split = SPLIT_STATUS,
|
||||
@ -3823,7 +3823,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
.accuracy = 0,
|
||||
.pp = 5,
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_USER,
|
||||
.target = MOVE_TARGET_ALL_BATTLERS,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.split = SPLIT_STATUS,
|
||||
@ -4130,7 +4130,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
.accuracy = 0,
|
||||
.pp = 10,
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_USER,
|
||||
.target = MOVE_TARGET_ALL_BATTLERS,
|
||||
.priority = 0,
|
||||
.flags = FLAG_PROTECT_AFFECTED,
|
||||
.split = SPLIT_STATUS,
|
||||
@ -4773,7 +4773,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
.accuracy = 100,
|
||||
.pp = 15,
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_USER,
|
||||
.target = MOVE_TARGET_ALL_BATTLERS,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.split = SPLIT_STATUS,
|
||||
@ -5513,7 +5513,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
.accuracy = 100,
|
||||
.pp = 15,
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_USER,
|
||||
.target = MOVE_TARGET_ALL_BATTLERS,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.split = SPLIT_STATUS,
|
||||
@ -5670,7 +5670,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
.accuracy = 0,
|
||||
.pp = 5,
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_USER,
|
||||
.target = MOVE_TARGET_ALL_BATTLERS,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.split = SPLIT_STATUS,
|
||||
@ -6884,7 +6884,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
.accuracy = 0,
|
||||
.pp = 5,
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_USER,
|
||||
.target = MOVE_TARGET_ALL_BATTLERS,
|
||||
.priority = -7,
|
||||
.flags = FLAG_MIRROR_MOVE_AFFECTED,
|
||||
.split = SPLIT_STATUS,
|
||||
@ -7487,7 +7487,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
.accuracy = 0,
|
||||
.pp = 10,
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_USER,
|
||||
.target = MOVE_TARGET_ALL_BATTLERS,
|
||||
.flags = FLAG_MIRROR_MOVE_AFFECTED,
|
||||
.split = SPLIT_STATUS,
|
||||
},
|
||||
@ -7579,7 +7579,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
.accuracy = 0,
|
||||
.pp = 10,
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_USER,
|
||||
.target = MOVE_TARGET_ALL_BATTLERS,
|
||||
.flags = FLAG_MIRROR_MOVE_AFFECTED,
|
||||
.split = SPLIT_STATUS,
|
||||
},
|
||||
@ -8847,7 +8847,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
.accuracy = 0,
|
||||
.pp = 10,
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_FOES_AND_ALLY | MOVE_TARGET_USER,
|
||||
.target = MOVE_TARGET_ALL_BATTLERS,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.split = SPLIT_STATUS,
|
||||
@ -8941,7 +8941,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
.accuracy = 0,
|
||||
.pp = 25,
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_USER,
|
||||
.target = MOVE_TARGET_ALL_BATTLERS,
|
||||
.priority = 1,
|
||||
.flags = 0,
|
||||
.split = SPLIT_STATUS,
|
||||
@ -9092,7 +9092,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
.accuracy = 0,
|
||||
.pp = 10,
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_USER | MOVE_TARGET_FOES_AND_ALLY,
|
||||
.target = MOVE_TARGET_ALL_BATTLERS,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.split = SPLIT_STATUS,
|
||||
@ -9106,7 +9106,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
.accuracy = 0,
|
||||
.pp = 10,
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_USER,
|
||||
.target = MOVE_TARGET_ALL_BATTLERS,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.split = SPLIT_STATUS,
|
||||
@ -9120,7 +9120,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
.accuracy = 0,
|
||||
.pp = 10,
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_USER,
|
||||
.target = MOVE_TARGET_ALL_BATTLERS,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.split = SPLIT_STATUS,
|
||||
@ -9204,7 +9204,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
.accuracy = 0,
|
||||
.pp = 10,
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_USER,
|
||||
.target = MOVE_TARGET_ALL_BATTLERS,
|
||||
.priority = 0,
|
||||
.flags = FLAG_MIRROR_MOVE_AFFECTED,
|
||||
.split = SPLIT_STATUS,
|
||||
@ -9454,7 +9454,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
.accuracy = 0,
|
||||
.pp = 10,
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_USER,
|
||||
.target = MOVE_TARGET_ALL_BATTLERS,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.split = SPLIT_STATUS,
|
||||
@ -9974,7 +9974,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
.accuracy = 0,
|
||||
.pp = 10,
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_USER,
|
||||
.target = MOVE_TARGET_ALL_BATTLERS,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.split = SPLIT_STATUS,
|
||||
@ -10857,7 +10857,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
.accuracy = 0,
|
||||
.pp = 10,
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_USER,
|
||||
.target = MOVE_TARGET_ALL_BATTLERS,
|
||||
.priority = 0,
|
||||
.flags = 0,
|
||||
.split = SPLIT_STATUS,
|
||||
@ -10913,7 +10913,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
.accuracy = 100,
|
||||
.pp = 10,
|
||||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_USER,
|
||||
.target = MOVE_TARGET_ALL_BATTLERS,
|
||||
.priority = 0,
|
||||
.flags = FLAG_MIRROR_MOVE_AFFECTED,
|
||||
.split = SPLIT_STATUS,
|
||||
|
Loading…
Reference in New Issue
Block a user