Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Ultra Burst #3221

Merged
merged 17 commits into from
Aug 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions asm/macros/battle_script.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1637,6 +1637,11 @@
.byte \case
.endm

.macro handleultraburst battler:req, case:req
various \battler, VARIOUS_HANDLE_ULTRA_BURST
.byte \case
.endm

.macro handleformchange battler:req, case:req
various \battler, VARIOUS_HANDLE_FORM_CHANGE
.byte \case
Expand Down
38 changes: 38 additions & 0 deletions data/battle_anim_scripts.s
Original file line number Diff line number Diff line change
Expand Up @@ -947,6 +947,7 @@ gBattleAnims_General::
.4byte General_ZMoveActivate @ B_ANIM_ZMOVE_ACTIVATE
.4byte General_AffectionHangedOn @ B_ANIM_AFFECTION_HANGED_ON
.4byte General_Snow @ B_ANIM_SNOW_CONTINUES
.4byte General_UltraBurst @ B_ANIM_ULTRA_BURST

.align 2
gBattleAnims_Special::
Expand Down Expand Up @@ -27002,6 +27003,43 @@ General_PrimalReversion_Omega:
blendoff
end

General_UltraBurst::
loadspritegfx ANIM_TAG_ULTRA_BURST_SYMBOL
loadspritegfx ANIM_TAG_SPARK_2 @spark
loadspritegfx ANIM_TAG_LEAF @green
loadspritegfx ANIM_TAG_ELECTRIC_ORBS @charge particles
loadspritegfx ANIM_TAG_CIRCLE_OF_LIGHT @psycho boost
monbg ANIM_ATTACKER
setalpha 12, 8
createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_ADJACENT), 0x2, 0x0, 0xF, 0x0000
waitforvisualfinish
createvisualtask AnimTask_ElectricChargingParticles, 2, ANIM_ATTACKER, 60, 2, 12 @ charge particles to attacker
delay 0x1e
loopsewithpan SE_M_CHARGE, SOUND_PAN_ATTACKER, 0xe, 0xa
createsprite gSuperpowerOrbSpriteTemplate, ANIM_TARGET, 3, 0x0
call LightThatBurnsTheSkyGreenSparks
call LightThatBurnsTheSkyGreenSparks
call LightThatBurnsTheSkyGreenSparks
call LightThatBurnsTheSkyGreenSparks
call LightThatBurnsTheSkyGreenSparks
call LightThatBurnsTheSkyGreenSparks
call LightThatBurnsTheSkyGreenSparks
call LightThatBurnsTheSkyGreenSparks
call LightThatBurnsTheSkyGreenSparks
delay 20
createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, 5, 2, 0, 16, RGB_WHITEALPHA
createvisualtask AnimTask_TransformMon, 2, 1, 0
createsprite gUltraBurstSymbolSpriteTemplate, ANIM_ATTACKER, 0x0, 0x0, 0x0, 0x0, 0x0
waitforvisualfinish
createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, 5, 2, 16, 0, RGB_WHITEALPHA
createvisualtask AnimTask_HorizontalShake, 5, ANIM_TARGET, 5, 14
waitforvisualfinish
createvisualtask SoundTask_PlayNormalCry, 0
waitforvisualfinish
clearmonbg ANIM_ATK_PARTNER
blendoff
end

General_AffectionHangedOn::
loadspritegfx ANIM_TAG_RED_HEART
loopsewithpan SE_M_CHARM, SOUND_PAN_ATTACKER, 12, 3
Expand Down
15 changes: 15 additions & 0 deletions data/battle_scripts_1.s
Original file line number Diff line number Diff line change
Expand Up @@ -7796,6 +7796,21 @@ BattleScript_PrimalReversionRet::
switchinabilities BS_ATTACKER
return

BattleScript_UltraBurst::
printstring STRINGID_EMPTYSTRING3
trytrainerslidezmovemsg BS_ATTACKER
printstring STRINGID_ULTRABURSTREACTING
waitmessage B_WAIT_TIME_LONG
setbyte gIsCriticalHit, 0
handleultraburst BS_ATTACKER, 0
playanimation BS_ATTACKER, B_ANIM_ULTRA_BURST
waitanimation
handleultraburst BS_ATTACKER, 1
printstring STRINGID_ULTRABURSTCOMPLETED
waitmessage B_WAIT_TIME_LONG
switchinabilities BS_ATTACKER
end3

