implemented G-Max Vine Lash, G-Max Wildfire, G-Max Cannonade, G-Max Volcalith

This commit is contained in:
AgustinGDLV 2023-02-26 23:35:36 -08:00
parent 4d19659b0b
commit a36c35aea1
13 changed files with 173 additions and 8 deletions

View file

@ -2233,6 +2233,10 @@
.4byte \failInstr
.endm
.macro damagenontypes
various 0, VARIOUS_DAMAGE_NON_TYPES
.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

View file

@ -10404,6 +10404,38 @@ BattleScript_TargetAbilityStatRaiseRet::
BattleScript_TargetAbilityStatRaiseRet_End:
return
BattleScript_DamageNonTypesStarts::
printfromtable gDamageNonTypesStartStringIds
waitmessage B_WAIT_TIME_LONG
return
BattleScript_DamageNonTypesContinues::
@printfromtable gDamageNonTypesStartStringIds
@waitmessage B_WAIT_TIME_LONG
setbyte gBattleCommunication, 0
BattleScript_DamageNonTypesLoop::
copyarraywithindex gBattlerAttacker, gBattlerByTurnOrder, gBattleCommunication, 1
damagenontypes
jumpifword CMP_EQUAL, gBattleMoveDamage, 0, BattleScript_DamageNonTypesLoopIncrement
printfromtable gDamageNonTypesDmgStringIds
waitmessage B_WAIT_TIME_LONG
effectivenesssound
hitanimation BS_ATTACKER
goto BattleScript_DamageNonTypesHpChange
BattleScript_DamageNonTypesHpChange:
orword gHitMarker, HITMARKER_SKIP_DMG_TRACK | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE | HITMARKER_GRUDGE
healthbarupdate BS_ATTACKER
datahpupdate BS_ATTACKER
tryfaintmon BS_ATTACKER
checkteamslost BattleScript_DamageNonTypesLoopIncrement
BattleScript_DamageNonTypesLoopIncrement::
jumpifbyte CMP_NOT_EQUAL, gBattleOutcome, 0, BattleScript_DamageNonTypesContinuesEnd
addbyte gBattleCommunication, 1
jumpifbytenotequal gBattleCommunication, gBattlersCount, BattleScript_DamageNonTypesLoop
BattleScript_DamageNonTypesContinuesEnd::
bicword gHitMarker, HITMARKER_SKIP_DMG_TRACK | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE | HITMARKER_GRUDGE
end2
BattleScript_PokemonCantUseTheMove::
attackstring
ppreduce

View file

@ -224,6 +224,8 @@ struct SideTimer
u8 followmeTarget:3;
u8 followmePowder:1; // Rage powder, does not affect grass type pokemon.
u8 retaliateTimer;
u8 damageNonTypesTimer;
u8 damageNonTypesType;
};
struct FieldTimer

View file

@ -40,7 +40,7 @@ enum MaxMoveEffect
MAX_EFFECT_HEAL_TEAM,
MAX_EFFECT_SPITE,
MAX_EFFECT_GRAVITY,
MAX_EFFECT_VOLCAITH_FOES,
MAX_EFFECT_VOLCALITH,
MAX_EFFECT_SANDBLAST_FOES,
MAX_EFFECT_YAWN_FOE,
MAX_EFFECT_LOWER_EVASIVENESS_FOES,
@ -56,5 +56,6 @@ bool8 ShouldUseMaxMove(u16 battlerId, u16 baseMove);
u16 GetMaxMove(u16 battlerId, u16 baseMove);
bool8 IsMaxMove(u16 move);
const u8 *GetMaxMoveName(u16 move);
void ChooseDamageNonTypesString(u8 move);
#endif

View file

@ -454,8 +454,6 @@ extern const u8 BattleScript_HealingWishActivates[];
extern const u8 BattleScript_LunarDanceActivates[];
extern const u8 BattleScript_ShellTrapSetUp[];
extern const u8 BattleScript_StealthRockActivates[];
extern const u8 BattleScript_SteelsurgeActivates[];
extern const u8 BattleScript_SteelsurgeFree[];
// zmoves
extern const u8 BattleScript_ZMoveActivateDamaging[];
@ -471,5 +469,9 @@ extern const u8 BattleScript_EffectRaiseSideStats[];
extern const u8 BattleScript_EffectLowerSideStats[];
extern const u8 BattleScript_EffectSetWeather[];
extern const u8 BattleScript_EffectSetTerrain[];
extern const u8 BattleScript_SteelsurgeActivates[];
extern const u8 BattleScript_SteelsurgeFree[];
extern const u8 BattleScript_DamageNonTypesStarts[];
extern const u8 BattleScript_DamageNonTypesContinues[];
#endif // GUARD_BATTLE_SCRIPTS_H

