Add Frostbite status (#2942)

This commit is contained in:
ghoulslash 2023-05-01 09:45:47 -04:00 committed by GitHub
commit 8cce130643
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 593 additions and 127 deletions

View File

@ -286,7 +286,11 @@ gBattleScriptsForMoveEffects::
.4byte BattleScript_EffectHealPulse @ EFFECT_HEAL_PULSE
.4byte BattleScript_EffectQuash @ EFFECT_QUASH
.4byte BattleScript_EffectIonDeluge @ EFFECT_ION_DELUGE
#if B_USE_FROSTBITE == TRUE
.4byte BattleScript_EffectFrostbiteHit @ EFFECT_FREEZE_DRY
#else
.4byte BattleScript_EffectFreezeHit @ EFFECT_FREEZE_DRY
#endif
.4byte BattleScript_EffectTopsyTurvy @ EFFECT_TOPSY_TURVY
.4byte BattleScript_EffectMistyTerrain @ EFFECT_MISTY_TERRAIN
.4byte BattleScript_EffectGrassyTerrain @ EFFECT_GRASSY_TERRAIN
@ -424,6 +428,7 @@ gBattleScriptsForMoveEffects::
.4byte BattleScript_EffectDireClaw @ EFFECT_DIRE_CLAW
.4byte BattleScript_EffectBarbBarrage @ EFFECT_BARB_BARRAGE
.4byte BattleScript_EffectRevivalBlessing @ EFFECT_REVIVAL_BLESSING
.4byte BattleScript_EffectFrostbiteHit @ EFFECT_FROSTBITE_HIT
BattleScript_EffectRevivalBlessing::
attackcanceler
@ -576,6 +581,7 @@ BattleScript_AffectionBasedStatusHeal::
jumpifstatus BS_ATTACKER, STATUS1_PARALYSIS, BattleScript_AffectionBasedStatus_HealParalysisString
jumpifstatus BS_ATTACKER, STATUS1_BURN, BattleScript_AffectionBasedStatus_HealBurnString
jumpifstatus BS_ATTACKER, STATUS1_FREEZE, BattleScript_AffectionBasedStatus_HealFreezeString
jumpifstatus BS_ATTACKER, STATUS1_FROSTBITE, BattleScript_AffectionBasedStatus_HealFrostbiteString
end2
BattleScript_AffectionBasedStatus_HealPoisonString:
printstring STRINGID_ATTACKEREXPELLEDTHEPOISON
@ -591,6 +597,9 @@ BattleScript_AffectionBasedStatus_HealBurnString:
goto BattleScript_AffectionBasedStatusHeal_Continue
BattleScript_AffectionBasedStatus_HealFreezeString:
printstring STRINGID_ATTACKERMELTEDTHEICE
goto BattleScript_AffectionBasedStatusHeal_Continue
BattleScript_AffectionBasedStatus_HealFrostbiteString:
printstring STRINGID_ATTACKERHEALEDITSFROSTBITE
BattleScript_AffectionBasedStatusHeal_Continue:
waitmessage B_WAIT_TIME_LONG
clearstatus BS_ATTACKER
@ -3466,6 +3475,10 @@ BattleScript_EffectBurnHit::
setmoveeffect MOVE_EFFECT_BURN
goto BattleScript_EffectHit
BattleScript_EffectFrostbiteHit::
setmoveeffect MOVE_EFFECT_FROSTBITE
goto BattleScript_EffectHit
BattleScript_EffectSleepHit::
setmoveeffect MOVE_EFFECT_SLEEP
goto BattleScript_EffectHit
@ -8127,6 +8140,11 @@ BattleScript_BurnTurnDmg::
waitmessage B_WAIT_TIME_LONG
goto BattleScript_DoStatusTurnDmg
BattleScript_FrostbiteTurnDmg::
printstring STRINGID_PKMNHURTBYFROSTBITE
waitmessage B_WAIT_TIME_LONG
goto BattleScript_DoStatusTurnDmg
BattleScript_MoveUsedIsFrozen::
printstring STRINGID_PKMNISFROZEN
waitmessage B_WAIT_TIME_LONG
@ -8139,12 +8157,24 @@ BattleScript_MoveUsedUnfroze::
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_TARGET
return
BattleScript_FrostbiteHealedViaFireMove::
printstring STRINGID_PKMNFROSTBITEHEALED
waitmessage B_WAIT_TIME_LONG
updatestatusicon BS_TARGET
return
BattleScript_MoveUsedIsParalyzed::
printstring STRINGID_PKMNISPARALYZED
waitmessage B_WAIT_TIME_LONG
@ -8366,6 +8396,12 @@ BattleScript_MoveEffectBurn::
waitmessage B_WAIT_TIME_LONG
goto BattleScript_UpdateEffectStatusIconRet
BattleScript_MoveEffectFrostbite::
statusanimation BS_EFFECT_BATTLER
printfromtable gGotFrostbiteStringIds
waitmessage B_WAIT_TIME_LONG
goto BattleScript_UpdateEffectStatusIconRet
BattleScript_MoveEffectFreeze::
statusanimation BS_EFFECT_BATTLER
printfromtable gGotFrozenStringIds
@ -9544,6 +9580,18 @@ BattleScript_BerryCureFrzRet::
removeitem BS_SCRIPTING
return
BattleScript_BerryCureFsbEnd2::
call BattleScript_BerryCureFrzRet
end2
BattleScript_BerryCureFsbRet::
playanimation BS_SCRIPTING, B_ANIM_HELD_ITEM_EFFECT
printstring STRINGID_PKMNSITEMHEALEDFROSTBITE
waitmessage B_WAIT_TIME_LONG
updatestatusicon BS_SCRIPTING
removeitem BS_SCRIPTING
return
BattleScript_BerryCureSlpEnd2::
call BattleScript_BerryCureSlpRet
end2

Binary file not shown.

Before

Width:  |  Height:  |  Size: 531 B

After

Width:  |  Height:  |  Size: 559 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 531 B

After

Width:  |  Height:  |  Size: 559 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 530 B

After

Width:  |  Height:  |  Size: 559 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 530 B

After

Width:  |  Height:  |  Size: 559 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 455 B

After

Width:  |  Height:  |  Size: 458 B

View File

@ -130,6 +130,7 @@ bool32 IsSemiInvulnerable(u8 battlerDef, u16 move);
// status checks
bool32 AI_CanBeBurned(u8 battler, u16 ability);
bool32 AI_CanGetFrostbite(u8 battler, u16 ability);
bool32 AI_CanBeConfused(u8 battler, u16 ability);
bool32 AI_CanSleep(u8 battler, u16 ability);
bool32 IsBattlerIncapacitated(u8 battler, u16 ability);
@ -140,6 +141,7 @@ bool32 AI_CanParalyze(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u1
bool32 AI_CanConfuse(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPartner, u16 move, u16 partnerMove);
bool32 ShouldBurnSelf(u8 battler, u16 ability);
bool32 AI_CanBurn(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPartner, u16 move, u16 partnerMove);
bool32 AI_CanGiveFrostbite(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPartner, u16 move, u16 partnerMove);
bool32 AI_CanBeInfatuated(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 atkGender, u8 defGender);
bool32 AnyPartyMemberStatused(u8 battlerId, bool32 checkSoundproof);
u32 ShouldTryToFlinch(u8 battlerAtk, u8 battlerDef, u16 atkAbility, u16 defAbility, u16 move);
@ -170,10 +172,11 @@ bool32 SideHasMoveSplit(u8 battlerId, u8 split);
// score increases
void IncreaseStatUpScore(u8 battlerAtk, u8 battlerDef, u8 statId, s16 *score);
void IncreasePoisonScore(u8 battlerAtk, u8 battlerdef, u16 move, s16 *score);
void IncreaseBurnScore(u8 battlerAtk, u8 battlerdef, u16 move, s16 *score);
void IncreasePoisonScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score);
void IncreaseBurnScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score);
void IncreaseParalyzeScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score);
void IncreaseSleepScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score);
void IncreaseConfusionScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score);
void IncreaseFrostbiteScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score);
#endif //GUARD_BATTLE_AI_UTIL_H
#endif //GUARD_BATTLE_AI_UTIL_H

View File

@ -108,9 +108,12 @@ extern const u8 BattleScript_MoveUsedWokeUp[];
extern const u8 BattleScript_MonWokeUpInUproar[];
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_MoveUsedIsParalyzed[];
extern const u8 BattleScript_MoveUsedFlinched[];
extern const u8 BattleScript_PrintUproarOverTurns[];
@ -131,6 +134,7 @@ extern const u8 BattleScript_MoveEffectSleep[];
extern const u8 BattleScript_YawnMakesAsleep[];
extern const u8 BattleScript_MoveEffectPoison[];
extern const u8 BattleScript_MoveEffectBurn[];
extern const u8 BattleScript_MoveEffectFrostbite[];
extern const u8 BattleScript_MoveEffectFreeze[];
extern const u8 BattleScript_MoveEffectParalysis[];
extern const u8 BattleScript_MoveEffectUproar[];
@ -192,6 +196,8 @@ extern const u8 BattleScript_BerryCureBrnEnd2[];
extern const u8 BattleScript_BerryCureBrnRet[];
extern const u8 BattleScript_BerryCureFrzEnd2[];
extern const u8 BattleScript_BerryCureFrzRet[];
extern const u8 BattleScript_BerryCureFsbEnd2[];
extern const u8 BattleScript_BerryCureFsbRet[];
extern const u8 BattleScript_BerryCureSlpEnd2[];
extern const u8 BattleScript_BerryCureSlpRet[];
extern const u8 BattleScript_BerryCureConfusionEnd2[];

View File

@ -228,6 +228,7 @@ bool32 CanBePoisoned(u8 battlerAttacker, u8 battlerTarget);
bool32 CanBeBurned(u8 battlerId);
bool32 CanBeParalyzed(u8 battlerId);
bool32 CanBeFrozen(u8 battlerId);
bool32 CanGetFrostbite(u8 battlerId);
bool32 CanBeConfused(u8 battlerId);
bool32 IsBattlerTerrainAffected(u8 battlerId, u32 terrainFlag);
u32 GetBattlerFriendshipScore(u8 battlerId);

View File

