added base functionality for max moves

This commit is contained in:
AgustinGDLV 2023-02-21 20:16:25 -08:00
parent ae7cbc2aa1
commit 87a9150134
16 changed files with 496 additions and 19 deletions

View file

@ -2145,3 +2145,18 @@
.macro trysymbiosis
various BS_ATTACKER, VARIOUS_TRY_SYMBIOSIS
.endm
@ The next few macros are used by Max Moves.
.macro setmaxmoveeffect
various 0, VARIOUS_SET_MAX_MOVE_EFFECT
.endm
.macro jumpiftargetabsent, ptr:req
various 0, VARIOUS_JUMP_IF_TARGET_ABSENT
.4byte \ptr
.endm
.macro jumpiftargetnotally, ptr:req
various 0, VARIOUS_JUMP_IF_TARGET_NOT_ALLY
.4byte \ptr
.endm

View file

@ -916,6 +916,7 @@ gBattleAnims_General::
.4byte General_ShellTrapSetUp @ B_ANIM_SHELL_TRAP_SETUP
.4byte General_ZMoveActivate @ B_ANIM_ZMOVE_ACTIVATE
.4byte General_AffectionHangedOn @ B_ANIM_AFFECTION_HANGED_ON
.4byte General_SetWeather @ B_ANIM_MAX_SET_WEATHER
.align 2
gBattleAnims_Special::
@ -30654,23 +30655,71 @@ SoulStealingSevenStarStrikeExplosion:
return
@@@@@@@@@@ MAX MOVES @@@@@@@@@@
Move_MAX_GUARD:
Move_MAX_STRIKE:
General_SetWeather::
createvisualtask AnimTask_GetWeatherToSet, 2
jumpreteq 1, General_Sun
jumpreteq 2, General_Rain
jumpreteq 3, General_Sandstorm
jumpreteq 4, General_Hail
end
Move_MAX_KNUCKLE:
Move_MAX_AIRSTREAM:
Move_MAX_OOZE:
Move_MAX_QUAKE:
Move_MAX_ROCKFALL:
Move_MAX_FLUTTERBY:
Move_MAX_PHANTASM:
Move_MAX_STEELSPIKE:
Move_MAX_FLARE:
Move_MAX_GEYSER:
Move_MAX_OVERGROWTH:
Move_MAX_LIGHTNING:
Move_MAX_HAILSTORM:
Move_MAX_MINDSTORM:
Move_MAX_WYRMWIND:
Move_MAX_DARKNESS:
Move_MAX_STARFALL:
end
Move_MAX_GUARD:
launchtask AnimTask_DynamaxGrowth 0x5 0x1 0x1
waitforvisualfinish
goto Move_PROTECT
end
Move_MAX_STRIKE::
launchtask AnimTask_DynamaxGrowth 0x5 0x1 0x1
waitforvisualfinish
goto Move_GIGA_IMPACT
end
Move_MAX_AIRSTREAM::
launchtask AnimTask_DynamaxGrowth 0x5 0x1 0x1
waitforvisualfinish
goto Move_AEROBLAST
end
Move_MAX_OOZE::
launchtask AnimTask_DynamaxGrowth 0x5 0x1 0x1
waitforvisualfinish
goto Move_GUNK_SHOT
end
Move_MAX_FLARE::
launchtask AnimTask_DynamaxGrowth 0x5 0x1 0x1
waitforvisualfinish
goto Move_BLAST_BURN
end
Move_MAX_GEYSER::
launchtask AnimTask_DynamaxGrowth 0x5 0x1 0x1
waitforvisualfinish
goto Move_HYDRO_CANNON
end
Move_MAX_OVERGROWTH::
launchtask AnimTask_DynamaxGrowth 0x5 0x1 0x1
waitforvisualfinish
goto Move_FRENZY_PLANT
end
Move_MAX_LIGHTNING::
launchtask AnimTask_DynamaxGrowth 0x5 0x1 0x1
waitforvisualfinish
goto Move_ZAP_CANNON
end

View file

