Updated switch mechanics

This commit is contained in:
DizzyEggg 2019-08-22 15:57:33 +02:00
parent f05375112b
commit 143cb7ad35
5 changed files with 480 additions and 437 deletions

View File

@ -6,6 +6,7 @@
s32 CalcCritChanceStage(u8 battlerAtk, u8 battlerDef, u32 move, bool32 recordAbility);
u8 GetBattlerTurnOrderNum(u8 battlerId);
bool32 NoAliveMonsForEitherParty(void);
void SetMoveEffect(bool32 primary, u32 certain);
void BattleDestroyYesNoCursorAt(u8 cursorPosition);
void BattleCreateYesNoCursorAt(u8 cursorPosition);

View File

@ -7,6 +7,7 @@ extern const u8 BattleScript_MakeMoveMissed[];
extern const u8 BattleScript_PrintMoveMissed[];
extern const u8 BattleScript_MoveMissedPause[];
extern const u8 BattleScript_MoveMissed[];
extern const u8 BattleScript_ButItFailedAtkStringPpReduce[];
extern const u8 BattleScript_ButItFailed[];
extern const u8 BattleScript_StatUp[];
extern const u8 BattleScript_StatDown[];

View File

@ -5220,7 +5220,7 @@ static void HandleAction_UseMove(void)
{
if (gBattlerTarget == gBattlerAttacker)
continue;
if (!(gAbsentBattlerFlags & gBitTable[gBattlerTarget]))
if (IsBattlerAlive(gBattlerTarget))
break;
}
}
@ -5229,7 +5229,7 @@ static void HandleAction_UseMove(void)
gBattlerTarget = *(gBattleStruct->moveTarget + gBattlerAttacker);
}
if (gAbsentBattlerFlags & gBitTable[gBattlerTarget])
if (!IsBattlerAlive(gBattlerTarget))
{
if (GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget))
{
@ -5238,7 +5238,7 @@ static void HandleAction_UseMove(void)
else
{
gBattlerTarget = GetBattlerAtPosition(GetBattlerPosition(gBattlerAttacker) ^ BIT_SIDE);
if (gAbsentBattlerFlags & gBitTable[gBattlerTarget])
if (!IsBattlerAlive(gBattlerTarget))
gBattlerTarget = GetBattlerAtPosition(GetBattlerPosition(gBattlerTarget) ^ BIT_FLANK);
}
}
@ -5292,14 +5292,14 @@ static void HandleAction_UseMove(void)
{
if (gBattlerTarget == gBattlerAttacker)
continue;
if (!(gAbsentBattlerFlags & gBitTable[gBattlerTarget]))
if (IsBattlerAlive(gBattlerTarget))
break;
}
}
else
{
gBattlerTarget = *(gBattleStruct->moveTarget + gBattlerAttacker);
if (gAbsentBattlerFlags & gBitTable[gBattlerTarget])
if (!IsBattlerAlive(gBattlerTarget))
{
if (GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget))
{
@ -5308,7 +5308,7 @@ static void HandleAction_UseMove(void)
else
{
gBattlerTarget = GetBattlerAtPosition(GetBattlerPosition(gBattlerAttacker) ^ BIT_SIDE);
if (gAbsentBattlerFlags & gBitTable[gBattlerTarget])
if (!IsBattlerAlive(gBattlerTarget))
gBattlerTarget = GetBattlerAtPosition(GetBattlerPosition(gBattlerTarget) ^ BIT_FLANK);
}
}

View File

@ -943,10 +943,35 @@ bool32 IsBattlerProtected(u8 battlerId, u16 move)
return FALSE;
}
static bool32 NoTargetPresent(u32 move)
{
if (!IsBattlerAlive(gBattlerTarget))
gBattlerTarget = GetMoveTarget(move, 0);
switch (gBattleMoves[move].target)
{
case MOVE_TARGET_SELECTED:
case MOVE_TARGET_DEPENDS:
case MOVE_TARGET_RANDOM:
if (!IsBattlerAlive(gBattlerTarget))
return TRUE;
break;
case MOVE_TARGET_BOTH:
if (!IsBattlerAlive(gBattlerTarget) && !IsBattlerAlive(BATTLE_PARTNER(gBattlerTarget)))
return TRUE;
break;
case MOVE_TARGET_FOES_AND_ALLY:
if (!IsBattlerAlive(gBattlerTarget) && !IsBattlerAlive(BATTLE_PARTNER(gBattlerTarget)) && !IsBattlerAlive(BATTLE_PARTNER(gBattlerAttacker)))
return TRUE;
break;
}
return FALSE;
}
static void atk00_attackcanceler(void)
{
s32 i;
u32 moveType;
s32 i, moveType;
if (gBattleOutcome != 0)
{
@ -990,11 +1015,9 @@ static void atk00_attackcanceler(void)
}
gHitMarker &= ~(HITMARKER_x800000);
if (!(gHitMarker & HITMARKER_OBEYS) && !(gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS))
{
i = IsMonDisobedient(); // why use the 'i' variable...?
switch (i)
switch (IsMonDisobedient())
{
case 0:
break;
@ -1009,6 +1032,12 @@ static void atk00_attackcanceler(void)
gHitMarker |= HITMARKER_OBEYS;
if (NoTargetPresent(gCurrentMove))
{
gBattlescriptCurrInstr = BattleScript_ButItFailedAtkStringPpReduce;
return;
}
if (gProtectStructs[gBattlerTarget].bounceMove
&& gBattleMoves[gCurrentMove].flags & FLAG_MAGICCOAT_AFFECTED
&& !gProtectStructs[gBattlerAttacker].usesBouncedMove)
@ -3553,7 +3582,7 @@ static void atk23_getexp(void)
}
}
static bool32 IsBattleLostForPlayer(void)
static bool32 NoAliveMonsForPlayer(void)
{
u32 i;
u32 HP_count = 0;
@ -3581,7 +3610,7 @@ static bool32 IsBattleLostForPlayer(void)
return (HP_count == 0);
}
static bool32 IsBattleWonForPlayer(void)
static bool32 NoAliveMonsForOpponent(void)
{
u32 i;
u32 HP_count = 0;
@ -3598,14 +3627,19 @@ static bool32 IsBattleWonForPlayer(void)
return (HP_count == 0);
}
bool32 NoAliveMonsForEitherParty(void)
{
return (NoAliveMonsForPlayer() || NoAliveMonsForOpponent());
}
static void atk24(void)
{
if (gBattleControllerExecFlags)
return;
if (IsBattleLostForPlayer())
if (NoAliveMonsForPlayer())
gBattleOutcome |= B_OUTCOME_LOST;
if (IsBattleWonForPlayer())
if (NoAliveMonsForOpponent())
gBattleOutcome |= B_OUTCOME_WON;
if (gBattleOutcome == 0 && (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000)))
@ -6910,8 +6944,7 @@ static void atk76_various(void)
case VARIOUS_TRY_ACTIVATE_MOXIE:
if (GetBattlerAbility(gActiveBattler) == ABILITY_MOXIE
&& HasAttackerFaintedTarget()
&& !IsBattleLostForPlayer()
&& !IsBattleWonForPlayer()
&& !NoAliveMonsForEitherParty()
&& gBattleMons[gBattlerAttacker].statStages[STAT_ATK] != 12)
{
gBattleMons[gBattlerAttacker].statStages[STAT_ATK]++;
@ -6925,8 +6958,7 @@ static void atk76_various(void)
case VARIOUS_TRY_ACTIVATE_FELL_STINGER:
if (gBattleMoves[gCurrentMove].effect == EFFECT_FELL_STINGER
&& HasAttackerFaintedTarget()
&& !IsBattleLostForPlayer()
&& !IsBattleWonForPlayer()
&& !NoAliveMonsForEitherParty()
&& gBattleMons[gBattlerAttacker].statStages[STAT_ATK] != 12)
{
if (gBattleMons[gBattlerAttacker].statStages[STAT_ATK] >= 11)
@ -7112,7 +7144,7 @@ static void atk76_various(void)
}
return;
case VARIOUS_JUMP_IF_BATTLE_END:
if (IsBattleLostForPlayer() || IsBattleWonForPlayer())
if (NoAliveMonsForEitherParty())
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
else
gBattlescriptCurrInstr += 7;
@ -7739,7 +7771,7 @@ static void atk7A_jumpifnexttargetvalid(void)
{
if (gBattlerTarget == gBattlerAttacker && !(gBattleMoves[gCurrentMove].target & MOVE_TARGET_USER))
continue;
if (!(gAbsentBattlerFlags & gBitTable[gBattlerTarget]))
if (IsBattlerAlive(gBattlerTarget))
break;
}
@ -8791,7 +8823,11 @@ static void atk95_setsandstorm(void)
static void atk96_weatherdamage(void)
{
if (WEATHER_HAS_EFFECT)
if (!IsBattlerAlive(gBattlerAttacker) || !WEATHER_HAS_EFFECT)
{
gBattleMoveDamage = 0;
}
else
{
u32 ability = GetBattlerAbility(gBattlerAttacker);
if (gBattleWeather & WEATHER_SANDSTORM_ANY)
@ -8847,13 +8883,6 @@ static void atk96_weatherdamage(void)
}
}
}
else
{
gBattleMoveDamage = 0;
}
if (gAbsentBattlerFlags & gBitTable[gBattlerAttacker])
gBattleMoveDamage = 0;
gBattlescriptCurrInstr++;
}
@ -10089,7 +10118,7 @@ static void atkC2_selectfirstvalidtarget(void)
{
if (gBattlerTarget == gBattlerAttacker && !(gBattleMoves[gCurrentMove].target & MOVE_TARGET_USER))
continue;
if (!(gAbsentBattlerFlags & gBitTable[gBattlerTarget]))
if (IsBattlerAlive(gBattlerTarget))
break;
}
gBattlescriptCurrInstr++;