@ -188,14 +188,15 @@
#define B_LAST_USED_BALL_BUTTON R_BUTTON // If last used ball is implemented, this button (or button combo) will trigger throwing the last used ball.
// 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_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)
#define B_AFFECTION_MECHANICS FALSE // In Gen6+, there's a stat called affection that can trigger different effects in battle. From LGPE onwards, those effects use friendship instead.
#define B_TRAINER_CLASS_POKE_BALLS GEN_LATEST // In Gen7+, trainers will use certain types of Poké Balls depending on their trainer class.
#define B_OBEDIENCE_MECHANICS GEN_LATEST // In PLA+ (here Gen8+), obedience restrictions also apply to non-outsider Pokémon, albeit based on their level met rather than actual level
#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_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)
#define B_AFFECTION_MECHANICS FALSE // In Gen6+, there's a stat called affection that can trigger different effects in battle. From LGPE onwards, those effects use friendship instead.
#define B_TRAINER_CLASS_POKE_BALLS GEN_LATEST // In Gen7+, trainers will use certain types of Poké Balls depending on their trainer class.
#define B_OBEDIENCE_MECHANICS GEN_LATEST // In PLA+ (here Gen8+), obedience restrictions also apply to non-outsider Pokémon, albeit based on their level met rather than actual level
#define B_USE_FROSTBITE FALSE // In PLA, Frostbite replaces Freeze. Enabling this flag does the same here. Moves can still be cherry-picked to either Freeze or Frostbite. Freeze-Dry, Secret Power & Tri Attack depend on this config.
// Animation Settings
#define B_NEW_SWORD_PARTICLE TRUE // If set to TRUE, it updates Swords Dance's particle.

View File

@ -115,8 +115,9 @@
#define STATUS1_TOXIC_POISON (1 << 7)
#define STATUS1_TOXIC_COUNTER (1 << 8 | 1 << 9 | 1 << 10 | 1 << 11)
#define STATUS1_TOXIC_TURN(num) ((num) << 8)
#define STATUS1_FROSTBITE (1 << 12)
#define STATUS1_PSN_ANY (STATUS1_POISON | STATUS1_TOXIC_POISON)
#define STATUS1_ANY (STATUS1_SLEEP | STATUS1_POISON | STATUS1_BURN | STATUS1_FREEZE | STATUS1_PARALYSIS | STATUS1_TOXIC_POISON)
#define STATUS1_ANY (STATUS1_SLEEP | STATUS1_POISON | STATUS1_BURN | STATUS1_FREEZE | STATUS1_PARALYSIS | STATUS1_TOXIC_POISON | STATUS1_FROSTBITE)
// Volatile status ailments
// These are removed after exiting the battle or switching out
@ -307,79 +308,80 @@
#define MOVE_EFFECT_FREEZE 4
#define MOVE_EFFECT_PARALYSIS 5
#define MOVE_EFFECT_TOXIC 6
#define PRIMARY_STATUS_MOVE_EFFECT MOVE_EFFECT_TOXIC // All above move effects apply primary status
#define MOVE_EFFECT_CONFUSION 7
#define MOVE_EFFECT_FLINCH 8
#define MOVE_EFFECT_TRI_ATTACK 9
#define MOVE_EFFECT_UPROAR 10
#define MOVE_EFFECT_PAYDAY 11
#define MOVE_EFFECT_CHARGING 12
#define MOVE_EFFECT_WRAP 13
#define MOVE_EFFECT_BURN_UP 14 // MOVE_EFFECT_BURN_UP replaces unused MOVE_EFFECT_RECOIL_25 so that stat change animations don't break
#define MOVE_EFFECT_ATK_PLUS_1 15
#define MOVE_EFFECT_DEF_PLUS_1 16
#define MOVE_EFFECT_SPD_PLUS_1 17
#define MOVE_EFFECT_SP_ATK_PLUS_1 18
#define MOVE_EFFECT_SP_DEF_PLUS_1 19
#define MOVE_EFFECT_ACC_PLUS_1 20
#define MOVE_EFFECT_EVS_PLUS_1 21
#define MOVE_EFFECT_ATK_MINUS_1 22
#define MOVE_EFFECT_DEF_MINUS_1 23
#define MOVE_EFFECT_SPD_MINUS_1 24
#define MOVE_EFFECT_SP_ATK_MINUS_1 25
#define MOVE_EFFECT_SP_DEF_MINUS_1 26
#define MOVE_EFFECT_ACC_MINUS_1 27
#define MOVE_EFFECT_EVS_MINUS_1 28
#define MOVE_EFFECT_RECHARGE 29
#define MOVE_EFFECT_RAGE 30
#define MOVE_EFFECT_STEAL_ITEM 31
#define MOVE_EFFECT_PREVENT_ESCAPE 32
#define MOVE_EFFECT_NIGHTMARE 33
#define MOVE_EFFECT_ALL_STATS_UP 34
#define MOVE_EFFECT_RAPIDSPIN 35
#define MOVE_EFFECT_REMOVE_STATUS 36
#define MOVE_EFFECT_ATK_DEF_DOWN 37
#define MOVE_EFFECT_SCALE_SHOT 38 // MOVE_EFFECT_SCALE_SHOT replaces unused MOVE_EFFECT_RECOIL_33 so that stat change animations don't break
#define MOVE_EFFECT_ATK_PLUS_2 39
#define MOVE_EFFECT_DEF_PLUS_2 40
#define MOVE_EFFECT_SPD_PLUS_2 41
#define MOVE_EFFECT_SP_ATK_PLUS_2 42
#define MOVE_EFFECT_SP_DEF_PLUS_2 43
#define MOVE_EFFECT_ACC_PLUS_2 44
#define MOVE_EFFECT_EVS_PLUS_2 45
#define MOVE_EFFECT_ATK_MINUS_2 46
#define MOVE_EFFECT_DEF_MINUS_2 47
#define MOVE_EFFECT_SPD_MINUS_2 48
#define MOVE_EFFECT_SP_ATK_MINUS_2 49
#define MOVE_EFFECT_SP_DEF_MINUS_2 50
#define MOVE_EFFECT_ACC_MINUS_2 51
#define MOVE_EFFECT_EVS_MINUS_2 52
#define MOVE_EFFECT_THRASH 53
#define MOVE_EFFECT_KNOCK_OFF 54
#define MOVE_EFFECT_DEF_SPDEF_DOWN 55
#define MOVE_EFFECT_CLEAR_SMOG 56
#define MOVE_EFFECT_SP_ATK_TWO_DOWN 57
#define MOVE_EFFECT_SMACK_DOWN 58
#define MOVE_EFFECT_FLAME_BURST 59
#define MOVE_EFFECT_FEINT 60
#define MOVE_EFFECT_SPECTRAL_THIEF 61
#define MOVE_EFFECT_V_CREATE 62
#define MOVE_EFFECT_HAPPY_HOUR 63
#define MOVE_EFFECT_CORE_ENFORCER 64
#define MOVE_EFFECT_THROAT_CHOP 65
#define MOVE_EFFECT_INCINERATE 66
#define MOVE_EFFECT_BUG_BITE 67
#define MOVE_EFFECT_RECOIL_HP_25 68
#define MOVE_EFFECT_RELIC_SONG 69
#define MOVE_EFFECT_TRAP_BOTH 70
#define MOVE_EFFECT_DOUBLE_SHOCK 71
#define MOVE_EFFECT_ROUND 72
#define MOVE_EFFECT_STOCKPILE_WORE_OFF 73
#define MOVE_EFFECT_DIRE_CLAW 74
#define MOVE_EFFECT_STEALTH_ROCK 75
#define MOVE_EFFECT_SPIKES 76
#define MOVE_EFFECT_FROSTBITE 7
#define PRIMARY_STATUS_MOVE_EFFECT MOVE_EFFECT_FROSTBITE // All above move effects apply primary status
#define MOVE_EFFECT_CONFUSION 8
#define MOVE_EFFECT_FLINCH 9
#define MOVE_EFFECT_TRI_ATTACK 10
#define MOVE_EFFECT_UPROAR 11
#define MOVE_EFFECT_PAYDAY 12
#define MOVE_EFFECT_CHARGING 13
#define MOVE_EFFECT_WRAP 14
#define MOVE_EFFECT_BURN_UP 15 // MOVE_EFFECT_BURN_UP replaces unused MOVE_EFFECT_RECOIL_25 so that stat change animations don't break
#define MOVE_EFFECT_ATK_PLUS_1 16
#define MOVE_EFFECT_DEF_PLUS_1 17
#define MOVE_EFFECT_SPD_PLUS_1 18
#define MOVE_EFFECT_SP_ATK_PLUS_1 19
#define MOVE_EFFECT_SP_DEF_PLUS_1 20
#define MOVE_EFFECT_ACC_PLUS_1 21
#define MOVE_EFFECT_EVS_PLUS_1 22
#define MOVE_EFFECT_ATK_MINUS_1 23
#define MOVE_EFFECT_DEF_MINUS_1 24
#define MOVE_EFFECT_SPD_MINUS_1 25
#define MOVE_EFFECT_SP_ATK_MINUS_1 26
#define MOVE_EFFECT_SP_DEF_MINUS_1 27
#define MOVE_EFFECT_ACC_MINUS_1 28
#define MOVE_EFFECT_EVS_MINUS_1 29
#define MOVE_EFFECT_RECHARGE 30
#define MOVE_EFFECT_RAGE 31
#define MOVE_EFFECT_STEAL_ITEM 32
#define MOVE_EFFECT_PREVENT_ESCAPE 33
#define MOVE_EFFECT_NIGHTMARE 34
#define MOVE_EFFECT_ALL_STATS_UP 35
#define MOVE_EFFECT_RAPIDSPIN 36
#define MOVE_EFFECT_REMOVE_STATUS 37
#define MOVE_EFFECT_ATK_DEF_DOWN 38
#define MOVE_EFFECT_SCALE_SHOT 39 // MOVE_EFFECT_SCALE_SHOT replaces unused MOVE_EFFECT_RECOIL_33 so that stat change animations don't break
#define MOVE_EFFECT_ATK_PLUS_2 40
#define MOVE_EFFECT_DEF_PLUS_2 41
#define MOVE_EFFECT_SPD_PLUS_2 42
#define MOVE_EFFECT_SP_ATK_PLUS_2 43
#define MOVE_EFFECT_SP_DEF_PLUS_2 44
#define MOVE_EFFECT_ACC_PLUS_2 45
#define MOVE_EFFECT_EVS_PLUS_2 46
#define MOVE_EFFECT_ATK_MINUS_2 47
#define MOVE_EFFECT_DEF_MINUS_2 48
#define MOVE_EFFECT_SPD_MINUS_2 49
#define MOVE_EFFECT_SP_ATK_MINUS_2 50
#define MOVE_EFFECT_SP_DEF_MINUS_2 51
#define MOVE_EFFECT_ACC_MINUS_2 52
#define MOVE_EFFECT_EVS_MINUS_2 53
#define MOVE_EFFECT_THRASH 54
#define MOVE_EFFECT_KNOCK_OFF 55
#define MOVE_EFFECT_DEF_SPDEF_DOWN 56
#define MOVE_EFFECT_CLEAR_SMOG 57
#define MOVE_EFFECT_SP_ATK_TWO_DOWN 58
#define MOVE_EFFECT_SMACK_DOWN 59
#define MOVE_EFFECT_FLAME_BURST 60
#define MOVE_EFFECT_FEINT 61
#define MOVE_EFFECT_SPECTRAL_THIEF 62
#define MOVE_EFFECT_V_CREATE 63
#define MOVE_EFFECT_HAPPY_HOUR 64
#define MOVE_EFFECT_CORE_ENFORCER 65
#define MOVE_EFFECT_THROAT_CHOP 66
#define MOVE_EFFECT_INCINERATE 67
#define MOVE_EFFECT_BUG_BITE 68
#define MOVE_EFFECT_RECOIL_HP_25 69
#define MOVE_EFFECT_RELIC_SONG 70
#define MOVE_EFFECT_TRAP_BOTH 71
#define MOVE_EFFECT_DOUBLE_SHOCK 72
#define MOVE_EFFECT_ROUND 73
#define MOVE_EFFECT_STOCKPILE_WORE_OFF 74
#define MOVE_EFFECT_DIRE_CLAW 75
#define MOVE_EFFECT_STEALTH_ROCK 76
#define MOVE_EFFECT_SPIKES 77
#define NUM_MOVE_EFFECTS 77
#define NUM_MOVE_EFFECTS 78
#define MOVE_EFFECT_AFFECTS_USER 0x4000
#define MOVE_EFFECT_CERTAIN 0x8000