@ -417,14 +417,6 @@ gBattleScriptsForMoveEffects::
.4byte BattleScript_EffectTerrainHit @ EFFECT_DAMAGE_SET_TERRAIN
.4byte BattleScript_EffectMaxMove @ EFFECT_MAX_MOVE
BattleScript_EffectMaxMove::
attackcanceler
@setmaxmoveeffect
accuracycheck BattleScript_ButItFailed, NO_ACC_CALC_CHECK_LOCK_ON
attackstring
ppreduce
goto BattleScript_HitFromCritCalc
BattleScript_AffectionBasedEndurance::
playanimation BS_TARGET, B_ANIM_AFFECTION_HANGED_ON
printstring STRINGID_TARGETTOUGHEDITOUT
@ -9889,3 +9881,67 @@ BattleScript_SymbiosisActivates::
printstring STRINGID_SYMBIOSISITEMPASS
waitmessage B_WAIT_TIME_LONG
return
@@@ MAX MOVES @@@
BattleScript_EffectMaxMove::
attackcanceler
setmaxmoveeffect
accuracycheck BattleScript_ButItFailed, NO_ACC_CALC_CHECK_LOCK_ON
attackstring
ppreduce
goto BattleScript_HitFromCritCalc
BattleScript_EffectRaiseSideStats::
savetarget
setbyte gBattlerTarget, 0
BattleScript_RaiseSideStatsLoop:
jumpiftargetnotally BattleScript_RaiseSideStatsIncrement
jumpiftargetabsent BattleScript_RaiseSideStatsIncrement
statbuffchange STAT_CHANGE_ALLOW_PTR, BattleScript_RaiseSideStatsIncrement
jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_INCREASE, BattleScript_RaiseSideStatsIncrement
setgraphicalstatchangevalues
playanimation BS_TARGET, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1
printfromtable gStatUpStringIds
waitmessage B_WAIT_TIME_LONG
BattleScript_RaiseSideStatsIncrement:
setbyte sSTAT_ANIM_PLAYED, FALSE
addbyte gBattlerTarget, 1
jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_RaiseSideStatsLoop
BattleScript_RaiseSideStatsEnd:
restoretarget
return
BattleScript_EffectLowerSideStats::
savetarget
setbyte gBattlerTarget, 0
BattleScript_LowerSideStatsLoop:
jumpiftargetally BattleScript_LowerSideStatsIncrement
jumpiftargetabsent BattleScript_LowerSideStatsIncrement
statbuffchange STAT_CHANGE_ALLOW_PTR, BattleScript_LowerSideStatsIncrement
jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_DECREASE, BattleScript_LowerSideStatsIncrement
setgraphicalstatchangevalues
playanimation BS_TARGET, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1
printfromtable gStatDownStringIds
waitmessage B_WAIT_TIME_LONG
BattleScript_LowerSideStatsIncrement:
setbyte sSTAT_ANIM_PLAYED, FALSE
addbyte gBattlerTarget, 1
jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_LowerSideStatsLoop
BattleScript_LowerSideStatsEnd:
restoretarget
return
BattleScript_EffectSetWeather::
playanimation 0, B_ANIM_MAX_SET_WEATHER
printfromtable gMoveWeatherChangeStringIds
waitmessage B_WAIT_TIME_LONG
call BattleScript_WeatherFormChanges
return
BattleScript_EffectSetTerrain::
printfromtable gTerrainStringIds
waitmessage B_WAIT_TIME_LONG
playanimation BS_SCRIPTING, B_ANIM_RESTORE_BG
call BattleScript_TerrainSeedLoop
jumpifabilitypresent ABILITY_MIMICRY, BattleScript_ApplyMimicry
return

View file

