mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2025-02-24 21:25:30 +01:00
merge with master
This commit is contained in:
commit
622a7f8141
@ -7257,6 +7257,10 @@ BattleScript_SelectingNotAllowedStuffCheeks::
|
|||||||
printselectionstring STRINGID_STUFFCHEEKSCANTSELECT
|
printselectionstring STRINGID_STUFFCHEEKSCANTSELECT
|
||||||
endselectionscript
|
endselectionscript
|
||||||
|
|
||||||
|
BattleScript_SelectingNotAllowedStuffCheeksInPalace::
|
||||||
|
printstring STRINGID_STUFFCHEEKSCANTSELECT
|
||||||
|
goto BattleScript_SelectingUnusableMoveInPalace
|
||||||
|
|
||||||
BattleScript_SelectingNotAllowedBelch::
|
BattleScript_SelectingNotAllowedBelch::
|
||||||
printselectionstring STRINGID_BELCHCANTSELECT
|
printselectionstring STRINGID_BELCHCANTSELECT
|
||||||
endselectionscript
|
endselectionscript
|
||||||
@ -9197,14 +9201,34 @@ BattleScript_SelectingNotAllowedMoveChoiceItem::
|
|||||||
printselectionstring STRINGID_ITEMALLOWSONLYYMOVE
|
printselectionstring STRINGID_ITEMALLOWSONLYYMOVE
|
||||||
endselectionscript
|
endselectionscript
|
||||||
|
|
||||||
|
BattleScript_SelectingNotAllowedMoveChoiceItemInPalace::
|
||||||
|
printstring STRINGID_ITEMALLOWSONLYYMOVE
|
||||||
|
goto BattleScript_SelectingUnusableMoveInPalace
|
||||||
|
|
||||||
BattleScript_SelectingNotAllowedMoveGorillaTactics::
|
BattleScript_SelectingNotAllowedMoveGorillaTactics::
|
||||||
printselectionstring STRINGID_ABILITYALLOWSONLYMOVE
|
printselectionstring STRINGID_ABILITYALLOWSONLYMOVE
|
||||||
endselectionscript
|
endselectionscript
|
||||||
|
|
||||||
|
BattleScript_SelectingNotAllowedMoveGorillaTacticsInPalace::
|
||||||
|
printstring STRINGID_ABILITYALLOWSONLYMOVE
|
||||||
|
goto BattleScript_SelectingUnusableMoveInPalace
|
||||||
|
|
||||||
BattleScript_SelectingNotAllowedMoveAssaultVest::
|
BattleScript_SelectingNotAllowedMoveAssaultVest::
|
||||||
printselectionstring STRINGID_ASSAULTVESTDOESNTALLOW
|
printselectionstring STRINGID_ASSAULTVESTDOESNTALLOW
|
||||||
endselectionscript
|
endselectionscript
|
||||||
|
|
||||||
|
BattleScript_SelectingNotAllowedMoveAssaultVestInPalace::
|
||||||
|
printstring STRINGID_ASSAULTVESTDOESNTALLOW
|
||||||
|
goto BattleScript_SelectingUnusableMoveInPalace
|
||||||
|
|
||||||
|
BattleScript_SelectingNotAllowedPlaceholder::
|
||||||
|
printselectionstring STRINGID_NOTDONEYET
|
||||||
|
endselectionscript
|
||||||
|
|
||||||
|
BattleScript_SelectingNotAllowedPlaceholderInPalace::
|
||||||
|
printstring STRINGID_NOTDONEYET
|
||||||
|
goto BattleScript_SelectingUnusableMoveInPalace
|
||||||
|
|
||||||
BattleScript_HangedOnMsg::
|
BattleScript_HangedOnMsg::
|
||||||
playanimation BS_TARGET, B_ANIM_HANGED_ON
|
playanimation BS_TARGET, B_ANIM_HANGED_ON
|
||||||
printstring STRINGID_PKMNHUNGONWITHX
|
printstring STRINGID_PKMNHUNGONWITHX
|
||||||
|
@ -73,6 +73,7 @@ enum
|
|||||||
HEALTHBOX_SAFARI_BALLS_TEXT
|
HEALTHBOX_SAFARI_BALLS_TEXT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
u32 WhichBattleCoords(u32 battlerId);
|
||||||
u8 GetMegaIndicatorSpriteId(u32 healthboxSpriteId);
|
u8 GetMegaIndicatorSpriteId(u32 healthboxSpriteId);
|
||||||
u8 CreateBattlerHealthboxSprites(u8 battler);
|
u8 CreateBattlerHealthboxSprites(u8 battler);
|
||||||
u8 CreateSafariPlayerHealthboxSprites(void);
|
u8 CreateSafariPlayerHealthboxSprites(void);
|
||||||
|
@ -210,6 +210,7 @@ extern const u8 BattleScript_BerryPPHealEnd2[];
|
|||||||
extern const u8 BattleScript_ItemHealHP_End2[];
|
extern const u8 BattleScript_ItemHealHP_End2[];
|
||||||
extern const u8 BattleScript_ItemHealHP_Ret[];
|
extern const u8 BattleScript_ItemHealHP_Ret[];
|
||||||
extern const u8 BattleScript_SelectingNotAllowedMoveChoiceItem[];
|
extern const u8 BattleScript_SelectingNotAllowedMoveChoiceItem[];
|
||||||
|
extern const u8 BattleScript_SelectingNotAllowedMoveChoiceItemInPalace[];
|
||||||
extern const u8 BattleScript_HangedOnMsg[];
|
extern const u8 BattleScript_HangedOnMsg[];
|
||||||
extern const u8 BattleScript_BerryConfuseHealEnd2[];
|
extern const u8 BattleScript_BerryConfuseHealEnd2[];
|
||||||
extern const u8 BattleScript_BerryConfuseHealRet[];
|
extern const u8 BattleScript_BerryConfuseHealRet[];
|
||||||
@ -275,6 +276,9 @@ extern const u8 BattleScript_SnowWarningActivates[];
|
|||||||
extern const u8 BattleScript_HarvestActivates[];
|
extern const u8 BattleScript_HarvestActivates[];
|
||||||
extern const u8 BattleScript_ImposterActivates[];
|
extern const u8 BattleScript_ImposterActivates[];
|
||||||
extern const u8 BattleScript_SelectingNotAllowedMoveAssaultVest[];
|
extern const u8 BattleScript_SelectingNotAllowedMoveAssaultVest[];
|
||||||
|
extern const u8 BattleScript_SelectingNotAllowedMoveAssaultVestInPalace[];
|
||||||
|
extern const u8 BattleScript_SelectingNotAllowedPlaceholder[];
|
||||||
|
extern const u8 BattleScript_SelectingNotAllowedPlaceholderInPalace[];
|
||||||
extern const u8 BattleScript_SelectingNotAllowedMoveGravity[];
|
extern const u8 BattleScript_SelectingNotAllowedMoveGravity[];
|
||||||
extern const u8 BattleScript_MoveUsedGravityPrevents[];
|
extern const u8 BattleScript_MoveUsedGravityPrevents[];
|
||||||
extern const u8 BattleScript_SelectingNotAllowedMoveGravityInPalace[];
|
extern const u8 BattleScript_SelectingNotAllowedMoveGravityInPalace[];
|
||||||
@ -301,6 +305,7 @@ extern const u8 BattleScript_DazzlingProtected[];
|
|||||||
extern const u8 BattleScript_MoveUsedPsychicTerrainPrevents[];
|
extern const u8 BattleScript_MoveUsedPsychicTerrainPrevents[];
|
||||||
extern const u8 BattleScript_MoveUsedPowder[];
|
extern const u8 BattleScript_MoveUsedPowder[];
|
||||||
extern const u8 BattleScript_SelectingNotAllowedStuffCheeks[];
|
extern const u8 BattleScript_SelectingNotAllowedStuffCheeks[];
|
||||||
|
extern const u8 BattleScript_SelectingNotAllowedStuffCheeksInPalace[];
|
||||||
extern const u8 BattleScript_SelectingNotAllowedBelch[];
|
extern const u8 BattleScript_SelectingNotAllowedBelch[];
|
||||||
extern const u8 BattleScript_SelectingNotAllowedBelchInPalace[];
|
extern const u8 BattleScript_SelectingNotAllowedBelchInPalace[];
|
||||||
extern const u8 BattleScript_PsychicSurgeActivates[];
|
extern const u8 BattleScript_PsychicSurgeActivates[];
|
||||||
@ -405,6 +410,7 @@ extern const u8 BattleScript_BlockedByPrimalWeatherRet[];
|
|||||||
extern const u8 BattleScript_PrimalReversion[];
|
extern const u8 BattleScript_PrimalReversion[];
|
||||||
extern const u8 BattleScript_HyperspaceFuryRemoveProtect[];
|
extern const u8 BattleScript_HyperspaceFuryRemoveProtect[];
|
||||||
extern const u8 BattleScript_SelectingNotAllowedMoveGorillaTactics[];
|
extern const u8 BattleScript_SelectingNotAllowedMoveGorillaTactics[];
|
||||||
|
extern const u8 BattleScript_SelectingNotAllowedMoveGorillaTacticsInPalace[];
|
||||||
extern const u8 BattleScript_WanderingSpiritActivates[];
|
extern const u8 BattleScript_WanderingSpiritActivates[];
|
||||||
extern const u8 BattleScript_MirrorArmorReflect[];
|
extern const u8 BattleScript_MirrorArmorReflect[];
|
||||||
extern const u8 BattleScript_GooeyActivates[];
|
extern const u8 BattleScript_GooeyActivates[];
|
||||||
|
@ -7,7 +7,17 @@
|
|||||||
#define MOVE_LIMITATION_TORMENTED (1 << 3)
|
#define MOVE_LIMITATION_TORMENTED (1 << 3)
|
||||||
#define MOVE_LIMITATION_TAUNT (1 << 4)
|
#define MOVE_LIMITATION_TAUNT (1 << 4)
|
||||||
#define MOVE_LIMITATION_IMPRISON (1 << 5)
|
#define MOVE_LIMITATION_IMPRISON (1 << 5)
|
||||||
#define MOVE_LIMITATIONS_ALL 0xFF
|
#define MOVE_LIMITATION_ENCORE (1 << 6)
|
||||||
|
#define MOVE_LIMITATION_CHOICE_ITEM (1 << 7)
|
||||||
|
#define MOVE_LIMITATION_ASSAULT_VEST (1 << 8)
|
||||||
|
#define MOVE_LIMITATION_GRAVITY (1 << 9)
|
||||||
|
#define MOVE_LIMITATION_HEAL_BLOCK (1 << 10)
|
||||||
|
#define MOVE_LIMITATION_BELCH (1 << 11)
|
||||||
|
#define MOVE_LIMITATION_THROAT_CHOP (1 << 12)
|
||||||
|
#define MOVE_LIMITATION_STUFF_CHEEKS (1 << 13)
|
||||||
|
|
||||||
|
#define MOVE_LIMITATION_PLACEHOLDER (1 << 15)
|
||||||
|
#define MOVE_LIMITATIONS_ALL 0xFFFF
|
||||||
|
|
||||||
#define ABILITYEFFECT_ON_SWITCHIN 0
|
#define ABILITYEFFECT_ON_SWITCHIN 0
|
||||||
#define ABILITYEFFECT_ENDTURN 1
|
#define ABILITYEFFECT_ENDTURN 1
|
||||||
@ -89,7 +99,7 @@ void BattleScriptPush(const u8 *bsPtr);
|
|||||||
void BattleScriptPushCursor(void);
|
void BattleScriptPushCursor(void);
|
||||||
void BattleScriptPop(void);
|
void BattleScriptPop(void);
|
||||||
u8 TrySetCantSelectMoveBattleScript(void);
|
u8 TrySetCantSelectMoveBattleScript(void);
|
||||||
u8 CheckMoveLimitations(u8 battlerId, u8 unusableMoves, u8 check);
|
u8 CheckMoveLimitations(u8 battlerId, u8 unusableMoves, u16 check);
|
||||||
bool8 AreAllMovesUnusable(void);
|
bool8 AreAllMovesUnusable(void);
|
||||||
u8 GetImprisonedMovesCount(u8 battlerId, u16 move);
|
u8 GetImprisonedMovesCount(u8 battlerId, u16 move);
|
||||||
u8 DoFieldEndTurnEffects(void);
|
u8 DoFieldEndTurnEffects(void);
|
||||||
|
@ -36,4 +36,12 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Compatibility definition for other projects to detect pokeemerald-expansion
|
||||||
|
#define RHH_EXPANSION
|
||||||
|
|
||||||
|
// Legacy branch-based defines included for backwards compatibility
|
||||||
|
#define BATTLE_ENGINE
|
||||||
|
#define POKEMON_EXPANSION
|
||||||
|
#define ITEM_EXPANSION
|
||||||
|
|
||||||
#endif // GUARD_CONFIG_H
|
#endif // GUARD_CONFIG_H
|
||||||
|
@ -81,7 +81,7 @@
|
|||||||
|
|
||||||
#define WILD_DOUBLE_BATTLE ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE && !(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_TRAINER))))
|
#define WILD_DOUBLE_BATTLE ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE && !(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_TRAINER))))
|
||||||
#define BATTLE_TWO_VS_ONE_OPPONENT ((gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && gTrainerBattleOpponent_B == 0xFFFF))
|
#define BATTLE_TWO_VS_ONE_OPPONENT ((gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && gTrainerBattleOpponent_B == 0xFFFF))
|
||||||
#define BATTLE_TYPE_HAS_AI (BATTLE_TYPE_TRAINER | BATTLE_TYPE_FIRST_BATTLE | BATTLE_TYPE_SAFARI | BATTLE_TYPE_ROAMER)
|
#define BATTLE_TYPE_HAS_AI (BATTLE_TYPE_TRAINER | BATTLE_TYPE_FIRST_BATTLE | BATTLE_TYPE_SAFARI | BATTLE_TYPE_ROAMER | BATTLE_TYPE_INGAME_PARTNER)
|
||||||
|
|
||||||
|
|
||||||
// Battle Outcome defines
|
// Battle Outcome defines
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
#ifndef GUARD_CONSTANTS_BATTLE_CONFIG_H
|
#ifndef GUARD_CONSTANTS_BATTLE_CONFIG_H
|
||||||
#define GUARD_CONSTANTS_BATTLE_CONFIG_H
|
#define GUARD_CONSTANTS_BATTLE_CONFIG_H
|
||||||
|
|
||||||
#include "constants/expansion_branches.h"
|
|
||||||
|
|
||||||
#ifndef GEN_3
|
#ifndef GEN_3
|
||||||
#define GEN_3 0
|
#define GEN_3 0
|
||||||
#define GEN_4 1
|
#define GEN_4 1
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
#ifndef GUARD_CONSTANTS_EXPANSION_BRANCHES_H
|
|
||||||
#define GUARD_CONSTANTS_EXPANSION_BRANCHES_H
|
|
||||||
|
|
||||||
// Branch defines: Used by other branches to detect each other.
|
|
||||||
// Each define must be here for each of RHH's branch you have pulled.
|
|
||||||
// e.g. If you have both the battle_engine and pokemon_expansion branch,
|
|
||||||
// then both BATTLE_ENGINE and POKEMON_EXPANSION must be defined here.
|
|
||||||
#define BATTLE_ENGINE
|
|
||||||
#define POKEMON_EXPANSION
|
|
||||||
#define ITEM_EXPANSION
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,8 +1,6 @@
|
|||||||
#ifndef GUARD_CONSTANTS_ITEM_CONFIG_H
|
#ifndef GUARD_CONSTANTS_ITEM_CONFIG_H
|
||||||
#define GUARD_CONSTANTS_ITEM_CONFIG_H
|
#define GUARD_CONSTANTS_ITEM_CONFIG_H
|
||||||
|
|
||||||
#include "constants/expansion_branches.h"
|
|
||||||
|
|
||||||
#ifndef GEN_3
|
#ifndef GEN_3
|
||||||
#define GEN_3 0
|
#define GEN_3 0
|
||||||
#define GEN_4 1
|
#define GEN_4 1
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
#ifndef GUARD_CONSTANTS_POKEMON_CONFIG_H
|
#ifndef GUARD_CONSTANTS_POKEMON_CONFIG_H
|
||||||
#define GUARD_CONSTANTS_POKEMON_CONFIG_H
|
#define GUARD_CONSTANTS_POKEMON_CONFIG_H
|
||||||
|
|
||||||
#include "constants/expansion_branches.h"
|
|
||||||
|
|
||||||
#ifndef GEN_3
|
#ifndef GEN_3
|
||||||
#define GEN_3 0
|
#define GEN_3 0
|
||||||
#define GEN_4 1
|
#define GEN_4 1
|
||||||
@ -14,7 +12,7 @@
|
|||||||
|
|
||||||
#define P_UPDATED_TYPES GEN_8 // Since Gen 6, several Pokémon were changed to be partially or fully Fairy type.
|
#define P_UPDATED_TYPES GEN_8 // Since Gen 6, several Pokémon were changed to be partially or fully Fairy type.
|
||||||
#define P_UPDATED_STATS GEN_8 // Since Gen 6, Pokémon stats are updated with each passing generation.
|
#define P_UPDATED_STATS GEN_8 // Since Gen 6, Pokémon stats are updated with each passing generation.
|
||||||
#define P_UPDATED_ABILITIES GEN_8 // Since Gen 6, certain Pokémon have their abilities changed. Requires BATTLE_ENGINE for Gen4+ abilities.
|
#define P_UPDATED_ABILITIES GEN_8 // Since Gen 6, certain Pokémon have their abilities changed.
|
||||||
#define P_UPDATED_EGG_GROUPS GEN_8 // Since Gen 8, certain Pokémon have gained new egg groups.
|
#define P_UPDATED_EGG_GROUPS GEN_8 // Since Gen 8, certain Pokémon have gained new egg groups.
|
||||||
#define P_SHEDINJA_BALL GEN_8 // Since Gen 4, Shedinja requires a Poké Ball for its evolution. In Gen 3, Shedinja inherits Nincada's Ball.
|
#define P_SHEDINJA_BALL GEN_8 // Since Gen 4, Shedinja requires a Poké Ball for its evolution. In Gen 3, Shedinja inherits Nincada's Ball.
|
||||||
#define P_LEGENDARY_PERFECT_IVS GEN_8 // Since Gen 6, Legendaries, Mythicals and Ultra Beasts found in the wild or given through gifts have at least 3 perfect IVs.
|
#define P_LEGENDARY_PERFECT_IVS GEN_8 // Since Gen 6, Legendaries, Mythicals and Ultra Beasts found in the wild or given through gifts have at least 3 perfect IVs.
|
||||||
|
@ -19,10 +19,9 @@ bool8 LoadCompressedSpritePaletteUsingHeap(const struct CompressedSpritePalette
|
|||||||
void DecompressPicFromTable(const struct CompressedSpriteSheet *src, void *buffer, s32 species);
|
void DecompressPicFromTable(const struct CompressedSpriteSheet *src, void *buffer, s32 species);
|
||||||
void DecompressPicFromTableGender(void* buffer, s32 species, u32 personality);
|
void DecompressPicFromTableGender(void* buffer, s32 species, u32 personality);
|
||||||
|
|
||||||
void HandleLoadSpecialPokePic(const struct CompressedSpriteSheet *src, void *dest, s32 species, u32 personality);
|
void HandleLoadSpecialPokePic(bool32 isFrontPic, void *dest, s32 species, u32 personality);
|
||||||
void HandleLoadSpecialPokePicCustom(const struct CompressedSpriteSheet *src, void *dest, s32 species, u32 personality, bool8 isFemale);
|
|
||||||
|
|
||||||
void LoadSpecialPokePic(const struct CompressedSpriteSheet *src, void *dest, s32 species, u32 personality, bool8 isFrontPic);
|
void LoadSpecialPokePic(void *dest, s32 species, u32 personality, bool8 isFrontPic);
|
||||||
|
|
||||||
u32 GetDecompressedDataSize(const u32 *ptr);
|
u32 GetDecompressedDataSize(const u32 *ptr);
|
||||||
|
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
#include "constants/pokemon.h"
|
#include "constants/pokemon.h"
|
||||||
#include "constants/easy_chat.h"
|
#include "constants/easy_chat.h"
|
||||||
#include "constants/trainer_hill.h"
|
#include "constants/trainer_hill.h"
|
||||||
#include "constants/expansion_branches.h"
|
|
||||||
|
|
||||||
// Prevent cross-jump optimization.
|
// Prevent cross-jump optimization.
|
||||||
#define BLOCK_CROSS_JUMP asm("");
|
#define BLOCK_CROSS_JUMP asm("");
|
||||||
|
@ -558,5 +558,6 @@ u8 GetFormIdFromFormSpeciesId(u16 formSpeciesId);
|
|||||||
u16 GetFormChangeTargetSpecies(struct Pokemon *mon, u16 method, u32 arg);
|
u16 GetFormChangeTargetSpecies(struct Pokemon *mon, u16 method, u32 arg);
|
||||||
u16 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *mon, u16 method, u32 arg);
|
u16 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *mon, u16 method, u32 arg);
|
||||||
u16 MonTryLearningNewMoveEvolution(struct Pokemon *mon, bool8 firstMove);
|
u16 MonTryLearningNewMoveEvolution(struct Pokemon *mon, bool8 firstMove);
|
||||||
|
bool32 ShouldShowFemaleDifferences(u16 species, u32 personality);
|
||||||
|
|
||||||
#endif // GUARD_POKEMON_H
|
#endif // GUARD_POKEMON_H
|
||||||
|
@ -21,7 +21,6 @@ u8 CreateMonIconNoPersonality(u16 species, void (*callback)(struct Sprite *), s1
|
|||||||
void FreeMonIconPalette(u16 species);
|
void FreeMonIconPalette(u16 species);
|
||||||
void FreeAndDestroyMonIconSprite(struct Sprite *sprite);
|
void FreeAndDestroyMonIconSprite(struct Sprite *sprite);
|
||||||
u8 CreateMonIcon(u16 species, void (*callback)(struct Sprite *), s16 x, s16 y, u8 subpriority, u32 personality);
|
u8 CreateMonIcon(u16 species, void (*callback)(struct Sprite *), s16 x, s16 y, u8 subpriority, u32 personality);
|
||||||
u8 CreateMonIconCustom(u16 species, void (*callback)(struct Sprite *), s16 x, s16 y, u8 subpriority, u32 personality, bool8 isFemale, bool8 isShiny);
|
|
||||||
u8 UpdateMonIconFrame(struct Sprite *sprite);
|
u8 UpdateMonIconFrame(struct Sprite *sprite);
|
||||||
void LoadMonIconPalette(u16 species);
|
void LoadMonIconPalette(u16 species);
|
||||||
void SpriteCB_MonIcon(struct Sprite *sprite);
|
void SpriteCB_MonIcon(struct Sprite *sprite);
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
extern u8 gLastViewedMonIndex;
|
extern u8 gLastViewedMonIndex;
|
||||||
|
|
||||||
extern const u8 *const gMoveDescriptionPointers[];
|
extern const u8 *const gMoveDescriptionPointers[];
|
||||||
|
extern const u8 gNotDoneYetDescription[];
|
||||||
extern const u8 *const gNatureNamePointers[];
|
extern const u8 *const gNatureNamePointers[];
|
||||||
|
|
||||||
void ShowPokemonSummaryScreen(u8 mode, void *mons, u8 monIndex, u8 maxMonIndex, void (*callback)(void));
|
void ShowPokemonSummaryScreen(u8 mode, void *mons, u8 monIndex, u8 maxMonIndex, void (*callback)(void));
|
||||||
|
@ -130,10 +130,10 @@ static u32 GetWildAiFlags(void)
|
|||||||
{
|
{
|
||||||
u8 avgLevel = GetMonData(&gEnemyParty[0], MON_DATA_LEVEL);
|
u8 avgLevel = GetMonData(&gEnemyParty[0], MON_DATA_LEVEL);
|
||||||
u32 flags;
|
u32 flags;
|
||||||
|
|
||||||
if (IsDoubleBattle())
|
if (IsDoubleBattle())
|
||||||
avgLevel = (GetMonData(&gEnemyParty[0], MON_DATA_LEVEL) + GetMonData(&gEnemyParty[1], MON_DATA_LEVEL)) / 2;
|
avgLevel = (GetMonData(&gEnemyParty[0], MON_DATA_LEVEL) + GetMonData(&gEnemyParty[1], MON_DATA_LEVEL)) / 2;
|
||||||
|
|
||||||
flags |= AI_FLAG_CHECK_BAD_MOVE;
|
flags |= AI_FLAG_CHECK_BAD_MOVE;
|
||||||
if (avgLevel >= 20)
|
if (avgLevel >= 20)
|
||||||
flags |= AI_FLAG_CHECK_VIABILITY;
|
flags |= AI_FLAG_CHECK_VIABILITY;
|
||||||
@ -141,10 +141,10 @@ static u32 GetWildAiFlags(void)
|
|||||||
flags |= AI_FLAG_PREFER_STRONGEST_MOVE;
|
flags |= AI_FLAG_PREFER_STRONGEST_MOVE;
|
||||||
if (avgLevel >= 80)
|
if (avgLevel >= 80)
|
||||||
flags |= AI_FLAG_HP_AWARE;
|
flags |= AI_FLAG_HP_AWARE;
|
||||||
|
|
||||||
if (B_VAR_WILD_AI_FLAGS != 0 && VarGet(B_VAR_WILD_AI_FLAGS) != 0)
|
if (B_VAR_WILD_AI_FLAGS != 0 && VarGet(B_VAR_WILD_AI_FLAGS) != 0)
|
||||||
flags |= VarGet(B_VAR_WILD_AI_FLAGS);
|
flags |= VarGet(B_VAR_WILD_AI_FLAGS);
|
||||||
|
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,7 +166,7 @@ void BattleAI_SetupFlags(void)
|
|||||||
AI_THINKING_STRUCT->aiFlags = gTrainers[gTrainerBattleOpponent_A].aiFlags | gTrainers[gTrainerBattleOpponent_B].aiFlags;
|
AI_THINKING_STRUCT->aiFlags = gTrainers[gTrainerBattleOpponent_A].aiFlags | gTrainers[gTrainerBattleOpponent_B].aiFlags;
|
||||||
else
|
else
|
||||||
AI_THINKING_STRUCT->aiFlags = gTrainers[gTrainerBattleOpponent_A].aiFlags;
|
AI_THINKING_STRUCT->aiFlags = gTrainers[gTrainerBattleOpponent_A].aiFlags;
|
||||||
|
|
||||||
// check smart wild AI
|
// check smart wild AI
|
||||||
if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_TRAINER)) && IsWildMonSmart())
|
if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_TRAINER)) && IsWildMonSmart())
|
||||||
AI_THINKING_STRUCT->aiFlags |= GetWildAiFlags();
|
AI_THINKING_STRUCT->aiFlags |= GetWildAiFlags();
|
||||||
@ -220,11 +220,11 @@ u8 BattleAI_ChooseMoveOrAction(void)
|
|||||||
ret = ChooseMoveOrAction_Singles();
|
ret = ChooseMoveOrAction_Singles();
|
||||||
else
|
else
|
||||||
ret = ChooseMoveOrAction_Doubles();
|
ret = ChooseMoveOrAction_Doubles();
|
||||||
|
|
||||||
// Clear protect structures, some flags may be set during AI calcs
|
// Clear protect structures, some flags may be set during AI calcs
|
||||||
// e.g. pranksterElevated from GetMovePriority
|
// e.g. pranksterElevated from GetMovePriority
|
||||||
memset(&gProtectStructs, 0, MAX_BATTLERS_COUNT * sizeof(struct ProtectStruct));
|
memset(&gProtectStructs, 0, MAX_BATTLERS_COUNT * sizeof(struct ProtectStruct));
|
||||||
|
|
||||||
gCurrentMove = savedCurrentMove;
|
gCurrentMove = savedCurrentMove;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -245,7 +245,7 @@ static void SetBattlerAiData(u8 battlerId)
|
|||||||
AI_DATA->holdEffectParams[battlerId] = GetBattlerHoldEffectParam(battlerId);
|
AI_DATA->holdEffectParams[battlerId] = GetBattlerHoldEffectParam(battlerId);
|
||||||
AI_DATA->predictedMoves[battlerId] = gLastMoves[battlerId];
|
AI_DATA->predictedMoves[battlerId] = gLastMoves[battlerId];
|
||||||
AI_DATA->hpPercents[battlerId] = GetHealthPercentage(battlerId);
|
AI_DATA->hpPercents[battlerId] = GetHealthPercentage(battlerId);
|
||||||
AI_DATA->moveLimitations[battlerId] = CheckMoveLimitations(battlerId, 0, 0xFF);
|
AI_DATA->moveLimitations[battlerId] = CheckMoveLimitations(battlerId, 0, MOVE_LIMITATIONS_ALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetAiLogicData(void)
|
void GetAiLogicData(void)
|
||||||
@ -253,13 +253,13 @@ void GetAiLogicData(void)
|
|||||||
u32 battlerAtk, battlerDef, i, move;
|
u32 battlerAtk, battlerDef, i, move;
|
||||||
u8 effectiveness;
|
u8 effectiveness;
|
||||||
s32 dmg;
|
s32 dmg;
|
||||||
|
|
||||||
memset(AI_DATA, 0, sizeof(struct AiLogicData));
|
memset(AI_DATA, 0, sizeof(struct AiLogicData));
|
||||||
|
|
||||||
if (!(gBattleTypeFlags & (BATTLE_TYPE_TRAINER | BATTLE_TYPE_FIRST_BATTLE | BATTLE_TYPE_SAFARI | BATTLE_TYPE_ROAMER))
|
if (!(gBattleTypeFlags & (BATTLE_TYPE_TRAINER | BATTLE_TYPE_FIRST_BATTLE | BATTLE_TYPE_SAFARI | BATTLE_TYPE_ROAMER))
|
||||||
&& !IsWildMonSmart())
|
&& !IsWildMonSmart())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// get/assume all battler data
|
// get/assume all battler data
|
||||||
for (i = 0; i < gBattlersCount; i++)
|
for (i = 0; i < gBattlersCount; i++)
|
||||||
{
|
{
|
||||||
@ -267,7 +267,7 @@ void GetAiLogicData(void)
|
|||||||
SetBattlerAiData(i);
|
SetBattlerAiData(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// simulate AI damage
|
// simulate AI damage
|
||||||
for (battlerAtk = 0; battlerAtk < gBattlersCount; battlerAtk++)
|
for (battlerAtk = 0; battlerAtk < gBattlersCount; battlerAtk++)
|
||||||
{
|
{
|
||||||
@ -275,26 +275,26 @@ void GetAiLogicData(void)
|
|||||||
|| !IsBattlerAIControlled(battlerAtk)) {
|
|| !IsBattlerAIControlled(battlerAtk)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (battlerDef = 0; battlerDef < gBattlersCount; battlerDef++)
|
for (battlerDef = 0; battlerDef < gBattlersCount; battlerDef++)
|
||||||
{
|
{
|
||||||
if (battlerAtk == battlerDef)
|
if (battlerAtk == battlerDef)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
RecordKnownMove(battlerDef, gLastMoves[battlerDef]);
|
RecordKnownMove(battlerDef, gLastMoves[battlerDef]);
|
||||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||||
{
|
{
|
||||||
dmg = 0;
|
dmg = 0;
|
||||||
effectiveness = AI_EFFECTIVENESS_x0;
|
effectiveness = AI_EFFECTIVENESS_x0;
|
||||||
move = gBattleMons[battlerAtk].moves[i];
|
move = gBattleMons[battlerAtk].moves[i];
|
||||||
|
|
||||||
if (move != 0
|
if (move != 0
|
||||||
&& move != 0xFFFF
|
&& move != 0xFFFF
|
||||||
//&& gBattleMoves[move].power != 0 /* we want to get effectiveness of status moves */
|
//&& gBattleMoves[move].power != 0 /* we want to get effectiveness of status moves */
|
||||||
&& !(AI_DATA->moveLimitations[battlerAtk] & gBitTable[i])) {
|
&& !(AI_DATA->moveLimitations[battlerAtk] & gBitTable[i])) {
|
||||||
dmg = AI_CalcDamage(move, battlerAtk, battlerDef, &effectiveness, TRUE);
|
dmg = AI_CalcDamage(move, battlerAtk, battlerDef, &effectiveness, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
AI_DATA->simulatedDmg[battlerAtk][battlerDef][i] = dmg;
|
AI_DATA->simulatedDmg[battlerAtk][battlerDef][i] = dmg;
|
||||||
AI_DATA->effectiveness[battlerAtk][battlerDef][i] = effectiveness;
|
AI_DATA->effectiveness[battlerAtk][battlerDef][i] = effectiveness;
|
||||||
}
|
}
|
||||||
@ -334,7 +334,7 @@ static u8 ChooseMoveOrAction_Singles(void)
|
|||||||
return AI_CHOICE_WATCH;
|
return AI_CHOICE_WATCH;
|
||||||
|
|
||||||
gActiveBattler = sBattler_AI;
|
gActiveBattler = sBattler_AI;
|
||||||
|
|
||||||
// If can switch.
|
// If can switch.
|
||||||
if (CountUsablePartyMons(sBattler_AI) > 0
|
if (CountUsablePartyMons(sBattler_AI) > 0
|
||||||
&& !IsAbilityPreventingEscape(sBattler_AI)
|
&& !IsAbilityPreventingEscape(sBattler_AI)
|
||||||
@ -375,7 +375,7 @@ static u8 ChooseMoveOrAction_Singles(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
numOfBestMoves = 1;
|
numOfBestMoves = 1;
|
||||||
currentMoveArray[0] = AI_THINKING_STRUCT->score[0];
|
currentMoveArray[0] = AI_THINKING_STRUCT->score[0];
|
||||||
consideredMoveArray[0] = 0;
|
consideredMoveArray[0] = 0;
|
||||||
@ -427,7 +427,7 @@ static u8 ChooseMoveOrAction_Doubles(void)
|
|||||||
BattleAI_SetupAIData(gBattleStruct->palaceFlags >> 4);
|
BattleAI_SetupAIData(gBattleStruct->palaceFlags >> 4);
|
||||||
else
|
else
|
||||||
BattleAI_SetupAIData(0xF);
|
BattleAI_SetupAIData(0xF);
|
||||||
|
|
||||||
gBattlerTarget = i;
|
gBattlerTarget = i;
|
||||||
if ((i & BIT_SIDE) != (sBattler_AI & BIT_SIDE))
|
if ((i & BIT_SIDE) != (sBattler_AI & BIT_SIDE))
|
||||||
RecordLastUsedMoveByTarget();
|
RecordLastUsedMoveByTarget();
|
||||||
@ -467,7 +467,7 @@ static u8 ChooseMoveOrAction_Doubles(void)
|
|||||||
{
|
{
|
||||||
if (!CanTargetBattler(sBattler_AI, i, gBattleMons[sBattler_AI].moves[j]))
|
if (!CanTargetBattler(sBattler_AI, i, gBattleMons[sBattler_AI].moves[j]))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (mostViableMovesScores[0] == AI_THINKING_STRUCT->score[j])
|
if (mostViableMovesScores[0] == AI_THINKING_STRUCT->score[j])
|
||||||
{
|
{
|
||||||
mostViableMovesScores[mostViableMovesNo] = AI_THINKING_STRUCT->score[j];
|
mostViableMovesScores[mostViableMovesNo] = AI_THINKING_STRUCT->score[j];
|
||||||
@ -586,7 +586,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
bool32 isDoubleBattle = IsValidDoubleBattle(battlerAtk);
|
bool32 isDoubleBattle = IsValidDoubleBattle(battlerAtk);
|
||||||
u32 i;
|
u32 i;
|
||||||
u16 predictedMove = AI_DATA->predictedMoves[battlerDef];
|
u16 predictedMove = AI_DATA->predictedMoves[battlerDef];
|
||||||
|
|
||||||
SetTypeBeforeUsingMove(move, battlerAtk);
|
SetTypeBeforeUsingMove(move, battlerAtk);
|
||||||
GET_MOVE_TYPE(move, moveType);
|
GET_MOVE_TYPE(move, moveType);
|
||||||
|
|
||||||
@ -594,7 +594,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
return score;
|
return score;
|
||||||
|
|
||||||
GET_MOVE_TYPE(move, moveType);
|
GET_MOVE_TYPE(move, moveType);
|
||||||
|
|
||||||
// check non-user target
|
// check non-user target
|
||||||
if (!(moveTarget & MOVE_TARGET_USER))
|
if (!(moveTarget & MOVE_TARGET_USER))
|
||||||
{
|
{
|
||||||
@ -604,7 +604,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
{
|
{
|
||||||
RETURN_SCORE_MINUS(20);
|
RETURN_SCORE_MINUS(20);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check ground immunities
|
// check ground immunities
|
||||||
if (moveType == TYPE_GROUND
|
if (moveType == TYPE_GROUND
|
||||||
&& !IsBattlerGrounded(battlerDef)
|
&& !IsBattlerGrounded(battlerDef)
|
||||||
@ -616,11 +616,11 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
{
|
{
|
||||||
RETURN_SCORE_MINUS(20);
|
RETURN_SCORE_MINUS(20);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check off screen
|
// check off screen
|
||||||
if (IsSemiInvulnerable(battlerDef, move) && moveEffect != EFFECT_SEMI_INVULNERABLE && AI_WhoStrikesFirst(battlerAtk, battlerDef, move) == AI_IS_FASTER)
|
if (IsSemiInvulnerable(battlerDef, move) && moveEffect != EFFECT_SEMI_INVULNERABLE && AI_WhoStrikesFirst(battlerAtk, battlerDef, move) == AI_IS_FASTER)
|
||||||
RETURN_SCORE_MINUS(20); // if target off screen and we go first, don't use move
|
RETURN_SCORE_MINUS(20); // if target off screen and we go first, don't use move
|
||||||
|
|
||||||
// check if negates type
|
// check if negates type
|
||||||
switch (effectiveness)
|
switch (effectiveness)
|
||||||
{
|
{
|
||||||
@ -632,7 +632,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
RETURN_SCORE_MINUS(10);
|
RETURN_SCORE_MINUS(10);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// target ability checks
|
// target ability checks
|
||||||
if (!DoesBattlerIgnoreAbilityChecks(AI_DATA->abilities[battlerAtk], move))
|
if (!DoesBattlerIgnoreAbilityChecks(AI_DATA->abilities[battlerAtk], move))
|
||||||
{
|
{
|
||||||
@ -758,7 +758,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
RETURN_SCORE_MINUS(10);
|
RETURN_SCORE_MINUS(10);
|
||||||
break;
|
break;
|
||||||
} // def ability checks
|
} // def ability checks
|
||||||
|
|
||||||
// target partner ability checks & not attacking partner
|
// target partner ability checks & not attacking partner
|
||||||
if (isDoubleBattle)
|
if (isDoubleBattle)
|
||||||
{
|
{
|
||||||
@ -796,35 +796,35 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
}
|
}
|
||||||
} // def partner ability checks
|
} // def partner ability checks
|
||||||
} // ignore def ability check
|
} // ignore def ability check
|
||||||
|
|
||||||
// gen7+ dark type mons immune to priority->elevated moves from prankster
|
// gen7+ dark type mons immune to priority->elevated moves from prankster
|
||||||
#if B_PRANKSTER_DARK_TYPES >= GEN_7
|
#if B_PRANKSTER_DARK_TYPES >= GEN_7
|
||||||
if (AI_DATA->abilities[battlerAtk] == ABILITY_PRANKSTER && IS_BATTLER_OF_TYPE(battlerDef, TYPE_DARK) && IS_MOVE_STATUS(move)
|
if (AI_DATA->abilities[battlerAtk] == ABILITY_PRANKSTER && IS_BATTLER_OF_TYPE(battlerDef, TYPE_DARK) && IS_MOVE_STATUS(move)
|
||||||
&& !(moveTarget & (MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_USER)))
|
&& !(moveTarget & (MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_USER)))
|
||||||
RETURN_SCORE_MINUS(10);
|
RETURN_SCORE_MINUS(10);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// terrain & effect checks
|
// terrain & effect checks
|
||||||
if (AI_IsTerrainAffected(battlerDef, STATUS_FIELD_ELECTRIC_TERRAIN))
|
if (AI_IsTerrainAffected(battlerDef, STATUS_FIELD_ELECTRIC_TERRAIN))
|
||||||
{
|
{
|
||||||
if (moveEffect == EFFECT_SLEEP || moveEffect == EFFECT_YAWN)
|
if (moveEffect == EFFECT_SLEEP || moveEffect == EFFECT_YAWN)
|
||||||
RETURN_SCORE_MINUS(20);
|
RETURN_SCORE_MINUS(20);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AI_IsTerrainAffected(battlerDef, STATUS_FIELD_MISTY_TERRAIN))
|
if (AI_IsTerrainAffected(battlerDef, STATUS_FIELD_MISTY_TERRAIN))
|
||||||
{
|
{
|
||||||
if (IsNonVolatileStatusMoveEffect(moveEffect) || IsConfusionMoveEffect(moveEffect))
|
if (IsNonVolatileStatusMoveEffect(moveEffect) || IsConfusionMoveEffect(moveEffect))
|
||||||
RETURN_SCORE_MINUS(20);
|
RETURN_SCORE_MINUS(20);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AI_IsTerrainAffected(battlerAtk, STATUS_FIELD_PSYCHIC_TERRAIN) && atkPriority > 0)
|
if (AI_IsTerrainAffected(battlerAtk, STATUS_FIELD_PSYCHIC_TERRAIN) && atkPriority > 0)
|
||||||
{
|
{
|
||||||
RETURN_SCORE_MINUS(20);
|
RETURN_SCORE_MINUS(20);
|
||||||
}
|
}
|
||||||
} // end check MOVE_TARGET_USER
|
} // end check MOVE_TARGET_USER
|
||||||
|
|
||||||
// the following checks apply to any target (including user)
|
// the following checks apply to any target (including user)
|
||||||
|
|
||||||
// throat chop check
|
// throat chop check
|
||||||
if (gDisableStructs[battlerAtk].throatChopTimer && TestMoveFlags(move, FLAG_SOUND))
|
if (gDisableStructs[battlerAtk].throatChopTimer && TestMoveFlags(move, FLAG_SOUND))
|
||||||
return 0; // Can't even select move at all
|
return 0; // Can't even select move at all
|
||||||
@ -860,7 +860,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check move effects
|
// check move effects
|
||||||
switch (moveEffect)
|
switch (moveEffect)
|
||||||
{
|
{
|
||||||
@ -874,7 +874,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
case EFFECT_EXPLOSION:
|
case EFFECT_EXPLOSION:
|
||||||
if (!(AI_THINKING_STRUCT->aiFlags & AI_FLAG_WILL_SUICIDE))
|
if (!(AI_THINKING_STRUCT->aiFlags & AI_FLAG_WILL_SUICIDE))
|
||||||
score -= 2;
|
score -= 2;
|
||||||
|
|
||||||
if (effectiveness == AI_EFFECTIVENESS_x0)
|
if (effectiveness == AI_EFFECTIVENESS_x0)
|
||||||
{
|
{
|
||||||
score -= 10;
|
score -= 10;
|
||||||
@ -920,7 +920,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
if (!BattlerStatCanRise(battlerAtk, AI_DATA->abilities[battlerAtk], STAT_SPATK) || !HasMoveWithSplit(battlerAtk, SPLIT_SPECIAL))
|
if (!BattlerStatCanRise(battlerAtk, AI_DATA->abilities[battlerAtk], STAT_SPATK) || !HasMoveWithSplit(battlerAtk, SPLIT_SPECIAL))
|
||||||
score -= 10;
|
score -= 10;
|
||||||
break;
|
break;
|
||||||
case EFFECT_SPECIAL_DEFENSE_UP:
|
case EFFECT_SPECIAL_DEFENSE_UP:
|
||||||
case EFFECT_SPECIAL_DEFENSE_UP_2:
|
case EFFECT_SPECIAL_DEFENSE_UP_2:
|
||||||
if (!BattlerStatCanRise(battlerAtk, AI_DATA->abilities[battlerAtk], STAT_SPDEF))
|
if (!BattlerStatCanRise(battlerAtk, AI_DATA->abilities[battlerAtk], STAT_SPDEF))
|
||||||
score -= 10;
|
score -= 10;
|
||||||
@ -1230,7 +1230,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
case EFFECT_LOW_KICK:
|
case EFFECT_LOW_KICK:
|
||||||
// AI_CBM_HighRiskForDamage
|
// AI_CBM_HighRiskForDamage
|
||||||
if (AI_DATA->abilities[battlerDef] == ABILITY_WONDER_GUARD && effectiveness < AI_EFFECTIVENESS_x2)
|
if (AI_DATA->abilities[battlerDef] == ABILITY_WONDER_GUARD && effectiveness < AI_EFFECTIVENESS_x2)
|
||||||
score -= 10;
|
score -= 10;
|
||||||
break;
|
break;
|
||||||
case EFFECT_COUNTER:
|
case EFFECT_COUNTER:
|
||||||
case EFFECT_MIRROR_COAT:
|
case EFFECT_MIRROR_COAT:
|
||||||
@ -1240,7 +1240,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
|| DoesSubstituteBlockMove(battlerAtk, BATTLE_PARTNER(battlerDef), predictedMove))
|
|| DoesSubstituteBlockMove(battlerAtk, BATTLE_PARTNER(battlerDef), predictedMove))
|
||||||
score -= 10;
|
score -= 10;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EFFECT_ROAR:
|
case EFFECT_ROAR:
|
||||||
if (CountUsablePartyMons(battlerDef) == 0)
|
if (CountUsablePartyMons(battlerDef) == 0)
|
||||||
score -= 10;
|
score -= 10;
|
||||||
@ -1392,7 +1392,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
case EFFECT_SPIKES:
|
case EFFECT_SPIKES:
|
||||||
if (gSideTimers[GetBattlerSide(battlerDef)].spikesAmount >= 3)
|
if (gSideTimers[GetBattlerSide(battlerDef)].spikesAmount >= 3)
|
||||||
score -= 10;
|
score -= 10;
|
||||||
else if (PartnerMoveIsSameNoTarget(BATTLE_PARTNER(battlerAtk), move, AI_DATA->partnerMove)
|
else if (PartnerMoveIsSameNoTarget(BATTLE_PARTNER(battlerAtk), move, AI_DATA->partnerMove)
|
||||||
&& gSideTimers[GetBattlerSide(battlerDef)].spikesAmount == 2)
|
&& gSideTimers[GetBattlerSide(battlerDef)].spikesAmount == 2)
|
||||||
score -= 10; // only one mon needs to set up the last layer of Spikes
|
score -= 10; // only one mon needs to set up the last layer of Spikes
|
||||||
break;
|
break;
|
||||||
@ -1570,7 +1570,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
score -= 10;
|
score -= 10;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (B_MENTAL_HERB >= GEN_5 && AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_MENTAL_HERB)
|
if (B_MENTAL_HERB >= GEN_5 && AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_MENTAL_HERB)
|
||||||
score -= 6;
|
score -= 6;
|
||||||
break;
|
break;
|
||||||
@ -1802,7 +1802,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
if (gBattleMons[battlerAtk].hp > (gBattleMons[battlerAtk].hp + gBattleMons[battlerDef].hp) / 2)
|
if (gBattleMons[battlerAtk].hp > (gBattleMons[battlerAtk].hp + gBattleMons[battlerDef].hp) / 2)
|
||||||
score -= 10;
|
score -= 10;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EFFECT_CONVERSION_2:
|
case EFFECT_CONVERSION_2:
|
||||||
//TODO
|
//TODO
|
||||||
break;
|
break;
|
||||||
@ -1862,7 +1862,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} // move check
|
} // move check
|
||||||
|
|
||||||
if (decreased)
|
if (decreased)
|
||||||
break;
|
break;
|
||||||
if (IsBattlerIncapacitated(battlerDef, AI_DATA->abilities[battlerDef]))
|
if (IsBattlerIncapacitated(battlerDef, AI_DATA->abilities[battlerDef]))
|
||||||
@ -1904,7 +1904,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
IncreaseAllyProtectionViability(&viability, 0xFF);
|
IncreaseAllyProtectionViability(&viability, 0xFF);
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EFFECT_MIRACLE_EYE:
|
case EFFECT_MIRACLE_EYE:
|
||||||
if (gStatuses3[battlerDef] & STATUS3_MIRACLE_EYED)
|
if (gStatuses3[battlerDef] & STATUS3_MIRACLE_EYED)
|
||||||
score -= 10;
|
score -= 10;
|
||||||
@ -1952,7 +1952,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
|| ((AI_DATA->abilities[battlerDef] == ABILITY_CONTRARY) && !IsTargetingPartner(battlerAtk, battlerDef))) // don't want to raise target stats unless its your partner
|
|| ((AI_DATA->abilities[battlerDef] == ABILITY_CONTRARY) && !IsTargetingPartner(battlerAtk, battlerDef))) // don't want to raise target stats unless its your partner
|
||||||
score -= 10;
|
score -= 10;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EFFECT_PSYCH_UP: // haze stats check
|
case EFFECT_PSYCH_UP: // haze stats check
|
||||||
{
|
{
|
||||||
for (i = STAT_ATK; i < NUM_BATTLE_STATS; i++)
|
for (i = STAT_ATK; i < NUM_BATTLE_STATS; i++)
|
||||||
@ -2116,7 +2116,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
u32 atkNegativeStages = CountNegativeStatStages(battlerAtk);
|
u32 atkNegativeStages = CountNegativeStatStages(battlerAtk);
|
||||||
u32 defPositiveStages = CountPositiveStatStages(battlerDef);
|
u32 defPositiveStages = CountPositiveStatStages(battlerDef);
|
||||||
u32 defNegativeStages = CountNegativeStatStages(battlerDef);
|
u32 defNegativeStages = CountNegativeStatStages(battlerDef);
|
||||||
|
|
||||||
if (atkPositiveStages >= defPositiveStages && atkNegativeStages <= defNegativeStages)
|
if (atkPositiveStages >= defPositiveStages && atkNegativeStages <= defNegativeStages)
|
||||||
score -= 10;
|
score -= 10;
|
||||||
break;
|
break;
|
||||||
@ -2512,22 +2512,24 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
if (gBattleMons[battlerAtk].hp <= gBattleMons[battlerAtk].maxHP / 3)
|
if (gBattleMons[battlerAtk].hp <= gBattleMons[battlerAtk].maxHP / 3)
|
||||||
score -= 10;
|
score -= 10;
|
||||||
break;*/
|
break;*/
|
||||||
|
case EFFECT_PLACEHOLDER:
|
||||||
|
return 0; // cannot even select
|
||||||
} // move effect checks
|
} // move effect checks
|
||||||
|
|
||||||
if (score < 0)
|
if (score < 0)
|
||||||
score = 0;
|
score = 0;
|
||||||
|
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
static s16 AI_TryToFaint(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
static s16 AI_TryToFaint(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||||
{
|
{
|
||||||
if (IsTargetingPartner(battlerAtk, battlerDef))
|
if (IsTargetingPartner(battlerAtk, battlerDef))
|
||||||
return score;
|
return score;
|
||||||
|
|
||||||
if (gBattleMoves[move].power == 0)
|
if (gBattleMoves[move].power == 0)
|
||||||
return score; // can't make anything faint with no power
|
return score; // can't make anything faint with no power
|
||||||
|
|
||||||
if (CanIndexMoveFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0) && gBattleMoves[move].effect != EFFECT_EXPLOSION)
|
if (CanIndexMoveFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0) && gBattleMoves[move].effect != EFFECT_EXPLOSION)
|
||||||
{
|
{
|
||||||
// this move can faint the target
|
// this move can faint the target
|
||||||
@ -2541,10 +2543,10 @@ static s16 AI_TryToFaint(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
// this move isn't expected to faint the target
|
// this move isn't expected to faint the target
|
||||||
if (TestMoveFlags(move, FLAG_HIGH_CRIT))
|
if (TestMoveFlags(move, FLAG_HIGH_CRIT))
|
||||||
score += 2; // crit makes it more likely to make them faint
|
score += 2; // crit makes it more likely to make them faint
|
||||||
|
|
||||||
if (GetMoveDamageResult(move) == MOVE_POWER_OTHER)
|
if (GetMoveDamageResult(move) == MOVE_POWER_OTHER)
|
||||||
score--;
|
score--;
|
||||||
|
|
||||||
switch (AI_DATA->effectiveness[battlerAtk][battlerDef][AI_THINKING_STRUCT->movesetIndex])
|
switch (AI_DATA->effectiveness[battlerAtk][battlerDef][AI_THINKING_STRUCT->movesetIndex])
|
||||||
{
|
{
|
||||||
case AI_EFFECTIVENESS_x8:
|
case AI_EFFECTIVENESS_x8:
|
||||||
@ -2561,7 +2563,7 @@ static s16 AI_TryToFaint(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//AI_TryToFaint_CheckIfDanger
|
//AI_TryToFaint_CheckIfDanger
|
||||||
if (!WillAIStrikeFirst() && CanTargetFaintAi(battlerDef, battlerAtk))
|
if (!WillAIStrikeFirst() && CanTargetFaintAi(battlerDef, battlerAtk))
|
||||||
{ // AI_TryToFaint_Danger
|
{ // AI_TryToFaint_Danger
|
||||||
@ -2570,7 +2572,7 @@ static s16 AI_TryToFaint(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
else
|
else
|
||||||
score++;
|
score++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2626,8 +2628,8 @@ static s16 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} // check partner move effect
|
} // check partner move effect
|
||||||
|
|
||||||
|
|
||||||
// consider our move effect relative to partner state
|
// consider our move effect relative to partner state
|
||||||
switch (effect)
|
switch (effect)
|
||||||
{
|
{
|
||||||
@ -2648,8 +2650,8 @@ static s16 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} // our effect relative to partner
|
} // our effect relative to partner
|
||||||
|
|
||||||
|
|
||||||
// consider global move effects
|
// consider global move effects
|
||||||
switch (effect)
|
switch (effect)
|
||||||
{
|
{
|
||||||
@ -2679,8 +2681,8 @@ static s16 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} // global move effect check
|
} // global move effect check
|
||||||
|
|
||||||
|
|
||||||
// check specific target
|
// check specific target
|
||||||
if (IsTargetingPartner(battlerAtk, battlerDef))
|
if (IsTargetingPartner(battlerAtk, battlerDef))
|
||||||
{
|
{
|
||||||
@ -2787,11 +2789,11 @@ static s16 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
{
|
{
|
||||||
RETURN_SCORE_PLUS(1);
|
RETURN_SCORE_PLUS(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} // ability checks
|
} // ability checks
|
||||||
} // move power check
|
} // move power check
|
||||||
|
|
||||||
// attacker move effects specifically targeting partner
|
// attacker move effects specifically targeting partner
|
||||||
if (!partnerProtecting)
|
if (!partnerProtecting)
|
||||||
{
|
{
|
||||||
@ -2904,12 +2906,12 @@ static s16 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
break;
|
break;
|
||||||
} // attacker move effects
|
} // attacker move effects
|
||||||
} // check partner protecting
|
} // check partner protecting
|
||||||
|
|
||||||
score -= 30; // otherwise, don't target partner
|
score -= 30; // otherwise, don't target partner
|
||||||
}
|
}
|
||||||
else // checking opponent
|
else // checking opponent
|
||||||
{
|
{
|
||||||
// these checks mostly handled in AI_CheckBadMove and AI_CheckViability
|
// these checks mostly handled in AI_CheckBadMove and AI_CheckViability
|
||||||
switch (effect)
|
switch (effect)
|
||||||
{
|
{
|
||||||
case EFFECT_SKILL_SWAP:
|
case EFFECT_SKILL_SWAP:
|
||||||
@ -2934,10 +2936,10 @@ static s16 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
score -= 3;
|
score -= 3;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// lightning rod, flash fire against enemy handled in AI_CheckBadMove
|
// lightning rod, flash fire against enemy handled in AI_CheckBadMove
|
||||||
}
|
}
|
||||||
|
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2974,11 +2976,11 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
u16 predictedMove = AI_DATA->predictedMoves[battlerDef];
|
u16 predictedMove = AI_DATA->predictedMoves[battlerDef];
|
||||||
bool32 isDoubleBattle = IsValidDoubleBattle(battlerAtk);
|
bool32 isDoubleBattle = IsValidDoubleBattle(battlerAtk);
|
||||||
u32 i;
|
u32 i;
|
||||||
|
|
||||||
// Targeting partner, check benefits of doing that instead
|
// Targeting partner, check benefits of doing that instead
|
||||||
if (IsTargetingPartner(battlerAtk, battlerDef))
|
if (IsTargetingPartner(battlerAtk, battlerDef))
|
||||||
return score;
|
return score;
|
||||||
|
|
||||||
// check always hits
|
// check always hits
|
||||||
if (!IS_MOVE_STATUS(move) && gBattleMoves[move].accuracy == 0)
|
if (!IS_MOVE_STATUS(move) && gBattleMoves[move].accuracy == 0)
|
||||||
{
|
{
|
||||||
@ -2987,11 +2989,11 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
if (AI_RandLessThan(100) && (gBattleMons[battlerDef].statStages[STAT_EVASION] >= 8 || gBattleMons[battlerAtk].statStages[STAT_ACC] <= 4))
|
if (AI_RandLessThan(100) && (gBattleMons[battlerDef].statStages[STAT_EVASION] >= 8 || gBattleMons[battlerAtk].statStages[STAT_ACC] <= 4))
|
||||||
score++;
|
score++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check high crit
|
// check high crit
|
||||||
if (TestMoveFlags(move, FLAG_HIGH_CRIT) && effectiveness >= AI_EFFECTIVENESS_x2 && AI_RandLessThan(128))
|
if (TestMoveFlags(move, FLAG_HIGH_CRIT) && effectiveness >= AI_EFFECTIVENESS_x2 && AI_RandLessThan(128))
|
||||||
score++;
|
score++;
|
||||||
|
|
||||||
// check already dead
|
// check already dead
|
||||||
if (!IsBattlerIncapacitated(battlerDef, AI_DATA->abilities[battlerDef])
|
if (!IsBattlerIncapacitated(battlerDef, AI_DATA->abilities[battlerDef])
|
||||||
&& CanTargetFaintAi(battlerAtk, battlerDef)
|
&& CanTargetFaintAi(battlerAtk, battlerDef)
|
||||||
@ -3002,7 +3004,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
else
|
else
|
||||||
score--;
|
score--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check damage
|
// check damage
|
||||||
if (gBattleMoves[move].power != 0 && GetMoveDamageResult(move) == MOVE_POWER_WEAK)
|
if (gBattleMoves[move].power != 0 && GetMoveDamageResult(move) == MOVE_POWER_WEAK)
|
||||||
score--;
|
score--;
|
||||||
@ -3010,11 +3012,11 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
// check status move preference
|
// check status move preference
|
||||||
if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_PREFER_STATUS_MOVES && IS_MOVE_STATUS(move) && effectiveness != AI_EFFECTIVENESS_x0)
|
if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_PREFER_STATUS_MOVES && IS_MOVE_STATUS(move) && effectiveness != AI_EFFECTIVENESS_x0)
|
||||||
score++;
|
score++;
|
||||||
|
|
||||||
// check thawing moves
|
// check thawing moves
|
||||||
if ((gBattleMons[battlerAtk].status1 & STATUS1_FREEZE) && TestMoveFlags(move, FLAG_THAW_USER))
|
if ((gBattleMons[battlerAtk].status1 & STATUS1_FREEZE) && TestMoveFlags(move, FLAG_THAW_USER))
|
||||||
score += (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) ? 20 : 10;
|
score += (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) ? 20 : 10;
|
||||||
|
|
||||||
// check burn
|
// check burn
|
||||||
if (gBattleMons[battlerAtk].status1 & STATUS1_BURN)
|
if (gBattleMons[battlerAtk].status1 & STATUS1_BURN)
|
||||||
{
|
{
|
||||||
@ -3033,7 +3035,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// attacker ability checks
|
// attacker ability checks
|
||||||
switch (AI_DATA->abilities[battlerAtk])
|
switch (AI_DATA->abilities[battlerAtk])
|
||||||
{
|
{
|
||||||
@ -3049,8 +3051,8 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
score += 8; // prioritize killing target for stat boost
|
score += 8; // prioritize killing target for stat boost
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} // ability checks
|
} // ability checks
|
||||||
|
|
||||||
// move effect checks
|
// move effect checks
|
||||||
switch (moveEffect)
|
switch (moveEffect)
|
||||||
{
|
{
|
||||||
@ -3095,7 +3097,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!AI_RandLessThan(100))
|
if (!AI_RandLessThan(100))
|
||||||
{
|
{
|
||||||
score--;
|
score--;
|
||||||
@ -3141,7 +3143,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!AI_RandLessThan(100))
|
if (!AI_RandLessThan(100))
|
||||||
{
|
{
|
||||||
score--;
|
score--;
|
||||||
@ -3164,7 +3166,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
score -= 2;
|
score -= 2;
|
||||||
else if (AI_DATA->hpPercents[battlerAtk] <= 70)
|
else if (AI_DATA->hpPercents[battlerAtk] <= 70)
|
||||||
score -= 2;
|
score -= 2;
|
||||||
else
|
else
|
||||||
score++;
|
score++;
|
||||||
break;
|
break;
|
||||||
case EFFECT_EVASION_UP:
|
case EFFECT_EVASION_UP:
|
||||||
@ -3294,7 +3296,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
case EFFECT_ATTACK_SPATK_UP: // work up
|
case EFFECT_ATTACK_SPATK_UP: // work up
|
||||||
if (AI_DATA->hpPercents[battlerAtk] <= 40 || AI_DATA->abilities[battlerAtk] == ABILITY_CONTRARY)
|
if (AI_DATA->hpPercents[battlerAtk] <= 40 || AI_DATA->abilities[battlerAtk] == ABILITY_CONTRARY)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (HasMoveWithSplit(battlerAtk, SPLIT_PHYSICAL))
|
if (HasMoveWithSplit(battlerAtk, SPLIT_PHYSICAL))
|
||||||
IncreaseStatUpScore(battlerAtk, battlerDef, STAT_ATK, &score);
|
IncreaseStatUpScore(battlerAtk, battlerDef, STAT_ATK, &score);
|
||||||
else if (HasMoveWithSplit(battlerAtk, SPLIT_SPECIAL))
|
else if (HasMoveWithSplit(battlerAtk, SPLIT_SPECIAL))
|
||||||
@ -3350,7 +3352,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ShouldRecover(battlerAtk, battlerDef, move, healPercent))
|
if (ShouldRecover(battlerAtk, battlerDef, move, healPercent))
|
||||||
score += 2;
|
score += 2;
|
||||||
}
|
}
|
||||||
@ -3578,7 +3580,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
if (newHp > healthBenchmark && ShouldAbsorb(battlerAtk, battlerDef, move, AI_DATA->simulatedDmg[battlerAtk][battlerDef][AI_THINKING_STRUCT->movesetIndex]))
|
if (newHp > healthBenchmark && ShouldAbsorb(battlerAtk, battlerDef, move, AI_DATA->simulatedDmg[battlerAtk][battlerDef][AI_THINKING_STRUCT->movesetIndex]))
|
||||||
score += 2;
|
score += 2;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EFFECT_SLEEP_TALK:
|
case EFFECT_SLEEP_TALK:
|
||||||
case EFFECT_SNORE:
|
case EFFECT_SNORE:
|
||||||
if (!IsWakeupTurn(battlerAtk) && gBattleMons[battlerAtk].status1 & STATUS1_SLEEP)
|
if (!IsWakeupTurn(battlerAtk) && gBattleMons[battlerAtk].status1 & STATUS1_SLEEP)
|
||||||
@ -3613,13 +3615,13 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
case EFFECT_THIEF:
|
case EFFECT_THIEF:
|
||||||
{
|
{
|
||||||
bool32 canSteal = FALSE;
|
bool32 canSteal = FALSE;
|
||||||
|
|
||||||
#if defined B_TRAINERS_KNOCK_OFF_ITEMS && B_TRAINERS_KNOCK_OFF_ITEMS == TRUE
|
#if defined B_TRAINERS_KNOCK_OFF_ITEMS && B_TRAINERS_KNOCK_OFF_ITEMS == TRUE
|
||||||
canSteal = TRUE;
|
canSteal = TRUE;
|
||||||
#endif
|
#endif
|
||||||
if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER || GetBattlerSide(battlerAtk) == B_SIDE_PLAYER)
|
if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER || GetBattlerSide(battlerAtk) == B_SIDE_PLAYER)
|
||||||
canSteal = TRUE;
|
canSteal = TRUE;
|
||||||
|
|
||||||
if (canSteal && AI_DATA->items[battlerAtk] == ITEM_NONE
|
if (canSteal && AI_DATA->items[battlerAtk] == ITEM_NONE
|
||||||
&& AI_DATA->items[battlerDef] != ITEM_NONE
|
&& AI_DATA->items[battlerDef] != ITEM_NONE
|
||||||
&& CanBattlerGetOrLoseItem(battlerDef, AI_DATA->items[battlerDef])
|
&& CanBattlerGetOrLoseItem(battlerDef, AI_DATA->items[battlerDef])
|
||||||
@ -3763,8 +3765,8 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
if (AI_DATA->abilities[battlerDef] == ABILITY_MAGIC_BOUNCE || CountUsablePartyMons(battlerDef) == 0)
|
if (AI_DATA->abilities[battlerDef] == ABILITY_MAGIC_BOUNCE || CountUsablePartyMons(battlerDef) == 0)
|
||||||
break;
|
break;
|
||||||
if (gDisableStructs[battlerAtk].isFirstTurn)
|
if (gDisableStructs[battlerAtk].isFirstTurn)
|
||||||
score += 2;
|
score += 2;
|
||||||
//TODO - track entire opponent party data to determine hazard effectiveness
|
//TODO - track entire opponent party data to determine hazard effectiveness
|
||||||
break;
|
break;
|
||||||
case EFFECT_FORESIGHT:
|
case EFFECT_FORESIGHT:
|
||||||
if (AI_DATA->abilities[battlerAtk] == ABILITY_SCRAPPY)
|
if (AI_DATA->abilities[battlerAtk] == ABILITY_SCRAPPY)
|
||||||
@ -3793,7 +3795,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
if (HasMoveEffect(battlerDef, EFFECT_MORNING_SUN)
|
if (HasMoveEffect(battlerDef, EFFECT_MORNING_SUN)
|
||||||
|| HasMoveEffect(battlerDef, EFFECT_SYNTHESIS)
|
|| HasMoveEffect(battlerDef, EFFECT_SYNTHESIS)
|
||||||
|| HasMoveEffect(battlerDef, EFFECT_MOONLIGHT))
|
|| HasMoveEffect(battlerDef, EFFECT_MOONLIGHT))
|
||||||
score += 2;
|
score += 2;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EFFECT_HAIL:
|
case EFFECT_HAIL:
|
||||||
@ -3802,7 +3804,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
if ((HasMoveEffect(battlerAtk, EFFECT_AURORA_VEIL) || HasMoveEffect(BATTLE_PARTNER(battlerAtk), EFFECT_AURORA_VEIL))
|
if ((HasMoveEffect(battlerAtk, EFFECT_AURORA_VEIL) || HasMoveEffect(BATTLE_PARTNER(battlerAtk), EFFECT_AURORA_VEIL))
|
||||||
&& ShouldSetScreen(battlerAtk, battlerDef, EFFECT_AURORA_VEIL))
|
&& ShouldSetScreen(battlerAtk, battlerDef, EFFECT_AURORA_VEIL))
|
||||||
score += 3;
|
score += 3;
|
||||||
|
|
||||||
score++;
|
score++;
|
||||||
if (AI_DATA->holdEffects[battlerAtk] == HOLD_EFFECT_ICY_ROCK)
|
if (AI_DATA->holdEffects[battlerAtk] == HOLD_EFFECT_ICY_ROCK)
|
||||||
score++;
|
score++;
|
||||||
@ -3861,7 +3863,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
case EFFECT_SPECTRAL_THIEF:
|
case EFFECT_SPECTRAL_THIEF:
|
||||||
// Want to copy positive stat changes
|
// Want to copy positive stat changes
|
||||||
for (i = STAT_ATK; i < NUM_BATTLE_STATS; i++)
|
for (i = STAT_ATK; i < NUM_BATTLE_STATS; i++)
|
||||||
{
|
{
|
||||||
if (gBattleMons[battlerDef].statStages[i] > gBattleMons[battlerAtk].statStages[i])
|
if (gBattleMons[battlerDef].statStages[i] > gBattleMons[battlerAtk].statStages[i])
|
||||||
{
|
{
|
||||||
switch (i)
|
switch (i)
|
||||||
@ -3920,7 +3922,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
if (HasMoveEffect(battlerAtk, EFFECT_SWALLOW)
|
if (HasMoveEffect(battlerAtk, EFFECT_SWALLOW)
|
||||||
|| HasMoveEffect(battlerAtk, EFFECT_SPIT_UP))
|
|| HasMoveEffect(battlerAtk, EFFECT_SPIT_UP))
|
||||||
score += 2;
|
score += 2;
|
||||||
|
|
||||||
IncreaseStatUpScore(battlerAtk, battlerDef, STAT_DEF, &score);
|
IncreaseStatUpScore(battlerAtk, battlerDef, STAT_DEF, &score);
|
||||||
IncreaseStatUpScore(battlerAtk, battlerDef, STAT_SPDEF, &score);
|
IncreaseStatUpScore(battlerAtk, battlerDef, STAT_SPDEF, &score);
|
||||||
break;
|
break;
|
||||||
@ -3937,20 +3939,20 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
|| HasMoveEffect(battlerAtk, EFFECT_PSYCH_UP)
|
|| HasMoveEffect(battlerAtk, EFFECT_PSYCH_UP)
|
||||||
|| HasMoveEffect(battlerAtk, EFFECT_SPECTRAL_THIEF))
|
|| HasMoveEffect(battlerAtk, EFFECT_SPECTRAL_THIEF))
|
||||||
score++;
|
score++;
|
||||||
|
|
||||||
if (AI_DATA->abilities[battlerDef] == ABILITY_CONTRARY)
|
if (AI_DATA->abilities[battlerDef] == ABILITY_CONTRARY)
|
||||||
score += 2;
|
score += 2;
|
||||||
|
|
||||||
IncreaseConfusionScore(battlerAtk, battlerDef, move, &score);
|
IncreaseConfusionScore(battlerAtk, battlerDef, move, &score);
|
||||||
break;
|
break;
|
||||||
case EFFECT_FLATTER:
|
case EFFECT_FLATTER:
|
||||||
if (HasMoveEffect(battlerAtk, EFFECT_PSYCH_UP)
|
if (HasMoveEffect(battlerAtk, EFFECT_PSYCH_UP)
|
||||||
|| HasMoveEffect(battlerAtk, EFFECT_SPECTRAL_THIEF))
|
|| HasMoveEffect(battlerAtk, EFFECT_SPECTRAL_THIEF))
|
||||||
score += 2;
|
score += 2;
|
||||||
|
|
||||||
if (AI_DATA->abilities[battlerDef] == ABILITY_CONTRARY)
|
if (AI_DATA->abilities[battlerDef] == ABILITY_CONTRARY)
|
||||||
score += 2;
|
score += 2;
|
||||||
|
|
||||||
IncreaseConfusionScore(battlerAtk, battlerDef, move, &score);
|
IncreaseConfusionScore(battlerAtk, battlerDef, move, &score);
|
||||||
break;
|
break;
|
||||||
case EFFECT_FURY_CUTTER:
|
case EFFECT_FURY_CUTTER:
|
||||||
@ -3991,7 +3993,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
score += 3;
|
score += 3;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (move)
|
switch (move)
|
||||||
{
|
{
|
||||||
case MOVE_DEFOG:
|
case MOVE_DEFOG:
|
||||||
@ -4007,7 +4009,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
&& AI_WhoStrikesFirst(battlerAtk, BATTLE_PARTNER(battlerAtk), move) == AI_IS_SLOWER) // Partner going first
|
&& AI_WhoStrikesFirst(battlerAtk, BATTLE_PARTNER(battlerAtk), move) == AI_IS_SLOWER) // Partner going first
|
||||||
break; // Don't use Defog if partner is going to set up hazards
|
break; // Don't use Defog if partner is going to set up hazards
|
||||||
}
|
}
|
||||||
|
|
||||||
// check defog lowering evasion
|
// check defog lowering evasion
|
||||||
if (ShouldLowerEvasion(battlerAtk, battlerDef, AI_DATA->abilities[battlerDef]))
|
if (ShouldLowerEvasion(battlerAtk, battlerDef, AI_DATA->abilities[battlerDef]))
|
||||||
{
|
{
|
||||||
@ -4179,10 +4181,10 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
{
|
{
|
||||||
u16 item = GetUsedHeldItem(battlerAtk);
|
u16 item = GetUsedHeldItem(battlerAtk);
|
||||||
u16 toHeal = (ItemId_GetHoldEffectParam(item) == 10) ? 10 : gBattleMons[battlerAtk].maxHP / ItemId_GetHoldEffectParam(item);
|
u16 toHeal = (ItemId_GetHoldEffectParam(item) == 10) ? 10 : gBattleMons[battlerAtk].maxHP / ItemId_GetHoldEffectParam(item);
|
||||||
|
|
||||||
if (IsStatBoostingBerry(item) && AI_DATA->hpPercents[battlerAtk] > 60)
|
if (IsStatBoostingBerry(item) && AI_DATA->hpPercents[battlerAtk] > 60)
|
||||||
score++;
|
score++;
|
||||||
else if (ShouldRestoreHpBerry(battlerAtk, item) && !CanAIFaintTarget(battlerAtk, battlerDef, 0)
|
else if (ShouldRestoreHpBerry(battlerAtk, item) && !CanAIFaintTarget(battlerAtk, battlerDef, 0)
|
||||||
&& ((GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0 && CanTargetFaintAiWithMod(battlerDef, battlerAtk, 0, 0))
|
&& ((GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0 && CanTargetFaintAiWithMod(battlerDef, battlerAtk, 0, 0))
|
||||||
|| !CanTargetFaintAiWithMod(battlerDef, battlerAtk, toHeal, 0)))
|
|| !CanTargetFaintAiWithMod(battlerDef, battlerAtk, toHeal, 0)))
|
||||||
score++; // Recycle healing berry if we can't otherwise faint the target and the target wont kill us after we activate the berry
|
score++; // Recycle healing berry if we can't otherwise faint the target and the target wont kill us after we activate the berry
|
||||||
@ -4229,7 +4231,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
{
|
{
|
||||||
if (AI_DATA->abilities[battlerDef] != AI_DATA->abilities[battlerAtk] && !(gStatuses3[battlerDef] & STATUS3_GASTRO_ACID))
|
if (AI_DATA->abilities[battlerDef] != AI_DATA->abilities[battlerAtk] && !(gStatuses3[battlerDef] & STATUS3_GASTRO_ACID))
|
||||||
score += 2;
|
score += 2;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EFFECT_IMPRISON:
|
case EFFECT_IMPRISON:
|
||||||
if (predictedMove != MOVE_NONE && HasMove(battlerAtk, predictedMove))
|
if (predictedMove != MOVE_NONE && HasMove(battlerAtk, predictedMove))
|
||||||
@ -4300,7 +4302,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
case EFFECT_SHELL_SMASH:
|
case EFFECT_SHELL_SMASH:
|
||||||
if (AI_DATA->holdEffects[battlerAtk] == HOLD_EFFECT_RESTORE_STATS)
|
if (AI_DATA->holdEffects[battlerAtk] == HOLD_EFFECT_RESTORE_STATS)
|
||||||
score += 1;
|
score += 1;
|
||||||
|
|
||||||
IncreaseStatUpScore(battlerAtk, battlerDef, STAT_SPEED, &score);
|
IncreaseStatUpScore(battlerAtk, battlerDef, STAT_SPEED, &score);
|
||||||
IncreaseStatUpScore(battlerAtk, battlerDef, STAT_SPATK, &score);
|
IncreaseStatUpScore(battlerAtk, battlerDef, STAT_SPATK, &score);
|
||||||
IncreaseStatUpScore(battlerAtk, battlerDef, STAT_ATK, &score);
|
IncreaseStatUpScore(battlerAtk, battlerDef, STAT_ATK, &score);
|
||||||
@ -4407,7 +4409,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
if (gStatuses3[battlerAtk] & STATUS3_YAWN && IsBattlerGrounded(battlerAtk))
|
if (gStatuses3[battlerAtk] & STATUS3_YAWN && IsBattlerGrounded(battlerAtk))
|
||||||
score += 10;
|
score += 10;
|
||||||
//fallthrough
|
//fallthrough
|
||||||
case EFFECT_GRASSY_TERRAIN:
|
case EFFECT_GRASSY_TERRAIN:
|
||||||
case EFFECT_PSYCHIC_TERRAIN:
|
case EFFECT_PSYCHIC_TERRAIN:
|
||||||
score += 2;
|
score += 2;
|
||||||
if (AI_DATA->holdEffects[battlerAtk] == HOLD_EFFECT_TERRAIN_EXTENDER)
|
if (AI_DATA->holdEffects[battlerAtk] == HOLD_EFFECT_TERRAIN_EXTENDER)
|
||||||
@ -4680,7 +4682,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
//case EFFECT_SKY_DROP
|
//case EFFECT_SKY_DROP
|
||||||
//break;
|
//break;
|
||||||
} // move effect checks
|
} // move effect checks
|
||||||
|
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4690,15 +4692,15 @@ static s16 AI_SetupFirstTurn(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
if (IsTargetingPartner(battlerAtk, battlerDef)
|
if (IsTargetingPartner(battlerAtk, battlerDef)
|
||||||
|| gBattleResults.battleTurnCounter != 0)
|
|| gBattleResults.battleTurnCounter != 0)
|
||||||
return score;
|
return score;
|
||||||
|
|
||||||
if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_SMART_SWITCHING
|
if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_SMART_SWITCHING
|
||||||
&& AI_WhoStrikesFirst(battlerAtk, battlerDef, move) == AI_IS_SLOWER
|
&& AI_WhoStrikesFirst(battlerAtk, battlerDef, move) == AI_IS_SLOWER
|
||||||
&& CanTargetFaintAi(battlerDef, battlerAtk)
|
&& CanTargetFaintAi(battlerDef, battlerAtk)
|
||||||
&& GetMovePriority(battlerAtk, move) == 0)
|
&& GetMovePriority(battlerAtk, move) == 0)
|
||||||
{
|
{
|
||||||
RETURN_SCORE_MINUS(20); // No point in setting up if you will faint. Should just switch if possible..
|
RETURN_SCORE_MINUS(20); // No point in setting up if you will faint. Should just switch if possible..
|
||||||
}
|
}
|
||||||
|
|
||||||
// check effects to prioritize first turn
|
// check effects to prioritize first turn
|
||||||
switch (gBattleMoves[move].effect)
|
switch (gBattleMoves[move].effect)
|
||||||
{
|
{
|
||||||
@ -4787,7 +4789,7 @@ static s16 AI_SetupFirstTurn(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4796,10 +4798,10 @@ static s16 AI_Risky(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
{
|
{
|
||||||
if (IsTargetingPartner(battlerAtk, battlerDef))
|
if (IsTargetingPartner(battlerAtk, battlerDef))
|
||||||
return score;
|
return score;
|
||||||
|
|
||||||
if (TestMoveFlags(move, FLAG_HIGH_CRIT))
|
if (TestMoveFlags(move, FLAG_HIGH_CRIT))
|
||||||
score += 2;
|
score += 2;
|
||||||
|
|
||||||
switch (gBattleMoves[move].effect)
|
switch (gBattleMoves[move].effect)
|
||||||
{
|
{
|
||||||
case EFFECT_SLEEP:
|
case EFFECT_SLEEP:
|
||||||
@ -4826,7 +4828,7 @@ static s16 AI_Risky(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4835,10 +4837,10 @@ static s16 AI_PreferStrongestMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 sc
|
|||||||
{
|
{
|
||||||
if (IsTargetingPartner(battlerAtk, battlerDef))
|
if (IsTargetingPartner(battlerAtk, battlerDef))
|
||||||
return score;
|
return score;
|
||||||
|
|
||||||
if (GetMoveDamageResult(move) == MOVE_POWER_BEST)
|
if (GetMoveDamageResult(move) == MOVE_POWER_BEST)
|
||||||
score += 2;
|
score += 2;
|
||||||
|
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4846,14 +4848,14 @@ static s16 AI_PreferStrongestMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 sc
|
|||||||
static s16 AI_PreferBatonPass(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
static s16 AI_PreferBatonPass(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||||
{
|
{
|
||||||
u32 i;
|
u32 i;
|
||||||
|
|
||||||
if (IsTargetingPartner(battlerAtk, battlerDef)
|
if (IsTargetingPartner(battlerAtk, battlerDef)
|
||||||
|| CountUsablePartyMons(battlerAtk) == 0
|
|| CountUsablePartyMons(battlerAtk) == 0
|
||||||
|| GetMoveDamageResult(move) != MOVE_POWER_OTHER
|
|| GetMoveDamageResult(move) != MOVE_POWER_OTHER
|
||||||
|| !HasMoveEffect(battlerAtk, EFFECT_BATON_PASS)
|
|| !HasMoveEffect(battlerAtk, EFFECT_BATON_PASS)
|
||||||
|| IsBattlerTrapped(battlerAtk, TRUE))
|
|| IsBattlerTrapped(battlerAtk, TRUE))
|
||||||
return score;
|
return score;
|
||||||
|
|
||||||
if (IsStatRaisingEffect(gBattleMoves[move].effect))
|
if (IsStatRaisingEffect(gBattleMoves[move].effect))
|
||||||
{
|
{
|
||||||
if (gBattleResults.battleTurnCounter == 0)
|
if (gBattleResults.battleTurnCounter == 0)
|
||||||
@ -4861,9 +4863,9 @@ static s16 AI_PreferBatonPass(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
else if (AI_DATA->hpPercents[battlerAtk] < 60)
|
else if (AI_DATA->hpPercents[battlerAtk] < 60)
|
||||||
score -= 10;
|
score -= 10;
|
||||||
else
|
else
|
||||||
score++;
|
score++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// other specific checks
|
// other specific checks
|
||||||
switch (gBattleMoves[move].effect)
|
switch (gBattleMoves[move].effect)
|
||||||
{
|
{
|
||||||
@ -4889,12 +4891,12 @@ static s16 AI_PreferBatonPass(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
if (gStatuses3[battlerAtk] & (STATUS3_ROOTED | STATUS3_AQUA_RING))
|
if (gStatuses3[battlerAtk] & (STATUS3_ROOTED | STATUS3_AQUA_RING))
|
||||||
score += 2;
|
score += 2;
|
||||||
if (gStatuses3[battlerAtk] & STATUS3_LEECHSEED)
|
if (gStatuses3[battlerAtk] & STATUS3_LEECHSEED)
|
||||||
score -= 3;
|
score -= 3;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4914,11 +4916,11 @@ static s16 AI_HPAware(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
{
|
{
|
||||||
if (gStatuses3[battlerDef] & STATUS3_HEAL_BLOCK)
|
if (gStatuses3[battlerDef] & STATUS3_HEAL_BLOCK)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (CanTargetFaintAi(FOE(battlerAtk), BATTLE_PARTNER(battlerAtk))
|
if (CanTargetFaintAi(FOE(battlerAtk), BATTLE_PARTNER(battlerAtk))
|
||||||
|| (CanTargetFaintAi(BATTLE_PARTNER(FOE(battlerAtk)), BATTLE_PARTNER(battlerAtk))))
|
|| (CanTargetFaintAi(BATTLE_PARTNER(FOE(battlerAtk)), BATTLE_PARTNER(battlerAtk))))
|
||||||
score--;
|
score--;
|
||||||
|
|
||||||
if (AI_DATA->hpPercents[battlerDef] <= 50)
|
if (AI_DATA->hpPercents[battlerDef] <= 50)
|
||||||
score++;
|
score++;
|
||||||
}
|
}
|
||||||
@ -4957,7 +4959,7 @@ static s16 AI_HPAware(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
// med hp
|
// med hp
|
||||||
if (IsStatRaisingEffect(effect) || IsStatLoweringEffect(effect))
|
if (IsStatRaisingEffect(effect) || IsStatLoweringEffect(effect))
|
||||||
score -= 2;
|
score -= 2;
|
||||||
|
|
||||||
switch (effect)
|
switch (effect)
|
||||||
{
|
{
|
||||||
case EFFECT_EXPLOSION:
|
case EFFECT_EXPLOSION:
|
||||||
@ -4980,7 +4982,7 @@ static s16 AI_HPAware(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
// low hp
|
// low hp
|
||||||
if (IsStatRaisingEffect(effect) || IsStatLoweringEffect(effect))
|
if (IsStatRaisingEffect(effect) || IsStatLoweringEffect(effect))
|
||||||
score -= 2;
|
score -= 2;
|
||||||
|
|
||||||
// check other discouraged low hp effects
|
// check other discouraged low hp effects
|
||||||
switch (effect)
|
switch (effect)
|
||||||
{
|
{
|
||||||
@ -5013,7 +5015,7 @@ static s16 AI_HPAware(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// consider target HP
|
// consider target HP
|
||||||
if (CanIndexMoveFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0))
|
if (CanIndexMoveFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0))
|
||||||
{
|
{
|
||||||
@ -5085,7 +5087,7 @@ static s16 AI_HPAware(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
score -= 2; // don't use status moves if target is at low health
|
score -= 2; // don't use status moves if target is at low health
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5104,7 +5106,7 @@ static s16 AI_Roaming(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||||||
{
|
{
|
||||||
if (IsBattlerTrapped(battlerAtk, FALSE))
|
if (IsBattlerTrapped(battlerAtk, FALSE))
|
||||||
return score;
|
return score;
|
||||||
|
|
||||||
AI_Flee();
|
AI_Flee();
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
@ -154,7 +154,7 @@ static bool8 FindMonThatAbsorbsOpponentsMove(void)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
if (gLastLandedMoves[gActiveBattler] == MOVE_UNAVAILABLE)
|
if (gLastLandedMoves[gActiveBattler] == MOVE_UNAVAILABLE)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (gBattleMoves[gLastLandedMoves[gActiveBattler]].power == 0)
|
if (IS_MOVE_STATUS(gLastLandedMoves[gActiveBattler]))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
|
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
|
||||||
@ -245,8 +245,7 @@ static bool8 ShouldSwitchIfNaturalCure(void)
|
|||||||
BtlController_EmitTwoReturnValues(BUFFER_B, B_ACTION_SWITCH, 0);
|
BtlController_EmitTwoReturnValues(BUFFER_B, B_ACTION_SWITCH, 0);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
else if (gBattleMoves[gLastLandedMoves[gActiveBattler]].power == 0
|
else if (IS_MOVE_STATUS(gLastLandedMoves[gActiveBattler]) && Random() & 1)
|
||||||
&& Random() & 1)
|
|
||||||
{
|
{
|
||||||
*(gBattleStruct->AI_monToSwitchIntoId + gActiveBattler) = PARTY_SIZE;
|
*(gBattleStruct->AI_monToSwitchIntoId + gActiveBattler) = PARTY_SIZE;
|
||||||
BtlController_EmitTwoReturnValues(BUFFER_B, B_ACTION_SWITCH, 0);
|
BtlController_EmitTwoReturnValues(BUFFER_B, B_ACTION_SWITCH, 0);
|
||||||
@ -350,7 +349,7 @@ static bool8 FindMonWithFlagsAndSuperEffective(u16 flags, u8 moduloPercent)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
if (gLastHitBy[gActiveBattler] == 0xFF)
|
if (gLastHitBy[gActiveBattler] == 0xFF)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (gBattleMoves[gLastLandedMoves[gActiveBattler]].power == 0)
|
if (IS_MOVE_STATUS(gLastLandedMoves[gActiveBattler]))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
|
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "battle.h"
|
#include "battle.h"
|
||||||
#include "battle_anim.h"
|
#include "battle_anim.h"
|
||||||
|
#include "battle_interface.h"
|
||||||
#include "bg.h"
|
#include "bg.h"
|
||||||
#include "contest.h"
|
#include "contest.h"
|
||||||
#include "data.h"
|
#include "data.h"
|
||||||
@ -134,10 +135,10 @@ u8 GetBattlerSpriteCoord(u8 battlerId, u8 coordType)
|
|||||||
{
|
{
|
||||||
case BATTLER_COORD_X:
|
case BATTLER_COORD_X:
|
||||||
case BATTLER_COORD_X_2:
|
case BATTLER_COORD_X_2:
|
||||||
retVal = sBattlerCoords[IS_DOUBLE_BATTLE()][GetBattlerPosition(battlerId)].x;
|
retVal = sBattlerCoords[WhichBattleCoords(battlerId)][GetBattlerPosition(battlerId)].x;
|
||||||
break;
|
break;
|
||||||
case BATTLER_COORD_Y:
|
case BATTLER_COORD_Y:
|
||||||
retVal = sBattlerCoords[IS_DOUBLE_BATTLE()][GetBattlerPosition(battlerId)].y;
|
retVal = sBattlerCoords[WhichBattleCoords(battlerId)][GetBattlerPosition(battlerId)].y;
|
||||||
break;
|
break;
|
||||||
case BATTLER_COORD_Y_PIC_OFFSET:
|
case BATTLER_COORD_Y_PIC_OFFSET:
|
||||||
case BATTLER_COORD_Y_PIC_OFFSET_DEFAULT:
|
case BATTLER_COORD_Y_PIC_OFFSET_DEFAULT:
|
||||||
@ -278,7 +279,7 @@ u8 GetBattlerSpriteFinal_Y(u8 battlerId, u16 species, bool8 a3)
|
|||||||
offset = GetBattlerYDelta(battlerId, species);
|
offset = GetBattlerYDelta(battlerId, species);
|
||||||
offset -= GetBattlerElevation(battlerId, species);
|
offset -= GetBattlerElevation(battlerId, species);
|
||||||
}
|
}
|
||||||
y = offset + sBattlerCoords[IS_DOUBLE_BATTLE()][GetBattlerPosition(battlerId)].y;
|
y = offset + sBattlerCoords[WhichBattleCoords(battlerId)][GetBattlerPosition(battlerId)].y;
|
||||||
if (a3)
|
if (a3)
|
||||||
{
|
{
|
||||||
if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
|
if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
|
||||||
@ -493,7 +494,7 @@ static void TranslateSpriteInWavePattern(struct Sprite *sprite)
|
|||||||
sprite->y2 = Cos(sprite->sCirclePosY, sprite->sAmplitude);
|
sprite->y2 = Cos(sprite->sCirclePosY, sprite->sAmplitude);
|
||||||
sprite->sCirclePosX += sprite->sCircleSpeedX;
|
sprite->sCirclePosX += sprite->sCircleSpeedX;
|
||||||
sprite->sCirclePosY += sprite->sCircleSpeedY;
|
sprite->sCirclePosY += sprite->sCircleSpeedY;
|
||||||
|
|
||||||
if (sprite->sCirclePosX >= 0x100)
|
if (sprite->sCirclePosX >= 0x100)
|
||||||
sprite->sCirclePosX -= 0x100;
|
sprite->sCirclePosX -= 0x100;
|
||||||
else if (sprite->sCirclePosX < 0)
|
else if (sprite->sCirclePosX < 0)
|
||||||
@ -2149,8 +2150,7 @@ u8 CreateAdditionalMonSpriteForMoveAnim(u16 species, bool8 isBackpic, u8 id, s16
|
|||||||
if (!isBackpic)
|
if (!isBackpic)
|
||||||
{
|
{
|
||||||
LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(species, trainerId, personality), (palette * 0x10) + 0x100, 0x20);
|
LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(species, trainerId, personality), (palette * 0x10) + 0x100, 0x20);
|
||||||
LoadSpecialPokePic(&gMonFrontPicTable[species],
|
LoadSpecialPokePic(gMonSpritesGfxPtr->buffer,
|
||||||
gMonSpritesGfxPtr->buffer,
|
|
||||||
species,
|
species,
|
||||||
personality,
|
personality,
|
||||||
TRUE);
|
TRUE);
|
||||||
@ -2158,8 +2158,7 @@ u8 CreateAdditionalMonSpriteForMoveAnim(u16 species, bool8 isBackpic, u8 id, s16
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(species, trainerId, personality), (palette * 0x10) + 0x100, 0x20);
|
LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(species, trainerId, personality), (palette * 0x10) + 0x100, 0x20);
|
||||||
LoadSpecialPokePic(&gMonBackPicTable[species],
|
LoadSpecialPokePic(gMonSpritesGfxPtr->buffer,
|
||||||
gMonSpritesGfxPtr->buffer,
|
|
||||||
species,
|
species,
|
||||||
personality,
|
personality,
|
||||||
FALSE);
|
FALSE);
|
||||||
@ -2445,7 +2444,7 @@ void AnimTask_AttackerPunchWithTrace(u8 taskId)
|
|||||||
|
|
||||||
dest = (task->tPaletteNum + 16) * 16;
|
dest = (task->tPaletteNum + 16) * 16;
|
||||||
src = (gSprites[task->tBattlerSpriteId].oam.paletteNum + 0x10) * 0x10;
|
src = (gSprites[task->tBattlerSpriteId].oam.paletteNum + 0x10) * 0x10;
|
||||||
|
|
||||||
// Set trace's priority based on battler's subpriority
|
// Set trace's priority based on battler's subpriority
|
||||||
task->tPriority = GetBattlerSpriteSubpriority(gBattleAnimAttacker);
|
task->tPriority = GetBattlerSpriteSubpriority(gBattleAnimAttacker);
|
||||||
if (task->tPriority == 20 || task->tPriority == 40)
|
if (task->tPriority == 20 || task->tPriority == 40)
|
||||||
|
@ -2747,7 +2747,7 @@ static int GetTypeEffectivenessPoints(int move, int targetSpecies, int mode)
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
int typePower = TYPE_x1;
|
int typePower = TYPE_x1;
|
||||||
|
|
||||||
if (move == MOVE_NONE || move == MOVE_UNAVAILABLE || gBattleMoves[move].power == 0)
|
if (move == MOVE_NONE || move == MOVE_UNAVAILABLE || IS_MOVE_STATUS(move))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
defType1 = gBaseStats[targetSpecies].type1;
|
defType1 = gBaseStats[targetSpecies].type1;
|
||||||
|
@ -282,7 +282,7 @@ static u8 GetBattlePalaceMoveGroup(u8 battlerId, u16 move)
|
|||||||
case MOVE_TARGET_RANDOM:
|
case MOVE_TARGET_RANDOM:
|
||||||
case MOVE_TARGET_BOTH:
|
case MOVE_TARGET_BOTH:
|
||||||
case MOVE_TARGET_FOES_AND_ALLY:
|
case MOVE_TARGET_FOES_AND_ALLY:
|
||||||
if (gBattleMoves[move].power == 0)
|
if (IS_MOVE_STATUS(move))
|
||||||
return PALACE_MOVE_GROUP_SUPPORT;
|
return PALACE_MOVE_GROUP_SUPPORT;
|
||||||
else
|
else
|
||||||
return PALACE_MOVE_GROUP_ATTACK;
|
return PALACE_MOVE_GROUP_ATTACK;
|
||||||
@ -578,13 +578,13 @@ static void BattleLoadMonSpriteGfx(struct Pokemon *mon, u32 battlerId, bool32 op
|
|||||||
position = GetBattlerPosition(battlerId);
|
position = GetBattlerPosition(battlerId);
|
||||||
if (opponent)
|
if (opponent)
|
||||||
{
|
{
|
||||||
HandleLoadSpecialPokePic(&gMonFrontPicTable[species],
|
HandleLoadSpecialPokePic(TRUE,
|
||||||
gMonSpritesGfxPtr->sprites.ptr[position],
|
gMonSpritesGfxPtr->sprites.ptr[position],
|
||||||
species, currentPersonality);
|
species, currentPersonality);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HandleLoadSpecialPokePic(&gMonBackPicTable[species],
|
HandleLoadSpecialPokePic(FALSE,
|
||||||
gMonSpritesGfxPtr->sprites.ptr[position],
|
gMonSpritesGfxPtr->sprites.ptr[position],
|
||||||
species, currentPersonality);
|
species, currentPersonality);
|
||||||
}
|
}
|
||||||
@ -715,7 +715,12 @@ bool8 BattleLoadAllHealthBoxesGfx(u8 state)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (state == 2)
|
if (state == 2)
|
||||||
LoadCompressedSpriteSheet(&sSpriteSheets_DoublesPlayerHealthbox[0]);
|
{
|
||||||
|
if (WhichBattleCoords(0))
|
||||||
|
LoadCompressedSpriteSheet(&sSpriteSheets_DoublesPlayerHealthbox[0]);
|
||||||
|
else
|
||||||
|
LoadCompressedSpriteSheet(&sSpriteSheet_SinglesPlayerHealthbox);
|
||||||
|
}
|
||||||
else if (state == 3)
|
else if (state == 3)
|
||||||
LoadCompressedSpriteSheet(&sSpriteSheets_DoublesPlayerHealthbox[1]);
|
LoadCompressedSpriteSheet(&sSpriteSheets_DoublesPlayerHealthbox[1]);
|
||||||
else if (state == 4)
|
else if (state == 4)
|
||||||
@ -860,7 +865,7 @@ void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool8 castform, bo
|
|||||||
personalityValue = gContestResources->moveAnim->personality;
|
personalityValue = gContestResources->moveAnim->personality;
|
||||||
otId = gContestResources->moveAnim->otId;
|
otId = gContestResources->moveAnim->otId;
|
||||||
|
|
||||||
HandleLoadSpecialPokePic(&gMonBackPicTable[targetSpecies],
|
HandleLoadSpecialPokePic(FALSE,
|
||||||
gMonSpritesGfxPtr->sprites.ptr[position],
|
gMonSpritesGfxPtr->sprites.ptr[position],
|
||||||
targetSpecies,
|
targetSpecies,
|
||||||
gContestResources->moveAnim->targetPersonality);
|
gContestResources->moveAnim->targetPersonality);
|
||||||
@ -879,7 +884,7 @@ void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool8 castform, bo
|
|||||||
personalityValue = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_PERSONALITY);
|
personalityValue = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_PERSONALITY);
|
||||||
otId = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_OT_ID);
|
otId = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_OT_ID);
|
||||||
|
|
||||||
HandleLoadSpecialPokePic(&gMonBackPicTable[targetSpecies],
|
HandleLoadSpecialPokePic(FALSE,
|
||||||
gMonSpritesGfxPtr->sprites.ptr[position],
|
gMonSpritesGfxPtr->sprites.ptr[position],
|
||||||
targetSpecies,
|
targetSpecies,
|
||||||
gTransformedPersonalities[battlerAtk]);
|
gTransformedPersonalities[battlerAtk]);
|
||||||
@ -889,7 +894,7 @@ void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool8 castform, bo
|
|||||||
personalityValue = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_PERSONALITY);
|
personalityValue = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_PERSONALITY);
|
||||||
otId = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_OT_ID);
|
otId = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_OT_ID);
|
||||||
|
|
||||||
HandleLoadSpecialPokePic(&gMonFrontPicTable[targetSpecies],
|
HandleLoadSpecialPokePic(TRUE,
|
||||||
gMonSpritesGfxPtr->sprites.ptr[position],
|
gMonSpritesGfxPtr->sprites.ptr[position],
|
||||||
targetSpecies,
|
targetSpecies,
|
||||||
gTransformedPersonalities[battlerAtk]);
|
gTransformedPersonalities[battlerAtk]);
|
||||||
|
@ -764,6 +764,15 @@ static void InitLastUsedBallAssets(void)
|
|||||||
gBattleStruct->ballSpriteIds[1] = MAX_SPRITES;
|
gBattleStruct->ballSpriteIds[1] = MAX_SPRITES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This function is here to cover a specific case - one player's mon in a 2 vs 1 double battle. In this scenario - display singles layout.
|
||||||
|
u32 WhichBattleCoords(u32 battlerId) // 0 - singles, 1 - doubles
|
||||||
|
{
|
||||||
|
if (GetBattlerPosition(battlerId) == B_POSITION_PLAYER_LEFT && gPlayerPartyCount == 1)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return IsDoubleBattle();
|
||||||
|
}
|
||||||
|
|
||||||
u8 CreateBattlerHealthboxSprites(u8 battlerId)
|
u8 CreateBattlerHealthboxSprites(u8 battlerId)
|
||||||
{
|
{
|
||||||
s16 data6 = 0;
|
s16 data6 = 0;
|
||||||
@ -771,7 +780,7 @@ u8 CreateBattlerHealthboxSprites(u8 battlerId)
|
|||||||
u8 healthbarSpriteId, megaIndicatorSpriteId;
|
u8 healthbarSpriteId, megaIndicatorSpriteId;
|
||||||
struct Sprite *healthBarSpritePtr;
|
struct Sprite *healthBarSpritePtr;
|
||||||
|
|
||||||
if (!IsDoubleBattle())
|
if (WhichBattleCoords(battlerId) == 0) // Singles
|
||||||
{
|
{
|
||||||
if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
|
if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
|
||||||
{
|
{
|
||||||
@ -1035,7 +1044,7 @@ void GetBattlerHealthboxCoords(u8 battler, s16 *x, s16 *y)
|
|||||||
{
|
{
|
||||||
*x = 0, *y = 0;
|
*x = 0, *y = 0;
|
||||||
|
|
||||||
if (!IsDoubleBattle())
|
if (!WhichBattleCoords(battler))
|
||||||
{
|
{
|
||||||
if (GetBattlerSide(battler) != B_SIDE_PLAYER)
|
if (GetBattlerSide(battler) != B_SIDE_PLAYER)
|
||||||
*x = 44, *y = 30;
|
*x = 44, *y = 30;
|
||||||
@ -1102,7 +1111,7 @@ static void UpdateLvlInHealthbox(u8 healthboxSpriteId, u8 lvl)
|
|||||||
if (GetBattlerSide(battler) == B_SIDE_PLAYER)
|
if (GetBattlerSide(battler) == B_SIDE_PLAYER)
|
||||||
{
|
{
|
||||||
objVram = (void *)(OBJ_VRAM0);
|
objVram = (void *)(OBJ_VRAM0);
|
||||||
if (!IsDoubleBattle())
|
if (!WhichBattleCoords(battler))
|
||||||
objVram += spriteTileNum + 0x820;
|
objVram += spriteTileNum + 0x820;
|
||||||
else
|
else
|
||||||
objVram += spriteTileNum + 0x420;
|
objVram += spriteTileNum + 0x420;
|
||||||
@ -1219,13 +1228,14 @@ static void UpdateOpponentHpTextSingles(u32 healthboxSpriteId, s16 value, u32 ma
|
|||||||
|
|
||||||
void UpdateHpTextInHealthbox(u32 healthboxSpriteId, u32 maxOrCurrent, s16 currHp, s16 maxHp)
|
void UpdateHpTextInHealthbox(u32 healthboxSpriteId, u32 maxOrCurrent, s16 currHp, s16 maxHp)
|
||||||
{
|
{
|
||||||
if (IsDoubleBattle())
|
u32 battlerId = gSprites[healthboxSpriteId].hMain_Battler;
|
||||||
|
if (WhichBattleCoords(battlerId))
|
||||||
{
|
{
|
||||||
UpdateHpTextInHealthboxInDoubles(healthboxSpriteId, maxOrCurrent, currHp, maxHp);
|
UpdateHpTextInHealthboxInDoubles(healthboxSpriteId, maxOrCurrent, currHp, maxHp);
|
||||||
}
|
}
|
||||||
else // Single Battle
|
else // Single Battle
|
||||||
{
|
{
|
||||||
if (GetBattlerSide(gSprites[healthboxSpriteId].hMain_Battler) == B_SIDE_PLAYER) // Player
|
if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) // Player
|
||||||
{
|
{
|
||||||
PrintHpOnHealthbox(healthboxSpriteId, currHp, maxHp, 2, 0xB00, 0x3A0);
|
PrintHpOnHealthbox(healthboxSpriteId, currHp, maxHp, 2, 0xB00, 0x3A0);
|
||||||
}
|
}
|
||||||
@ -1334,7 +1344,7 @@ void SwapHpBarsWithHpText(void)
|
|||||||
{
|
{
|
||||||
if (gSprites[gHealthboxSpriteIds[i]].callback == SpriteCallbackDummy
|
if (gSprites[gHealthboxSpriteIds[i]].callback == SpriteCallbackDummy
|
||||||
&& GetBattlerSide(i) != B_SIDE_OPPONENT
|
&& GetBattlerSide(i) != B_SIDE_OPPONENT
|
||||||
&& (IsDoubleBattle() || GetBattlerSide(i) != B_SIDE_PLAYER))
|
&& (WhichBattleCoords(i) || GetBattlerSide(i) != B_SIDE_PLAYER))
|
||||||
{
|
{
|
||||||
s32 currHp = GetMonData(&gPlayerParty[gBattlerPartyIndexes[i]], MON_DATA_HP);
|
s32 currHp = GetMonData(&gPlayerParty[gBattlerPartyIndexes[i]], MON_DATA_HP);
|
||||||
s32 maxHp = GetMonData(&gPlayerParty[gBattlerPartyIndexes[i]], MON_DATA_MAX_HP);
|
s32 maxHp = GetMonData(&gPlayerParty[gBattlerPartyIndexes[i]], MON_DATA_MAX_HP);
|
||||||
@ -1344,7 +1354,7 @@ void SwapHpBarsWithHpText(void)
|
|||||||
noBars = gBattleSpritesDataPtr->battlerData[i].hpNumbersNoBars;
|
noBars = gBattleSpritesDataPtr->battlerData[i].hpNumbersNoBars;
|
||||||
if (GetBattlerSide(i) == B_SIDE_PLAYER)
|
if (GetBattlerSide(i) == B_SIDE_PLAYER)
|
||||||
{
|
{
|
||||||
if (!IsDoubleBattle())
|
if (!WhichBattleCoords(i))
|
||||||
continue;
|
continue;
|
||||||
if (gBattleTypeFlags & BATTLE_TYPE_SAFARI)
|
if (gBattleTypeFlags & BATTLE_TYPE_SAFARI)
|
||||||
continue;
|
continue;
|
||||||
@ -1638,7 +1648,7 @@ u8 CreatePartyStatusSummarySprites(u8 battlerId, struct HpAndStatus *partyInfo,
|
|||||||
{
|
{
|
||||||
isOpponent = TRUE;
|
isOpponent = TRUE;
|
||||||
|
|
||||||
if (!skipPlayer || !IsDoubleBattle())
|
if (!skipPlayer || !WhichBattleCoords(battlerId))
|
||||||
bar_X = 104, bar_Y = 40;
|
bar_X = 104, bar_Y = 40;
|
||||||
else
|
else
|
||||||
bar_X = 104, bar_Y = 16;
|
bar_X = 104, bar_Y = 16;
|
||||||
@ -2124,7 +2134,7 @@ static void UpdateNickInHealthbox(u8 healthboxSpriteId, struct Pokemon *mon)
|
|||||||
{
|
{
|
||||||
TextIntoHealthboxObject((void *)(OBJ_VRAM0 + 0x40 + spriteTileNum), windowTileData, 6);
|
TextIntoHealthboxObject((void *)(OBJ_VRAM0 + 0x40 + spriteTileNum), windowTileData, 6);
|
||||||
ptr = (void *)(OBJ_VRAM0);
|
ptr = (void *)(OBJ_VRAM0);
|
||||||
if (!IsDoubleBattle())
|
if (!WhichBattleCoords(gSprites[healthboxSpriteId].data[6]))
|
||||||
ptr += spriteTileNum + 0x800;
|
ptr += spriteTileNum + 0x800;
|
||||||
else
|
else
|
||||||
ptr += spriteTileNum + 0x400;
|
ptr += spriteTileNum + 0x400;
|
||||||
@ -2175,7 +2185,7 @@ static void UpdateStatusIconInHealthbox(u8 healthboxSpriteId)
|
|||||||
if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
|
if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
|
||||||
{
|
{
|
||||||
status = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_STATUS);
|
status = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_STATUS);
|
||||||
if (!IsDoubleBattle())
|
if (!WhichBattleCoords(battlerId))
|
||||||
tileNumAdder = 0x1A;
|
tileNumAdder = 0x1A;
|
||||||
else
|
else
|
||||||
tileNumAdder = 0x12;
|
tileNumAdder = 0x12;
|
||||||
@ -2231,7 +2241,7 @@ static void UpdateStatusIconInHealthbox(u8 healthboxSpriteId)
|
|||||||
FillPalette(sStatusIconColors[statusPalId], pltAdder + 0x100, 2);
|
FillPalette(sStatusIconColors[statusPalId], pltAdder + 0x100, 2);
|
||||||
CpuCopy16(gPlttBufferUnfaded + 0x100 + pltAdder, (void *)(OBJ_PLTT + pltAdder * 2), 2);
|
CpuCopy16(gPlttBufferUnfaded + 0x100 + pltAdder, (void *)(OBJ_PLTT + pltAdder * 2), 2);
|
||||||
CpuCopy32(statusGfxPtr, (void *)(OBJ_VRAM0 + (gSprites[healthboxSpriteId].oam.tileNum + tileNumAdder) * TILE_SIZE_4BPP), 96);
|
CpuCopy32(statusGfxPtr, (void *)(OBJ_VRAM0 + (gSprites[healthboxSpriteId].oam.tileNum + tileNumAdder) * TILE_SIZE_4BPP), 96);
|
||||||
if (IsDoubleBattle() == TRUE || GetBattlerSide(battlerId) == B_SIDE_OPPONENT)
|
if (WhichBattleCoords(battlerId) == 1 || GetBattlerSide(battlerId) == B_SIDE_OPPONENT)
|
||||||
{
|
{
|
||||||
if (!gBattleSpritesDataPtr->battlerData[battlerId].hpNumbersNoBars)
|
if (!gBattleSpritesDataPtr->battlerData[battlerId].hpNumbersNoBars)
|
||||||
{
|
{
|
||||||
@ -2339,7 +2349,7 @@ void UpdateHealthboxAttribute(u8 healthboxSpriteId, struct Pokemon *mon, u8 elem
|
|||||||
|
|
||||||
if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
|
if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
|
||||||
{
|
{
|
||||||
u8 isDoubles = IsDoubleBattle();
|
u8 isDoubles = WhichBattleCoords(battlerId);
|
||||||
|
|
||||||
if (elementId == HEALTHBOX_LEVEL || elementId == HEALTHBOX_ALL)
|
if (elementId == HEALTHBOX_LEVEL || elementId == HEALTHBOX_ALL)
|
||||||
UpdateLvlInHealthbox(healthboxSpriteId, GetMonData(mon, MON_DATA_LEVEL));
|
UpdateLvlInHealthbox(healthboxSpriteId, GetMonData(mon, MON_DATA_LEVEL));
|
||||||
@ -2886,7 +2896,7 @@ static void TextIntoAbilityPopUp(void *dest, u8 *windowTileData, s32 arg2, bool3
|
|||||||
|
|
||||||
#define MAX_CHARS_PRINTED 12
|
#define MAX_CHARS_PRINTED 12
|
||||||
|
|
||||||
static void PrintOnAbilityPopUp(const u8 *str, u8 *spriteTileData1, u8 *spriteTileData2, u32 x1, u32 x2, u32 y, u32 color1, u32 color2, u32 color3)
|
static void PrintOnAbilityPopUp(const u8 *str, u8 *spriteTileData1, u8 *spriteTileData2, u32 x1, u32 x2, u32 y, u32 color1, u32 color2, u32 color3, bool32 alignAbilityChars)
|
||||||
{
|
{
|
||||||
u32 windowId, i;
|
u32 windowId, i;
|
||||||
u8 *windowTileData;
|
u8 *windowTileData;
|
||||||
@ -2901,6 +2911,15 @@ static void PrintOnAbilityPopUp(const u8 *str, u8 *spriteTileData1, u8 *spriteTi
|
|||||||
}
|
}
|
||||||
text1[i] = EOS;
|
text1[i] = EOS;
|
||||||
|
|
||||||
|
// Because there are two Windows, we need to align the strings, so that the first char in the second window starts right after the last char in the first window.
|
||||||
|
// Windows are 64 pixels in width.
|
||||||
|
if (alignAbilityChars && i == MAX_CHARS_PRINTED)
|
||||||
|
{
|
||||||
|
u32 width = GetStringWidth(FONT_SMALL, text1, 0);
|
||||||
|
if (x1 + width < 64)
|
||||||
|
x1 += 64 - (x1 + width);
|
||||||
|
}
|
||||||
|
|
||||||
windowTileData = AddTextPrinterAndCreateWindowOnAbilityPopUp(text1, x1, y, color1, color2, color3, &windowId);
|
windowTileData = AddTextPrinterAndCreateWindowOnAbilityPopUp(text1, x1, y, color1, color2, color3, &windowId);
|
||||||
TextIntoAbilityPopUp(spriteTileData1, windowTileData, 8, (y == 0));
|
TextIntoAbilityPopUp(spriteTileData1, windowTileData, 8, (y == 0));
|
||||||
RemoveWindow(windowId);
|
RemoveWindow(windowId);
|
||||||
@ -2929,7 +2948,8 @@ static void ClearAbilityName(u8 spriteId1, u8 spriteId2)
|
|||||||
(void*)(OBJ_VRAM0) + (gSprites[spriteId2].oam.tileNum * 32) + 256,
|
(void*)(OBJ_VRAM0) + (gSprites[spriteId2].oam.tileNum * 32) + 256,
|
||||||
6, 1,
|
6, 1,
|
||||||
4,
|
4,
|
||||||
7, 9, 1);
|
7, 9, 1,
|
||||||
|
FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PrintBattlerOnAbilityPopUp(u8 battlerId, u8 spriteId1, u8 spriteId2)
|
static void PrintBattlerOnAbilityPopUp(u8 battlerId, u8 spriteId1, u8 spriteId2)
|
||||||
@ -2966,7 +2986,8 @@ static void PrintBattlerOnAbilityPopUp(u8 battlerId, u8 spriteId1, u8 spriteId2)
|
|||||||
(void*)(OBJ_VRAM0) + (gSprites[spriteId2].oam.tileNum * 32),
|
(void*)(OBJ_VRAM0) + (gSprites[spriteId2].oam.tileNum * 32),
|
||||||
7, 0,
|
7, 0,
|
||||||
0,
|
0,
|
||||||
2, 7, 1);
|
2, 7, 1,
|
||||||
|
FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PrintAbilityOnAbilityPopUp(u32 ability, u8 spriteId1, u8 spriteId2)
|
static void PrintAbilityOnAbilityPopUp(u32 ability, u8 spriteId1, u8 spriteId2)
|
||||||
@ -2974,9 +2995,10 @@ static void PrintAbilityOnAbilityPopUp(u32 ability, u8 spriteId1, u8 spriteId2)
|
|||||||
PrintOnAbilityPopUp(gAbilityNames[ability],
|
PrintOnAbilityPopUp(gAbilityNames[ability],
|
||||||
(void*)(OBJ_VRAM0) + (gSprites[spriteId1].oam.tileNum * 32) + 256,
|
(void*)(OBJ_VRAM0) + (gSprites[spriteId1].oam.tileNum * 32) + 256,
|
||||||
(void*)(OBJ_VRAM0) + (gSprites[spriteId2].oam.tileNum * 32) + 256,
|
(void*)(OBJ_VRAM0) + (gSprites[spriteId2].oam.tileNum * 32) + 256,
|
||||||
6, 1,
|
6, 0,
|
||||||
4,
|
4,
|
||||||
7, 9, 1);
|
7, 9, 1,
|
||||||
|
TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PIXEL_COORDS_TO_OFFSET(x, y)( \
|
#define PIXEL_COORDS_TO_OFFSET(x, y)( \
|
||||||
|
@ -2981,10 +2981,10 @@ static void BattleStartClearSetData(void)
|
|||||||
gBattleStruct->arenaLostOpponentMons = 0;
|
gBattleStruct->arenaLostOpponentMons = 0;
|
||||||
|
|
||||||
gBattleStruct->mega.triggerSpriteId = 0xFF;
|
gBattleStruct->mega.triggerSpriteId = 0xFF;
|
||||||
|
|
||||||
gBattleStruct->stickyWebUser = 0xFF;
|
gBattleStruct->stickyWebUser = 0xFF;
|
||||||
gBattleStruct->appearedInBattle = 0;
|
gBattleStruct->appearedInBattle = 0;
|
||||||
|
|
||||||
for (i = 0; i < PARTY_SIZE; i++)
|
for (i = 0; i < PARTY_SIZE; i++)
|
||||||
{
|
{
|
||||||
gBattleStruct->usedHeldItems[i][0] = 0;
|
gBattleStruct->usedHeldItems[i][0] = 0;
|
||||||
@ -3084,7 +3084,7 @@ void SwitchInClearSetData(void)
|
|||||||
gBattleStruct->lastTakenMoveFrom[gActiveBattler][3] = 0;
|
gBattleStruct->lastTakenMoveFrom[gActiveBattler][3] = 0;
|
||||||
gBattleStruct->lastMoveFailed &= ~(gBitTable[gActiveBattler]);
|
gBattleStruct->lastMoveFailed &= ~(gBitTable[gActiveBattler]);
|
||||||
gBattleStruct->palaceFlags &= ~(gBitTable[gActiveBattler]);
|
gBattleStruct->palaceFlags &= ~(gBitTable[gActiveBattler]);
|
||||||
|
|
||||||
if (gActiveBattler == gBattleStruct->stickyWebUser)
|
if (gActiveBattler == gBattleStruct->stickyWebUser)
|
||||||
gBattleStruct->stickyWebUser = 0xFF; // Switched into sticky web user slot so reset it
|
gBattleStruct->stickyWebUser = 0xFF; // Switched into sticky web user slot so reset it
|
||||||
|
|
||||||
@ -3100,7 +3100,7 @@ void SwitchInClearSetData(void)
|
|||||||
gBattleResources->flags->flags[gActiveBattler] = 0;
|
gBattleResources->flags->flags[gActiveBattler] = 0;
|
||||||
gCurrentMove = MOVE_NONE;
|
gCurrentMove = MOVE_NONE;
|
||||||
gBattleStruct->arenaTurnCounter = 0xFF;
|
gBattleStruct->arenaTurnCounter = 0xFF;
|
||||||
|
|
||||||
// Reset damage to prevent things like red card activating if the switched-in mon is holding it
|
// Reset damage to prevent things like red card activating if the switched-in mon is holding it
|
||||||
gSpecialStatuses[gActiveBattler].physicalDmg = 0;
|
gSpecialStatuses[gActiveBattler].physicalDmg = 0;
|
||||||
gSpecialStatuses[gActiveBattler].specialDmg = 0;
|
gSpecialStatuses[gActiveBattler].specialDmg = 0;
|
||||||
@ -3184,7 +3184,7 @@ void FaintClearSetData(void)
|
|||||||
gBattleStruct->lastTakenMoveFrom[gActiveBattler][3] = 0;
|
gBattleStruct->lastTakenMoveFrom[gActiveBattler][3] = 0;
|
||||||
|
|
||||||
gBattleStruct->palaceFlags &= ~(gBitTable[gActiveBattler]);
|
gBattleStruct->palaceFlags &= ~(gBitTable[gActiveBattler]);
|
||||||
|
|
||||||
if (gActiveBattler == gBattleStruct->stickyWebUser)
|
if (gActiveBattler == gBattleStruct->stickyWebUser)
|
||||||
gBattleStruct->stickyWebUser = 0xFF; // User of sticky web fainted, so reset the stored battler ID
|
gBattleStruct->stickyWebUser = 0xFF; // User of sticky web fainted, so reset the stored battler ID
|
||||||
|
|
||||||
@ -3342,7 +3342,7 @@ static void DoBattleIntro(void)
|
|||||||
MarkBattlerForControllerExec(gActiveBattler);
|
MarkBattlerForControllerExec(gActiveBattler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // wild mon 2
|
else if (IsBattlerAlive(gActiveBattler)) // wild mon 2 if alive
|
||||||
{
|
{
|
||||||
BtlController_EmitLoadMonSprite(BUFFER_A);
|
BtlController_EmitLoadMonSprite(BUFFER_A);
|
||||||
MarkBattlerForControllerExec(gActiveBattler);
|
MarkBattlerForControllerExec(gActiveBattler);
|
||||||
@ -3696,7 +3696,7 @@ static void TryDoEventsBeforeFirstTurn(void)
|
|||||||
gMoveResultFlags = 0;
|
gMoveResultFlags = 0;
|
||||||
|
|
||||||
gRandomTurnNumber = Random();
|
gRandomTurnNumber = Random();
|
||||||
|
|
||||||
GetAiLogicData(); // get assumed abilities, hold effects, etc of all battlers
|
GetAiLogicData(); // get assumed abilities, hold effects, etc of all battlers
|
||||||
|
|
||||||
if (gBattleTypeFlags & BATTLE_TYPE_ARENA)
|
if (gBattleTypeFlags & BATTLE_TYPE_ARENA)
|
||||||
@ -3904,7 +3904,7 @@ static void HandleTurnActionSelectionState(void)
|
|||||||
case STATE_TURN_START_RECORD: // Recorded battle related action on start of every turn.
|
case STATE_TURN_START_RECORD: // Recorded battle related action on start of every turn.
|
||||||
RecordedBattle_CopyBattlerMoves();
|
RecordedBattle_CopyBattlerMoves();
|
||||||
gBattleCommunication[gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN;
|
gBattleCommunication[gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN;
|
||||||
|
|
||||||
// Do AI score computations here so we can use them in AI_TrySwitchOrUseItem
|
// Do AI score computations here so we can use them in AI_TrySwitchOrUseItem
|
||||||
if ((gBattleTypeFlags & BATTLE_TYPE_HAS_AI || IsWildMonSmart()) && IsBattlerAIControlled(gActiveBattler)) {
|
if ((gBattleTypeFlags & BATTLE_TYPE_HAS_AI || IsWildMonSmart()) && IsBattlerAIControlled(gActiveBattler)) {
|
||||||
gBattleStruct->aiMoveOrAction[gActiveBattler] = ComputeBattleAiScores(gActiveBattler);
|
gBattleStruct->aiMoveOrAction[gActiveBattler] = ComputeBattleAiScores(gActiveBattler);
|
||||||
@ -4564,7 +4564,7 @@ u8 GetWhoStrikesFirst(u8 battler1, u8 battler2, bool8 ignoreChosenMoves)
|
|||||||
// QUICK CLAW / CUSTAP - always first
|
// QUICK CLAW / CUSTAP - always first
|
||||||
// LAGGING TAIL - always last
|
// LAGGING TAIL - always last
|
||||||
// STALL - always last
|
// STALL - always last
|
||||||
|
|
||||||
if (gProtectStructs[battler1].quickDraw && !gProtectStructs[battler2].quickDraw)
|
if (gProtectStructs[battler1].quickDraw && !gProtectStructs[battler2].quickDraw)
|
||||||
strikesFirst = 0;
|
strikesFirst = 0;
|
||||||
else if (!gProtectStructs[battler1].quickDraw && gProtectStructs[battler2].quickDraw)
|
else if (!gProtectStructs[battler1].quickDraw && gProtectStructs[battler2].quickDraw)
|
||||||
|
@ -1345,7 +1345,7 @@ static bool32 TryAegiFormChange(void)
|
|||||||
default:
|
default:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
case SPECIES_AEGISLASH: // Shield -> Blade
|
case SPECIES_AEGISLASH: // Shield -> Blade
|
||||||
if (gBattleMoves[gCurrentMove].power == 0)
|
if (IS_MOVE_STATUS(gCurrentMove))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
gBattleMons[gBattlerAttacker].species = SPECIES_AEGISLASH_BLADE;
|
gBattleMons[gBattlerAttacker].species = SPECIES_AEGISLASH_BLADE;
|
||||||
break;
|
break;
|
||||||
@ -1687,7 +1687,7 @@ u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move, u32 atkAbility, u
|
|||||||
&& (gBattleMoves[move].effect == EFFECT_THUNDER || gBattleMoves[move].effect == EFFECT_HURRICANE))
|
&& (gBattleMoves[move].effect == EFFECT_THUNDER || gBattleMoves[move].effect == EFFECT_HURRICANE))
|
||||||
moveAcc = 50;
|
moveAcc = 50;
|
||||||
// Check Wonder Skin.
|
// Check Wonder Skin.
|
||||||
if (defAbility == ABILITY_WONDER_SKIN && gBattleMoves[move].power == 0)
|
if (defAbility == ABILITY_WONDER_SKIN && IS_MOVE_STATUS(move) && moveAcc > 50)
|
||||||
moveAcc = 50;
|
moveAcc = 50;
|
||||||
|
|
||||||
calc = gAccuracyStageRatios[buff].dividend * moveAcc;
|
calc = gAccuracyStageRatios[buff].dividend * moveAcc;
|
||||||
@ -8395,7 +8395,7 @@ static void Cmd_various(void)
|
|||||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
|
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
|
||||||
else if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget))
|
else if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget))
|
||||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
|
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
|
||||||
else if (gBattleMoves[gBattleMons[gBattlerTarget].moves[gBattleStruct->chosenMovePositions[gBattlerTarget]]].power == 0)
|
else if (IS_MOVE_STATUS(gBattleMons[gBattlerTarget].moves[gBattleStruct->chosenMovePositions[gBattlerTarget]]))
|
||||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
|
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
|
||||||
else
|
else
|
||||||
gBattlescriptCurrInstr += 7;
|
gBattlescriptCurrInstr += 7;
|
||||||
@ -8493,7 +8493,7 @@ static void Cmd_various(void)
|
|||||||
case VARIOUS_TRY_ME_FIRST:
|
case VARIOUS_TRY_ME_FIRST:
|
||||||
if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget))
|
if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget))
|
||||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
|
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
|
||||||
else if (gBattleMoves[gBattleMons[gBattlerTarget].moves[gBattleStruct->chosenMovePositions[gBattlerTarget]]].power == 0)
|
else if (IS_MOVE_STATUS(gBattleMons[gBattlerTarget].moves[gBattleStruct->chosenMovePositions[gBattlerTarget]]))
|
||||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
|
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -10571,19 +10571,20 @@ static void Cmd_setmultihitcounter(void)
|
|||||||
}
|
}
|
||||||
else if (B_MULTI_HIT_CHANCE >= GEN_5)
|
else if (B_MULTI_HIT_CHANCE >= GEN_5)
|
||||||
{
|
{
|
||||||
// 2 and 3 hits: 33.3%
|
// Based on Gen 5's odds
|
||||||
// 4 and 5 hits: 16.7%
|
// 35% for 2 hits
|
||||||
gMultiHitCounter = Random() % 4;
|
// 35% for 3 hits
|
||||||
if (gMultiHitCounter > 2)
|
// 15% for 4 hits
|
||||||
{
|
// 15% for 5 hits
|
||||||
gMultiHitCounter = (Random() % 3);
|
gMultiHitCounter = Random() % 100;
|
||||||
if (gMultiHitCounter < 2)
|
if (gMultiHitCounter < 35)
|
||||||
gMultiHitCounter = 2;
|
gMultiHitCounter = 2;
|
||||||
else
|
else if (gMultiHitCounter < 35 + 35)
|
||||||
gMultiHitCounter = 3;
|
gMultiHitCounter = 3;
|
||||||
}
|
else if (gMultiHitCounter < 35 + 35 + 15)
|
||||||
|
gMultiHitCounter = 4;
|
||||||
else
|
else
|
||||||
gMultiHitCounter += 3;
|
gMultiHitCounter = 5;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -13451,11 +13452,11 @@ bool32 DoesSubstituteBlockMove(u8 battlerAtk, u8 battlerDef, u32 move)
|
|||||||
|
|
||||||
bool32 DoesDisguiseBlockMove(u8 battlerAtk, u8 battlerDef, u32 move)
|
bool32 DoesDisguiseBlockMove(u8 battlerAtk, u8 battlerDef, u32 move)
|
||||||
{
|
{
|
||||||
if (GetBattlerAbility(battlerDef) != ABILITY_DISGUISE
|
if (gBattleMons[battlerDef].species != SPECIES_MIMIKYU
|
||||||
|| gBattleMons[battlerDef].species != SPECIES_MIMIKYU
|
|
||||||
|| gBattleMons[battlerDef].status2 & STATUS2_TRANSFORMED
|
|| gBattleMons[battlerDef].status2 & STATUS2_TRANSFORMED
|
||||||
|| gBattleMoves[move].power == 0
|
|| IS_MOVE_STATUS(move)
|
||||||
|| gHitMarker & HITMARKER_IGNORE_DISGUISE)
|
|| gHitMarker & HITMARKER_IGNORE_DISGUISE
|
||||||
|
|| GetBattlerAbility(battlerDef) != ABILITY_DISGUISE)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
else
|
else
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -13870,13 +13871,13 @@ static void Cmd_handleballthrow(void)
|
|||||||
u8 shakes;
|
u8 shakes;
|
||||||
u8 maxShakes;
|
u8 maxShakes;
|
||||||
|
|
||||||
gBattleSpritesDataPtr->animationData->isCriticalCapture = 0;
|
gBattleSpritesDataPtr->animationData->isCriticalCapture = FALSE;
|
||||||
gBattleSpritesDataPtr->animationData->criticalCaptureSuccess = 0;
|
gBattleSpritesDataPtr->animationData->criticalCaptureSuccess = FALSE;
|
||||||
|
|
||||||
if (CriticalCapture(odds))
|
if (CriticalCapture(odds))
|
||||||
{
|
{
|
||||||
maxShakes = BALL_1_SHAKE; // critical capture doesn't guarantee capture
|
maxShakes = BALL_1_SHAKE; // critical capture doesn't guarantee capture
|
||||||
gBattleSpritesDataPtr->animationData->isCriticalCapture = 1;
|
gBattleSpritesDataPtr->animationData->isCriticalCapture = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -13900,7 +13901,7 @@ static void Cmd_handleballthrow(void)
|
|||||||
if (shakes == maxShakes) // mon caught, copy of the code above
|
if (shakes == maxShakes) // mon caught, copy of the code above
|
||||||
{
|
{
|
||||||
if (IsCriticalCapture())
|
if (IsCriticalCapture())
|
||||||
gBattleSpritesDataPtr->animationData->criticalCaptureSuccess = 1;
|
gBattleSpritesDataPtr->animationData->criticalCaptureSuccess = TRUE;
|
||||||
|
|
||||||
UndoFormChange(gBattlerPartyIndexes[gBattlerTarget], GET_BATTLER_SIDE(gBattlerTarget), FALSE);
|
UndoFormChange(gBattlerPartyIndexes[gBattlerTarget], GET_BATTLER_SIDE(gBattlerTarget), FALSE);
|
||||||
gBattlescriptCurrInstr = BattleScript_SuccessBallThrow;
|
gBattlescriptCurrInstr = BattleScript_SuccessBallThrow;
|
||||||
|
@ -1435,7 +1435,7 @@ static void TrySetBattleSeminarShow(void)
|
|||||||
return;
|
return;
|
||||||
else if (gBattleTypeFlags & (BATTLE_TYPE_PALACE | BATTLE_TYPE_PIKE | BATTLE_TYPE_PYRAMID))
|
else if (gBattleTypeFlags & (BATTLE_TYPE_PALACE | BATTLE_TYPE_PIKE | BATTLE_TYPE_PYRAMID))
|
||||||
return;
|
return;
|
||||||
else if (gBattleMoves[gBattleMons[gBattlerAttacker].moves[gMoveSelectionCursor[gBattlerAttacker]]].power == 0)
|
else if (IS_MOVE_STATUS(gBattleMons[gBattlerAttacker].moves[gMoveSelectionCursor[gBattlerAttacker]]))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
@ -1496,7 +1496,7 @@ static void TrySetBattleSeminarShow(void)
|
|||||||
|
|
||||||
static bool8 ShouldCalculateDamage(u16 moveId, s32 *dmg, u16 *powerOverride)
|
static bool8 ShouldCalculateDamage(u16 moveId, s32 *dmg, u16 *powerOverride)
|
||||||
{
|
{
|
||||||
if (gBattleMoves[moveId].power == 0)
|
if (IS_MOVE_STATUS(moveId))
|
||||||
{
|
{
|
||||||
*dmg = 0;
|
*dmg = 0;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -294,7 +294,7 @@ void HandleAction_UseMove(void)
|
|||||||
{
|
{
|
||||||
gCurrentMove = gChosenMove = gBattleMons[gBattlerAttacker].moves[gCurrMovePos];
|
gCurrentMove = gChosenMove = gBattleMons[gBattlerAttacker].moves[gCurrMovePos];
|
||||||
}
|
}
|
||||||
|
|
||||||
// check z move used
|
// check z move used
|
||||||
if (gBattleStruct->zmove.toBeUsed[gBattlerAttacker] != MOVE_NONE && !IS_MOVE_STATUS(gCurrentMove))
|
if (gBattleStruct->zmove.toBeUsed[gBattlerAttacker] != MOVE_NONE && !IS_MOVE_STATUS(gCurrentMove))
|
||||||
{
|
{
|
||||||
@ -395,7 +395,7 @@ void HandleAction_UseMove(void)
|
|||||||
u16 battlerAbility;
|
u16 battlerAbility;
|
||||||
gActiveBattler = gBattlerByTurnOrder[var];
|
gActiveBattler = gBattlerByTurnOrder[var];
|
||||||
battlerAbility = GetBattlerAbility(gActiveBattler);
|
battlerAbility = GetBattlerAbility(gActiveBattler);
|
||||||
|
|
||||||
RecordAbilityBattle(gActiveBattler, gBattleMons[gActiveBattler].ability);
|
RecordAbilityBattle(gActiveBattler, gBattleMons[gActiveBattler].ability);
|
||||||
if (battlerAbility == ABILITY_LIGHTNING_ROD)
|
if (battlerAbility == ABILITY_LIGHTNING_ROD)
|
||||||
gSpecialStatuses[gActiveBattler].lightningRodRedirected = TRUE;
|
gSpecialStatuses[gActiveBattler].lightningRodRedirected = TRUE;
|
||||||
@ -909,7 +909,7 @@ void HandleAction_ActionFinished(void)
|
|||||||
gBattleCommunication[4] = 0;
|
gBattleCommunication[4] = 0;
|
||||||
gBattleScripting.multihitMoveEffect = 0;
|
gBattleScripting.multihitMoveEffect = 0;
|
||||||
gBattleResources->battleScriptsStack->size = 0;
|
gBattleResources->battleScriptsStack->size = 0;
|
||||||
|
|
||||||
#if B_RECALC_TURN_AFTER_ACTIONS >= GEN_8
|
#if B_RECALC_TURN_AFTER_ACTIONS >= GEN_8
|
||||||
// i starts at `gCurrentTurnActionNumber` because we don't want to recalculate turn order for mon that have already
|
// i starts at `gCurrentTurnActionNumber` because we don't want to recalculate turn order for mon that have already
|
||||||
// taken action. It's been previously increased, which we want in order to not recalculate the turn of the mon that just finished its action
|
// taken action. It's been previously increased, which we want in order to not recalculate the turn of the mon that just finished its action
|
||||||
@ -930,7 +930,7 @@ void HandleAction_ActionFinished(void)
|
|||||||
{
|
{
|
||||||
if (GetWhoStrikesFirst(battler1, battler2, TRUE)) // If the actions chosen are switching, we recalc order but ignoring the moves
|
if (GetWhoStrikesFirst(battler1, battler2, TRUE)) // If the actions chosen are switching, we recalc order but ignoring the moves
|
||||||
SwapTurnOrder(i, j);
|
SwapTurnOrder(i, j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1463,20 +1463,20 @@ void CancelMultiTurnMoves(u8 battler)
|
|||||||
// Clear battler's semi-invulnerable bits if they are not held by Sky Drop.
|
// Clear battler's semi-invulnerable bits if they are not held by Sky Drop.
|
||||||
if (!(gStatuses3[battler] & STATUS3_SKY_DROPPED))
|
if (!(gStatuses3[battler] & STATUS3_SKY_DROPPED))
|
||||||
gStatuses3[battler] &= ~(STATUS3_SEMI_INVULNERABLE);
|
gStatuses3[battler] &= ~(STATUS3_SEMI_INVULNERABLE);
|
||||||
|
|
||||||
// Check to see if this Pokemon was in the middle of using Sky Drop. If so, release the target.
|
// 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))
|
if (gBattleStruct->skyDropTargets[battler] != 0xFF && !(gStatuses3[battler] & STATUS3_SKY_DROPPED))
|
||||||
{
|
{
|
||||||
// Get the target's battler id
|
// Get the target's battler id
|
||||||
u8 otherSkyDropper = gBattleStruct->skyDropTargets[battler];
|
u8 otherSkyDropper = gBattleStruct->skyDropTargets[battler];
|
||||||
|
|
||||||
// Clears sky_dropped and on_air statuses
|
// Clears sky_dropped and on_air statuses
|
||||||
gStatuses3[otherSkyDropper] &= ~(STATUS3_SKY_DROPPED | STATUS3_ON_AIR);
|
gStatuses3[otherSkyDropper] &= ~(STATUS3_SKY_DROPPED | STATUS3_ON_AIR);
|
||||||
|
|
||||||
// Makes both attacker and target's sprites visible
|
// Makes both attacker and target's sprites visible
|
||||||
gSprites[gBattlerSpriteIds[battler]].invisible = FALSE;
|
gSprites[gBattlerSpriteIds[battler]].invisible = FALSE;
|
||||||
gSprites[gBattlerSpriteIds[otherSkyDropper]].invisible = FALSE;
|
gSprites[gBattlerSpriteIds[otherSkyDropper]].invisible = FALSE;
|
||||||
|
|
||||||
// If target was sky dropped in the middle of Outrage/Thrash/Petal Dance,
|
// If target was sky dropped in the middle of Outrage/Thrash/Petal Dance,
|
||||||
// confuse them upon release and display "confused by fatigue" message & animation.
|
// 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.
|
// Don't do this if this CancelMultiTurnMoves is caused by falling asleep via Yawn.
|
||||||
@ -1764,7 +1764,7 @@ u8 TrySetCantSelectMoveBattleScript(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gBattleStruct->zmove.active && gDisableStructs[gActiveBattler].tauntTimer != 0 && gBattleMoves[move].power == 0)
|
if (!gBattleStruct->zmove.active && gDisableStructs[gActiveBattler].tauntTimer != 0 && IS_MOVE_STATUS(move))
|
||||||
{
|
{
|
||||||
gCurrentMove = move;
|
gCurrentMove = move;
|
||||||
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
|
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
|
||||||
@ -1859,7 +1859,7 @@ u8 TrySetCantSelectMoveBattleScript(void)
|
|||||||
gCurrentMove = move;
|
gCurrentMove = move;
|
||||||
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
|
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
|
||||||
{
|
{
|
||||||
gPalaceSelectionBattleScripts[gActiveBattler] = BattleScript_SelectingNotAllowedBelchInPalace;
|
gPalaceSelectionBattleScripts[gActiveBattler] = BattleScript_SelectingNotAllowedStuffCheeksInPalace;
|
||||||
gProtectStructs[gActiveBattler].palaceUnableToUseMove = TRUE;
|
gProtectStructs[gActiveBattler].palaceUnableToUseMove = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1876,6 +1876,7 @@ u8 TrySetCantSelectMoveBattleScript(void)
|
|||||||
gLastUsedItem = gBattleMons[gActiveBattler].item;
|
gLastUsedItem = gBattleMons[gActiveBattler].item;
|
||||||
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
|
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
|
||||||
{
|
{
|
||||||
|
gPalaceSelectionBattleScripts[gActiveBattler] = BattleScript_SelectingNotAllowedMoveChoiceItemInPalace;
|
||||||
gProtectStructs[gActiveBattler].palaceUnableToUseMove = TRUE;
|
gProtectStructs[gActiveBattler].palaceUnableToUseMove = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1884,12 +1885,13 @@ u8 TrySetCantSelectMoveBattleScript(void)
|
|||||||
limitations++;
|
limitations++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (holdEffect == HOLD_EFFECT_ASSAULT_VEST && gBattleMoves[move].power == 0 && move != MOVE_ME_FIRST)
|
else if (holdEffect == HOLD_EFFECT_ASSAULT_VEST && IS_MOVE_STATUS(move) && move != MOVE_ME_FIRST)
|
||||||
{
|
{
|
||||||
gCurrentMove = move;
|
gCurrentMove = move;
|
||||||
gLastUsedItem = gBattleMons[gActiveBattler].item;
|
gLastUsedItem = gBattleMons[gActiveBattler].item;
|
||||||
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
|
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
|
||||||
{
|
{
|
||||||
|
gPalaceSelectionBattleScripts[gActiveBattler] = BattleScript_SelectingNotAllowedMoveAssaultVestInPalace;
|
||||||
gProtectStructs[gActiveBattler].palaceUnableToUseMove = TRUE;
|
gProtectStructs[gActiveBattler].palaceUnableToUseMove = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1905,6 +1907,7 @@ u8 TrySetCantSelectMoveBattleScript(void)
|
|||||||
gLastUsedItem = gBattleMons[gActiveBattler].item;
|
gLastUsedItem = gBattleMons[gActiveBattler].item;
|
||||||
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
|
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
|
||||||
{
|
{
|
||||||
|
gPalaceSelectionBattleScripts[gActiveBattler] = BattleScript_SelectingNotAllowedMoveGorillaTacticsInPalace;
|
||||||
gProtectStructs[gActiveBattler].palaceUnableToUseMove = TRUE;
|
gProtectStructs[gActiveBattler].palaceUnableToUseMove = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1927,10 +1930,24 @@ u8 TrySetCantSelectMoveBattleScript(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gBattleMoves[move].effect == EFFECT_PLACEHOLDER)
|
||||||
|
{
|
||||||
|
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
|
||||||
|
{
|
||||||
|
gPalaceSelectionBattleScripts[gActiveBattler] = BattleScript_SelectingNotAllowedPlaceholderInPalace;
|
||||||
|
gProtectStructs[gActiveBattler].palaceUnableToUseMove = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gSelectionBattleScripts[gActiveBattler] = BattleScript_SelectingNotAllowedPlaceholder;
|
||||||
|
limitations++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return limitations;
|
return limitations;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 CheckMoveLimitations(u8 battlerId, u8 unusableMoves, u8 check)
|
u8 CheckMoveLimitations(u8 battlerId, u8 unusableMoves, u16 check)
|
||||||
{
|
{
|
||||||
u8 holdEffect = GetBattlerHoldEffect(battlerId, TRUE);
|
u8 holdEffect = GetBattlerHoldEffect(battlerId, TRUE);
|
||||||
u16 *choicedMove = &gBattleStruct->choicedMove[battlerId];
|
u16 *choicedMove = &gBattleStruct->choicedMove[battlerId];
|
||||||
@ -1941,49 +1958,52 @@ u8 CheckMoveLimitations(u8 battlerId, u8 unusableMoves, u8 check)
|
|||||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||||
{
|
{
|
||||||
// No move
|
// No move
|
||||||
if (gBattleMons[battlerId].moves[i] == MOVE_NONE && check & MOVE_LIMITATION_ZEROMOVE)
|
if (check & MOVE_LIMITATION_ZEROMOVE && gBattleMons[battlerId].moves[i] == MOVE_NONE)
|
||||||
unusableMoves |= gBitTable[i];
|
unusableMoves |= gBitTable[i];
|
||||||
// No PP
|
// No PP
|
||||||
else if (gBattleMons[battlerId].pp[i] == 0 && check & MOVE_LIMITATION_PP)
|
else if (check & MOVE_LIMITATION_PP && gBattleMons[battlerId].pp[i] == 0)
|
||||||
|
unusableMoves |= gBitTable[i];
|
||||||
|
// Placeholder
|
||||||
|
else if (check & MOVE_LIMITATION_PLACEHOLDER && gBattleMoves[gBattleMons[battlerId].moves[i]].effect == EFFECT_PLACEHOLDER)
|
||||||
unusableMoves |= gBitTable[i];
|
unusableMoves |= gBitTable[i];
|
||||||
// Disable
|
// Disable
|
||||||
else if (gBattleMons[battlerId].moves[i] == gDisableStructs[battlerId].disabledMove && check & MOVE_LIMITATION_DISABLED)
|
else if (check & MOVE_LIMITATION_DISABLED && gBattleMons[battlerId].moves[i] == gDisableStructs[battlerId].disabledMove)
|
||||||
unusableMoves |= gBitTable[i];
|
unusableMoves |= gBitTable[i];
|
||||||
// Torment
|
// Torment
|
||||||
else if (gBattleMons[battlerId].moves[i] == gLastMoves[battlerId] && check & MOVE_LIMITATION_TORMENTED && gBattleMons[battlerId].status2 & STATUS2_TORMENT)
|
else if (check & MOVE_LIMITATION_TORMENTED && gBattleMons[battlerId].moves[i] == gLastMoves[battlerId] && gBattleMons[battlerId].status2 & STATUS2_TORMENT)
|
||||||
unusableMoves |= gBitTable[i];
|
unusableMoves |= gBitTable[i];
|
||||||
// Taunt
|
// Taunt
|
||||||
else if (gDisableStructs[battlerId].tauntTimer && check & MOVE_LIMITATION_TAUNT && gBattleMoves[gBattleMons[battlerId].moves[i]].power == 0)
|
else if (check & MOVE_LIMITATION_TAUNT && gDisableStructs[battlerId].tauntTimer && IS_MOVE_STATUS(gBattleMons[battlerId].moves[i]))
|
||||||
unusableMoves |= gBitTable[i];
|
unusableMoves |= gBitTable[i];
|
||||||
// Imprison
|
// Imprison
|
||||||
else if (GetImprisonedMovesCount(battlerId, gBattleMons[battlerId].moves[i]) && check & MOVE_LIMITATION_IMPRISON)
|
else if (check & MOVE_LIMITATION_IMPRISON && GetImprisonedMovesCount(battlerId, gBattleMons[battlerId].moves[i]))
|
||||||
unusableMoves |= gBitTable[i];
|
unusableMoves |= gBitTable[i];
|
||||||
// Encore
|
// Encore
|
||||||
else if (gDisableStructs[battlerId].encoreTimer && gDisableStructs[battlerId].encoredMove != gBattleMons[battlerId].moves[i])
|
else if (check & MOVE_LIMITATION_ENCORE && gDisableStructs[battlerId].encoreTimer && gDisableStructs[battlerId].encoredMove != gBattleMons[battlerId].moves[i])
|
||||||
unusableMoves |= gBitTable[i];
|
unusableMoves |= gBitTable[i];
|
||||||
// Choice Items
|
// Choice Items
|
||||||
else if (HOLD_EFFECT_CHOICE(holdEffect) && *choicedMove != MOVE_NONE && *choicedMove != MOVE_UNAVAILABLE && *choicedMove != gBattleMons[battlerId].moves[i])
|
else if (check & MOVE_LIMITATION_CHOICE_ITEM && HOLD_EFFECT_CHOICE(holdEffect) && *choicedMove != MOVE_NONE && *choicedMove != MOVE_UNAVAILABLE && *choicedMove != gBattleMons[battlerId].moves[i])
|
||||||
unusableMoves |= gBitTable[i];
|
unusableMoves |= gBitTable[i];
|
||||||
// Assault Vest
|
// Assault Vest
|
||||||
else if (holdEffect == HOLD_EFFECT_ASSAULT_VEST && gBattleMoves[gBattleMons[battlerId].moves[i]].power == 0 && gBattleMons[battlerId].moves[i] != MOVE_ME_FIRST)
|
else if (check & MOVE_LIMITATION_ASSAULT_VEST && holdEffect == HOLD_EFFECT_ASSAULT_VEST && IS_MOVE_STATUS(gBattleMons[battlerId].moves[i]) && gBattleMons[battlerId].moves[i] != MOVE_ME_FIRST)
|
||||||
unusableMoves |= gBitTable[i];
|
unusableMoves |= gBitTable[i];
|
||||||
// Gravity
|
// Gravity
|
||||||
else if (IsGravityPreventingMove(gBattleMons[battlerId].moves[i]))
|
else if (check & MOVE_LIMITATION_GRAVITY && IsGravityPreventingMove(gBattleMons[battlerId].moves[i]))
|
||||||
unusableMoves |= gBitTable[i];
|
unusableMoves |= gBitTable[i];
|
||||||
// Heal Block
|
// Heal Block
|
||||||
else if (IsHealBlockPreventingMove(battlerId, gBattleMons[battlerId].moves[i]))
|
else if (check & MOVE_LIMITATION_HEAL_BLOCK && IsHealBlockPreventingMove(battlerId, gBattleMons[battlerId].moves[i]))
|
||||||
unusableMoves |= gBitTable[i];
|
unusableMoves |= gBitTable[i];
|
||||||
// Belch
|
// Belch
|
||||||
else if (IsBelchPreventingMove(battlerId, gBattleMons[battlerId].moves[i]))
|
else if (check & MOVE_LIMITATION_BELCH && IsBelchPreventingMove(battlerId, gBattleMons[battlerId].moves[i]))
|
||||||
unusableMoves |= gBitTable[i];
|
unusableMoves |= gBitTable[i];
|
||||||
// Throat Chop
|
// Throat Chop
|
||||||
else if (gDisableStructs[battlerId].throatChopTimer && gBattleMoves[gBattleMons[battlerId].moves[i]].flags & FLAG_SOUND)
|
else if (check & MOVE_LIMITATION_THROAT_CHOP && gDisableStructs[battlerId].throatChopTimer && gBattleMoves[gBattleMons[battlerId].moves[i]].flags & FLAG_SOUND)
|
||||||
unusableMoves |= gBitTable[i];
|
unusableMoves |= gBitTable[i];
|
||||||
// Stuff Cheeks
|
// Stuff Cheeks
|
||||||
else if (gBattleMons[battlerId].moves[i] == MOVE_STUFF_CHEEKS && ItemId_GetPocket(gBattleMons[gActiveBattler].item) != POCKET_BERRIES)
|
else if (check & MOVE_LIMITATION_STUFF_CHEEKS && gBattleMons[battlerId].moves[i] == MOVE_STUFF_CHEEKS && ItemId_GetPocket(gBattleMons[gActiveBattler].item) != POCKET_BERRIES)
|
||||||
unusableMoves |= gBitTable[i];
|
unusableMoves |= gBitTable[i];
|
||||||
// Gorilla Tactics
|
// Gorilla Tactics
|
||||||
else if (GetBattlerAbility(battlerId) == ABILITY_GORILLA_TACTICS && *choicedMove != MOVE_NONE && *choicedMove != MOVE_UNAVAILABLE && *choicedMove != gBattleMons[battlerId].moves[i])
|
else if (check & MOVE_LIMITATION_CHOICE_ITEM && GetBattlerAbility(battlerId) == ABILITY_GORILLA_TACTICS && *choicedMove != MOVE_NONE && *choicedMove != MOVE_UNAVAILABLE && *choicedMove != gBattleMons[battlerId].moves[i])
|
||||||
unusableMoves |= gBitTable[i];
|
unusableMoves |= gBitTable[i];
|
||||||
}
|
}
|
||||||
return unusableMoves;
|
return unusableMoves;
|
||||||
@ -2341,6 +2361,7 @@ u8 DoFieldEndTurnEffects(void)
|
|||||||
if (effect == 0)
|
if (effect == 0)
|
||||||
{
|
{
|
||||||
gBattleStruct->turnCountersTracker++;
|
gBattleStruct->turnCountersTracker++;
|
||||||
|
gBattleStruct->turnSideTracker = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ENDTURN_RAIN:
|
case ENDTURN_RAIN:
|
||||||
@ -3545,7 +3566,7 @@ u8 AtkCanceller_UnableToUseMove(void)
|
|||||||
gBattleStruct->atkCancellerTracker++;
|
gBattleStruct->atkCancellerTracker++;
|
||||||
break;
|
break;
|
||||||
case CANCELLER_TAUNTED: // taunt
|
case CANCELLER_TAUNTED: // taunt
|
||||||
if (gDisableStructs[gBattlerAttacker].tauntTimer && gBattleMoves[gCurrentMove].power == 0)
|
if (gDisableStructs[gBattlerAttacker].tauntTimer && IS_MOVE_STATUS(gCurrentMove))
|
||||||
{
|
{
|
||||||
gProtectStructs[gBattlerAttacker].usedTauntedMove = TRUE;
|
gProtectStructs[gBattlerAttacker].usedTauntedMove = TRUE;
|
||||||
CancelMultiTurnMoves(gBattlerAttacker);
|
CancelMultiTurnMoves(gBattlerAttacker);
|
||||||
@ -3729,7 +3750,7 @@ u8 AtkCanceller_UnableToUseMove(void)
|
|||||||
gBattleStruct->zmove.used[gBattlerAttacker] = TRUE;
|
gBattleStruct->zmove.used[gBattlerAttacker] = TRUE;
|
||||||
if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && IsPartnerMonFromSameTrainer(gBattlerAttacker))
|
if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && IsPartnerMonFromSameTrainer(gBattlerAttacker))
|
||||||
gBattleStruct->zmove.used[BATTLE_PARTNER(gBattlerAttacker)] = TRUE; //if 1v1 double, set partner used flag as well
|
gBattleStruct->zmove.used[BATTLE_PARTNER(gBattlerAttacker)] = TRUE; //if 1v1 double, set partner used flag as well
|
||||||
|
|
||||||
gBattleScripting.battler = gBattlerAttacker;
|
gBattleScripting.battler = gBattlerAttacker;
|
||||||
if (gBattleStruct->zmove.activeSplit == SPLIT_STATUS)
|
if (gBattleStruct->zmove.activeSplit == SPLIT_STATUS)
|
||||||
{
|
{
|
||||||
@ -4961,7 +4982,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
|
|||||||
|
|
||||||
if (effect == 1) // Drain Hp ability.
|
if (effect == 1) // Drain Hp ability.
|
||||||
{
|
{
|
||||||
#if B_HEAL_BLOCKING >= GEN_5
|
#if B_HEAL_BLOCKING >= GEN_5
|
||||||
if (BATTLER_MAX_HP(battler) || gStatuses3[battler] & STATUS3_HEAL_BLOCK)
|
if (BATTLER_MAX_HP(battler) || gStatuses3[battler] & STATUS3_HEAL_BLOCK)
|
||||||
#else
|
#else
|
||||||
if (BATTLER_MAX_HP(battler))
|
if (BATTLER_MAX_HP(battler))
|
||||||
@ -8048,7 +8069,7 @@ static u16 CalcMoveBasePower(u16 move, u8 battlerAtk, u8 battlerDef)
|
|||||||
u32 i;
|
u32 i;
|
||||||
u16 basePower = gBattleMoves[move].power;
|
u16 basePower = gBattleMoves[move].power;
|
||||||
u32 weight, hpFraction, speed;
|
u32 weight, hpFraction, speed;
|
||||||
|
|
||||||
if (gBattleStruct->zmove.active)
|
if (gBattleStruct->zmove.active)
|
||||||
return gBattleMoves[gBattleStruct->zmove.baseMoves[battlerAtk]].zMovePower;
|
return gBattleMoves[gBattleStruct->zmove.baseMoves[battlerAtk]].zMovePower;
|
||||||
|
|
||||||
@ -8476,15 +8497,15 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe
|
|||||||
MulModifier(&modifier, holdEffectModifier);
|
MulModifier(&modifier, holdEffectModifier);
|
||||||
break;
|
break;
|
||||||
case HOLD_EFFECT_LUSTROUS_ORB:
|
case HOLD_EFFECT_LUSTROUS_ORB:
|
||||||
if (gBattleMons[battlerAtk].species == SPECIES_PALKIA && (moveType == TYPE_WATER || moveType == TYPE_DRAGON))
|
if (GET_BASE_SPECIES_ID(gBattleMons[battlerAtk].species) == SPECIES_PALKIA && (moveType == TYPE_WATER || moveType == TYPE_DRAGON))
|
||||||
MulModifier(&modifier, holdEffectModifier);
|
MulModifier(&modifier, holdEffectModifier);
|
||||||
break;
|
break;
|
||||||
case HOLD_EFFECT_ADAMANT_ORB:
|
case HOLD_EFFECT_ADAMANT_ORB:
|
||||||
if (gBattleMons[battlerAtk].species == SPECIES_DIALGA && (moveType == TYPE_STEEL || moveType == TYPE_DRAGON))
|
if (GET_BASE_SPECIES_ID(gBattleMons[battlerAtk].species) == SPECIES_DIALGA && (moveType == TYPE_STEEL || moveType == TYPE_DRAGON))
|
||||||
MulModifier(&modifier, holdEffectModifier);
|
MulModifier(&modifier, holdEffectModifier);
|
||||||
break;
|
break;
|
||||||
case HOLD_EFFECT_GRISEOUS_ORB:
|
case HOLD_EFFECT_GRISEOUS_ORB:
|
||||||
if (gBattleMons[battlerAtk].species == SPECIES_GIRATINA && (moveType == TYPE_GHOST || moveType == TYPE_DRAGON))
|
if (GET_BASE_SPECIES_ID(gBattleMons[battlerAtk].species) == SPECIES_GIRATINA && (moveType == TYPE_GHOST || moveType == TYPE_DRAGON))
|
||||||
MulModifier(&modifier, holdEffectModifier);
|
MulModifier(&modifier, holdEffectModifier);
|
||||||
break;
|
break;
|
||||||
case HOLD_EFFECT_SOUL_DEW:
|
case HOLD_EFFECT_SOUL_DEW:
|
||||||
@ -9122,7 +9143,7 @@ static s32 DoMoveDamageCalc(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType,
|
|||||||
bool32 isCrit, bool32 randomFactor, bool32 updateFlags, u16 typeEffectivenessModifier)
|
bool32 isCrit, bool32 randomFactor, bool32 updateFlags, u16 typeEffectivenessModifier)
|
||||||
{
|
{
|
||||||
s32 dmg;
|
s32 dmg;
|
||||||
|
|
||||||
// Don't calculate damage if the move has no effect on target.
|
// Don't calculate damage if the move has no effect on target.
|
||||||
if (typeEffectivenessModifier == UQ_4_12(0))
|
if (typeEffectivenessModifier == UQ_4_12(0))
|
||||||
return 0;
|
return 0;
|
||||||
@ -9454,7 +9475,7 @@ bool32 CanMegaEvolve(u8 battlerId)
|
|||||||
// Cannot use z move and mega evolve on same turn
|
// Cannot use z move and mega evolve on same turn
|
||||||
if (gBattleStruct->zmove.toBeUsed[battlerId])
|
if (gBattleStruct->zmove.toBeUsed[battlerId])
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
|
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
|
||||||
&& IsPartnerMonFromSameTrainer(battlerId)
|
&& IsPartnerMonFromSameTrainer(battlerId)
|
||||||
&& (mega->alreadyEvolved[partnerPosition] || (mega->toEvolve & gBitTable[BATTLE_PARTNER(battlerId)])))
|
&& (mega->alreadyEvolved[partnerPosition] || (mega->toEvolve & gBitTable[BATTLE_PARTNER(battlerId)])))
|
||||||
@ -10115,7 +10136,7 @@ void DoBurmyFormChange(u32 monId)
|
|||||||
|
|
||||||
currSpecies = GetMonData(&party[monId], MON_DATA_SPECIES, NULL);
|
currSpecies = GetMonData(&party[monId], MON_DATA_SPECIES, NULL);
|
||||||
|
|
||||||
if ((GET_BASE_SPECIES_ID(currSpecies) == SPECIES_BURMY)
|
if ((GET_BASE_SPECIES_ID(currSpecies) == SPECIES_BURMY)
|
||||||
&& (gBattleStruct->appearedInBattle & gBitTable[monId]) // Burmy appeared in battle
|
&& (gBattleStruct->appearedInBattle & gBitTable[monId]) // Burmy appeared in battle
|
||||||
&& GetMonData(&party[monId], MON_DATA_HP, NULL) != 0) // Burmy isn't fainted
|
&& GetMonData(&party[monId], MON_DATA_HP, NULL) != 0) // Burmy isn't fainted
|
||||||
{
|
{
|
||||||
|
@ -3121,7 +3121,7 @@ static u8 CreateContestantSprite(u16 species, u32 otId, u32 personality, u32 ind
|
|||||||
u8 spriteId;
|
u8 spriteId;
|
||||||
species = SanitizeSpecies(species);
|
species = SanitizeSpecies(species);
|
||||||
|
|
||||||
HandleLoadSpecialPokePic(&gMonBackPicTable[species], gMonSpritesGfxPtr->sprites.ptr[B_POSITION_PLAYER_LEFT], species, personality);
|
HandleLoadSpecialPokePic(FALSE, gMonSpritesGfxPtr->sprites.ptr[B_POSITION_PLAYER_LEFT], species, personality);
|
||||||
|
|
||||||
LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(species, otId, personality), 0x120, 0x20);
|
LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(species, otId, personality), 0x120, 0x20);
|
||||||
SetMultiuseSpriteTemplateToPokemon(species, B_POSITION_PLAYER_LEFT);
|
SetMultiuseSpriteTemplateToPokemon(species, B_POSITION_PLAYER_LEFT);
|
||||||
|
@ -367,20 +367,18 @@ static void InitContestMonPixels(u16 species, bool8 backPic)
|
|||||||
LZDecompressVram(pal, gContestPaintingMonPalette);
|
LZDecompressVram(pal, gContestPaintingMonPalette);
|
||||||
if (!backPic)
|
if (!backPic)
|
||||||
{
|
{
|
||||||
HandleLoadSpecialPokePic(
|
HandleLoadSpecialPokePic(TRUE,
|
||||||
&gMonFrontPicTable[species],
|
gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_LEFT],
|
||||||
gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_LEFT],
|
species,
|
||||||
species,
|
gContestPaintingWinner->personality);
|
||||||
gContestPaintingWinner->personality);
|
|
||||||
_InitContestMonPixels(gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_LEFT], gContestPaintingMonPalette, (void *)gContestMonPixels);
|
_InitContestMonPixels(gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_LEFT], gContestPaintingMonPalette, (void *)gContestMonPixels);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HandleLoadSpecialPokePic(
|
HandleLoadSpecialPokePic(FALSE,
|
||||||
&gMonBackPicTable[species],
|
gMonSpritesGfxPtr->sprites.ptr[B_POSITION_PLAYER_LEFT],
|
||||||
gMonSpritesGfxPtr->sprites.ptr[B_POSITION_PLAYER_LEFT],
|
species,
|
||||||
species,
|
gContestPaintingWinner->personality);
|
||||||
gContestPaintingWinner->personality);
|
|
||||||
_InitContestMonPixels(gMonSpritesGfxPtr->sprites.ptr[B_POSITION_PLAYER_LEFT], gContestPaintingMonPalette, (void *)gContestMonPixels);
|
_InitContestMonPixels(gMonSpritesGfxPtr->sprites.ptr[B_POSITION_PLAYER_LEFT], gContestPaintingMonPalette, (void *)gContestMonPixels);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -892,11 +892,10 @@ static void Task_ShowWinnerMonBanner(u8 taskId)
|
|||||||
species = gContestMons[i].species;
|
species = gContestMons[i].species;
|
||||||
personality = gContestMons[i].personality;
|
personality = gContestMons[i].personality;
|
||||||
otId = gContestMons[i].otId;
|
otId = gContestMons[i].otId;
|
||||||
HandleLoadSpecialPokePic(
|
HandleLoadSpecialPokePic(TRUE,
|
||||||
&gMonFrontPicTable[species],
|
gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_LEFT],
|
||||||
gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_LEFT],
|
species,
|
||||||
species,
|
personality);
|
||||||
personality);
|
|
||||||
|
|
||||||
pokePal = GetMonSpritePalStructFromOtIdPersonality(species, otId, personality);
|
pokePal = GetMonSpritePalStructFromOtIdPersonality(species, otId, personality);
|
||||||
LoadCompressedSpritePalette(pokePal);
|
LoadCompressedSpritePalette(pokePal);
|
||||||
@ -2572,7 +2571,7 @@ void ShowContestEntryMonPic(void)
|
|||||||
taskId = CreateTask(Task_ShowContestEntryMonPic, 0x50);
|
taskId = CreateTask(Task_ShowContestEntryMonPic, 0x50);
|
||||||
gTasks[taskId].data[0] = 0;
|
gTasks[taskId].data[0] = 0;
|
||||||
gTasks[taskId].data[1] = species;
|
gTasks[taskId].data[1] = species;
|
||||||
HandleLoadSpecialPokePic(&gMonFrontPicTable[species], gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_LEFT], species, personality);
|
HandleLoadSpecialPokePic(TRUE, gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_LEFT], species, personality);
|
||||||
|
|
||||||
palette = GetMonSpritePalStructFromOtIdPersonality(species, otId, personality);
|
palette = GetMonSpritePalStructFromOtIdPersonality(species, otId, personality);
|
||||||
LoadCompressedSpritePalette(palette);
|
LoadCompressedSpritePalette(palette);
|
||||||
|
@ -2978,8 +2978,9 @@ static const u8 sEerieSpellDescription[] = _(
|
|||||||
"Attacks with psychic power.\n"
|
"Attacks with psychic power.\n"
|
||||||
"Foe's last move has 3 PP cut.");
|
"Foe's last move has 3 PP cut.");
|
||||||
|
|
||||||
static const u8 sNotDoneYetDescription[] = _(
|
const u8 gNotDoneYetDescription[] = _(
|
||||||
"Not done yet.");
|
"This move can't be used. Its\n"
|
||||||
|
"effect is in development.");
|
||||||
|
|
||||||
// MOVE_NONE is ignored in this table. Make sure to always subtract 1 before getting the right pointer.
|
// MOVE_NONE is ignored in this table. Make sure to always subtract 1 before getting the right pointer.
|
||||||
const u8 *const gMoveDescriptionPointers[MOVES_COUNT - 1] =
|
const u8 *const gMoveDescriptionPointers[MOVES_COUNT - 1] =
|
||||||
|
@ -70,25 +70,18 @@ void DecompressPicFromTable(const struct CompressedSpriteSheet *src, void *buffe
|
|||||||
|
|
||||||
void DecompressPicFromTableGender(void* buffer, s32 species, u32 personality)
|
void DecompressPicFromTableGender(void* buffer, s32 species, u32 personality)
|
||||||
{
|
{
|
||||||
if ((gBaseStats[species].flags & FLAG_GENDER_DIFFERENCE) && GetGenderFromSpeciesAndPersonality(species, personality) == MON_FEMALE)
|
if (ShouldShowFemaleDifferences(species, personality))
|
||||||
DecompressPicFromTable(&gMonFrontPicTableFemale[species], buffer, species);
|
DecompressPicFromTable(&gMonFrontPicTableFemale[species], buffer, species);
|
||||||
else
|
else
|
||||||
DecompressPicFromTable(&gMonFrontPicTable[species], buffer, species);
|
DecompressPicFromTable(&gMonFrontPicTable[species], buffer, species);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleLoadSpecialPokePic(const struct CompressedSpriteSheet *src, void *dest, s32 species, u32 personality)
|
void HandleLoadSpecialPokePic(bool32 isFrontPic, void *dest, s32 species, u32 personality)
|
||||||
{
|
{
|
||||||
bool8 isFrontPic;
|
LoadSpecialPokePic(dest, species, personality, isFrontPic);
|
||||||
|
|
||||||
if (src == &gMonFrontPicTable[species])
|
|
||||||
isFrontPic = TRUE; // frontPic
|
|
||||||
else
|
|
||||||
isFrontPic = FALSE; // backPic
|
|
||||||
|
|
||||||
LoadSpecialPokePic(src, dest, species, personality, isFrontPic);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadSpecialPokePic(const struct CompressedSpriteSheet *src, void *dest, s32 species, u32 personality, bool8 isFrontPic)
|
void LoadSpecialPokePic(void *dest, s32 species, u32 personality, bool8 isFrontPic)
|
||||||
{
|
{
|
||||||
if (species == SPECIES_UNOWN)
|
if (species == SPECIES_UNOWN)
|
||||||
{
|
{
|
||||||
@ -100,8 +93,13 @@ void LoadSpecialPokePic(const struct CompressedSpriteSheet *src, void *dest, s32
|
|||||||
LZ77UnCompWram(gMonFrontPicTable[id].data, dest);
|
LZ77UnCompWram(gMonFrontPicTable[id].data, dest);
|
||||||
}
|
}
|
||||||
else if (species > NUM_SPECIES) // is species unknown? draw the ? icon
|
else if (species > NUM_SPECIES) // is species unknown? draw the ? icon
|
||||||
LZ77UnCompWram(gMonFrontPicTable[0].data, dest);
|
{
|
||||||
else if ((gBaseStats[species].flags & FLAG_GENDER_DIFFERENCE) && GetGenderFromSpeciesAndPersonality(species, personality) == MON_FEMALE)
|
if (isFrontPic)
|
||||||
|
LZ77UnCompWram(gMonFrontPicTable[0].data, dest);
|
||||||
|
else
|
||||||
|
LZ77UnCompWram(gMonBackPicTable[0].data, dest);
|
||||||
|
}
|
||||||
|
else if (ShouldShowFemaleDifferences(species, personality))
|
||||||
{
|
{
|
||||||
if (isFrontPic)
|
if (isFrontPic)
|
||||||
LZ77UnCompWram(gMonFrontPicTableFemale[species].data, dest);
|
LZ77UnCompWram(gMonFrontPicTableFemale[species].data, dest);
|
||||||
@ -109,49 +107,15 @@ void LoadSpecialPokePic(const struct CompressedSpriteSheet *src, void *dest, s32
|
|||||||
LZ77UnCompWram(gMonBackPicTableFemale[species].data, dest);
|
LZ77UnCompWram(gMonBackPicTableFemale[species].data, dest);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LZ77UnCompWram(src->data, dest);
|
|
||||||
|
|
||||||
DrawSpindaSpots(species, personality, dest, isFrontPic);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if P_ENABLE_DEBUG == TRUE
|
|
||||||
static void LoadSpecialPokePicCustom(const struct CompressedSpriteSheet *src, void *dest, s32 species, u32 personality, bool8 isFrontPic, bool8 isFemale)
|
|
||||||
{
|
|
||||||
if (species == SPECIES_UNOWN)
|
|
||||||
{
|
|
||||||
u32 id = GetUnownSpeciesId(personality);
|
|
||||||
|
|
||||||
if (!isFrontPic)
|
|
||||||
LZ77UnCompWram(gMonBackPicTable[id].data, dest);
|
|
||||||
else
|
|
||||||
LZ77UnCompWram(gMonFrontPicTable[id].data, dest);
|
|
||||||
}
|
|
||||||
else if (species > NUM_SPECIES) // is species unknown? draw the ? icon
|
|
||||||
LZ77UnCompWram(gMonFrontPicTable[0].data, dest);
|
|
||||||
else if ((gBaseStats[species].flags & FLAG_GENDER_DIFFERENCE) && isFemale)
|
|
||||||
{
|
{
|
||||||
if (isFrontPic)
|
if (isFrontPic)
|
||||||
LZ77UnCompWram(gMonFrontPicTableFemale[species].data, dest);
|
LZ77UnCompWram(gMonFrontPicTable[species].data, dest);
|
||||||
else
|
else
|
||||||
LZ77UnCompWram(gMonBackPicTableFemale[species].data, dest);
|
LZ77UnCompWram(gMonBackPicTable[species].data, dest);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
LZ77UnCompWram(src->data, dest);
|
|
||||||
|
|
||||||
DrawSpindaSpots(species, personality, dest, isFrontPic);
|
DrawSpindaSpots(species, personality, dest, isFrontPic);
|
||||||
}
|
}
|
||||||
void HandleLoadSpecialPokePicCustom(const struct CompressedSpriteSheet *src, void *dest, s32 species, u32 personality, bool8 isFemale)
|
|
||||||
{
|
|
||||||
bool8 isFrontPic;
|
|
||||||
|
|
||||||
if (src == &gMonFrontPicTable[species])
|
|
||||||
isFrontPic = TRUE; // frontPic
|
|
||||||
else
|
|
||||||
isFrontPic = FALSE; // backPic
|
|
||||||
|
|
||||||
LoadSpecialPokePicCustom(src, dest, species, personality, isFrontPic, isFemale);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void Unused_LZDecompressWramIndirect(const void **src, void *dest)
|
void Unused_LZDecompressWramIndirect(const void **src, void *dest)
|
||||||
{
|
{
|
||||||
|
@ -444,7 +444,7 @@ static u8 EggHatchCreateMonSprite(u8 useAlt, u8 state, u8 partyId, u16 *speciesL
|
|||||||
{
|
{
|
||||||
u16 species = GetMonData(mon, MON_DATA_SPECIES);
|
u16 species = GetMonData(mon, MON_DATA_SPECIES);
|
||||||
u32 pid = GetMonData(mon, MON_DATA_PERSONALITY);
|
u32 pid = GetMonData(mon, MON_DATA_PERSONALITY);
|
||||||
HandleLoadSpecialPokePic(&gMonFrontPicTable[species],
|
HandleLoadSpecialPokePic(TRUE,
|
||||||
gMonSpritesGfxPtr->sprites.ptr[(useAlt * 2) + B_POSITION_OPPONENT_LEFT],
|
gMonSpritesGfxPtr->sprites.ptr[(useAlt * 2) + B_POSITION_OPPONENT_LEFT],
|
||||||
species, pid);
|
species, pid);
|
||||||
LoadCompressedSpritePalette(GetMonSpritePalStruct(mon));
|
LoadCompressedSpritePalette(GetMonSpritePalStruct(mon));
|
||||||
|
@ -2033,12 +2033,3 @@ const u16 gFrontierPassCancelButtonHighlighted_Tilemap[] = INCBIN_U16("graphics/
|
|||||||
const u16 gBerryCrush_Crusher_Pal[] = INCBIN_U16("graphics/berry_crush/crusher.gbapal");
|
const u16 gBerryCrush_Crusher_Pal[] = INCBIN_U16("graphics/berry_crush/crusher.gbapal");
|
||||||
const u32 gBerryCrush_Crusher_Gfx[] = INCBIN_U32("graphics/berry_crush/crusher.4bpp.lz");
|
const u32 gBerryCrush_Crusher_Gfx[] = INCBIN_U32("graphics/berry_crush/crusher.4bpp.lz");
|
||||||
const u32 gBerryCrush_TextWindows_Tilemap[] = INCBIN_U32("graphics/berry_crush/text_windows.bin.lz");
|
const u32 gBerryCrush_TextWindows_Tilemap[] = INCBIN_U32("graphics/berry_crush/text_windows.bin.lz");
|
||||||
|
|
||||||
// random garbage at the end.
|
|
||||||
static const u8 sEmpty3[0x54BAC] = {0};
|
|
||||||
static const u8 sUnused1[] = {0x0D, 0x00, 0x58, 0x02};
|
|
||||||
static const u8 sEmpty4[0x1145] = {0};
|
|
||||||
static const u8 sUnused2[] = {0x02};
|
|
||||||
static const u8 sEmpty5[0x3242] = {0};
|
|
||||||
static const u8 sUnused3[] = {0x40};
|
|
||||||
static const u8 sEmpty6[0x13] = {0};
|
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "trig.h"
|
#include "trig.h"
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
#include "constants/songs.h"
|
#include "constants/songs.h"
|
||||||
|
#include "constants/battle_move_effects.h"
|
||||||
#include "gba/io_reg.h"
|
#include "gba/io_reg.h"
|
||||||
|
|
||||||
extern const struct CompressedSpriteSheet gMonFrontPicTable[];
|
extern const struct CompressedSpriteSheet gMonFrontPicTable[];
|
||||||
@ -807,7 +808,11 @@ static void MoveRelearnerLoadBattleMoveDescription(u32 chosenMove)
|
|||||||
}
|
}
|
||||||
AddTextPrinterParameterized(0, FONT_NORMAL, str, 0x6A, 0x29, TEXT_SKIP_DRAW, NULL);
|
AddTextPrinterParameterized(0, FONT_NORMAL, str, 0x6A, 0x29, TEXT_SKIP_DRAW, NULL);
|
||||||
|
|
||||||
str = gMoveDescriptionPointers[chosenMove - 1];
|
if (move->effect != EFFECT_PLACEHOLDER)
|
||||||
|
str = gMoveDescriptionPointers[chosenMove - 1];
|
||||||
|
else
|
||||||
|
str = gNotDoneYetDescription;
|
||||||
|
|
||||||
AddTextPrinterParameterized(0, FONT_NARROW, str, 0, 0x41, 0, NULL);
|
AddTextPrinterParameterized(0, FONT_NARROW, str, 0, 0x41, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1075,7 +1080,7 @@ void GetConditionMenuMonGfx(void *tilesDst, void *palDst, u16 boxId, u16 monId,
|
|||||||
u32 trainerId = GetBoxOrPartyMonData(boxId, monId, MON_DATA_OT_ID, NULL);
|
u32 trainerId = GetBoxOrPartyMonData(boxId, monId, MON_DATA_OT_ID, NULL);
|
||||||
u32 personality = GetBoxOrPartyMonData(boxId, monId, MON_DATA_PERSONALITY, NULL);
|
u32 personality = GetBoxOrPartyMonData(boxId, monId, MON_DATA_PERSONALITY, NULL);
|
||||||
|
|
||||||
LoadSpecialPokePic(&gMonFrontPicTable[species], tilesDst, species, personality, TRUE);
|
LoadSpecialPokePic(tilesDst, species, personality, TRUE);
|
||||||
LZ77UnCompWram(GetMonSpritePalFromSpeciesAndPersonality(species, trainerId, personality), palDst);
|
LZ77UnCompWram(GetMonSpritePalFromSpeciesAndPersonality(species, trainerId, personality), palDst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6134,7 +6134,7 @@ void ChooseMonForWirelessMinigame(void)
|
|||||||
|
|
||||||
static u8 GetPartyLayoutFromBattleType(void)
|
static u8 GetPartyLayoutFromBattleType(void)
|
||||||
{
|
{
|
||||||
if (IsDoubleBattle() == FALSE)
|
if (!IsDoubleBattle() || gPlayerPartyCount == 1) // Draw the single layout in a double battle where the player has only one pokemon.
|
||||||
return PARTY_LAYOUT_SINGLE;
|
return PARTY_LAYOUT_SINGLE;
|
||||||
if (IsMultiBattle() == TRUE)
|
if (IsMultiBattle() == TRUE)
|
||||||
return PARTY_LAYOUT_MULTI;
|
return PARTY_LAYOUT_MULTI;
|
||||||
|
@ -727,7 +727,7 @@ static bool8 LoadMonAndSceneGfx(struct Pokemon *mon)
|
|||||||
// Load mon gfx
|
// Load mon gfx
|
||||||
species = GetMonData(mon, MON_DATA_SPECIES2);
|
species = GetMonData(mon, MON_DATA_SPECIES2);
|
||||||
personality = GetMonData(mon, MON_DATA_PERSONALITY);
|
personality = GetMonData(mon, MON_DATA_PERSONALITY);
|
||||||
HandleLoadSpecialPokePic(&gMonFrontPicTable[species], gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_LEFT], species, personality);
|
HandleLoadSpecialPokePic(TRUE, gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_LEFT], species, personality);
|
||||||
sPokeblockFeed->loadGfxState++;
|
sPokeblockFeed->loadGfxState++;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -7520,14 +7520,14 @@ const u32 *GetMonSpritePalFromSpeciesAndPersonality(u16 species, u32 otId, u32 p
|
|||||||
shinyValue = GET_SHINY_VALUE(otId, personality);
|
shinyValue = GET_SHINY_VALUE(otId, personality);
|
||||||
if (shinyValue < SHINY_ODDS)
|
if (shinyValue < SHINY_ODDS)
|
||||||
{
|
{
|
||||||
if ((gBaseStats[species].flags & FLAG_GENDER_DIFFERENCE) && GetGenderFromSpeciesAndPersonality(species, personality) == MON_FEMALE)
|
if (ShouldShowFemaleDifferences(species, personality))
|
||||||
return gMonShinyPaletteTableFemale[species].data;
|
return gMonShinyPaletteTableFemale[species].data;
|
||||||
else
|
else
|
||||||
return gMonShinyPaletteTable[species].data;
|
return gMonShinyPaletteTable[species].data;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((gBaseStats[species].flags & FLAG_GENDER_DIFFERENCE) && GetGenderFromSpeciesAndPersonality(species, personality) == MON_FEMALE)
|
if (ShouldShowFemaleDifferences(species, personality))
|
||||||
return gMonPaletteTableFemale[species].data;
|
return gMonPaletteTableFemale[species].data;
|
||||||
else
|
else
|
||||||
return gMonPaletteTable[species].data;
|
return gMonPaletteTable[species].data;
|
||||||
@ -7549,14 +7549,14 @@ const struct CompressedSpritePalette *GetMonSpritePalStructFromOtIdPersonality(u
|
|||||||
shinyValue = GET_SHINY_VALUE(otId, personality);
|
shinyValue = GET_SHINY_VALUE(otId, personality);
|
||||||
if (shinyValue < SHINY_ODDS)
|
if (shinyValue < SHINY_ODDS)
|
||||||
{
|
{
|
||||||
if ((gBaseStats[species].flags & FLAG_GENDER_DIFFERENCE) && GetGenderFromSpeciesAndPersonality(species, personality) == MON_FEMALE)
|
if (ShouldShowFemaleDifferences(species, personality))
|
||||||
return &gMonShinyPaletteTableFemale[species];
|
return &gMonShinyPaletteTableFemale[species];
|
||||||
else
|
else
|
||||||
return &gMonShinyPaletteTable[species];
|
return &gMonShinyPaletteTable[species];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((gBaseStats[species].flags & FLAG_GENDER_DIFFERENCE) && GetGenderFromSpeciesAndPersonality(species, personality) == MON_FEMALE)
|
if (ShouldShowFemaleDifferences(species, personality))
|
||||||
return &gMonPaletteTableFemale[species];
|
return &gMonPaletteTableFemale[species];
|
||||||
else
|
else
|
||||||
return &gMonPaletteTable[species];
|
return &gMonPaletteTable[species];
|
||||||
@ -8359,3 +8359,8 @@ void TrySpecialOverworldEvo(void)
|
|||||||
sTriedEvolving = 0;
|
sTriedEvolving = 0;
|
||||||
SetMainCallback2(CB2_ReturnToField);
|
SetMainCallback2(CB2_ReturnToField);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool32 ShouldShowFemaleDifferences(u16 species, u32 personality)
|
||||||
|
{
|
||||||
|
return (gBaseStats[species].flags & FLAG_GENDER_DIFFERENCE) && GetGenderFromSpeciesAndPersonality(species, personality) == MON_FEMALE;
|
||||||
|
}
|
||||||
|
@ -1107,6 +1107,9 @@ static void ResetPokemonDebugWindows(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define MALE_PERSONALITY 0xFE
|
||||||
|
#define FEMALE_PERSONALITY 0X0
|
||||||
|
|
||||||
void CB2_Debug_Pokemon(void)
|
void CB2_Debug_Pokemon(void)
|
||||||
{
|
{
|
||||||
u8 taskId;
|
u8 taskId;
|
||||||
@ -1180,7 +1183,7 @@ void CB2_Debug_Pokemon(void)
|
|||||||
palette = GetMonSpritePalStructCustom(species, data->isFemale, data->isShiny);
|
palette = GetMonSpritePalStructCustom(species, data->isFemale, data->isShiny);
|
||||||
LoadCompressedSpritePalette(palette);
|
LoadCompressedSpritePalette(palette);
|
||||||
//Front
|
//Front
|
||||||
HandleLoadSpecialPokePicCustom(&gMonFrontPicTable[species], gMonSpritesGfxPtr->sprites.ptr[1], species, 0, data->isFemale);
|
HandleLoadSpecialPokePic(TRUE, gMonSpritesGfxPtr->sprites.ptr[1], species, (data->isFemale ? FEMALE_PERSONALITY : MALE_PERSONALITY));
|
||||||
data->isShiny = FALSE;
|
data->isShiny = FALSE;
|
||||||
data->isFemale = FALSE;
|
data->isFemale = FALSE;
|
||||||
BattleLoadOpponentMonSpriteGfxCustom(species, data->isFemale, data->isShiny, 1);
|
BattleLoadOpponentMonSpriteGfxCustom(species, data->isFemale, data->isShiny, 1);
|
||||||
@ -1195,7 +1198,7 @@ void CB2_Debug_Pokemon(void)
|
|||||||
LoadAndCreateEnemyShadowSpriteCustom(data, species);
|
LoadAndCreateEnemyShadowSpriteCustom(data, species);
|
||||||
|
|
||||||
//Back
|
//Back
|
||||||
HandleLoadSpecialPokePicCustom(&gMonBackPicTable[species], gMonSpritesGfxPtr->sprites.ptr[2], species, 0, data->isFemale);
|
HandleLoadSpecialPokePic(FALSE, gMonSpritesGfxPtr->sprites.ptr[2], species, (data->isFemale ? FEMALE_PERSONALITY : MALE_PERSONALITY));
|
||||||
BattleLoadOpponentMonSpriteGfxCustom(species, data->isFemale, data->isShiny, 4);
|
BattleLoadOpponentMonSpriteGfxCustom(species, data->isFemale, data->isShiny, 4);
|
||||||
SetMultiuseSpriteTemplateToPokemon(species, 2);
|
SetMultiuseSpriteTemplateToPokemon(species, 2);
|
||||||
offset_y = gMonBackPicCoords[species].y_offset;
|
offset_y = gMonBackPicCoords[species].y_offset;
|
||||||
@ -1205,7 +1208,7 @@ void CB2_Debug_Pokemon(void)
|
|||||||
gSprites[data->backspriteId].oam.priority = 0;
|
gSprites[data->backspriteId].oam.priority = 0;
|
||||||
|
|
||||||
//Icon Sprite
|
//Icon Sprite
|
||||||
data->iconspriteId = CreateMonIconCustom(species, SpriteCB_MonIcon, DEBUG_ICON_X, DEBUG_ICON_Y, 4, data->isShiny, data->isFemale, data->isShiny);
|
data->iconspriteId = CreateMonIcon(species, SpriteCB_MonIcon, DEBUG_ICON_X, DEBUG_ICON_Y, 4, (data->isFemale ? FEMALE_PERSONALITY : MALE_PERSONALITY));
|
||||||
gSprites[data->iconspriteId].oam.priority = 0;
|
gSprites[data->iconspriteId].oam.priority = 0;
|
||||||
|
|
||||||
//Modify Arrows
|
//Modify Arrows
|
||||||
@ -1692,7 +1695,7 @@ static void ReloadPokemonSprites(struct PokemonDebugMenu *data)
|
|||||||
palette = GetMonSpritePalStructCustom(species, data->isFemale, data->isShiny);
|
palette = GetMonSpritePalStructCustom(species, data->isFemale, data->isShiny);
|
||||||
LoadCompressedSpritePalette(palette);
|
LoadCompressedSpritePalette(palette);
|
||||||
//Front
|
//Front
|
||||||
HandleLoadSpecialPokePicCustom(&gMonFrontPicTable[species], gMonSpritesGfxPtr->sprites.ptr[1], species, 0, data->isFemale);
|
HandleLoadSpecialPokePic(TRUE, gMonSpritesGfxPtr->sprites.ptr[1], species, (data->isFemale ? FEMALE_PERSONALITY : MALE_PERSONALITY));
|
||||||
BattleLoadOpponentMonSpriteGfxCustom(species, data->isFemale, data->isShiny, 1);
|
BattleLoadOpponentMonSpriteGfxCustom(species, data->isFemale, data->isShiny, 1);
|
||||||
SetMultiuseSpriteTemplateToPokemon(species, 1);
|
SetMultiuseSpriteTemplateToPokemon(species, 1);
|
||||||
gMultiuseSpriteTemplate.paletteTag = palette->tag;
|
gMultiuseSpriteTemplate.paletteTag = palette->tag;
|
||||||
@ -1705,7 +1708,7 @@ static void ReloadPokemonSprites(struct PokemonDebugMenu *data)
|
|||||||
LoadAndCreateEnemyShadowSpriteCustom(data, species);
|
LoadAndCreateEnemyShadowSpriteCustom(data, species);
|
||||||
|
|
||||||
//Back
|
//Back
|
||||||
HandleLoadSpecialPokePicCustom(&gMonBackPicTable[species], gMonSpritesGfxPtr->sprites.ptr[2], species, 0, data->isFemale);
|
HandleLoadSpecialPokePic(FALSE, gMonSpritesGfxPtr->sprites.ptr[2], species, (data->isFemale ? FEMALE_PERSONALITY : MALE_PERSONALITY));
|
||||||
BattleLoadOpponentMonSpriteGfxCustom(species, data->isFemale, data->isShiny, 5);
|
BattleLoadOpponentMonSpriteGfxCustom(species, data->isFemale, data->isShiny, 5);
|
||||||
SetMultiuseSpriteTemplateToPokemon(species, 2);
|
SetMultiuseSpriteTemplateToPokemon(species, 2);
|
||||||
offset_y = gMonBackPicCoords[species].y_offset;
|
offset_y = gMonBackPicCoords[species].y_offset;
|
||||||
@ -1715,7 +1718,7 @@ static void ReloadPokemonSprites(struct PokemonDebugMenu *data)
|
|||||||
gSprites[data->backspriteId].oam.priority = 0;
|
gSprites[data->backspriteId].oam.priority = 0;
|
||||||
|
|
||||||
//Icon Sprite
|
//Icon Sprite
|
||||||
data->iconspriteId = CreateMonIconCustom(species, SpriteCB_MonIcon, DEBUG_ICON_X, DEBUG_ICON_Y, 4, data->isShiny, data->isFemale, data->isShiny);
|
data->iconspriteId = CreateMonIcon(species, SpriteCB_MonIcon, DEBUG_ICON_X, DEBUG_ICON_Y, 4, (data->isFemale ? FEMALE_PERSONALITY : MALE_PERSONALITY));
|
||||||
gSprites[data->iconspriteId].oam.priority = 0;
|
gSprites[data->iconspriteId].oam.priority = 0;
|
||||||
|
|
||||||
//Modify Arrows
|
//Modify Arrows
|
||||||
|
@ -23,10 +23,6 @@ struct MonIconSpriteTemplate
|
|||||||
|
|
||||||
static u8 CreateMonIconSprite(struct MonIconSpriteTemplate *, s16, s16, u8);
|
static u8 CreateMonIconSprite(struct MonIconSpriteTemplate *, s16, s16, u8);
|
||||||
static void FreeAndDestroyMonIconSprite_(struct Sprite *sprite);
|
static void FreeAndDestroyMonIconSprite_(struct Sprite *sprite);
|
||||||
#if P_ENABLE_DEBUG == TRUE
|
|
||||||
static const u8 *GetMonIconPtrCustom(u16 species, u32 personality, bool8 isFemale);
|
|
||||||
static const u8 *GetMonIconTilesCustom(u16 species, bool8 isFemale);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const u8 *const gMonIconTable[] =
|
const u8 *const gMonIconTable[] =
|
||||||
{
|
{
|
||||||
@ -2596,7 +2592,7 @@ u8 CreateMonIcon(u16 species, void (*callback)(struct Sprite *), s16 x, s16 y, u
|
|||||||
|
|
||||||
if (species > NUM_SPECIES)
|
if (species > NUM_SPECIES)
|
||||||
iconTemplate.paletteTag = POKE_ICON_BASE_PAL_TAG;
|
iconTemplate.paletteTag = POKE_ICON_BASE_PAL_TAG;
|
||||||
else if ((gBaseStats[species].flags & FLAG_GENDER_DIFFERENCE) && GetGenderFromSpeciesAndPersonality(species, personality) == MON_FEMALE)
|
else if (ShouldShowFemaleDifferences(species, personality))
|
||||||
iconTemplate.paletteTag = POKE_ICON_BASE_PAL_TAG + gMonIconPaletteIndicesFemale[species];
|
iconTemplate.paletteTag = POKE_ICON_BASE_PAL_TAG + gMonIconPaletteIndicesFemale[species];
|
||||||
|
|
||||||
spriteId = CreateMonIconSprite(&iconTemplate, x, y, subpriority);
|
spriteId = CreateMonIconSprite(&iconTemplate, x, y, subpriority);
|
||||||
@ -2606,32 +2602,6 @@ u8 CreateMonIcon(u16 species, void (*callback)(struct Sprite *), s16 x, s16 y, u
|
|||||||
return spriteId;
|
return spriteId;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if P_ENABLE_DEBUG == TRUE
|
|
||||||
u8 CreateMonIconCustom(u16 species, void (*callback)(struct Sprite *), s16 x, s16 y, u8 subpriority, u32 personality, bool8 isFemale, bool8 isShiny)
|
|
||||||
{
|
|
||||||
u8 spriteId;
|
|
||||||
struct MonIconSpriteTemplate iconTemplate =
|
|
||||||
{
|
|
||||||
.oam = &sMonIconOamData,
|
|
||||||
.image = GetMonIconPtrCustom(species, personality, isFemale),
|
|
||||||
.anims = sMonIconAnims,
|
|
||||||
.affineAnims = sMonIconAffineAnims,
|
|
||||||
.callback = callback,
|
|
||||||
.paletteTag = POKE_ICON_BASE_PAL_TAG + gMonIconPaletteIndices[species],
|
|
||||||
};
|
|
||||||
|
|
||||||
if (species > NUM_SPECIES)
|
|
||||||
iconTemplate.paletteTag = POKE_ICON_BASE_PAL_TAG;
|
|
||||||
else if ((gBaseStats[species].flags & FLAG_GENDER_DIFFERENCE) && isFemale)
|
|
||||||
iconTemplate.paletteTag = POKE_ICON_BASE_PAL_TAG + gMonIconPaletteIndicesFemale[species];
|
|
||||||
|
|
||||||
spriteId = CreateMonIconSprite(&iconTemplate, x, y, subpriority);
|
|
||||||
|
|
||||||
UpdateMonIconFrame(&gSprites[spriteId]);
|
|
||||||
|
|
||||||
return spriteId;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
u8 CreateMonIconNoPersonality(u16 species, void (*callback)(struct Sprite *), s16 x, s16 y, u8 subpriority)
|
u8 CreateMonIconNoPersonality(u16 species, void (*callback)(struct Sprite *), s16 x, s16 y, u8 subpriority)
|
||||||
{
|
{
|
||||||
@ -2704,13 +2674,6 @@ const u8 *GetMonIconPtr(u16 species, u32 personality)
|
|||||||
return GetMonIconTiles(GetIconSpecies(species, personality), personality);
|
return GetMonIconTiles(GetIconSpecies(species, personality), personality);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if P_ENABLE_DEBUG == TRUE
|
|
||||||
static const u8 *GetMonIconPtrCustom(u16 species, u32 personality, bool8 isFemale)
|
|
||||||
{
|
|
||||||
return GetMonIconTilesCustom(GetIconSpecies(species, personality), isFemale);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void FreeAndDestroyMonIconSprite(struct Sprite *sprite)
|
void FreeAndDestroyMonIconSprite(struct Sprite *sprite)
|
||||||
{
|
{
|
||||||
FreeAndDestroyMonIconSprite_(sprite);
|
FreeAndDestroyMonIconSprite_(sprite);
|
||||||
@ -2772,24 +2735,15 @@ void SpriteCB_MonIcon(struct Sprite *sprite)
|
|||||||
|
|
||||||
const u8 *GetMonIconTiles(u16 species, u32 personality)
|
const u8 *GetMonIconTiles(u16 species, u32 personality)
|
||||||
{
|
{
|
||||||
const u8 *iconSprite = gMonIconTable[species];
|
const u8 *iconSprite;
|
||||||
if ((gBaseStats[species].flags & FLAG_GENDER_DIFFERENCE) && GetGenderFromSpeciesAndPersonality(species, personality) == MON_FEMALE)
|
|
||||||
{
|
if (ShouldShowFemaleDifferences(species, personality))
|
||||||
iconSprite = gMonIconTableFemale[species];
|
iconSprite = gMonIconTableFemale[species];
|
||||||
}
|
else
|
||||||
|
iconSprite = gMonIconTable[species];
|
||||||
|
|
||||||
return iconSprite;
|
return iconSprite;
|
||||||
}
|
}
|
||||||
#if P_ENABLE_DEBUG == TRUE
|
|
||||||
static const u8 *GetMonIconTilesCustom(u16 species, bool8 isFemale)
|
|
||||||
{
|
|
||||||
const u8 *iconSprite = gMonIconTable[species];
|
|
||||||
if ((gBaseStats[species].flags & FLAG_GENDER_DIFFERENCE) && isFemale)
|
|
||||||
{
|
|
||||||
iconSprite = gMonIconTableFemale[species];
|
|
||||||
}
|
|
||||||
return iconSprite;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void TryLoadAllMonIconPalettesAtOffset(u16 offset)
|
void TryLoadAllMonIconPalettesAtOffset(u16 offset)
|
||||||
{
|
{
|
||||||
|
@ -2905,11 +2905,10 @@ static void CreateJumpMonSprite(struct PokemonJumpGfx *jumpGfx, struct PokemonJu
|
|||||||
|
|
||||||
if (buffer && unusedBuffer)
|
if (buffer && unusedBuffer)
|
||||||
{
|
{
|
||||||
HandleLoadSpecialPokePic(
|
HandleLoadSpecialPokePic(TRUE,
|
||||||
&gMonFrontPicTable[monInfo->species],
|
buffer,
|
||||||
buffer,
|
monInfo->species,
|
||||||
monInfo->species,
|
monInfo->personality);
|
||||||
monInfo->personality);
|
|
||||||
|
|
||||||
spriteSheet.data = buffer;
|
spriteSheet.data = buffer;
|
||||||
spriteSheet.tag = multiplayerId;
|
spriteSheet.tag = multiplayerId;
|
||||||
|
@ -3991,7 +3991,7 @@ static void LoadDisplayMonGfx(u16 species, u32 pid)
|
|||||||
|
|
||||||
if (species != SPECIES_NONE)
|
if (species != SPECIES_NONE)
|
||||||
{
|
{
|
||||||
LoadSpecialPokePic(&gMonFrontPicTable[species], sStorage->tileBuffer, species, pid, TRUE);
|
LoadSpecialPokePic(sStorage->tileBuffer, species, pid, TRUE);
|
||||||
LZ77UnCompWram(sStorage->displayMonPalette, sStorage->displayMonPalBuffer);
|
LZ77UnCompWram(sStorage->displayMonPalette, sStorage->displayMonPalBuffer);
|
||||||
CpuCopy32(sStorage->tileBuffer, sStorage->displayMonTilePtr, MON_PIC_SIZE);
|
CpuCopy32(sStorage->tileBuffer, sStorage->displayMonTilePtr, MON_PIC_SIZE);
|
||||||
LoadPalette(sStorage->displayMonPalBuffer, sStorage->displayMonPalOffset, 0x20);
|
LoadPalette(sStorage->displayMonPalBuffer, sStorage->displayMonPalOffset, 0x20);
|
||||||
@ -5109,7 +5109,7 @@ static u16 TryLoadMonIconTiles(u16 species, u32 personality)
|
|||||||
u16 i, offset;
|
u16 i, offset;
|
||||||
|
|
||||||
// Treat female mons as a seperate species as they may have a different icon than males
|
// Treat female mons as a seperate species as they may have a different icon than males
|
||||||
if ((gBaseStats[species].flags & FLAG_GENDER_DIFFERENCE) && GetGenderFromSpeciesAndPersonality(species, personality) == MON_FEMALE)
|
if (ShouldShowFemaleDifferences(species, personality))
|
||||||
species |= 0x8000; // 1 << 15
|
species |= 0x8000; // 1 << 15
|
||||||
|
|
||||||
// Search icon list for this species
|
// Search icon list for this species
|
||||||
@ -5176,7 +5176,7 @@ static struct Sprite *CreateMonIconSprite(u16 species, u32 personality, s16 x, s
|
|||||||
struct SpriteTemplate template = sSpriteTemplate_MonIcon;
|
struct SpriteTemplate template = sSpriteTemplate_MonIcon;
|
||||||
|
|
||||||
species = GetIconSpecies(species, personality);
|
species = GetIconSpecies(species, personality);
|
||||||
if ((gBaseStats[species].flags & FLAG_GENDER_DIFFERENCE) && GetGenderFromSpeciesAndPersonality(species, personality) == MON_FEMALE)
|
if (ShouldShowFemaleDifferences(species, personality))
|
||||||
{
|
{
|
||||||
template.paletteTag = PALTAG_MON_ICON_0 + gMonIconPaletteIndicesFemale[species];
|
template.paletteTag = PALTAG_MON_ICON_0 + gMonIconPaletteIndicesFemale[species];
|
||||||
}
|
}
|
||||||
|
@ -41,13 +41,14 @@
|
|||||||
#include "text.h"
|
#include "text.h"
|
||||||
#include "tv.h"
|
#include "tv.h"
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
|
#include "constants/battle_config.h"
|
||||||
|
#include "constants/battle_move_effects.h"
|
||||||
#include "constants/items.h"
|
#include "constants/items.h"
|
||||||
#include "constants/moves.h"
|
#include "constants/moves.h"
|
||||||
#include "constants/party_menu.h"
|
#include "constants/party_menu.h"
|
||||||
#include "constants/region_map_sections.h"
|
#include "constants/region_map_sections.h"
|
||||||
#include "constants/rgb.h"
|
#include "constants/rgb.h"
|
||||||
#include "constants/songs.h"
|
#include "constants/songs.h"
|
||||||
#include "constants/battle_config.h"
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PSS_PAGE_INFO,
|
PSS_PAGE_INFO,
|
||||||
@ -3730,15 +3731,21 @@ static void PrintContestMoveDescription(u8 moveSlot)
|
|||||||
static void PrintMoveDetails(u16 move)
|
static void PrintMoveDetails(u16 move)
|
||||||
{
|
{
|
||||||
u8 windowId = AddWindowFromTemplateList(sPageMovesTemplate, PSS_DATA_WINDOW_MOVE_DESCRIPTION);
|
u8 windowId = AddWindowFromTemplateList(sPageMovesTemplate, PSS_DATA_WINDOW_MOVE_DESCRIPTION);
|
||||||
|
u8 moveEffect;
|
||||||
FillWindowPixelBuffer(windowId, PIXEL_FILL(0));
|
FillWindowPixelBuffer(windowId, PIXEL_FILL(0));
|
||||||
if (move != MOVE_NONE)
|
if (move != MOVE_NONE)
|
||||||
{
|
{
|
||||||
if (sMonSummaryScreen->currPageIndex == PSS_PAGE_BATTLE_MOVES)
|
if (sMonSummaryScreen->currPageIndex == PSS_PAGE_BATTLE_MOVES)
|
||||||
{
|
{
|
||||||
|
moveEffect = gBattleMoves[move].effect;
|
||||||
if (B_SHOW_SPLIT_ICON == TRUE)
|
if (B_SHOW_SPLIT_ICON == TRUE)
|
||||||
ShowSplitIcon(GetBattleMoveSplit(move));
|
ShowSplitIcon(GetBattleMoveSplit(move));
|
||||||
PrintMovePowerAndAccuracy(move);
|
PrintMovePowerAndAccuracy(move);
|
||||||
PrintTextOnWindow(windowId, gMoveDescriptionPointers[move - 1], 6, 1, 0, 0);
|
|
||||||
|
if (moveEffect != EFFECT_PLACEHOLDER)
|
||||||
|
PrintTextOnWindow(windowId, gMoveDescriptionPointers[move - 1], 6, 1, 0, 0);
|
||||||
|
else
|
||||||
|
PrintTextOnWindow(windowId, gNotDoneYetDescription, 6, 1, 0, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -3980,7 +3987,7 @@ static u8 LoadMonGfxAndSprite(struct Pokemon *mon, s16 *state)
|
|||||||
case 0:
|
case 0:
|
||||||
if (gMain.inBattle)
|
if (gMain.inBattle)
|
||||||
{
|
{
|
||||||
HandleLoadSpecialPokePic(&gMonFrontPicTable[summary->species2],
|
HandleLoadSpecialPokePic(TRUE,
|
||||||
gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_LEFT],
|
gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_LEFT],
|
||||||
summary->species2,
|
summary->species2,
|
||||||
summary->pid);
|
summary->pid);
|
||||||
@ -3989,14 +3996,14 @@ static u8 LoadMonGfxAndSprite(struct Pokemon *mon, s16 *state)
|
|||||||
{
|
{
|
||||||
if (gMonSpritesGfxPtr != NULL)
|
if (gMonSpritesGfxPtr != NULL)
|
||||||
{
|
{
|
||||||
HandleLoadSpecialPokePic(&gMonFrontPicTable[summary->species2],
|
HandleLoadSpecialPokePic(TRUE,
|
||||||
gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_LEFT],
|
gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_LEFT],
|
||||||
summary->species2,
|
summary->species2,
|
||||||
summary->pid);
|
summary->pid);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HandleLoadSpecialPokePic(&gMonFrontPicTable[summary->species2],
|
HandleLoadSpecialPokePic(TRUE,
|
||||||
MonSpritesGfxManager_GetSpritePtr(MON_SPR_GFX_MANAGER_A, B_POSITION_OPPONENT_LEFT),
|
MonSpritesGfxManager_GetSpritePtr(MON_SPR_GFX_MANAGER_A, B_POSITION_OPPONENT_LEFT),
|
||||||
summary->species2,
|
summary->species2,
|
||||||
summary->pid);
|
summary->pid);
|
||||||
|
@ -534,7 +534,7 @@ static void ConditionGraphDrawMonPic(s16 listId, u8 loadId)
|
|||||||
species = GetBoxOrPartyMonData(boxId, monId, MON_DATA_SPECIES2, NULL);
|
species = GetBoxOrPartyMonData(boxId, monId, MON_DATA_SPECIES2, NULL);
|
||||||
tid = GetBoxOrPartyMonData(boxId, monId, MON_DATA_OT_ID, NULL);
|
tid = GetBoxOrPartyMonData(boxId, monId, MON_DATA_OT_ID, NULL);
|
||||||
personality = GetBoxOrPartyMonData(boxId, monId, MON_DATA_PERSONALITY, NULL);
|
personality = GetBoxOrPartyMonData(boxId, monId, MON_DATA_PERSONALITY, NULL);
|
||||||
LoadSpecialPokePic(&gMonFrontPicTable[species], menu->monPicGfx[loadId], species, personality, TRUE);
|
LoadSpecialPokePic(menu->monPicGfx[loadId], species, personality, TRUE);
|
||||||
LZ77UnCompWram(GetMonSpritePalFromSpeciesAndPersonality(species, tid, personality), menu->monPal[loadId]);
|
LZ77UnCompWram(GetMonSpritePalFromSpeciesAndPersonality(species, tid, personality), menu->monPal[loadId]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2734,7 +2734,7 @@ static void LoadTradeMonPic(u8 whichParty, u8 state)
|
|||||||
species = GetMonData(mon, MON_DATA_SPECIES2);
|
species = GetMonData(mon, MON_DATA_SPECIES2);
|
||||||
personality = GetMonData(mon, MON_DATA_PERSONALITY);
|
personality = GetMonData(mon, MON_DATA_PERSONALITY);
|
||||||
|
|
||||||
HandleLoadSpecialPokePic(&gMonFrontPicTable[species], gMonSpritesGfxPtr->sprites.ptr[whichParty * 2 + B_POSITION_OPPONENT_LEFT], species, personality);
|
HandleLoadSpecialPokePic(TRUE, gMonSpritesGfxPtr->sprites.ptr[whichParty * 2 + B_POSITION_OPPONENT_LEFT], species, personality);
|
||||||
|
|
||||||
LoadCompressedSpritePalette(GetMonSpritePalStruct(mon));
|
LoadCompressedSpritePalette(GetMonSpritePalStruct(mon));
|
||||||
sTradeData->monSpecies[whichParty] = species;
|
sTradeData->monSpecies[whichParty] = species;
|
||||||
@ -3727,7 +3727,7 @@ static bool8 AnimateTradeSequenceCable(void)
|
|||||||
case TS_STATE_POKEBALL_ARRIVE_WAIT:
|
case TS_STATE_POKEBALL_ARRIVE_WAIT:
|
||||||
if (gSprites[sTradeData->bouncingPokeballSpriteId].callback == SpriteCallbackDummy)
|
if (gSprites[sTradeData->bouncingPokeballSpriteId].callback == SpriteCallbackDummy)
|
||||||
{
|
{
|
||||||
HandleLoadSpecialPokePic(&gMonFrontPicTable[sTradeData->monSpecies[TRADE_PARTNER]], gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_RIGHT], sTradeData->monSpecies[TRADE_PARTNER], sTradeData->monPersonalities[TRADE_PARTNER]);
|
HandleLoadSpecialPokePic(TRUE, gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_RIGHT], sTradeData->monSpecies[TRADE_PARTNER], sTradeData->monPersonalities[TRADE_PARTNER]);
|
||||||
sTradeData->state++;
|
sTradeData->state++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -4224,7 +4224,7 @@ static bool8 AnimateTradeSequenceWireless(void)
|
|||||||
case TS_STATE_POKEBALL_ARRIVE_WAIT:
|
case TS_STATE_POKEBALL_ARRIVE_WAIT:
|
||||||
if (gSprites[sTradeData->bouncingPokeballSpriteId].callback == SpriteCallbackDummy)
|
if (gSprites[sTradeData->bouncingPokeballSpriteId].callback == SpriteCallbackDummy)
|
||||||
{
|
{
|
||||||
HandleLoadSpecialPokePic(&gMonFrontPicTable[sTradeData->monSpecies[TRADE_PARTNER]],
|
HandleLoadSpecialPokePic(TRUE,
|
||||||
gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_RIGHT],
|
gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_RIGHT],
|
||||||
sTradeData->monSpecies[TRADE_PARTNER],
|
sTradeData->monSpecies[TRADE_PARTNER],
|
||||||
sTradeData->monPersonalities[TRADE_PARTNER]);
|
sTradeData->monPersonalities[TRADE_PARTNER]);
|
||||||
|
@ -59,11 +59,11 @@ static bool16 DecompressPic(u16 species, u32 personality, bool8 isFrontPic, u8 *
|
|||||||
{
|
{
|
||||||
if (isFrontPic)
|
if (isFrontPic)
|
||||||
{
|
{
|
||||||
LoadSpecialPokePic(&gMonFrontPicTable[species], dest, species, personality, isFrontPic);
|
LoadSpecialPokePic(dest, species, personality, isFrontPic);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LoadSpecialPokePic(&gMonBackPicTable[species], dest, species, personality, isFrontPic);
|
LoadSpecialPokePic(dest, species, personality, isFrontPic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
Loading…
x
Reference in New Issue
Block a user