View File

@ -1372,7 +1372,7 @@ enum
u8 DoBattlerEndTurnEffects(void)
{
u8 effect = FALSE;
u32 ability, effect = 0;
gHitMarker |= (HITMARKER_GRUDGE | HITMARKER_x20);
while (gBattleStruct->turnEffectsBattlerId < gBattlersCount && gBattleStruct->turnEffectsTracker <= ENDTURN_BATTLER_COUNT)
@ -1381,10 +1381,10 @@ u8 DoBattlerEndTurnEffects(void)
if (gAbsentBattlerFlags & gBitTable[gActiveBattler])
{
gBattleStruct->turnEffectsBattlerId++;
continue;
}
else
{
u8 ability = GetBattlerAbility(gActiveBattler);
ability = GetBattlerAbility(gActiveBattler);
switch (gBattleStruct->turnEffectsTracker)
{
case ENDTURN_INGRAIN: // ingrain
@ -1825,9 +1825,10 @@ u8 DoBattlerEndTurnEffects(void)
gBattleStruct->turnEffectsBattlerId++;
break;
}
if (effect != 0)
return effect;
}
}
gHitMarker &= ~(HITMARKER_GRUDGE | HITMARKER_x20);
return 0;
@ -1978,6 +1979,15 @@ bool8 HandleFaintedMonActions(void)
gBattleStruct->faintedActionsState = 3;
else
gBattleStruct->faintedActionsState = 1;
// Don't switch mons until all pokemon performed their actions or the battle's over.
if (gBattleOutcome == 0
&& !NoAliveMonsForEitherParty()
&& gCurrentTurnActionNumber != gBattlersCount)
{
gAbsentBattlerFlags |= gBitTable[gBattlerFainted];
return FALSE;
}
break;
case 3:
gBattleStruct->faintedActionsBattlerId = 0;
@ -4591,14 +4601,16 @@ u8 GetMoveTarget(u16 move, u8 setTarget)
case MOVE_TARGET_SELECTED:
side = GetBattlerSide(gBattlerAttacker) ^ BIT_SIDE;
if (gSideTimers[side].followmeTimer && gBattleMons[gSideTimers[side].followmeTarget].hp)
{
targetBattler = gSideTimers[side].followmeTarget;
}
else
{
side = GetBattlerSide(gBattlerAttacker);
do
{
targetBattler = Random() % gBattlersCount;
} while (targetBattler == gBattlerAttacker || side == GetBattlerSide(targetBattler) || gAbsentBattlerFlags & gBitTable[targetBattler]);
} while (targetBattler == gBattlerAttacker || side == GetBattlerSide(targetBattler) || !IsBattlerAlive(targetBattler));
if (gBattleMoves[move].type == TYPE_ELECTRIC
&& IsAbilityOnOpposingSide(gBattlerAttacker, ABILITY_LIGHTNING_ROD)
&& gBattleMons[targetBattler].ability != ABILITY_LIGHTNING_ROD)
@ -4622,7 +4634,7 @@ u8 GetMoveTarget(u16 move, u8 setTarget)
case MOVE_TARGET_FOES_AND_ALLY:
case MOVE_TARGET_OPPONENTS_FIELD:
targetBattler = GetBattlerAtPosition((GetBattlerPosition(gBattlerAttacker) & BIT_SIDE) ^ BIT_SIDE);
if (gAbsentBattlerFlags & gBitTable[targetBattler])
if (!IsBattlerAlive(targetBattler))
targetBattler ^= BIT_FLANK;
break;
case MOVE_TARGET_RANDOM:
@ -4645,7 +4657,7 @@ u8 GetMoveTarget(u16 move, u8 setTarget)
else
targetBattler = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT);
}
if (gAbsentBattlerFlags & gBitTable[targetBattler])
if (!IsBattlerAlive(targetBattler))
targetBattler ^= BIT_FLANK;
}
else