View file

@ -235,6 +235,7 @@
#define SIDE_STATUS_MAT_BLOCK (1 << 21)
#define SIDE_STATUS_STEELSURGE (1 << 22)
#define SIDE_STATUS_STEELSURGE_DAMAGED (1 << 23)
#define SIDE_STATUS_DAMAGE_NON_TYPES (1 << 24)
#define SIDE_STATUS_HAZARDS_ANY (SIDE_STATUS_SPIKES | SIDE_STATUS_STICKY_WEB | SIDE_STATUS_TOXIC_SPIKES | SIDE_STATUS_STEALTH_ROCK | SIDE_STATUS_STEELSURGE)
#define SIDE_STATUS_SCREEN_ANY (SIDE_STATUS_REFLECT | SIDE_STATUS_LIGHTSCREEN | SIDE_STATUS_AURORA_VEIL)
@ -379,8 +380,9 @@
#define MOVE_EFFECT_TERRAIN 76
#define MOVE_EFFECT_STEALTH_ROCK 77
#define MOVE_EFFECT_STEELSURGE 78
#define MOVE_EFFECT_DAMAGE_NON_TYPES 79
#define NUM_MOVE_EFFECTS 79
#define NUM_MOVE_EFFECTS 80
#define MOVE_EFFECT_AFFECTS_USER 0x4000
#define MOVE_EFFECT_CERTAIN 0x8000

View file

@ -264,6 +264,7 @@
#define VARIOUS_JUMP_IF_TARGET_NOT_ALLY 172
#define VARIOUS_JUMP_IF_TARGET_ABSENT 173
#define VARIOUS_SET_STEELSURGE 174
#define VARIOUS_DAMAGE_NON_TYPES 175
// Cmd_manipulatedamage
#define DMG_CHANGE_SIGN 0

View file

@ -644,8 +644,16 @@
#define STRINGID_SHARPSTEELFLOATS 642
#define STRINGID_SHARPSTEELDMG 643
#define STRINGID_PKMNBLEWAWAYSHARPSTEEL 644
#define STRINGID_TEAMTRAPPEDWITHVINES 645
#define STRINGID_PKMNHURTBYVINES 646
#define STRINGID_TEAMCAUGHTINVORTEX 647
#define STRINGID_PKMNHURTBYVORTEX 648
#define STRINGID_TEAMSURROUNDEDBYFIRE 649
#define STRINGID_PKMNBURNINGUP 650
#define STRINGID_TEAMSURROUNDEDBYROCKS 651
#define STRINGID_PKMNHURTBYROCKSTHROWN 652
#define BATTLESTRINGS_COUNT 645
#define BATTLESTRINGS_COUNT 653
// This is the string id that gBattleStringsTable starts with.
// String ids before this (e.g. STRINGID_INTROMSG) are not in the table,

View file

@ -71,7 +71,7 @@ static const struct GMaxMove sGMaxMoveTable[] =
{SPECIES_URSHIFU_RAPID_STRIKE_STYLE_GMAX, TYPE_WATER, MOVE_G_MAX_RAPID_FLOW},
};
// Functions:
// Returns whether a move should be converted into a Max Move.
bool8 ShouldUseMaxMove(u16 battlerId, u16 baseMove)
{
// TODO: Raids
@ -82,6 +82,7 @@ bool8 ShouldUseMaxMove(u16 battlerId, u16 baseMove)
return FALSE;
}
// Returns the appropriate Max Move or G-Max Move for a battler to use.
u16 GetMaxMove(u16 battlerId, u16 baseMove)
{
u16 move = baseMove;
@ -103,11 +104,13 @@ u16 GetMaxMove(u16 battlerId, u16 baseMove)
return move;
}
// Returns whether a move is a Max Move or not.
bool8 IsMaxMove(u16 move)
{
return move >= FIRST_MAX_MOVE && move <= LAST_MAX_MOVE;
}
// Returns the full name of a Max Move for the move usage text.
const u8 *GetMaxMoveName(u16 move)
{
if (IsMaxMove(move))
@ -115,3 +118,22 @@ const u8 *GetMaxMoveName(u16 move)
else
return gMaxMoveNames[0]; // Failsafe
}
// Assigns the multistring to use for the "Damage Non- Types" G-Max effect.
void ChooseDamageNonTypesString(u8 type)
{
switch (type) {
case TYPE_GRASS:
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
break;
case TYPE_WATER:
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
break;
case TYPE_FIRE:
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
break;
case TYPE_ROCK:
gBattleCommunication[MULTISTRING_CHOOSER] = 3;
break;
}
}

View file

