From ad481c8688e440d88ae7acb859e988f56d58136f Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Sun, 19 Apr 2020 15:44:44 +0200 Subject: [PATCH] Moody --- data/battle_scripts_1.s | 27 ++++++++++++++- include/battle.h | 3 +- include/battle_scripts.h | 1 + include/constants/battle_config.h | 2 ++ include/constants/battle_script_commands.h | 2 +- src/battle_util.c | 39 ++++++++++++++++++++++ 6 files changed, 71 insertions(+), 3 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 4623efd9cd..a3cf4b5481 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -6394,6 +6394,31 @@ BattleScript_SpeedBoostActivates:: printstring STRINGID_PKMNRAISEDSPEED waitmessage 0x40 end3 + +@ Can't compare directly to a value, have to compare to value at pointer +sZero: +.byte 0 + +BattleScript_MoodyActivates:: + call BattleScript_AbilityPopUp + jumpifbyteequal sSTATCHANGER, sZero, BattleScript_MoodyLower + statbuffchange MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN | STAT_BUFF_NOT_PROTECT_AFFECTED, BattleScript_MoodyLower + jumpifbyte CMP_GREATER_THAN, cMULTISTRING_CHOOSER, 0x1, BattleScript_MoodyLower + setgraphicalstatchangevalues + playanimation BS_ATTACKER, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1 + printfromtable gStatUpStringIds + waitmessage 0x40 +BattleScript_MoodyLower: + jumpifbyteequal sSAVED_STAT_CHANGER, sZero, BattleScript_MoodyEnd + copybyte sSTATCHANGER, sSAVED_STAT_CHANGER + statbuffchange MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN | STAT_BUFF_NOT_PROTECT_AFFECTED, BattleScript_MoodyEnd + jumpifbyte CMP_GREATER_THAN, cMULTISTRING_CHOOSER, 0x1, BattleScript_MoodyEnd + setgraphicalstatchangevalues + playanimation BS_ATTACKER, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1 + printfromtable gStatDownStringIds + waitmessage 0x40 +BattleScript_MoodyEnd: + end3 BattleScript_TraceActivates:: pause 0x20 @@ -6859,9 +6884,9 @@ BattleScript_WeakArmorActivatesEnd: return BattleScript_AttackerAbilityStatRaise:: - setgraphicalstatchangevalues copybyte gBattlerAbility, gBattlerAttacker call BattleScript_AbilityPopUp + setgraphicalstatchangevalues playanimation BS_ATTACKER, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1 waitanimation printstring STRINGID_ATTACKERABILITYSTATRAISE diff --git a/include/battle.h b/include/battle.h index 6180829a99..8f75c124d4 100644 --- a/include/battle.h +++ b/include/battle.h @@ -578,6 +578,7 @@ struct BattleStruct #define SET_STAT_BUFF_VALUE(n)((((n) << 3) & 0xF8)) #define SET_STATCHANGER(statId, stage, goesDown)(gBattleScripting.statChanger = (statId) + ((stage) << 3) + (goesDown << 7)) +#define SET_STATCHANGER2(dst, statId, stage, goesDown)(dst = (statId) + ((stage) << 3) + (goesDown << 7)) struct BattleScripting { @@ -590,7 +591,7 @@ struct BattleScripting u8 animArg2; u16 tripleKickPower; u8 moveendState; - u8 unused_15; + u8 savedStatChanger; // For further use, if attempting to change stat two times(ex. Moody) u8 unused_16; u8 battler; u8 animTurn; diff --git a/include/battle_scripts.h b/include/battle_scripts.h index 7c3b2ef534..493dc1cda2 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -339,5 +339,6 @@ extern const u8 BattleScript_ReceiverActivates[]; extern const u8 BattleScript_FriskActivates[]; extern const u8 BattleScript_FriskMsg[]; extern const u8 BattleScript_FriskMsgWithPopup[]; +extern const u8 BattleScript_MoodyActivates[]; #endif // GUARD_BATTLE_SCRIPTS_H diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index 0baf5d4fc0..b93838b571 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -46,6 +46,7 @@ #define GEN_5 2 #define GEN_6 3 #define GEN_7 4 +#define GEN_8 5 // Calculation settings #define B_CRIT_CHANCE GEN_6 // Chances of a critical hit landing. See atk04_critcalc. @@ -59,6 +60,7 @@ #define B_FELL_STINGER_STAT_RAISE GEN_6 // Gen6 Atk+2, Gen7 Atk+3. #define B_SOUND_SUBSTITUTE GEN_6 // Starting from Gen6 sound moves bypass Substitute. #define B_TOXIC_NEVER_MISS GEN_6 // Starting from Gen6, if Toxic is used by a Poison type, it will never miss. +#define B_MOODY_ACC_EVASION GEN_6 // In Gen8, Moody CANNOT raise Accuray and Evasion any more // Ability settings #define B_ABILITY_POP_UP GEN_6 // Starting from gen5, the pokemon abilities are displayed in a pop-up, when they activate in battle. diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index fa48d0cfc7..bc88e04ad9 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -11,7 +11,7 @@ #define sB_ANIM_ARG2 gBattleScripting + 0x11 #define sTRIPLE_KICK_POWER gBattleScripting + 0x12 #define sMOVEEND_STATE gBattleScripting + 0x14 -#define sUNUSED_15 gBattleScripting + 0x15 +#define sSAVED_STAT_CHANGER gBattleScripting + 0x15 #define sUNUSED_16 gBattleScripting + 0x16 #define sBATTLER gBattleScripting + 0x17 #define sB_ANIM_TURN gBattleScripting + 0x18 diff --git a/src/battle_util.c b/src/battle_util.c index 249cc1019d..5276dd584d 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -3131,6 +3131,45 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA effect++; } break; + case ABILITY_MOODY: + if (gDisableStructs[battler].isFirstTurn != 2) + { + u32 validToRaise = 0, validToLower; + u32 statsNum = (B_MOODY_ACC_EVASION != GEN_8) ? NUM_BATTLE_STATS : NUM_STATS; + + for (i = STAT_ATK; i < statsNum; i++) + { + if (gBattleMons[battler].statStages[i] != 0) + validToLower |= gBitTable[i]; + if (gBattleMons[battler].statStages[i] != 12) + validToRaise |= gBitTable[i]; + } + + if (validToLower != 0 || validToRaise != 0) // Can lower one stat, or can raise one stat + { + gBattleScripting.statChanger = gBattleScripting.savedStatChanger = 0; // for raising and lowering stat respectively + if (validToRaise != 0) // Find stat to raise + { + do + { + i = (Random() % statsNum) + STAT_ATK; + } while (!(validToRaise & gBitTable[i])); + SET_STATCHANGER(i, (gBattleMons[battler].statStages[i] < 11) ? 2 : 1, FALSE); + validToLower &= ~(gBitTable[i]); // Can't lower the same stat as raising. + } + if (validToLower != 0) // Find stat to lower + { + do + { + i = (Random() % statsNum) + STAT_ATK; + } while (!(validToLower & gBitTable[i])); + SET_STATCHANGER2(gBattleScripting.savedStatChanger, i, 1, TRUE); + } + BattleScriptPushCursorAndCallback(BattleScript_MoodyActivates); + effect++; + } + } + break; case ABILITY_TRUANT: gDisableStructs[gBattlerAttacker].truantCounter ^= 1; break;