diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index 8a8e12e9a..ad323a819 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -1575,6 +1575,11 @@ various \battler, VARIOUS_TRY_THIRD_TYPE .4byte \ptr .endm + + .macro tryaccupressure battler, ptr + various \battler, VARIOUS_ACUPRESSURE + .4byte \ptr + .endm @ helpful macros .macro setstatchanger stat, stages, down diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index a7d105b4e..122b0f26e 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -336,6 +336,23 @@ gBattleScriptsForMoveEffects:: @ 82D86A8 .4byte BattleScript_EffectAuroraVeil .4byte BattleScript_EffectThirdType .4byte BattleScript_EffectFeint + .4byte BattleScript_EffectSparklingAria + .4byte BattleScript_EffectAcupressure + +BattleScript_EffectAcupressure: + attackcanceler + jumpifbyteequal gBattlerTarget, gBattlerAttacker, BattleScript_EffectAcupressureTry + jumpifstatus2 BS_TARGET, STATUS2_SUBSTITUTE, BattleScript_PrintMoveMissed +BattleScript_EffectAcupressureTry: + attackstring + ppreduce + tryaccupressure BS_TARGET, BattleScript_ButItFailed + setgraphicalstatchangevalues + playanimation BS_TARGET, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1 + statbuffchange MOVE_EFFECT_CERTAIN, BattleScript_MoveEnd + printstring STRINGID_PKMNSSTATCHANGED2 + waitmessage 0x40 + goto BattleScript_MoveEnd BattleScript_MoveEffectFeint:: printstring STRINGID_FELLFORFEINT @@ -1583,7 +1600,6 @@ BattleScript_EffectEruption: BattleScript_EffectPledge: BattleScript_EffectFling: BattleScript_EffectNaturalGift: -BattleScript_EffectWakeUpSlap: BattleScript_EffectWringOut: BattleScript_EffectHex: BattleScript_EffectAssurance: @@ -3511,7 +3527,7 @@ BattleScript_AlreadyAtFullHp:: BattleScript_EffectFakeOut:: attackcanceler jumpifnotfirstturn BattleScript_ButItFailedAtkStringPpReduce - setmoveeffect MOVE_EFFECT_FLINCH | MOVE_EFFECT_CERTAIN + setmoveeffect MOVE_EFFECT_FLINCH goto BattleScript_EffectHit BattleScript_ButItFailedAtkStringPpReduce:: @@ -3716,9 +3732,11 @@ BattleScript_EffectFocusPunch:: waitmessage 0x40 goto BattleScript_MoveEnd -BattleScript_EffectSmellingsalt:: +BattleScript_EffectSmellingsalt: +BattleScript_EffectWakeUpSlap: +BattleScript_EffectSparklingAria: jumpifsubstituteblocks BattleScript_EffectHit - setmoveeffect MOVE_EFFECT_REMOVE_PARALYSIS | MOVE_EFFECT_CERTAIN + setmoveeffect MOVE_EFFECT_REMOVE_STATUS | MOVE_EFFECT_CERTAIN goto BattleScript_EffectHit BattleScript_EffectFollowMe:: diff --git a/include/battle.h b/include/battle.h index bbdc3a7a3..cf4daf276 100644 --- a/include/battle.h +++ b/include/battle.h @@ -60,6 +60,7 @@ #define MOVE_TARGET_USER 0x10 #define MOVE_TARGET_FOES_AND_ALLY 0x20 #define MOVE_TARGET_OPPONENTS_FIELD 0x40 +#define MOVE_TARGET_ALLY 0x80 #define BATTLE_BUFFER_LINK_SIZE 0x1000 diff --git a/include/constants/battle.h b/include/constants/battle.h index d61e040fd..99eb49053 100644 --- a/include/constants/battle.h +++ b/include/constants/battle.h @@ -293,7 +293,7 @@ #define MOVE_EFFECT_NIGHTMARE 0x21 #define MOVE_EFFECT_ALL_STATS_UP 0x22 #define MOVE_EFFECT_RAPIDSPIN 0x23 -#define MOVE_EFFECT_REMOVE_PARALYSIS 0x24 +#define MOVE_EFFECT_REMOVE_STATUS 0x24 #define MOVE_EFFECT_ATK_DEF_DOWN 0x25 #define MOVE_EFFECT_RECOIL_33 0x26 #define MOVE_EFFECT_ATK_PLUS_2 0x27 diff --git a/include/constants/battle_move_effects.h b/include/constants/battle_move_effects.h index d3c569a1e..554b8d934 100644 --- a/include/constants/battle_move_effects.h +++ b/include/constants/battle_move_effects.h @@ -324,5 +324,7 @@ #define EFFECT_AURORA_VEIL 318 #define EFFECT_THIRD_TYPE 319 #define EFFECT_FEINT 320 +#define EFFECT_SPARKLING_ARIA 321 +#define EFFECT_ACUPRESSURE 322 #endif // GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index c4ba51f13..9c345f91c 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -132,6 +132,7 @@ #define VARIOUS_TRY_TRAINER_SLIDE_MSG_LAST_ON 70 #define VARIOUS_SET_AURORA_VEIL 71 #define VARIOUS_TRY_THIRD_TYPE 72 +#define VARIOUS_ACUPRESSURE 73 // atk80, dmg manipulation #define ATK80_DMG_CHANGE_SIGN 0 diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c index 9f7acdbf0..fb461fa16 100644 --- a/src/battle_controller_player.c +++ b/src/battle_controller_player.c @@ -359,6 +359,7 @@ static void HandleInputChooseTarget(void) { s32 i; u8 identities[4]; + u16 move = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MOVE1 + gMoveSelectionCursor[gActiveBattler]); memcpy(identities, sTargetIdentities, ARRAY_COUNT(sTargetIdentities)); DoBounceEffect(gMultiUsePlayerCursor, BOUNCE_HEALTHBOX, 15, 1); @@ -406,41 +407,48 @@ static void HandleInputChooseTarget(void) PlaySE(SE_SELECT); gSprites[gBattlerSpriteIds[gMultiUsePlayerCursor]].callback = sub_8039B2C; - do + if (gBattleMoves[move].target == (MOVE_TARGET_USER | MOVE_TARGET_ALLY)) + { + gMultiUsePlayerCursor ^= BIT_FLANK; + } + else { - u8 currSelIdentity = GetBattlerPosition(gMultiUsePlayerCursor); - - for (i = 0; i < MAX_BATTLERS_COUNT; i++) - { - if (currSelIdentity == identities[i]) - break; - } do { - if (--i < 0) - i = 4; // UB: array out of range - gMultiUsePlayerCursor = GetBattlerAtPosition(identities[i]); - } while (gMultiUsePlayerCursor == gBattlersCount); + u8 currSelIdentity = GetBattlerPosition(gMultiUsePlayerCursor); - i = 0; - switch (GetBattlerPosition(gMultiUsePlayerCursor)) - { - case B_POSITION_PLAYER_LEFT: - case B_POSITION_PLAYER_RIGHT: - if (gActiveBattler != gMultiUsePlayerCursor) - i++; - else if (gBattleMoves[GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MOVE1 + gMoveSelectionCursor[gActiveBattler])].target & MOVE_TARGET_USER_OR_SELECTED) - i++; - break; - case B_POSITION_OPPONENT_LEFT: - case B_POSITION_OPPONENT_RIGHT: - i++; - break; - } + for (i = 0; i < MAX_BATTLERS_COUNT; i++) + { + if (currSelIdentity == identities[i]) + break; + } + do + { + if (--i < 0) + i = 3; + gMultiUsePlayerCursor = GetBattlerAtPosition(identities[i]); + } while (gMultiUsePlayerCursor == gBattlersCount); - if (gAbsentBattlerFlags & gBitTable[gMultiUsePlayerCursor]) i = 0; - } while (i == 0); + switch (GetBattlerPosition(gMultiUsePlayerCursor)) + { + case B_POSITION_PLAYER_LEFT: + case B_POSITION_PLAYER_RIGHT: + if (gActiveBattler != gMultiUsePlayerCursor) + i++; + else if (gBattleMoves[move].target & MOVE_TARGET_USER_OR_SELECTED) + i++; + break; + case B_POSITION_OPPONENT_LEFT: + case B_POSITION_OPPONENT_RIGHT: + i++; + break; + } + + if (gAbsentBattlerFlags & gBitTable[gMultiUsePlayerCursor]) + i = 0; + } while (i == 0); + } gSprites[gBattlerSpriteIds[gMultiUsePlayerCursor]].callback = sub_8039AD8; } else if (gMain.newKeys & (DPAD_RIGHT | DPAD_DOWN)) @@ -448,41 +456,49 @@ static void HandleInputChooseTarget(void) PlaySE(SE_SELECT); gSprites[gBattlerSpriteIds[gMultiUsePlayerCursor]].callback = sub_8039B2C; - do + if (gBattleMoves[move].target == (MOVE_TARGET_USER | MOVE_TARGET_ALLY)) + { + gMultiUsePlayerCursor ^= BIT_FLANK; + } + else { - u8 currSelIdentity = GetBattlerPosition(gMultiUsePlayerCursor); - - for (i = 0; i < MAX_BATTLERS_COUNT; i++) - { - if (currSelIdentity == identities[i]) - break; - } do { - if (++i > 3) - i = 0; - gMultiUsePlayerCursor = GetBattlerAtPosition(identities[i]); - } while (gMultiUsePlayerCursor == gBattlersCount); + u8 currSelIdentity = GetBattlerPosition(gMultiUsePlayerCursor); - i = 0; - switch (GetBattlerPosition(gMultiUsePlayerCursor)) - { - case B_POSITION_PLAYER_LEFT: - case B_POSITION_PLAYER_RIGHT: - if (gActiveBattler != gMultiUsePlayerCursor) - i++; - else if (gBattleMoves[GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MOVE1 + gMoveSelectionCursor[gActiveBattler])].target & MOVE_TARGET_USER_OR_SELECTED) - i++; - break; - case B_POSITION_OPPONENT_LEFT: - case B_POSITION_OPPONENT_RIGHT: - i++; - break; - } + for (i = 0; i < MAX_BATTLERS_COUNT; i++) + { + if (currSelIdentity == identities[i]) + break; + } + do + { + if (++i > 3) + i = 0; + gMultiUsePlayerCursor = GetBattlerAtPosition(identities[i]); + } while (gMultiUsePlayerCursor == gBattlersCount); - if (gAbsentBattlerFlags & gBitTable[gMultiUsePlayerCursor]) i = 0; - } while (i == 0); + switch (GetBattlerPosition(gMultiUsePlayerCursor)) + { + case B_POSITION_PLAYER_LEFT: + case B_POSITION_PLAYER_RIGHT: + if (gActiveBattler != gMultiUsePlayerCursor) + i++; + else if (gBattleMoves[move].target & MOVE_TARGET_USER_OR_SELECTED) + i++; + break; + case B_POSITION_OPPONENT_LEFT: + case B_POSITION_OPPONENT_RIGHT: + i++; + break; + } + + if (gAbsentBattlerFlags & gBitTable[gMultiUsePlayerCursor]) + i = 0; + } while (i == 0); + } + gSprites[gBattlerSpriteIds[gMultiUsePlayerCursor]].callback = sub_8039AD8; } } @@ -528,6 +544,8 @@ static void HandleInputChooseMove(void) { if (!(moveTarget & (MOVE_TARGET_RANDOM | MOVE_TARGET_BOTH | MOVE_TARGET_DEPENDS | MOVE_TARGET_FOES_AND_ALLY | MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_USER))) canSelectTarget++; // either selected or user + if (moveTarget == (MOVE_TARGET_USER | MOVE_TARGET_ALLY) && IsBattlerAlive(BATTLE_PARTNER(gActiveBattler))) + canSelectTarget++; if (moveInfo->currentPp[gMoveSelectionCursor[gActiveBattler]] == 0) { diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index d5180cb0b..00c899158 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -722,7 +722,7 @@ static const u8* const sMoveEffectBS_Ptrs[] = BattleScript_MoveEffectSleep, // MOVE_EFFECT_NIGHTMARE BattleScript_MoveEffectSleep, // MOVE_EFFECT_ALL_STATS_UP BattleScript_MoveEffectSleep, // MOVE_EFFECT_RAPIDSPIN - BattleScript_MoveEffectSleep, // MOVE_EFFECT_REMOVE_PARALYSIS + BattleScript_MoveEffectSleep, // MOVE_EFFECT_REMOVE_STATUS BattleScript_MoveEffectSleep, // MOVE_EFFECT_ATK_DEF_DOWN BattleScript_MoveEffectRecoil, // MOVE_EFFECT_RECOIL_33 }; @@ -2602,14 +2602,14 @@ void SetMoveEffect(bool8 primary, u8 certain) BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_RapidSpinAway; break; - case MOVE_EFFECT_REMOVE_PARALYSIS: // Smelling salts - if (!(gBattleMons[gBattlerTarget].status1 & STATUS1_PARALYSIS)) + case MOVE_EFFECT_REMOVE_STATUS: // Smelling salts + if (!(gBattleMons[gBattlerTarget].status1 & gBattleMoves[gCurrentMove].argument)) { gBattlescriptCurrInstr++; } else { - gBattleMons[gBattlerTarget].status1 &= ~(STATUS1_PARALYSIS); + gBattleMons[gBattlerTarget].status1 &= ~(gBattleMoves[gCurrentMove].argument); gActiveBattler = gBattlerTarget; BtlController_EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1); @@ -6311,6 +6311,7 @@ static void atk76_various(void) u8 side; s32 i, j; u8 data[10]; + u32 bits; if (gBattleControllerExecFlags) return; @@ -6319,6 +6320,33 @@ static void atk76_various(void) switch (gBattlescriptCurrInstr[2]) { + case VARIOUS_ACUPRESSURE: + bits = 0; + for (i = STAT_ATK; i < NUM_BATTLE_STATS; i++) + { + if (gBattleMons[gActiveBattler].statStages[i] != 12) + bits |= gBitTable[i]; + } + if (bits) + { + u32 statId; + do + { + statId = (Random() % NUM_BATTLE_STATS) + 1; + } while (!(bits & gBitTable[statId])); + + if (gBattleMons[gActiveBattler].statStages[statId] >= 11) + SET_STATCHANGER(statId, 1, FALSE); + else + SET_STATCHANGER(statId, 2, FALSE); + + gBattlescriptCurrInstr += 7; + } + else + { + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + } + return; case VARIOUS_CANCEL_MULTI_TURN_MOVES: CancelMultiTurnMoves(gActiveBattler); break; diff --git a/src/data/battle_moves.h b/src/data/battle_moves.h index 7038e3072..098f431c8 100644 --- a/src/data/battle_moves.h +++ b/src/data/battle_moves.h @@ -3034,7 +3034,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .type = TYPE_NORMAL, .accuracy = 100, .pp = 10, - .secondaryEffectChance = 0, + .secondaryEffectChance = 100, .target = MOVE_TARGET_SELECTED, .priority = 1, .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST, @@ -3195,6 +3195,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .priority = 0, .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED, .split = SPLIT_PHYSICAL, + .argument = STATUS1_PARALYSIS, }, { // MOVE_FOLLOW_ME .effect = EFFECT_FOLLOW_ME, @@ -4312,6 +4313,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .priority = 0, .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGSROCK_AFFECTED, .split = SPLIT_PHYSICAL, + .argument = STATUS1_SLEEP, }, { // MOVE_HAMMER_ARM .effect = EFFECT_SPEED_DOWN, @@ -4410,13 +4412,13 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .split = SPLIT_STATUS, }, { // MOVE_ACUPRESSURE - .effect = EFFECT_PLACEHOLDER, // Needs a custom move effect + .effect = EFFECT_ACUPRESSURE, .power = 0, .type = TYPE_NORMAL, .accuracy = 0, .pp = 30, .secondaryEffectChance = 0, - .target = MOVE_TARGET_USER, + .target = MOVE_TARGET_USER | MOVE_TARGET_ALLY, .priority = 0, .flags = 0, .split = SPLIT_STATUS, @@ -7493,7 +7495,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .split = SPLIT_STATUS, }, { // MOVE_FIRST_IMPRESSION - .effect = EFFECT_PLACEHOLDER, + .effect = EFFECT_FAKE_OUT, .power = 90, .type = TYPE_BUG, .accuracy = 100, @@ -7541,7 +7543,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .split = SPLIT_PHYSICAL, }, { // MOVE_SPARKLING_ARIA - .effect = EFFECT_PLACEHOLDER, + .effect = EFFECT_SPARKLING_ARIA, .power = 90, .type = TYPE_WATER, .accuracy = 100, @@ -7551,6 +7553,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .priority = 0, .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGSROCK_AFFECTED | FLAG_SOUND, .split = SPLIT_SPECIAL, + .argument = STATUS1_BURN, }, { // MOVE_ICE_HAMMER .effect = EFFECT_SPEED_DOWN_HIT,