@ -779,9 +779,25 @@ static const u8 sText_ShellTrapDidntWork[] = _("{B_ATK_NAME_WITH_PREFIX}'s shell
static const u8 sText_SharpSteelFloats[] = _("Sharp-pointed steel floats\naround {B_DEF_TEAM2} team!");
static const u8 sText_SharpSteelDmg[] = _("Sharp steel bit into {B_DEF_NAME_WITH_PREFIX}!");
static const u8 sText_PkmnBlewAwaySharpSteel[] = _("{B_ATK_NAME_WITH_PREFIX} blew away\nsharp steel!");
static const u8 sText_TeamTrappedWithVines[] = _("{B_DEF_TEAM1} team got trapped\nwith vines!");
static const u8 sText_PkmnHurtByVines[] = _("{B_ATK_NAME_WITH_PREFIX} is hurt by\nG-Max Vine Lash's ferocious beating!");
static const u8 sText_TeamCaughtInVortex[] = _("{B_DEF_TEAM1} team got caught\nin a vortex of water!");
static const u8 sText_PkmnHurtByVortex[] = _("{B_ATK_NAME_WITH_PREFIX} is hurt by\nG-Max Cannonade's vortex!");
static const u8 sText_TeamSurroundedByFire[] = _("{B_DEF_TEAM1} team was surrounded\nby flames!");
static const u8 sText_PkmnBurningUp[] = _("{B_ATK_NAME_WITH_PREFIX} is burning up\nwithin G-Max Wildfire's flames!");
static const u8 sText_TeamSurroundedByRocks[] = _("{B_DEF_TEAM1} team was surrounded\nby rocks!");
static const u8 sText_PkmnHurtByRocksThrown[] = _("{B_ATK_NAME_WITH_PREFIX} is hurt by\nrocks thrown out by G-Max Volcalith!");
const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
{
[STRINGID_PKMNHURTBYROCKSTHROWN - BATTLESTRINGS_TABLE_START] = sText_PkmnHurtByRocksThrown,
[STRINGID_TEAMSURROUNDEDBYROCKS - BATTLESTRINGS_TABLE_START] = sText_TeamSurroundedByRocks,
[STRINGID_PKMNBURNINGUP - BATTLESTRINGS_TABLE_START] = sText_PkmnBurningUp,
[STRINGID_TEAMSURROUNDEDBYFIRE - BATTLESTRINGS_TABLE_START] = sText_TeamSurroundedByFire,
[STRINGID_PKMNHURTBYVORTEX - BATTLESTRINGS_TABLE_START] = sText_PkmnHurtByVortex,
[STRINGID_TEAMCAUGHTINVORTEX - BATTLESTRINGS_TABLE_START] = sText_TeamCaughtInVortex,
[STRINGID_PKMNHURTBYVINES - BATTLESTRINGS_TABLE_START] = sText_PkmnHurtByVines,
[STRINGID_TEAMTRAPPEDWITHVINES - BATTLESTRINGS_TABLE_START] = sText_TeamTrappedWithVines,
[STRINGID_PKMNBLEWAWAYSHARPSTEEL - BATTLESTRINGS_TABLE_START] = sText_PkmnBlewAwaySharpSteel,
[STRINGID_SHARPSTEELDMG - BATTLESTRINGS_TABLE_START] = sText_SharpSteelDmg,
[STRINGID_SHARPSTEELFLOATS - BATTLESTRINGS_TABLE_START] = sText_SharpSteelFloats,
@ -1877,6 +1893,16 @@ const u16 gStatusConditionsStringIds[] =
STRINGID_PKMNWASPOISONED, STRINGID_PKMNBADLYPOISONED, STRINGID_PKMNWASBURNED, STRINGID_PKMNWASPARALYZED, STRINGID_PKMNFELLASLEEP
};
const u16 gDamageNonTypesStartStringIds[] =
{
STRINGID_TEAMTRAPPEDWITHVINES, STRINGID_TEAMCAUGHTINVORTEX, STRINGID_TEAMSURROUNDEDBYFIRE, STRINGID_TEAMSURROUNDEDBYROCKS
};
const u16 gDamageNonTypesDmgStringIds[] =
{
STRINGID_PKMNHURTBYVINES, STRINGID_PKMNHURTBYVORTEX, STRINGID_PKMNBURNINGUP, STRINGID_PKMNHURTBYROCKSTHROWN
};
const u8 gText_PkmnIsEvolving[] = _("What?\n{STR_VAR_1} is evolving!");
const u8 gText_CongratsPkmnEvolved[] = _("Congratulations! Your {STR_VAR_1}\nevolved into {STR_VAR_2}!{WAIT_SE}\p");
const u8 gText_PkmnStoppedEvolving[] = _("Huh? {STR_VAR_1}\nstopped evolving!\p");

View file

@ -3845,6 +3845,20 @@ void SetMoveEffect(bool32 primary, u32 certain)
gBattlescriptCurrInstr = BattleScript_SteelsurgeActivates;
}
break;
case MOVE_EFFECT_DAMAGE_NON_TYPES:
{
side = GetBattlerSide(gEffectBattler);
if (!(gSideStatuses[side] & SIDE_STATUS_DAMAGE_NON_TYPES))
{
gSideStatuses[side] |= SIDE_STATUS_DAMAGE_NON_TYPES;
gSideTimers[side].damageNonTypesTimer = 4;
gSideTimers[side].damageNonTypesType = gBattleMoves[gCurrentMove].type;
BattleScriptPush(gBattlescriptCurrInstr + 1);
ChooseDamageNonTypesString(gBattleMoves[gCurrentMove].type);
gBattlescriptCurrInstr = BattleScript_DamageNonTypesStarts;
}
break;
}
}
}
}
@ -11281,11 +11295,17 @@ static void Cmd_various(void)
gBattleScripting.moveEffect = MOVE_EFFECT_WEATHER;
break;
case MAX_EFFECT_MISTY_TERRAIN:
case MAX_EFFECT_GRASSY_TERRAIN: // TODO: Grassy terrain not working?
case MAX_EFFECT_GRASSY_TERRAIN:
case MAX_EFFECT_ELECTRIC_TERRAIN:
case MAX_EFFECT_PSYCHIC_TERRAIN:
gBattleScripting.moveEffect = MOVE_EFFECT_TERRAIN;
break;
case MAX_EFFECT_VINE_LASH:
case MAX_EFFECT_CANNONADE:
case MAX_EFFECT_WILDFIRE:
case MAX_EFFECT_VOLCALITH:
gBattleScripting.moveEffect = MOVE_EFFECT_DAMAGE_NON_TYPES;
break;
case MAX_EFFECT_STEALTH_ROCK:
gBattleScripting.moveEffect = MOVE_EFFECT_STEALTH_ROCK;
break;
@ -11329,6 +11349,22 @@ static void Cmd_various(void)
}
return;
}
case VARIOUS_DAMAGE_NON_TYPES:
{
VARIOUS_ARGS();
side = GetBattlerSide(gBattlerAttacker);
gBattleMoveDamage = 0;
if (gSideTimers[side].damageNonTypesTimer
&& !IS_BATTLER_OF_TYPE(gBattlerAttacker, gSideTimers[side].damageNonTypesType)
&& IsBattlerAlive(gBattlerAttacker)
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD)
{
gBattleMoveDamage = gBattleMons[gBattlerAttacker].maxHP / 6;
if (gBattleMoveDamage == 0)
gBattleMoveDamage = 1;
}
break;
}
} // End of switch (cmd->id)
gBattlescriptCurrInstr = cmd->nextInstr;