@ -148,6 +148,7 @@ struct ProtectStruct
u16 quickDraw:1;
u16 beakBlastCharge:1;
u16 quash:1;
u16 maxGuarded:1;
u32 physicalDmg;
u32 specialDmg;
u8 physicalBattlerId;
@ -510,6 +511,14 @@ struct ZMoveData
u8 splits[MAX_BATTLERS_COUNT];
};
struct DynamaxData
{
u8 dynamaxTurns[MAX_BATTLERS_COUNT];
u8 usingMaxMove[MAX_BATTLERS_COUNT];
u8 activeSplit;
u8 splits[MAX_BATTLERS_COUNT];
};
struct StolenItem
{
u16 originalItem:15;
@ -615,6 +624,7 @@ struct BattleStruct
bool8 throwingPokeBall;
struct MegaEvolutionData mega;
struct ZMoveData zmove;
struct DynamaxData dynamax;
const u8 *trainerSlideMsg;
bool8 trainerSlideLowHpMsgDone;
u8 introState;

View file

@ -1,5 +1,5 @@
#ifndef GUARD_BATTLE_RAID_H
#define GUARD_BATTLE_RAID_H
#ifndef GUARD_BATTLE_DYNAMAX_H
#define GUARD_BATTLE_DYNAMAX_H
enum MaxMoveEffect
{
@ -52,4 +52,8 @@ enum MaxMoveEffect
MAX_EFFECT_FIRE_SPIN_FOES,
};
bool8 ShouldUseMaxMove(u16 battlerId, u16 baseMove);
u16 GetMaxMove(u16 battlerId, u16 baseMove);
bool8 IsMaxMove(u16 move);
#endif

View file

@ -439,4 +439,10 @@ extern const u8 BattleScript_StatUpZMove[];
extern const u8 BattleScript_HealReplacementZMove[];
extern const u8 BattleScript_EffectExtremeEvoboost[];
// max moves
extern const u8 BattleScript_EffectRaiseSideStats[];
extern const u8 BattleScript_EffectLowerSideStats[];
extern const u8 BattleScript_EffectSetWeather[];
extern const u8 BattleScript_EffectSetTerrain[];
#endif // GUARD_BATTLE_SCRIPTS_H

View file

@ -368,8 +368,12 @@
#define MOVE_EFFECT_TRAP_BOTH 0x48
#define MOVE_EFFECT_SKY_DROP 0x49
#define MOVE_EFFECT_SCALE_SHOT 0x4A
#define MOVE_EFFECT_RAISE_SIDE_STATS 0x4B
#define MOVE_EFFECT_LOWER_SIDE_STATS 0x4C
#define MOVE_EFFECT_WEATHER 0x4D
#define MOVE_EFFECT_TERRAIN 0x4E
#define NUM_MOVE_EFFECTS 0x4B
#define NUM_MOVE_EFFECTS 0x4F
#define MOVE_EFFECT_AFFECTS_USER 0x4000
#define MOVE_EFFECT_CERTAIN 0x8000

View file

@ -535,6 +535,7 @@
#define B_ANIM_SHELL_TRAP_SETUP 34
#define B_ANIM_ZMOVE_ACTIVATE 35 // Using Z Moves
#define B_ANIM_AFFECTION_HANGED_ON 36
#define B_ANIM_MAX_SET_WEATHER 37
// special animations table (gBattleAnims_Special)
#define B_ANIM_LVL_UP 0

View file

@ -245,6 +245,9 @@
#define VARIOUS_TRY_SYMBIOSIS 154
#define VARIOUS_CAN_TELEPORT 155
#define VARIOUS_GET_BATTLER_SIDE 156
#define VARIOUS_SET_MAX_MOVE_EFFECT 157
#define VARIOUS_JUMP_IF_TARGET_NOT_ALLY 158
#define VARIOUS_JUMP_IF_TARGET_ABSENT 159
// Cmd_manipulatedamage
#define DMG_CHANGE_SIGN 0

View file

@ -7903,3 +7903,60 @@ void AnimTask_AffectionHangedOn(u8 taskId)
gBattleAnimArgs[0] = GetBattlerFriendshipScore(gBattleAnimTarget);
DestroyAnimVisualTask(taskId);
}
// DYNAMAX
static const union AffineAnimCmd sDynamaxGrowthAffineAnimCmds[] = // from CFRU
{
AFFINEANIMCMD_FRAME(-2, -2, 0, 64), //Double in size over 1 second
AFFINEANIMCMD_FRAME(0, 0, 0, 64), //Pause for 1 seconds
AFFINEANIMCMD_FRAME(16, 16, 0, 8), //Shrink back down in 1/8 of a second
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sDynamaxGrowthAttackAnimationAffineAnimCmds[] =
{
AFFINEANIMCMD_FRAME(-4, -4, 0, 32), //Double in size quicker
AFFINEANIMCMD_FRAME(0, 0, 0, 32), //Pause for less
AFFINEANIMCMD_FRAME(16, 16, 0, 8),
AFFINEANIMCMD_END,
};
static void AnimTask_DynamaxGrowthStep(u8 taskId) // from CFRU
{
struct Task* task = &gTasks[taskId];
if (!RunAffineAnimFromTaskData(task))
DestroyAnimVisualTask(taskId);
}
//Arg 0: Animation for attack
void AnimTask_DynamaxGrowth(u8 taskId) // from CFRU
{
struct Task* task = &gTasks[taskId];
u8 spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER);
if (gBattleAnimArgs[0] == 0)
PrepareAffineAnimInTaskData(task, spriteId, sDynamaxGrowthAffineAnimCmds);
else
PrepareAffineAnimInTaskData(task, spriteId, sDynamaxGrowthAttackAnimationAffineAnimCmds);
task->func = AnimTask_DynamaxGrowthStep;
}
void AnimTask_GetWeatherToSet(u8 taskId)
{
switch (gBattleMoves[gCurrentMove].argument)
{
case MAX_EFFECT_SUN:
gBattleAnimArgs[ARG_RET_ID] = 1;
break;
case MAX_EFFECT_RAIN:
gBattleAnimArgs[ARG_RET_ID] = 2;
break;
case MAX_EFFECT_SANDSTORM:
gBattleAnimArgs[ARG_RET_ID] = 3;
break;
case MAX_EFFECT_HAIL:
gBattleAnimArgs[ARG_RET_ID] = 4;
break;
}
DestroyAnimVisualTask(taskId);
}

