mirror of
https://github.com/rh-hideout/pokeemerald-expansion.git
synced 2026-03-21 18:04:50 -05:00
Simplify defrosting/thawing and expand target thawing config (#9271)
This commit is contained in:
parent
12d16aad16
commit
8e3183a7a9
|
|
@ -5644,26 +5644,14 @@ BattleScript_MoveUsedIsFrozen::
|
|||
statusanimation BS_ATTACKER
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_MoveUsedUnfroze::
|
||||
BattleScript_BattlerDefrosted::
|
||||
printfromtable gGotDefrostedStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
updatestatusicon BS_ATTACKER
|
||||
return
|
||||
|
||||
BattleScript_MoveUsedUnfrostbite::
|
||||
printfromtable gFrostbiteHealedStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
updatestatusicon BS_ATTACKER
|
||||
return
|
||||
|
||||
BattleScript_DefrostedViaFireMove::
|
||||
printstring STRINGID_PKMNWASDEFROSTED
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
updatestatusicon BS_SCRIPTING
|
||||
return
|
||||
|
||||
BattleScript_FrostbiteHealedViaFireMove::
|
||||
printstring STRINGID_PKMNFROSTBITEHEALED
|
||||
BattleScript_BattlerFrostbiteHealed::
|
||||
printfromtable gFrostbiteHealedStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
updatestatusicon BS_SCRIPTING
|
||||
return
|
||||
|
|
|
|||
|
|
@ -601,7 +601,8 @@ struct BattleStruct
|
|||
u8 sleepClauseNotBlocked:1;
|
||||
u8 isSkyBattle:1;
|
||||
u8 unableToUseMove:1; // for the current action only, to check if the battler failed to act at end turn use the DisableStruct member
|
||||
u8 unused:4;
|
||||
u8 triAttackBurn:1;
|
||||
u8 unused:3;
|
||||
void (*savedCallback)(void);
|
||||
u16 chosenItem[MAX_BATTLERS_COUNT];
|
||||
u16 choicedMove[MAX_BATTLERS_COUNT];
|
||||
|
|
|
|||
|
|
@ -68,7 +68,9 @@ bool32 ProteanTryChangeType(enum BattlerId battler, enum Ability ability, enum M
|
|||
u8 GetFirstFaintedPartyIndex(enum BattlerId battler);
|
||||
void SaveBattlerTarget(enum BattlerId battler);
|
||||
void SaveBattlerAttacker(enum BattlerId battler);
|
||||
bool32 CanBurnHitThaw(enum Ability abilityAtk, enum Move move);
|
||||
bool32 CanBurnHitThaw(enum Move move);
|
||||
bool32 CanMoveThawTarget(enum Ability abilityAtk, enum Move move);
|
||||
bool32 CanFireMoveThawTarget(enum Move move);
|
||||
|
||||
extern void (*const gBattleScriptingCommandsTable[])(void);
|
||||
extern const struct StatFractions gAccuracyStageRatios[];
|
||||
|
|
|
|||
|
|
@ -126,10 +126,8 @@ extern const u8 BattleScript_PoisonTurnDmg[];
|
|||
extern const u8 BattleScript_BurnTurnDmg[];
|
||||
extern const u8 BattleScript_FrostbiteTurnDmg[];
|
||||
extern const u8 BattleScript_MoveUsedIsFrozen[];
|
||||
extern const u8 BattleScript_MoveUsedUnfroze[];
|
||||
extern const u8 BattleScript_MoveUsedUnfrostbite[];
|
||||
extern const u8 BattleScript_DefrostedViaFireMove[];
|
||||
extern const u8 BattleScript_FrostbiteHealedViaFireMove[];
|
||||
extern const u8 BattleScript_BattlerDefrosted[];
|
||||
extern const u8 BattleScript_BattlerFrostbiteHealed[];
|
||||
extern const u8 BattleScript_MoveUsedIsParalyzed[];
|
||||
extern const u8 BattleScript_MoveUsedFlinched[];
|
||||
extern const u8 BattleScript_PrintUproarOverTurns[];
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@
|
|||
#define B_TELEPORT_BEHAVIOR GEN_LATEST // In LGPE onwards (Gen8+ here), Teleport allows the user to swap out with another party member.
|
||||
#define B_BEAT_UP GEN_LATEST // In Gen5+, Beat Up uses a different formula to calculate its damage, and deals Dark-type damage. Prior to Gen 5, each hit also announces the party member's name.
|
||||
#define B_DARK_VOID_FAIL GEN_LATEST // In Gen7+, only Darkrai can use Dark Void.
|
||||
#define B_BURN_HIT_THAW GEN_LATEST // In Gen6+, damaging moves with a chance of burn will thaw the target, regardless if they're fire-type moves or not.
|
||||
#define B_HIT_THAW GEN_LATEST // In Gen6+, damaging moves that thaw the user will thaw the target. In Gen 3+, Fire-type moves thaw the target. In Gen 1-2, damaging moves that can burn will thaw the target, regardless if they can be burned or not.
|
||||
#define B_HEALING_WISH_SWITCH GEN_LATEST // In Gen5+, the mon receiving Healing Wish is sent out at the end of the turn.
|
||||
// Additionally, in gen8+ the Healing Wish's effect will be stored until the user switches into a statused or hurt mon.
|
||||
#define B_DEFOG_EFFECT_CLEARING GEN_LATEST // In Gen5+, Defog does not lower Evasion of target behind Subsitute. In Gen6+, Defog clears Spikes, Toxic Spikes, Stealth Rock and Sticky Web from both sides. In Gen8+, Defog also clears active Terrain.
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@ enum StringID
|
|||
STRINGID_PKMNFROZENBY,
|
||||
STRINGID_PKMNISFROZEN,
|
||||
STRINGID_PKMNWASDEFROSTED,
|
||||
STRINGID_PKMNWASDEFROSTED2,
|
||||
STRINGID_PKMNWASDEFROSTEDBY,
|
||||
STRINGID_PKMNWASPARALYZED,
|
||||
STRINGID_PKMNWASPARALYZEDBY,
|
||||
|
|
@ -629,7 +628,6 @@ enum StringID
|
|||
STRINGID_PKMNSITEMHEALEDFROSTBITE,
|
||||
STRINGID_ATTACKERHEALEDITSFROSTBITE,
|
||||
STRINGID_PKMNFROSTBITEHEALED,
|
||||
STRINGID_PKMNFROSTBITEHEALED2,
|
||||
STRINGID_PKMNFROSTBITEHEALEDBY,
|
||||
STRINGID_MIRRORHERBCOPIED,
|
||||
STRINGID_STARTEDSNOW,
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@
|
|||
F(B_TELEPORT_BEHAVIOR, teleportBehavior, (u32, GEN_COUNT - 1)) \
|
||||
F(B_BEAT_UP, beatUp, (u32, GEN_COUNT - 1)) \
|
||||
F(B_DARK_VOID_FAIL, darkVoidFail, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
|
||||
F(B_BURN_HIT_THAW, burnHitThaw, (u32, GEN_COUNT - 1)) \
|
||||
F(B_HIT_THAW, hitThaw, (u32, GEN_COUNT - 1)) \
|
||||
F(B_HEALING_WISH_SWITCH, healingWishSwitch, (u32, GEN_COUNT - 1)) \
|
||||
F(B_DEFOG_EFFECT_CLEARING, defogEffectClearing, (u32, GEN_COUNT - 1)) \
|
||||
F(B_STOCKPILE_RAISES_DEFS, stockpileRaisesDefs, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
|
||||
|
|
|
|||
|
|
@ -1203,13 +1203,14 @@ static s32 AI_CheckBadMove(enum BattlerId battlerAtk, enum BattlerId battlerDef,
|
|||
}
|
||||
|
||||
// Don't use anything but super effective thawing moves if target is frozen if any other attack available
|
||||
if (((GetMoveType(move) == TYPE_FIRE && GetMovePower(move) != 0) || CanBurnHitThaw(abilityAtk, move)) && effectiveness < UQ_4_12(2.0) && (gBattleMons[battlerDef].status1 & STATUS1_ICY_ANY))
|
||||
if ((CanFireMoveThawTarget(move) || CanBurnHitThaw(move) || CanMoveThawTarget(abilityAtk, move))
|
||||
&& effectiveness < UQ_4_12(2.0) && (gBattleMons[battlerDef].status1 & STATUS1_ICY_ANY))
|
||||
{
|
||||
enum Move aiMove;
|
||||
for (u32 moveIndex = 0; moveIndex < MAX_MON_MOVES; moveIndex++)
|
||||
{
|
||||
aiMove = gBattleMons[battlerAtk].moves[moveIndex];
|
||||
if (GetMoveType(aiMove) != TYPE_FIRE && !CanBurnHitThaw(abilityAtk, aiMove) && GetMovePower(gBattleMons[battlerAtk].moves[moveIndex]) != 0)
|
||||
if (!CanFireMoveThawTarget(aiMove) && !CanBurnHitThaw(aiMove) && !CanMoveThawTarget(abilityAtk, aiMove))
|
||||
{
|
||||
ADJUST_SCORE(-1);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -230,8 +230,7 @@ const u8 *const gBattleStringsTable[STRINGID_COUNT] =
|
|||
[STRINGID_PKMNFROZENBY] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_BUFF1} froze {B_EFF_NAME_WITH_PREFIX2} solid!"), //not in gen 5+, ability popup
|
||||
[STRINGID_PKMNISFROZEN] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} is frozen solid!"),
|
||||
[STRINGID_PKMNWASDEFROSTED] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} thawed out!"),
|
||||
[STRINGID_PKMNWASDEFROSTED2] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} thawed out!"),
|
||||
[STRINGID_PKMNWASDEFROSTEDBY] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s {B_CURRENT_MOVE} melted the ice!"),
|
||||
[STRINGID_PKMNWASDEFROSTEDBY] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_CURRENT_MOVE} melted the ice!"),
|
||||
[STRINGID_PKMNWASPARALYZED] = COMPOUND_STRING("{B_EFF_NAME_WITH_PREFIX} is paralyzed, so it may be unable to move!"),
|
||||
[STRINGID_PKMNWASPARALYZEDBY] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_BUFF1} paralyzed {B_EFF_NAME_WITH_PREFIX2}, so it may be unable to move!"), //not in gen 5+, ability popup
|
||||
[STRINGID_PKMNISPARALYZED] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} couldn't move because it's paralyzed!"),
|
||||
|
|
@ -806,8 +805,7 @@ const u8 *const gBattleStringsTable[STRINGID_COUNT] =
|
|||
[STRINGID_PKMNSITEMHEALEDFROSTBITE] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_LAST_ITEM} cured its frostbite!"),
|
||||
[STRINGID_ATTACKERHEALEDITSFROSTBITE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} cured its frostbite through sheer determination so you wouldn't worry!"),
|
||||
[STRINGID_PKMNFROSTBITEHEALED] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s frostbite was cured!"),
|
||||
[STRINGID_PKMNFROSTBITEHEALED2] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s frostbite was cured!"),
|
||||
[STRINGID_PKMNFROSTBITEHEALEDBY] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s {B_CURRENT_MOVE} cured its frostbite!"),
|
||||
[STRINGID_PKMNFROSTBITEHEALEDBY] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_CURRENT_MOVE} cured its frostbite!"),
|
||||
[STRINGID_MIRRORHERBCOPIED] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} used its Mirror Herb to mirror its opponent's stat changes!"),
|
||||
[STRINGID_STARTEDSNOW] = COMPOUND_STRING("It started to snow!"),
|
||||
[STRINGID_SNOWCONTINUES] = COMPOUND_STRING("Snow continues to fall."), //not in gen 5+ (lol)
|
||||
|
|
@ -1212,7 +1210,7 @@ const u16 gGotFrostbiteStringIds[] =
|
|||
|
||||
const u16 gFrostbiteHealedStringIds[] =
|
||||
{
|
||||
[B_MSG_FROSTBITE_HEALED] = STRINGID_PKMNFROSTBITEHEALED2,
|
||||
[B_MSG_FROSTBITE_HEALED] = STRINGID_PKMNFROSTBITEHEALED,
|
||||
[B_MSG_FROSTBITE_HEALED_BY_MOVE] = STRINGID_PKMNFROSTBITEHEALEDBY
|
||||
};
|
||||
|
||||
|
|
@ -1224,7 +1222,7 @@ const u16 gGotFrozenStringIds[] =
|
|||
|
||||
const u16 gGotDefrostedStringIds[] =
|
||||
{
|
||||
[B_MSG_DEFROSTED] = STRINGID_PKMNWASDEFROSTED2,
|
||||
[B_MSG_DEFROSTED] = STRINGID_PKMNWASDEFROSTED,
|
||||
[B_MSG_DEFROSTED_BY_MOVE] = STRINGID_PKMNWASDEFROSTEDBY
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ static enum Move GetOriginallyUsedMove(enum Move chosenMove);
|
|||
static void SetSameMoveTurnValues(enum BattleMoveEffects moveEffect);
|
||||
static void TryClearChargeVolatile(enum Type moveType);
|
||||
static inline bool32 IsBattlerUsingBeakBlast(enum BattlerId battler);
|
||||
static void RequestNonVolatileChangee(enum BattlerId battlerAtk);
|
||||
static void RequestNonVolatileChange(enum BattlerId battlerAtk);
|
||||
static bool32 CanBattlerBounceBackMove(struct BattleContext *ctx);
|
||||
static bool32 TryMagicBounce(struct BattleContext *ctx);
|
||||
static bool32 TryMagicCoat(struct BattleContext *ctx);
|
||||
|
|
@ -97,6 +97,13 @@ static enum CancelerResult CancelerChillyReception(struct BattleContext *ctx)
|
|||
return CANCELER_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
static void DefrostBattler(enum BattlerId battler, u32 status)
|
||||
{
|
||||
gBattleScripting.battler = battler;
|
||||
gBattleMons[battler].status1 &= ~status;
|
||||
RequestNonVolatileChange(battler);
|
||||
}
|
||||
|
||||
static enum CancelerResult CancelerAsleepOrFrozen(struct BattleContext *ctx)
|
||||
{
|
||||
enum CancelerResult result = CANCELER_RESULT_BREAK;
|
||||
|
|
@ -153,7 +160,7 @@ static enum CancelerResult CancelerAsleepOrFrozen(struct BattleContext *ctx)
|
|||
BattleScriptCall(BattleScript_MoveUsedWokeUp);
|
||||
}
|
||||
}
|
||||
RequestNonVolatileChangee(ctx->battlerAtk);
|
||||
RequestNonVolatileChange(ctx->battlerAtk);
|
||||
}
|
||||
else if (gBattleMons[ctx->battlerAtk].status1 & STATUS1_FREEZE && !MoveThawsUser(ctx->move))
|
||||
{
|
||||
|
|
@ -164,12 +171,11 @@ static enum CancelerResult CancelerAsleepOrFrozen(struct BattleContext *ctx)
|
|||
}
|
||||
else // unfreeze
|
||||
{
|
||||
gBattleMons[ctx->battlerAtk].status1 &= ~STATUS1_FREEZE;
|
||||
DefrostBattler(ctx->battlerAtk, STATUS1_FREEZE);
|
||||
result = CANCELER_RESULT_BREAK;
|
||||
BattleScriptCall(BattleScript_MoveUsedUnfroze);
|
||||
BattleScriptCall(BattleScript_BattlerDefrosted);
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_DEFROSTED;
|
||||
}
|
||||
RequestNonVolatileChangee(ctx->battlerAtk);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
@ -564,35 +570,36 @@ static enum CancelerResult CancelerThaw(struct BattleContext *ctx)
|
|||
{
|
||||
enum CancelerResult result = CANCELER_RESULT_BREAK;
|
||||
|
||||
if (gBattleMons[ctx->battlerAtk].status1 & STATUS1_FREEZE)
|
||||
if (MoveThawsUser(ctx->move))
|
||||
{
|
||||
if (!(IsMoveEffectRemoveSpeciesType(ctx->move, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_FIRE) && !IS_BATTLER_OF_TYPE(ctx->battlerAtk, TYPE_FIRE)))
|
||||
if (gBattleMons[ctx->battlerAtk].status1 & STATUS1_FREEZE)
|
||||
{
|
||||
gBattleMons[ctx->battlerAtk].status1 &= ~STATUS1_FREEZE;
|
||||
result = CANCELER_RESULT_BREAK;
|
||||
BattleScriptCall(BattleScript_MoveUsedUnfroze);
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_DEFROSTED_BY_MOVE;
|
||||
if (!IsMoveEffectRemoveSpeciesType(ctx->move, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_FIRE) || IS_BATTLER_OF_TYPE(ctx->battlerAtk, TYPE_FIRE))
|
||||
{
|
||||
DefrostBattler(ctx->battlerAtk, STATUS1_FREEZE);
|
||||
result = CANCELER_RESULT_BREAK;
|
||||
BattleScriptCall(BattleScript_BattlerDefrosted);
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_DEFROSTED_BY_MOVE;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = CANCELER_RESULT_FAILURE;
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (gBattleMons[ctx->battlerAtk].status1 & STATUS1_FROSTBITE)
|
||||
{
|
||||
result = CANCELER_RESULT_FAILURE;
|
||||
if (!IsMoveEffectRemoveSpeciesType(ctx->move, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_FIRE) || IS_BATTLER_OF_TYPE(ctx->battlerAtk, TYPE_FIRE))
|
||||
{
|
||||
DefrostBattler(ctx->battlerAtk, STATUS1_FROSTBITE);
|
||||
result = CANCELER_RESULT_BREAK;
|
||||
BattleScriptCall(BattleScript_BattlerFrostbiteHealed);
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_FROSTBITE_HEALED_BY_MOVE;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = CANCELER_RESULT_FAILURE;
|
||||
}
|
||||
}
|
||||
RequestNonVolatileChangee(ctx->battlerAtk);
|
||||
}
|
||||
else if (gBattleMons[ctx->battlerAtk].status1 & STATUS1_FROSTBITE && MoveThawsUser(ctx->move))
|
||||
{
|
||||
if (!(IsMoveEffectRemoveSpeciesType(ctx->move, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_FIRE) && !IS_BATTLER_OF_TYPE(ctx->battlerAtk, TYPE_FIRE)))
|
||||
{
|
||||
gBattleMons[ctx->battlerAtk].status1 &= ~STATUS1_FROSTBITE;
|
||||
result = CANCELER_RESULT_BREAK;
|
||||
BattleScriptCall(BattleScript_MoveUsedUnfrostbite);
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_FROSTBITE_HEALED_BY_MOVE;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = CANCELER_RESULT_FAILURE;
|
||||
}
|
||||
RequestNonVolatileChangee(ctx->battlerAtk);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -2827,17 +2834,10 @@ static enum MoveEndResult MoveEndMultihitMove(void)
|
|||
return result;
|
||||
}
|
||||
|
||||
static void DefrostBattler(enum BattlerId battler, u32 status)
|
||||
{
|
||||
gBattleScripting.battler = battler;
|
||||
gBattleMons[battler].status1 &= ~status;
|
||||
BtlController_EmitSetMonData(battler, B_COMM_TO_CONTROLLER, REQUEST_STATUS_BATTLE, 0, sizeof(gBattleMons[battler].status1), &gBattleMons[battler].status1);
|
||||
MarkBattlerForControllerExec(battler);
|
||||
}
|
||||
|
||||
static enum MoveEndResult MoveEndDefrost(void)
|
||||
{
|
||||
enum Ability abilityAtk = GetBattlerAbility(gBattlerAttacker);
|
||||
const u8 *battleScript = NULL;
|
||||
|
||||
while (gBattleStruct->eventState.moveEndBattler < gBattlersCount)
|
||||
{
|
||||
|
|
@ -2846,32 +2846,29 @@ static enum MoveEndResult MoveEndDefrost(void)
|
|||
if (battler == gBattlerAttacker)
|
||||
continue;
|
||||
|
||||
if (gBattleMons[battler].status1 & STATUS1_FREEZE
|
||||
&& IsBattlerTurnDamaged(battler)
|
||||
&& IsBattlerAlive(battler)
|
||||
&& GetBattleMoveType(gCurrentMove) == TYPE_FIRE)
|
||||
if (!(gBattleMons[battler].status1 & STATUS1_ICY_ANY)
|
||||
|| !IsBattlerTurnDamaged(battler)
|
||||
|| !IsBattlerAlive(battler))
|
||||
continue;
|
||||
|
||||
if (gBattleMons[battler].status1 & STATUS1_FREEZE)
|
||||
battleScript = BattleScript_BattlerDefrosted;
|
||||
else
|
||||
battleScript = BattleScript_BattlerFrostbiteHealed;
|
||||
|
||||
if ((CanFireMoveThawTarget(gCurrentMove) || CanBurnHitThaw(gCurrentMove)) && gBattleMons[battler].status1 & STATUS1_FREEZE)
|
||||
{
|
||||
DefrostBattler(battler, STATUS1_FREEZE);
|
||||
BattleScriptCall(BattleScript_DefrostedViaFireMove);
|
||||
DefrostBattler(battler, gBattleMons[battler].status1);
|
||||
BattleScriptCall(battleScript);
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_DEFROSTED;
|
||||
return MOVEEND_RESULT_RUN_SCRIPT;
|
||||
}
|
||||
else if (gBattleMons[battler].status1 & STATUS1_FREEZE
|
||||
&& IsBattlerTurnDamaged(battler)
|
||||
&& IsBattlerAlive(battler)
|
||||
&& IsBattlerAlive(gBattlerAttacker)
|
||||
&& CanBurnHitThaw(abilityAtk, gCurrentMove))
|
||||
else if (IsBattlerAlive(gBattlerAttacker)
|
||||
&& CanMoveThawTarget(abilityAtk, gCurrentMove))
|
||||
{
|
||||
DefrostBattler(battler, STATUS1_FREEZE);
|
||||
BattleScriptCall(BattleScript_DefrostedViaFireMove);
|
||||
return MOVEEND_RESULT_RUN_SCRIPT;
|
||||
}
|
||||
else if (gBattleMons[battler].status1 & STATUS1_FROSTBITE
|
||||
&& IsBattlerTurnDamaged(battler)
|
||||
&& IsBattlerAlive(battler)
|
||||
&& MoveThawsUser(GetOriginallyUsedMove(gChosenMove)))
|
||||
{
|
||||
DefrostBattler(battler, STATUS1_FROSTBITE);
|
||||
BattleScriptCall(BattleScript_FrostbiteHealedViaFireMove);
|
||||
DefrostBattler(battler, gBattleMons[battler].status1);
|
||||
BattleScriptCall(battleScript);
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_DEFROSTED;
|
||||
return MOVEEND_RESULT_RUN_SCRIPT;
|
||||
}
|
||||
}
|
||||
|
|
@ -3692,6 +3689,7 @@ static enum MoveEndResult MoveEndClearBits(void)
|
|||
gBattleStruct->swapDamageCategory = FALSE;
|
||||
gBattleStruct->categoryOverride = FALSE;
|
||||
gBattleStruct->additionalEffectsCounter = 0;
|
||||
gBattleStruct->triAttackBurn = FALSE;
|
||||
gBattleStruct->poisonPuppeteerConfusion = FALSE;
|
||||
gBattleStruct->fickleBeamBoosted = FALSE;
|
||||
gBattleStruct->battlerState[gBattlerAttacker].usedMicleBerry = FALSE;
|
||||
|
|
@ -3964,14 +3962,14 @@ void MoveValuesCleanUp(void)
|
|||
gBattleCommunication[MISS_TYPE] = 0;
|
||||
}
|
||||
|
||||
static void RequestNonVolatileChangee(enum BattlerId battlerAtk)
|
||||
static void RequestNonVolatileChange(enum BattlerId battlerAtk)
|
||||
{
|
||||
BtlController_EmitSetMonData(
|
||||
battlerAtk,
|
||||
B_COMM_TO_CONTROLLER,
|
||||
REQUEST_STATUS_BATTLE,
|
||||
0,
|
||||
4,
|
||||
sizeof(gBattleMons[battlerAtk].status1),
|
||||
&gBattleMons[battlerAtk].status1);
|
||||
MarkBattlerForControllerExec(battlerAtk);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2554,21 +2554,21 @@ void SetMoveEffect(enum BattlerId battlerAtk, enum BattlerId effectBattler, enum
|
|||
gBattlescriptCurrInstr = battleScript;
|
||||
break;
|
||||
case MOVE_EFFECT_TRI_ATTACK:
|
||||
if (gBattleMons[gEffectBattler].status1)
|
||||
{
|
||||
static const u8 sTriAttackEffects[] =
|
||||
{
|
||||
gBattlescriptCurrInstr = battleScript;
|
||||
}
|
||||
else
|
||||
{
|
||||
static const u8 sTriAttackEffects[] =
|
||||
{
|
||||
MOVE_EFFECT_BURN,
|
||||
MOVE_EFFECT_FREEZE_OR_FROSTBITE,
|
||||
MOVE_EFFECT_PARALYSIS
|
||||
};
|
||||
SetMoveEffect(battlerAtk, effectBattler, RandomElement(RNG_TRI_ATTACK, sTriAttackEffects), battleScript, effectFlags);
|
||||
}
|
||||
MOVE_EFFECT_BURN,
|
||||
MOVE_EFFECT_FREEZE_OR_FROSTBITE,
|
||||
MOVE_EFFECT_PARALYSIS
|
||||
};
|
||||
u32 chosenMoveEffect = RandomUniform(RNG_TRI_ATTACK, 0, ARRAY_COUNT(sTriAttackEffects) - 1);
|
||||
if (sTriAttackEffects[chosenMoveEffect] == MOVE_EFFECT_BURN)
|
||||
gBattleStruct->triAttackBurn = TRUE;
|
||||
|
||||
if (!gBattleMons[effectBattler].status1)
|
||||
SetMoveEffect(battlerAtk, effectBattler, sTriAttackEffects[chosenMoveEffect], battleScript, effectFlags);
|
||||
break;
|
||||
}
|
||||
case MOVE_EFFECT_WRAP:
|
||||
if (gBattleMons[gEffectBattler].volatiles.wrapped)
|
||||
{
|
||||
|
|
@ -3438,6 +3438,7 @@ void SetMoveEffect(enum BattlerId battlerAtk, enum BattlerId effectBattler, enum
|
|||
if ((gBattleMons[gEffectBattler].status1 & argStatus)
|
||||
&& (NumAffectedSpreadMoveTargets() > 1 || !IsMoveEffectBlockedByTarget(abilities[gEffectBattler])))
|
||||
{
|
||||
gBattleScripting.battler = gEffectBattler;
|
||||
gBattleMons[gEffectBattler].status1 &= ~(argStatus);
|
||||
BtlController_EmitSetMonData(gEffectBattler, 0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gEffectBattler].status1);
|
||||
MarkBattlerForControllerExec(gEffectBattler);
|
||||
|
|
@ -3456,10 +3457,10 @@ void SetMoveEffect(enum BattlerId battlerAtk, enum BattlerId effectBattler, enum
|
|||
gBattlescriptCurrInstr = BattleScript_TargetBurnHeal;
|
||||
break;
|
||||
case STATUS1_FREEZE:
|
||||
gBattlescriptCurrInstr = BattleScript_DefrostedViaFireMove;
|
||||
gBattlescriptCurrInstr = BattleScript_BattlerDefrosted;
|
||||
break;
|
||||
case STATUS1_FROSTBITE:
|
||||
gBattlescriptCurrInstr = BattleScript_FrostbiteHealedViaFireMove;
|
||||
gBattlescriptCurrInstr = BattleScript_BattlerFrostbiteHealed;
|
||||
break;
|
||||
case STATUS1_POISON:
|
||||
case STATUS1_TOXIC_POISON:
|
||||
|
|
@ -11652,11 +11653,11 @@ static bool32 CanAbilityPreventStatLoss(enum Ability abilityDef)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 CanBurnHitThaw(enum Ability abilityAtk, enum Move move)
|
||||
bool32 CanBurnHitThaw(enum Move move)
|
||||
{
|
||||
u8 i;
|
||||
|
||||
if (GetConfig(B_BURN_HIT_THAW) >= GEN_6 && abilityAtk != ABILITY_SHEER_FORCE)
|
||||
if (GetConfig(B_HIT_THAW) <= GEN_2)
|
||||
{
|
||||
u32 numAdditionalEffects = GetMoveAdditionalEffectCount(move);
|
||||
for (i = 0; i < numAdditionalEffects; i++)
|
||||
|
|
@ -11664,11 +11665,25 @@ bool32 CanBurnHitThaw(enum Ability abilityAtk, enum Move move)
|
|||
const struct AdditionalEffect *additionalEffect = GetMoveAdditionalEffectById(move, i);
|
||||
if (additionalEffect->moveEffect == MOVE_EFFECT_BURN)
|
||||
return TRUE;
|
||||
|
||||
if (additionalEffect->moveEffect == MOVE_EFFECT_TRI_ATTACK
|
||||
&& gBattleStruct->triAttackBurn)
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 CanMoveThawTarget(enum Ability abilityAtk, enum Move move)
|
||||
{
|
||||
return GetConfig(B_HIT_THAW) >= GEN_6 && !IsSheerForceAffected(move, abilityAtk) && MoveThawsUser(move);
|
||||
}
|
||||
|
||||
bool32 CanFireMoveThawTarget(enum Move move)
|
||||
{
|
||||
return GetConfig(B_HIT_THAW) >= GEN_3 && GetMoveType(move) == TYPE_FIRE && GetMovePower(move) != 0;
|
||||
}
|
||||
|
||||
void BS_CheckParentalBondCounter(void)
|
||||
{
|
||||
NATIVE_ARGS(u8 counter, const u8 *jumpInstr);
|
||||
|
|
|
|||
|
|
@ -189,7 +189,8 @@ u32 BattlePalace_TryEscapeStatus(enum BattlerId battler)
|
|||
{
|
||||
// Unfreeze
|
||||
gBattleMons[battler].status1 &= ~(STATUS1_FREEZE);
|
||||
BattleScriptCall(BattleScript_MoveUsedUnfroze);
|
||||
gBattleScripting.battler = battler;
|
||||
BattleScriptCall(BattleScript_BattlerDefrosted);
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_DEFROSTED;
|
||||
}
|
||||
effect = 2;
|
||||
|
|
|
|||
|
|
@ -687,7 +687,7 @@ AI_SINGLE_BATTLE_TEST("AI won't use thawing moves if target is frozen unless it
|
|||
PARAMETRIZE { status = STATUS1_FROSTBITE; aiMove = MOVE_EMBER; aiFlags = AI_FLAG_CHECK_BAD_MOVE; }
|
||||
|
||||
GIVEN {
|
||||
WITH_CONFIG(B_BURN_HIT_THAW, GEN_6); // In Gen 5, non-Fire burning moves didn't cause thawing
|
||||
WITH_CONFIG(B_HIT_THAW, GEN_6); // In Gen 5, moves that thawed the user didn't thaw the target
|
||||
ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE);
|
||||
ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
|
||||
ASSUME(GetMoveCategory(MOVE_WATER_GUN) == DAMAGE_CATEGORY_SPECIAL);
|
||||
|
|
|
|||
|
|
@ -14,25 +14,27 @@ SINGLE_BATTLE_TEST("Freeze has a 20% chance of being thawed")
|
|||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Freeze is thawed by opponent's Fire-type attacks")
|
||||
SINGLE_BATTLE_TEST("Freeze is thawed by opponent's Fire-type attacks (Gen 3+)")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE);
|
||||
WITH_CONFIG(B_HIT_THAW, GEN_3);
|
||||
ASSUME(GetMoveType(MOVE_FIRE_SPIN) == TYPE_FIRE);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_FREEZE); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_EMBER); MOVE(player, MOVE_CELEBRATE); }
|
||||
TURN { MOVE(opponent, MOVE_FIRE_SPIN); MOVE(player, MOVE_CELEBRATE); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_EMBER, opponent);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_FIRE_SPIN, opponent);
|
||||
MESSAGE("Wobbuffet thawed out!");
|
||||
STATUS_ICON(player, none: TRUE);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Freeze is thawed by opponent's Fire-type attacks even if Sheer Force affected")
|
||||
SINGLE_BATTLE_TEST("Freeze is thawed by opponent's Fire-type attacks even if Sheer Force affected (Gen 3+)")
|
||||
{
|
||||
GIVEN {
|
||||
WITH_CONFIG(B_HIT_THAW, GEN_3);
|
||||
ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_FREEZE); }
|
||||
OPPONENT(SPECIES_TAUROS) { Ability(ABILITY_SHEER_FORCE); }
|
||||
|
|
@ -46,11 +48,46 @@ SINGLE_BATTLE_TEST("Freeze is thawed by opponent's Fire-type attacks even if She
|
|||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Freeze is thawed by opponent's attack that can burn (Gen 6+)")
|
||||
SINGLE_BATTLE_TEST("Freeze is thawed by opponent's attack that can burn (Gen 1-2)")
|
||||
{
|
||||
GIVEN {
|
||||
WITH_CONFIG(B_BURN_HIT_THAW, GEN_6);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_SCALD, MOVE_EFFECT_BURN));
|
||||
WITH_CONFIG(B_HIT_THAW, GEN_2);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_EMBER, MOVE_EFFECT_BURN));
|
||||
PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_FREEZE); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_EMBER); MOVE(player, MOVE_CELEBRATE); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_EMBER, opponent);
|
||||
MESSAGE("Wobbuffet thawed out!");
|
||||
STATUS_ICON(player, none: TRUE);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Freeze is thawed by opponent's Tri Attack 1/3 of the time (Gen 1-2)")
|
||||
{
|
||||
PASSES_RANDOMLY(1, 3, RNG_TRI_ATTACK);
|
||||
GIVEN {
|
||||
WITH_CONFIG(B_HIT_THAW, GEN_2);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_TRI_ATTACK, MOVE_EFFECT_TRI_ATTACK));
|
||||
PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_FREEZE); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_TRI_ATTACK); MOVE(player, MOVE_CELEBRATE, WITH_RNG(RNG_FROZEN, FALSE)); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TRI_ATTACK, opponent);
|
||||
MESSAGE("Wobbuffet thawed out!");
|
||||
STATUS_ICON(player, none: TRUE);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Freeze is thawed by opponent's attack that can thaw the user (Gen 6+)")
|
||||
{
|
||||
GIVEN {
|
||||
WITH_CONFIG(B_HIT_THAW, GEN_6);
|
||||
ASSUME(MoveThawsUser(MOVE_SCALD));
|
||||
PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_FREEZE); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
|
|
@ -62,24 +99,45 @@ SINGLE_BATTLE_TEST("Freeze is thawed by opponent's attack that can burn (Gen 6+)
|
|||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player);
|
||||
}
|
||||
}
|
||||
SINGLE_BATTLE_TEST("Freeze isn't thawed by opponent's attack that can burn if Sheer Force affected (Gen 6+)")
|
||||
|
||||
SINGLE_BATTLE_TEST("Freeze isn't thawed by opponent's attack that can thaw the user if Sheer Force affected (Gen 6+)")
|
||||
{
|
||||
GIVEN {
|
||||
WITH_CONFIG(B_BURN_HIT_THAW, GEN_6);
|
||||
ASSUME(MoveHasAdditionalEffect(MOVE_SCALD, MOVE_EFFECT_BURN));
|
||||
WITH_CONFIG(B_HIT_THAW, GEN_6);
|
||||
ASSUME(MoveThawsUser(MOVE_SCALD));
|
||||
ASSUME(MoveIsAffectedBySheerForce(MOVE_SCALD));
|
||||
PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_FREEZE); }
|
||||
OPPONENT(SPECIES_TAUROS) { Ability(ABILITY_SHEER_FORCE); }
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_SCALD); }
|
||||
TURN { MOVE(opponent, MOVE_SCALD); MOVE(player, MOVE_CELEBRATE, WITH_RNG(RNG_FROZEN, FALSE)); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SCALD, opponent);
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player);
|
||||
MESSAGE("Wobbuffet thawed out!");
|
||||
STATUS_ICON(player, none: TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Freeze is thawed by opponent's attack that can thaw the user if not Sheer Force affected (Gen 6+)")
|
||||
{
|
||||
GIVEN {
|
||||
WITH_CONFIG(B_HIT_THAW, GEN_6);
|
||||
ASSUME(MoveThawsUser(MOVE_HYDRO_STEAM));
|
||||
ASSUME(!MoveIsAffectedBySheerForce(MOVE_HYDRO_STEAM));
|
||||
PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_FREEZE); }
|
||||
OPPONENT(SPECIES_TAUROS) { Ability(ABILITY_SHEER_FORCE); }
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_HYDRO_STEAM); MOVE(player, MOVE_CELEBRATE); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_HYDRO_STEAM, opponent);
|
||||
MESSAGE("Wobbuffet thawed out!");
|
||||
STATUS_ICON(player, none: TRUE);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Freeze is thawed by user's Flame Wheel")
|
||||
{
|
||||
GIVEN {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user