View file

@ -2117,6 +2117,7 @@ enum
ENDTURN_SANDSTORM,
ENDTURN_SUN,
ENDTURN_HAIL,
ENDTURN_DAMAGE_NON_TYPES,
ENDTURN_GRAVITY,
ENDTURN_WATER_SPORT,
ENDTURN_MUD_SPORT,
@ -2458,6 +2459,34 @@ u8 DoFieldEndTurnEffects(void)
}
gBattleStruct->turnCountersTracker++;
break;
case ENDTURN_DAMAGE_NON_TYPES:
while (gBattleStruct->turnSideTracker < 2)
{
side = gBattleStruct->turnSideTracker;
if (gSideStatuses[side] & SIDE_STATUS_DAMAGE_NON_TYPES)
{
if (--gSideTimers[side].damageNonTypesTimer == 0)
{
gSideStatuses[side] &= ~SIDE_STATUS_DAMAGE_NON_TYPES;
//gBattlescriptCurrInstr = BattleScript_DamageNonTypesEnds; TODO: no end message in-game?
effect++;
}
else
{
ChooseDamageNonTypesString(gSideTimers[side].damageNonTypesType);
BattleScriptExecute(BattleScript_DamageNonTypesContinues);
}
}
gBattleStruct->turnSideTracker++;
if (effect != 0)
break;
}
if (!effect)
{
gBattleStruct->turnCountersTracker++;
gBattleStruct->turnSideTracker = 0;
}
break;
case ENDTURN_TRICK_ROOM:
if (gFieldStatuses & STATUS_FIELD_TRICK_ROOM && --gFieldTimers.trickRoomTimer == 0)
{

View file

@ -15613,7 +15613,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.priority = 0,
.flags = 0,
.split = SPLIT_PHYSICAL,
.argument = MAX_EFFECT_VOLCAITH_FOES,
.argument = MAX_EFFECT_VOLCALITH,
},
[MOVE_G_MAX_TARTNESS] =