103
src/battle_dynamax.c Normal file
View file

@ -0,0 +1,103 @@
#include "global.h"
#include "pokemon.h"
#include "battle.h"
#include "constants/moves.h"
// Constant Data
static const u16 sMaxMoveTable[] =
{
[TYPE_NORMAL] = MOVE_MAX_STRIKE,
[TYPE_FIGHTING] = MOVE_MAX_KNUCKLE,
[TYPE_FLYING] = MOVE_MAX_AIRSTREAM,
[TYPE_POISON] = MOVE_MAX_OOZE,
[TYPE_GROUND] = MOVE_MAX_QUAKE,
[TYPE_ROCK] = MOVE_MAX_ROCKFALL,
[TYPE_BUG] = MOVE_MAX_FLUTTERBY,
[TYPE_GHOST] = MOVE_MAX_PHANTASM,
[TYPE_STEEL] = MOVE_MAX_STEELSPIKE,
[TYPE_FIRE] = MOVE_MAX_FLARE,
[TYPE_WATER] = MOVE_MAX_GEYSER,
[TYPE_GRASS] = MOVE_MAX_OVERGROWTH,
[TYPE_ELECTRIC] = MOVE_MAX_LIGHTNING,
[TYPE_PSYCHIC] = MOVE_MAX_MINDSTORM,
[TYPE_ICE] = MOVE_MAX_HAILSTORM,
[TYPE_DRAGON] = MOVE_MAX_WYRMWIND,
[TYPE_DARK] = MOVE_MAX_DARKNESS,
[TYPE_FAIRY] = MOVE_MAX_STARFALL,
};
struct GMaxMove
{
u16 species;
u8 moveType;
u16 gmaxMove;
};
static const struct GMaxMove sGMaxMoveTable[] =
{
{SPECIES_VENUSAUR_GMAX, TYPE_GRASS, MOVE_G_MAX_VINE_LASH},
{SPECIES_CHARIZARD_GMAX, TYPE_FIRE, MOVE_G_MAX_WILDFIRE},
{SPECIES_BLASTOISE_GMAX, TYPE_WATER, MOVE_G_MAX_CANNONADE},
{SPECIES_BUTTERFREE_GMAX, TYPE_BUG, MOVE_G_MAX_BEFUDDLE},
{SPECIES_PIKACHU_GMAX, TYPE_ELECTRIC, MOVE_G_MAX_VOLT_CRASH},
{SPECIES_MEOWTH_GMAX, TYPE_NORMAL, MOVE_G_MAX_GOLD_RUSH},
{SPECIES_MACHAMP_GMAX, TYPE_FIGHTING, MOVE_G_MAX_CHI_STRIKE},
{SPECIES_GENGAR_GMAX, TYPE_GHOST, MOVE_G_MAX_TERROR},
{SPECIES_KINGLER_GMAX, TYPE_WATER, MOVE_G_MAX_FOAM_BURST},
{SPECIES_LAPRAS_GMAX, TYPE_ICE, MOVE_G_MAX_RESONANCE},
{SPECIES_EEVEE_GMAX, TYPE_NORMAL, MOVE_G_MAX_CUDDLE},
{SPECIES_SNORLAX_GMAX, TYPE_NORMAL, MOVE_G_MAX_REPLENISH},
{SPECIES_GARBODOR_GMAX, TYPE_POISON, MOVE_G_MAX_MALODOR},
{SPECIES_MELMETAL_GMAX, TYPE_STEEL, MOVE_G_MAX_MELTDOWN},
{SPECIES_RILLABOOM_GMAX, TYPE_GRASS, MOVE_G_MAX_DRUM_SOLO},
{SPECIES_CINDERACE_GMAX, TYPE_FIRE, MOVE_G_MAX_FIREBALL},
{SPECIES_INTELEON_GMAX, TYPE_WATER, MOVE_G_MAX_HYDROSNIPE},
{SPECIES_CORVIKNIGHT_GMAX, TYPE_FLYING, MOVE_G_MAX_WIND_RAGE},
{SPECIES_ORBEETLE_GMAX, TYPE_PSYCHIC, MOVE_G_MAX_GRAVITAS},
{SPECIES_DREDNAW_GMAX, TYPE_WATER, MOVE_G_MAX_STONESURGE},
{SPECIES_COALOSSAL_GMAX, TYPE_ROCK, MOVE_G_MAX_VOLCALITH},
{SPECIES_FLAPPLE_GMAX, TYPE_GRASS, MOVE_G_MAX_TARTNESS},
{SPECIES_APPLETUN_GMAX, TYPE_GRASS, MOVE_G_MAX_SWEETNESS},
{SPECIES_SANDACONDA_GMAX, TYPE_GROUND, MOVE_G_MAX_SANDBLAST},
{SPECIES_TOXTRICITY_GMAX, TYPE_ELECTRIC, MOVE_G_MAX_STUN_SHOCK},
{SPECIES_CENTISKORCH_GMAX, TYPE_FIRE, MOVE_G_MAX_CENTIFERNO},
{SPECIES_HATTERENE_GMAX, TYPE_FAIRY, MOVE_G_MAX_SMITE},
{SPECIES_GRIMMSNARL_GMAX, TYPE_DARK, MOVE_G_MAX_SNOOZE},
{SPECIES_ALCREMIE_GMAX, TYPE_FAIRY, MOVE_G_MAX_FINALE},
{SPECIES_COPPERAJAH_GMAX, TYPE_STEEL, MOVE_G_MAX_STEELSURGE},
{SPECIES_DURALUDON_GMAX, TYPE_DRAGON, MOVE_G_MAX_DEPLETION},
{SPECIES_URSHIFU_GMAX, TYPE_DARK, MOVE_G_MAX_ONE_BLOW},
{SPECIES_URSHIFU_RAPID_STRIKE_STYLE_GMAX, TYPE_WATER, MOVE_G_MAX_RAPID_FLOW},
};
// Functions:
bool8 ShouldUseMaxMove(u16 battlerId, u16 baseMove)
{
// TODO: Raids
//if (IsRaidBoss(battlerId))
// return !IsRaidBossUsingRegularMove(battlerId, baseMove);
if (gBattleStruct->dynamax.dynamaxTurns[battlerId] > 0)
return TRUE;
return TRUE;
}
u16 GetMaxMove(u16 battlerId, u16 baseMove)
{
u16 move = baseMove;
if (gBattleMoves[baseMove].split == SPLIT_STATUS)
{
move = MOVE_MAX_GUARD;
}
else
{
move = sMaxMoveTable[gBattleMoves[baseMove].type];
gBattleStruct->dynamax.splits[battlerId] = gBattleMoves[baseMove].split;
}
return move;
}
bool8 IsMaxMove(u16 move)
{
return move >= FIRST_MAX_MOVE && move <= LAST_MAX_MOVE;
}

