diff --git a/asm/macros/event.inc b/asm/macros/event.inc index 62f59ecd97..7b5163bd82 100644 --- a/asm/macros/event.inc +++ b/asm/macros/event.inc @@ -1785,6 +1785,10 @@ dofieldeffect FLDEFF_SPARKLE .endm + @ Set up a totem boost for the next battle. + @ 'battler' is the position of the mon you want to gain a boost. see B_POSITION_xx in include/constants/battle.h. + @ The rest of the arguments are the stat change values to each stat. + @ For example, giving the first opponent +1 to atk and -2 to speed would be: settotemboost B_POSITION_OPPONENT_LEFT, 1, 0, -2 .macro settotemboost battler:req, atk=0,def=0,speed=0,spatk=0,spdef=0,acc=0,evas=0 setvar VAR_0x8000, \battler setvar VAR_0x8001, \atk diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index b9ce864818..d51c66e95d 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -815,6 +815,7 @@ gBattleAnims_General:: .4byte General_IllusionOff .4byte General_FormChange .4byte General_SlideOffScreen + .4byte General_RestoreBg .4byte General_TotemFlare .align 2 @@ -8454,6 +8455,8 @@ Move_GRASSY_TERRAIN:: delay 4 createvisualtask AnimTask_BlendBattleAnimPal, 10, ANIM_PAL_BG, 3, 4, 0, RGB(31, 24, 31) waitforvisualfinish + restorebg + waitbgfadein end Move_MISTY_TERRAIN:: @@ -8492,6 +8495,8 @@ Move_MISTY_TERRAIN:: delay 4 createvisualtask AnimTask_BlendBattleAnimPal, 10, ANIM_PAL_BG, 3, 7, 0, RGB(31, 24, 31) waitforvisualfinish + restorebg + waitbgfadein end Move_ELECTRIFY:: @@ -9375,6 +9380,8 @@ Move_ELECTRIC_TERRAIN:: delay 2 createvisualtask AnimTask_BlendBattleAnimPal, 10, ANIM_PAL_BG, 3, 4, 0, RGB(28, 28, 0) waitforvisualfinish + restorebg + waitbgfadein end Move_DAZZLING_GLEAM:: @@ -9452,6 +9459,7 @@ Move_BABY_DOLL_EYES:: loadspritegfx ANIM_TAG_PINK_CLOUD loadspritegfx ANIM_TAG_OPENING_EYE @eye setalpha 8, 8 + monbg ANIM_DEF_PARTNER launchtask AnimTask_BlendBattleAnimPal 0xa 0x5 ANIM_PAL_BG 0x0 0x0 0xA 0x7FFF waitforvisualfinish launchtemplate gOpeningEyeSpriteTemplate 0x5 0x4 0x0 0x0 0x1 0x0 @@ -9464,6 +9472,7 @@ Move_BABY_DOLL_EYES:: launchtask AnimTask_ShakeMon2 0x2 0x5 0x3 0x1 0x0 0x9 0x1 launchtask AnimTask_BlendBattleAnimPal 0xa 0x5 ANIM_PAL_BG 0x0 0xA 0x0 0x7FFF waitforvisualfinish + clearmonbg ANIM_DEF_PARTNER blendoff end @@ -11028,6 +11037,8 @@ Move_PSYCHIC_TERRAIN:: delay 4 createvisualtask AnimTask_BlendBattleAnimPal, 10, ANIM_PAL_BG, 3, 4, 0, RGB(27, 0, 13) waitforvisualfinish + restorebg + waitbgfadein end Move_LUNGE:: @@ -24321,6 +24332,11 @@ General_TerrainElectric: General_TerrainPsychic: end +General_RestoreBg: + restorebg + waitbgfadein + end + General_TotemFlare:: loadspritegfx ANIM_TAG_FOCUS_ENERGY loadspritegfx ANIM_TAG_WHIP_HIT @green color diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index b3b5f7029f..76bcc5d270 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -5424,21 +5424,25 @@ BattleScript_MagicRoomEnds:: BattleScript_ElectricTerrainEnds:: printstring STRINGID_ELECTRICTERRAINENDS waitmessage 0x40 + playanimation BS_ATTACKER, B_ANIM_RESTORE_BG, NULL end2 BattleScript_MistyTerrainEnds:: printstring STRINGID_MISTYTERRAINENDS waitmessage 0x40 + playanimation BS_ATTACKER, B_ANIM_RESTORE_BG, NULL end2 BattleScript_GrassyTerrainEnds:: printstring STRINGID_GRASSYTERRAINENDS waitmessage 0x40 + playanimation BS_ATTACKER, B_ANIM_RESTORE_BG, NULL end2 BattleScript_PsychicTerrainEnds:: printstring STRINGID_PSYCHICTERRAINENDS waitmessage 0x40 + playanimation BS_ATTACKER, B_ANIM_RESTORE_BG, NULL end2 BattleScript_MudSportEnds:: diff --git a/include/battle.h b/include/battle.h index e319104f68..7ce9feef3c 100644 --- a/include/battle.h +++ b/include/battle.h @@ -711,8 +711,8 @@ struct MonSpritesGfx struct TotemBoost { - u8 stats; //bitfield for each battle stat - u8 statChanges[NUM_BATTLE_STATS - 1]; //highest bit is decrease + u8 stats; // bitfield for each battle stat that is set if the stat changes + s8 statChanges[NUM_BATTLE_STATS - 1]; // highest bit being set decreases the stat }; /* size = 8 */ // All battle variables are declared in battle_main.c diff --git a/include/battle_anim.h b/include/battle_anim.h index 2f481c5f26..2b28e92fb1 100644 --- a/include/battle_anim.h +++ b/include/battle_anim.h @@ -68,6 +68,7 @@ s16 KeepPanInRange(s16 a, int oldPan); s16 CalculatePanIncrement(s16 sourcePan, s16 targetPan, s16 incrementPan); void sub_80A4720(u16 a, u16 *b, u32 c, u8 d); void sub_80A477C(bool8); +void LoadMoveBg(u16 bgId); // battle_intro.c void SetAnimBgAttribute(u8 bgId, u8 attributeId, u8 value); diff --git a/include/battle_bg.h b/include/battle_bg.h index 167ea5cf74..43295476f5 100644 --- a/include/battle_bg.h +++ b/include/battle_bg.h @@ -9,5 +9,6 @@ void LoadBattleTextboxAndBackground(void); void InitLinkBattleVsScreen(u8 taskId); void DrawBattleEntryBackground(void); bool8 LoadChosenBattleElement(u8 caseId); +void DrawTerrainTypeBattleBackground(void); #endif // GUARD_BATTLE_BG_H diff --git a/include/constants/battle.h b/include/constants/battle.h index 2c573dcbed..40c604c9ed 100644 --- a/include/constants/battle.h +++ b/include/constants/battle.h @@ -234,6 +234,8 @@ #define STATUS_FIELD_ION_DELUGE 0x400 #define STATUS_FIELD_FAIRY_LOCK 0x800 +#define STATUS_TERRAIN_ANY (STATUS_FIELD_GRASSY_TERRAIN | STATUS_FIELD_MISTY_TERRAIN | STATUS_FIELD_ELECTRIC_TERRAIN | STATUS_FIELD_PSYCHIC_TERRAIN) + // Flags describing move's result #define MOVE_RESULT_MISSED (1 << 0) #define MOVE_RESULT_SUPER_EFFECTIVE (1 << 1) diff --git a/include/constants/battle_anim.h b/include/constants/battle_anim.h index 5596f28bf8..09c7fb21af 100644 --- a/include/constants/battle_anim.h +++ b/include/constants/battle_anim.h @@ -525,7 +525,8 @@ #define B_ANIM_ILLUSION_OFF 0x1C #define B_ANIM_FORM_CHANGE 0x1D #define B_ANIM_SLIDE_OFFSCREEN 0x1E // for Emergency Exit -#define B_ANIM_TOTEM_FLARE 0x1F +#define B_ANIM_RESTORE_BG 0x1F // for Terrain Endings +#define B_ANIM_TOTEM_FLARE 0x20 // Totem boosts aura flare // special animations table #define B_ANIM_LVL_UP 0x0 diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index d7f1785709..55c62af987 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -164,5 +164,6 @@ #define B_NEW_SURF_PARTICLE_PALETTE TRUE // If set to TRUE, it updates Surf's wave palette. #define HIDE_HEALTHBOXES_DURING_ANIMS TRUE //if TRUE, hides healthboxes during move animations +#define B_TERRAIN_BG_CHANGE TRUE // If TRUE, terrain moves permanently change the default battle background until the effect fades. #endif // GUARD_CONSTANTS_BATTLE_CONFIG_H diff --git a/src/battle_anim.c b/src/battle_anim.c index 6482ccc6ba..cb7ea5bea0 100644 --- a/src/battle_anim.c +++ b/src/battle_anim.c @@ -88,7 +88,6 @@ static void Task_PanFromInitialToTarget(u8 taskId); static void Task_LoopAndPlaySE(u8 taskId); static void Task_WaitAndPlaySE(u8 taskId); static void LoadDefaultBg(void); -static void LoadMoveBg(u16 bgId); // ewram EWRAM_DATA static const u8 *sBattleAnimScriptPtr = NULL; @@ -3177,7 +3176,7 @@ static void Task_FadeToBg(u8 taskId) } } -static void LoadMoveBg(u16 bgId) +void LoadMoveBg(u16 bgId) { if (IsContest()) { @@ -3205,6 +3204,10 @@ static void LoadDefaultBg(void) { if (IsContest()) LoadContestBgAfterMoveAnim(); + #if B_TERRAIN_BG_CHANGE == TRUE + else if (gFieldStatuses & STATUS_TERRAIN_ANY) + DrawTerrainTypeBattleBackground(); + #endif else DrawMainBattleBackground(); } diff --git a/src/battle_bg.c b/src/battle_bg.c index d9d6bf87cc..ca1893d652 100644 --- a/src/battle_bg.c +++ b/src/battle_bg.c @@ -1,5 +1,6 @@ #include "global.h" #include "battle.h" +#include "battle_anim.h" #include "battle_bg.h" #include "battle_main.h" #include "battle_message.h" @@ -23,6 +24,7 @@ #include "constants/map_types.h" #include "constants/songs.h" #include "constants/trainers.h" +#include "constants/battle_anim.h" struct BattleBackground { @@ -863,7 +865,11 @@ void LoadBattleTextboxAndBackground(void) CopyBgTilemapBufferToVram(0); LoadCompressedPalette(gBattleTextboxPalette, 0, 0x40); LoadBattleMenuWindowGfx(); - DrawMainBattleBackground(); + #if B_TERRAIN_BG_CHANGE == TRUE + DrawTerrainTypeBattleBackground(); + #else + DrawMainBattleBackground(); + #endif } static void DrawLinkBattleParticipantPokeballs(u8 taskId, u8 multiplayerId, u8 bgId, u8 destX, u8 destY) @@ -1413,3 +1419,26 @@ bool8 LoadChosenBattleElement(u8 caseId) return ret; } + +void DrawTerrainTypeBattleBackground(void) +{ + switch (gFieldStatuses & STATUS_TERRAIN_ANY) + { + case STATUS_FIELD_GRASSY_TERRAIN: + LoadMoveBg(BG_GRASSY_TERRAIN); + break; + case STATUS_FIELD_MISTY_TERRAIN: + LoadMoveBg(BG_MISTY_TERRAIN); + break; + case STATUS_FIELD_ELECTRIC_TERRAIN: + LoadMoveBg(BG_ELECTRIC_TERRAIN); + break; + case STATUS_FIELD_PSYCHIC_TERRAIN: + LoadMoveBg(BG_PSYCHIC_TERRAIN); + break; + default: + DrawMainBattleBackground(); + break; + } +} + diff --git a/src/battle_main.c b/src/battle_main.c index 73362864ec..8f5a5ccffe 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -3484,6 +3484,19 @@ static void TryDoEventsBeforeFirstTurn(void) gBattleStruct->overworldWeatherDone = TRUE; return; } + + // Totem boosts + for (i = 0; i < gBattlersCount; i++) + { + if (gTotemBoosts[i].stats != 0) + { + gBattlerAttacker = i; + BattleScriptExecute(BattleScript_TotemVar); + return; + } + } + memset(gTotemBoosts, 0, sizeof(gTotemBoosts)); // erase all totem boosts just to be safe + // Check all switch in abilities happening from the fastest mon to slowest. while (gBattleStruct->switchInAbilitiesCounter < gBattlersCount) { @@ -3501,17 +3514,6 @@ static void TryDoEventsBeforeFirstTurn(void) if (ItemBattleEffects(ITEMEFFECT_ON_SWITCH_IN, gBattlerByTurnOrder[gBattleStruct->switchInItemsCounter++], FALSE)) return; } - // Totem - for (i = 0; i < gBattlersCount; i++) - { - if (gTotemBoosts[i].stats != 0) - { - gBattlerAttacker = i; - BattleScriptExecute(BattleScript_TotemVar); - return; - } - } - memset(gTotemBoosts, 0, sizeof(gTotemBoosts)); //erase all totem boosts just to be safe for (i = 0; i < MAX_BATTLERS_COUNT; i++) { @@ -5078,7 +5080,7 @@ void SetTotemBoost(void) { gTotemBoosts[battlerId].stats |= (1 << i); gTotemBoosts[battlerId].statChanges[i] = *(&gSpecialVar_0x8001 + i); - gTotemBoosts[battlerId].stats |= 0x80; //used as a flag for the "totem flared to life" script + gTotemBoosts[battlerId].stats |= 0x80; // used as a flag for the "totem flared to life" script } } } diff --git a/src/battle_message.c b/src/battle_message.c index 33624c1f66..4ef4250926 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -3434,7 +3434,7 @@ static void ExpandBattleTextBuffPlaceholders(const u8 *src, u8 *dst) srcID += 2; break; case B_BUFF_ABILITY: // ability names - StringAppend(dst, gAbilityNames[src[srcID + 1]]); + StringAppend(dst, gAbilityNames[T1_READ_16(&src[srcID + 1])]); srcID += 3; break; case B_BUFF_ITEM: // item name diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 0492e0a708..c8c36fa9cd 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -6952,7 +6952,7 @@ static void HandleTerrainMove(u32 moveEffect) } else { - gFieldStatuses &= ~(STATUS_FIELD_MISTY_TERRAIN | STATUS_FIELD_GRASSY_TERRAIN | STATUS_FIELD_ELECTRIC_TERRAIN | STATUS_FIELD_PSYCHIC_TERRAIN); + gFieldStatuses &= ~STATUS_TERRAIN_ANY; gFieldStatuses |= statusFlag; if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_TERRAIN_EXTENDER) *timer = 8; @@ -8304,7 +8304,7 @@ static void Cmd_various(void) gActiveBattler = gBattlerAttacker; if (gTotemBoosts[gActiveBattler].stats == 0) { - gBattlescriptCurrInstr += 7; //stats done, exit + gBattlescriptCurrInstr += 7; // stats done, exit } else { @@ -8312,26 +8312,27 @@ static void Cmd_various(void) { if (gTotemBoosts[gActiveBattler].stats & (1 << i)) { - bool8 negative = (gTotemBoosts[gActiveBattler].statChanges[i] & 0x80) ? TRUE : FALSE; - u8 change = gTotemBoosts[gActiveBattler].statChanges[i] & 0x7F; + if (gTotemBoosts[gActiveBattler].statChanges[i] <= -1) + SET_STATCHANGER(i + 1, abs(gTotemBoosts[gActiveBattler].statChanges[i]), TRUE); + else + SET_STATCHANGER(i + 1, gTotemBoosts[gActiveBattler].statChanges[i], FALSE); gTotemBoosts[gActiveBattler].stats &= ~(1 << i); - SET_STATCHANGER(i + 1, change, negative); gBattleScripting.battler = gActiveBattler; gBattlerTarget = gActiveBattler; if (gTotemBoosts[gActiveBattler].stats & 0x80) { - gTotemBoosts[gActiveBattler].stats &= ~0x80; + gTotemBoosts[gActiveBattler].stats &= ~0x80; // set 'aura flared to life' flag gBattlescriptCurrInstr = BattleScript_TotemFlaredToLife; } else { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); //do boost + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); // do boost } return; } } - gBattlescriptCurrInstr += 7; //exit if loop failed (failsafe) + gBattlescriptCurrInstr += 7; // exit if loop failed (failsafe) } return; }