mirror of
https://github.com/pret/pokefirered.git
synced 2026-05-24 06:36:49 -05:00
updated up to Cmd_seteffectsecondary, Cmd_setgastroacid and Cmd_setstealthrock
This commit is contained in:
parent
3ad08c53b0
commit
a5f2b89e29
|
|
@ -92,7 +92,7 @@
|
|||
.4byte \ptr
|
||||
.endm
|
||||
|
||||
.macro seteffectwithchance
|
||||
.macro setadditionaleffects
|
||||
.byte 0x15
|
||||
.endm
|
||||
|
||||
|
|
@ -1095,8 +1095,9 @@
|
|||
.4byte \param0
|
||||
.endm
|
||||
|
||||
.macro doubledamagedealtifdamaged
|
||||
.macro setgastroacid failInstr:req
|
||||
.byte 0xd6
|
||||
.4byte \failInstr
|
||||
.endm
|
||||
|
||||
.macro setyawn param0:req
|
||||
|
|
@ -1123,9 +1124,9 @@
|
|||
.4byte \param0
|
||||
.endm
|
||||
|
||||
.macro trysetgrudge param0:req
|
||||
.macro setstealthrock failInstr:req
|
||||
.byte 0xdc
|
||||
.4byte \param0
|
||||
.4byte \failInstr
|
||||
.endm
|
||||
|
||||
.macro weightdamagecalculation
|
||||
|
|
@ -1307,13 +1308,13 @@
|
|||
various \battler, VARIOUS_WAIT_FANFARE
|
||||
.endm
|
||||
|
||||
@ pokeemerald
|
||||
|
||||
.macro handleformchange battler:req, case:req
|
||||
various \battler, VARIOUS_HANDLE_FORM_CHANGE
|
||||
.byte \case
|
||||
.endm
|
||||
|
||||
@ pokeemerald
|
||||
|
||||
.macro playmoveanimation battler:req, move:req
|
||||
various \battler, VARIOUS_PLAY_MOVE_ANIMATION
|
||||
.2byte \move
|
||||
|
|
@ -1334,10 +1335,26 @@
|
|||
.byte \equal
|
||||
.endm
|
||||
|
||||
.macro jumpifnoholdeffect battler:req, holdEffect:req, jumpInstr:req
|
||||
jumpifholdeffect \battler, \holdEffect, \jumpInstr, FALSE
|
||||
.macro savetarget
|
||||
various BS_TARGET, VARIOUS_SAVE_TARGET
|
||||
.endm
|
||||
|
||||
.macro restoretarget
|
||||
various BS_TARGET, VARIOUS_RESTORE_TARGET
|
||||
.endm
|
||||
|
||||
.macro spectralthiefprintstats
|
||||
various BS_ATTACKER, VARIOUS_SPECTRAL_THIEF
|
||||
.endm
|
||||
|
||||
.macro trytoclearprimalweather
|
||||
various BS_ATTACKER, VARIOUS_TRY_TO_CLEAR_PRIMAL_WEATHER
|
||||
.endm
|
||||
|
||||
.macro consumeberry battler:req, fromBattler:req
|
||||
various \battler, VARIOUS_CONSUME_BERRY
|
||||
.byte \fromBattler
|
||||
.endm
|
||||
|
||||
@ helpful macros
|
||||
.macro setstatchanger stat:req, stages:req, down:req
|
||||
|
|
@ -1416,6 +1433,10 @@
|
|||
jumpifword CMP_NO_COMMON_BITS, gBattleTypeFlags, \flags, \jumpptr
|
||||
.endm
|
||||
|
||||
.macro jumpifnoholdeffect battler:req, holdEffect:req, jumpInstr:req
|
||||
jumpifholdeffect \battler, \holdEffect, \jumpInstr, FALSE
|
||||
.endm
|
||||
|
||||
@ callnative macros
|
||||
.macro itemrestorehp
|
||||
callnative BS_ItemRestoreHP
|
||||
|
|
@ -1443,3 +1464,12 @@
|
|||
printstring STRINGID_EMPTYSTRING3
|
||||
waitmessage 1
|
||||
.endm
|
||||
|
||||
.macro tryrevertweatherform
|
||||
callnative BS_TryRevertWeatherForm
|
||||
.endm
|
||||
|
||||
@ Used by effects that may proc Symbiosis but do not call removeitem.
|
||||
.macro trysymbiosis
|
||||
callnative BS_TrySymbiosis
|
||||
.endm
|
||||
|
|
|
|||
|
|
@ -406,6 +406,7 @@ B_DEF_PREFIX3 = FD 2D
|
|||
B_TRAINER2_LOSE_TEXT = FD 2E
|
||||
B_TRAINER2_WIN_TEXT = FD 2F
|
||||
B_BUFF3 = FD 30
|
||||
B_DEF_TEAM2 = FD 3B
|
||||
|
||||
@ indicates the end of a town/city name (before " TOWN" or " CITY")
|
||||
NAME_END = FC 00
|
||||
|
|
|
|||
|
|
@ -268,7 +268,7 @@ BattleScript_HitFromAtkAnimation::
|
|||
waitmessage B_WAIT_TIME_LONG
|
||||
resultmessage
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
seteffectwithchance
|
||||
setadditionaleffects
|
||||
tryfaintmon BS_TARGET
|
||||
BattleScript_MoveEnd::
|
||||
moveendall
|
||||
|
|
@ -514,6 +514,7 @@ BattleScript_StatUpEnd::
|
|||
|
||||
BattleScript_StatUp::
|
||||
playanimation BS_EFFECT_BATTLER, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1
|
||||
BattleScript_StatUpMsg::
|
||||
printfromtable gStatUpStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
|
@ -652,7 +653,7 @@ BattleScript_MultiHitPrintStrings::
|
|||
printstring STRINGID_HITXTIMES
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
BattleScript_MultiHitEnd::
|
||||
seteffectwithchance
|
||||
setadditionaleffects
|
||||
tryfaintmon BS_TARGET
|
||||
moveendcase MOVEEND_SYNCHRONIZE_TARGET
|
||||
moveendfrom MOVEEND_IMMUNITY_ABILITIES
|
||||
|
|
@ -1431,7 +1432,7 @@ BattleScript_TripleKickPrintStrings::
|
|||
printstring STRINGID_HITXTIMES
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
BattleScript_TripleKickEnd::
|
||||
seteffectwithchance
|
||||
setadditionaleffects
|
||||
tryfaintmon BS_TARGET
|
||||
moveendfrom MOVEEND_UPDATE_LAST_MOVES
|
||||
end
|
||||
|
|
@ -2412,7 +2413,7 @@ BattleScript_EffectRecycle::
|
|||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_EffectRevenge::
|
||||
doubledamagedealtifdamaged
|
||||
setgastroacid BattleScript_CoreEnforcerRet
|
||||
goto BattleScript_EffectHit
|
||||
|
||||
BattleScript_EffectBrickBreak::
|
||||
|
|
@ -2444,7 +2445,7 @@ BattleScript_BrickBreakDoHit::
|
|||
waitmessage B_WAIT_TIME_LONG
|
||||
resultmessage
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
seteffectwithchance
|
||||
setadditionaleffects
|
||||
tryfaintmon BS_TARGET
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
|
|
@ -2533,7 +2534,7 @@ BattleScript_EffectGrudge::
|
|||
attackcanceler
|
||||
attackstring
|
||||
ppreduce
|
||||
trysetgrudge BattleScript_ButItFailed
|
||||
setstealthrock BattleScript_ButItFailed
|
||||
attackanimation
|
||||
waitanimation
|
||||
printstring STRINGID_PKMNWANTSGRUDGE
|
||||
|
|
@ -3591,6 +3592,25 @@ BattleScript_AtkDefDownAtkFail::
|
|||
BattleScript_AtkDefDownDefFail::
|
||||
return
|
||||
|
||||
BattleScript_DefSpDefDown::
|
||||
setbyte sSTAT_ANIM_PLAYED, FALSE
|
||||
playstatchangeanimation BS_ATTACKER, BIT_DEF | BIT_SPDEF, STAT_CHANGE_CANT_PREVENT | STAT_CHANGE_NEGATIVE | STAT_CHANGE_MULTIPLE_STATS
|
||||
playstatchangeanimation BS_ATTACKER, BIT_DEF, STAT_CHANGE_CANT_PREVENT | STAT_CHANGE_NEGATIVE
|
||||
setstatchanger STAT_DEF, 1, TRUE
|
||||
statbuffchange MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN | STAT_CHANGE_ALLOW_PTR, BattleScript_DefSpDefDownTrySpDef
|
||||
jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_DECREASE, BattleScript_DefSpDefDownTrySpDef
|
||||
printfromtable gStatDownStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
BattleScript_DefSpDefDownTrySpDef::
|
||||
playstatchangeanimation BS_ATTACKER, BIT_SPDEF, STAT_CHANGE_CANT_PREVENT | STAT_CHANGE_NEGATIVE
|
||||
setstatchanger STAT_SPDEF, 1, TRUE
|
||||
statbuffchange MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN | STAT_CHANGE_ALLOW_PTR, BattleScript_DefSpDefDownRet
|
||||
jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_DECREASE, BattleScript_DefSpDefDownRet
|
||||
printfromtable gStatDownStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
BattleScript_DefSpDefDownRet::
|
||||
return
|
||||
|
||||
BattleScript_KnockedOff::
|
||||
playanimation BS_TARGET, B_ANIM_ITEM_KNOCKOFF
|
||||
printstring STRINGID_PKMNKNOCKEDOFF
|
||||
|
|
@ -4580,3 +4600,165 @@ BattleScript_TargetFormChangeWithStringNoPopup::
|
|||
printstring STRINGID_PKMNTRANSFORMED
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
||||
BattleScript_IceFaceNullsDamage::
|
||||
call BattleScript_TargetFormChangeWithString
|
||||
return
|
||||
|
||||
BattleScript_AffectionBasedEndurance::
|
||||
@ playanimation BS_TARGET, B_ANIM_AFFECTION_HANGED_ON @ TODO: Animation
|
||||
printstring STRINGID_TARGETTOUGHEDITOUT
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
||||
BattleScript_MoveEffectClearSmog::
|
||||
printstring STRINGID_RESETSTARGETSSTATLEVELS
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
||||
BattleScript_MoveEffectFlameBurst::
|
||||
tryfaintmon BS_TARGET
|
||||
copybyte sBATTLER, sSAVED_BATTLER
|
||||
printstring STRINGID_BURSTINGFLAMESHIT
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
savetarget
|
||||
copybyte gBattlerTarget, sSAVED_BATTLER
|
||||
healthbarupdate BS_TARGET
|
||||
datahpupdate BS_TARGET
|
||||
tryfaintmon BS_TARGET
|
||||
restoretarget
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_HyperspaceFuryRemoveProtect::
|
||||
printstring STRINGID_BROKETHROUGHPROTECTION
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
||||
BattleScript_MoveEffectFeint::
|
||||
printstring STRINGID_FELLFORFEINT
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
||||
BattleScript_SpectralThiefSteal::
|
||||
printstring STRINGID_SPECTRALTHIEFSTEAL
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
setbyte sB_ANIM_ARG2, 0
|
||||
playanimation BS_ATTACKER, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1
|
||||
spectralthiefprintstats
|
||||
return
|
||||
|
||||
BattleScript_VCreateStatLoss::
|
||||
jumpifstat BS_ATTACKER, CMP_GREATER_THAN, STAT_DEF, MIN_STAT_STAGE, BattleScript_VCreateStatAnim
|
||||
jumpifstat BS_ATTACKER, CMP_GREATER_THAN, STAT_SPDEF, MIN_STAT_STAGE, BattleScript_VCreateStatAnim
|
||||
jumpifstat BS_ATTACKER, CMP_EQUAL, STAT_SPEED, MIN_STAT_STAGE, BattleScript_VCreateStatLossRet
|
||||
BattleScript_VCreateStatAnim:
|
||||
setbyte sSTAT_ANIM_PLAYED, FALSE
|
||||
playstatchangeanimation BS_ATTACKER, BIT_DEF | BIT_SPDEF | BIT_SPEED, STAT_CHANGE_NEGATIVE | STAT_CHANGE_CANT_PREVENT
|
||||
setstatchanger STAT_DEF, 1, TRUE
|
||||
statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_CHANGE_NOT_PROTECT_AFFECTED | MOVE_EFFECT_CERTAIN, BattleScript_VCreateTrySpDef
|
||||
jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_DECREASE, BattleScript_VCreateTrySpDef
|
||||
printfromtable gStatDownStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
BattleScript_VCreateTrySpDef:
|
||||
setstatchanger STAT_SPDEF, 1, TRUE
|
||||
statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_CHANGE_NOT_PROTECT_AFFECTED | MOVE_EFFECT_CERTAIN, BattleScript_VCreateTrySpeed
|
||||
jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_DECREASE, BattleScript_VCreateTrySpeed
|
||||
printfromtable gStatDownStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
BattleScript_VCreateTrySpeed:
|
||||
setstatchanger STAT_SPEED, 1, TRUE
|
||||
statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_CHANGE_NOT_PROTECT_AFFECTED | MOVE_EFFECT_CERTAIN, BattleScript_VCreateStatLossRet
|
||||
jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_DECREASE, BattleScript_VCreateStatLossRet
|
||||
printfromtable gStatDownStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
BattleScript_VCreateStatLossRet:
|
||||
return
|
||||
|
||||
BattleScript_MoveEffectCoreEnforcer::
|
||||
setgastroacid BattleScript_CoreEnforcerRet
|
||||
printstring STRINGID_PKMNSABILITYSUPPRESSED
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
trytoclearprimalweather
|
||||
tryrevertweatherform
|
||||
flushtextbox
|
||||
BattleScript_CoreEnforcerRet:
|
||||
return
|
||||
|
||||
BattleScript_MoveEffectIncinerate::
|
||||
printstring STRINGID_INCINERATEBURN
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
||||
BattleScript_MoveEffectBugBite::
|
||||
printstring STRINGID_BUGBITE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
orword gHitMarker, HITMARKER_DISABLE_ANIMATION
|
||||
setbyte sBERRY_OVERRIDE, 1 @ override the requirements for eating berries
|
||||
savetarget
|
||||
consumeberry BS_ATTACKER, FALSE
|
||||
bicword gHitMarker, HITMARKER_DISABLE_ANIMATION
|
||||
setbyte sBERRY_OVERRIDE, 0
|
||||
trysymbiosis
|
||||
restoretarget
|
||||
return
|
||||
|
||||
BattleScript_BothCanNoLongerEscape::
|
||||
printstring STRINGID_BOTHCANNOLONGERESCAPE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
||||
BattleScript_RemoveFireType::
|
||||
printstring STRINGID_ATTACKERLOSTFIRETYPE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
||||
BattleScript_RemoveElectricType::
|
||||
printstring STRINGID_ATTACKERLOSTELECTRICTYPE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
||||
BattleScript_RemoveGenericType::
|
||||
printstring STRINGID_ATTACKERLOSTITSTYPE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
||||
BattleScript_StealthRockActivates::
|
||||
setstealthrock BattleScript_MoveEnd
|
||||
printfromtable gDmgHazardsStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
||||
BattleScript_SpikesActivates::
|
||||
trysetspikes BattleScript_MoveEnd
|
||||
printfromtable gDmgHazardsStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
||||
BattleScript_SyrupBombActivates::
|
||||
printstring STRINGID_TARGETCOVEREDINSTICKYCANDYSYRUP
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
||||
BattleScript_AromaVeilProtectsRet::
|
||||
pause B_WAIT_TIME_SHORT
|
||||
call BattleScript_AbilityPopUp
|
||||
printstring STRINGID_AROMAVEILPROTECTED
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
||||
BattleScript_EffectPsychicNoise::
|
||||
printstring STRINGID_PKMNPREVENTEDFROMHEALING
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
||||
BattleScript_SymbiosisActivates::
|
||||
call BattleScript_AbilityPopUp
|
||||
printstring STRINGID_SYMBIOSISITEMPASS
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
||||
BattleScript_NoItemSteal::
|
||||
pause B_WAIT_TIME_SHORT
|
||||
printstring STRINGID_PKMNSXMADEYINEFFECTIVE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include <limits.h>
|
||||
#include "global.h"
|
||||
#include "constants/battle.h"
|
||||
#include "constants/form_change_types.h"
|
||||
#include "constants/battle_script_commands.h"
|
||||
#include "battle_util.h"
|
||||
#include "battle_script_commands.h"
|
||||
|
|
@ -352,6 +353,7 @@ struct SideTimer
|
|||
/*0x0B*/ u8 fieldB;
|
||||
// pokeemerald
|
||||
u8 retaliateTimer;
|
||||
u8 stealthRockAmount;
|
||||
};
|
||||
|
||||
extern struct SideTimer gSideTimers[];
|
||||
|
|
@ -485,6 +487,12 @@ struct Illusion
|
|||
struct Pokemon *mon;
|
||||
};
|
||||
|
||||
struct LostItem
|
||||
{
|
||||
u16 originalItem:15;
|
||||
u16 stolen:1;
|
||||
};
|
||||
|
||||
struct BattleStruct
|
||||
{
|
||||
u8 turnEffectsTracker;
|
||||
|
|
@ -593,6 +601,17 @@ struct BattleStruct
|
|||
u8 bonusCritStages[MAX_BATTLERS_COUNT]; // G-Max Chi Strike boosts crit stages of allies.
|
||||
u8 enduredDamage;
|
||||
u16 changedSpecies[NUM_BATTLE_SIDES][PARTY_SIZE]; // For forms when multiple mons can change into the same pokemon.
|
||||
u8 trainerSlideFirstCriticalHitMsgState:2;
|
||||
u8 trainerSlideFirstSuperEffectiveHitMsgState:2;
|
||||
u8 additionalEffectsCounter:4; // A counter for the additionalEffects applied by the current move in Cmd_setadditionaleffects
|
||||
u8 targetsDone[MAX_BATTLERS_COUNT]; // Each battler as a bit.
|
||||
u16 moveEffect2; // For Knock Off
|
||||
u8 stolenStats[NUM_BATTLE_STATS]; // hp byte is used for which stats to raise, other inform about by how many stages
|
||||
u8 stickySyrupdBy[MAX_BATTLERS_COUNT];
|
||||
u8 moneyMultiplierMove:1;
|
||||
struct LostItem itemLost[PARTY_SIZE]; // Player's team that had items consumed or stolen (two bytes per party member)
|
||||
u8 savedBattlerTarget;
|
||||
u8 ateBerry[2]; // array id determined by side, each party pokemon as bit
|
||||
}; // size == 0x200 bytes
|
||||
|
||||
extern struct BattleStruct *gBattleStruct;
|
||||
|
|
@ -621,15 +640,29 @@ extern struct BattleStruct *gBattleStruct;
|
|||
#define BATTLER_MAX_HP(battlerId)(gBattleMons[battlerId].hp == gBattleMons[battlerId].maxHP)
|
||||
#define TARGET_TURN_DAMAGED ((gSpecialStatuses[gBattlerTarget].physicalDmg != 0 || gSpecialStatuses[gBattlerTarget].specialDmg != 0))
|
||||
|
||||
#define IS_BATTLER_OF_TYPE(battlerId, type)((gBattleMons[battlerId].type1 == type || gBattleMons[battlerId].type2 == type))
|
||||
#define SET_BATTLER_TYPE(battlerId, type) \
|
||||
{ \
|
||||
gBattleMons[battlerId].type1 = type; \
|
||||
gBattleMons[battlerId].type2 = type; \
|
||||
#define IS_BATTLER_OF_TYPE(battlerId, type)((GetBattlerType(battlerId, 0) == type || GetBattlerType(battlerId, 1) == type || (GetBattlerType(battlerId, 2) != TYPE_MYSTERY && GetBattlerType(battlerId, 2) == type)))
|
||||
#define SET_BATTLER_TYPE(battlerId, type) \
|
||||
{ \
|
||||
gBattleMons[battlerId].type1 = type; \
|
||||
gBattleMons[battlerId].type2 = type; \
|
||||
gBattleMons[battlerId].type3 = TYPE_MYSTERY; \
|
||||
}
|
||||
|
||||
#define IS_BATTLER_PROTECTED(battlerId)(gProtectStructs[battlerId].protected \
|
||||
|| gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_WIDE_GUARD \
|
||||
|| gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_QUICK_GUARD \
|
||||
|| gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_CRAFTY_SHIELD \
|
||||
|| gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_MAT_BLOCK \
|
||||
|| gProtectStructs[battlerId].spikyShielded \
|
||||
|| gProtectStructs[battlerId].kingsShielded \
|
||||
|| gProtectStructs[battlerId].banefulBunkered \
|
||||
|| gProtectStructs[battlerId].burningBulwarked \
|
||||
|| gProtectStructs[battlerId].obstructed \
|
||||
|| gProtectStructs[battlerId].silkTrapped)
|
||||
|
||||
#define GET_STAT_BUFF_ID(n)((n & 0xF)) // first four bits 0x1, 0x2, 0x4, 0x8
|
||||
#define GET_STAT_BUFF_VALUE2(n)((n & 0xF0))
|
||||
#define GET_STAT_BUFF_VALUE_WITH_SIGN(n)((n & 0xF8))
|
||||
#define GET_STAT_BUFF_VALUE(n)(((n >> 4) & 7)) // 0x10, 0x20, 0x40
|
||||
#define STAT_BUFF_NEGATIVE 0x80 // 0x80, the sign bit
|
||||
|
||||
|
|
|
|||
|
|
@ -233,7 +233,6 @@ extern const u8 *const gRefereeStringsTable[];
|
|||
extern const u8 *const gStatNamesTable2[];
|
||||
|
||||
extern const u16 gMissStringIds[];
|
||||
extern const u16 gTrappingMoves[];
|
||||
|
||||
extern const u8 gText_Sleep[];
|
||||
extern const u8 gText_Poison[];
|
||||
|
|
|
|||
|
|
@ -30,6 +30,15 @@ u32 GetHighestStatId(u32 battlerId);
|
|||
u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move, u32 atkAbility, u32 defAbility, u32 atkHoldEffect, u32 defHoldEffect);
|
||||
bool32 DoesSubstituteBlockMove(u32 battlerAtk, u32 battlerDef, u32 move);
|
||||
bool32 DoesDisguiseBlockMove(u32 battler, u32 move);
|
||||
bool32 CanPoisonType(u8 battlerAttacker, u8 battlerTarget);
|
||||
bool32 CanParalyzeType(u8 battlerAttacker, u8 battlerTarget);
|
||||
bool32 NoAliveMonsForPlayer(void);
|
||||
bool32 NoAliveMonsForEitherParty(void);
|
||||
void StealTargetItem(u8 battlerStealer, u8 battlerItem);
|
||||
u32 IsFlowerVeilProtected(u32 battler);
|
||||
u32 IsLeafGuardProtected(u32 battler);
|
||||
bool32 IsShieldsDownProtected(u32 battler);
|
||||
u32 IsAbilityStatusProtected(u32 battler);
|
||||
|
||||
extern void (* const gBattleScriptingCommandsTable[])(void);
|
||||
extern const struct StatFractions gAccuracyStageRatios[];
|
||||
|
|
|
|||
|
|
@ -476,5 +476,28 @@ extern const u8 BattleScript_HangedOnMsg[];
|
|||
extern const u8 BattleScript_PrintBerryReduceString[];
|
||||
extern const u8 BattleScript_TargetFormChange[];
|
||||
extern const u8 BattleScript_TargetFormChangeWithStringNoPopup[];
|
||||
extern const u8 BattleScript_IceFaceNullsDamage[];
|
||||
extern const u8 BattleScript_AffectionBasedEndurance[];
|
||||
extern const u8 BattleScript_DefSpDefDown[];
|
||||
extern const u8 BattleScript_MoveEffectClearSmog[];
|
||||
extern const u8 BattleScript_MoveEffectFlameBurst[];
|
||||
extern const u8 BattleScript_HyperspaceFuryRemoveProtect[];
|
||||
extern const u8 BattleScript_MoveEffectFeint[];
|
||||
extern const u8 BattleScript_SpectralThiefSteal[];
|
||||
extern const u8 BattleScript_VCreateStatLoss[];
|
||||
extern const u8 BattleScript_MoveEffectCoreEnforcer[];
|
||||
extern const u8 BattleScript_MoveEffectIncinerate[];
|
||||
extern const u8 BattleScript_MoveEffectBugBite[];
|
||||
extern const u8 BattleScript_BothCanNoLongerEscape[];
|
||||
extern const u8 BattleScript_RemoveFireType[];
|
||||
extern const u8 BattleScript_RemoveElectricType[];
|
||||
extern const u8 BattleScript_RemoveGenericType[];
|
||||
extern const u8 BattleScript_StealthRockActivates[];
|
||||
extern const u8 BattleScript_SpikesActivates[];
|
||||
extern const u8 BattleScript_SyrupBombActivates[];
|
||||
extern const u8 BattleScript_AromaVeilProtectsRet[];
|
||||
extern const u8 BattleScript_EffectPsychicNoise[];
|
||||
extern const u8 BattleScript_StatUpMsg[];
|
||||
extern const u8 BattleScript_SymbiosisActivates[];
|
||||
|
||||
#endif // GUARD_BATTLE_SCRIPTS_H
|
||||
|
|
|
|||
|
|
@ -39,12 +39,17 @@
|
|||
#define ABILITY_ON_FIELD(abilityId)(AbilityBattleEffects(ABILITYEFFECT_CHECK_ON_FIELD, 0, abilityId, 0, 0))
|
||||
#define ABILITY_ON_FIELD2(abilityId)(AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, abilityId, 0, 0))
|
||||
|
||||
// For the first argument of ItemBattleEffects, to deteremine which block of item effects to try
|
||||
/// For the first argument of ItemBattleEffects, to deteremine which block of item effects to try
|
||||
#define ITEMEFFECT_ON_SWITCH_IN 0
|
||||
#define ITEMEFFECT_NORMAL 1
|
||||
#define ITEMEFFECT_DUMMY 2 // Unused, empty
|
||||
#define ITEMEFFECT_MOVE_END 3
|
||||
#define ITEMEFFECT_KINGSROCK_SHELLBELL 4
|
||||
#define ITEMEFFECT_KINGSROCK 4
|
||||
#define ITEMEFFECT_TARGET 5
|
||||
#define ITEMEFFECT_ORBS 6
|
||||
#define ITEMEFFECT_LIFEORB_SHELLBELL 7
|
||||
#define ITEMEFFECT_USE_LAST_ITEM 8 // move end effects for just the battler, not whole field
|
||||
#define ITEMEFFECT_STATS_CHANGED 9 // For White Herb and Eject Pack
|
||||
|
||||
#define WEATHER_HAS_EFFECT ((!AbilityBattleEffects(ABILITYEFFECT_CHECK_ON_FIELD, 0, ABILITY_CLOUD_NINE, 0, 0) && !AbilityBattleEffects(ABILITYEFFECT_CHECK_ON_FIELD, 0, ABILITY_AIR_LOCK, 0, 0)))
|
||||
#define WEATHER_HAS_EFFECT2 ((!AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_CLOUD_NINE, 0, 0) && !AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_AIR_LOCK, 0, 0)))
|
||||
|
|
@ -103,7 +108,7 @@ void PressurePPLoseOnUsingImprison(u8 attacker);
|
|||
void PressurePPLoseOnUsingPerishSong(u8 attacker);
|
||||
void MarkBattlerForControllerExec(u8 battlerId);
|
||||
void MarkBattlerReceivedLinkData(u8 battlerId);
|
||||
void CancelMultiTurnMoves(u8 battler);
|
||||
const u8* CancelMultiTurnMoves(u32 battler);
|
||||
bool32 WasUnableToUseMove(u32 battler);
|
||||
void PrepareStringBattle(u16 stringId, u8 battler);
|
||||
void ResetSentPokesToOpponentValue(void);
|
||||
|
|
@ -182,6 +187,22 @@ u32 GetBattlerHoldEffect(u32 battler, bool32 checkNegating);
|
|||
u32 GetBattlerHoldEffectIgnoreAbility(u32 battler, bool32 checkNegating);
|
||||
u32 GetBattlerHoldEffectInternal(u32 battler, bool32 checkNegating, bool32 checkAbility);
|
||||
void RecalcBattlerStats(u32 battler, struct Pokemon *mon);
|
||||
bool32 TestIfSheerForceAffected(u32 battler, u16 move);
|
||||
bool32 CanSleep(u32 battler);
|
||||
bool32 CanBePoisoned(u32 battlerAttacker, u32 battlerTarget);
|
||||
bool32 CanBeBurned(u32 battler);
|
||||
bool32 CanBeParalyzed(u32 battler);
|
||||
bool32 CanBeFrozen(u32 battler);
|
||||
bool32 CanGetFrostbite(u32 battler);
|
||||
bool32 CanBeConfused(u32 battler);
|
||||
bool32 CanStealItem(u32 battlerStealing, u32 battlerItem, u16 item);
|
||||
void TrySaveExchangedItem(u32 battler, u16 stolenItem);
|
||||
void RemoveBattlerType(u32 battler, u8 type);
|
||||
bool32 IsBattlerMegaEvolved(u32 battler);
|
||||
bool32 IsBattlerPrimalReverted(u32 battler);
|
||||
bool32 IsBattlerUltraBursted(u32 battler);
|
||||
u16 GetBattleFormChangeTargetSpecies(u32 battler, u16 method);
|
||||
bool32 TryBattleFormChange(u32 battler, u16 method);
|
||||
|
||||
// battle_ai_util.h
|
||||
bool32 IsHealingMove(u32 move);
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@
|
|||
#define BATTLE_TYPE_WILD_SCRIPTED (1 << 17) // Used in pokeemerald as BATTLE_TYPE_PALACE.
|
||||
#define BATTLE_TYPE_LEGENDARY_FRLG (1 << 18) // Used in pokeemerald as BATTLE_TYPE_ARENA.
|
||||
#define BATTLE_TYPE_TRAINER_TOWER (1 << 19) // Used in pokeemerald as BATTLE_TYPE_FACTORY.
|
||||
#define BATTLE_TYPE_INGAME_PARTNER (1 << 20)
|
||||
|
||||
#define IS_BATTLE_TYPE_GHOST_WITHOUT_SCOPE(flags) ((flags) & BATTLE_TYPE_GHOST && !((flags) & BATTLE_TYPE_GHOST_UNVEILED))
|
||||
#define IS_BATTLE_TYPE_GHOST_WITH_SCOPE(flags) ((flags) & BATTLE_TYPE_GHOST && (flags) & BATTLE_TYPE_GHOST_UNVEILED)
|
||||
|
|
|
|||
|
|
@ -263,7 +263,9 @@
|
|||
|
||||
// Cmd_statbuffchange
|
||||
#define STAT_CHANGE_ALLOW_PTR (1 << 0) // If set, allow use of jumpptr. Set in every use of statbuffchange
|
||||
#define STAT_CHANGE_MIRROR_ARMOR (1 << 1) // Stat change redirection caused by Mirror Armor ability.
|
||||
#define STAT_CHANGE_NOT_PROTECT_AFFECTED (1 << 5)
|
||||
#define STAT_CHANGE_UPDATE_MOVE_EFFECT (1 << 6)
|
||||
|
||||
// stat change flags for Cmd_playstatchangeanimation
|
||||
#define STAT_CHANGE_NEGATIVE (1 << 0)
|
||||
|
|
|
|||
|
|
@ -411,8 +411,36 @@
|
|||
#define STRINGID_ATTACKWEAKENEDBSTRONGWINDS 409
|
||||
#define STRINGID_ENDUREDSTURDY 410
|
||||
#define STRINGID_BERRYDMGREDUCES 411
|
||||
#define STRINGID_TARGETTOUGHEDITOUT 412
|
||||
#define STRINGID_TRAPPEDBYSWIRLINGMAGMA 413
|
||||
#define STRINGID_INFESTATION 414
|
||||
#define STRINGID_PKMNINSNAPTRAP 415
|
||||
#define STRINGID_THUNDERCAGETRAPPED 416
|
||||
#define STRINGID_RESETSTARGETSSTATLEVELS 417
|
||||
#define STRINGID_EXTREMESUNLIGHTFADED 418
|
||||
#define STRINGID_HEAVYRAINLIFTED 419
|
||||
#define STRINGID_STRONGWINDSDISSIPATED 420
|
||||
#define STRINGID_SYMBIOSISITEMPASS 421
|
||||
#define STRINGID_BURSTINGFLAMESHIT 422
|
||||
#define STRINGID_BROKETHROUGHPROTECTION 423
|
||||
#define STRINGID_FELLFORFEINT 424
|
||||
#define STRINGID_SPECTRALTHIEFSTEAL 425
|
||||
#define STRINGID_PKMNSABILITYSUPPRESSED 426
|
||||
#define STRINGID_INCINERATEBURN 427
|
||||
#define STRINGID_BUGBITE 428
|
||||
#define STRINGID_BOTHCANNOLONGERESCAPE 429
|
||||
#define STRINGID_ATTACKERLOSTFIRETYPE 430
|
||||
#define STRINGID_ATTACKERLOSTELECTRICTYPE 431
|
||||
#define STRINGID_ATTACKERLOSTITSTYPE 432
|
||||
#define STRINGID_STEALTHROCKDMG 433
|
||||
#define STRINGID_SHARPSTEELDMG 434
|
||||
#define STRINGID_POINTEDSTONESFLOAT 435
|
||||
#define STRINGID_SHARPSTEELFLOATS 436
|
||||
#define STRINGID_TARGETCOVEREDINSTICKYCANDYSYRUP 437
|
||||
#define STRINGID_AROMAVEILPROTECTED 438
|
||||
#define STRINGID_PKMNPREVENTEDFROMHEALING 439
|
||||
|
||||
#define BATTLESTRINGS_COUNT 412
|
||||
#define BATTLESTRINGS_COUNT 440
|
||||
|
||||
// This is the string id that gBattleStringsTable starts with.
|
||||
// String ids before this (e.g. STRINGID_INTROMSG) are not in the table,
|
||||
|
|
@ -621,6 +649,25 @@
|
|||
#define B_MSG_FROSTBITE_HEALED 0
|
||||
#define B_MSG_FROSTBITE_HEALED_BY_MOVE 1
|
||||
|
||||
#define NUM_TRAPPING_MOVES 6
|
||||
// gWrappedStringIds
|
||||
#define B_MSG_WRAPPED_BIND 0
|
||||
#define B_MSG_WRAPPED_WRAP 1
|
||||
#define B_MSG_WRAPPED_FIRE_SPIN 2
|
||||
#define B_MSG_WRAPPED_CLAMP 3
|
||||
#define B_MSG_WRAPPED_WHIRLPOOL 4
|
||||
#define B_MSG_WRAPPED_SAND_TOMB 5
|
||||
#define B_MSG_WRAPPED_MAGMA_STORM 6
|
||||
#define B_MSG_WRAPPED_INFESTATION 7
|
||||
#define B_MSG_WRAPPED_SNAP_TRAP 8
|
||||
#define B_MSG_WRAPPED_THUNDER_CAGE 9
|
||||
#define NUM_TRAPPING_MOVES 10
|
||||
|
||||
// gDmgHazardsStringIds
|
||||
#define B_MSG_PKMNHURTBYSPIKES 0
|
||||
#define B_MSG_STEALTHROCKDMG 1
|
||||
#define B_MSG_SHARPSTEELDMG 2
|
||||
#define B_MSG_POINTEDSTONESFLOAT 3
|
||||
#define B_MSG_SPIKESSCATTERED 4
|
||||
#define B_MSG_SHARPSTEELFLOATS 5
|
||||
|
||||
#endif // GUARD_BATTLE_STRING_IDS_H
|
||||
|
|
|
|||
123
include/constants/form_change_types.h
Normal file
123
include/constants/form_change_types.h
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
#ifndef GUARD_CONSTANTS_FORM_CHANGE_TYPES_H
|
||||
#define GUARD_CONSTANTS_FORM_CHANGE_TYPES_H
|
||||
|
||||
// FORM_CHANGE_BATTLE_HP_PERCENT param2 arguments
|
||||
#define HP_HIGHER_THAN 1
|
||||
#define HP_LOWER_EQ_THAN 2
|
||||
// FORM_CHANGE_MOVE param2 Arguments
|
||||
#define WHEN_LEARNED 0
|
||||
#define WHEN_FORGOTTEN 1
|
||||
// FORM_CHANGE_ITEM_USE param2 Arguments
|
||||
#define DAY 1
|
||||
#define NIGHT 2
|
||||
|
||||
#define FUSION_TERMINATOR 0xFF
|
||||
#define FORM_CHANGE_TERMINATOR 0
|
||||
|
||||
// Form change that activates when the specified item is given to or taken from the selected Pokémon.
|
||||
// param1: item to hold.
|
||||
// param2: ability to check for, optional.
|
||||
#define FORM_CHANGE_ITEM_HOLD 1
|
||||
|
||||
// Form change that activates when the item is used on the selected Pokémon.
|
||||
// param1: item to use
|
||||
// param2: time of day to check, optional.
|
||||
// - DAY if Form change that activates in the daytime.
|
||||
// - NIGHT if Form change that activates at nighttime.
|
||||
#define FORM_CHANGE_ITEM_USE 2
|
||||
|
||||
// TODO: Form change that activates when the Pokémon learns or forgets the move.
|
||||
// param1: move to check for
|
||||
// param2:
|
||||
// - WHEN_LEARNED if Form change that activates when move is forgotten
|
||||
// - WHEN_FORGOTTEN if Form change that activates when move is learned
|
||||
#define FORM_CHANGE_MOVE 3
|
||||
|
||||
// Form change that activates when the Pokémon is withdrawn from the PC or Daycare.
|
||||
// Daycare withdraw done, PC withdraw TODO.
|
||||
// - No parameters.
|
||||
#define FORM_CHANGE_WITHDRAW 4
|
||||
|
||||
// Form change that activates when the Pokémon faints, either in battle or in the overworld by poison.
|
||||
// If species is not specified and it's on the player's side, it will try to use the value
|
||||
// saved in gBattleStruct->changedSpecies from a previous form change.
|
||||
// - No parameters.
|
||||
#define FORM_CHANGE_FAINT 5
|
||||
|
||||
// Form change that activates when the Pokémon is sent out at the beginning of a battle
|
||||
// param1: item to hold, optional
|
||||
// param2: a move that will be replaced, optional
|
||||
// param3: a new move to replace it with, optional
|
||||
#define FORM_CHANGE_BEGIN_BATTLE 6
|
||||
|
||||
// Form change that activates at the end of a battle. If species is not specified and it's on the player's side, it will try to use the value saved in gBattleStruct->changedSpecies from a previous form change.
|
||||
// param1: item to hold, optional
|
||||
// param2: a move that will be replaced, optional
|
||||
// param3: a new move to replace it with, optional
|
||||
#define FORM_CHANGE_END_BATTLE 7
|
||||
|
||||
// Form change that activates at the end of a battle based on the terrain if it participated in the battle and hasn't fainted. Takes priority over FORM_CHANGE_END_BATTLE.
|
||||
// param1: battle terrain to check.
|
||||
#define FORM_CHANGE_END_BATTLE_TERRAIN 8
|
||||
|
||||
// Form change that activates when the Pokémon is switched out in battle.
|
||||
// - No parameters.
|
||||
#define FORM_CHANGE_BATTLE_SWITCH 9
|
||||
|
||||
// Form change that activates when the Pokémon's HP % passes a certain threshold.
|
||||
// param1: Ability to check.
|
||||
// param2: HP comparer
|
||||
// - HP_HIGHER_THAN if the form triggers when the current HP is higher than the specified threshold.
|
||||
// - HP_LOWER_EQ_THAN if the form triggers when the current HP is lower or equal than the specified threshold.
|
||||
// param3: HP percentage threshold.
|
||||
#define FORM_CHANGE_BATTLE_HP_PERCENT 10
|
||||
|
||||
// Form change that activates when the mon has the defined item.
|
||||
// If it's on the player's side, it also requires ITEM_MEGA_RING in the user's bag and for the player to trigger it by pressing START before selecting a move.
|
||||
// param1: item to hold.
|
||||
#define FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM 11
|
||||
|
||||
// Form change that activates when the mon has the defined move.
|
||||
// If it's on the player's side, it also requires ITEM_MEGA_RING in the user's bag and for the player to trigger it by pressing START before selecting a move.
|
||||
// param1: move to have.
|
||||
#define FORM_CHANGE_BATTLE_MEGA_EVOLUTION_MOVE 12
|
||||
|
||||
// Form change that activates automatically when entering battle with the specified item.
|
||||
// If the item is a Red Orb, it uses the Omega Symbol for the animation and icon. Otherwise, it defaults to the Alpha symbol.
|
||||
// The battle indicator icon is based on the species, with Primal Groudon's as Omega and otherwise being Alpha.
|
||||
// param1: item to hold.
|
||||
#define FORM_CHANGE_BATTLE_PRIMAL_REVERSION 13
|
||||
|
||||
// Form change that activates when a specific weather is set during battle.
|
||||
// param1: weather to check
|
||||
// param2: (optional) revert if specified ability is lost
|
||||
#define FORM_CHANGE_BATTLE_WEATHER 14
|
||||
|
||||
// Form change that activates automatically when the turn ends.
|
||||
// param1: ability to check.
|
||||
#define FORM_CHANGE_BATTLE_TURN_END 15
|
||||
|
||||
// Form change that activates when the mon has the defined item.
|
||||
// If it's on the player's side, it also requires for the player to trigger it by pressing START before selecting a move.
|
||||
// param1: item to hold.
|
||||
#define FORM_CHANGE_BATTLE_ULTRA_BURST 16
|
||||
|
||||
// Form change that activates when the mon Dynamaxes (TODO: with Gigantamax factor).
|
||||
// - No parameters
|
||||
#define FORM_CHANGE_BATTLE_GIGANTAMAX 17
|
||||
|
||||
// Form change that activates at a certain time of day in the overworld automatically.
|
||||
// param1: time of day to check.
|
||||
// - DAY if Form change that activates in the daytime.
|
||||
// - NIGHT if Form change that activates at nighttime.
|
||||
#define FORM_CHANGE_TIME_OF_DAY 18
|
||||
|
||||
// Form change that depends on a multichoice (e.g. Rotom Catalog).
|
||||
// param1: multichoice list (starting at 0).
|
||||
#define FORM_CHANGE_ITEM_USE_MULTICHOICE 19
|
||||
|
||||
// Form change that activates when inflicted with a specific status
|
||||
// param1: status
|
||||
#define FORM_CHANGE_STATUS 20
|
||||
|
||||
#endif // GUARD_CONSTANTS_FORM_CHANGE_TYPES_H
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -62,6 +62,7 @@ void ItemUseCB_PPUp(u8 taskId, TaskFunc func);
|
|||
u16 ItemIdToBattleMoveId(u16 item);
|
||||
bool8 IsMoveHm(u16 move);
|
||||
bool8 MonKnowsMove(struct Pokemon *mon, u16 move);
|
||||
bool8 BoxMonKnowsMove(struct BoxPokemon *boxMon, u16 move);
|
||||
void ItemUseCB_TMHM(u8 taskId, TaskFunc func);
|
||||
void ItemUseCB_RareCandy(u8 taskId, TaskFunc func);
|
||||
void ItemUseCB_SacredAsh(u8 taskId, TaskFunc func);
|
||||
|
|
|
|||
|
|
@ -791,6 +791,11 @@ struct MonSpritesGfxManager *CreateMonSpritesGfxManager(u8 battlePosition, u8 mo
|
|||
void DestroyMonSpritesGfxManager(void);
|
||||
u8 *MonSpritesGfxManager_GetSpritePtr(u8 bufferId);
|
||||
u16 GetFormSpeciesId(u16 speciesId, u8 formId);
|
||||
u8 GetFormIdFromFormSpeciesId(u16 formSpeciesId);
|
||||
u16 GetFormChangeTargetSpecies(struct Pokemon *mon, u16 method, u32 arg);
|
||||
u16 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *boxMon, u16 method, u32 arg);
|
||||
bool32 DoesSpeciesHaveFormChangeMethod(u16 species, u16 method);
|
||||
void TryToSetBattleFormChangeMoves(struct Pokemon *mon, u16 method);
|
||||
|
||||
|
||||
bool8 HealStatusConditions(struct Pokemon *mon, u32 healMask, u8 battleId);
|
||||
|
|
|
|||
|
|
@ -541,6 +541,34 @@ static const u8 sText_GemActivates[] = _("{B_LAST_ITEM} strengthened\n{B_ATK_NAM
|
|||
static const u8 sText_AttackWeakenedByStrongWinds[] = _("The mysterious strong winds\nweakened the attack!");
|
||||
static const u8 sText_EnduredViaSturdy[] = _("{B_DEF_NAME_WITH_PREFIX} endured\nthe hit using {B_DEF_ABILITY}!");
|
||||
static const u8 sText_BerryDmgReducing[] = _("{B_LAST_ITEM} weakened the damage\nto {B_DEF_NAME_WITH_PREFIX}!");
|
||||
static const u8 sText_TargetToughedItOut[] = _("{B_DEF_NAME_WITH_PREFIX} toughed it out\nto show you its best side!");
|
||||
static const u8 sText_TrappedBySwirlingMagma[] =_("{B_DEF_NAME_WITH_PREFIX} became\ntrapped by swirling magma!");
|
||||
static const u8 sText_Infestation[] = _("{B_DEF_NAME_WITH_PREFIX} has been afflicted\nwith an infestation by {B_ATK_NAME_WITH_PREFIX}!");
|
||||
static const u8 sText_PkmnInSnapTrap[] = _("{B_DEF_NAME_WITH_PREFIX} got trapped\nby a snap trap!");
|
||||
static const u8 sText_AtkTrappedDef[] = _("{B_ATK_NAME_WITH_PREFIX} trapped\nthe {B_DEF_NAME_WITH_PREFIX}!");
|
||||
static const u8 sText_ResetsTargetsStatLevels[] =_("{B_DEF_NAME_WITH_PREFIX}'s stat changes\nwere removed!");
|
||||
static const u8 sText_StrongWindsDissipated[] = _("The mysterious strong winds\nhave dissipated!{PAUSE 64}");
|
||||
static const u8 sText_ExtremeSunlightFaded[] = _("The extreme sunlight faded.{PAUSE 64}");
|
||||
static const u8 sText_HeavyRainLifted[] = _("The heavy rain has lifted!{PAUSE 64}");
|
||||
static const u8 sText_SymbiosisItemPass[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} passed its {B_LAST_ITEM}\nto {B_ATK_NAME_WITH_PREFIX} through {B_LAST_ABILITY}!");
|
||||
static const u8 sText_BurstingFlames[] = _("The bursting flames\nhit {B_SCR_ACTIVE_NAME_WITH_PREFIX}!");
|
||||
static const u8 sText_BrokeThroughProtection[] = _("It broke through\n{B_DEF_NAME_WITH_PREFIX}'s protection!");
|
||||
static const u8 sText_FellForFeint[] = _("{B_DEF_NAME_WITH_PREFIX} fell for\nthe feint!");
|
||||
static const u8 sText_SpectralThiefSteal[] = _("{B_ATK_NAME_WITH_PREFIX} stole the target's\nboosted stats!");
|
||||
static const u8 sText_PkmnsAbilitySuppressed[] = _("{B_DEF_NAME_WITH_PREFIX}'s ability\nwas suppressed!");
|
||||
static const u8 sText_IncinerateBurn[] = _("{B_EFF_NAME_WITH_PREFIX}'s {B_LAST_ITEM}\nwas burnt up!");
|
||||
static const u8 sText_BugBite[] = _("{B_ATK_NAME_WITH_PREFIX} stole and ate\n{B_EFF_NAME_WITH_PREFIX}'s {B_LAST_ITEM}!");
|
||||
static const u8 sText_BothCanNoLongerEscape[] = _("Neither Pokémon can run away!");
|
||||
static const u8 sText_AttackerLostFireType[] = _("{B_ATK_NAME_WITH_PREFIX} burned itself out!");
|
||||
static const u8 sText_AttackerLostElectricType[] = _("{B_ATK_NAME_WITH_PREFIX} used up all\nof its electricity!");
|
||||
static const u8 sText_AttackerLostItsType[] = _("{B_ATK_NAME_WITH_PREFIX} lost\nits {B_BUFF1} type!");
|
||||
static const u8 sText_StealthRockDmg[] = _("Pointed stones dug into\n{B_SCR_ACTIVE_NAME_WITH_PREFIX}!");
|
||||
static const u8 sText_SharpSteelDmg[] = _("Sharp steel bit into {B_DEF_NAME_WITH_PREFIX}!");
|
||||
static const u8 sText_PointedStonesFloat[] =_("Pointed stones float in the air\naround {B_DEF_TEAM2} team!");
|
||||
static const u8 sText_SharpSteelFloats[] = _("Sharp-pointed steel floats\naround {B_DEF_TEAM2} team!");
|
||||
static const u8 sText_TargetCoveredInStickyCandySyrup[] = _("{B_DEF_NAME_WITH_PREFIX} got covered\nin sticky syrup!");
|
||||
static const u8 sText_AromaVeilProtected[] = _("{B_DEF_NAME_WITH_PREFIX} is protected\nby an aromatic veil!");
|
||||
static const u8 sText_PkmnPreventedFromHealing[] = _("{B_DEF_NAME_WITH_PREFIX} was prevented\nfrom healing!");
|
||||
|
||||
|
||||
const u16 gTrainerUsedItemStringIds[] =
|
||||
|
|
@ -952,6 +980,34 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT - BATTLESTRINGS_TABLE_ST
|
|||
[STRINGID_ATTACKWEAKENEDBSTRONGWINDS - BATTLESTRINGS_TABLE_START] = sText_AttackWeakenedByStrongWinds,
|
||||
[STRINGID_ENDUREDSTURDY - BATTLESTRINGS_TABLE_START] = sText_EnduredViaSturdy,
|
||||
[STRINGID_BERRYDMGREDUCES - BATTLESTRINGS_TABLE_START] = sText_BerryDmgReducing,
|
||||
[STRINGID_TARGETTOUGHEDITOUT - BATTLESTRINGS_TABLE_START] = sText_TargetToughedItOut,
|
||||
[STRINGID_TRAPPEDBYSWIRLINGMAGMA - BATTLESTRINGS_TABLE_START] = sText_TrappedBySwirlingMagma,
|
||||
[STRINGID_INFESTATION - BATTLESTRINGS_TABLE_START] = sText_Infestation,
|
||||
[STRINGID_PKMNINSNAPTRAP - BATTLESTRINGS_TABLE_START] = sText_PkmnInSnapTrap,
|
||||
[STRINGID_THUNDERCAGETRAPPED - BATTLESTRINGS_TABLE_START] = sText_AtkTrappedDef,
|
||||
[STRINGID_RESETSTARGETSSTATLEVELS - BATTLESTRINGS_TABLE_START] = sText_ResetsTargetsStatLevels,
|
||||
[STRINGID_STRONGWINDSDISSIPATED - BATTLESTRINGS_TABLE_START] = sText_StrongWindsDissipated,
|
||||
[STRINGID_EXTREMESUNLIGHTFADED - BATTLESTRINGS_TABLE_START] = sText_ExtremeSunlightFaded,
|
||||
[STRINGID_HEAVYRAINLIFTED - BATTLESTRINGS_TABLE_START] = sText_HeavyRainLifted,
|
||||
[STRINGID_SYMBIOSISITEMPASS - BATTLESTRINGS_TABLE_START] = sText_SymbiosisItemPass,
|
||||
[STRINGID_BURSTINGFLAMESHIT - BATTLESTRINGS_TABLE_START] = sText_BurstingFlames,
|
||||
[STRINGID_BROKETHROUGHPROTECTION - BATTLESTRINGS_TABLE_START] = sText_BrokeThroughProtection,
|
||||
[STRINGID_FELLFORFEINT - BATTLESTRINGS_TABLE_START] = sText_FellForFeint,
|
||||
[STRINGID_SPECTRALTHIEFSTEAL - BATTLESTRINGS_TABLE_START] = sText_SpectralThiefSteal,
|
||||
[STRINGID_PKMNSABILITYSUPPRESSED - BATTLESTRINGS_TABLE_START] = sText_PkmnsAbilitySuppressed,
|
||||
[STRINGID_INCINERATEBURN - BATTLESTRINGS_TABLE_START] = sText_IncinerateBurn,
|
||||
[STRINGID_BUGBITE - BATTLESTRINGS_TABLE_START] = sText_BugBite,
|
||||
[STRINGID_BOTHCANNOLONGERESCAPE - BATTLESTRINGS_TABLE_START] = sText_BothCanNoLongerEscape,
|
||||
[STRINGID_ATTACKERLOSTFIRETYPE - BATTLESTRINGS_TABLE_START] = sText_AttackerLostFireType,
|
||||
[STRINGID_ATTACKERLOSTELECTRICTYPE - BATTLESTRINGS_TABLE_START] = sText_AttackerLostElectricType,
|
||||
[STRINGID_ATTACKERLOSTITSTYPE - BATTLESTRINGS_TABLE_START] = sText_AttackerLostItsType,
|
||||
[STRINGID_STEALTHROCKDMG - BATTLESTRINGS_TABLE_START] = sText_StealthRockDmg,
|
||||
[STRINGID_SHARPSTEELDMG - BATTLESTRINGS_TABLE_START] = sText_SharpSteelDmg,
|
||||
[STRINGID_POINTEDSTONESFLOAT - BATTLESTRINGS_TABLE_START] = sText_PointedStonesFloat,
|
||||
[STRINGID_SHARPSTEELFLOATS - BATTLESTRINGS_TABLE_START] = sText_SharpSteelFloats,
|
||||
[STRINGID_TARGETCOVEREDINSTICKYCANDYSYRUP - BATTLESTRINGS_TABLE_START] = sText_TargetCoveredInStickyCandySyrup,
|
||||
[STRINGID_AROMAVEILPROTECTED - BATTLESTRINGS_TABLE_START] = sText_AromaVeilProtected,
|
||||
[STRINGID_PKMNPREVENTEDFROMHEALING - BATTLESTRINGS_TABLE_START] = sText_PkmnPreventedFromHealing,
|
||||
};
|
||||
|
||||
const u16 gMagicCoatBounceStringIds[] =
|
||||
|
|
@ -959,6 +1015,16 @@ const u16 gMagicCoatBounceStringIds[] =
|
|||
STRINGID_PKMNMOVEBOUNCED, STRINGID_PKMNMOVEBOUNCEDABILITY
|
||||
};
|
||||
|
||||
const u16 gDmgHazardsStringIds[] =
|
||||
{
|
||||
[B_MSG_PKMNHURTBYSPIKES] = STRINGID_PKMNHURTBYSPIKES,
|
||||
[B_MSG_STEALTHROCKDMG] = STRINGID_STEALTHROCKDMG,
|
||||
[B_MSG_SHARPSTEELDMG] = STRINGID_SHARPSTEELDMG,
|
||||
[B_MSG_POINTEDSTONESFLOAT] = STRINGID_POINTEDSTONESFLOAT,
|
||||
[B_MSG_SPIKESSCATTERED] = STRINGID_SPIKESSCATTERED,
|
||||
[B_MSG_SHARPSTEELFLOATS] = STRINGID_SHARPSTEELFLOATS,
|
||||
};
|
||||
|
||||
const u16 gMissStringIds[] =
|
||||
{
|
||||
[B_MSG_MISSED] = STRINGID_ATTACKMISSED,
|
||||
|
|
@ -1106,15 +1172,19 @@ const u16 gFirstTurnOfTwoStringIds[] =
|
|||
[B_MSG_TURN1_BOUNCE] = STRINGID_PKMNSPRANGUP
|
||||
};
|
||||
|
||||
// Index copied from move's index in gTrappingMoves
|
||||
const u16 gWrappedStringIds[] =
|
||||
// Index copied from move's index in sTrappingMoves
|
||||
const u16 gWrappedStringIds[NUM_TRAPPING_MOVES] =
|
||||
{
|
||||
STRINGID_PKMNSQUEEZEDBYBIND, // MOVE_BIND
|
||||
STRINGID_PKMNWRAPPEDBY, // MOVE_WRAP
|
||||
STRINGID_PKMNTRAPPEDINVORTEX, // MOVE_FIRE_SPIN
|
||||
STRINGID_PKMNCLAMPED, // MOVE_CLAMP
|
||||
STRINGID_PKMNTRAPPEDINVORTEX, // MOVE_WHIRLPOOL
|
||||
STRINGID_PKMNTRAPPEDBYSANDTOMB // MOVE_SAND_TOMB
|
||||
[B_MSG_WRAPPED_BIND] = STRINGID_PKMNSQUEEZEDBYBIND, // MOVE_BIND
|
||||
[B_MSG_WRAPPED_WRAP] = STRINGID_PKMNWRAPPEDBY, // MOVE_WRAP
|
||||
[B_MSG_WRAPPED_FIRE_SPIN] = STRINGID_PKMNTRAPPEDINVORTEX, // MOVE_FIRE_SPIN
|
||||
[B_MSG_WRAPPED_CLAMP] = STRINGID_PKMNCLAMPED, // MOVE_CLAMP
|
||||
[B_MSG_WRAPPED_WHIRLPOOL] = STRINGID_PKMNTRAPPEDINVORTEX, // MOVE_WHIRLPOOL
|
||||
[B_MSG_WRAPPED_SAND_TOMB] = STRINGID_PKMNTRAPPEDBYSANDTOMB, // MOVE_SAND_TOMB
|
||||
[B_MSG_WRAPPED_MAGMA_STORM] = STRINGID_TRAPPEDBYSWIRLINGMAGMA, // MOVE_MAGMA_STORM
|
||||
[B_MSG_WRAPPED_INFESTATION] = STRINGID_INFESTATION, // MOVE_INFESTATION
|
||||
[B_MSG_WRAPPED_SNAP_TRAP] = STRINGID_PKMNINSNAPTRAP, // MOVE_SNAP_TRAP
|
||||
[B_MSG_WRAPPED_THUNDER_CAGE]= STRINGID_THUNDERCAGETRAPPED, // MOVE_THUNDER_CAGE
|
||||
};
|
||||
|
||||
const u16 gMistUsedStringIds[] =
|
||||
|
|
@ -1340,17 +1410,6 @@ const u16 gDoubleBattleRecallStrings[1 << (MAX_BATTLERS_COUNT / 2)] =
|
|||
STRINGID_TRAINER1MON1AND2COMEBACK
|
||||
};
|
||||
|
||||
const u16 gTrappingMoves[NUM_TRAPPING_MOVES + 1] =
|
||||
{
|
||||
MOVE_BIND,
|
||||
MOVE_WRAP,
|
||||
MOVE_FIRE_SPIN,
|
||||
MOVE_CLAMP,
|
||||
MOVE_WHIRLPOOL,
|
||||
MOVE_SAND_TOMB,
|
||||
0xFFFF // Never read
|
||||
};
|
||||
|
||||
const u8 gText_PkmnIsEvolving[] = _("What?\n{STR_VAR_1} is evolving!");
|
||||
const u8 gText_CongratsPkmnEvolved[] = _("Congratulations! Your {STR_VAR_1}\nevolved into {STR_VAR_2}!{WAIT_SE}\p");
|
||||
const u8 gText_PkmnStoppedEvolving[] = _("Huh? {STR_VAR_1}\nstopped evolving!\p");
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -227,17 +227,87 @@ void MarkBattlerReceivedLinkData(u8 battlerId)
|
|||
gBattleControllerExecFlags &= ~((1 << 28) << battlerId);
|
||||
}
|
||||
|
||||
void CancelMultiTurnMoves(u8 battler)
|
||||
const u8* CancelMultiTurnMoves(u32 battler)
|
||||
{
|
||||
gBattleMons[battler].status2 &= ~STATUS2_MULTIPLETURNS;
|
||||
gBattleMons[battler].status2 &= ~STATUS2_LOCK_CONFUSE;
|
||||
gBattleMons[battler].status2 &= ~STATUS2_UPROAR;
|
||||
gBattleMons[battler].status2 &= ~STATUS2_BIDE;
|
||||
const u8 *result = NULL;
|
||||
gBattleMons[battler].status2 &= ~(STATUS2_MULTIPLETURNS);
|
||||
gBattleMons[battler].status2 &= ~(STATUS2_LOCK_CONFUSE);
|
||||
gBattleMons[battler].status2 &= ~(STATUS2_UPROAR);
|
||||
gBattleMons[battler].status2 &= ~(STATUS2_BIDE);
|
||||
|
||||
gStatuses3[battler] &= ~STATUS3_SEMI_INVULNERABLE;
|
||||
// Clear battler's semi-invulnerable bits if they are not held by Sky Drop.
|
||||
if (!(gStatuses3[battler] & STATUS3_SKY_DROPPED))
|
||||
gStatuses3[battler] &= ~(STATUS3_SEMI_INVULNERABLE);
|
||||
|
||||
// Check to see if this Pokemon was in the middle of using Sky Drop. If so, release the target.
|
||||
if (gBattleStruct->skyDropTargets[battler] != 0xFF && !(gStatuses3[battler] & STATUS3_SKY_DROPPED))
|
||||
{
|
||||
// Get the target's battler id
|
||||
u8 otherSkyDropper = gBattleStruct->skyDropTargets[battler];
|
||||
|
||||
// Clears sky_dropped and on_air statuses
|
||||
gStatuses3[otherSkyDropper] &= ~(STATUS3_SKY_DROPPED | STATUS3_ON_AIR);
|
||||
|
||||
// Makes both attacker and target's sprites visible
|
||||
gSprites[gBattlerSpriteIds[battler]].invisible = FALSE;
|
||||
gSprites[gBattlerSpriteIds[otherSkyDropper]].invisible = FALSE;
|
||||
|
||||
// If target was sky dropped in the middle of Outrage/Thrash/Petal Dance,
|
||||
// confuse them upon release and display "confused by fatigue" message & animation.
|
||||
// Don't do this if this CancelMultiTurnMoves is caused by falling asleep via Yawn.
|
||||
if (gBattleMons[otherSkyDropper].status2 & STATUS2_LOCK_CONFUSE && gBattleStruct->turnEffectsTracker != 24)
|
||||
{
|
||||
gBattleMons[otherSkyDropper].status2 &= ~(STATUS2_LOCK_CONFUSE);
|
||||
|
||||
// If the target can be confused, confuse them.
|
||||
// Don't use CanBeConfused, can cause issues in edge cases.
|
||||
if (!(GetBattlerAbility(otherSkyDropper) == ABILITY_OWN_TEMPO
|
||||
|| gBattleMons[otherSkyDropper].status2 & STATUS2_CONFUSION
|
||||
|| IsBattlerTerrainAffected(otherSkyDropper, STATUS_FIELD_MISTY_TERRAIN)))
|
||||
{
|
||||
// Set confused status
|
||||
gBattleMons[otherSkyDropper].status2 |= STATUS2_CONFUSION_TURN(((Random()) % 4) + 2);
|
||||
|
||||
// If this CancelMultiTurnMoves is occuring due to attackcanceller
|
||||
if (gBattlescriptCurrInstr[0] == 0x0)
|
||||
{
|
||||
gBattleStruct->skyDropTargets[battler] = 0xFE;
|
||||
}
|
||||
// If this CancelMultiTurnMoves is occuring due to VARIOUS_GRAVITY_ON_AIRBORNE_MONS
|
||||
// Reapplying STATUS3_SKY_DROPPED allows for avoiding unecessary messages when Gravity is applied to the target.
|
||||
else if (gBattlescriptCurrInstr[0] == 0x76 && gBattlescriptCurrInstr[2] == 76)
|
||||
{
|
||||
gBattleStruct->skyDropTargets[battler] = 0xFE;
|
||||
gStatuses3[otherSkyDropper] |= STATUS3_SKY_DROPPED;
|
||||
}
|
||||
// If this CancelMultiTurnMoves is occuring due to cancelmultiturnmoves script
|
||||
else if (gBattlescriptCurrInstr[0] == 0x76 && gBattlescriptCurrInstr[2] == 0)
|
||||
{
|
||||
gBattlerAttacker = otherSkyDropper;
|
||||
result = BattleScript_ThrashConfuses;
|
||||
}
|
||||
// If this CancelMultiTurnMoves is occuring due to receiving Sleep/Freeze status
|
||||
else if (gBattleScripting.moveEffect <= PRIMARY_STATUS_MOVE_EFFECT)
|
||||
{
|
||||
gBattlerAttacker = otherSkyDropper;
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
||||
result = BattleScript_ThrashConfuses;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clear skyDropTargets data, unless this CancelMultiTurnMoves is caused by Yawn, attackcanceler, or VARIOUS_GRAVITY_ON_AIRBORNE_MONS
|
||||
if (!(gBattleMons[otherSkyDropper].status2 & STATUS2_LOCK_CONFUSE) && gBattleStruct->skyDropTargets[battler] < 4)
|
||||
{
|
||||
gBattleStruct->skyDropTargets[battler] = 0xFF;
|
||||
gBattleStruct->skyDropTargets[otherSkyDropper] = 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
gDisableStructs[battler].rolloutTimer = 0;
|
||||
gDisableStructs[battler].furyCutterCounter = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool32 WasUnableToUseMove(u32 battler)
|
||||
|
|
@ -3255,7 +3325,7 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn)
|
|||
}
|
||||
}
|
||||
break;
|
||||
case ITEMEFFECT_KINGSROCK_SHELLBELL:
|
||||
case ITEMEFFECT_KINGSROCK:
|
||||
if (gBattleMoveDamage)
|
||||
{
|
||||
switch (atkHoldEffect)
|
||||
|
|
@ -6213,6 +6283,366 @@ void RecalcBattlerStats(u32 battler, struct Pokemon *mon)
|
|||
CopyMonAbilityAndTypesToBattleMon(battler, mon);
|
||||
}
|
||||
|
||||
bool32 TestIfSheerForceAffected(u32 battler, u16 move)
|
||||
{
|
||||
return GetBattlerAbility(battler) == ABILITY_SHEER_FORCE && MoveIsAffectedBySheerForce(move);
|
||||
}
|
||||
|
||||
bool32 CanSleep(u32 battler)
|
||||
{
|
||||
u16 ability = GetBattlerAbility(battler);
|
||||
if (ability == ABILITY_INSOMNIA
|
||||
|| ability == ABILITY_VITAL_SPIRIT
|
||||
|| ability == ABILITY_COMATOSE
|
||||
|| ability == ABILITY_PURIFYING_SALT
|
||||
|| gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_SAFEGUARD
|
||||
|| gBattleMons[battler].status1 & STATUS1_ANY
|
||||
|| IsAbilityOnSide(battler, ABILITY_SWEET_VEIL)
|
||||
|| IsAbilityStatusProtected(battler)
|
||||
|| IsBattlerTerrainAffected(battler, STATUS_FIELD_ELECTRIC_TERRAIN | STATUS_FIELD_MISTY_TERRAIN))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool32 CanBePoisoned(u32 battlerAttacker, u32 battlerTarget)
|
||||
{
|
||||
u16 ability = GetBattlerAbility(battlerTarget);
|
||||
|
||||
if (!(CanPoisonType(battlerAttacker, battlerTarget))
|
||||
|| gSideStatuses[GetBattlerSide(battlerTarget)] & SIDE_STATUS_SAFEGUARD
|
||||
|| gBattleMons[battlerTarget].status1 & STATUS1_ANY
|
||||
|| ability == ABILITY_IMMUNITY
|
||||
|| ability == ABILITY_COMATOSE
|
||||
|| ability == ABILITY_PURIFYING_SALT
|
||||
|| IsAbilityOnSide(battlerTarget, ABILITY_PASTEL_VEIL)
|
||||
|| IsAbilityStatusProtected(battlerTarget)
|
||||
|| IsBattlerTerrainAffected(battlerTarget, STATUS_FIELD_MISTY_TERRAIN))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool32 CanBeBurned(u32 battler)
|
||||
{
|
||||
u16 ability = GetBattlerAbility(battler);
|
||||
if (IS_BATTLER_OF_TYPE(battler, TYPE_FIRE)
|
||||
|| gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_SAFEGUARD
|
||||
|| gBattleMons[battler].status1 & STATUS1_ANY
|
||||
|| ability == ABILITY_WATER_VEIL
|
||||
|| ability == ABILITY_WATER_BUBBLE
|
||||
|| ability == ABILITY_COMATOSE
|
||||
|| ability == ABILITY_THERMAL_EXCHANGE
|
||||
|| ability == ABILITY_PURIFYING_SALT
|
||||
|| IsAbilityStatusProtected(battler)
|
||||
|| IsBattlerTerrainAffected(battler, STATUS_FIELD_MISTY_TERRAIN))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool32 CanBeParalyzed(u32 battler)
|
||||
{
|
||||
u16 ability = GetBattlerAbility(battler);
|
||||
if ((B_PARALYZE_ELECTRIC >= GEN_6 && IS_BATTLER_OF_TYPE(battler, TYPE_ELECTRIC))
|
||||
|| gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_SAFEGUARD
|
||||
|| ability == ABILITY_LIMBER
|
||||
|| ability == ABILITY_COMATOSE
|
||||
|| ability == ABILITY_PURIFYING_SALT
|
||||
|| gBattleMons[battler].status1 & STATUS1_ANY
|
||||
|| IsAbilityStatusProtected(battler)
|
||||
|| IsBattlerTerrainAffected(battler, STATUS_FIELD_MISTY_TERRAIN))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool32 CanBeFrozen(u32 battler)
|
||||
{
|
||||
u16 ability = GetBattlerAbility(battler);
|
||||
if (IS_BATTLER_OF_TYPE(battler, TYPE_ICE)
|
||||
|| IsBattlerWeatherAffected(battler, B_WEATHER_SUN)
|
||||
|| gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_SAFEGUARD
|
||||
|| ability == ABILITY_MAGMA_ARMOR
|
||||
|| ability == ABILITY_COMATOSE
|
||||
|| ability == ABILITY_PURIFYING_SALT
|
||||
|| gBattleMons[battler].status1 & STATUS1_ANY
|
||||
|| IsAbilityStatusProtected(battler)
|
||||
|| IsBattlerTerrainAffected(battler, STATUS_FIELD_MISTY_TERRAIN))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool32 CanGetFrostbite(u32 battler)
|
||||
{
|
||||
u16 ability = GetBattlerAbility(battler);
|
||||
if (IS_BATTLER_OF_TYPE(battler, TYPE_ICE)
|
||||
|| gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_SAFEGUARD
|
||||
|| ability == ABILITY_MAGMA_ARMOR
|
||||
|| ability == ABILITY_COMATOSE
|
||||
|| ability == ABILITY_PURIFYING_SALT
|
||||
|| gBattleMons[battler].status1 & STATUS1_ANY
|
||||
|| IsAbilityStatusProtected(battler)
|
||||
|| IsBattlerTerrainAffected(battler, STATUS_FIELD_MISTY_TERRAIN))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool32 CanBeConfused(u32 battler)
|
||||
{
|
||||
if (GetBattlerAbility(battler) == ABILITY_OWN_TEMPO
|
||||
|| gBattleMons[battler].status2 & STATUS2_CONFUSION
|
||||
|| IsBattlerTerrainAffected(battler, STATUS_FIELD_MISTY_TERRAIN))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool32 CanStealItem(u32 battlerStealing, u32 battlerItem, u16 item)
|
||||
{
|
||||
u8 stealerSide = GetBattlerSide(battlerStealing);
|
||||
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER_TOWER)
|
||||
return FALSE;
|
||||
|
||||
// Check if the battler trying to steal should be able to
|
||||
if (stealerSide == B_SIDE_OPPONENT
|
||||
&& !(gBattleTypeFlags &
|
||||
(BATTLE_TYPE_EREADER_TRAINER
|
||||
| BATTLE_TYPE_TRAINER_TOWER
|
||||
| BATTLE_TYPE_LINK
|
||||
| (B_TRAINERS_KNOCK_OFF_ITEMS == TRUE ? BATTLE_TYPE_TRAINER : 0)
|
||||
)))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
else if (!(gBattleTypeFlags &
|
||||
(BATTLE_TYPE_EREADER_TRAINER
|
||||
| BATTLE_TYPE_BATTLE_TOWER
|
||||
| BATTLE_TYPE_LINK))
|
||||
&& (gWishFutureKnock.knockedOffMons[stealerSide] & gBitTable[gBattlerPartyIndexes[battlerStealing]]))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!CanBattlerGetOrLoseItem(battlerItem, item) // Battler with item cannot have it stolen
|
||||
||!CanBattlerGetOrLoseItem(battlerStealing, item)) // Stealer cannot take the item
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void TrySaveExchangedItem(u32 battler, u16 stolenItem)
|
||||
{
|
||||
// Because BtlController_EmitSetMonData does SetMonData, we need to save the stolen item only if it matches the battler's original
|
||||
// So, if the player steals an item during battle and has it stolen from it, it will not end the battle with it (naturally)
|
||||
if (B_TRAINERS_KNOCK_OFF_ITEMS == FALSE)
|
||||
return;
|
||||
// If regular trainer battle and mon's original item matches what is being stolen, save it to be restored at end of battle
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER
|
||||
&& !(gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER)
|
||||
&& GetBattlerSide(battler) == B_SIDE_PLAYER
|
||||
&& stolenItem == gBattleStruct->itemLost[gBattlerPartyIndexes[battler]].originalItem)
|
||||
gBattleStruct->itemLost[gBattlerPartyIndexes[battler]].stolen = TRUE;
|
||||
}
|
||||
|
||||
void RemoveBattlerType(u32 battler, u8 type)
|
||||
{
|
||||
u32 i;
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
if (*(u8 *)(&gBattleMons[battler].type1 + i) == type)
|
||||
*(u8 *)(&gBattleMons[battler].type1 + i) = TYPE_MYSTERY;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns SPECIES_NONE if no form change is possible
|
||||
u16 GetBattleFormChangeTargetSpecies(u32 battler, u16 method)
|
||||
{
|
||||
u32 i;
|
||||
u16 targetSpecies = SPECIES_NONE;
|
||||
u16 species = gBattleMons[battler].species;
|
||||
const struct FormChange *formChanges = GetSpeciesFormChanges(species);
|
||||
struct Pokemon *mon = &GetBattlerParty(battler)[gBattlerPartyIndexes[battler]];
|
||||
u16 heldItem;
|
||||
|
||||
if (formChanges != NULL)
|
||||
{
|
||||
heldItem = gBattleMons[battler].item;
|
||||
|
||||
for (i = 0; formChanges[i].method != FORM_CHANGE_TERMINATOR; i++)
|
||||
{
|
||||
if (method == formChanges[i].method && species != formChanges[i].targetSpecies)
|
||||
{
|
||||
switch (method)
|
||||
{
|
||||
case FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM:
|
||||
case FORM_CHANGE_BATTLE_PRIMAL_REVERSION:
|
||||
case FORM_CHANGE_BATTLE_ULTRA_BURST:
|
||||
if (heldItem == formChanges[i].param1)
|
||||
targetSpecies = formChanges[i].targetSpecies;
|
||||
break;
|
||||
case FORM_CHANGE_BATTLE_MEGA_EVOLUTION_MOVE:
|
||||
if (gBattleMons[battler].moves[0] == formChanges[i].param1
|
||||
|| gBattleMons[battler].moves[1] == formChanges[i].param1
|
||||
|| gBattleMons[battler].moves[2] == formChanges[i].param1
|
||||
|| gBattleMons[battler].moves[3] == formChanges[i].param1)
|
||||
targetSpecies = formChanges[i].targetSpecies;
|
||||
break;
|
||||
case FORM_CHANGE_BATTLE_SWITCH:
|
||||
targetSpecies = formChanges[i].targetSpecies;
|
||||
break;
|
||||
case FORM_CHANGE_BATTLE_HP_PERCENT:
|
||||
if (formChanges[i].param1 == GetBattlerAbility(battler))
|
||||
{
|
||||
// We multiply by 100 to make sure that integer division doesn't mess with the health check.
|
||||
u32 hpCheck = gBattleMons[battler].hp * 100 * 100 / gBattleMons[battler].maxHP;
|
||||
switch(formChanges[i].param2)
|
||||
{
|
||||
case HP_HIGHER_THAN:
|
||||
if (hpCheck > formChanges[i].param3 * 100)
|
||||
targetSpecies = formChanges[i].targetSpecies;
|
||||
break;
|
||||
case HP_LOWER_EQ_THAN:
|
||||
if (hpCheck <= formChanges[i].param3 * 100)
|
||||
targetSpecies = formChanges[i].targetSpecies;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FORM_CHANGE_BATTLE_GIGANTAMAX:
|
||||
if (GetMonData(mon, MON_DATA_GIGANTAMAX_FACTOR))
|
||||
targetSpecies = formChanges[i].targetSpecies;
|
||||
break;
|
||||
case FORM_CHANGE_BATTLE_WEATHER:
|
||||
// Check if there is a required ability and if the battler's ability does not match it
|
||||
// or is suppressed. If so, revert to the no weather form.
|
||||
if (formChanges[i].param2
|
||||
&& GetBattlerAbility(battler) != formChanges[i].param2
|
||||
&& formChanges[i].param1 == B_WEATHER_NONE)
|
||||
{
|
||||
targetSpecies = formChanges[i].targetSpecies;
|
||||
}
|
||||
// We need to revert the weather form if the field is under Air Lock, too.
|
||||
else if (!WEATHER_HAS_EFFECT && formChanges[i].param1 == B_WEATHER_NONE)
|
||||
{
|
||||
targetSpecies = formChanges[i].targetSpecies;
|
||||
}
|
||||
// Otherwise, just check for a match between the weather and the form change table.
|
||||
// Added a check for whether the weather is in effect to prevent end-of-turn soft locks with Cloud Nine / Air Lock
|
||||
else if (((gBattleWeather & formChanges[i].param1) && WEATHER_HAS_EFFECT)
|
||||
|| (gBattleWeather == B_WEATHER_NONE && formChanges[i].param1 == B_WEATHER_NONE))
|
||||
{
|
||||
targetSpecies = formChanges[i].targetSpecies;
|
||||
}
|
||||
break;
|
||||
case FORM_CHANGE_BATTLE_TURN_END:
|
||||
if (formChanges[i].param1 == GetBattlerAbility(battler))
|
||||
targetSpecies = formChanges[i].targetSpecies;
|
||||
break;
|
||||
case FORM_CHANGE_STATUS:
|
||||
if (gBattleMons[battler].status1 & formChanges[i].param1)
|
||||
targetSpecies = formChanges[i].targetSpecies;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return targetSpecies;
|
||||
}
|
||||
|
||||
bool32 IsBattlerMegaEvolved(u32 battler)
|
||||
{
|
||||
// While Transform does copy stats and visuals, it shouldn't be counted as true Mega Evolution.
|
||||
if (gBattleMons[battler].status2 & STATUS2_TRANSFORMED)
|
||||
return FALSE;
|
||||
return (gSpeciesInfo[gBattleMons[battler].species].isMegaEvolution);
|
||||
}
|
||||
|
||||
bool32 IsBattlerPrimalReverted(u32 battler)
|
||||
{
|
||||
// While Transform does copy stats and visuals, it shouldn't be counted as true Primal Revesion.
|
||||
if (gBattleMons[battler].status2 & STATUS2_TRANSFORMED)
|
||||
return FALSE;
|
||||
return (gSpeciesInfo[gBattleMons[battler].species].isPrimalReversion);
|
||||
}
|
||||
|
||||
bool32 IsBattlerUltraBursted(u32 battler)
|
||||
{
|
||||
// While Transform does copy stats and visuals, it shouldn't be counted as true Ultra Burst.
|
||||
if (gBattleMons[battler].status2 & STATUS2_TRANSFORMED)
|
||||
return FALSE;
|
||||
return (gSpeciesInfo[gBattleMons[battler].species].isUltraBurst);
|
||||
}
|
||||
|
||||
bool32 CanBattlerFormChange(u32 battler, u16 method)
|
||||
{
|
||||
// Can't change form if transformed.
|
||||
if (gBattleMons[battler].status2 & STATUS2_TRANSFORMED
|
||||
&& B_TRANSFORM_FORM_CHANGES >= GEN_5)
|
||||
return FALSE;
|
||||
// Mega Evolved and Ultra Bursted Pokémon should always revert to normal upon fainting or ending the battle.
|
||||
if ((IsBattlerMegaEvolved(battler) || IsBattlerUltraBursted(battler)) && (method == FORM_CHANGE_FAINT || method == FORM_CHANGE_END_BATTLE))
|
||||
return TRUE;
|
||||
else if (IsBattlerPrimalReverted(battler) && (method == FORM_CHANGE_END_BATTLE))
|
||||
return TRUE;
|
||||
// TODO: Dynamax
|
||||
// Gigantamaxed Pokemon should revert upon fainting, switching, or ending the battle.
|
||||
/* else if (IsGigantamaxed(battler) && (method == FORM_CHANGE_FAINT || method == FORM_CHANGE_BATTLE_SWITCH || method == FORM_CHANGE_END_BATTLE))
|
||||
return TRUE; */
|
||||
return DoesSpeciesHaveFormChangeMethod(gBattleMons[battler].species, method);
|
||||
}
|
||||
|
||||
bool32 TryBattleFormChange(u32 battler, u16 method)
|
||||
{
|
||||
u8 monId = gBattlerPartyIndexes[battler];
|
||||
u8 side = GetBattlerSide(battler);
|
||||
struct Pokemon *party = GetBattlerParty(battler);
|
||||
u16 targetSpecies;
|
||||
|
||||
if (!CanBattlerFormChange(battler, method))
|
||||
return FALSE;
|
||||
|
||||
targetSpecies = GetBattleFormChangeTargetSpecies(battler, method);
|
||||
if (targetSpecies == SPECIES_NONE)
|
||||
targetSpecies = GetFormChangeTargetSpecies(&party[monId], method, 0);
|
||||
if (targetSpecies != SPECIES_NONE)
|
||||
{
|
||||
// Saves the original species on the first form change.
|
||||
if (gBattleStruct->changedSpecies[side][monId] == SPECIES_NONE)
|
||||
gBattleStruct->changedSpecies[side][monId] = gBattleMons[battler].species;
|
||||
|
||||
TryToSetBattleFormChangeMoves(&party[monId], method);
|
||||
SetMonData(&party[monId], MON_DATA_SPECIES, &targetSpecies);
|
||||
gBattleMons[battler].species = targetSpecies;
|
||||
RecalcBattlerStats(battler, &party[monId]);
|
||||
return TRUE;
|
||||
}
|
||||
else if (gBattleStruct->changedSpecies[side][monId] != SPECIES_NONE)
|
||||
{
|
||||
bool32 restoreSpecies = FALSE;
|
||||
|
||||
// Mega Evolved and Ultra Bursted Pokémon should always revert to normal upon fainting or ending the battle, so no need to add it to the form change tables.
|
||||
if ((IsBattlerMegaEvolved(battler) || IsBattlerUltraBursted(battler)) && (method == FORM_CHANGE_FAINT || method == FORM_CHANGE_END_BATTLE))
|
||||
restoreSpecies = TRUE;
|
||||
|
||||
// Unlike Megas, Primal Reversion isn't canceled on fainting.
|
||||
else if (IsBattlerPrimalReverted(battler) && (method == FORM_CHANGE_END_BATTLE))
|
||||
restoreSpecies = TRUE;
|
||||
|
||||
// Gigantamax Pokemon have their forms reverted after fainting, switching, or ending the battle.
|
||||
else if (FALSE /* IsGigantamaxed(battler) */ && (method == FORM_CHANGE_FAINT || method == FORM_CHANGE_BATTLE_SWITCH || method == FORM_CHANGE_END_BATTLE))
|
||||
restoreSpecies = TRUE;
|
||||
|
||||
if (restoreSpecies)
|
||||
{
|
||||
// Reverts the original species
|
||||
TryToSetBattleFormChangeMoves(&party[monId], method);
|
||||
SetMonData(&party[monId], MON_DATA_SPECIES, &gBattleStruct->changedSpecies[side][monId]);
|
||||
RecalcBattlerStats(battler, &party[monId]);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// battle_ai_util.c
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -5128,7 +5128,7 @@ bool8 MonKnowsMove(struct Pokemon *mon, u16 move)
|
|||
{
|
||||
u8 i;
|
||||
|
||||
for (i = 0; i < MAX_MON_MOVES; ++i)
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
if (GetMonData(mon, MON_DATA_MOVE1 + i) == move)
|
||||
return TRUE;
|
||||
|
|
@ -5136,6 +5136,18 @@ bool8 MonKnowsMove(struct Pokemon *mon, u16 move)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
bool8 BoxMonKnowsMove(struct BoxPokemon *boxMon, u16 move)
|
||||
{
|
||||
u8 i;
|
||||
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
if (GetBoxMonData(boxMon, MON_DATA_MOVE1 + i) == move)
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void DisplayLearnMoveMessage(const u8 *str)
|
||||
{
|
||||
StringExpandPlaceholders(gStringVar4, str);
|
||||
|
|
|
|||
177
src/pokemon.c
177
src/pokemon.c
|
|
@ -30,6 +30,7 @@
|
|||
#include "constants/items.h"
|
||||
#include "constants/item_effects.h"
|
||||
#include "constants/cries.h"
|
||||
#include "constants/form_change_types.h"
|
||||
#include "constants/pokemon.h"
|
||||
#include "constants/abilities.h"
|
||||
#include "constants/moves.h"
|
||||
|
|
@ -1673,6 +1674,17 @@ void SetMonMoveSlot(struct Pokemon *mon, u16 move, u8 slot)
|
|||
SetMonData(mon, MON_DATA_PP1 + slot, &gMovesInfo[move].pp);
|
||||
}
|
||||
|
||||
static void SetMonMoveSlot_KeepPP(struct Pokemon *mon, u16 move, u8 slot)
|
||||
{
|
||||
u8 ppBonuses = GetMonData(mon, MON_DATA_PP_BONUSES, NULL);
|
||||
u8 currPP = GetMonData(mon, MON_DATA_PP1 + slot, NULL);
|
||||
u8 newPP = CalculatePPWithBonus(move, ppBonuses, slot);
|
||||
u16 finalPP = min(currPP, newPP);
|
||||
|
||||
SetMonData(mon, MON_DATA_MOVE1 + slot, &move);
|
||||
SetMonData(mon, MON_DATA_PP1 + slot, &finalPP);
|
||||
}
|
||||
|
||||
void SetBattleMonMoveSlot(struct BattlePokemon *mon, u16 move, u8 slot)
|
||||
{
|
||||
mon->moves[slot] = move;
|
||||
|
|
@ -6171,6 +6183,140 @@ u16 GetFormSpeciesId(u16 speciesId, u8 formId)
|
|||
return speciesId;
|
||||
}
|
||||
|
||||
u8 GetFormIdFromFormSpeciesId(u16 formSpeciesId)
|
||||
{
|
||||
u8 targetFormId = 0;
|
||||
|
||||
if (GetSpeciesFormTable(formSpeciesId) != NULL)
|
||||
{
|
||||
for (targetFormId = 0; GetSpeciesFormTable(formSpeciesId)[targetFormId] != FORM_SPECIES_END; targetFormId++)
|
||||
{
|
||||
if (formSpeciesId == GetSpeciesFormTable(formSpeciesId)[targetFormId])
|
||||
break;
|
||||
}
|
||||
}
|
||||
return targetFormId;
|
||||
}
|
||||
|
||||
u16 GetFormChangeTargetSpecies(struct Pokemon *mon, u16 method, u32 arg)
|
||||
{
|
||||
return GetFormChangeTargetSpeciesBoxMon(&mon->box, method, arg);
|
||||
}
|
||||
|
||||
// Returns SPECIES_NONE if no form change is possible
|
||||
u16 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *boxMon, u16 method, u32 arg)
|
||||
{
|
||||
u32 i;
|
||||
u16 targetSpecies = SPECIES_NONE;
|
||||
u16 species = GetBoxMonData(boxMon, MON_DATA_SPECIES, NULL);
|
||||
const struct FormChange *formChanges = GetSpeciesFormChanges(species);
|
||||
u16 heldItem;
|
||||
u32 ability;
|
||||
|
||||
if (formChanges != NULL)
|
||||
{
|
||||
heldItem = GetBoxMonData(boxMon, MON_DATA_HELD_ITEM, NULL);
|
||||
ability = GetAbilityBySpecies(species, GetBoxMonData(boxMon, MON_DATA_ABILITY_NUM, NULL));
|
||||
|
||||
for (i = 0; formChanges[i].method != FORM_CHANGE_TERMINATOR; i++)
|
||||
{
|
||||
if (method == formChanges[i].method && species != formChanges[i].targetSpecies)
|
||||
{
|
||||
switch (method)
|
||||
{
|
||||
case FORM_CHANGE_ITEM_HOLD:
|
||||
if ((heldItem == formChanges[i].param1 || formChanges[i].param1 == ITEM_NONE)
|
||||
&& (ability == formChanges[i].param2 || formChanges[i].param2 == ABILITY_NONE))
|
||||
targetSpecies = formChanges[i].targetSpecies;
|
||||
break;
|
||||
case FORM_CHANGE_ITEM_USE:
|
||||
if (arg == formChanges[i].param1)
|
||||
{
|
||||
// TODO: time
|
||||
switch (formChanges[i].param2)
|
||||
{
|
||||
case DAY:
|
||||
// if (GetTimeOfDay() != TIME_NIGHT)
|
||||
// targetSpecies = formChanges[i].targetSpecies;
|
||||
targetSpecies = SPECIES_NONE;
|
||||
break;
|
||||
case NIGHT:
|
||||
// if (GetTimeOfDay() == TIME_NIGHT)
|
||||
// targetSpecies = formChanges[i].targetSpecies;
|
||||
targetSpecies = SPECIES_NONE;
|
||||
break;
|
||||
default:
|
||||
targetSpecies = formChanges[i].targetSpecies;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FORM_CHANGE_ITEM_USE_MULTICHOICE:
|
||||
if (arg == formChanges[i].param1)
|
||||
{
|
||||
if (formChanges[i].param2 == gSpecialVar_Result)
|
||||
targetSpecies = formChanges[i].targetSpecies;
|
||||
}
|
||||
break;
|
||||
case FORM_CHANGE_MOVE:
|
||||
if (BoxMonKnowsMove(boxMon, formChanges[i].param1) != formChanges[i].param2)
|
||||
targetSpecies = formChanges[i].targetSpecies;
|
||||
break;
|
||||
case FORM_CHANGE_BEGIN_BATTLE:
|
||||
case FORM_CHANGE_END_BATTLE:
|
||||
if (heldItem == formChanges[i].param1 || formChanges[i].param1 == ITEM_NONE)
|
||||
targetSpecies = formChanges[i].targetSpecies;
|
||||
break;
|
||||
case FORM_CHANGE_END_BATTLE_TERRAIN:
|
||||
if (gBattleTerrain == formChanges[i].param1)
|
||||
targetSpecies = formChanges[i].targetSpecies;
|
||||
break;
|
||||
case FORM_CHANGE_WITHDRAW:
|
||||
case FORM_CHANGE_FAINT:
|
||||
case FORM_CHANGE_STATUS:
|
||||
targetSpecies = formChanges[i].targetSpecies;
|
||||
break;
|
||||
case FORM_CHANGE_TIME_OF_DAY:
|
||||
// TODO: time
|
||||
// switch (formChanges[i].param1)
|
||||
// {
|
||||
// case DAY:
|
||||
// if (GetTimeOfDay() != TIME_NIGHT)
|
||||
// targetSpecies = formChanges[i].targetSpecies;
|
||||
// break;
|
||||
// case NIGHT:
|
||||
// if (GetTimeOfDay() == TIME_NIGHT)
|
||||
// targetSpecies = formChanges[i].targetSpecies;
|
||||
// break;
|
||||
// }
|
||||
// break;
|
||||
targetSpecies = SPECIES_NONE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return targetSpecies;
|
||||
}
|
||||
|
||||
bool32 DoesSpeciesHaveFormChangeMethod(u16 species, u16 method)
|
||||
{
|
||||
u32 i;
|
||||
const struct FormChange *formChanges = GetSpeciesFormChanges(species);
|
||||
|
||||
if (formChanges != NULL)
|
||||
{
|
||||
for (i = 0; formChanges[i].method != FORM_CHANGE_TERMINATOR; i++)
|
||||
{
|
||||
if (method == formChanges[i].method && species != formChanges[i].targetSpecies)
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
u32 GetMonAffectionHearts(struct Pokemon *pokemon)
|
||||
{
|
||||
u32 friendship = GetMonData(pokemon, MON_DATA_FRIENDSHIP, NULL);
|
||||
|
|
@ -6188,3 +6334,34 @@ u32 GetMonAffectionHearts(struct Pokemon *pokemon)
|
|||
|
||||
return AFFECTION_NO_HEARTS;
|
||||
}
|
||||
|
||||
void TryToSetBattleFormChangeMoves(struct Pokemon *mon, u16 method)
|
||||
{
|
||||
int i, j;
|
||||
u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL);
|
||||
const struct FormChange *formChanges = GetSpeciesFormChanges(species);
|
||||
|
||||
if (formChanges == NULL
|
||||
|| (method != FORM_CHANGE_BEGIN_BATTLE && method != FORM_CHANGE_END_BATTLE))
|
||||
return;
|
||||
|
||||
for (i = 0; formChanges[i].method != FORM_CHANGE_TERMINATOR; i++)
|
||||
{
|
||||
if (formChanges[i].method == method
|
||||
&& formChanges[i].param2
|
||||
&& formChanges[i].param3
|
||||
&& formChanges[i].targetSpecies != species)
|
||||
{
|
||||
u16 originalMove = formChanges[i].param2;
|
||||
u16 newMove = formChanges[i].param3;
|
||||
|
||||
for (j = 0; j < MAX_MON_MOVES; j++)
|
||||
{
|
||||
u16 currMove = GetMonData(mon, MON_DATA_MOVE1 + j, NULL);
|
||||
if (currMove == originalMove)
|
||||
SetMonMoveSlot_KeepPP(mon, newMove, j);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user