View File

@ -405,7 +405,8 @@
#define EFFECT_DIRE_CLAW 399
#define EFFECT_BARB_BARRAGE 400
#define EFFECT_REVIVAL_BLESSING 401
#define EFFECT_FROSTBITE_HIT 402
#define NUM_BATTLE_MOVE_EFFECTS 402
#define NUM_BATTLE_MOVE_EFFECTS 403
#endif // GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H

View File

@ -652,8 +652,15 @@
#define STRINGID_ITEMCUREDSPECIESSTATUS 650
#define STRINGID_ITEMRESTOREDSPECIESPP 651
#define STRINGID_THUNDERCAGETRAPPED 652
#define STRINGID_PKMNHURTBYFROSTBITE 653
#define STRINGID_PKMNGOTFROSTBITE 654
#define STRINGID_PKMNSITEMHEALEDFROSTBITE 655
#define STRINGID_ATTACKERHEALEDITSFROSTBITE 656
#define STRINGID_PKMNFROSTBITEHEALED 657
#define STRINGID_PKMNFROSTBITEHEALED2 658
#define STRINGID_PKMNFROSTBITEHEALEDBY 659
#define BATTLESTRINGS_COUNT 653
#define BATTLESTRINGS_COUNT 660
// This is the string id that gBattleStringsTable starts with.
// String ids before this (e.g. STRINGID_INTROMSG) are not in the table,
@ -861,6 +868,10 @@
#define B_MSG_DEFROSTED 0
#define B_MSG_DEFROSTED_BY_MOVE 1
// gFrostbiteHealedStringIds
#define B_MSG_FROSTBITE_HEALED 0
#define B_MSG_FROSTBITE_HEALED_BY_MOVE 1
// gBattlePalaceFlavorTextTable
#define B_MSG_GLINT_IN_EYE 0
#define B_MSG_GETTING_IN_POS 1

View File

@ -74,7 +74,7 @@
#define ITEM_EFFECT_CURE_POISON 3
#define ITEM_EFFECT_CURE_SLEEP 4
#define ITEM_EFFECT_CURE_BURN 5
#define ITEM_EFFECT_CURE_FREEZE 6
#define ITEM_EFFECT_CURE_FREEZE_FROSTBITE 6
#define ITEM_EFFECT_CURE_PARALYSIS 7
#define ITEM_EFFECT_CURE_CONFUSION 8
#define ITEM_EFFECT_CURE_INFATUATION 9

View File

@ -11,6 +11,7 @@
#define AILMENT_BRN 5
#define AILMENT_PKRS 6
#define AILMENT_FNT 7
#define AILMENT_FSB 8
#define PARTY_LAYOUT_SINGLE 0
#define PARTY_LAYOUT_DOUBLE 1

View File

@ -346,7 +346,7 @@ struct BattleMove
s8 priority;
u32 flags;
u8 split;
u8 argument;
u16 argument;
u8 zMoveEffect;
};

View File

@ -475,6 +475,7 @@ extern const u8 gText_EscapeFromHere[];
extern const u8 gText_PkmnCuredOfPoison[];
extern const u8 gText_PkmnWokeUp2[];
extern const u8 gText_PkmnBurnHealed[];
extern const u8 gText_PkmnFrostbiteHealed[];
extern const u8 gText_PkmnThawedOut[];
extern const u8 gText_PkmnCuredOfParalysis[];
extern const u8 gText_PkmnGotOverInfatuation[];

View File