View file

@ -4225,6 +4225,8 @@ static void HandleTurnActionSelectionState(void)
*(gBattleStruct->moveTarget + gActiveBattler) = gBattleResources->bufferB[gActiveBattler][3];
if (gBattleResources->bufferB[gActiveBattler][2] & RET_MEGA_EVOLUTION)
gBattleStruct->mega.toEvolve |= gBitTable[gActiveBattler];
if (ShouldUseMaxMove(gActiveBattler, gChosenMoveByBattler[gActiveBattler])) // max move check
gBattleStruct->dynamax.usingMaxMove[gActiveBattler] = TRUE;
gBattleCommunication[gActiveBattler]++;
}
break;
@ -4524,6 +4526,11 @@ s8 GetMovePriority(u32 battlerId, u16 move)
u16 ability = GetBattlerAbility(battlerId);
priority = gBattleMoves[move].priority;
// Max Guard check
if (gBattleStruct->dynamax.usingMaxMove[battlerId] && gBattleMoves[move].split == SPLIT_STATUS)
return gBattleMoves[MOVE_MAX_GUARD].priority;
if (ability == ABILITY_GALE_WINGS
#if B_GALE_WINGS >= GEN_7
&& BATTLER_MAX_HP(battlerId)

View file

@ -2837,6 +2837,8 @@ void BufferStringBattle(u16 stringID)
case STRINGID_USEDMOVE: // pokemon used a move msg
if (gBattleStruct->zmove.active && gBattleStruct->zmove.activeSplit != SPLIT_STATUS)
StringCopy(gBattleTextBuff3, GetZMoveName(gBattleMsgDataPtr->currentMove));
else if (IsMaxMove(gBattleMsgDataPtr->currentMove))
StringCopy(gBattleTextBuff3, gMoveNames[gBattleMsgDataPtr->currentMove]);
else if (gBattleMsgDataPtr->currentMove >= MOVES_COUNT)
StringCopy(gBattleTextBuff3, sATypeMove_Table[*(&gBattleStruct->stringMoveType)]);
else

View file

@ -3616,6 +3616,89 @@ void SetMoveEffect(bool32 primary, u32 certain)
gBattlescriptCurrInstr = BattleScript_DefDownSpeedUp;
}
break;
// MAX MOVE EFFECTS
case MOVE_EFFECT_RAISE_SIDE_STATS:
if (!NoAliveMonsForEitherParty())
{
SET_STATCHANGER(gBattleMoves[gCurrentMove].argument, 1, FALSE); // see enum MaxMoveEffect
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_EffectRaiseSideStats;
break;
}
case MOVE_EFFECT_LOWER_SIDE_STATS:
if (!NoAliveMonsForEitherParty())
{
SET_STATCHANGER(gBattleMoves[gCurrentMove].argument - 5, 1, TRUE); // see enum MaxMoveEffect
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_EffectLowerSideStats;
break;
}
case MOVE_EFFECT_WEATHER:
{
u8 weather, msg;
switch (gBattleMoves[gCurrentMove].argument)
{
case MAX_EFFECT_SUN:
weather = ENUM_WEATHER_SUN;
msg = B_MSG_STARTED_SUNLIGHT;
break;
case MAX_EFFECT_RAIN:
weather = ENUM_WEATHER_RAIN;
msg = B_MSG_STARTED_RAIN;
break;
case MAX_EFFECT_SANDSTORM:
weather = ENUM_WEATHER_SANDSTORM;
msg = B_MSG_STARTED_SANDSTORM;
break;
case MAX_EFFECT_HAIL:
weather = ENUM_WEATHER_HAIL;
msg = B_MSG_STARTED_HAIL;
break;
}
if (TryChangeBattleWeather(gBattlerAttacker, weather, FALSE))
{
gBattleCommunication[MULTISTRING_CHOOSER] = msg;
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_EffectSetWeather;
}
break;
}
case MOVE_EFFECT_TERRAIN:
{
u32 statusFlag = 0;
u8 *timer = NULL;
switch (gBattleMoves[gCurrentMove].argument)
{
case MAX_EFFECT_MISTY_TERRAIN:
statusFlag = STATUS_FIELD_MISTY_TERRAIN, timer = &gFieldTimers.terrainTimer;
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
break;
case MAX_EFFECT_GRASSY_TERRAIN:
statusFlag = STATUS_FIELD_GRASSY_TERRAIN, timer = &gFieldTimers.terrainTimer;
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
break;
case MAX_EFFECT_ELECTRIC_TERRAIN:
statusFlag = STATUS_FIELD_ELECTRIC_TERRAIN, timer = &gFieldTimers.terrainTimer;
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
break;
case MAX_EFFECT_PSYCHIC_TERRAIN:
statusFlag = STATUS_FIELD_PSYCHIC_TERRAIN, timer = &gFieldTimers.terrainTimer;
gBattleCommunication[MULTISTRING_CHOOSER] = 3;
break;
}
if (!(gFieldStatuses & statusFlag) && statusFlag != 0)
{
gFieldStatuses &= ~STATUS_FIELD_TERRAIN_ANY;
gFieldStatuses |= statusFlag;
if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_TERRAIN_EXTENDER)
*timer = 8;
else
*timer = 5;
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_EffectSetTerrain;
}
break;
}
}
}
}
@ -9898,6 +9981,49 @@ static void Cmd_various(void)
else
gBattleCommunication[0] = B_SIDE_OPPONENT;
break;
case VARIOUS_SET_MAX_MOVE_EFFECT:
switch (gBattleMoves[gCurrentMove].argument)
{
case MAX_EFFECT_RAISE_TEAM_ATTACK:
case MAX_EFFECT_RAISE_TEAM_DEFENSE:
case MAX_EFFECT_RAISE_TEAM_SPEED:
case MAX_EFFECT_RAISE_TEAM_SP_ATK:
case MAX_EFFECT_RAISE_TEAM_SP_DEF:
gBattleScripting.moveEffect = MOVE_EFFECT_RAISE_SIDE_STATS;
break;
case MAX_EFFECT_LOWER_ATTACK:
case MAX_EFFECT_LOWER_DEFENSE:
case MAX_EFFECT_LOWER_SPEED:
case MAX_EFFECT_LOWER_SP_ATK:
case MAX_EFFECT_LOWER_SP_DEF:
gBattleScripting.moveEffect = MOVE_EFFECT_LOWER_SIDE_STATS;
break;
case MAX_EFFECT_SUN:
case MAX_EFFECT_RAIN:
case MAX_EFFECT_SANDSTORM:
case MAX_EFFECT_HAIL:
gBattleScripting.moveEffect = MOVE_EFFECT_WEATHER;
break;
case MAX_EFFECT_MISTY_TERRAIN:
case MAX_EFFECT_GRASSY_TERRAIN: // TODO: Grassy terrain not working?
case MAX_EFFECT_ELECTRIC_TERRAIN:
case MAX_EFFECT_PSYCHIC_TERRAIN:
gBattleScripting.moveEffect = MOVE_EFFECT_TERRAIN;
break;
}
break;
case VARIOUS_JUMP_IF_TARGET_NOT_ALLY:
if (GetBattlerSide(gBattlerTarget) != GetBattlerSide(gBattlerAttacker))
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
else
gBattlescriptCurrInstr += 7;
return;
case VARIOUS_JUMP_IF_TARGET_ABSENT:
if (!IsBattlerAlive(gBattlerTarget))
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
else
gBattlescriptCurrInstr += 7;
return;
} // End of switch (gBattlescriptCurrInstr[2])
gBattlescriptCurrInstr += 3;
@ -9948,6 +10074,11 @@ static void Cmd_setprotectlike(void)
gProtectStructs[gBattlerAttacker].obstructed = TRUE;
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
}
else if (gCurrentMove == MOVE_MAX_GUARD)
{
gProtectStructs[gBattlerAttacker].maxGuarded = TRUE;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_PROTECTED_ITSELF;
}
gDisableStructs[gBattlerAttacker].protectUses++;
fail = FALSE;