BattleScript_AttackerFormChange::
pause 5
copybyte gBattlerAbility, gBattlerAttacker
Expand Down
Binary file added graphics/battle_interface/burst_trigger.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions include/battle.h
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,15 @@ struct MegaEvolutionData
u8 triggerSpriteId;
};

struct UltraBurstData
{
u8 toBurst; // As flags using gBitTable.
bool8 alreadyBursted[4]; // Array id is used for mon position.
u8 battlerId;
bool8 playerSelect;
u8 triggerSpriteId;
};

struct Illusion
{
u8 on;
Expand Down Expand Up @@ -616,6 +625,7 @@ struct BattleStruct
u8 abilityPopUpSpriteIds[MAX_BATTLERS_COUNT][2]; // two per battler
bool8 throwingPokeBall;
struct MegaEvolutionData mega;
struct UltraBurstData burst;
struct ZMoveData zmove;
const u8 *trainerSlideMsg;
bool8 trainerSlideLowHpMsgDone;
Expand Down
2 changes: 2 additions & 0 deletions include/battle_controllers.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ enum {
// Special return values in gBattleBufferB from Battle Controller functions.
#define RET_VALUE_LEVELED_UP 11
#define RET_MEGA_EVOLUTION 0x80
#define RET_ULTRA_BURST 0x70

struct UnusedControllerStruct
{
Expand Down Expand Up @@ -129,6 +130,7 @@ struct ChooseMoveStruct
u8 monType2;
u8 monType3;
struct MegaEvolutionData mega;
struct UltraBurstData burst;
struct ZMoveData zmove;
};

Expand Down
7 changes: 7 additions & 0 deletions include/battle_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,13 @@ enum
#define TAG_ALPHA_INDICATOR_TILE 0xD779
#define TAG_OMEGA_INDICATOR_TILE 0xD77A
#define TAG_ZMOVE_TRIGGER_TILE 0xD77B
#define TAG_BURST_TRIGGER_TILE 0xD77C

#define TAG_MEGA_TRIGGER_PAL 0xD777
#define TAG_MEGA_INDICATOR_PAL 0xD778
#define TAG_ALPHA_OMEGA_INDICATOR_PAL 0xD779 // Alpha and Omega indicators use the same palette as each of them only uses 4 different colors.
#define TAG_ZMOVE_TRIGGER_PAL 0xD77B
#define TAG_BURST_TRIGGER_PAL 0xD77C

enum
{
Expand Down Expand Up @@ -91,6 +93,11 @@ void CreateMegaTriggerSprite(u8 battlerId, u8 palId);
bool32 IsMegaTriggerSpriteActive(void);
void HideMegaTriggerSprite(void);
void DestroyMegaTriggerSprite(void);
void ChangeBurstTriggerSprite(u8 spriteId, u8 animId);
void CreateBurstTriggerSprite(u8 battlerId, u8 palId);
bool32 IsBurstTriggerSpriteActive(void);
void HideBurstTriggerSprite(void);
void DestroyBurstTriggerSprite(void);
void MegaIndicator_LoadSpritesGfx(void);
u8 CreatePartyStatusSummarySprites(u8 battler, struct HpAndStatus *partyInfo, bool8 skipPlayer, bool8 isBattleStart);
void Task_HidePartyStatusSummary(u8 taskId);
Expand Down
1 change: 1 addition & 0 deletions include/battle_scripts.h
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,7 @@ extern const u8 BattleScript_SpikesActivates[];
extern const u8 BattleScript_BerserkGeneRet[];
extern const u8 BattleScript_TargetFormChangeWithStringNoPopup[];
extern const u8 BattleScript_DefDown[];
extern const u8 BattleScript_UltraBurst[];

// zmoves
extern const u8 BattleScript_ZMoveActivateDamaging[];
Expand Down
2 changes: 2 additions & 0 deletions include/battle_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,10 @@ uq4_12_t GetTypeModifier(u8 atkType, u8 defType);
s32 GetStealthHazardDamage(u8 hazardType, u8 battlerId);
s32 GetStealthHazardDamageByTypesAndHP(u8 hazardType, u8 type1, u8 type2, u32 maxHp);
bool32 CanMegaEvolve(u8 battlerId);
bool32 CanUltraBurst(u8 battlerId);
bool32 IsBattlerMegaEvolved(u8 battlerId);
bool32 IsBattlerPrimalReverted(u8 battlerId);
bool32 IsBattlerUltraBursted(u8 battlerId);
u16 GetBattleFormChangeTargetSpecies(u8 battlerId, u16 method);
bool32 TryBattleFormChange(u8 battlerId, u16 method);
bool32 DoBattlersShareType(u32 battler1, u32 battler2);
Expand Down
5 changes: 5 additions & 0 deletions include/constants/battle.h
Original file line number Diff line number Diff line change
Expand Up @@ -495,4 +495,9 @@
#define PARENTAL_BOND_2ND_HIT 1
#define PARENTAL_BOND_OFF 0

// Constants for if HandleScriptMegaPrimalBurst should handle Mega Evolution, Primal Reversion, or Ultra Burst.
#define HANDLE_TYPE_MEGA_EVOLUTION 0
#define HANDLE_TYPE_PRIMAL_REVERSION 1
#define HANDLE_TYPE_ULTRA_BURST 2

#endif // GUARD_CONSTANTS_BATTLE_H
1 change: 1 addition & 0 deletions include/constants/battle_anim.h
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,7 @@
#define B_ANIM_ZMOVE_ACTIVATE 34 // Using Z Moves
#define B_ANIM_AFFECTION_HANGED_ON 35
#define B_ANIM_SNOW_CONTINUES 36
#define B_ANIM_ULTRA_BURST 37

// special animations table (gBattleAnims_Special)
#define B_ANIM_LVL_UP 0
Expand Down
1 change: 1 addition & 0 deletions include/constants/battle_script_commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@
#define VARIOUS_TRY_REVIVAL_BLESSING 165
#define VARIOUS_TRY_TRAINER_SLIDE_MSG_Z_MOVE 166
#define VARIOUS_TRY_TRAINER_SLIDE_MSG_MEGA_EVOLUTION 167
#define VARIOUS_HANDLE_ULTRA_BURST 168

// Cmd_manipulatedamage
#define DMG_CHANGE_SIGN 0
Expand Down
4 changes: 3 additions & 1 deletion include/constants/battle_string_ids.h
Original file line number Diff line number Diff line change
Expand Up @@ -665,8 +665,10 @@
#define STRINGID_SNOWSTOPPED 663
#define STRINGID_SNOWWARNINGSNOW 664
#define STRINGID_PKMNITEMMELTED 665
#define STRINGID_ULTRABURSTREACTING 666
#define STRINGID_ULTRABURSTCOMPLETED 667

#define BATTLESTRINGS_COUNT 666
#define BATTLESTRINGS_COUNT 668

// This is the string id that gBattleStringsTable starts with.
// String ids before this (e.g. STRINGID_INTROMSG) are not in the table,
Expand Down
5 changes: 5 additions & 0 deletions include/constants/form_change_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,9 @@
// param1: ability to check.
#define FORM_CHANGE_BATTLE_TURN_END 15

// Form change that activates when the mon has the defined item.
// If it's on the player's side, it also requires for the player to trigger it by pressing START before selecting a move.
// param1: item to hold.
#define FORM_CHANGE_BATTLE_ULTRA_BURST 16

#endif // GUARD_CONSTANTS_FORM_CHANGE_TYPES_H
1 change: 1 addition & 0 deletions include/constants/pokemon.h
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,7 @@
#define SPECIES_FLAG_HISUIAN_FORM (1 << 7)
#define SPECIES_FLAG_ALL_PERFECT_IVS (1 << 8)
#define SPECIES_FLAG_CANNOT_BE_TRADED (1 << 9)
#define SPECIES_FLAG_ULTRA_BURST (1 << 10)

#define LEGENDARY_PERFECT_IV_COUNT 3

Expand Down
2 changes: 2 additions & 0 deletions include/test/battle.h
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,8 @@ struct MoveContext
u16 explicitSecondaryEffect:1;
u16 megaEvolve:1;
u16 explicitMegaEvolve:1;
u16 ultraBurst:1;
u16 explicitUltraBurst:1;
// TODO: u8 zMove:1;
u16 allowed:1;
u16 explicitAllowed:1;
Expand Down
1 change: 1 addition & 0 deletions src/battle_anim.c
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ void LaunchBattleAnimation(u32 animType, u32 animId)
case B_ANIM_WISH_HEAL:
case B_ANIM_MEGA_EVOLUTION:
case B_ANIM_PRIMAL_REVERSION:
case B_ANIM_ULTRA_BURST:
case B_ANIM_GULP_MISSILE:
sAnimHideHpBoxes = TRUE;
break;
Expand Down
12 changes: 12 additions & 0 deletions src/battle_anim_new.c
Original file line number Diff line number Diff line change
Expand Up @@ -4761,6 +4761,18 @@ const struct SpriteTemplate gSpriteTemplate_BitterMaliceRing = {
.callback = AnimParticleInVortex
};

//ultra burst
const struct SpriteTemplate gUltraBurstSymbolSpriteTemplate =
{
.tileTag = ANIM_TAG_ULTRA_BURST_SYMBOL,
.paletteTag = ANIM_TAG_ULTRA_BURST_SYMBOL,
.oam = &gOamData_AffineDouble_ObjBlend_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gAffineAnims_LusterPurgeCircle,
.callback = AnimSpriteOnMonPos
};

// Z MOVES
//activate
const struct SpriteTemplate gZMoveSymbolSpriteTemplate =
Expand Down
2 changes: 2 additions & 0 deletions src/battle_controller_opponent.c
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,8 @@ static void OpponentHandleChooseMove(u32 battler)
QueueZMove(battler, chosenMove);
if (CanMegaEvolve(battler)) // If opponent can mega evolve, do it.
BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (RET_MEGA_EVOLUTION) | (gBattlerTarget << 8));
else if (CanUltraBurst(gActiveBattler))
BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (RET_ULTRA_BURST) | (gBattlerTarget << 8));
else
BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (gBattlerTarget << 8));
}
Expand Down
23 changes: 22 additions & 1 deletion src/battle_controller_player.c
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,8 @@ static void HandleInputChooseTarget(u32 battler)
gSprites[gBattlerSpriteIds[gMultiUsePlayerCursor]].callback = SpriteCB_HideAsMoveTarget;
if (gBattleStruct->mega.playerSelect)
BtlController_EmitTwoReturnValues(BUFFER_B, 10, gMoveSelectionCursor[battler] | RET_MEGA_EVOLUTION | (gMultiUsePlayerCursor << 8));
else if (gBattleStruct->burst.playerSelect)
BtlController_EmitTwoReturnValues(BUFFER_B, 10, gMoveSelectionCursor[battler] | RET_ULTRA_BURST | (gMultiUsePlayerCursor << 8));
else
BtlController_EmitTwoReturnValues(BUFFER_B, 10, gMoveSelectionCursor[battler] | (gMultiUsePlayerCursor << 8));
EndBounceEffect(gMultiUsePlayerCursor, BOUNCE_HEALTHBOX);
Expand Down Expand Up @@ -594,9 +596,11 @@ static void HandleInputShowEntireFieldTargets(u32 battler)
HideAllTargets();
if (gBattleStruct->mega.playerSelect)
BtlController_EmitTwoReturnValues(BUFFER_B, 10, gMoveSelectionCursor[battler] | RET_MEGA_EVOLUTION | (gMultiUsePlayerCursor << 8));
else if (gBattleStruct->burst.playerSelect)
BtlController_EmitTwoReturnValues(BUFFER_B, 10, gMoveSelectionCursor[battler] | RET_ULTRA_BURST | (gMultiUsePlayerCursor << 8));
else
BtlController_EmitTwoReturnValues(BUFFER_B, 10, gMoveSelectionCursor[battler] | (gMultiUsePlayerCursor << 8));
HideMegaTriggerSprite();
HideTriggerSprites();
PlayerBufferExecCompleted(battler);
}
else if (JOY_NEW(B_BUTTON) || gPlayerDpadHoldFrames > 59)
Expand All @@ -622,6 +626,8 @@ static void HandleInputShowTargets(u32 battler)
HideShownTargets(battler);
if (gBattleStruct->mega.playerSelect)
BtlController_EmitTwoReturnValues(BUFFER_B, 10, gMoveSelectionCursor[battler] | RET_MEGA_EVOLUTION | (gMultiUsePlayerCursor << 8));
else if (gBattleStruct->burst.playerSelect)
BtlController_EmitTwoReturnValues(BUFFER_B, 10, gMoveSelectionCursor[battler] | RET_ULTRA_BURST | (gMultiUsePlayerCursor << 8));
else
BtlController_EmitTwoReturnValues(BUFFER_B, 10, gMoveSelectionCursor[battler] | (gMultiUsePlayerCursor << 8));
HideTriggerSprites();
Expand Down Expand Up @@ -737,6 +743,8 @@ static void HandleInputChooseMove(u32 battler)
default:
if (gBattleStruct->mega.playerSelect)
BtlController_EmitTwoReturnValues(BUFFER_B, 10, gMoveSelectionCursor[battler] | RET_MEGA_EVOLUTION | (gMultiUsePlayerCursor << 8));
else if (gBattleStruct->burst.playerSelect)
BtlController_EmitTwoReturnValues(BUFFER_B, 10, gMoveSelectionCursor[battler] | RET_ULTRA_BURST | (gMultiUsePlayerCursor << 8));
else
BtlController_EmitTwoReturnValues(BUFFER_B, 10, gMoveSelectionCursor[battler] | (gMultiUsePlayerCursor << 8));
HideTriggerSprites();
Expand Down Expand Up @@ -773,6 +781,7 @@ static void HandleInputChooseMove(u32 battler)
else
{
gBattleStruct->mega.playerSelect = FALSE;
gBattleStruct->burst.playerSelect = FALSE;
gBattleStruct->zmove.viable = FALSE;
BtlController_EmitTwoReturnValues(BUFFER_B, 10, 0xFFFF);
HideTriggerSprites();
Expand Down Expand Up @@ -857,6 +866,12 @@ static void HandleInputChooseMove(u32 battler)
ChangeMegaTriggerSprite(gBattleStruct->mega.triggerSpriteId, gBattleStruct->mega.playerSelect);
PlaySE(SE_SELECT);
}
else if (CanUltraBurst(gActiveBattler))
{
gBattleStruct->burst.playerSelect ^= 1;
ChangeBurstTriggerSprite(gBattleStruct->burst.triggerSpriteId, gBattleStruct->burst.playerSelect);
PlaySE(SE_SELECT);
}
else if (gBattleStruct->zmove.viable)
{
// show z move name / info
Expand All @@ -873,6 +888,7 @@ static void HandleInputChooseMove(u32 battler)
static void ReloadMoveNames(u32 battler)
{
gBattleStruct->mega.playerSelect = FALSE;
gBattleStruct->burst.playerSelect = FALSE;
gBattleStruct->zmove.viewing = FALSE;
MoveSelectionDestroyCursorAt(battler);
MoveSelectionDisplayMoveNames(battler);
Expand Down Expand Up @@ -1954,10 +1970,15 @@ static void PlayerHandleChooseMove(u32 battler)

InitMoveSelectionsVarsAndStrings(battler);
gBattleStruct->mega.playerSelect = FALSE;
gBattleStruct->burst.playerSelect = FALSE;
if (!IsMegaTriggerSpriteActive())
gBattleStruct->mega.triggerSpriteId = 0xFF;
if (CanMegaEvolve(battler))
CreateMegaTriggerSprite(battler, 0);
if (!IsBurstTriggerSpriteActive())
gBattleStruct->burst.triggerSpriteId = 0xFF;
if (CanUltraBurst(battler))
CreateBurstTriggerSprite(battler, 0);
if (!IsZMoveTriggerSpriteActive())
gBattleStruct->zmove.triggerSpriteId = 0xFF;

Expand Down
2 changes: 2 additions & 0 deletions src/battle_controller_player_partner.c
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,8 @@ static void PlayerPartnerHandleChooseMove(u32 battler)
// If partner can mega evolve, do it.
if (CanMegaEvolve(battler))
BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (RET_MEGA_EVOLUTION) | (gBattlerTarget << 8));
else if (CanUltraBurst(battler))
BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (RET_ULTRA_BURST) | (gBattlerTarget << 8));
else
BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (gBattlerTarget << 8));
}
Expand Down
Loading
Loading