Merge branch 'upcoming' of https://github.com/rh-hideout/pokeemerald-expansion into dynamax
This commit is contained in:
commit
d133564e21
@ -1349,6 +1349,76 @@
|
||||
.macro setsnow
|
||||
callnative BS_SetSnow
|
||||
.endm
|
||||
|
||||
.macro setzeffect
|
||||
callnative BS_SetZEffect
|
||||
.endm
|
||||
|
||||
@ Used by effects that may proc Symbiosis but do not call removeitem.
|
||||
.macro trysymbiosis
|
||||
callnative BS_TrySymbiosis
|
||||
.endm
|
||||
|
||||
@ returns TRUE or FALSE to gBattleCommunication[0]
|
||||
.macro canteleport battler:req
|
||||
callnative BS_CanTeleport
|
||||
.byte \battler
|
||||
.endm
|
||||
|
||||
@ returns B_SIDE_x to gBattleCommunication[0]
|
||||
.macro getbattlerside battler:req
|
||||
callnative BS_GetBattlerSide
|
||||
.byte \battler
|
||||
.endm
|
||||
|
||||
.macro checkparentalbondcounter counter:req, ptr:req
|
||||
callnative BS_CheckParentalBondCounter
|
||||
.byte \counter
|
||||
.4byte \ptr
|
||||
.endm
|
||||
|
||||
@ Used to active a different Max Move effects.
|
||||
.macro setmaxmoveeffect
|
||||
callnative BS_SetMaxMoveEffect
|
||||
.endm
|
||||
|
||||
.macro setsteelsurge, failInstr:req
|
||||
callnative BS_SetSteelsurge
|
||||
.4byte \failInstr
|
||||
.endm
|
||||
|
||||
.macro damagenontypes
|
||||
callnative BS_DamageNonTypes
|
||||
.endm
|
||||
|
||||
.macro trysetstatus1, ptr:req
|
||||
callnative BS_TrySetStatus1
|
||||
.4byte \ptr
|
||||
.endm
|
||||
|
||||
.macro trysetstatus2, ptr:req
|
||||
callnative BS_TrySetStatus2
|
||||
.4byte \ptr
|
||||
.endm
|
||||
|
||||
.macro tryhealsixthhealth, ptr:req
|
||||
callnative BS_HealOneSixth
|
||||
.4byte \ptr
|
||||
.endm
|
||||
|
||||
.macro tryrecycleberry, ptr:req
|
||||
callnative BS_TryRecycleBerry
|
||||
.4byte \ptr
|
||||
.endm
|
||||
|
||||
.macro updatedynamax
|
||||
callnative BS_UpdateDynamax
|
||||
.endm
|
||||
|
||||
.macro jumpiftargetdynamaxed, ptr:req
|
||||
callnative BS_JumpIfDynamaxed
|
||||
.4byte \ptr
|
||||
.endm
|
||||
|
||||
@ various command changed to more readable macros
|
||||
.macro cancelmultiturnmoves battler:req
|
||||
@ -1835,10 +1905,6 @@
|
||||
various \battler, VARIOUS_TRY_ACTIVATE_GRIM_NEIGH
|
||||
.endm
|
||||
|
||||
.macro setzeffect
|
||||
various BS_ATTACKER, VARIOUS_SET_Z_EFFECT
|
||||
.endm
|
||||
|
||||
.macro consumeberry battler:req, fromBattler:req
|
||||
various \battler, VARIOUS_CONSUME_BERRY
|
||||
.byte \fromBattler
|
||||
@ -2049,20 +2115,7 @@
|
||||
.macro swapsidestatuses
|
||||
various BS_ATTACKER, VARIOUS_SWAP_SIDE_STATUSES
|
||||
.endm
|
||||
|
||||
.macro canteleport battler:req
|
||||
various \battler, VARIOUS_CAN_TELEPORT
|
||||
.endm
|
||||
|
||||
.macro getbattlerside battler:req
|
||||
various \battler, VARIOUS_GET_BATTLER_SIDE
|
||||
.endm
|
||||
|
||||
.macro checkparentalbondcounter counter:req, jumpInstr:req
|
||||
various BS_ATTACKER, VARIOUS_CHECK_PARENTAL_BOND_COUNTER
|
||||
.byte \counter
|
||||
.4byte \jumpInstr
|
||||
.endm
|
||||
|
||||
.macro swapstats stat:req
|
||||
various BS_ATTACKER, VARIOUS_SWAP_STATS
|
||||
.byte \stat
|
||||
@ -2242,54 +2295,6 @@
|
||||
various 0, VARIOUS_SKY_DROP_YAWN
|
||||
.endm
|
||||
|
||||
@ Used by effects that may proc Symbiosis but do not call removeitem.
|
||||
.macro trysymbiosis
|
||||
various BS_ATTACKER, VARIOUS_TRY_SYMBIOSIS
|
||||
.endm
|
||||
|
||||
@ Used to active a different Max Move effects.
|
||||
.macro setmaxmoveeffect
|
||||
callnative BS_SetMaxMoveEffect
|
||||
.endm
|
||||
|
||||
.macro setsteelsurge, failInstr:req
|
||||
callnative BS_SetSteelsurge
|
||||
.4byte \failInstr
|
||||
.endm
|
||||
|
||||
.macro damagenontypes
|
||||
callnative BS_DamageNonTypes
|
||||
.endm
|
||||
|
||||
.macro trysetstatus1, ptr:req
|
||||
callnative BS_TrySetStatus1
|
||||
.4byte \ptr
|
||||
.endm
|
||||
|
||||
.macro trysetstatus2, ptr:req
|
||||
callnative BS_TrySetStatus2
|
||||
.4byte \ptr
|
||||
.endm
|
||||
|
||||
.macro tryhealsixthhealth, ptr:req
|
||||
callnative BS_HealOneSixth
|
||||
.4byte \ptr
|
||||
.endm
|
||||
|
||||
.macro tryrecycleberry, ptr:req
|
||||
callnative BS_TryRecycleBerry
|
||||
.4byte \ptr
|
||||
.endm
|
||||
|
||||
.macro updatedynamax
|
||||
callnative BS_UpdateDynamax
|
||||
.endm
|
||||
|
||||
.macro jumpiftargetdynamaxed, ptr:req
|
||||
callnative BS_JumpIfDynamaxed
|
||||
.4byte \ptr
|
||||
.endm
|
||||
|
||||
@ Tries to increase or decrease a battler's stat's stat stage by a specified amount. If impossible, jumps to \script.
|
||||
.macro modifybattlerstatstage battler:req, stat:req, mode:req, amount:req, script:req, animation:req, customString
|
||||
|
||||
|
||||
@ -436,9 +436,9 @@ BattleScript_EffectRevivalBlessing::
|
||||
attackcanceler
|
||||
attackstring
|
||||
ppreduce
|
||||
tryrevivalblessing BattleScript_ButItFailed
|
||||
attackanimation
|
||||
waitanimation
|
||||
tryrevivalblessing BattleScript_ButItFailed
|
||||
printstring STRINGID_PKMNREVIVEDREADYTOFIGHT
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
jumpifbyte CMP_EQUAL, gBattleCommunication, TRUE, BattleScript_EffectRevivalBlessingSendOut
|
||||
@ -616,7 +616,7 @@ BattleScript_ShellTrapSetUp::
|
||||
playanimation BS_ATTACKER, B_ANIM_SHELL_TRAP_SETUP, NULL
|
||||
printstring STRINGID_PREPARESHELLTRAP
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
end2
|
||||
end3
|
||||
|
||||
BattleScript_EffectShellTrap::
|
||||
attackcanceler
|
||||
@ -690,7 +690,7 @@ BattleScript_BeakBlastSetUp::
|
||||
playanimation BS_ATTACKER, B_ANIM_BEAK_BLAST_SETUP, NULL
|
||||
printstring STRINGID_HEATUPBEAK
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
end2
|
||||
end3
|
||||
|
||||
BattleScript_BeakBlastBurn::
|
||||
setbyte cMULTISTRING_CHOOSER, 0
|
||||
@ -7918,7 +7918,7 @@ BattleScript_FocusPunchSetUp::
|
||||
playanimation BS_ATTACKER, B_ANIM_FOCUS_PUNCH_SETUP
|
||||
printstring STRINGID_PKMNTIGHTENINGFOCUS
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
end2
|
||||
end3
|
||||
|
||||
BattleScript_MegaEvolution::
|
||||
printstring STRINGID_EMPTYSTRING3
|
||||
@ -7934,7 +7934,7 @@ BattleScript_MegaEvolutionAfterString:
|
||||
printstring STRINGID_MEGAEVOEVOLVED
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
switchinabilities BS_ATTACKER
|
||||
end2
|
||||
end3
|
||||
|
||||
BattleScript_WishMegaEvolution::
|
||||
printstring STRINGID_EMPTYSTRING3
|
||||
@ -9398,8 +9398,8 @@ BattleScript_FriskActivates::
|
||||
end3
|
||||
|
||||
BattleScript_ImposterActivates::
|
||||
transformdataexecution
|
||||
call BattleScript_AbilityPopUp
|
||||
transformdataexecution
|
||||
playmoveanimation BS_ATTACKER, MOVE_TRANSFORM
|
||||
waitanimation
|
||||
printstring STRINGID_IMPOSTERTRANSFORM
|
||||
@ -10749,7 +10749,7 @@ BattleScript_DynamaxBegins::
|
||||
updatedynamax
|
||||
playanimation BS_SCRIPTING, B_ANIM_DYNAMAX_GROWTH
|
||||
waitanimation
|
||||
end
|
||||
end3
|
||||
|
||||
BattleScript_DynamaxEnds::
|
||||
printstring STRINGID_EMPTYSTRING3
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 135 B After Width: | Height: | Size: 195 B |
@ -1,6 +1,6 @@
|
||||
JASC-PAL
|
||||
0100
|
||||
256
|
||||
16
|
||||
152 208 160
|
||||
152 128 80
|
||||
224 176 72
|
||||
@ -17,243 +17,3 @@ JASC-PAL
|
||||
0 88 208
|
||||
56 56 56
|
||||
120 120 120
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
|
||||
@ -525,7 +525,7 @@ struct DynamaxData
|
||||
bool8 playerSelect;
|
||||
u8 triggerSpriteId;
|
||||
u8 indicatorSpriteId[MAX_BATTLERS_COUNT];
|
||||
bool8 toDynamax[MAX_BATTLERS_COUNT];
|
||||
u8 toDynamax; // flags using gBitTable
|
||||
bool8 alreadyDynamaxed[NUM_BATTLE_SIDES];
|
||||
bool8 dynamaxed[MAX_BATTLERS_COUNT];
|
||||
u8 dynamaxTurns[MAX_BATTLERS_COUNT];
|
||||
@ -554,7 +554,7 @@ struct BattleStruct
|
||||
u8 wildVictorySong;
|
||||
u8 dynamicMoveType;
|
||||
u8 wrappedBy[MAX_BATTLERS_COUNT];
|
||||
u8 focusPunchBattlerId;
|
||||
u8 focusPunchBattlers; // as bits
|
||||
u8 battlerPreventingSwitchout;
|
||||
u8 moneyMultiplier:6;
|
||||
u8 moneyMultiplierItem:1;
|
||||
@ -674,6 +674,7 @@ struct BattleStruct
|
||||
u8 attackerBeforeBounce:2;
|
||||
u8 beatUpSlot:3;
|
||||
bool8 hitSwitchTargetFailed:1;
|
||||
bool8 effectsBeforeUsingMoveDone:1; // Mega Evo and Focus Punch/Shell Trap effects.
|
||||
u8 targetsDone[MAX_BATTLERS_COUNT]; // Each battler as a bit.
|
||||
u16 overwrittenAbilities[MAX_BATTLERS_COUNT]; // abilities overwritten during battle (keep separate from battle history in case of switching)
|
||||
bool8 allowedToChangeFormInWeather[PARTY_SIZE][2]; // For each party member and side, used by Ice Face.
|
||||
|
||||
@ -193,7 +193,6 @@ bool32 IsHealBlockPreventingMove(u32 battler, u32 move);
|
||||
bool32 HasEnoughHpToEatBerry(u32 battlerId, u32 hpFraction, u32 itemId);
|
||||
bool32 IsPartnerMonFromSameTrainer(u8 battlerId);
|
||||
u8 GetSplitBasedOnStats(u8 battlerId);
|
||||
void SortBattlersBySpeed(u8 *battlers, bool8 slowToFast);
|
||||
bool32 TestSheerForceFlag(u8 battler, u16 move);
|
||||
void TryRestoreHeldItems(void);
|
||||
bool32 CanStealItem(u8 battlerStealing, u8 battlerItem, u16 item);
|
||||
|
||||
@ -192,7 +192,7 @@
|
||||
|
||||
// Other settings
|
||||
#define B_DOUBLE_WILD_CHANCE 0 // % chance of encountering two Pokémon in a Wild Encounter.
|
||||
#define B_DOUBLE_WILD_REQUIRE_2_MONS FALSE // If set to TRUE, Wild Double Battles will default to Single Battles when the player only has 1 usuable Pokémon, ignoring B_DOUBLE_WILD_CHANCE and B_FLAG_FORCE_DOUBLE_WILD.
|
||||
#define B_DOUBLE_WILD_REQUIRE_2_MONS FALSE // If set to TRUE, Wild Double Battles will default to Single Battles when the player only has 1 usable Pokémon, ignoring B_DOUBLE_WILD_CHANCE and B_FLAG_FORCE_DOUBLE_WILD.
|
||||
#define B_MULTI_BATTLE_WHITEOUT GEN_LATEST // In Gen4+, multi battles end when the Player and also their Partner don't have any more Pokémon to fight.
|
||||
#define B_EVOLUTION_AFTER_WHITEOUT GEN_LATEST // In Gen6+, Pokemon that qualify for evolution after battle will evolve even if the player loses.
|
||||
#define B_WILD_NATURAL_ENEMIES TRUE // If set to TRUE, certain wild mon species will attack other species when partnered in double wild battles (eg. Zangoose vs Seviper)
|
||||
|
||||
@ -241,27 +241,22 @@
|
||||
#define VARIOUS_BATTLER_ITEM_TO_LAST_USED_ITEM 149
|
||||
#define VARIOUS_SET_BEAK_BLAST 150
|
||||
#define VARIOUS_SWAP_SIDE_STATUSES 151
|
||||
#define VARIOUS_SET_Z_EFFECT 152
|
||||
#define VARIOUS_TRY_SYMBIOSIS 153
|
||||
#define VARIOUS_CAN_TELEPORT 154
|
||||
#define VARIOUS_GET_BATTLER_SIDE 155
|
||||
#define VARIOUS_CHECK_PARENTAL_BOND_COUNTER 156
|
||||
#define VARIOUS_SWAP_STATS 157
|
||||
#define VARIOUS_JUMP_IF_ROD 158
|
||||
#define VARIOUS_JUMP_IF_ABSORB 159
|
||||
#define VARIOUS_JUMP_IF_MOTOR 160
|
||||
#define VARIOUS_TEATIME_INVUL 161
|
||||
#define VARIOUS_TEATIME_TARGETS 162
|
||||
#define VARIOUS_TRY_WIND_RIDER_POWER 163
|
||||
#define VARIOUS_ACTIVATE_WEATHER_CHANGE_ABILITIES 164
|
||||
#define VARIOUS_ACTIVATE_TERRAIN_CHANGE_ABILITIES 165
|
||||
#define VARIOUS_JUMP_IF_EMERGENCY_EXITED 166
|
||||
#define VARIOUS_STORE_HEALING_WISH 167
|
||||
#define VARIOUS_HIT_SWITCH_TARGET_FAILED 168
|
||||
#define VARIOUS_JUMP_IF_SHELL_TRAP 169
|
||||
#define VARIOUS_TRY_REVIVAL_BLESSING 170
|
||||
#define VARIOUS_TRY_TRAINER_SLIDE_MSG_Z_MOVE 171
|
||||
#define VARIOUS_TRY_TRAINER_SLIDE_MSG_MEGA_EVOLUTION 172
|
||||
#define VARIOUS_SWAP_STATS 152
|
||||
#define VARIOUS_JUMP_IF_ROD 153
|
||||
#define VARIOUS_JUMP_IF_ABSORB 154
|
||||
#define VARIOUS_JUMP_IF_MOTOR 155
|
||||
#define VARIOUS_TEATIME_INVUL 156
|
||||
#define VARIOUS_TEATIME_TARGETS 157
|
||||
#define VARIOUS_TRY_WIND_RIDER_POWER 158
|
||||
#define VARIOUS_ACTIVATE_WEATHER_CHANGE_ABILITIES 159
|
||||
#define VARIOUS_ACTIVATE_TERRAIN_CHANGE_ABILITIES 160
|
||||
#define VARIOUS_JUMP_IF_EMERGENCY_EXITED 161
|
||||
#define VARIOUS_STORE_HEALING_WISH 162
|
||||
#define VARIOUS_HIT_SWITCH_TARGET_FAILED 163
|
||||
#define VARIOUS_JUMP_IF_SHELL_TRAP 164
|
||||
#define VARIOUS_TRY_REVIVAL_BLESSING 165
|
||||
#define VARIOUS_TRY_TRAINER_SLIDE_MSG_Z_MOVE 166
|
||||
#define VARIOUS_TRY_TRAINER_SLIDE_MSG_MEGA_EVOLUTION 167
|
||||
|
||||
// Cmd_manipulatedamage
|
||||
#define DMG_CHANGE_SIGN 0
|
||||
|
||||
@ -53,7 +53,6 @@
|
||||
#define OBJECT_EVENTS_COUNT 16
|
||||
#define MAIL_COUNT (10 + PARTY_SIZE)
|
||||
#define SECRET_BASES_COUNT 20
|
||||
#define TV_SHOWS_COUNT 25
|
||||
#define POKE_NEWS_COUNT 16
|
||||
#define PC_ITEMS_COUNT 50
|
||||
#define BAG_ITEMS_COUNT 30
|
||||
|
||||
@ -74,6 +74,7 @@
|
||||
// for TV shows from TVGROUP_NORMAL. The remainder are for TV
|
||||
// shows from TVGROUP_RECORD_MIX.
|
||||
#define NUM_NORMAL_TVSHOW_SLOTS 5
|
||||
#define TV_SHOWS_COUNT (NUM_NORMAL_TVSHOW_SLOTS + 20)
|
||||
|
||||
#define PLAYERS_HOUSE_TV_NONE 0
|
||||
#define PLAYERS_HOUSE_TV_LATI 1
|
||||
|
||||
@ -2484,9 +2484,14 @@ void TryShinyAnimation(u8 battler, struct Pokemon *mon)
|
||||
u32 otId, personality;
|
||||
u32 shinyValue;
|
||||
u8 taskCirc, taskDgnl;
|
||||
struct Pokemon* illusionMon;
|
||||
|
||||
isShiny = FALSE;
|
||||
gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = TRUE;
|
||||
illusionMon = GetIllusionMonPtr(battler);
|
||||
if (illusionMon != NULL)
|
||||
mon = illusionMon;
|
||||
|
||||
otId = GetMonData(mon, MON_DATA_OT_ID);
|
||||
personality = GetMonData(mon, MON_DATA_PERSONALITY);
|
||||
|
||||
|
||||
@ -136,7 +136,7 @@ bool32 CanDynamax(u16 battlerId)
|
||||
// Cannot Dynamax if your side has already or will Dynamax.
|
||||
if (gBattleStruct->dynamax.alreadyDynamaxed[GetBattlerSide(battlerId)]
|
||||
|| gBattleStruct->dynamax.dynamaxed[BATTLE_PARTNER(battlerId)]
|
||||
|| gBattleStruct->dynamax.toDynamax[BATTLE_PARTNER(battlerId)])
|
||||
|| gBattleStruct->dynamax.toDynamax & gBitTable[BATTLE_PARTNER(battlerId)])
|
||||
return FALSE;
|
||||
|
||||
// TODO: Cannot Dynamax in a Max Raid if you don't have Dynamax Energy.
|
||||
@ -281,7 +281,7 @@ bool32 ShouldUseMaxMove(u16 battlerId, u16 baseMove)
|
||||
// TODO: Raid bosses do not always use Max Moves.
|
||||
// if (IsRaidBoss(battlerId))
|
||||
// return !IsRaidBossUsingRegularMove(battlerId, baseMove);
|
||||
return IsDynamaxed(battlerId) || gBattleStruct->dynamax.toDynamax[battlerId];
|
||||
return IsDynamaxed(battlerId) || gBattleStruct->dynamax.toDynamax & gBitTable[battlerId];
|
||||
}
|
||||
|
||||
static u16 GetTypeBasedMaxMove(u16 battlerId, u16 type)
|
||||
|
||||
@ -103,7 +103,6 @@ static void UpdateBattlerPartyOrdersOnSwitch(void);
|
||||
static bool8 AllAtActionConfirmed(void);
|
||||
static void TryChangeTurnOrder(void);
|
||||
static void CheckChosenMoveForEffectsBeforeTurnStarts(void);
|
||||
static void CheckMegaEvolutionBeforeTurn(void);
|
||||
static void CheckQuickClaw_CustapBerryActivation(void);
|
||||
static void FreeResetData_ReturnToOvOrDoEvolutions(void);
|
||||
static void ReturnFromBattleToOverworld(void);
|
||||
@ -4324,7 +4323,7 @@ static void HandleTurnActionSelectionState(void)
|
||||
}
|
||||
|
||||
gBattleStruct->mega.toEvolve &= ~(gBitTable[BATTLE_PARTNER(GetBattlerPosition(gActiveBattler))]);
|
||||
gBattleStruct->dynamax.toDynamax[gActiveBattler] = FALSE;
|
||||
gBattleStruct->dynamax.toDynamax &= ~(gBitTable[gActiveBattler]);
|
||||
gBattleStruct->dynamax.usingMaxMove[gActiveBattler] = FALSE;
|
||||
gBattleStruct->zmove.toBeUsed[BATTLE_PARTNER(GetBattlerPosition(gActiveBattler))] = MOVE_NONE;
|
||||
BtlController_EmitEndBounceEffect(BUFFER_A);
|
||||
@ -4412,14 +4411,19 @@ static void HandleTurnActionSelectionState(void)
|
||||
RecordedBattle_SetBattlerAction(gActiveBattler, gBattleResources->bufferB[gActiveBattler][2]);
|
||||
RecordedBattle_SetBattlerAction(gActiveBattler, gBattleResources->bufferB[gActiveBattler][3]);
|
||||
}
|
||||
*(gBattleStruct->chosenMovePositions + gActiveBattler) = gBattleResources->bufferB[gActiveBattler][2] & ~RET_MEGA_EVOLUTION & ~RET_DYNAMAX;
|
||||
gChosenMoveByBattler[gActiveBattler] = gBattleMons[gActiveBattler].moves[*(gBattleStruct->chosenMovePositions + gActiveBattler)];
|
||||
*(gBattleStruct->moveTarget + gActiveBattler) = gBattleResources->bufferB[gActiveBattler][3];
|
||||
// Get the chosen move position (and thus the chosen move) and target from the returned buffer.
|
||||
gBattleStruct->chosenMovePositions[gActiveBattler] = gBattleResources->bufferB[gActiveBattler][2] & ~(RET_MEGA_EVOLUTION | RET_DYNAMAX);
|
||||
gChosenMoveByBattler[gActiveBattler] = gBattleMons[gActiveBattler].moves[gBattleStruct->chosenMovePositions[gActiveBattler]];
|
||||
gBattleStruct->moveTarget[gActiveBattler] = gBattleResources->bufferB[gActiveBattler][3];
|
||||
|
||||
// Check to see if any gimmicks need to be prepared.
|
||||
if (gBattleResources->bufferB[gActiveBattler][2] & RET_MEGA_EVOLUTION)
|
||||
gBattleStruct->mega.toEvolve |= gBitTable[gActiveBattler];
|
||||
else if (gBattleResources->bufferB[gActiveBattler][2] & RET_DYNAMAX)
|
||||
gBattleStruct->dynamax.toDynamax[gActiveBattler] = TRUE;
|
||||
if (ShouldUseMaxMove(gActiveBattler, gChosenMoveByBattler[gActiveBattler])) // max move check
|
||||
gBattleStruct->dynamax.toDynamax |= gBitTable[gActiveBattler];
|
||||
|
||||
// Max Move check
|
||||
if (ShouldUseMaxMove(gActiveBattler, gChosenMoveByBattler[gActiveBattler]))
|
||||
{
|
||||
gBattleStruct->dynamax.baseMove[gActiveBattler] = gBattleMons[gActiveBattler].moves[gBattleStruct->chosenMovePositions[gActiveBattler]];
|
||||
gBattleStruct->dynamax.usingMaxMove[gActiveBattler] = TRUE;
|
||||
@ -4937,9 +4941,6 @@ static void SetActionsAndBattlersTurnOrder(void)
|
||||
turnOrderId++;
|
||||
}
|
||||
}
|
||||
gBattleMainFunc = CheckMegaEvolutionBeforeTurn;
|
||||
gBattleStruct->mega.battlerId = 0;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -4985,8 +4986,8 @@ static void SetActionsAndBattlersTurnOrder(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
gBattleMainFunc = CheckMegaEvolutionBeforeTurn;
|
||||
gBattleStruct->mega.battlerId = 0;
|
||||
gBattleMainFunc = CheckQuickClaw_CustapBerryActivation;
|
||||
gBattleStruct->quickClawBattlerId = 0;
|
||||
}
|
||||
|
||||
static void TurnValuesCleanUp(bool8 var0)
|
||||
@ -5035,60 +5036,110 @@ void SpecialStatusesClear(void)
|
||||
memset(&gSpecialStatuses, 0, sizeof(gSpecialStatuses));
|
||||
}
|
||||
|
||||
// TODO: Rename function to denote use for Dynamax, too.
|
||||
static void CheckMegaEvolutionBeforeTurn(void)
|
||||
static void PopulateArrayWithBattlers(u8 *battlers)
|
||||
{
|
||||
if (!(gHitMarker & HITMARKER_RUN))
|
||||
u32 i;
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
battlers[i] = i;
|
||||
}
|
||||
|
||||
static bool32 TryDoGimmicksBeforeMoves(void)
|
||||
{
|
||||
if (!(gHitMarker & HITMARKER_RUN)
|
||||
&& (gBattleStruct->mega.toEvolve || gBattleStruct->dynamax.toDynamax))
|
||||
{
|
||||
while (gBattleStruct->mega.battlerId < gBattlersCount)
|
||||
u32 i;
|
||||
struct Pokemon *party;
|
||||
struct Pokemon *mon;
|
||||
u8 order[MAX_BATTLERS_COUNT];
|
||||
|
||||
PopulateArrayWithBattlers(order);
|
||||
SortBattlersBySpeed(order, FALSE);
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
gActiveBattler = gBattlerAttacker = gBattleStruct->mega.battlerId;
|
||||
gBattleStruct->mega.battlerId++;
|
||||
// Dynamax Check
|
||||
if (gBattleStruct->dynamax.toDynamax[gActiveBattler])
|
||||
if (gBattleStruct->dynamax.toDynamax & gBitTable[order[i]])
|
||||
{
|
||||
gBattleStruct->dynamax.toDynamax[gActiveBattler] = FALSE;
|
||||
gActiveBattler = gBattlerAttacker = order[i];
|
||||
gBattleScripting.battler = gActiveBattler;
|
||||
gBattleStruct->dynamax.toDynamax &= ~(gBitTable[gActiveBattler]);
|
||||
PrepareBattlerForDynamax(gActiveBattler);
|
||||
BattleScriptExecute(BattleScript_DynamaxBegins);
|
||||
return;
|
||||
return TRUE;
|
||||
}
|
||||
// Mega Evo Check
|
||||
if (gBattleStruct->mega.toEvolve & gBitTable[gActiveBattler]
|
||||
&& !(gProtectStructs[gActiveBattler].noValidMoves))
|
||||
if (gBattleStruct->mega.toEvolve & gBitTable[order[i]]
|
||||
&& !(gProtectStructs[order[i]].noValidMoves))
|
||||
{
|
||||
struct Pokemon *party = GetBattlerParty(gActiveBattler);
|
||||
struct Pokemon *mon = &party[gBattlerPartyIndexes[gActiveBattler]];
|
||||
|
||||
gActiveBattler = gBattlerAttacker = order[i];
|
||||
gBattleStruct->mega.toEvolve &= ~(gBitTable[gActiveBattler]);
|
||||
gLastUsedItem = gBattleMons[gActiveBattler].item;
|
||||
party = GetBattlerParty(gActiveBattler);
|
||||
mon = &party[gBattlerPartyIndexes[gActiveBattler]];
|
||||
if (GetBattleFormChangeTargetSpecies(gActiveBattler, FORM_CHANGE_BATTLE_MEGA_EVOLUTION_MOVE) != SPECIES_NONE)
|
||||
BattleScriptExecute(BattleScript_WishMegaEvolution);
|
||||
else
|
||||
BattleScriptExecute(BattleScript_MegaEvolution);
|
||||
return;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if B_MEGA_EVO_TURN_ORDER <= GEN_6
|
||||
gBattleMainFunc = CheckChosenMoveForEffectsBeforeTurnStarts;
|
||||
gBattleStruct->focusPunchBattlerId = 0;
|
||||
#else
|
||||
gBattleMainFunc = TryChangeTurnOrder; // This will just do nothing if no mon has mega evolved
|
||||
#if B_MEGA_EVO_TURN_ORDER >= GEN_7
|
||||
TryChangeTurnOrder(); // This will just do nothing if no mon has mega evolved.
|
||||
#endif
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static bool32 TryDoMoveEffectsBeforeMoves(void)
|
||||
{
|
||||
if (!(gHitMarker & HITMARKER_RUN))
|
||||
{
|
||||
u32 i;
|
||||
struct Pokemon *mon;
|
||||
u8 battlers[MAX_BATTLERS_COUNT];
|
||||
|
||||
PopulateArrayWithBattlers(battlers);
|
||||
SortBattlersBySpeed(battlers, FALSE);
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
if (!(gBattleStruct->focusPunchBattlers & gBitTable[battlers[i]])
|
||||
&& !(gBattleMons[battlers[i]].status1 & STATUS1_SLEEP)
|
||||
&& !(gDisableStructs[battlers[i]].truantCounter)
|
||||
&& !(gProtectStructs[battlers[i]].noValidMoves))
|
||||
{
|
||||
gBattleStruct->focusPunchBattlers |= gBitTable[battlers[i]];
|
||||
gActiveBattler = gBattlerAttacker = battlers[i];
|
||||
switch (gChosenMoveByBattler[gActiveBattler])
|
||||
{
|
||||
case MOVE_FOCUS_PUNCH:
|
||||
BattleScriptExecute(BattleScript_FocusPunchSetUp);
|
||||
return TRUE;
|
||||
case MOVE_BEAK_BLAST:
|
||||
BattleScriptExecute(BattleScript_BeakBlastSetUp);
|
||||
return TRUE;
|
||||
case MOVE_SHELL_TRAP:
|
||||
BattleScriptExecute(BattleScript_ShellTrapSetUp);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// In gen7, priority and speed are recalculated during the turn in which a pokemon mega evolves
|
||||
static void TryChangeTurnOrder(void)
|
||||
{
|
||||
s32 i, j;
|
||||
u32 i, j;
|
||||
for (i = 0; i < gBattlersCount - 1; i++)
|
||||
{
|
||||
for (j = i + 1; j < gBattlersCount; j++)
|
||||
{
|
||||
u8 battler1 = gBattlerByTurnOrder[i];
|
||||
u8 battler2 = gBattlerByTurnOrder[j];
|
||||
u32 battler1 = gBattlerByTurnOrder[i];
|
||||
u32 battler2 = gBattlerByTurnOrder[j];
|
||||
|
||||
if (gActionsByTurnOrder[i] == B_ACTION_USE_MOVE
|
||||
&& gActionsByTurnOrder[j] == B_ACTION_USE_MOVE)
|
||||
{
|
||||
@ -5097,42 +5148,6 @@ static void TryChangeTurnOrder(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
gBattleMainFunc = CheckChosenMoveForEffectsBeforeTurnStarts;
|
||||
gBattleStruct->focusPunchBattlerId = 0;
|
||||
}
|
||||
|
||||
static void CheckChosenMoveForEffectsBeforeTurnStarts(void)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
if (!(gHitMarker & HITMARKER_RUN))
|
||||
{
|
||||
while (gBattleStruct->focusPunchBattlerId < gBattlersCount)
|
||||
{
|
||||
gActiveBattler = gBattlerAttacker = gBattleStruct->focusPunchBattlerId;
|
||||
gBattleStruct->focusPunchBattlerId++;
|
||||
if (!(gBattleMons[gActiveBattler].status1 & STATUS1_SLEEP)
|
||||
&& !(gDisableStructs[gBattlerAttacker].truantCounter)
|
||||
&& !(gProtectStructs[gActiveBattler].noValidMoves))
|
||||
{
|
||||
switch (gChosenMoveByBattler[gActiveBattler])
|
||||
{
|
||||
case MOVE_FOCUS_PUNCH:
|
||||
BattleScriptExecute(BattleScript_FocusPunchSetUp);
|
||||
return;
|
||||
case MOVE_BEAK_BLAST:
|
||||
BattleScriptExecute(BattleScript_BeakBlastSetUp);
|
||||
return;
|
||||
case MOVE_SHELL_TRAP:
|
||||
BattleScriptExecute(BattleScript_ShellTrapSetUp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gBattleMainFunc = CheckQuickClaw_CustapBerryActivation;
|
||||
gBattleStruct->quickClawBattlerId = 0;
|
||||
}
|
||||
|
||||
static void CheckQuickClaw_CustapBerryActivation(void)
|
||||
@ -5187,6 +5202,8 @@ static void CheckQuickClaw_CustapBerryActivation(void)
|
||||
gCurrentTurnActionNumber = 0;
|
||||
gCurrentActionFuncId = gActionsByTurnOrder[0];
|
||||
gBattleStruct->dynamicMoveType = 0;
|
||||
gBattleStruct->effectsBeforeUsingMoveDone = FALSE;
|
||||
gBattleStruct->focusPunchBattlers = 0;
|
||||
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
|
||||
{
|
||||
gBattleStruct->ateBoost[i] = FALSE;
|
||||
@ -5205,6 +5222,16 @@ static void RunTurnActionsFunctions(void)
|
||||
if (gBattleOutcome != 0)
|
||||
gCurrentActionFuncId = B_ACTION_FINISHED;
|
||||
|
||||
// Mega Evolve / Focus Punch-like moves after switching, items, running, but before using a move.
|
||||
if (gCurrentActionFuncId == B_ACTION_USE_MOVE && !gBattleStruct->effectsBeforeUsingMoveDone)
|
||||
{
|
||||
if (TryDoGimmicksBeforeMoves())
|
||||
return;
|
||||
else if (TryDoMoveEffectsBeforeMoves())
|
||||
return;
|
||||
gBattleStruct->effectsBeforeUsingMoveDone = TRUE;
|
||||
}
|
||||
|
||||
*(&gBattleStruct->savedTurnActionNumber) = gCurrentTurnActionNumber;
|
||||
sTurnActionsFuncsTable[gCurrentActionFuncId]();
|
||||
|
||||
|
||||
@ -3119,7 +3119,11 @@ static const u8 *BattleStringGetPlayerName(u8 *text, u8 battlerId)
|
||||
toCpy = gSaveBlock2Ptr->playerName;
|
||||
break;
|
||||
case B_POSITION_PLAYER_RIGHT:
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_LINK && gBattleTypeFlags & (BATTLE_TYPE_RECORDED | BATTLE_TYPE_MULTI))
|
||||
if ((gBattleTypeFlags & BATTLE_TYPE_RECORDED) && !(gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_INGAME_PARTNER)))
|
||||
{
|
||||
toCpy = gLinkPlayers[0].name;
|
||||
}
|
||||
else if ((gBattleTypeFlags & BATTLE_TYPE_LINK) && gBattleTypeFlags & (BATTLE_TYPE_RECORDED | BATTLE_TYPE_MULTI))
|
||||
{
|
||||
toCpy = gLinkPlayers[2].name;
|
||||
}
|
||||
|
||||
@ -5567,6 +5567,9 @@ static void Cmd_moveend(void)
|
||||
{
|
||||
gProtectStructs[gBattlerAttacker].touchedProtectLike = FALSE;
|
||||
gBattleMons[gBattlerAttacker].status1 = STATUS1_BURN;
|
||||
gActiveBattler = gBattlerAttacker;
|
||||
BtlController_EmitSetMonData(BUFFER_A, REQUEST_STATUS_BATTLE, 0, sizeof(gBattleMons[gActiveBattler].status1), &gBattleMons[gActiveBattler].status1);
|
||||
MarkBattlerForControllerExec(gActiveBattler);
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_BeakBlastBurn;
|
||||
effect = 1;
|
||||
@ -10360,12 +10363,6 @@ static void Cmd_various(void)
|
||||
}
|
||||
return;
|
||||
}
|
||||
case VARIOUS_SET_Z_EFFECT:
|
||||
{
|
||||
VARIOUS_ARGS();
|
||||
SetZEffect(); //handles battle script jumping internally
|
||||
return;
|
||||
}
|
||||
case VARIOUS_MOVEEND_ITEM_EFFECTS:
|
||||
{
|
||||
VARIOUS_ARGS();
|
||||
@ -11044,48 +11041,6 @@ static void Cmd_various(void)
|
||||
CourtChangeSwapSideStatuses();
|
||||
break;
|
||||
}
|
||||
case VARIOUS_TRY_SYMBIOSIS: //called by Bestow, Fling, and Bug Bite, which don't work with Cmd_removeitem.
|
||||
{
|
||||
VARIOUS_ARGS();
|
||||
if (SYMBIOSIS_CHECK(gActiveBattler, BATTLE_PARTNER(gActiveBattler)))
|
||||
{
|
||||
BestowItem(BATTLE_PARTNER(gActiveBattler), gActiveBattler);
|
||||
gLastUsedAbility = gBattleMons[BATTLE_PARTNER(gActiveBattler)].ability;
|
||||
gBattleScripting.battler = gBattlerAbility = BATTLE_PARTNER(gActiveBattler);
|
||||
gBattlerAttacker = gActiveBattler;
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_SymbiosisActivates;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VARIOUS_CAN_TELEPORT:
|
||||
{
|
||||
VARIOUS_ARGS();
|
||||
gBattleCommunication[0] = CanTeleport(gActiveBattler);
|
||||
break;
|
||||
}
|
||||
case VARIOUS_GET_BATTLER_SIDE:
|
||||
{
|
||||
VARIOUS_ARGS();
|
||||
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
|
||||
gBattleCommunication[0] = B_SIDE_PLAYER;
|
||||
else
|
||||
gBattleCommunication[0] = B_SIDE_OPPONENT;
|
||||
break;
|
||||
}
|
||||
case VARIOUS_CHECK_PARENTAL_BOND_COUNTER:
|
||||
{
|
||||
VARIOUS_ARGS(u8 counter, const u8 *jumpInstr);
|
||||
// Some effects should only happen on the first or second strike of Parental Bond,
|
||||
// so a way to check this in battle scripts is useful
|
||||
u8 counter = cmd->counter;
|
||||
if (gSpecialStatuses[gBattlerAttacker].parentalBondState == counter && gBattleMons[gBattlerTarget].hp != 0)
|
||||
gBattlescriptCurrInstr = cmd->jumpInstr;
|
||||
else
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
return;
|
||||
}
|
||||
case VARIOUS_SWAP_STATS:
|
||||
{
|
||||
VARIOUS_ARGS(u8 stat);
|
||||
@ -16436,6 +16391,55 @@ static bool8 IsFinalStrikeEffect(u16 move)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void BS_CheckParentalBondCounter(void)
|
||||
{
|
||||
NATIVE_ARGS(u8 counter, const u8 *jumpInstr);
|
||||
// Some effects should only happen on the first or second strike of Parental Bond,
|
||||
// so a way to check this in battle scripts is useful
|
||||
if (gSpecialStatuses[gBattlerAttacker].parentalBondState == cmd->counter && gBattleMons[gBattlerTarget].hp != 0)
|
||||
gBattlescriptCurrInstr = cmd->jumpInstr;
|
||||
else
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
||||
void BS_GetBattlerSide(void)
|
||||
{
|
||||
NATIVE_ARGS(u8 battler);
|
||||
gBattleCommunication[0] = GetBattlerSide(cmd->battler);
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
||||
void BS_CanTeleport(void)
|
||||
{
|
||||
NATIVE_ARGS(u8 battler);
|
||||
gBattleCommunication[0] = CanTeleport(cmd->battler);
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
||||
void BS_TrySymbiosis(void)
|
||||
{
|
||||
NATIVE_ARGS();
|
||||
//called by Bestow, Fling, and Bug Bite, which don't work with Cmd_removeitem.
|
||||
gActiveBattler = gBattlerAttacker;
|
||||
if (SYMBIOSIS_CHECK(gBattlerAttacker, BATTLE_PARTNER(gActiveBattler)))
|
||||
{
|
||||
BestowItem(BATTLE_PARTNER(gActiveBattler), gActiveBattler);
|
||||
gLastUsedAbility = gBattleMons[BATTLE_PARTNER(gActiveBattler)].ability;
|
||||
gBattleScripting.battler = gBattlerAbility = BATTLE_PARTNER(gActiveBattler);
|
||||
gBattlerAttacker = gActiveBattler;
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_SymbiosisActivates;
|
||||
return;
|
||||
}
|
||||
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
||||
void BS_SetZEffect(void)
|
||||
{
|
||||
SetZEffect(); // Handles battle script jumping internally
|
||||
}
|
||||
|
||||
static void TryUpdateRoundTurnOrder(void)
|
||||
{
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
|
||||
|
||||
@ -1606,7 +1606,8 @@ void BattleScriptPushCursor(void)
|
||||
|
||||
void BattleScriptPop(void)
|
||||
{
|
||||
gBattlescriptCurrInstr = gBattleResources->battleScriptsStack->ptr[--gBattleResources->battleScriptsStack->size];
|
||||
if (gBattleResources->battleScriptsStack->size != 0)
|
||||
gBattlescriptCurrInstr = gBattleResources->battleScriptsStack->ptr[--gBattleResources->battleScriptsStack->size];
|
||||
}
|
||||
|
||||
static bool32 IsGravityPreventingMove(u32 move)
|
||||
@ -8185,8 +8186,6 @@ u8 IsMonDisobedient(void)
|
||||
if (!IsOtherTrainer(gBattleMons[gBattlerAttacker].otId, gBattleMons[gBattlerAttacker].otName))
|
||||
levelReferenced = gBattleMons[gBattlerAttacker].metLevel;
|
||||
else
|
||||
#else
|
||||
if (gBattleMons[gBattlerAttacker].level <= obedienceLevel)
|
||||
#endif
|
||||
levelReferenced = gBattleMons[gBattlerAttacker].level;
|
||||
|
||||
@ -10486,12 +10485,19 @@ bool32 SetIllusionMon(struct Pokemon *mon, u32 battlerId)
|
||||
{
|
||||
struct Pokemon *party, *partnerMon;
|
||||
s32 i, id;
|
||||
u8 side, partyCount;
|
||||
|
||||
gBattleStruct->illusion[battlerId].set = 1;
|
||||
if (GetMonAbility(mon) != ABILITY_ILLUSION)
|
||||
return FALSE;
|
||||
|
||||
party = GetBattlerParty(battlerId);
|
||||
side = GetBattlerSide(battlerId);
|
||||
partyCount = side == B_SIDE_PLAYER ? gPlayerPartyCount : gEnemyPartyCount;
|
||||
|
||||
// If this pokemon is last in the party, ignore Illusion.
|
||||
if (&party[partyCount - 1] == mon)
|
||||
return FALSE;
|
||||
|
||||
if (IsBattlerAlive(BATTLE_PARTNER(battlerId)))
|
||||
partnerMon = &party[gBattlerPartyIndexes[BATTLE_PARTNER(battlerId)]];
|
||||
@ -10733,7 +10739,7 @@ bool32 IsEntrainmentTargetOrSimpleBeamBannedAbility(u16 ability)
|
||||
void SortBattlersBySpeed(u8 *battlers, bool8 slowToFast)
|
||||
{
|
||||
int i, j, currSpeed, currBattler;
|
||||
u16 speeds[4] = {0};
|
||||
u16 speeds[MAX_BATTLERS_COUNT] = {0};
|
||||
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
speeds[i] = GetBattlerTotalSpeedStat(battlers[i]);
|
||||
|
||||
@ -585,7 +585,7 @@ const u8 *GetZMoveName(u16 move)
|
||||
return gZMoveNames[0]; // Failsafe
|
||||
}
|
||||
|
||||
#define Z_EFFECT_BS_LENGTH 3
|
||||
#define Z_EFFECT_BS_LENGTH 5
|
||||
// This function kinda cheats by setting a return battle script to after the setzeffect various command
|
||||
// and then jumping to a z effect script
|
||||
void SetZEffect(void)
|
||||
@ -676,7 +676,7 @@ void SetZEffect(void)
|
||||
gBattlescriptCurrInstr = BattleScript_StatUpZMove;
|
||||
break;
|
||||
default:
|
||||
gBattlescriptCurrInstr += 3;
|
||||
gBattlescriptCurrInstr += Z_EFFECT_BS_LENGTH;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@ -12699,12 +12699,13 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
|
||||
{
|
||||
#if B_UPDATED_MOVE_DATA >= GEN_9
|
||||
.power = 80,
|
||||
.accuracy = 100,
|
||||
#else
|
||||
.power = 75,
|
||||
.accuracy = 90,
|
||||
#endif
|
||||
.effect = EFFECT_SPEED_UP_HIT,
|
||||
.type = TYPE_PSYCHIC,
|
||||
.accuracy = 90,
|
||||
.pp = 10,
|
||||
.secondaryEffectChance = 100,
|
||||
.target = MOVE_TARGET_SELECTED,
|
||||
|
||||
@ -2327,7 +2327,7 @@ static void DebugAction_Give_Pokemon_SelectNature(u8 taskId)
|
||||
}
|
||||
static void DebugAction_Give_Pokemon_SelectAbility(u8 taskId)
|
||||
{
|
||||
u8 abilityId;
|
||||
u16 abilityId;
|
||||
u8 abilityCount = NUM_ABILITY_SLOTS - 1; //-1 for proper iteration
|
||||
u8 i = 0;
|
||||
|
||||
|
||||
@ -2576,7 +2576,7 @@ bool8 MovementType_WanderAround_Step2(struct ObjectEvent *objectEvent, struct Sp
|
||||
{
|
||||
if (!ObjectEventExecSingleMovementAction(objectEvent, sprite))
|
||||
return FALSE;
|
||||
SetMovementDelay(sprite, sMovementDelaysMedium[Random() & 3]);
|
||||
SetMovementDelay(sprite, sMovementDelaysMedium[Random() % ARRAY_COUNT(sMovementDelaysMedium)]);
|
||||
sprite->sTypeFuncId = 3;
|
||||
return TRUE;
|
||||
}
|
||||
@ -2856,7 +2856,7 @@ bool8 MovementType_LookAround_Step2(struct ObjectEvent *objectEvent, struct Spri
|
||||
{
|
||||
if (ObjectEventExecSingleMovementAction(objectEvent, sprite))
|
||||
{
|
||||
SetMovementDelay(sprite, sMovementDelaysMedium[Random() & 3]);
|
||||
SetMovementDelay(sprite, sMovementDelaysMedium[Random() % ARRAY_COUNT(sMovementDelaysMedium)]);
|
||||
objectEvent->singleMovementActive = FALSE;
|
||||
sprite->sTypeFuncId = 3;
|
||||
}
|
||||
@ -2908,7 +2908,7 @@ bool8 MovementType_WanderUpAndDown_Step2(struct ObjectEvent *objectEvent, struct
|
||||
if (!ObjectEventExecSingleMovementAction(objectEvent, sprite))
|
||||
return FALSE;
|
||||
|
||||
SetMovementDelay(sprite, sMovementDelaysMedium[Random() & 3]);
|
||||
SetMovementDelay(sprite, sMovementDelaysMedium[Random() % ARRAY_COUNT(sMovementDelaysMedium)]);
|
||||
sprite->sTypeFuncId = 3;
|
||||
return TRUE;
|
||||
}
|
||||
@ -2976,7 +2976,7 @@ bool8 MovementType_WanderLeftAndRight_Step2(struct ObjectEvent *objectEvent, str
|
||||
if (!ObjectEventExecSingleMovementAction(objectEvent, sprite))
|
||||
return FALSE;
|
||||
|
||||
SetMovementDelay(sprite, sMovementDelaysMedium[Random() & 3]);
|
||||
SetMovementDelay(sprite, sMovementDelaysMedium[Random() % ARRAY_COUNT(sMovementDelaysMedium)]);
|
||||
sprite->sTypeFuncId = 3;
|
||||
return TRUE;
|
||||
}
|
||||
@ -3196,7 +3196,7 @@ bool8 MovementType_FaceDownAndUp_Step2(struct ObjectEvent *objectEvent, struct S
|
||||
{
|
||||
if (ObjectEventExecSingleMovementAction(objectEvent, sprite))
|
||||
{
|
||||
SetMovementDelay(sprite, sMovementDelaysMedium[Random() & 3]);
|
||||
SetMovementDelay(sprite, sMovementDelaysMedium[Random() % ARRAY_COUNT(sMovementDelaysMedium)]);
|
||||
objectEvent->singleMovementActive = FALSE;
|
||||
sprite->sTypeFuncId = 3;
|
||||
}
|
||||
@ -3246,7 +3246,7 @@ bool8 MovementType_FaceLeftAndRight_Step2(struct ObjectEvent *objectEvent, struc
|
||||
{
|
||||
if (ObjectEventExecSingleMovementAction(objectEvent, sprite))
|
||||
{
|
||||
SetMovementDelay(sprite, sMovementDelaysMedium[Random() & 3]);
|
||||
SetMovementDelay(sprite, sMovementDelaysMedium[Random() % ARRAY_COUNT(sMovementDelaysMedium)]);
|
||||
objectEvent->singleMovementActive = FALSE;
|
||||
sprite->sTypeFuncId = 3;
|
||||
}
|
||||
@ -3296,7 +3296,7 @@ bool8 MovementType_FaceUpAndLeft_Step2(struct ObjectEvent *objectEvent, struct S
|
||||
{
|
||||
if (ObjectEventExecSingleMovementAction(objectEvent, sprite))
|
||||
{
|
||||
SetMovementDelay(sprite, sMovementDelaysShort[Random() & 3]);
|
||||
SetMovementDelay(sprite, sMovementDelaysShort[Random() % ARRAY_COUNT(sMovementDelaysShort)]);
|
||||
objectEvent->singleMovementActive = FALSE;
|
||||
sprite->sTypeFuncId = 3;
|
||||
}
|
||||
@ -3346,7 +3346,7 @@ bool8 MovementType_FaceUpAndRight_Step2(struct ObjectEvent *objectEvent, struct
|
||||
{
|
||||
if (ObjectEventExecSingleMovementAction(objectEvent, sprite))
|
||||
{
|
||||
SetMovementDelay(sprite, sMovementDelaysShort[Random() & 3]);
|
||||
SetMovementDelay(sprite, sMovementDelaysShort[Random() % ARRAY_COUNT(sMovementDelaysShort)]);
|
||||
objectEvent->singleMovementActive = FALSE;
|
||||
sprite->sTypeFuncId = 3;
|
||||
}
|
||||
@ -3396,7 +3396,7 @@ bool8 MovementType_FaceDownAndLeft_Step2(struct ObjectEvent *objectEvent, struct
|
||||
{
|
||||
if (ObjectEventExecSingleMovementAction(objectEvent, sprite))
|
||||
{
|
||||
SetMovementDelay(sprite, sMovementDelaysShort[Random() & 3]);
|
||||
SetMovementDelay(sprite, sMovementDelaysShort[Random() % ARRAY_COUNT(sMovementDelaysShort)]);
|
||||
objectEvent->singleMovementActive = FALSE;
|
||||
sprite->sTypeFuncId = 3;
|
||||
}
|
||||
@ -3446,7 +3446,7 @@ bool8 MovementType_FaceDownAndRight_Step2(struct ObjectEvent *objectEvent, struc
|
||||
{
|
||||
if (ObjectEventExecSingleMovementAction(objectEvent, sprite))
|
||||
{
|
||||
SetMovementDelay(sprite, sMovementDelaysShort[Random() & 3]);
|
||||
SetMovementDelay(sprite, sMovementDelaysShort[Random() % ARRAY_COUNT(sMovementDelaysShort)]);
|
||||
objectEvent->singleMovementActive = FALSE;
|
||||
sprite->sTypeFuncId = 3;
|
||||
}
|
||||
@ -3496,7 +3496,7 @@ bool8 MovementType_FaceDownUpAndLeft_Step2(struct ObjectEvent *objectEvent, stru
|
||||
{
|
||||
if (ObjectEventExecSingleMovementAction(objectEvent, sprite))
|
||||
{
|
||||
SetMovementDelay(sprite, sMovementDelaysShort[Random() & 3]);
|
||||
SetMovementDelay(sprite, sMovementDelaysShort[Random() % ARRAY_COUNT(sMovementDelaysShort)]);
|
||||
objectEvent->singleMovementActive = FALSE;
|
||||
sprite->sTypeFuncId = 3;
|
||||
}
|
||||
@ -3546,7 +3546,7 @@ bool8 MovementType_FaceDownUpAndRight_Step2(struct ObjectEvent *objectEvent, str
|
||||
{
|
||||
if (ObjectEventExecSingleMovementAction(objectEvent, sprite))
|
||||
{
|
||||
SetMovementDelay(sprite, sMovementDelaysShort[Random() & 3]);
|
||||
SetMovementDelay(sprite, sMovementDelaysShort[Random() % ARRAY_COUNT(sMovementDelaysShort)]);
|
||||
objectEvent->singleMovementActive = FALSE;
|
||||
sprite->sTypeFuncId = 3;
|
||||
}
|
||||
@ -3596,7 +3596,7 @@ bool8 MovementType_FaceUpLeftAndRight_Step2(struct ObjectEvent *objectEvent, str
|
||||
{
|
||||
if (ObjectEventExecSingleMovementAction(objectEvent, sprite))
|
||||
{
|
||||
SetMovementDelay(sprite, sMovementDelaysShort[Random() & 3]);
|
||||
SetMovementDelay(sprite, sMovementDelaysShort[Random() % ARRAY_COUNT(sMovementDelaysShort)]);
|
||||
objectEvent->singleMovementActive = FALSE;
|
||||
sprite->sTypeFuncId = 3;
|
||||
}
|
||||
@ -3646,7 +3646,7 @@ bool8 MovementType_FaceDownLeftAndRight_Step2(struct ObjectEvent *objectEvent, s
|
||||
{
|
||||
if (ObjectEventExecSingleMovementAction(objectEvent, sprite))
|
||||
{
|
||||
SetMovementDelay(sprite, sMovementDelaysShort[Random() & 3]);
|
||||
SetMovementDelay(sprite, sMovementDelaysShort[Random() % ARRAY_COUNT(sMovementDelaysShort)]);
|
||||
objectEvent->singleMovementActive = FALSE;
|
||||
sprite->sTypeFuncId = 3;
|
||||
}
|
||||
|
||||
@ -249,7 +249,7 @@ static const struct ListMenuTemplate sItemListMenu =
|
||||
.itemPrintFunc = BagMenu_ItemPrintCallback,
|
||||
.totalItems = 0,
|
||||
.maxShowed = 0,
|
||||
.windowId = 0,
|
||||
.windowId = WIN_ITEM_LIST,
|
||||
.header_X = 0,
|
||||
.item_X = 8,
|
||||
.cursor_X = 0,
|
||||
|
||||
@ -1284,23 +1284,34 @@ static void PlayAmbientCry(void)
|
||||
PlayCry_NormalNoDucking(sAmbientCrySpecies, pan, volume, CRY_PRIORITY_AMBIENT);
|
||||
}
|
||||
|
||||
// States for UpdateAmbientCry
|
||||
enum {
|
||||
AMB_CRY_INIT,
|
||||
AMB_CRY_FIRST,
|
||||
AMB_CRY_RESET,
|
||||
AMB_CRY_WAIT,
|
||||
AMB_CRY_IDLE,
|
||||
};
|
||||
|
||||
void UpdateAmbientCry(s16 *state, u16 *delayCounter)
|
||||
{
|
||||
u8 i, monsCount, divBy;
|
||||
|
||||
switch (*state)
|
||||
{
|
||||
case 0:
|
||||
case AMB_CRY_INIT:
|
||||
// This state will be revisited whenever ResetFieldTasksArgs is called (which happens on map transition)
|
||||
if (sAmbientCrySpecies == SPECIES_NONE)
|
||||
*state = 4;
|
||||
*state = AMB_CRY_IDLE;
|
||||
else
|
||||
*state = 1;
|
||||
*state = AMB_CRY_FIRST;
|
||||
break;
|
||||
case 1:
|
||||
case AMB_CRY_FIRST:
|
||||
// It takes between 1200-3599 frames (~20-60 seconds) to play the first ambient cry after entering a map
|
||||
*delayCounter = (Random() % 2400) + 1200;
|
||||
*state = 3;
|
||||
*state = AMB_CRY_WAIT;
|
||||
break;
|
||||
case 2:
|
||||
case AMB_CRY_RESET:
|
||||
divBy = 1;
|
||||
monsCount = CalculatePlayerPartyCount();
|
||||
for (i = 0; i < monsCount; i++)
|
||||
@ -1312,18 +1323,20 @@ void UpdateAmbientCry(s16 *state, u16 *delayCounter)
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Ambient cries after the first one take between 1200-2399 frames (~20-40 seconds)
|
||||
// If the player has a pokemon with the ability Swarm in their party, the time is halved to 600-1199 frames (~10-20 seconds)
|
||||
*delayCounter = ((Random() % 1200) + 1200) / divBy;
|
||||
*state = 3;
|
||||
*state = AMB_CRY_WAIT;
|
||||
break;
|
||||
case 3:
|
||||
(*delayCounter)--;
|
||||
if (*delayCounter == 0)
|
||||
case AMB_CRY_WAIT:
|
||||
if (--(*delayCounter) == 0)
|
||||
{
|
||||
PlayAmbientCry();
|
||||
*state = 2;
|
||||
*state = AMB_CRY_RESET;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
case AMB_CRY_IDLE:
|
||||
// No land/water pokemon on this map
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4663,7 +4663,6 @@ void Task_AbilityPatch(u8 taskId)
|
||||
// Can't use.
|
||||
if (gSpeciesInfo[tSpecies].abilities[tAbilityNum] == 0
|
||||
|| !tSpecies
|
||||
|| GetMonData(&gPlayerParty[tMonId], MON_DATA_ABILITY_NUM, NULL) > 1
|
||||
)
|
||||
{
|
||||
gPartyMenuUseExitCallback = FALSE;
|
||||
@ -4734,7 +4733,10 @@ void ItemUseCB_AbilityPatch(u8 taskId, TaskFunc task)
|
||||
tState = 0;
|
||||
tMonId = gPartyMenu.slotId;
|
||||
tSpecies = GetMonData(&gPlayerParty[tMonId], MON_DATA_SPECIES, NULL);
|
||||
tAbilityNum = 2;
|
||||
if (GetMonData(&gPlayerParty[tMonId], MON_DATA_ABILITY_NUM, NULL) == 2)
|
||||
tAbilityNum = 0;
|
||||
else
|
||||
tAbilityNum = 2;
|
||||
SetWordTaskArg(taskId, tOldFunc, (uintptr_t)(gTasks[taskId].func));
|
||||
gTasks[taskId].func = Task_AbilityPatch;
|
||||
}
|
||||
|
||||
@ -172,12 +172,12 @@ void CreateScriptedDoubleWildMon(u16 species1, u8 level1, u16 item1, u16 species
|
||||
SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, heldItem1);
|
||||
}
|
||||
|
||||
CreateMon(&gEnemyParty[3], species2, level2, 32, 0, 0, OT_ID_PLAYER_ID, 0);
|
||||
CreateMon(&gEnemyParty[1], species2, level2, 32, 0, 0, OT_ID_PLAYER_ID, 0);
|
||||
if (item2)
|
||||
{
|
||||
heldItem2[0] = item2;
|
||||
heldItem2[1] = item2 >> 8;
|
||||
SetMonData(&gEnemyParty[3], MON_DATA_HELD_ITEM, heldItem2);
|
||||
SetMonData(&gEnemyParty[1], MON_DATA_HELD_ITEM, heldItem2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -17,6 +17,44 @@ SINGLE_BATTLE_TEST("Venusaur can Mega Evolve holding Venusaurite")
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Mega Evolution's order is determined by Speed - opponent faster")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_VENUSAUR) { Item(ITEM_VENUSAURITE); Speed(1); }
|
||||
PLAYER(SPECIES_WOBBUFFET) { Speed(3);}
|
||||
OPPONENT(SPECIES_GARDEVOIR) { Item(ITEM_GARDEVOIRITE); Speed(3);}
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(4);}
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentLeft, MOVE_CELEBRATE, megaEvolve: TRUE); MOVE(playerLeft, MOVE_CELEBRATE, megaEvolve: TRUE); }
|
||||
} SCENE {
|
||||
MESSAGE("Foe Gardevoir's Gardevoirite is reacting to 's Mega Ring!");
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_MEGA_EVOLUTION, opponentLeft);
|
||||
MESSAGE("Foe Gardevoir has Mega Evolved into Mega Gardevoir!");
|
||||
MESSAGE("Venusaur's Venusaurite is reacting to 1's Mega Ring!");
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_MEGA_EVOLUTION, playerLeft);
|
||||
MESSAGE("Venusaur has Mega Evolved into Mega Venusaur!");
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Mega Evolution's order is determined by Speed - player faster")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_VENUSAUR) { Item(ITEM_VENUSAURITE); Speed(5); }
|
||||
PLAYER(SPECIES_WOBBUFFET) { Speed(3);}
|
||||
OPPONENT(SPECIES_GARDEVOIR) { Item(ITEM_GARDEVOIRITE); Speed(2);}
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(4);}
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentLeft, MOVE_CELEBRATE, megaEvolve: TRUE); MOVE(playerLeft, MOVE_CELEBRATE, megaEvolve: TRUE); }
|
||||
} SCENE {
|
||||
MESSAGE("Venusaur's Venusaurite is reacting to 1's Mega Ring!");
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_MEGA_EVOLUTION, playerLeft);
|
||||
MESSAGE("Venusaur has Mega Evolved into Mega Venusaur!");
|
||||
MESSAGE("Foe Gardevoir's Gardevoirite is reacting to 's Mega Ring!");
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_MEGA_EVOLUTION, opponentLeft);
|
||||
MESSAGE("Foe Gardevoir has Mega Evolved into Mega Gardevoir!");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Rayquaza can Mega Evolve knowing Dragon Ascent")
|
||||
{
|
||||
GIVEN {
|
||||
@ -66,3 +104,52 @@ SINGLE_BATTLE_TEST("Abilities replaced by Mega Evolution do not affect turn orde
|
||||
ASSUME(player->speed == 45);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Mega Evolution happens after switching, but before Focus Punch-like Moves")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gBattleMoves[MOVE_FOCUS_PUNCH].effect == EFFECT_FOCUS_PUNCH);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_VENUSAUR) { Item(ITEM_VENUSAURITE);}
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { SWITCH(opponentRight, 2); MOVE(playerRight, MOVE_FOCUS_PUNCH, megaEvolve: TRUE, target:opponentLeft); MOVE(playerLeft, MOVE_FOCUS_PUNCH, target:opponentLeft); }
|
||||
TURN {};
|
||||
} SCENE {
|
||||
MESSAGE("2 withdrew Wobbuffet!");
|
||||
MESSAGE("2 sent out Wobbuffet!");
|
||||
|
||||
MESSAGE("Venusaur's Venusaurite is reacting to 1's Mega Ring!");
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_MEGA_EVOLUTION, playerRight);
|
||||
MESSAGE("Venusaur has Mega Evolved into Mega Venusaur!");
|
||||
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FOCUS_PUNCH_SETUP, playerRight);
|
||||
MESSAGE("Venusaur is tightening its focus!");
|
||||
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FOCUS_PUNCH_SETUP, playerLeft);
|
||||
MESSAGE("Wobbuffet is tightening its focus!");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Regular Mega Evolution and Fervent Wish Mega Evolution can happen on the same turn")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_RAYQUAZA) { Moves(MOVE_DRAGON_ASCENT, MOVE_CELEBRATE); Speed(3);}
|
||||
OPPONENT(SPECIES_GARDEVOIR) { Item(ITEM_GARDEVOIRITE); Speed(2);}
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_CELEBRATE, megaEvolve: TRUE); MOVE(opponent, MOVE_CELEBRATE, megaEvolve: TRUE); }
|
||||
} SCENE {
|
||||
MESSAGE("1's fervent wish has reached Rayquaza!");
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_MEGA_EVOLUTION, player);
|
||||
MESSAGE("Rayquaza has Mega Evolved into Mega Rayquaza!");
|
||||
|
||||
MESSAGE("Foe Gardevoir's Gardevoirite is reacting to 's Mega Ring!");
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_MEGA_EVOLUTION, opponent);
|
||||
MESSAGE("Foe Gardevoir has Mega Evolved into Mega Gardevoir!");
|
||||
} THEN {
|
||||
EXPECT_EQ(player->species, SPECIES_RAYQUAZA_MEGA);
|
||||
EXPECT_EQ(opponent->species, SPECIES_GARDEVOIR_MEGA);
|
||||
}
|
||||
}
|
||||
|
||||
113
test/move_effect_beak_blast.c
Normal file
113
test/move_effect_beak_blast.c
Normal file
@ -0,0 +1,113 @@
|
||||
#include "global.h"
|
||||
#include "test_battle.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(gBattleMoves[MOVE_BEAK_BLAST].effect == EFFECT_BEAK_BLAST);
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Beak Blast's charging message is shown before other moves are used")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gBattleMoves[MOVE_BEAK_BLAST].priority < 0);
|
||||
PLAYER(SPECIES_WYNAUT) {Speed(10); }
|
||||
PLAYER(SPECIES_WOBBUFFET) {Speed(5); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) {Speed(2); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) {Speed(3); }
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_BEAK_BLAST, target:opponentLeft); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_BEAK_BLAST_SETUP, playerLeft);
|
||||
MESSAGE("Wynaut started heating up its beak!");
|
||||
|
||||
MESSAGE("Wobbuffet used Celebrate!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, playerRight);
|
||||
MESSAGE("Foe Wobbuffet used Celebrate!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponentRight);
|
||||
MESSAGE("Foe Wobbuffet used Celebrate!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponentLeft);
|
||||
|
||||
MESSAGE("Wynaut used Beak Blast!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_BEAK_BLAST, playerLeft);
|
||||
HP_BAR(opponentLeft);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Beak Blast burns all who make contact with the pokemon")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gBattleMoves[MOVE_BEAK_BLAST].priority < 0);
|
||||
ASSUME(gBattleMoves[MOVE_TACKLE].flags & FLAG_MAKES_CONTACT);
|
||||
PLAYER(SPECIES_WYNAUT) {Speed(10); }
|
||||
PLAYER(SPECIES_WOBBUFFET) {Speed(5); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) {Speed(3); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) {Speed(2); }
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentLeft, MOVE_TACKLE, target:playerLeft); MOVE(opponentRight, MOVE_TACKLE, target:playerLeft); MOVE(playerLeft, MOVE_BEAK_BLAST, target:opponentLeft); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_BEAK_BLAST_SETUP, playerLeft);
|
||||
MESSAGE("Wynaut started heating up its beak!");
|
||||
|
||||
MESSAGE("Wobbuffet used Celebrate!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, playerRight);
|
||||
|
||||
MESSAGE("Foe Wobbuffet used Tackle!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponentLeft);
|
||||
HP_BAR(playerLeft);
|
||||
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_BRN, opponentLeft);
|
||||
MESSAGE("Foe Wobbuffet was burned!");
|
||||
STATUS_ICON(opponentLeft, burn: TRUE);
|
||||
|
||||
MESSAGE("Foe Wobbuffet used Tackle!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponentRight);
|
||||
HP_BAR(playerLeft);
|
||||
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_BRN, opponentRight);
|
||||
MESSAGE("Foe Wobbuffet was burned!");
|
||||
STATUS_ICON(opponentRight, burn: TRUE);
|
||||
|
||||
MESSAGE("Wynaut used Beak Blast!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_BEAK_BLAST, playerLeft);
|
||||
HP_BAR(opponentLeft);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Beak Blast burns only when contact moves are used")
|
||||
{
|
||||
u32 move;
|
||||
bool32 burn;
|
||||
PARAMETRIZE { move = MOVE_TACKLE; burn = TRUE; }
|
||||
PARAMETRIZE { move = MOVE_WATER_GUN; burn = FALSE; }
|
||||
PARAMETRIZE { move = MOVE_LEER; burn = FALSE; }
|
||||
|
||||
GIVEN {
|
||||
ASSUME(gBattleMoves[MOVE_TACKLE].flags & FLAG_MAKES_CONTACT);
|
||||
ASSUME(!(gBattleMoves[MOVE_WATER_GUN].flags & FLAG_MAKES_CONTACT));
|
||||
ASSUME(!(gBattleMoves[MOVE_LEER].flags & FLAG_MAKES_CONTACT));
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_BEAK_BLAST); MOVE(opponent, move); }
|
||||
TURN {}
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_BEAK_BLAST_SETUP, player);
|
||||
MESSAGE("Wobbuffet started heating up its beak!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, move, opponent);
|
||||
|
||||
if (burn) {
|
||||
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_BRN, opponent);
|
||||
MESSAGE("Foe Wobbuffet was burned!");
|
||||
STATUS_ICON(opponent, burn: TRUE);
|
||||
}
|
||||
else {
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_BRN, opponent);
|
||||
MESSAGE("Foe Wobbuffet was burned!");
|
||||
STATUS_ICON(opponent, burn: TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
MESSAGE("Wobbuffet used Beak Blast!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_BEAK_BLAST, player);
|
||||
HP_BAR(opponent);
|
||||
}
|
||||
}
|
||||
76
test/move_effect_focus_punch.c
Normal file
76
test/move_effect_focus_punch.c
Normal file
@ -0,0 +1,76 @@
|
||||
#include "global.h"
|
||||
#include "test_battle.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(gBattleMoves[MOVE_FOCUS_PUNCH].effect == EFFECT_FOCUS_PUNCH);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Focus Punch activates only if not damaged")
|
||||
{
|
||||
u32 move;
|
||||
bool32 activate;
|
||||
PARAMETRIZE { move = MOVE_TACKLE; activate = FALSE; }
|
||||
PARAMETRIZE { move = MOVE_WATER_GUN; activate = FALSE; }
|
||||
PARAMETRIZE { move = MOVE_LEER; activate = TRUE; }
|
||||
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_FOCUS_PUNCH); MOVE(opponent, move); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FOCUS_PUNCH_SETUP, player);
|
||||
MESSAGE("Wobbuffet is tightening its focus!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, move, opponent);
|
||||
|
||||
if (activate) {
|
||||
MESSAGE("Wobbuffet used Focus Punch!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_FOCUS_PUNCH, player);
|
||||
HP_BAR(opponent);
|
||||
} else {
|
||||
MESSAGE("Wobbuffet lost its focus and couldn't move!");
|
||||
NONE_OF {
|
||||
MESSAGE("Wobbuffet used Focus Punch!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_FOCUS_PUNCH, player);
|
||||
HP_BAR(opponent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Focus Punch activation is based on Speed")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) {Speed(2) ;}
|
||||
PLAYER(SPECIES_WYNAUT) {Speed(3) ;}
|
||||
OPPONENT(SPECIES_WOBBUFFET) {Speed(1) ;}
|
||||
OPPONENT(SPECIES_WYNAUT) {Speed(5) ;}
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentRight, MOVE_FOCUS_PUNCH, target:playerLeft); MOVE(playerRight, MOVE_FOCUS_PUNCH, target:opponentLeft); MOVE(playerLeft, MOVE_FOCUS_PUNCH, target:opponentLeft); MOVE(opponentLeft, MOVE_FOCUS_PUNCH, target:playerLeft); }
|
||||
}
|
||||
SCENE {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FOCUS_PUNCH_SETUP, opponentRight);
|
||||
MESSAGE("Foe Wynaut is tightening its focus!");
|
||||
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FOCUS_PUNCH_SETUP, playerRight);
|
||||
MESSAGE("Wynaut is tightening its focus!");
|
||||
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FOCUS_PUNCH_SETUP, playerLeft);
|
||||
MESSAGE("Wobbuffet is tightening its focus!");
|
||||
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FOCUS_PUNCH_SETUP, opponentLeft);
|
||||
MESSAGE("Foe Wobbuffet is tightening its focus!");
|
||||
|
||||
MESSAGE("Foe Wynaut used Focus Punch!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_FOCUS_PUNCH, opponentRight);
|
||||
HP_BAR(playerLeft);
|
||||
|
||||
MESSAGE("Wynaut used Focus Punch!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_FOCUS_PUNCH, playerRight);
|
||||
HP_BAR(opponentLeft);
|
||||
|
||||
MESSAGE("Wobbuffet lost its focus and couldn't move!");
|
||||
MESSAGE("Foe Wobbuffet lost its focus and couldn't move!");
|
||||
}
|
||||
}
|
||||
@ -798,6 +798,7 @@ struct MoveContext
|
||||
u16 explicitMegaEvolve:1;
|
||||
// TODO: u8 zMove:1;
|
||||
u16 dynamax:1;
|
||||
u16 explicitDynamax:1;
|
||||
u16 allowed:1;
|
||||
u16 explicitAllowed:1;
|
||||
struct BattlePokemon *target;
|
||||
|
||||
@ -1418,7 +1418,7 @@ void Move(u32 sourceLine, struct BattlePokemon *battler, struct MoveContext ctx)
|
||||
if (ctx.explicitMegaEvolve && ctx.megaEvolve)
|
||||
moveSlot |= RET_MEGA_EVOLUTION;
|
||||
|
||||
if (ctx.dynamax)
|
||||
if (ctx.explicitDynamax && ctx.dynamax)
|
||||
moveSlot |= RET_DYNAMAX;
|
||||
|
||||
if (ctx.explicitTarget)
|
||||
|
||||
@ -75,6 +75,9 @@ string json_to_string(const Json &data, const string &field = "", bool silent =
|
||||
case Json::Type::BOOL:
|
||||
output = value.bool_value() ? "TRUE" : "FALSE";
|
||||
break;
|
||||
case Json::Type::NUL:
|
||||
output = "";
|
||||
break;
|
||||
default:{
|
||||
if (!silent) {
|
||||
string s = !field.empty() ? ("Value for '" + field + "'") : "JSON field";
|
||||
@ -461,26 +464,27 @@ string generate_map_constants_text(string groups_filepath, Json groups_data) {
|
||||
for (auto &group : groups_data["group_order"].array_items()) {
|
||||
string groupName = json_to_string(group);
|
||||
text << "// " << groupName << "\n";
|
||||
vector<Json> map_ids;
|
||||
vector<string> map_ids;
|
||||
size_t max_length = 0;
|
||||
|
||||
int map_count = 0; //DEBUG
|
||||
|
||||
for (auto &map_name : groups_data[groupName].array_items()) {
|
||||
string header_filepath = file_dir + json_to_string(map_name) + dir_separator + "map.json";
|
||||
string map_filepath = file_dir + json_to_string(map_name) + dir_separator + "map.json";
|
||||
string err_str;
|
||||
Json map_data = Json::parse(read_text_file(header_filepath), err_str);
|
||||
map_ids.push_back(map_data["id"]);
|
||||
string id = json_to_string(map_data, "id");
|
||||
Json map_data = Json::parse(read_text_file(map_filepath), err_str);
|
||||
if (map_data == Json())
|
||||
FATAL_ERROR("%s: %s\n", map_filepath.c_str(), err_str.c_str());
|
||||
string id = json_to_string(map_data, "id", true);
|
||||
map_ids.push_back(id);
|
||||
if (id.length() > max_length)
|
||||
max_length = id.length();
|
||||
map_count++; //DEBUG
|
||||
}
|
||||
|
||||
int map_id_num = 0;
|
||||
for (Json map_id : map_ids) {
|
||||
string id = json_to_string(map_id);
|
||||
text << "#define " << id << string((max_length - id.length() + 1), ' ')
|
||||
for (string map_id : map_ids) {
|
||||
text << "#define " << map_id << string((max_length - map_id.length() + 1), ' ')
|
||||
<< "(" << map_id_num++ << " | (" << group_num << " << 8))\n";
|
||||
}
|
||||
text << "\n";
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user