View file

@ -48,6 +48,7 @@
#include "constants/pokemon.h"
extern struct Evolution gEvolutionTable[][EVOS_PER_MON];
extern u8 gDynamaxMovePowers[MOVES_COUNT];
/*
NOTE: The data and functions in this file up until (but not including) sSoundMovesTable
@ -303,6 +304,14 @@ void HandleAction_UseMove(void)
gCurrentMove = gBattleStruct->zmove.toBeUsed[gBattlerAttacker];
}
// check max move used
if (gBattleStruct->dynamax.usingMaxMove[gBattlerAttacker])
{
gCurrentMove = gChosenMove = GetMaxMove(gBattlerAttacker, gCurrentMove);
gBattleStruct->dynamax.activeSplit = gBattleStruct->dynamax.splits[gBattlerAttacker];
gBattleStruct->moveTarget[gBattlerAttacker] = GetMoveTarget(gCurrentMove, NO_TARGET_OVERRIDE);
}
if (gBattleMons[gBattlerAttacker].hp != 0)
{
if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
@ -911,6 +920,7 @@ void HandleAction_ActionFinished(void)
gBattleCommunication[4] = 0;
gBattleScripting.multihitMoveEffect = 0;
gBattleResources->battleScriptsStack->size = 0;
gBattleStruct->dynamax.usingMaxMove[gBattlerAttacker] = 0;
#if B_RECALC_TURN_AFTER_ACTIONS >= GEN_8
// i starts at `gCurrentTurnActionNumber` because we don't want to recalculate turn order for mon that have already
@ -7908,6 +7918,15 @@ bool32 IsBattlerProtected(u8 battlerId, u16 move)
return FALSE;
}
// Max Moves bypass any protection except Max Guard
if (IsMaxMove(move))
{
if (gProtectStructs[battlerId].maxGuarded)
return TRUE;
else
return FALSE;
}
// Protective Pads doesn't stop Unseen Fist from bypassing Protect effects, so IsMoveMakingContact() isn't used here.
// This means extra logic is needed to handle Shell Side Arm.
if (GetBattlerAbility(gBattlerAttacker) == ABILITY_UNSEEN_FIST
@ -8404,6 +8423,9 @@ static u16 CalcMoveBasePower(u16 move, u8 battlerAtk, u8 battlerDef)
if (IsBattlerTerrainAffected(gBattlerTarget, STATUS_FIELD_ELECTRIC_TERRAIN))
basePower *= 2;
break;
case EFFECT_MAX_MOVE:
basePower = gDynamaxMovePowers[gBattleMons[battlerAtk].moves[gBattleStruct->chosenMovePositions[battlerAtk]]];
break;
}
// Move-specific base power changes
@ -9869,6 +9891,8 @@ u8 GetBattleMoveSplit(u32 moveId)
{
if (gBattleStruct != NULL && gBattleStruct->zmove.active && !IS_MOVE_STATUS(moveId))
return gBattleStruct->zmove.activeSplit;
if (gBattleStruct != NULL && IsMaxMove(moveId)) // TODO: Might be buggy depending on when this is called.
return gBattleStruct->dynamax.activeSplit;
if (gBattleStruct != NULL && gBattleStruct->swapDamageCategory) // Photon Geyser, Shell Side Arm, Light That Burns the Sky
return SPLIT_PHYSICAL;

View file

@ -14355,6 +14355,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.split = SPLIT_PHYSICAL,
.argument = MAX_EFFECT_PSYCHIC_TERRAIN,
},
[MOVE_MAX_ROCKFALL] =
{
.effect = EFFECT_MAX_MOVE,
@ -14369,6 +14370,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.split = SPLIT_PHYSICAL,
.argument = MAX_EFFECT_SANDSTORM,
},
[MOVE_MAX_QUAKE] =
{
.effect = EFFECT_MAX_MOVE,
@ -14383,6 +14385,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.split = SPLIT_PHYSICAL,
.argument = MAX_EFFECT_RAISE_TEAM_SP_DEF,
},
[MOVE_MAX_DARKNESS] =
{
.effect = EFFECT_MAX_MOVE,
@ -14397,6 +14400,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.split = SPLIT_PHYSICAL,
.argument = MAX_EFFECT_LOWER_SP_DEF,
},
[MOVE_MAX_OVERGROWTH] =
{
.effect = EFFECT_MAX_MOVE,
@ -14411,6 +14415,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.split = SPLIT_PHYSICAL,
.argument = MAX_EFFECT_GRASSY_TERRAIN,
},
[MOVE_MAX_STEELSPIKE] =
{
.effect = EFFECT_MAX_MOVE,