@ -1725,7 +1725,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
score -= 10;
break;
case EFFECT_REFRESH:
if (!(gBattleMons[battlerDef].status1 & (STATUS1_PSN_ANY | STATUS1_BURN | STATUS1_PARALYSIS)))
if (!(gBattleMons[battlerDef].status1 & (STATUS1_PSN_ANY | STATUS1_BURN | STATUS1_PARALYSIS | STATUS1_FROSTBITE)))
score -= 10;
break;
case EFFECT_PSYCHO_SHIFT:
@ -1734,6 +1734,9 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
else if (gBattleMons[battlerAtk].status1 & STATUS1_BURN && !AI_CanBurn(battlerAtk, battlerDef,
AI_DATA->abilities[battlerDef], BATTLE_PARTNER(battlerAtk), move, AI_DATA->partnerMove))
score -= 10;
else if (gBattleMons[battlerAtk].status1 & STATUS1_FROSTBITE && !AI_CanGiveFrostbite(battlerAtk, battlerDef,
AI_DATA->abilities[battlerDef], BATTLE_PARTNER(battlerAtk), move, AI_DATA->partnerMove))
score -= 10;
else if (gBattleMons[battlerAtk].status1 & STATUS1_PARALYSIS && !AI_CanParalyze(battlerAtk, battlerDef, AI_DATA->abilities[battlerDef], move, AI_DATA->partnerMove))
score -= 10;
else if (gBattleMons[battlerAtk].status1 & STATUS1_SLEEP && !AI_CanPutToSleep(battlerAtk, battlerDef, AI_DATA->abilities[battlerDef], move, AI_DATA->partnerMove))
@ -3139,7 +3142,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
score++;
// check thawing moves
if ((gBattleMons[battlerAtk].status1 & STATUS1_FREEZE) && TestMoveFlags(move, FLAG_THAW_USER))
if ((gBattleMons[battlerAtk].status1 & (STATUS1_FREEZE | STATUS1_FROSTBITE)) && TestMoveFlags(move, FLAG_THAW_USER))
score += (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) ? 20 : 10;
// check burn
@ -3161,6 +3164,25 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
}
}
// check frostbite
if (gBattleMons[battlerAtk].status1 & STATUS1_FROSTBITE)
{
switch (AI_DATA->abilities[battlerAtk])
{
case ABILITY_GUTS:
break;
case ABILITY_NATURAL_CURE:
if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_SMART_SWITCHING
&& HasOnlyMovesWithSplit(battlerAtk, SPLIT_SPECIAL, TRUE))
score = 90; // Force switch if all your attacking moves are special and you have Natural Cure.
break;
default:
if (IS_MOVE_SPECIAL(move) && gBattleMoves[move].effect != EFFECT_FACADE)
score -= 2;
break;
}
}
// attacker ability checks
switch (AI_DATA->abilities[battlerAtk])
{
@ -3598,7 +3620,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
case EFFECT_SUBSTITUTE:
if (gStatuses3[battlerDef] & STATUS3_PERISH_SONG)
score += 3;
if (gBattleMons[battlerDef].status1 & (STATUS1_BURN | STATUS1_PSN_ANY))
if (gBattleMons[battlerDef].status1 & (STATUS1_BURN | STATUS1_PSN_ANY | STATUS1_FROSTBITE))
score++;
if (HasMoveEffect(battlerDef, EFFECT_SLEEP)
|| HasMoveEffect(battlerDef, EFFECT_TOXIC)
@ -4385,6 +4407,8 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
IncreaseParalyzeScore(battlerAtk, battlerDef, move, &score);
else if (gBattleMons[battlerAtk].status1 & STATUS1_SLEEP)
IncreaseSleepScore(battlerAtk, battlerDef, move, &score);
else if (gBattleMons[battlerAtk].status1 & STATUS1_FROSTBITE)
IncreaseFrostbiteScore(battlerAtk, battlerDef, move, &score);
break;
case EFFECT_GRUDGE:
break;
@ -4773,7 +4797,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
score += 2;
break;
case EFFECT_FACADE:
if (gBattleMons[battlerAtk].status1 & (STATUS1_POISON | STATUS1_BURN | STATUS1_PARALYSIS | STATUS1_TOXIC_POISON))
if (gBattleMons[battlerAtk].status1 & (STATUS1_POISON | STATUS1_BURN | STATUS1_PARALYSIS | STATUS1_TOXIC_POISON | STATUS1_FROSTBITE))
score++;
break;
case EFFECT_FOCUS_PUNCH:

View File

@ -1079,7 +1079,7 @@ static bool8 ShouldUseItem(void)
shouldUse = TRUE;
if (itemEffects[3] & ITEM3_BURN && gBattleMons[gActiveBattler].status1 & STATUS1_BURN)
shouldUse = TRUE;
if (itemEffects[3] & ITEM3_FREEZE && gBattleMons[gActiveBattler].status1 & STATUS1_FREEZE)
if (itemEffects[3] & ITEM3_FREEZE && (gBattleMons[gActiveBattler].status1 & STATUS1_FREEZE || gBattleMons[gActiveBattler].status1 & STATUS1_FROSTBITE))
shouldUse = TRUE;
if (itemEffects[3] & ITEM3_PARALYSIS && gBattleMons[gActiveBattler].status1 & STATUS1_PARALYSIS)
shouldUse = TRUE;

View File

@ -1678,7 +1678,7 @@ void ProtectChecks(u8 battlerAtk, u8 battlerDef, u16 move, u16 predictedMove, s1
(*score) -= min(uses, 3);
}
if (gBattleMons[battlerAtk].status1 & (STATUS1_PSN_ANY | STATUS1_BURN)
if (gBattleMons[battlerAtk].status1 & (STATUS1_PSN_ANY | STATUS1_BURN | STATUS1_FROSTBITE)
|| gBattleMons[battlerAtk].status2 & (STATUS2_CURSED | STATUS2_INFATUATION)
|| gStatuses3[battlerAtk] & (STATUS3_PERISH_SONG | STATUS3_LEECHSEED | STATUS3_YAWN))
{
@ -2766,6 +2766,7 @@ bool32 AI_CanSleep(u8 battler, u16 ability)
{
if (ability == ABILITY_INSOMNIA
|| ability == ABILITY_VITAL_SPIRIT
|| ability == ABILITY_COMATOSE
|| gBattleMons[battler].status1 & STATUS1_ANY
|| gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_SAFEGUARD
|| (gFieldStatuses & (STATUS_FIELD_MISTY_TERRAIN | STATUS_FIELD_ELECTRIC_TERRAIN))
@ -2839,6 +2840,7 @@ bool32 AI_CanPoison(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16
static bool32 AI_CanBeParalyzed(u8 battler, u16 ability)
{
if (ability == ABILITY_LIMBER
|| ability == ABILITY_COMATOSE
|| IS_BATTLER_OF_TYPE(battler, TYPE_ELECTRIC)
|| gBattleMons[battler].status1 & STATUS1_ANY
|| IsAbilityStatusProtected(battler))
@ -2884,6 +2886,7 @@ bool32 AI_CanBeBurned(u8 battler, u16 ability)
{
if (ability == ABILITY_WATER_VEIL
|| ability == ABILITY_WATER_BUBBLE
|| ability == ABILITY_COMATOSE
|| IS_BATTLER_OF_TYPE(battler, TYPE_FIRE)
|| gBattleMons[battler].status1 & STATUS1_ANY
|| IsAbilityStatusProtected(battler)
@ -2892,6 +2895,18 @@ bool32 AI_CanBeBurned(u8 battler, u16 ability)
return TRUE;
}
bool32 AI_CanGetFrostbite(u8 battler, u16 ability)
{
if (ability == ABILITY_MAGMA_ARMOR
|| ability == ABILITY_COMATOSE
|| IS_BATTLER_OF_TYPE(battler, TYPE_ICE)
|| gBattleMons[battler].status1 & STATUS1_ANY
|| IsAbilityStatusProtected(battler)
|| gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_SAFEGUARD)
return FALSE;
return TRUE;
}
bool32 ShouldBurnSelf(u8 battler, u16 ability)
{
if (AI_CanBeBurned(battler, ability) && (
@ -2918,6 +2933,18 @@ bool32 AI_CanBurn(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPar
return TRUE;
}
bool32 AI_CanGiveFrostbite(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPartner, u16 move, u16 partnerMove)
{
if (!AI_CanGetFrostbite(battlerDef, defAbility)
|| AI_GetMoveEffectiveness(move, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0
|| DoesSubstituteBlockMove(battlerAtk, battlerDef, move)
|| PartnerMoveEffectIsStatusSameTarget(battlerAtkPartner, battlerDef, partnerMove))
{
return FALSE;
}
return TRUE;
}
bool32 AI_CanBeInfatuated(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 atkGender, u8 defGender)
{
if ((gBattleMons[battlerDef].status2 & STATUS2_INFATUATION)
@ -3717,6 +3744,25 @@ void IncreaseConfusionScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
}
}
void IncreaseFrostbiteScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
{
if ((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
return;
if (AI_CanGiveFrostbite(battlerAtk, battlerDef, AI_DATA->abilities[battlerDef], BATTLE_PARTNER(battlerAtk), move, AI_DATA->partnerMove))
{
(*score)++; // frostbite is good
if (HasMoveWithSplit(battlerDef, SPLIT_SPECIAL))
{
if (CanTargetFaintAi(battlerDef, battlerAtk))
*score += 2; // frostbiting the target to stay alive is cool
}
if (HasMoveEffect(battlerAtk, EFFECT_HEX) || HasMoveEffect(BATTLE_PARTNER(battlerAtk), EFFECT_HEX))
(*score)++;
}
}
bool32 AI_MoveMakesContact(u32 ability, u32 holdEffect, u16 move)
{
if (TestMoveFlags(move, FLAG_MAKES_CONTACT)

View File

@ -181,6 +181,7 @@ static const u8 sText_SideStatus[] = _("Side Status");
static const u8 sText_MaxHp[] = _("HP Max");
static const u8 sText_CurrHp[] = _("HP Current");
static const u8 sText_Freeze[] = _("Freeze");
static const u8 sText_Frostbite[] = _("Frostbite");
static const u8 sText_ToxicPoison[] = _("Toxic Poison");
static const u8 sText_ToxicCounter[] = _("Toxic Counter");
static const u8 sText_Flinch[] = _("Flinch");
@ -258,6 +259,7 @@ static const struct BitfieldInfo sStatus1Bitfield[] =
{/*Paralysis*/1, 6},
{/*Toxic Poison*/ 1, 7},
{/*Toxic Counter*/ 4, 8},
{/*Frostbite*/ 1, 12},
};
static const struct BitfieldInfo sStatus2Bitfield[] =
@ -397,6 +399,7 @@ static const struct ListMenuItem sStatus1ListItems[] =
{gText_Paralysis, 4},
{sText_ToxicPoison, 5},
{sText_ToxicCounter, 6},
{sText_Frostbite, 7},
};
static const struct ListMenuItem sStatus2ListItems[] =

View File

@ -398,7 +398,7 @@ void InitAndLaunchChosenStatusAnimation(bool8 isStatus2, u32 status)
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].statusAnimActive = 1;
if (!isStatus2)
{
if (status == STATUS1_FREEZE)
if (status == STATUS1_FREEZE || status == STATUS1_FROSTBITE)
LaunchStatusAnimation(gActiveBattler, B_ANIM_STATUS_FRZ);
else if (status == STATUS1_POISON || status & STATUS1_TOXIC_POISON)
LaunchStatusAnimation(gActiveBattler, B_ANIM_STATUS_PSN);

View File

@ -73,6 +73,9 @@ enum
HEALTHBOX_GFX_STATUS_BRN_BATTLER0, //status brn
HEALTHBOX_GFX_34,
HEALTHBOX_GFX_35,
HEALTHBOX_GFX_STATUS_FSB_BATTLER0, //status fsb
HEALTHBOX_GFX_116,
HEALTHBOX_GFX_117,
HEALTHBOX_GFX_36, //misc [Black section]
HEALTHBOX_GFX_37, //misc [Black section]
HEALTHBOX_GFX_38, //misc [Black section]
@ -123,6 +126,9 @@ enum
HEALTHBOX_GFX_STATUS_BRN_BATTLER1, //status2 "BRN"
HEALTHBOX_GFX_84,
HEALTHBOX_GFX_85,
HEALTHBOX_GFX_STATUS_FSB_BATTLER1, //status2 "FSB"
HEALTHBOX_GFX_118,
HEALTHBOX_GFX_119,
HEALTHBOX_GFX_STATUS_PSN_BATTLER2, //status3 "PSN"
HEALTHBOX_GFX_87,
HEALTHBOX_GFX_88,
@ -138,6 +144,9 @@ enum
HEALTHBOX_GFX_STATUS_BRN_BATTLER2, //status3 "BRN"
HEALTHBOX_GFX_99,
HEALTHBOX_GFX_100,
HEALTHBOX_GFX_STATUS_FSB_BATTLER2, //status3 "FSB"
HEALTHBOX_GFX_120,
HEALTHBOX_GFX_121,
HEALTHBOX_GFX_STATUS_PSN_BATTLER3, //status4 "PSN"
HEALTHBOX_GFX_102,
HEALTHBOX_GFX_103,
@ -153,6 +162,9 @@ enum
HEALTHBOX_GFX_STATUS_BRN_BATTLER3, //status4 "BRN"
HEALTHBOX_GFX_114,
HEALTHBOX_GFX_115,
HEALTHBOX_GFX_STATUS_FSB_BATTLER3, //status4 "FSB"
HEALTHBOX_GFX_122,
HEALTHBOX_GFX_123,
HEALTHBOX_GFX_FRAME_END,
HEALTHBOX_GFX_FRAME_END_BAR,
};
@ -2201,6 +2213,11 @@ static void UpdateStatusIconInHealthbox(u8 healthboxSpriteId)
statusGfxPtr = GetHealthboxElementGfxPtr(GetStatusIconForBattlerId(HEALTHBOX_GFX_STATUS_FRZ_BATTLER0, battlerId));
statusPalId = PAL_STATUS_FRZ;
}
else if (status & STATUS1_FROSTBITE)
{
statusGfxPtr = GetHealthboxElementGfxPtr(GetStatusIconForBattlerId(HEALTHBOX_GFX_STATUS_FSB_BATTLER0, battlerId));
statusPalId = PAL_STATUS_FRZ;
}
else if (status & STATUS1_PARALYSIS)
{
statusGfxPtr = GetHealthboxElementGfxPtr(GetStatusIconForBattlerId(HEALTHBOX_GFX_STATUS_PRZ_BATTLER0, battlerId));
@ -2283,6 +2300,16 @@ static u8 GetStatusIconForBattlerId(u8 statusElementId, u8 battlerId)
else
ret = HEALTHBOX_GFX_STATUS_FRZ_BATTLER3;
break;
case HEALTHBOX_GFX_STATUS_FSB_BATTLER0:
if (battlerId == 0)
ret = HEALTHBOX_GFX_STATUS_FSB_BATTLER0;
else if (battlerId == 1)
ret = HEALTHBOX_GFX_STATUS_FSB_BATTLER1;
else if (battlerId == 2)
ret = HEALTHBOX_GFX_STATUS_FSB_BATTLER2;
else
ret = HEALTHBOX_GFX_STATUS_FSB_BATTLER3;
break;
case HEALTHBOX_GFX_STATUS_BRN_BATTLER0:
if (battlerId == 0)
ret = HEALTHBOX_GFX_STATUS_BRN_BATTLER0;

View File

@ -101,8 +101,10 @@ static const u8 sText_PkmnAlreadyPoisoned[] = _("{B_DEF_NAME_WITH_PREFIX} is alr
static const u8 sText_PkmnBadlyPoisoned[] = _("{B_EFF_NAME_WITH_PREFIX} is badly\npoisoned!");
static const u8 sText_PkmnEnergyDrained[] = _("{B_DEF_NAME_WITH_PREFIX} had its\nenergy drained!");
static const u8 sText_PkmnWasBurned[] = _("{B_EFF_NAME_WITH_PREFIX} was burned!");
static const u8 sText_PkmnGotFrostbite[] = _("{B_EFF_NAME_WITH_PREFIX} got frostbite!");
static const u8 sText_PkmnBurnedBy[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY}\nburned {B_EFF_NAME_WITH_PREFIX}!");
static const u8 sText_PkmnHurtByBurn[] = _("{B_ATK_NAME_WITH_PREFIX} is hurt\nby its burn!");
static const u8 sText_PkmnHurtByFrostbite[] = _("{B_ATK_NAME_WITH_PREFIX} is hurt\nby its frostbite!");
static const u8 sText_PkmnAlreadyHasBurn[] = _("{B_DEF_NAME_WITH_PREFIX} already\nhas a burn.");
static const u8 sText_PkmnWasFrozen[] = _("{B_EFF_NAME_WITH_PREFIX} was\nfrozen solid!");
static const u8 sText_PkmnFrozenBy[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY}\nfroze {B_EFF_NAME_WITH_PREFIX} solid!");
@ -110,6 +112,9 @@ static const u8 sText_PkmnIsFrozen[] = _("{B_ATK_NAME_WITH_PREFIX} is\nfrozen so
static const u8 sText_PkmnWasDefrosted[] = _("{B_DEF_NAME_WITH_PREFIX} was\ndefrosted!");
static const u8 sText_PkmnWasDefrosted2[] = _("{B_ATK_NAME_WITH_PREFIX} was\ndefrosted!");
static const u8 sText_PkmnWasDefrostedBy[] = _("{B_ATK_NAME_WITH_PREFIX} was\ndefrosted by {B_CURRENT_MOVE}!");
static const u8 sText_PkmnFrostbiteHealed[] = _("{B_DEF_NAME_WITH_PREFIX}'s\nfrostbite was healed!");
static const u8 sText_PkmnFrostbiteHealed2[] = _("{B_ATK_NAME_WITH_PREFIX}'s\nfrostbite was healed!");
static const u8 sText_PkmnFrostbiteHealedBy[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_CURRENT_MOVE}\nhealed its frostbite!");
static const u8 sText_PkmnWasParalyzed[] = _("{B_EFF_NAME_WITH_PREFIX} is paralyzed!\nIt may be unable to move!");
static const u8 sText_PkmnWasParalyzedBy[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY}\nparalyzed {B_EFF_NAME_WITH_PREFIX}!\lIt may be unable to move!");
static const u8 sText_PkmnIsParalyzed[] = _("{B_ATK_NAME_WITH_PREFIX} is paralyzed!\nIt can't move!");
@ -491,6 +496,7 @@ static const u8 sText_BerrySuffix[] = _(" BERRY");
static const u8 sText_PkmnsItemCuredParalysis[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ITEM}\ncured paralysis!");
static const u8 sText_PkmnsItemCuredPoison[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ITEM}\ncured poison!");
static const u8 sText_PkmnsItemHealedBurn[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ITEM}\nhealed its burn!");
static const u8 sText_PkmnsItemHealedFrostbite[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ITEM}\nhealed its frostbite!");
static const u8 sText_PkmnsItemDefrostedIt[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ITEM}\ndefrosted it!");
static const u8 sText_PkmnsItemWokeIt[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ITEM}\nwoke it from its sleep!");
static const u8 sText_PkmnsItemSnappedOut[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ITEM}\nsnapped it out of confusion!");
@ -768,6 +774,7 @@ static const u8 sText_AttackerExpelledThePoison[] = _("{B_ATK_NAME_WITH_PREFIX}
static const u8 sText_AttackerShookItselfAwake[] = _("{B_ATK_NAME_WITH_PREFIX} shook itself awake!");
static const u8 sText_AttackerBrokeThroughParalysis[] = _("{B_ATK_NAME_WITH_PREFIX} gathered all its energy\nto overcome its paralysis!");
static const u8 sText_AttackerHealedItsBurn[] = _("{B_ATK_NAME_WITH_PREFIX} healed its burn with\nits sheer determination!");
static const u8 sText_AttackerHealedItsFrostbite[] = _("{B_ATK_NAME_WITH_PREFIX} healed its frostbite with\nits sheer determination!");
static const u8 sText_AttackerMeltedTheIce[] = _("{B_ATK_NAME_WITH_PREFIX} melted the ice with\nits fiery determination!");
static const u8 sText_TargetToughedItOut[] = _("{B_DEF_NAME_WITH_PREFIX} toughed it out\nto show you its best side!");
static const u8 sText_AttackerLostElectricType[] = _("{B_ATK_NAME_WITH_PREFIX} used up all\nof its electricity!");
@ -1430,6 +1437,13 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
[STRINGID_TARGETTOOHEAVY - BATTLESTRINGS_TABLE_START] = sText_TargetTooHeavy,
[STRINGID_ATTACKERLOSTELECTRICTYPE - BATTLESTRINGS_TABLE_START] = sText_AttackerLostElectricType,
[STRINGID_PKMNSABILITYPREVENTSABILITY - BATTLESTRINGS_TABLE_START] = sText_PkmnsAbilityPreventsAbility,
[STRINGID_PKMNHURTBYFROSTBITE - BATTLESTRINGS_TABLE_START] = sText_PkmnHurtByFrostbite,
[STRINGID_PKMNGOTFROSTBITE - BATTLESTRINGS_TABLE_START] = sText_PkmnGotFrostbite,
[STRINGID_PKMNSITEMHEALEDFROSTBITE - BATTLESTRINGS_TABLE_START] = sText_PkmnsItemHealedFrostbite,
[STRINGID_ATTACKERHEALEDITSFROSTBITE - BATTLESTRINGS_TABLE_START] = sText_AttackerHealedItsFrostbite,
[STRINGID_PKMNFROSTBITEHEALED - BATTLESTRINGS_TABLE_START] = sText_PkmnFrostbiteHealed,
[STRINGID_PKMNFROSTBITEHEALED2 - BATTLESTRINGS_TABLE_START] = sText_PkmnFrostbiteHealed2,
[STRINGID_PKMNFROSTBITEHEALEDBY - BATTLESTRINGS_TABLE_START] = sText_PkmnFrostbiteHealedBy,
};
const u16 gTrainerUsedItemStringIds[] =
@ -1732,6 +1746,17 @@ const u16 gGotBurnedStringIds[] =
[B_MSG_STATUSED_BY_ABILITY] = STRINGID_PKMNBURNEDBY
};
const u16 gGotFrostbiteStringIds[] =
{
[B_MSG_STATUSED] = STRINGID_PKMNGOTFROSTBITE
};
const u16 gFrostbiteHealedStringIds[] =
{
[B_MSG_FROSTBITE_HEALED] = STRINGID_PKMNFROSTBITEHEALED2,
[B_MSG_FROSTBITE_HEALED_BY_MOVE] = STRINGID_PKMNFROSTBITEHEALEDBY
};
const u16 gGotFrozenStringIds[] =
{
[B_MSG_STATUSED] = STRINGID_PKMNWASFROZEN,
@ -1892,7 +1917,7 @@ const u16 gRoomsStringIds[] =
const u16 gStatusConditionsStringIds[] =
{
STRINGID_PKMNWASPOISONED, STRINGID_PKMNBADLYPOISONED, STRINGID_PKMNWASBURNED, STRINGID_PKMNWASPARALYZED, STRINGID_PKMNFELLASLEEP
STRINGID_PKMNWASPOISONED, STRINGID_PKMNBADLYPOISONED, STRINGID_PKMNWASBURNED, STRINGID_PKMNWASPARALYZED, STRINGID_PKMNFELLASLEEP, STRINGID_PKMNGOTFROSTBITE
};
const u8 gText_PkmnIsEvolving[] = _("What?\n{STR_VAR_1} is evolving!");

View File

@ -729,6 +729,7 @@ static void GetRoomInflictedStatus(void)
switch (sStatusFlags)
{
case STATUS1_FREEZE:
case STATUS1_FROSTBITE:
gSpecialVar_Result = PIKE_STATUS_FREEZE;
break;
case STATUS1_BURN:
@ -818,6 +819,7 @@ static bool8 DoesAbilityPreventStatus(struct Pokemon *mon, u32 status)
switch (status)
{
case STATUS1_FREEZE:
case STATUS1_FROSTBITE:
if (ability == ABILITY_MAGMA_ARMOR)
ret = TRUE;
break;
@ -853,6 +855,7 @@ static bool8 DoesTypePreventStatus(u16 species, u32 status)
ret = TRUE;
break;
case STATUS1_FREEZE:
case STATUS1_FROSTBITE:
if (gSpeciesInfo[species].types[0] == TYPE_ICE || gSpeciesInfo[species].types[1] == TYPE_ICE)
ret = TRUE;
break;
@ -913,7 +916,11 @@ static bool8 TryInflictRandomStatus(void)
if (rand < 35)
sStatusFlags = STATUS1_TOXIC_POISON;
else if (rand < 60)
#if B_USE_FROSTBITE == TRUE
sStatusFlags = STATUS1_FROSTBITE;
#else
sStatusFlags = STATUS1_FREEZE;
#endif
else if (rand < 80)
sStatusFlags = STATUS1_PARALYSIS;
else if (rand < 90)
@ -950,6 +957,7 @@ static bool8 TryInflictRandomStatus(void)
switch (sStatusFlags)
{
case STATUS1_FREEZE:
case STATUS1_FROSTBITE:
sStatusMon = PIKE_STATUSMON_DUSCLOPS;
break;
case STATUS1_BURN:

View File

@ -61,6 +61,7 @@
#include "constants/trainers.h"
#include "battle_util.h"
#include "constants/pokemon.h"
#include "config/battle.h"
// Helper for accessing command arguments and advancing gBattlescriptCurrInstr.
//
@ -896,6 +897,7 @@ static const u32 sStatusFlagsForMoveEffects[NUM_MOVE_EFFECTS] =
[MOVE_EFFECT_FREEZE] = STATUS1_FREEZE,
[MOVE_EFFECT_PARALYSIS] = STATUS1_PARALYSIS,
[MOVE_EFFECT_TOXIC] = STATUS1_TOXIC_POISON,
[MOVE_EFFECT_FROSTBITE] = STATUS1_FROSTBITE,
[MOVE_EFFECT_CONFUSION] = STATUS2_CONFUSION,
[MOVE_EFFECT_FLINCH] = STATUS2_FLINCHED,
[MOVE_EFFECT_UPROAR] = STATUS2_UPROAR,
@ -919,6 +921,7 @@ static const u8 *const sMoveEffectBS_Ptrs[] =
[MOVE_EFFECT_UPROAR] = BattleScript_MoveEffectUproar,
[MOVE_EFFECT_PAYDAY] = BattleScript_MoveEffectPayDay,
[MOVE_EFFECT_WRAP] = BattleScript_MoveEffectWrap,
[MOVE_EFFECT_FROSTBITE] = BattleScript_MoveEffectFrostbite,
};
static const struct WindowTemplate sUnusedWinTemplate =
@ -3208,6 +3211,12 @@ void SetMoveEffect(bool32 primary, u32 certain)
gMoveResultFlags |= MOVE_RESULT_DOESNT_AFFECT_FOE;
}
break;
case STATUS1_FROSTBITE:
if (!CanGetFrostbite(gEffectBattler))
break;
statusChanged = TRUE;
break;
}
if (statusChanged == TRUE)
{
@ -3366,7 +3375,11 @@ void SetMoveEffect(bool32 primary, u32 certain)
}
else
{
#if B_USE_FROSTBITE == TRUE
static const u8 sTriAttackEffects[] = { MOVE_EFFECT_BURN, MOVE_EFFECT_FROSTBITE, MOVE_EFFECT_PARALYSIS };
#else
static const u8 sTriAttackEffects[] = { MOVE_EFFECT_BURN, MOVE_EFFECT_FREEZE, MOVE_EFFECT_PARALYSIS };
#endif
gBattleScripting.moveEffect = RandomElement(RNG_TRI_ATTACK, sTriAttackEffects);
SetMoveEffect(FALSE, 0);
}
@ -5575,7 +5588,6 @@ static void Cmd_moveend(void)
if (gBattleMons[gBattlerTarget].status1 & STATUS1_FREEZE
&& gBattleMons[gBattlerTarget].hp != 0
&& gBattlerAttacker != gBattlerTarget
&& gSpecialStatuses[gBattlerTarget].specialDmg
&& (moveType == TYPE_FIRE
#if B_BURN_HIT_THAW >= GEN_6
|| gBattleMoves[gCurrentMove].effect == EFFECT_BURN_HIT
@ -5591,6 +5603,20 @@ static void Cmd_moveend(void)
gBattlescriptCurrInstr = BattleScript_DefrostedViaFireMove;
effect = TRUE;
}
if (gBattleMons[gBattlerTarget].status1 & STATUS1_FROSTBITE
&& gBattleMons[gBattlerTarget].hp != 0
&& gBattlerAttacker != gBattlerTarget
&& gBattleMoves[originallyUsedMove].flags & FLAG_THAW_USER
&& !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT))
{
gBattleMons[gBattlerTarget].status1 &= ~STATUS1_FROSTBITE;
gActiveBattler = gBattlerTarget;
BtlController_EmitSetMonData(BUFFER_A, REQUEST_STATUS_BATTLE, 0, sizeof(gBattleMons[gBattlerTarget].status1), &gBattleMons[gBattlerTarget].status1);
MarkBattlerForControllerExec(gActiveBattler);
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_FrostbiteHealedViaFireMove;
effect = TRUE;
}
gBattleScripting.moveendState++;
break;
case MOVEEND_RECOIL:
@ -9917,6 +9943,9 @@ static void Cmd_various(void)
case STATUS1_TOXIC_POISON:
gBattleScripting.moveEffect = MOVE_EFFECT_TOXIC;
break;
case STATUS1_FROSTBITE:
gBattleScripting.moveEffect = MOVE_EFFECT_FROSTBITE;
break;
default:
gBattleScripting.moveEffect = 0;
break;
@ -10085,6 +10114,8 @@ static void Cmd_various(void)
gBattleCommunication[MULTISTRING_CHOOSER] = 3;
else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP) && CanSleep(gBattlerTarget))
gBattleCommunication[MULTISTRING_CHOOSER] = 4;
else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_FROSTBITE) && CanBeFrozen(gBattlerTarget))
gBattleCommunication[MULTISTRING_CHOOSER] = 5;
else
{
gBattlescriptCurrInstr = cmd->failInstr;
@ -14315,7 +14346,7 @@ static void Cmd_cureifburnedparalysedorpoisoned(void)
{
CMD_ARGS(const u8 *failInstr);
if (gBattleMons[gBattlerAttacker].status1 & (STATUS1_POISON | STATUS1_BURN | STATUS1_PARALYSIS | STATUS1_TOXIC_POISON))
if (gBattleMons[gBattlerAttacker].status1 & (STATUS1_POISON | STATUS1_BURN | STATUS1_PARALYSIS | STATUS1_TOXIC_POISON | STATUS1_FROSTBITE))
{
gBattleMons[gBattlerAttacker].status1 = 0;
gBattlescriptCurrInstr = cmd->nextInstr;
@ -15037,7 +15068,11 @@ u16 GetSecretPowerMoveEffect(void)
break;
case BATTLE_TERRAIN_SNOW:
case BATTLE_TERRAIN_ICE:
#if B_USE_FROSTBITE == TRUE
moveEffect = MOVE_EFFECT_FROSTBITE;
#else
moveEffect = MOVE_EFFECT_FREEZE;
#endif
break;
case BATTLE_TERRAIN_VOLCANO:
moveEffect = MOVE_EFFECT_BURN;
@ -15626,7 +15661,7 @@ static void Cmd_handleballthrow(void)
if (gBattleMons[gBattlerTarget].status1 & (STATUS1_SLEEP | STATUS1_FREEZE))
odds *= 2;
if (gBattleMons[gBattlerTarget].status1 & (STATUS1_POISON | STATUS1_BURN | STATUS1_PARALYSIS | STATUS1_TOXIC_POISON))
if (gBattleMons[gBattlerTarget].status1 & (STATUS1_POISON | STATUS1_BURN | STATUS1_PARALYSIS | STATUS1_TOXIC_POISON | STATUS1_FROSTBITE))
odds = (odds * 15) / 10;
if (gBattleResults.catchAttempts[gLastUsedItem - FIRST_BALL] < 255)

View File

@ -481,6 +481,7 @@ static const u16 sPoints_MoveEffect[NUM_BATTLE_MOVE_EFFECTS] =
[EFFECT_DOUBLE_SHOCK] = 0, // TODO: Assign points
[EFFECT_SPECIAL_ATTACK_UP_HIT] = 1,
[EFFECT_VICTORY_DANCE] = 0, // TODO: Assign points
[EFFECT_FROSTBITE_HIT] = 1,
};
static const u16 sPoints_Effectiveness[] =

View File

@ -2533,6 +2533,7 @@ enum
ENDTURN_POISON,
ENDTURN_BAD_POISON,
ENDTURN_BURN,
ENDTURN_FROSTBITE,
ENDTURN_NIGHTMARES,
ENDTURN_CURSE,
ENDTURN_WRAP,
@ -2746,6 +2747,23 @@ u8 DoBattlerEndTurnEffects(void)
}
gBattleStruct->turnEffectsTracker++;
break;
case ENDTURN_FROSTBITE: // burn
if ((gBattleMons[gActiveBattler].status1 & STATUS1_FROSTBITE)
&& gBattleMons[gActiveBattler].hp != 0)
{
MAGIC_GUARD_CHECK;
#if B_BURN_DAMAGE >= GEN_7
gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 16;
#else
gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 8;
#endif
if (gBattleMoveDamage == 0)
gBattleMoveDamage = 1;
BattleScriptExecute(BattleScript_FrostbiteTurnDmg);
effect++;
}
gBattleStruct->turnEffectsTracker++;
break;
case ENDTURN_NIGHTMARES: // spooky nightmares
if ((gBattleMons[gActiveBattler].status2 & STATUS2_NIGHTMARE)
&& gBattleMons[gActiveBattler].hp != 0)
@ -3637,6 +3655,17 @@ u8 AtkCanceller_UnableToUseMove(void)
}
effect = 2;
}
if (gBattleMons[gBattlerAttacker].status1 & STATUS1_FROSTBITE && (gBattleMoves[gCurrentMove].flags & FLAG_THAW_USER))
{
if (!(gBattleMoves[gCurrentMove].effect == EFFECT_BURN_UP && !IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_FIRE)))
{
gBattleMons[gBattlerAttacker].status1 &= ~STATUS1_FROSTBITE;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_MoveUsedUnfrostbite;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_FROSTBITE_HEALED_BY_MOVE;
}
effect = 2;
}
gBattleStruct->atkCancellerTracker++;
break;
case CANCELLER_POWDER_MOVE:
@ -4852,7 +4881,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
StringCopy(gBattleTextBuff1, gStatusConditionString_ParalysisJpn);
if (gBattleMons[battler].status1 & STATUS1_BURN)
StringCopy(gBattleTextBuff1, gStatusConditionString_BurnJpn);
if (gBattleMons[battler].status1 & STATUS1_FREEZE)
if (gBattleMons[battler].status1 & (STATUS1_FREEZE | STATUS1_FROSTBITE))
StringCopy(gBattleTextBuff1, gStatusConditionString_IceJpn);
gBattleMons[battler].status1 = 0;
@ -5878,7 +5907,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
}
break;
case ABILITY_MAGMA_ARMOR:
if (gBattleMons[battler].status1 & STATUS1_FREEZE)
if (gBattleMons[battler].status1 & (STATUS1_FREEZE | STATUS1_FROSTBITE))
{
StringCopy(gBattleTextBuff1, gStatusConditionString_IceJpn);
effect = 1;
@ -6411,6 +6440,20 @@ bool32 CanBeFrozen(u8 battlerId)
return TRUE;
}
bool32 CanGetFrostbite(u8 battlerId)
{
u16 ability = GetBattlerAbility(battlerId);
if (IS_BATTLER_OF_TYPE(battlerId, TYPE_ICE)
|| gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_SAFEGUARD
|| ability == ABILITY_MAGMA_ARMOR
|| ability == ABILITY_COMATOSE
|| gBattleMons[battlerId].status1 & STATUS1_ANY
|| IsAbilityStatusProtected(battlerId)
|| IsBattlerTerrainAffected(battlerId, STATUS_FIELD_MISTY_TERRAIN))
return FALSE;
return TRUE;
}
bool32 CanBeConfused(u8 battlerId)
{
if (GetBattlerAbility(battlerId) == ABILITY_OWN_TEMPO
@ -6825,6 +6868,13 @@ static u8 ItemEffectMoveEnd(u32 battlerId, u16 holdEffect)
gBattlescriptCurrInstr = BattleScript_BerryCureFrzRet;
effect = ITEM_STATUS_CHANGE;
}
if (gBattleMons[battlerId].status1 & STATUS1_FROSTBITE && !UnnerveOn(battlerId, gLastUsedItem))
{
gBattleMons[battlerId].status1 &= ~STATUS1_FROSTBITE;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_BerryCureFsbRet;
effect = ITEM_STATUS_CHANGE;
}
break;
case HOLD_EFFECT_CURE_SLP:
if (gBattleMons[battlerId].status1 & STATUS1_SLEEP && !UnnerveOn(battlerId, gLastUsedItem))
@ -6873,7 +6923,7 @@ static u8 ItemEffectMoveEnd(u32 battlerId, u16 holdEffect)
if (gBattleMons[battlerId].status1 & STATUS1_BURN)
StringCopy(gBattleTextBuff1, gStatusConditionString_BurnJpn);
if (gBattleMons[battlerId].status1 & STATUS1_FREEZE)
if (gBattleMons[battlerId].status1 & STATUS1_FREEZE || gBattleMons[battlerId].status1 & STATUS1_FROSTBITE)
StringCopy(gBattleTextBuff1, gStatusConditionString_IceJpn);
if (gBattleMons[battlerId].status2 & STATUS2_CONFUSION)
@ -7061,6 +7111,12 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn)
BattleScriptExecute(BattleScript_BerryCureFrzEnd2);
effect = ITEM_STATUS_CHANGE;
}
if (gBattleMons[battlerId].status1 & STATUS1_FROSTBITE && !UnnerveOn(battlerId, gLastUsedItem))
{
gBattleMons[battlerId].status1 &= ~STATUS1_FROSTBITE;
BattleScriptExecute(BattleScript_BerryCureFsbEnd2);
effect = ITEM_STATUS_CHANGE;
}
break;
case HOLD_EFFECT_CURE_SLP:
if (gBattleMons[battlerId].status1 & STATUS1_SLEEP && !UnnerveOn(battlerId, gLastUsedItem))
@ -7096,7 +7152,7 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn)
StringCopy(gBattleTextBuff1, gStatusConditionString_BurnJpn);
i++;
}
if (gBattleMons[battlerId].status1 & STATUS1_FREEZE)
if (gBattleMons[battlerId].status1 & STATUS1_FREEZE || gBattleMons[battlerId].status1 & STATUS1_FROSTBITE)
{
StringCopy(gBattleTextBuff1, gStatusConditionString_IceJpn);
i++;
@ -7394,6 +7450,12 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn)
BattleScriptExecute(BattleScript_BerryCureFrzEnd2);
effect = ITEM_STATUS_CHANGE;
}
if (gBattleMons[battlerId].status1 & STATUS1_FROSTBITE && !UnnerveOn(battlerId, gLastUsedItem))
{
gBattleMons[battlerId].status1 &= ~STATUS1_FROSTBITE;
BattleScriptExecute(BattleScript_BerryCureFsbEnd2);
effect = ITEM_STATUS_CHANGE;
}
break;
case HOLD_EFFECT_CURE_SLP:
if (gBattleMons[battlerId].status1 & STATUS1_SLEEP && !UnnerveOn(battlerId, gLastUsedItem))
@ -7437,7 +7499,7 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn)
StringCopy(gBattleTextBuff1, gStatusConditionString_BurnJpn);
i++;
}
if (gBattleMons[battlerId].status1 & STATUS1_FREEZE)
if (gBattleMons[battlerId].status1 & STATUS1_FREEZE || gBattleMons[battlerId].status1 & STATUS1_FROSTBITE)
{
StringCopy(gBattleTextBuff1, gStatusConditionString_IceJpn);
i++;
@ -9020,7 +9082,7 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe
switch (gBattleMoves[move].effect)
{
case EFFECT_FACADE:
if (gBattleMons[battlerAtk].status1 & (STATUS1_BURN | STATUS1_PSN_ANY | STATUS1_PARALYSIS))
if (gBattleMons[battlerAtk].status1 & (STATUS1_BURN | STATUS1_PSN_ANY | STATUS1_PARALYSIS | STATUS1_FROSTBITE))
MulModifier(&modifier, UQ_4_12(2.0));
break;
case EFFECT_BRINE:
@ -9489,6 +9551,14 @@ static u32 CalcFinalDmg(u32 dmg, u16 move, u8 battlerAtk, u8 battlerDef, u8 move
&& abilityAtk != ABILITY_GUTS)
dmg = ApplyModifier(UQ_4_12(0.5), dmg);
// check frostbite
if (gBattleMons[battlerAtk].status1 & STATUS1_FROSTBITE && !IS_MOVE_PHYSICAL(move)
#if B_BURN_FACADE_DMG >= GEN_6
&& gBattleMoves[move].effect != EFFECT_FACADE
#endif
&& abilityAtk != ABILITY_GUTS)
dmg = ApplyModifier(UQ_4_12(0.5), dmg);
// check sunny/rain weather
if (IsBattlerWeatherAffected(battlerAtk, B_WEATHER_RAIN))
{

View File

@ -121,7 +121,11 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] =
[MOVE_ICE_PUNCH] =
{
.effect = EFFECT_FREEZE_HIT,
#if B_USE_FROSTBITE == TRUE
.effect = EFFECT_FROSTBITE_HIT,
#else
.effect = EFFECT_FREEZE_HIT,
#endif
.power = 75,
.type = TYPE_ICE,
.accuracy = 100,
@ -982,7 +986,13 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] =
#else
.power = 95,
#endif
.effect = EFFECT_FREEZE_HIT,
// The following effect is also relevant in battle_pike.c
// If you cherry-pick this to use something other than the config, make sure to update it there too
#if B_USE_FROSTBITE == TRUE
.effect = EFFECT_FROSTBITE_HIT,
#else
.effect = EFFECT_FREEZE_HIT,
#endif
.type = TYPE_ICE,
.accuracy = 100,
.pp = 10,
@ -1001,7 +1011,11 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] =
#else
.power = 120,
#endif
.effect = EFFECT_FREEZE_HIT,
#if B_USE_FROSTBITE == TRUE
.effect = EFFECT_FROSTBITE_HIT,
#else
.effect = EFFECT_FREEZE_HIT,
#endif
.type = TYPE_ICE,
.accuracy = 70,
.pp = 5,
@ -3062,7 +3076,11 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] =
[MOVE_POWDER_SNOW] =
{
.effect = EFFECT_FREEZE_HIT,
#if B_USE_FROSTBITE == TRUE
.effect = EFFECT_FROSTBITE_HIT,
#else
.effect = EFFECT_FREEZE_HIT,
#endif
.power = 40,
.type = TYPE_ICE,
.accuracy = 100,
@ -7177,6 +7195,11 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] =
#else
.flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_STRONG_JAW_BOOST,
#endif
#if B_USE_FROSTBITE == TRUE
.argument = STATUS1_FROSTBITE,
#else
.argument = STATUS1_FREEZE,
#endif
.effect = EFFECT_FLINCH_STATUS,
.power = 65,
.type = TYPE_ICE,
@ -7186,7 +7209,6 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.split = SPLIT_PHYSICAL,
.argument = STATUS1_FREEZE,
.zMoveEffect = Z_EFFECT_NONE,
},
@ -12354,7 +12376,11 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] =
[MOVE_FREEZING_GLARE] =
{
.power = 90,
.effect = EFFECT_FREEZE_HIT,
#if B_USE_FROSTBITE == TRUE
.effect = EFFECT_FROSTBITE_HIT,
#else
.effect = EFFECT_FREEZE_HIT,
#endif
.type = TYPE_PSYCHIC,
.accuracy = 100,
.pp = 10,

View File

@ -1054,7 +1054,7 @@ static const union AnimCmd sSpriteAnim_StatusFaint[] =
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_Blank[] =
static const union AnimCmd sSpriteAnim_StatusFrostbite[] =
{
ANIMCMD_FRAME(28, 0),
ANIMCMD_END
@ -1069,7 +1069,7 @@ static const union AnimCmd *const sSpriteTemplate_StatusCondition[] =
sSpriteAnim_StatusBurn,
sSpriteAnim_StatusPokerus,
sSpriteAnim_StatusFaint,
sSpriteAnim_Blank
sSpriteAnim_StatusFrostbite
};
static const struct CompressedSpriteSheet sSpriteSheet_StatusIcons =

View File

@ -38,7 +38,11 @@ static const u8 sFirePunchDescription[] = _(
static const u8 sIcePunchDescription[] = _(
"An icy punch that may\n"
#if B_USE_FROSTBITE == TRUE
"leave the foe with frostbite.");
#else
"freeze the foe.");
#endif
static const u8 sThunderPunchDescription[] = _(
"An electrified punch that\n"
@ -238,11 +242,19 @@ static const u8 sSurfDescription[] = _(
static const u8 sIceBeamDescription[] = _(
"Blasts the foe with an icy\n"
#if B_USE_FROSTBITE == TRUE
"beam. May cause frostbite.");
#else
"beam that may freeze it.");
#endif
static const u8 sBlizzardDescription[] = _(
"Hits the foe with an icy\n"
#if B_USE_FROSTBITE == TRUE
"storm. May cause frostbite.");
#else
"storm that may freeze it.");
#endif
static const u8 sPsybeamDescription[] = _(
"Fires a peculiar ray that\n"
@ -2931,7 +2943,11 @@ static const u8 sDragonEnergyDescription[] = _(
static const u8 sFreezingGlareDescription[] = _(
"Shoots psychic power from\n"
#if B_USE_FROSTBITE == TRUE
"the eyes. May frostbite.");
#else
"the eyes. May freeze the foe.");
#endif
static const u8 sFieryWrathDescription[] = _(
"An attack fueled by your\n"

View File

@ -941,7 +941,7 @@ u8 ItemId_GetBattleUsage(u16 itemId)
case ITEM_EFFECT_CURE_POISON:
case ITEM_EFFECT_CURE_SLEEP:
case ITEM_EFFECT_CURE_BURN:
case ITEM_EFFECT_CURE_FREEZE:
case ITEM_EFFECT_CURE_FREEZE_FROSTBITE:
case ITEM_EFFECT_CURE_PARALYSIS:
case ITEM_EFFECT_CURE_ALL_STATUS:
case ITEM_EFFECT_CURE_CONFUSION:
@ -976,7 +976,7 @@ u32 GetItemStatus1Mask(u16 itemId)
case ITEM3_PARALYSIS:
return STATUS1_PARALYSIS;
case ITEM3_FREEZE:
return STATUS1_FREEZE;
return STATUS1_FREEZE | STATUS1_FROSTBITE;
case ITEM3_BURN:
return STATUS1_BURN;
case ITEM3_POISON:

View File

@ -1245,7 +1245,7 @@ void ItemUseOutOfBattle_EnigmaBerry(u8 taskId)
case ITEM_EFFECT_CURE_POISON:
case ITEM_EFFECT_CURE_SLEEP:
case ITEM_EFFECT_CURE_BURN:
case ITEM_EFFECT_CURE_FREEZE:
case ITEM_EFFECT_CURE_FREEZE_FROSTBITE:
case ITEM_EFFECT_CURE_PARALYSIS:
case ITEM_EFFECT_CURE_ALL_STATUS:
case ITEM_EFFECT_ATK_EV:

View File

@ -1942,6 +1942,8 @@ u8 GetAilmentFromStatus(u32 status)
return AILMENT_FRZ;
if (status & STATUS1_BURN)
return AILMENT_BRN;
if (status & STATUS1_FROSTBITE)
return AILMENT_FSB;
return AILMENT_NONE;
}
@ -4316,7 +4318,7 @@ static bool8 IsHPRecoveryItem(u16 item)
return FALSE;
}
static void GetMedicineItemEffectMessage(u16 item)
static void GetMedicineItemEffectMessage(u16 item, u32 statusCured)
{
switch (GetItemEffectType(item))
{
@ -4329,8 +4331,11 @@ static void GetMedicineItemEffectMessage(u16 item)
case ITEM_EFFECT_CURE_BURN:
StringExpandPlaceholders(gStringVar4, gText_PkmnBurnHealed);
break;
case ITEM_EFFECT_CURE_FREEZE:
StringExpandPlaceholders(gStringVar4, gText_PkmnThawedOut);
case ITEM_EFFECT_CURE_FREEZE_FROSTBITE:
if (statusCured & STATUS1_FREEZE)
StringExpandPlaceholders(gStringVar4, gText_PkmnThawedOut);
if (statusCured & STATUS1_FROSTBITE)
StringExpandPlaceholders(gStringVar4, gText_PkmnFrostbiteHealed);
break;
case ITEM_EFFECT_CURE_PARALYSIS:
StringExpandPlaceholders(gStringVar4, gText_PkmnCuredOfParalysis);
@ -4491,6 +4496,7 @@ void ItemUseCB_Medicine(u8 taskId, TaskFunc task)
struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId];
u16 item = gSpecialVar_ItemId;
bool8 canHeal, cannotUse;
u32 oldStatus = GetMonData(mon, MON_DATA_STATUS);
if (NotUsingHPEVItemOnShedinja(mon, item) == FALSE)
{
@ -4543,7 +4549,7 @@ void ItemUseCB_Medicine(u8 taskId, TaskFunc task)
else
{
GetMonNickname(mon, gStringVar1);
GetMedicineItemEffectMessage(item);
GetMedicineItemEffectMessage(item, oldStatus);
DisplayPartyMenuMessage(gStringVar4, TRUE);
ScheduleBgCopyTilemapToVram(2);
gTasks[taskId].func = task;
@ -4967,7 +4973,7 @@ static void TryUseItemOnMove(u8 taskId)
RemoveBagItem(item, 1);
move = GetMonData(mon, MON_DATA_MOVE1 + *moveSlot);
StringCopy(gStringVar1, gMoveNames[move]);
GetMedicineItemEffectMessage(item);
GetMedicineItemEffectMessage(item, 0);
DisplayPartyMenuMessage(gStringVar4, TRUE);
ScheduleBgCopyTilemapToVram(2);
gTasks[taskId].func = Task_ClosePartyMenuAfterText;
@ -5817,7 +5823,7 @@ u8 GetItemEffectType(u16 item)
else if (statusCure == ITEM3_BURN)
return ITEM_EFFECT_CURE_BURN;
else if (statusCure == ITEM3_FREEZE)
return ITEM_EFFECT_CURE_FREEZE;
return ITEM_EFFECT_CURE_FREEZE_FROSTBITE;
else if (statusCure == ITEM3_PARALYSIS)
return ITEM_EFFECT_CURE_PARALYSIS;
else if (statusCure == ITEM3_CONFUSION)

View File

@ -5815,7 +5815,7 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov
retVal = FALSE;
if ((itemEffect[i] & ITEM3_BURN) && HealStatusConditions(mon, partyIndex, STATUS1_BURN, battlerId) == 0)
retVal = FALSE;
if ((itemEffect[i] & ITEM3_FREEZE) && HealStatusConditions(mon, partyIndex, STATUS1_FREEZE, battlerId) == 0)
if ((itemEffect[i] & ITEM3_FREEZE) && HealStatusConditions(mon, partyIndex, STATUS1_FREEZE | STATUS1_FROSTBITE, battlerId) == 0)
retVal = FALSE;
if ((itemEffect[i] & ITEM3_PARALYSIS) && HealStatusConditions(mon, partyIndex, STATUS1_PARALYSIS, battlerId) == 0)
retVal = FALSE;

View File

@ -1112,6 +1112,10 @@ static const union AnimCmd sSpriteAnim_StatusFaint[] = {
ANIMCMD_FRAME(24, 0, FALSE, FALSE),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_StatusFrostbite[] = {
ANIMCMD_FRAME(28, 0, FALSE, FALSE),
ANIMCMD_END
};
static const union AnimCmd *const sSpriteAnimTable_StatusCondition[] = {
sSpriteAnim_StatusPoison,
sSpriteAnim_StatusParalyzed,
@ -1120,11 +1124,12 @@ static const union AnimCmd *const sSpriteAnimTable_StatusCondition[] = {
sSpriteAnim_StatusBurn,
sSpriteAnim_StatusPokerus,
sSpriteAnim_StatusFaint,
sSpriteAnim_StatusFrostbite,
};
static const struct CompressedSpriteSheet sStatusIconsSpriteSheet =
{
.data = gStatusGfx_Icons,
.size = 0x380,
.size = 0x400,
.tag = TAG_MON_STATUS
};
static const struct CompressedSpritePalette sStatusIconsSpritePalette =

View File

@ -414,6 +414,7 @@ const u8 gText_PkmnCuredOfPoison[] = _("{STR_VAR_1} was cured of its\npoisoning.
const u8 gText_PkmnCuredOfParalysis[] = _("{STR_VAR_1} was cured of\nparalysis.{PAUSE_UNTIL_PRESS}");
const u8 gText_PkmnWokeUp2[] = _("{STR_VAR_1} woke up.{PAUSE_UNTIL_PRESS}");
const u8 gText_PkmnBurnHealed[] = _("{STR_VAR_1}'s burn was healed.{PAUSE_UNTIL_PRESS}");
const u8 gText_PkmnFrostbiteHealed[] = _("{STR_VAR_1}'s frostbite was healed.{PAUSE_UNTIL_PRESS}");
const u8 gText_PkmnThawedOut[] = _("{STR_VAR_1} was thawed out.{PAUSE_UNTIL_PRESS}");
const u8 gText_PPWasRestored[] = _("PP was restored.{PAUSE_UNTIL_PRESS}");
const u8 gText_PkmnRegainhedHealth[] = _("{STR_VAR_1} regained health.{PAUSE_UNTIL_PRESS}"); // Unused

96
test/status_frostbite.c Normal file
View File

@ -0,0 +1,96 @@
#include "global.h"
#include "test_battle.h"
SINGLE_BATTLE_TEST("Frostbite reduces the special attack by 50 percent")
{
s16 reducedDamage;
s16 normaleDamage;
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET) { Status1(STATUS1_FROSTBITE); }
} WHEN {
TURN { MOVE(opponent, MOVE_SWIFT); MOVE(player, MOVE_FLAME_WHEEL); }
TURN { MOVE(opponent, MOVE_SWIFT); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_SWIFT, opponent);
HP_BAR(player, captureDamage: &reducedDamage);
ANIMATION(ANIM_TYPE_MOVE, MOVE_FLAME_WHEEL, player);
HP_BAR(opponent);
ANIMATION(ANIM_TYPE_MOVE, MOVE_SWIFT, opponent);
HP_BAR(player, captureDamage: &normaleDamage);
} THEN { EXPECT_EQ(reducedDamage * 2, normaleDamage); }
}
SINGLE_BATTLE_TEST("Frostbite deals 1/16 damage to effected pokemon")
{
s16 frostbiteDamage;
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET) { Status1(STATUS1_FROSTBITE); }
} WHEN {
TURN { }
} SCENE {
MESSAGE("Foe Wobbuffet is hurt by its frostbite!");
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_FRZ, opponent);
HP_BAR(opponent, captureDamage: &frostbiteDamage);
} THEN { EXPECT_EQ(frostbiteDamage, opponent->maxHP / 16); }
}
SINGLE_BATTLE_TEST("Frostbite is healed if hit with a thawing move")
{
u32 move;
PARAMETRIZE { move = MOVE_FLAME_WHEEL; }
PARAMETRIZE { move = MOVE_SACRED_FIRE; }
PARAMETRIZE { move = MOVE_FLARE_BLITZ; }
PARAMETRIZE { move = MOVE_FUSION_FLARE; }
PARAMETRIZE { move = MOVE_EMBER; }
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET) { Status1(STATUS1_FROSTBITE); }
} WHEN {
TURN { MOVE(player, move); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, move, player);
if (move == MOVE_EMBER) {
NONE_OF {
MESSAGE("Foe Wobbuffet's frostbite was healed!");
}
} else {
MESSAGE("Foe Wobbuffet's frostbite was healed!");
}
}
}
SINGLE_BATTLE_TEST("Frostbite is healed when the user uses a thawing move")
{
u32 move;
PARAMETRIZE { move = MOVE_FLAME_WHEEL; }
PARAMETRIZE { move = MOVE_SACRED_FIRE; }
PARAMETRIZE { move = MOVE_FLARE_BLITZ; }
PARAMETRIZE { move = MOVE_FUSION_FLARE; }
PARAMETRIZE { move = MOVE_EMBER; }
GIVEN {
PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_FROSTBITE); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, move); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, move, player);
HP_BAR(opponent);
if (move == MOVE_EMBER) {
MESSAGE("Wobbuffet is hurt by its frostbite!");
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_FRZ, player);
} else {
NONE_OF {
MESSAGE("Wobbuffet is hurt by its frostbite!");
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_FRZ, player);
}
}
}
}

