From 908b509401e497f1df540c5565c5ab498e2bbef1 Mon Sep 17 00:00:00 2001 From: ghoulslash <41651341+ghoulslash@users.noreply.github.com> Date: Tue, 14 Feb 2023 10:49:50 -0500 Subject: [PATCH] Fix Round's Base Power calc, Add Turn order effects (#2602) * fix round base power calc, add turn order change * remove unused callnative cmd * fix round turn order update * fix moveTarget getting set incorrectly in HandleAction_UseMove. also redirection doesn't affect MOVE_TARGET_ALL_BATTLERS --------- Co-authored-by: ghoulslash --- data/battle_scripts_1.s | 6 +++- include/constants/battle.h | 3 +- src/battle_script_commands.c | 55 +++++++++++++++++++++++++++++++++++- src/battle_util.c | 24 ++++++++++++---- src/data/battle_moves.h | 2 +- 5 files changed, 81 insertions(+), 9 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 25386dbf0..c404dc37d 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -250,7 +250,7 @@ gBattleScriptsForMoveEffects:: .4byte BattleScript_EffectHit @ EFFECT_GYRO_BALL .4byte BattleScript_EffectHit @ EFFECT_ECHOED_VOICE .4byte BattleScript_EffectHit @ EFFECT_PAYBACK - .4byte BattleScript_EffectHit @ EFFECT_ROUND + .4byte BattleScript_EffectRound @ EFFECT_ROUND .4byte BattleScript_EffectHit @ EFFECT_BRINE .4byte BattleScript_EffectHit @ EFFECT_VENOSHOCK .4byte BattleScript_EffectHit @ EFFECT_RETALIATE @@ -3082,6 +3082,10 @@ BattleScript_EffectPlaceholder: printstring STRINGID_NOTDONEYET goto BattleScript_MoveEnd +BattleScript_EffectRound: + setmoveeffect MOVE_EFFECT_ROUND + goto BattleScript_EffectHit + BattleScript_EffectHit:: BattleScript_HitFromAtkCanceler:: attackcanceler diff --git a/include/constants/battle.h b/include/constants/battle.h index be44c21cb..c24178cd0 100644 --- a/include/constants/battle.h +++ b/include/constants/battle.h @@ -371,8 +371,9 @@ #define MOVE_EFFECT_RELIC_SONG 69 #define MOVE_EFFECT_TRAP_BOTH 70 #define MOVE_EFFECT_DOUBLE_SHOCK 71 +#define MOVE_EFFECT_ROUND 72 -#define NUM_MOVE_EFFECTS 72 +#define NUM_MOVE_EFFECTS 73 #define MOVE_EFFECT_AFFECTS_USER 0x4000 #define MOVE_EFFECT_CERTAIN 0x8000 diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 38fb1e069..d1c0a7c77 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -318,6 +318,7 @@ static void SpriteCB_MonIconOnLvlUpBanner(struct Sprite *sprite); static bool32 CriticalCapture(u32 odds); static void BestowItem(u32 battlerAtk, u32 battlerDef); static bool8 IsFinalStrikeEffect(u16 move); +static void TryUpdateRoundTurnOrder(void); static void Cmd_attackcanceler(void); static void Cmd_accuracycheck(void); @@ -3660,6 +3661,10 @@ void SetMoveEffect(bool32 primary, u32 certain) BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_DoubleShockRemoveType; break; + case MOVE_EFFECT_ROUND: + TryUpdateRoundTurnOrder(); // If another Pokémon uses Round before the user this turn, the user will use Round directly after it + gBattlescriptCurrInstr++; + break; } } } @@ -14960,7 +14965,7 @@ static void Cmd_callnative(void) func(); } -// Callnative Funcs +// Callnative Funcs void BS_CalcMetalBurstDmg(void) { u8 sideAttacker = GetBattlerSide(gBattlerAttacker); @@ -15089,3 +15094,51 @@ static bool8 IsFinalStrikeEffect(u16 move) } return FALSE; } + +static void TryUpdateRoundTurnOrder(void) +{ + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + { + u32 i; + u32 j = 0; + u32 k = 0; + u32 currRounder; + u8 roundUsers[3] = {0xFF, 0xFF, 0xFF}; + u8 nonRoundUsers[3] = {0xFF, 0xFF, 0xFF}; + for (i = 0; i < gBattlersCount; i++) + { + if (gBattlerByTurnOrder[i] == gBattlerAttacker) + { + currRounder = i + 1; // Current battler going after attacker + break; + } + } + + // Get battlers after us using round + for (i = currRounder; i < gBattlersCount; i++) + { + if (gChosenMoveByBattler[gBattlerByTurnOrder[i]] == MOVE_ROUND) + roundUsers[j++] = gBattlerByTurnOrder[i]; + else + nonRoundUsers[k++] = gBattlerByTurnOrder[i]; + } + + // update turn order for round users + for (i = 0; roundUsers[i] != 0xFF && i < 3; i++) + { + gBattlerByTurnOrder[currRounder] = roundUsers[i]; + gActionsByTurnOrder[currRounder] = gActionsByTurnOrder[roundUsers[i]]; + gProtectStructs[roundUsers[i]].quash = TRUE; // Make it so their turn order can't be changed again + currRounder++; + } + + // Update turn order for non-round users + for (i = 0; nonRoundUsers[i] != 0xFF && i < 3; i++) + { + gBattlerByTurnOrder[currRounder] = nonRoundUsers[i]; + gActionsByTurnOrder[currRounder] = gActionsByTurnOrder[nonRoundUsers[i]]; + currRounder++; + } + } +} + diff --git a/src/battle_util.c b/src/battle_util.c index c51585185..4503c9208 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -259,7 +259,7 @@ bool32 IsAffectedByFollowMe(u32 battlerAtk, u32 defSide, u32 move) void HandleAction_UseMove(void) { u32 i, side, moveType, var = 4; - u16 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove); + u16 moveTarget; gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber]; if (gBattleStruct->absentBattlerFlags & gBitTable[gBattlerAttacker] || !IsBattlerAlive(gBattlerAttacker)) @@ -323,6 +323,8 @@ void HandleAction_UseMove(void) { gCurrentMove = gBattleStruct->zmove.toBeUsed[gBattlerAttacker]; } + + moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove); if (gBattleMons[gBattlerAttacker].hp != 0) { @@ -346,7 +348,7 @@ void HandleAction_UseMove(void) } else if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && gSideTimers[side].followmeTimer == 0 - && (gBattleMoves[gCurrentMove].power != 0 || moveTarget != MOVE_TARGET_USER) + && (gBattleMoves[gCurrentMove].power != 0 || (moveTarget != MOVE_TARGET_USER && moveTarget != MOVE_TARGET_ALL_BATTLERS)) && ((GetBattlerAbility(*(gBattleStruct->moveTarget + gBattlerAttacker)) != ABILITY_LIGHTNING_ROD && moveType == TYPE_ELECTRIC) || (GetBattlerAbility(*(gBattleStruct->moveTarget + gBattlerAttacker)) != ABILITY_STORM_DRAIN && moveType == TYPE_WATER))) { @@ -944,6 +946,10 @@ void HandleAction_ActionFinished(void) { u8 battler1 = gBattlerByTurnOrder[i]; u8 battler2 = gBattlerByTurnOrder[j]; + + if (gProtectStructs[battler1].quash || gProtectStructs[battler2].quash) + continue; + // We recalculate order only for action of the same priority. If any action other than switch/move has been taken, they should // have been executed before. The only recalculation needed is for moves/switch. Mega evolution is handled in src/battle_main.c/TryChangeOrder if((gActionsByTurnOrder[i] == B_ACTION_USE_MOVE && gActionsByTurnOrder[j] == B_ACTION_USE_MOVE)) @@ -2141,7 +2147,9 @@ u8 DoFieldEndTurnEffects(void) s32 j; for (j = i + 1; j < gBattlersCount; j++) { - if (GetWhoStrikesFirst(gBattlerByTurnOrder[i], gBattlerByTurnOrder[j], FALSE)) + if (!gProtectStructs[i].quash + && !gProtectStructs[j].quash + && GetWhoStrikesFirst(gBattlerByTurnOrder[i], gBattlerByTurnOrder[j], FALSE)) SwapTurnOrder(i, j); } } @@ -8689,8 +8697,14 @@ static u16 CalcMoveBasePower(u16 move, u8 battlerAtk, u8 battlerDef) basePower *= 2; break; case EFFECT_ROUND: - if (gChosenMoveByBattler[BATTLE_PARTNER(battlerAtk)] == MOVE_ROUND && !(gAbsentBattlerFlags & gBitTable[BATTLE_PARTNER(battlerAtk)])) - basePower *= 2; + for (i = 0; i < gBattlersCount; i++) + { + if (i != battlerAtk && IsBattlerAlive(i) && gLastMoves[i] == MOVE_ROUND) + { + basePower *= 2; + break; + } + } break; case EFFECT_FUSION_COMBO: if (gBattleMoves[gLastUsedMove].effect == EFFECT_FUSION_COMBO && move != gLastUsedMove) diff --git a/src/data/battle_moves.h b/src/data/battle_moves.h index c34ad89d0..267381563 100644 --- a/src/data/battle_moves.h +++ b/src/data/battle_moves.h @@ -8914,7 +8914,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .type = TYPE_NORMAL, .accuracy = 100, .pp = 15, - .secondaryEffectChance = 0, + .secondaryEffectChance = 100, .target = MOVE_TARGET_SELECTED, .priority = 0, .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SOUND,