View File

@ -333,7 +333,7 @@
* Used when the battler chooses to switch to another Pokémon but not
* via Switch, e.g. after fainting or due to a U-turn.
* SEND_OUT(player, 1);
*
*
* USE_ITEM(battler, itemId, [partyIndex:], [move:])
* Used when the battler chooses to use an item from the Bag. The item
* ID must be specified, and party index and move slot if applicable, e.g:
@ -526,8 +526,7 @@ struct QueuedMessageEvent
struct QueuedStatusEvent
{
u32 battlerId:3;
u32 mask:8;
u32 unused_01:21;
u32 mask:29;
};
struct QueuedEvent
@ -872,6 +871,7 @@ struct StatusEventContext
bool8 freeze:1;
bool8 paralysis:1;
bool8 badPoison:1;
bool8 frostbite:1;
};
void OpenQueueGroup(u32 sourceLine, enum QueueGroupType);

View File

@ -1720,6 +1720,8 @@ void QueueStatus(u32 sourceLine, struct BattlePokemon *battler, struct StatusEve
mask = STATUS1_PARALYSIS;
else if (ctx.badPoison)
mask = STATUS1_TOXIC_POISON;
else if (ctx.frostbite)
mask = STATUS1_FROSTBITE;
else
mask = ctx.status1;