Add B_SHOW_TYPES and cleaned up IsDoubleBattle (#5131)

* First attempt at a port

* Slightly broken but working

* Got images working and opponent palettes

* half finished compressed spritesheet approach instead

* fix the palettes (smh)

* fix hflip, and a lot of clean-up

* Add B_SHOW_TYPES

* Got Illusion working

* Add num type enum

* Updated function to get type

* Fixed type icon position and cleaned up functions

* Updated illusions and Tera handling

* Added BATTLE_TYPE_IS_SINGLE and DOUBLE

* Removed IS_BATTLE_TYPE_SINGLE

* Implemented BATTLE_TYPE_IS_DOUBLE across repo

* Removed SIDE macro

* Updated config

* Deprecated battler alive macro

* Reindented file

* Added exceptions for 2v1

* Replaced Fainted check with Null check

* Added functionality for only types of caught mons

* UseDoubleBattleCoords updated

* Added ShouldFlipTypeIcon

* Renamed TryLoadTypeIcon

* Refactored functions

* Refactored functions

* Refactored functions

* Refactored functions

* Renamed SEEN to CAUGHT

* Reset config

* Added useSecondPalette and isOrdinary to gTypesInfo

* Further simplified secondPalette and isOrdinary

* Changed isordinary to isSpecialCase

* Renamed to useSecondTypeIconPalette

* Fixed Stellar type interactions

* fixed spacing

* fixed include/config/battle.h

* fixed

* fixed include/config/general.h

* changed type1 and type2

* Moved IsDoubleBattle to include.battle.h
Removed BATTLE_TYPE_IS_DOUBLE
Removed IS_DOUBLE_BATTLE

* Changed IsBattlerFainted to IsBattlerAlive

* Removed IsBattlerNull

* Moved GetBattlerData to be inline

* Renamed GetMonDefensiveTeraType

* Removed IsIllusionActive

* Fixed identation

* found one last isDoubleBattle hold out

* fixed redundant brackets

* Fixed spacing for B_SHOW_TYPES

* Update src/battle_script_commands.c

Co-authored-by: Alex <93446519+AlexOn1ine@users.noreply.github.com>

* Fixed padding

* Reindent file and refactored GetTypeIconHideMovement

* Update include/data.h

---------

Co-authored-by: RavePossum <ravepossum@proton.me>
Co-authored-by: Frank <fdeblasio1004@gmail.com>
Co-authored-by: Alex <93446519+AlexOn1ine@users.noreply.github.com>
This commit is contained in:
psf 2024-08-11 08:55:51 -07:00 committed by GitHub
parent 97fa0be36e
commit d1183f4b8a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
38 changed files with 758 additions and 131 deletions

View file

@ -52,7 +52,6 @@ static void SortSprites(u32 *spritePriorities, s32 n);
static u32 CreateSpriteAt(u32 index, const struct SpriteTemplate *template, s16 x, s16 y, u32 subpriority);
static void ResetOamMatrices(void);
static void ResetSprite(struct Sprite *sprite);
static void RequestSpriteFrameImageCopy(u16 index, u16 tileNum, const struct SpriteFrameImage *images);
static void ResetAllSprites(void);
static void BeginAnim(struct Sprite *sprite);
static void ContinueAnim(struct Sprite *sprite);
@ -75,7 +74,6 @@ static void AffineAnimCmd_end(u8 matrixNum, struct Sprite *sprite);
static void AffineAnimCmd_frame(u8 matrixNum, struct Sprite *sprite);
static void CopyOamMatrix(u8 destMatrixIndex, struct OamMatrix *srcMatrix);
static u8 GetSpriteMatrixNum(struct Sprite *sprite);
static void SetSpriteOamFlipBits(struct Sprite *sprite, u8 hFlip, u8 vFlip);
static void AffineAnimStateRestartAnim(u8 matrixNum);
static void AffineAnimStateStartAnim(u8 matrixNum, u8 animNum);
static void AffineAnimStateReset(u8 matrixNum);

View file

@ -331,5 +331,7 @@ u8 SpriteTileAllocBitmapOp(u16 bit, u8 op);
void ClearSpriteCopyRequests(void);
void ResetAffineAnimData(void);
u32 GetSpanPerImage(u32 shape, u32 size);
void RequestSpriteFrameImageCopy(u16 index, u16 tileNum, const struct SpriteFrameImage *images);
void SetSpriteOamFlipBits(struct Sprite *sprite, u8 hFlip, u8 vFlip);
#endif //GUARD_SPRITE_H

View file

@ -0,0 +1,15 @@
JASC-PAL
0100
12
120 152 128
49 49 49
255 255 255
164 82 57
172 189 32
184 160 90
213 180 90
98 98 180
180 90 164
172 164 148
172 172 197
152 172 246

Binary file not shown.

After

Width:  |  Height:  |  Size: 354 B

View file

@ -0,0 +1,15 @@
JASC-PAL
0100
12
120 152 128
49 49 49
255 255 255
240 82 48
120 200 80
248 197 49
80 120 136
123 98 230
248 115 164
57 156 255
90 205 230
246 180 246

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 B

View file

@ -1131,6 +1131,13 @@ static inline u32 GetBattlerSide(u32 battler)
return GetBattlerPosition(battler) & BIT_SIDE;
}
static inline struct Pokemon* GetBattlerData(u32 battlerId)
{
u32 index = gBattlerPartyIndexes[battlerId];
return (GetBattlerSide(battlerId) == B_SIDE_OPPONENT) ? &gEnemyParty[index] : &gPlayerParty[index];
}
static inline struct Pokemon *GetSideParty(u32 side)
{
return (side == B_SIDE_PLAYER) ? gPlayerParty : gEnemyParty;
@ -1141,4 +1148,9 @@ static inline struct Pokemon *GetBattlerParty(u32 battler)
return GetSideParty(GetBattlerSide(battler));
}
static inline bool32 IsDoubleBattle(void)
{
return gBattleTypeFlags & BATTLE_TYPE_DOUBLE;
}
#endif // GUARD_BATTLE_H

View file

@ -194,7 +194,6 @@ u8 GetBattlerSpriteCoord(u8 battlerId, u8 attributeId);
bool8 IsBattlerSpritePresent(u8 battlerId);
void ClearBattleAnimBg(u32 bgId);
u8 GetAnimBattlerSpriteId(u8 wantedBattler);
bool8 IsDoubleBattle(void);
u8 GetBattleBgPaletteNum(void);
u8 GetBattlerSpriteBGPriorityRank(u8 battlerId);
void StoreSpriteCallbackInData6(struct Sprite *sprite, void (*spriteCallback)(struct Sprite *));

View file

@ -310,6 +310,11 @@ void ActionSelectionDestroyCursorAt(u8 cursorPos);
void InitMoveSelectionsVarsAndStrings(u32 battler);
void MoveSelectionCreateCursorAt(u8 cursorPos, u8 arg1);
void MoveSelectionDestroyCursorAt(u8 cursorPosition);
void PlayerHandleChooseMove(u32 battler);
void HandleInputChooseMove(u32 battler);
void HandleInputChooseTarget(u32 battler);
void HandleMoveSwitching(u32 battler);
void HandleChooseMoveAfterDma3(u32 battler);
// recorded player controller
void SetControllerToRecordedPlayer(u32 battler);

View file

@ -273,4 +273,9 @@
#define B_ENEMY_THROW_BALLS_SOUND GEN_LATEST // In GEN_5+, enemy Trainer's Poké Balls make a sound when thrown to send out a Pokémon. This can only be used when B_ENEMY_THROW_BALLS is set to GEN_6 or later.
#define B_PLAYER_THROW_BALLS_SOUND GEN_LATEST // In GEN_5+, the player's Poké Balls make a sound when thrown to send out a Pokémon.
#define SHOW_TYPES_NEVER 0
#define SHOW_TYPES_ALWAYS 1
#define SHOW_TYPES_CAUGHT 2
#define B_SHOW_TYPES SHOW_TYPES_NEVER // When defined as SHOW_TYPES_ALWAYS, after selecting "Fight" in battle, the types of all Pokemon are revealed. Whe defined as SHOW_TYPES_OWN, types are only revealed if the player owns the mon in question.
#endif // GUARD_CONFIG_BATTLE_H

View file

@ -89,7 +89,6 @@
#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 | BATTLE_TYPE_INGAME_PARTNER)
// Battle Outcome defines
#define B_OUTCOME_WON 1
#define B_OUTCOME_LOST 2

View file

@ -110,7 +110,9 @@ struct TypeInfo
u16 maxMove;
u16 teraTypeRGBValue; // Most values pulled from the Tera type icon palette.
u16 damageCategory:2; // Used for B_PHYSICAL_SPECIAL_SPLIT <= GEN_3
u16 padding:14;
u16 useSecondTypeIconPalette:1;
u16 isSpecialCaseType:1;
u16 padding:12;
const u32 *const paletteTMHM;
//u16 enhanceItem;
//u16 berry;

View file

@ -3363,4 +3363,9 @@ extern const u8 gMailTilemap_Retro[];
extern const u8 gMonMarkingsMenu_Gfx[];
extern const u16 gMonMarkingsMenu_Pal[];
extern const u32 gBattleIcons_Gfx1[];
extern const u32 gBattleIcons_Gfx2[];
extern const u32 gBattleIcons_Pal1[];
extern const u32 gBattleIcons_Pal2[];
#endif //GUARD_GRAPHICS_H

18
include/type_icons.h Normal file
View file

@ -0,0 +1,18 @@
#ifndef GUARD_TYPE_ICONS_H
#define GUARD_TYPE_ICONS_H
void LoadTypeIcons(u32);
#define TYPE_ICON_TAG 0x2720
#define TYPE_ICON_TAG_2 0x2721
#define NUM_FRAMES_HIDE_TYPE_ICON 10
#define tMonPosition data[0]
#define tBattlerId data[1]
#define tHideIconTimer data[2]
#define tVerticalPosition data[3]
#define TYPE_ICON_1_FRAME(monType) ((monType - 1) * 2)
#define TYPE_ICON_2_FRAME(monType) ((monType - 11) * 2)
#endif // GUARD_TYPE_ICONS_H

View file

@ -174,7 +174,7 @@ static u32 GetAiFlags(u16 trainerId)
flags = GetTrainerAIFlagsFromId(trainerId);
}
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
if (IsDoubleBattle())
{
flags |= AI_FLAG_DOUBLE_BATTLE;
}
@ -224,7 +224,7 @@ void BattleAI_SetupFlags(void)
{
AI_THINKING_STRUCT->aiFlags[B_POSITION_PLAYER_RIGHT] = GetAiFlags(gPartnerTrainerId - TRAINER_PARTNER(PARTNER_NONE));
}
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && IsAiVsAiBattle())
else if (IsDoubleBattle() && IsAiVsAiBattle())
{
AI_THINKING_STRUCT->aiFlags[B_POSITION_PLAYER_RIGHT] = AI_THINKING_STRUCT->aiFlags[B_POSITION_PLAYER_LEFT];
}
@ -275,7 +275,7 @@ u32 BattleAI_ChooseMoveOrAction(void)
{
u32 ret;
if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
if (!IsDoubleBattle())
ret = ChooseMoveOrAction_Singles(sBattler_AI);
else
ret = ChooseMoveOrAction_Doubles(sBattler_AI);
@ -323,7 +323,7 @@ void Ai_InitPartyStruct(void)
// Save first 2 or 4(in doubles) mons
CopyBattlerDataToAIParty(B_POSITION_PLAYER_LEFT, B_SIDE_PLAYER);
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
if (IsDoubleBattle())
CopyBattlerDataToAIParty(B_POSITION_PLAYER_RIGHT, B_SIDE_PLAYER);
// If player's partner is AI, save opponent mons
@ -2050,7 +2050,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
}
/*if (AI_THINKING_STRUCT->aiFlags[battlerAtk] == AI_SCRIPT_CHECK_BAD_MOVE //Only basic AI
&& IS_DOUBLE_BATTLE) //Make the regular AI know how to use Protect minimally in Doubles
&& IsDoubleBattle()) //Make the regular AI know how to use Protect minimally in Doubles
{
u8 shouldProtect = ShouldProtect(battlerAtk, battlerDef, move);
if (shouldProtect == USE_PROTECT || shouldProtect == PROTECT_FROM_FOES)

View file

@ -82,7 +82,7 @@ static bool32 HasBadOdds(u32 battler, bool32 emitResult)
return FALSE;
// Double Battles aren't included in AI_FLAG_SMART_MON_CHOICE. Defaults to regular switch in logic
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
if (IsDoubleBattle())
return FALSE;
opposingPosition = BATTLE_OPPOSITE(GetBattlerPosition(battler));
@ -242,7 +242,7 @@ static bool32 ShouldSwitchIfWonderGuard(u32 battler, bool32 emitResult)
struct Pokemon *party = NULL;
u16 move;
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
if (IsDoubleBattle())
return FALSE;
opposingPosition = BATTLE_OPPOSITE(GetBattlerPosition(battler));
@ -318,7 +318,7 @@ static bool32 FindMonThatAbsorbsOpponentsMove(u32 battler, bool32 emitResult)
if (IS_MOVE_STATUS(gLastLandedMoves[battler]))
return FALSE;
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
if (IsDoubleBattle())
{
battlerIn1 = battler;
if (gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler)))])
@ -707,7 +707,7 @@ static bool32 HasSuperEffectiveMoveAgainstOpponents(u32 battler, bool32 noRng)
}
}
}
if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
if (!IsDoubleBattle())
return FALSE;
opposingBattler = GetBattlerAtPosition(BATTLE_PARTNER(opposingPosition));
@ -765,7 +765,7 @@ static bool32 FindMonWithFlagsAndSuperEffective(u32 battler, u16 flags, u32 modu
if (IS_MOVE_STATUS(gLastLandedMoves[battler]))
return FALSE;
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
if (IsDoubleBattle())
{
battlerIn1 = battler;
if (gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler)))])
@ -846,7 +846,7 @@ static bool32 CanMonSurviveHazardSwitchin(u32 battler)
// Battler will faint to hazards, check to see if another mon can clear them
if (hazardDamage > battlerHp)
{
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
if (IsDoubleBattle())
{
battlerIn1 = battler;
if (gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler)))])
@ -1023,7 +1023,7 @@ bool32 ShouldSwitch(u32 battler, bool32 emitResult)
availableToSwitch = 0;
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
if (IsDoubleBattle())
{
battlerIn1 = battler;
if (gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler)))])
@ -1140,7 +1140,7 @@ void AI_TrySwitchOrUseItem(u32 battler)
s32 monToSwitchId = AI_DATA->mostSuitableMonId[battler];
if (monToSwitchId == PARTY_SIZE)
{
if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
if (!IsDoubleBattle())
{
battlerIn1 = GetBattlerAtPosition(battlerPosition);
battlerIn2 = battlerIn1;
@ -2040,7 +2040,7 @@ u32 GetMostSuitableMonToSwitchInto(u32 battler, bool32 switchAfterMonKOd)
if (gBattleTypeFlags & BATTLE_TYPE_ARENA)
return gBattlerPartyIndexes[battler] + 1;
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
if (IsDoubleBattle())
{
battlerIn1 = battler;
if (gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler)))])
@ -2074,7 +2074,7 @@ u32 GetMostSuitableMonToSwitchInto(u32 battler, bool32 switchAfterMonKOd)
// Split ideal mon decision between after previous mon KO'd (prioritize offensive options) and after switching active mon out (prioritize defensive options), and expand the scope of both.
// Only use better mon selection if AI_FLAG_SMART_MON_CHOICES is set for the trainer.
if (AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_SMART_MON_CHOICES && !(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) // Double Battles aren't included in AI_FLAG_SMART_MON_CHOICE. Defaults to regular switch in logic
if (AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_SMART_MON_CHOICES && !IsDoubleBattle()) // Double Battles aren't included in AI_FLAG_SMART_MON_CHOICE. Defaults to regular switch in logic
{
bestMonId = GetBestMonIntegrated(party, firstId, lastId, battler, opposingBattler, battlerIn1, battlerIn2, switchAfterMonKOd);
return bestMonId;

View file

@ -3026,7 +3026,7 @@ bool32 AnyPartyMemberStatused(u32 battlerId, bool32 checkSoundproof)
else
party = gEnemyParty;
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
if (IsDoubleBattle())
{
battlerOnField1 = gBattlerPartyIndexes[battlerId];
battlerOnField2 = gBattlerPartyIndexes[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battlerId)))];
@ -3417,7 +3417,7 @@ s32 CountUsablePartyMons(u32 battlerId)
else
party = gEnemyParty;
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
if (IsDoubleBattle())
{
battlerOnField1 = gBattlerPartyIndexes[battlerId];
battlerOnField2 = gBattlerPartyIndexes[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battlerId)))];
@ -3828,7 +3828,7 @@ bool32 AI_MoveMakesContact(u32 ability, u32 holdEffect, u32 move)
bool32 ShouldUseZMove(u32 battlerAtk, u32 battlerDef, u32 chosenMove)
{
// simple logic. just upgrades chosen move to z move if possible, unless regular move would kill opponent
if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && battlerDef == BATTLE_PARTNER(battlerAtk))
if ((IsDoubleBattle()) && battlerDef == BATTLE_PARTNER(battlerAtk))
return FALSE; // don't use z move on partner
if (HasTrainerUsedGimmick(battlerAtk, GIMMICK_Z_MOVE))
return FALSE; // can't use z move twice

View file

@ -3317,7 +3317,7 @@ static void AnimSolarBeamSmallOrb(struct Sprite *sprite)
{
InitSpritePosToAnimAttacker(sprite, TRUE);
if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && gAnimMoveIndex == MOVE_CORE_ENFORCER)
if (IsDoubleBattle() && gAnimMoveIndex == MOVE_CORE_ENFORCER)
{
CoreEnforcerLoadBeamTarget(sprite);
}
@ -6567,11 +6567,11 @@ void PrepareDoubleTeamAnim(u32 taskId, u32 animBattler, bool32 forAllySwitch)
gSprites[spriteId].sBattlerFlank = (animBattler != ANIM_ATTACKER);
else
gSprites[spriteId].sBattlerFlank = (animBattler == ANIM_ATTACKER);
// correct direction on opponent side
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_OPPONENT)
gSprites[spriteId].sBattlerFlank ^= 1;
gSprites[spriteId].callback = AnimDoubleTeam;
task->tBlendSpritesCount++;
}
@ -6603,7 +6603,7 @@ static void ReloadBattlerSprites(u32 battler, struct Pokemon *party)
UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], mon, HEALTHBOX_ALL);
// If battler has an indicator for a gimmick, hide the sprite until the move animation finishes.
UpdateIndicatorVisibilityAndType(gHealthboxSpriteIds[battler], TRUE);
// Try to recreate shadow sprite
if (gBattleSpritesDataPtr->healthBoxesData[battler].shadowSpriteId < MAX_SPRITES)
{

View file

@ -1726,7 +1726,7 @@ void AnimTask_AirCutterProjectile(u8 taskId)
attackerX = gTasks[taskId].data[9] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X);
attackerY = gTasks[taskId].data[10] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y);
if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
if (IsDoubleBattle()
&& IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimTarget)))
{
SetAverageBattlerPositions(gBattleAnimTarget, FALSE, &targetX, &targetY);
@ -3854,7 +3854,7 @@ static void AnimPerishSongMusicNote_Step2(struct Sprite *sprite)
static void AnimGuardRing(struct Sprite *sprite)
{
if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimAttacker)))
if (IsDoubleBattle() && IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimAttacker)))
{
SetAverageBattlerPositions(gBattleAnimAttacker, FALSE, &sprite->x, &sprite->y);
sprite->y += 40;

View file

@ -17,8 +17,6 @@
#include "util.h"
#include "constants/battle_anim.h"
#define IS_DOUBLE_BATTLE() ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
extern const struct OamData gOamData_AffineNormal_ObjNormal_64x64;
static void AnimTranslateLinear_WithFollowup_SetCornerVecX(struct Sprite *sprite);
@ -868,11 +866,6 @@ bool8 IsBattlerSpritePresent(u8 battlerId)
}
}
bool8 IsDoubleBattle(void)
{
return IS_DOUBLE_BATTLE();
}
#define BG_ANIM_PAL_1 8
#define BG_ANIM_PAL_2 9
#define BG_ANIM_PAL_CONTEST 14

View file

@ -7250,7 +7250,7 @@ static u8 LoadBattleAnimTarget(u8 arg)
{
u8 battler;
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
if (IsDoubleBattle())
{
switch (gBattleAnimArgs[arg])
{
@ -7281,7 +7281,7 @@ static u8 LoadBattleAnimTarget(u8 arg)
static u8 GetProperCentredCoord(u8 battler, u8 coordType)
{
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
if (IsDoubleBattle())
return (GetBattlerSpriteCoord2(battler, coordType) + GetBattlerSpriteCoord2(BATTLE_PARTNER(battler), coordType)) / 2;
return GetBattlerSpriteCoord(battler, coordType);
@ -7471,14 +7471,14 @@ static void SpriteCB_SpriteToCentreOfSide(struct Sprite *sprite)
if (gBattleAnimArgs[2] == 0) //Attacker
{
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
if (IsDoubleBattle())
InitSpritePosToAnimAttackersCentre(sprite, var);
else
InitSpritePosToAnimAttacker(sprite, var);
}
else
{
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
if (IsDoubleBattle())
InitSpritePosToAnimTargetsCentre(sprite, var);
else
InitSpritePosToAnimTarget(sprite, var);
@ -7562,7 +7562,7 @@ static void SpriteCB_GrowingSuperpower(struct Sprite *sprite)
static void SpriteCB_CentredSpiderWeb(struct Sprite *sprite)
{
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
if (IsDoubleBattle())
InitSpritePosToAnimTargetsCentre(sprite, FALSE);
else
InitSpritePosToAnimTarget(sprite, FALSE);
@ -7576,14 +7576,14 @@ static void SpriteCB_CoreEnforcerHits(struct Sprite *sprite)
if (gBattleAnimArgs[2] == 0)
{
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
if (IsDoubleBattle())
InitSpritePosToAnimAttackersCentre(sprite, FALSE);
else
InitSpritePosToAnimAttacker(sprite, FALSE);
}
else
{
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
if (IsDoubleBattle())
InitSpritePosToAnimTargetsCentre(sprite, FALSE);
else
InitSpritePosToAnimTarget(sprite, FALSE);
@ -7595,7 +7595,7 @@ static void SpriteCB_CoreEnforcerHits(struct Sprite *sprite)
static void SpriteCB_CoreEnforcerBeam(struct Sprite *sprite)
{
if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
if (!IsDoubleBattle())
{
AnimSolarBeamBigOrb(sprite);
}
@ -7867,14 +7867,14 @@ void SpriteCB_RandomCentredHits(struct Sprite *sprite)
if (gBattleAnimArgs[0] == 0)
{
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
if (IsDoubleBattle())
InitSpritePosToAnimAttackersCentre(sprite, FALSE);
else
InitSpritePosToAnimAttacker(sprite, FALSE);
}
else
{
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
if (IsDoubleBattle())
InitSpritePosToAnimTargetsCentre(sprite, FALSE);
else
InitSpritePosToAnimTarget(sprite, FALSE);
@ -8179,7 +8179,7 @@ static void SpriteCB_BeamUpStep(struct Sprite *sprite)
static void SpriteCB_CentredElectricity(struct Sprite *sprite)
{
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
if (IsDoubleBattle())
InitSpritePosToAnimTargetsCentre(sprite, FALSE);
else
InitSpritePosToAnimTarget(sprite, FALSE);

View file

@ -581,7 +581,7 @@ static void OpponentHandleChooseMove(u32 battler)
if (GetBattlerMoveTargetType(battler, move) & (MOVE_TARGET_USER_OR_SELECTED | MOVE_TARGET_USER))
BtlController_EmitTwoReturnValues(battler, BUFFER_B, 10, (chosenMoveId) | (battler << 8));
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
else if (IsDoubleBattle())
{
do {
target = GetBattlerAtPosition(Random() & 2);
@ -653,7 +653,7 @@ static void OpponentHandleChoosePokemon(u32 battler)
{
s32 battler1, battler2, firstId, lastId;
if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
if (!IsDoubleBattle())
{
battler2 = battler1 = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
}

View file

@ -44,6 +44,7 @@
#include "level_caps.h"
#include "menu.h"
#include "pokemon_summary_screen.h"
#include "type_icons.h"
static void PlayerBufferExecCompleted(u32 battler);
static void PlayerHandleLoadMonSprite(u32 battler);
@ -59,7 +60,6 @@ static void PlayerHandlePrintString(u32 battler);
static void PlayerHandlePrintSelectionString(u32 battler);
static void PlayerHandleChooseAction(u32 battler);
static void PlayerHandleYesNoBox(u32 battler);
static void PlayerHandleChooseMove(u32 battler);
static void PlayerHandleChooseItem(u32 battler);
static void PlayerHandleChoosePokemon(u32 battler);
static void PlayerHandleCmd23(u32 battler);
@ -81,14 +81,11 @@ static void PlayerHandleEndLinkBattle(u32 battler);
static void PlayerHandleBattleDebug(u32 battler);
static void PlayerBufferRunCommand(u32 battler);
static void HandleInputChooseTarget(u32 battler);
static void HandleInputChooseMove(u32 battler);
static void MoveSelectionDisplayPpNumber(u32 battler);
static void MoveSelectionDisplayPpString(u32 battler);
static void MoveSelectionDisplayMoveType(u32 battler);
static void MoveSelectionDisplayMoveNames(u32 battler);
static void MoveSelectionDisplayMoveDescription(u32 battler);
static void HandleMoveSwitching(u32 battler);
static void SwitchIn_HandleSoundAndEnd(u32 battler);
static void WaitForMonSelection(u32 battler);
static void CompleteWhenChoseItem(u32 battler);
@ -382,7 +379,7 @@ static void HandleInputChooseAction(u32 battler)
}
else if (JOY_NEW(B_BUTTON) || gPlayerDpadHoldFrames > 59)
{
if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
if (IsDoubleBattle()
&& GetBattlerPosition(battler) == B_POSITION_PLAYER_RIGHT
&& !(gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)])
&& !(gBattleTypeFlags & BATTLE_TYPE_MULTI))
@ -426,7 +423,7 @@ static void HandleInputChooseAction(u32 battler)
}
}
static void HandleInputChooseTarget(u32 battler)
void HandleInputChooseTarget(u32 battler)
{
s32 i;
static const u8 identities[MAX_BATTLERS_COUNT] = {B_POSITION_PLAYER_LEFT, B_POSITION_PLAYER_RIGHT, B_POSITION_OPPONENT_RIGHT, B_POSITION_OPPONENT_LEFT};
@ -662,7 +659,7 @@ static void TryShowAsTarget(u32 battler)
}
}
static void HandleInputChooseMove(u32 battler)
void HandleInputChooseMove(u32 battler)
{
u16 moveTarget;
u32 canSelectTarget = 0;
@ -968,7 +965,7 @@ static u32 UNUSED HandleMoveInputUnused(u32 battler)
return var;
}
static void HandleMoveSwitching(u32 battler)
void HandleMoveSwitching(u32 battler)
{
u8 perMovePPBonuses[MAX_MON_MOVES];
struct ChooseMoveStruct moveStruct;
@ -1757,7 +1754,7 @@ static void MoveSelectionDisplayMoveType(u32 battler)
}
else
{
end = StringCopy(txtPtr, gTypesInfo[type].name);
end = StringCopy(txtPtr, gTypesInfo[type].name);
}
PrependFontIdToFit(txtPtr, end, FONT_NORMAL, WindowWidthPx(B_WIN_MOVE_TYPE) - 25);
@ -2075,7 +2072,7 @@ static void PlayerHandleYesNoBox(u32 battler)
}
}
static void HandleChooseMoveAfterDma3(u32 battler)
void HandleChooseMoveAfterDma3(u32 battler)
{
if (!IsDma3ManagerBusyWithBgCopy())
{
@ -2097,7 +2094,7 @@ static void PlayerChooseMoveInBattlePalace(u32 battler)
}
}
static void PlayerHandleChooseMove(u32 battler)
void PlayerHandleChooseMove(u32 battler)
{
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
{
@ -2125,6 +2122,7 @@ static void PlayerHandleChooseMove(u32 battler)
void InitMoveSelectionsVarsAndStrings(u32 battler)
{
LoadTypeIcons(battler);
MoveSelectionDisplayMoveNames(battler);
gMultiUsePlayerCursor = 0xFF;
MoveSelectionCreateCursorAt(gMoveSelectionCursor[battler], 0);

View file

@ -175,7 +175,7 @@ static void InitSinglePlayerBtlControllers(void)
gBattlerPartyIndexes[3] = 3;
}
}
else if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
else if (!IsDoubleBattle())
{
gBattleMainFunc = BeginBattleIntro;
@ -417,7 +417,7 @@ static void InitLinkBtlControllers(void)
s32 i;
u8 multiplayerId;
if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
if (!IsDoubleBattle())
{
if (gBattleTypeFlags & BATTLE_TYPE_IS_MASTER)
{
@ -442,7 +442,7 @@ static void InitLinkBtlControllers(void)
gBattlersCount = 2;
}
}
else if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) && gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
else if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) && IsDoubleBattle())
{
if (gBattleTypeFlags & BATTLE_TYPE_IS_MASTER)
{
@ -610,7 +610,7 @@ static void InitLinkBtlControllers(void)
bool32 IsValidForBattle(struct Pokemon *mon)
{
u32 species = GetMonData(mon, MON_DATA_SPECIES_OR_EGG);
return (species != SPECIES_NONE
return (species != SPECIES_NONE
&& species != SPECIES_EGG
&& GetMonData(mon, MON_DATA_HP) != 0
&& GetMonData(mon, MON_DATA_IS_EGG) == FALSE);

View file

@ -309,7 +309,7 @@ static u8 GetBattlePalaceMoveGroup(u8 battler, u16 move)
static u16 GetBattlePalaceTarget(u32 battler)
{
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
if (IsDoubleBattle())
{
u8 opposing1, opposing2;

View file

@ -96,7 +96,7 @@ bool32 ShouldTrainerBattlerUseGimmick(u32 battler, enum Gimmick gimmick)
bool32 HasTrainerUsedGimmick(u32 battler, enum Gimmick gimmick)
{
// Check whether partner battler has used gimmick or plans to during turn.
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
if (IsDoubleBattle()
&& IsPartnerMonFromSameTrainer(battler)
&& (gBattleStruct->gimmick.activated[BATTLE_PARTNER(battler)][gimmick]
|| ((gBattleStruct->gimmick.toActivate & gBitTable[BATTLE_PARTNER(battler)]
@ -115,7 +115,7 @@ bool32 HasTrainerUsedGimmick(u32 battler, enum Gimmick gimmick)
void SetGimmickAsActivated(u32 battler, enum Gimmick gimmick)
{
gBattleStruct->gimmick.activated[battler][gimmick] = TRUE;
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && IsPartnerMonFromSameTrainer(battler))
if (IsDoubleBattle() && IsPartnerMonFromSameTrainer(battler))
gBattleStruct->gimmick.activated[BATTLE_PARTNER(battler)][gimmick] = TRUE;
}
@ -155,7 +155,7 @@ void CreateGimmickTriggerSprite(u32 battler)
if (gBattleStruct->gimmick.triggerSpriteId == 0xFF)
{
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
if (IsDoubleBattle())
gBattleStruct->gimmick.triggerSpriteId = CreateSprite(gimmick->triggerTemplate,
gSprites[gHealthboxSpriteIds[battler]].x - DOUBLES_GIMMICK_TRIGGER_POS_X_SLIDE,
gSprites[gHealthboxSpriteIds[battler]].y - DOUBLES_GIMMICK_TRIGGER_POS_Y_DIFF, 0);
@ -204,7 +204,7 @@ static void SpriteCb_GimmickTrigger(struct Sprite *sprite)
s32 xSlide, xPriority, xOptimal;
s32 yDiff;
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
if (IsDoubleBattle())
{
xSlide = DOUBLES_GIMMICK_TRIGGER_POS_X_SLIDE;
xPriority = DOUBLES_GIMMICK_TRIGGER_POS_X_PRIORITY;

View file

@ -4136,7 +4136,7 @@ void SwitchPartyOrder(u32 battler)
partyId2 = GetPartyIdFromBattlePartyId(*(gBattleStruct->monToSwitchIntoId + battler));
SwitchPartyMonSlots(partyId1, partyId2);
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
if (IsDoubleBattle())
{
for (i = 0; i < (int)ARRAY_COUNT(gBattlePartyCurrentOrder); i++)
{
@ -4277,7 +4277,7 @@ static void HandleTurnActionSelectionState(void)
i);
}
BtlController_EmitChooseMove(battler, BUFFER_A, (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) != 0, FALSE, &moveInfo);
BtlController_EmitChooseMove(battler, BUFFER_A, IsDoubleBattle() != 0, FALSE, &moveInfo);
MarkBattlerForControllerExec(battler);
}
break;
@ -4570,7 +4570,7 @@ static void HandleTurnActionSelectionState(void)
else
i = FALSE;
if (((gBattleTypeFlags & BATTLE_TYPE_MULTI) || !(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
if (((gBattleTypeFlags & BATTLE_TYPE_MULTI) || !IsDoubleBattle())
|| (position & BIT_FLANK) != B_FLANK_LEFT
|| (*(&gBattleStruct->absentBattlerFlags) & gBitTable[GetBattlerAtPosition(BATTLE_PARTNER(position))]))
{

View file

@ -2826,7 +2826,7 @@ void BufferStringBattle(u16 stringID, u32 battler)
{
if (gBattleTypeFlags & BATTLE_TYPE_LEGENDARY)
stringPtr = sText_LegendaryPkmnAppeared;
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && IsValidForBattle(&gEnemyParty[gBattlerPartyIndexes[GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT)]]))
else if (IsDoubleBattle() && IsValidForBattle(&gEnemyParty[gBattlerPartyIndexes[GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT)]]))
stringPtr = sText_TwoWildPkmnAppeared;
else if (gBattleTypeFlags & BATTLE_TYPE_WALLY_TUTORIAL)
stringPtr = sText_WildPkmnAppearedPause;
@ -2837,7 +2837,7 @@ void BufferStringBattle(u16 stringID, u32 battler)
case STRINGID_INTROSENDOUT: // poke first send-out
if (GetBattlerSide(battler) == B_SIDE_PLAYER)
{
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && IsValidForBattle(&gPlayerParty[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]]))
if (IsDoubleBattle() && IsValidForBattle(&gPlayerParty[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]]))
{
if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)
stringPtr = sText_InGamePartnerSentOutZGoN;
@ -2855,7 +2855,7 @@ void BufferStringBattle(u16 stringID, u32 battler)
}
else
{
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && IsValidForBattle(&gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]]))
if (IsDoubleBattle() && IsValidForBattle(&gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]]))
{
if (BATTLE_TWO_VS_ONE_OPPONENT)
stringPtr = sText_Trainer1SentOutTwoPkmn;
@ -2886,7 +2886,7 @@ void BufferStringBattle(u16 stringID, u32 battler)
{
if (*(&gBattleStruct->hpScale) == 0)
stringPtr = sText_PkmnThatsEnough;
else if (*(&gBattleStruct->hpScale) == 1 || gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
else if (*(&gBattleStruct->hpScale) == 1 || IsDoubleBattle())
stringPtr = sText_PkmnComeBack;
else if (*(&gBattleStruct->hpScale) == 2)
stringPtr = sText_PkmnOkComeBack;
@ -2911,7 +2911,7 @@ void BufferStringBattle(u16 stringID, u32 battler)
case STRINGID_SWITCHINMON: // switch-in msg
if (GetBattlerSide(gBattleScripting.battler) == B_SIDE_PLAYER)
{
if (*(&gBattleStruct->hpScale) == 0 || gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
if (*(&gBattleStruct->hpScale) == 0 || IsDoubleBattle())
stringPtr = sText_GoPkmn2;
else if (*(&gBattleStruct->hpScale) == 1)
stringPtr = sText_DoItPkmn;

View file

@ -1752,7 +1752,7 @@ static void AccuracyCheck(bool32 recalcDragonDarts, const u8 *nextInstr, const u
return;
}
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE &&
if (IsDoubleBattle() &&
(moveTarget == MOVE_TARGET_BOTH || moveTarget == MOVE_TARGET_FOES_AND_ALLY))
gBattleCommunication[MISS_TYPE] = B_MSG_AVOIDED_ATK;
else
@ -2498,7 +2498,7 @@ static void Cmd_resultmessage(void)
if (gMoveResultFlags & MOVE_RESULT_MISSED && (!(gMoveResultFlags & MOVE_RESULT_DOESNT_AFFECT_FOE) || gBattleCommunication[MISS_TYPE] > B_MSG_AVOIDED_ATK))
{
if (gBattleCommunication[MISS_TYPE] > B_MSG_AVOIDED_ATK) // Wonder Guard or Levitate - show the ability pop-up
CreateAbilityPopUp(gBattlerTarget, gBattleMons[gBattlerTarget].ability, (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) != 0);
CreateAbilityPopUp(gBattlerTarget, gBattleMons[gBattlerTarget].ability, (IsDoubleBattle()) != 0);
stringId = gMissStringIds[gBattleCommunication[MISS_TYPE]];
gBattleCommunication[MSG_DISPLAY] = 1;
}
@ -4352,7 +4352,7 @@ static void Cmd_getexp(void)
{
// Music change in a wild battle after fainting opposing pokemon.
if (!(gBattleTypeFlags & BATTLE_TYPE_TRAINER)
&& (gBattleMons[0].hp || (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && gBattleMons[2].hp))
&& (gBattleMons[0].hp || (IsDoubleBattle() && gBattleMons[2].hp))
&& !IsBattlerAlive(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT))
&& !IsBattlerAlive(GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT))
&& !gBattleStruct->wildVictorySong)
@ -4403,7 +4403,7 @@ static void Cmd_getexp(void)
}
// get exp getter battler
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
if (IsDoubleBattle())
{
if (gBattlerPartyIndexes[2] == *expMonId && !(gAbsentBattlerFlags & gBitTable[2]))
gBattleStruct->expGetterBattlerId = 2;
@ -4483,7 +4483,7 @@ static void Cmd_getexp(void)
// update battle mon structure after level up
if (gBattlerPartyIndexes[0] == *expMonId && gBattleMons[0].hp)
battler = 0;
else if (gBattlerPartyIndexes[2] == *expMonId && gBattleMons[2].hp && (gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
else if (gBattlerPartyIndexes[2] == *expMonId && gBattleMons[2].hp && (IsDoubleBattle()))
battler = 2;
if (battler != 0xFF)
@ -5919,7 +5919,7 @@ static void Cmd_moveend(void)
gBattleStruct->targetsDone[gBattlerAttacker] |= gBitTable[gBattlerTarget];
if (!(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE)
&& gBattleTypeFlags & BATTLE_TYPE_DOUBLE
&& IsDoubleBattle()
&& !gProtectStructs[gBattlerAttacker].chargingTurn
&& (moveTarget == MOVE_TARGET_BOTH
|| moveTarget == MOVE_TARGET_FOES_AND_ALLY)
@ -6689,7 +6689,7 @@ bool32 CanBattlerSwitch(u32 battler)
{
battlerIn1 = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
if (IsDoubleBattle())
battlerIn2 = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT);
else
battlerIn2 = battlerIn1;
@ -6701,7 +6701,7 @@ bool32 CanBattlerSwitch(u32 battler)
// Check if attacker side has mon to switch into
battlerIn1 = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
if (IsDoubleBattle())
battlerIn2 = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT);
else
battlerIn2 = battlerIn1;
@ -6765,7 +6765,7 @@ static void Cmd_openpartyscreen(void)
if (cmd->battler == BS_FAINTED_MULTIPLE_1)
{
if ((gBattleTypeFlags & BATTLE_TYPE_MULTI) || !(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
if ((gBattleTypeFlags & BATTLE_TYPE_MULTI) || !(IsDoubleBattle()))
{
for (battler = 0; battler < gBattlersCount; battler++)
{
@ -6791,7 +6791,7 @@ static void Cmd_openpartyscreen(void)
}
}
}
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
else if (IsDoubleBattle())
{
bool8 hasReplacement_0, hasReplacement_1, hasReplacement_2, hasReplacement_3;
@ -6922,7 +6922,7 @@ static void Cmd_openpartyscreen(void)
{
if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI))
{
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
if (IsDoubleBattle())
{
hitmarkerFaintBits = gHitMarker >> 28;
if (gBitTable[2] & hitmarkerFaintBits && gBitTable[0] & hitmarkerFaintBits)
@ -7466,7 +7466,7 @@ static void Cmd_handlelearnnewmove(void)
{
GiveMoveToBattleMon(&gBattleMons[battler], learnMove);
}
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
if (IsDoubleBattle())
{
battler = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT);
if (gBattlerPartyIndexes[battler] == monId
@ -7572,7 +7572,7 @@ static void Cmd_yesnoboxlearnmove(void)
RemoveBattleMonPPBonus(&gBattleMons[0], movePosition);
SetBattleMonMoveSlot(&gBattleMons[0], gMoveToLearn, movePosition);
}
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
if (IsDoubleBattle()
&& gBattlerPartyIndexes[2] == gBattleStruct->expGetterMonId
&& MOVE_IS_PERMANENT(2, movePosition))
{
@ -7686,7 +7686,7 @@ static u32 GetTrainerMoneyToGive(u16 trainerId)
if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)
moneyReward = 4 * lastMonLevel * gBattleStruct->moneyMultiplier * trainerMoney;
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
else if (IsDoubleBattle())
moneyReward = 4 * lastMonLevel * gBattleStruct->moneyMultiplier * 2 * trainerMoney;
else
moneyReward = 4 * lastMonLevel * gBattleStruct->moneyMultiplier * trainerMoney;
@ -8352,7 +8352,7 @@ static bool32 IsMonGettingExpSentOut(void)
{
if (gBattlerPartyIndexes[0] == gBattleStruct->expGetterMonId)
return TRUE;
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && gBattlerPartyIndexes[2] == gBattleStruct->expGetterMonId)
if (IsDoubleBattle() && gBattlerPartyIndexes[2] == gBattleStruct->expGetterMonId)
return TRUE;
return FALSE;
@ -8425,7 +8425,7 @@ static void Cmd_hpthresholds(void)
{
CMD_ARGS(u8 battler);
if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
if (!(IsDoubleBattle()))
{
u32 battler = GetBattlerForBattleScript(cmd->battler);
u32 opposingBattler = BATTLE_OPPOSITE(battler);
@ -8451,7 +8451,7 @@ static void Cmd_hpthresholds2(void)
{
CMD_ARGS(u8 battler);
if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
if (!(IsDoubleBattle()))
{
u32 battler = GetBattlerForBattleScript(cmd->battler);
u32 opposingBattler = BATTLE_OPPOSITE(battler);
@ -9931,7 +9931,7 @@ static void Cmd_various(void)
case VARIOUS_ABILITY_POPUP:
{
VARIOUS_ARGS();
CreateAbilityPopUp(battler, gBattleMons[battler].ability, (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) != 0);
CreateAbilityPopUp(battler, gBattleMons[battler].ability, (IsDoubleBattle()) != 0);
break;
}
case VARIOUS_UPDATE_ABILITY_POPUP:
@ -10125,7 +10125,7 @@ static void Cmd_various(void)
gSideTimers[GetBattlerSide(battler)].auroraVeilTimer = 5;
gSideTimers[GetBattlerSide(battler)].auroraVeilBattlerId = battler;
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && CountAliveMonsInBattle(BATTLE_ALIVE_SIDE, gBattlerAttacker) == 2)
if (IsDoubleBattle() && CountAliveMonsInBattle(BATTLE_ALIVE_SIDE, gBattlerAttacker) == 2)
gBattleCommunication[MULTISTRING_CHOOSER] = 5;
else
gBattleCommunication[MULTISTRING_CHOOSER] = 5;
@ -10301,7 +10301,7 @@ static void Cmd_various(void)
case VARIOUS_JUMP_IF_TEAM_HEALTHY:
{
VARIOUS_ARGS(const u8 *jumpInstr);
if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && IsBattlerAlive(BATTLE_PARTNER(battler)))
if ((IsDoubleBattle()) && IsBattlerAlive(BATTLE_PARTNER(battler)))
{
u8 partner = BATTLE_PARTNER(battler);
if ((gBattleMons[battler].hp == gBattleMons[battler].maxHP && !(gBattleMons[battler].status1 & STATUS1_ANY))
@ -10914,7 +10914,7 @@ static void Cmd_various(void)
PREPARE_SPECIES_BUFFER(gBattleTextBuff1, GetMonData(&party[gSelectedMonPartyId], MON_DATA_SPECIES));
// If an on-field battler is revived, it needs to be sent out again.
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE &&
if (IsDoubleBattle() &&
gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerAttacker)] == gSelectedMonPartyId)
{
gBattleScripting.battler = BATTLE_PARTNER(gBattlerAttacker);
@ -11233,7 +11233,7 @@ static void Cmd_setreflect(void)
gSideTimers[GetBattlerSide(gBattlerAttacker)].reflectTimer = 5;
gSideTimers[GetBattlerSide(gBattlerAttacker)].reflectBattlerId = gBattlerAttacker;
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && CountAliveMonsInBattle(BATTLE_ALIVE_SIDE, gBattlerAttacker) == 2)
if (IsDoubleBattle() && CountAliveMonsInBattle(BATTLE_ALIVE_SIDE, gBattlerAttacker) == 2)
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_REFLECT_DOUBLE;
else
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_REFLECT_SINGLE;
@ -12097,7 +12097,7 @@ static void Cmd_forcerandomswitch(void)
battler2PartyId = gBattlerPartyIndexes[gBattlerTarget];
battler1PartyId = gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerTarget)];
}
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
else if (IsDoubleBattle())
{
firstMonId = 0;
lastMonId = PARTY_SIZE;
@ -12295,7 +12295,7 @@ static void Cmd_setlightscreen(void)
gSideTimers[GetBattlerSide(gBattlerAttacker)].lightscreenTimer = 5;
gSideTimers[GetBattlerSide(gBattlerAttacker)].lightscreenBattlerId = gBattlerAttacker;
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && CountAliveMonsInBattle(BATTLE_ALIVE_SIDE, gBattlerAttacker) == 2)
if (IsDoubleBattle() && CountAliveMonsInBattle(BATTLE_ALIVE_SIDE, gBattlerAttacker) == 2)
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_LIGHTSCREEN_DOUBLE;
else
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_LIGHTSCREEN_SINGLE;
@ -12465,7 +12465,7 @@ static void Cmd_updatestatusicon(void)
BtlController_EmitStatusIconUpdate(battler, BUFFER_A, gBattleMons[battler].status1, gBattleMons[battler].status2);
MarkBattlerForControllerExec(battler);
}
if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
if ((IsDoubleBattle()))
{
battler = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gBattlerAttacker)));
if (!(gAbsentBattlerFlags & gBitTable[battler]))
@ -12502,7 +12502,7 @@ static void Cmd_setfocusenergy(void)
CMD_ARGS(u8 battler);
u8 battler = GetBattlerForBattleScript(cmd->battler);
if ((gMovesInfo[gCurrentMove].effect == EFFECT_DRAGON_CHEER && (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE) || (gAbsentBattlerFlags & gBitTable[battler])))
if ((gMovesInfo[gCurrentMove].effect == EFFECT_DRAGON_CHEER && (!(IsDoubleBattle()) || (gAbsentBattlerFlags & gBitTable[battler])))
|| gBattleMons[battler].status2 & STATUS2_FOCUS_ENERGY_ANY)
{
gMoveResultFlags |= MOVE_RESULT_FAILED;
@ -13245,7 +13245,7 @@ static void Cmd_healpartystatus(void)
gBattleMons[gBattlerAttacker].status1 = 0;
gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_NIGHTMARE;
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
if (IsDoubleBattle()
&& !(gAbsentBattlerFlags & gBitTable[partner]))
{
gBattleMons[partner].status1 = 0;
@ -14088,7 +14088,7 @@ static void Cmd_trysethelpinghand(void)
gBattlerTarget = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gBattlerAttacker)));
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
if (IsDoubleBattle()
&& !(gAbsentBattlerFlags & gBitTable[gBattlerTarget])
&& !gProtectStructs[gBattlerAttacker].helpingHand
&& !gProtectStructs[gBattlerTarget].helpingHand)
@ -14910,7 +14910,7 @@ static void Cmd_pursuitdoubles(void)
u32 battler = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gBattlerAttacker)));
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
if (IsDoubleBattle()
&& !(gAbsentBattlerFlags & gBitTable[battler])
&& gChosenActionByBattler[battler] == B_ACTION_USE_MOVE
&& gMovesInfo[gChosenMoveByBattler[battler]].effect == EFFECT_PURSUIT)
@ -15908,7 +15908,7 @@ bool32 IsMoveAffectedByParentalBond(u32 move, u32 battler)
&& gMovesInfo[move].strikeCount < 2
&& gMovesInfo[move].effect != EFFECT_MULTI_HIT)
{
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
if (IsDoubleBattle())
{
switch (GetBattlerMoveTargetType(battler, move))
{
@ -16025,7 +16025,7 @@ void BS_SetZEffect(void)
static void TryUpdateRoundTurnOrder(void)
{
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
if (IsDoubleBattle())
{
u32 i;
u32 j = 0;
@ -16163,8 +16163,7 @@ void BS_ItemRestoreHP(void)
// Check if the recipient is an active battler.
if (gBattleStruct->itemPartyIndex[gBattlerAttacker] == gBattlerPartyIndexes[gBattlerAttacker])
battler = gBattlerAttacker;
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
&& gBattleStruct->itemPartyIndex[gBattlerAttacker] == gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerAttacker)])
else if (IsDoubleBattle() && gBattleStruct->itemPartyIndex[gBattlerAttacker] == gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerAttacker)])
battler = BATTLE_PARTNER(gBattlerAttacker);
// Get amount to heal.
@ -16201,7 +16200,7 @@ void BS_ItemRestoreHP(void)
SetMonData(&party[gBattleStruct->itemPartyIndex[gBattlerAttacker]], MON_DATA_HP, &hp);
// Revived battlers on the field need to be brought back.
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && battler != MAX_BATTLERS_COUNT)
if (IsDoubleBattle() && battler != MAX_BATTLERS_COUNT)
{
gAbsentBattlerFlags &= ~gBitTable[battler];
gBattleMons[battler].hp = hp;
@ -16227,7 +16226,7 @@ void BS_ItemCureStatus(void)
previousStatus2 = gBattleMons[battler].status2;
gBattleMons[gBattlerAttacker].status2 &= ~GetItemStatus2Mask(gLastUsedItem);
}
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
else if (IsDoubleBattle()
&& gBattleStruct->itemPartyIndex[gBattlerAttacker] == gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerAttacker)])
{
battler = BATTLE_PARTNER(gBattlerAttacker);
@ -16292,7 +16291,7 @@ void BS_ItemRestorePP(void)
// Check if the recipient is an active battler.
if (gBattleStruct->itemPartyIndex[gBattlerAttacker] == gBattlerPartyIndexes[gBattlerAttacker])
battler = gBattlerAttacker;
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
else if (IsDoubleBattle()
&& gBattleStruct->itemPartyIndex[gBattlerAttacker] == gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerAttacker)])
battler = BATTLE_PARTNER(gBattlerAttacker);
@ -16623,7 +16622,7 @@ void BS_SetPledge(void)
gBattleCommunication[MSG_DISPLAY] = 0;
}
else if ((gChosenActionByBattler[partner] == B_ACTION_USE_MOVE)
&& gBattleTypeFlags & BATTLE_TYPE_DOUBLE
&& IsDoubleBattle()
&& IsBattlerAlive(partner)
&& gCurrentMove != partnerMove
&& gMovesInfo[partnerMove].effect == EFFECT_PLEDGE)

View file

@ -30,7 +30,7 @@ void ActivateTera(u32 battler)
if (B_FLAG_TERA_ORB_CHARGED != 0
&& (B_FLAG_TERA_ORB_NO_COST == 0 || !FlagGet(B_FLAG_TERA_ORB_NO_COST))
&& side == B_SIDE_PLAYER
&& !(gBattleTypeFlags & BATTLE_TYPE_DOUBLE && !IsPartnerMonFromSameTrainer(battler)))
&& !(IsDoubleBattle() && !IsPartnerMonFromSameTrainer(battler)))
{
FlagClear(B_FLAG_TERA_ORB_CHARGED);
}

View file

@ -221,7 +221,7 @@ void HandleAction_UseMove(void)
{
gBattleStruct->moveTarget[gBattlerAttacker] = gBattlerTarget = gSideTimers[side].followmeTarget; // follow me moxie fix
}
else if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
else if (IsDoubleBattle()
&& gSideTimers[side].followmeTimer == 0
&& (gMovesInfo[gCurrentMove].power != 0 || (moveTarget != MOVE_TARGET_USER && moveTarget != MOVE_TARGET_ALL_BATTLERS))
&& ((GetBattlerAbility(*(gBattleStruct->moveTarget + gBattlerAttacker)) != ABILITY_LIGHTNING_ROD && moveType == TYPE_ELECTRIC)
@ -305,8 +305,7 @@ void HandleAction_UseMove(void)
gBattlerTarget = battler;
}
}
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
&& moveTarget & MOVE_TARGET_RANDOM)
else if (IsDoubleBattle() && moveTarget & MOVE_TARGET_RANDOM)
{
if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
{
@ -336,8 +335,7 @@ void HandleAction_UseMove(void)
else
gBattlerTarget = gBattlerAttacker;
}
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
&& moveTarget == MOVE_TARGET_FOES_AND_ALLY)
else if (IsDoubleBattle() && moveTarget == MOVE_TARGET_FOES_AND_ALLY)
{
for (gBattlerTarget = 0; gBattlerTarget < gBattlersCount; gBattlerTarget++)
{
@ -3744,7 +3742,7 @@ bool32 HasNoMonsToSwitch(u32 battler, u8 partyIdBattlerOn1, u8 partyIdBattlerOn2
u32 i, side, playerId, flankId;
struct Pokemon *party;
if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
if (!IsDoubleBattle())
return FALSE;
side = GetBattlerSide(battler);
@ -4328,7 +4326,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
target1 = GetBattlerAtPosition(side);
target2 = GetBattlerAtPosition(side + BIT_FLANK);
gSpecialStatuses[battler].switchInAbilityDone = TRUE;
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
if (IsDoubleBattle())
{
if (!gAbilitiesInfo[gBattleMons[target1].ability].cantBeTraced && gBattleMons[target1].hp != 0
&& !gAbilitiesInfo[gBattleMons[target2].ability].cantBeTraced && gBattleMons[target2].hp != 0)
@ -5177,7 +5175,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
&& BlocksPrankster(move, gBattlerAttacker, gBattlerTarget, TRUE)
&& !(IS_MOVE_STATUS(move) && (gLastUsedAbility == ABILITY_MAGIC_BOUNCE || gProtectStructs[gBattlerTarget].bounceMove)))
{
if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE) || !(moveTarget & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY)))
if (!IsDoubleBattle() || !(moveTarget & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY)))
CancelMultiTurnMoves(gBattlerAttacker); // Don't cancel moves that can hit two targets bc one target might not be protected
gBattleScripting.battler = gBattlerAbility = gBattlerTarget;
battleScriptBlocksMove = BattleScript_DarkTypePreventsPrankster;
@ -8252,7 +8250,7 @@ u32 SetRandomTarget(u32 battler)
[B_SIDE_OPPONENT] = {B_POSITION_PLAYER_LEFT, B_POSITION_PLAYER_RIGHT},
};
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
if (IsDoubleBattle())
{
target = GetBattlerAtPosition(targets[GetBattlerSide(battler)][Random() % 2]);
if (!IsBattlerAlive(target))
@ -8317,7 +8315,7 @@ u32 GetMoveTarget(u16 move, u8 setTarget)
side = BATTLE_OPPOSITE(GetBattlerSide(gBattlerAttacker));
if (IsAffectedByFollowMe(gBattlerAttacker, side, move))
targetBattler = gSideTimers[side].followmeTarget;
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && moveTarget & MOVE_TARGET_RANDOM)
else if (IsDoubleBattle() && moveTarget & MOVE_TARGET_RANDOM)
targetBattler = SetRandomTarget(gBattlerAttacker);
else
targetBattler = GetBattlerAtPosition(BATTLE_OPPOSITE(GetBattlerSide(gBattlerAttacker)));
@ -9983,7 +9981,7 @@ static inline uq4_12_t GetScreensModifier(u32 move, u32 battlerAtk, u32 battlerD
if (isCrit || abilityAtk == ABILITY_INFILTRATOR || gProtectStructs[battlerAtk].confusionSelfDmg)
return UQ_4_12(1.0);
if (reflect || lightScreen || auroraVeil)
return (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) ? UQ_4_12(0.667) : UQ_4_12(0.5);
return (IsDoubleBattle()) ? UQ_4_12(0.667) : UQ_4_12(0.5);
return UQ_4_12(1.0);
}
@ -11787,7 +11785,7 @@ void SetShellSideArmCategory(void)
bool32 CanTargetPartner(u32 battlerAtk, u32 battlerDef)
{
return (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
return (IsDoubleBattle()
&& IsBattlerAlive(BATTLE_PARTNER(battlerDef))
&& battlerDef != BATTLE_PARTNER(battlerAtk));
}

View file

@ -80,7 +80,7 @@ void AdjustFriendshipOnBattleFaint(u8 battler)
{
u8 opposingBattlerId;
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
if (IsDoubleBattle())
{
u8 opposingBattlerId2;

View file

@ -60,6 +60,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] =
.teraTypeRGBValue = RGB_WHITE,
.damageCategory = DAMAGE_CATEGORY_PHYSICAL,
.paletteTMHM = gItemIconPalette_NormalTMHM,
.useSecondTypeIconPalette = FALSE,
.isSpecialCaseType = TRUE,
},
[TYPE_NORMAL] =
{
@ -71,6 +73,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] =
.teraTypeRGBValue = RGB_WHITE, // custom
.damageCategory = DAMAGE_CATEGORY_PHYSICAL,
.paletteTMHM = gItemIconPalette_NormalTMHM,
.useSecondTypeIconPalette = FALSE,
.isSpecialCaseType = FALSE,
//.enhanceItem = ITEM_SILK_SCARF,
//.berry = ITEM_CHILAN_BERRY,
//.gem = ITEM_NORMAL_GEM,
@ -88,6 +92,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] =
.teraTypeRGBValue = RGB(26, 8, 14),
.damageCategory = DAMAGE_CATEGORY_PHYSICAL,
.paletteTMHM = gItemIconPalette_FightingTMHM,
.useSecondTypeIconPalette = FALSE,
.isSpecialCaseType = FALSE,
//.enhanceItem = ITEM_BLACK_BELT,
//.berry = ITEM_CHOPLE_BERRY,
//.gem = ITEM_FIGHTING_GEM,
@ -107,6 +113,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] =
.teraTypeRGBValue = RGB(31, 26, 7),
.damageCategory = DAMAGE_CATEGORY_PHYSICAL,
.paletteTMHM = gItemIconPalette_FlyingTMHM,
.useSecondTypeIconPalette = FALSE,
.isSpecialCaseType = FALSE,
//.enhanceItem = ITEM_SHARP_BEAK,
//.berry = ITEM_COBA_BERRY,
//.gem = ITEM_FLYING_GEM,
@ -126,6 +134,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] =
.teraTypeRGBValue = RGB(26, 10, 25), // custom
.damageCategory = DAMAGE_CATEGORY_PHYSICAL,
.paletteTMHM = gItemIconPalette_PoisonTMHM,
.useSecondTypeIconPalette = FALSE,
.isSpecialCaseType = FALSE,
//.enhanceItem = ITEM_POISON_BARB,
//.berry = ITEM_KEBIA_BERRY,
//.gem = ITEM_POISON_GEM,
@ -145,6 +155,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] =
.teraTypeRGBValue = RGB(25, 23, 18),
.damageCategory = DAMAGE_CATEGORY_PHYSICAL,
.paletteTMHM = gItemIconPalette_GroundTMHM,
.useSecondTypeIconPalette = FALSE,
.isSpecialCaseType = FALSE,
//.enhanceItem = ITEM_SOFT_SAND,
//.berry = ITEM_SHUCA_BERRY,
//.gem = ITEM_GROUND_GEM,
@ -164,6 +176,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] =
.teraTypeRGBValue = RGB(18, 16, 8), // custom
.damageCategory = DAMAGE_CATEGORY_PHYSICAL,
.paletteTMHM = gItemIconPalette_RockTMHM,
.useSecondTypeIconPalette = FALSE,
.isSpecialCaseType = FALSE,
//.enhanceItem = ITEM_HARD_STONE,
//.berry = ITEM_CHARTI_BERRY,
//.gem = ITEM_ROCK_GEM,
@ -183,6 +197,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] =
.teraTypeRGBValue = RGB(18, 24, 6),
.damageCategory = DAMAGE_CATEGORY_PHYSICAL,
.paletteTMHM = gItemIconPalette_BugTMHM,
.useSecondTypeIconPalette = FALSE,
.isSpecialCaseType = FALSE,
//.enhanceItem = ITEM_SILVER_POWDER,
//.berry = ITEM_TANGA_BERRY,
//.gem = ITEM_BUG_GEM,
@ -202,6 +218,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] =
.teraTypeRGBValue = RGB(12, 10, 16),
.damageCategory = DAMAGE_CATEGORY_PHYSICAL,
.paletteTMHM = gItemIconPalette_GhostTMHM,
.useSecondTypeIconPalette = FALSE,
.isSpecialCaseType = FALSE,
//.enhanceItem = ITEM_SPELL_TAG,
//.berry = ITEM_KASIB_BERRY,
//.gem = ITEM_GHOST_GEM,
@ -221,6 +239,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] =
.teraTypeRGBValue = RGB(19, 19, 20),
.damageCategory = DAMAGE_CATEGORY_PHYSICAL,
.paletteTMHM = gItemIconPalette_SteelTMHM,
.useSecondTypeIconPalette = FALSE,
.isSpecialCaseType = FALSE,
//.enhanceItem = ITEM_METAL_COAT,
//.berry = ITEM_BABIRI_BERRY,
//.gem = ITEM_STEEL_GEM,
@ -237,6 +257,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] =
.palette = 15,
.teraTypeRGBValue = RGB_WHITE,
.damageCategory = DAMAGE_CATEGORY_SPECIAL,
.useSecondTypeIconPalette = FALSE,
.isSpecialCaseType = TRUE,
},
[TYPE_FIRE] =
{
@ -248,6 +270,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] =
.teraTypeRGBValue = RGB(31, 20, 11),
.damageCategory = DAMAGE_CATEGORY_SPECIAL,
.paletteTMHM = gItemIconPalette_FireTMHM,
.useSecondTypeIconPalette = TRUE,
.isSpecialCaseType = FALSE,
//.enhanceItem = ITEM_CHARCOAL,
//.berry = ITEM_OCCA_BERRY,
//.gem = ITEM_FIRE_GEM,
@ -267,6 +291,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] =
.teraTypeRGBValue = RGB(10, 18, 27),
.damageCategory = DAMAGE_CATEGORY_SPECIAL,
.paletteTMHM = gItemIconPalette_WaterTMHM,
.useSecondTypeIconPalette = TRUE,
.isSpecialCaseType = FALSE,
//.enhanceItem = ITEM_MYSTIC_WATER,
//.berry = ITEM_PASSHO_BERRY,
//.gem = ITEM_WATER_GEM,
@ -286,6 +312,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] =
.teraTypeRGBValue = RGB(12, 24, 11),
.damageCategory = DAMAGE_CATEGORY_SPECIAL,
.paletteTMHM = gItemIconPalette_GrassTMHM,
.useSecondTypeIconPalette = TRUE,
.isSpecialCaseType = FALSE,
//.enhanceItem = ITEM_MIRACLE_SEED,
//.berry = ITEM_RINDO_BERRY,
//.gem = ITEM_GRASS_GEM,
@ -305,6 +333,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] =
.teraTypeRGBValue = RGB(30, 26, 7),
.damageCategory = DAMAGE_CATEGORY_SPECIAL,
.paletteTMHM = gItemIconPalette_ElectricTMHM,
.useSecondTypeIconPalette = TRUE,
.isSpecialCaseType = FALSE,
//.enhanceItem = ITEM_MAGNET,
//.berry = ITEM_WACAN_BERRY,
//.gem = ITEM_ELECTRIC_GEM,
@ -324,6 +354,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] =
.teraTypeRGBValue = RGB(31, 14, 15),
.damageCategory = DAMAGE_CATEGORY_SPECIAL,
.paletteTMHM = gItemIconPalette_PsychicTMHM,
.useSecondTypeIconPalette = TRUE,
.isSpecialCaseType = FALSE,
//.enhanceItem = ITEM_TWISTED_SPOON,
//.berry = ITEM_PAYAPA_BERRY,
//.gem = ITEM_PSYCHIC_GEM,
@ -343,6 +375,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] =
.teraTypeRGBValue = RGB(14, 26, 25),
.damageCategory = DAMAGE_CATEGORY_SPECIAL,
.paletteTMHM = gItemIconPalette_IceTMHM,
.useSecondTypeIconPalette = TRUE,
.isSpecialCaseType = FALSE,
//.enhanceItem = ITEM_NEVER_MELT_ICE,
//.berry = ITEM_YACHE_BERRY,
//.gem = ITEM_ICE_GEM,
@ -362,6 +396,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] =
.teraTypeRGBValue = RGB(10, 18, 27),
.damageCategory = DAMAGE_CATEGORY_SPECIAL,
.paletteTMHM = gItemIconPalette_DragonTMHM,
.useSecondTypeIconPalette = TRUE,
.isSpecialCaseType = FALSE,
//.enhanceItem = ITEM_DRAGON_FANG,
//.berry = ITEM_HABAN_BERRY,
//.gem = ITEM_DRAGON_GEM,
@ -381,6 +417,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] =
.teraTypeRGBValue = RGB(6, 5, 8),
.damageCategory = DAMAGE_CATEGORY_SPECIAL,
.paletteTMHM = gItemIconPalette_DarkTMHM,
.useSecondTypeIconPalette = TRUE,
.isSpecialCaseType = FALSE,
//.enhanceItem = ITEM_BLACK_GLASSES,
//.berry = ITEM_COLBUR_BERRY,
//.gem = ITEM_DARK_GEM,
@ -400,6 +438,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] =
.teraTypeRGBValue = RGB(31, 15, 21),
.damageCategory = DAMAGE_CATEGORY_SPECIAL,
.paletteTMHM = gItemIconPalette_FairyTMHM,
.useSecondTypeIconPalette = TRUE,
.isSpecialCaseType = FALSE,
//.enhanceItem = ITEM_FAIRY_FEATHER,
//.berry = ITEM_ROSELI_BERRY,
//.gem = ITEM_FAIRY_GEM,
@ -418,6 +458,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] =
.maxMove = MOVE_MAX_STRIKE,
.teraTypeRGBValue = RGB(10, 18, 27),
.paletteTMHM = gItemIconPalette_NormalTMHM, // failsafe
.useSecondTypeIconPalette = FALSE,
.isSpecialCaseType = TRUE,
// .teraShard = ITEM_STELLAR_TERA_SHARD,
},
};

View file

@ -2048,3 +2048,9 @@ const u16 gFrontierPassCancelButtonHighlighted_Tilemap[] = INCBIN_U16("graphics/
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_TextWindows_Tilemap[] = INCBIN_U32("graphics/berry_crush/text_windows.bin.lz");
const u32 gBattleIcons_Gfx1[] = INCBIN_U32("graphics/types/battle_icons1.4bpp.lz");
const u32 gBattleIcons_Gfx2[] = INCBIN_U32("graphics/types/battle_icons2.4bpp.lz");
const u32 gBattleIcons_Pal1[] = INCBIN_U32("graphics/types/battle_icons1.gbapal.lz");
const u32 gBattleIcons_Pal2[] = INCBIN_U32("graphics/types/battle_icons2.gbapal.lz");

View file

@ -1353,7 +1353,7 @@ static void DrawCancelConfirmButtons(void)
bool8 IsMultiBattle(void)
{
if (gBattleTypeFlags & BATTLE_TYPE_MULTI && gBattleTypeFlags & BATTLE_TYPE_DOUBLE && gMain.inBattle)
if (gBattleTypeFlags & BATTLE_TYPE_MULTI && IsDoubleBattle() && gMain.inBattle)
return TRUE;
else
return FALSE;

View file

@ -2100,7 +2100,7 @@ u8 GetDefaultMoveTarget(u8 battlerId)
{
u8 opposing = BATTLE_OPPOSITE(GetBattlerSide(battlerId));
if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
if (!IsDoubleBattle())
return GetBattlerAtPosition(opposing);
if (CountAliveMonsInBattle(BATTLE_ALIVE_EXCEPT_BATTLER, battlerId) > 1)
{

View file

@ -1262,7 +1262,7 @@ void PutBattleUpdateOnTheAir(u8 opponentLinkPlayerId, u16 move, u16 speciesPlaye
if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
show->battleUpdate.battleType = 2;
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
else if (IsDoubleBattle())
show->battleUpdate.battleType = 1;
else
show->battleUpdate.battleType = 0;

516
src/type_icons.c Normal file
View file

@ -0,0 +1,516 @@
#include "global.h"
#include "battle.h"
#include "battle_anim.h"
#include "battle_controllers.h"
#include "battle_gimmick.h"
#include "decompress.h"
#include "graphics.h"
#include "pokedex.h"
#include "sprite.h"
#include "type_icons.h"
static void LoadTypeSpritesAndPalettes(void);
static void LoadTypeIconsPerBattler(u32, u32);
static bool32 UseDoubleBattleCoords(u32);
static u32 GetMonPublicType(u32, u32);
static bool32 ShouldHideUncaughtType(u32);
static u32 GetMonDefensiveTeraType(struct Pokemon *, struct Pokemon*, u32, u32, u32, u32);
static u32 IsIllusionActiveAndTypeUnchanged(struct Pokemon*, u32, u32);
static void CreateSpriteFromType(u32, bool32, u32[], u32, u32);
static bool32 ShouldSkipSecondType(u32[], u32);
static void SetTypeIconXY(s32*, s32*, u32, bool32, u32);
static void CreateSpriteAndSetTypeSpriteAttributes(u32, u32 x, u32 y, u32, u32, bool32);
static bool32 ShouldFlipTypeIcon(bool32, u32, u32);
static void SpriteCB_TypeIcon(struct Sprite*);
static void DestroyTypeIcon(struct Sprite*);
static bool32 ShouldHideTypeIcon(u32);
static s32 GetTypeIconHideMovement(bool32, u32);
static s32 GetTypeIconSlideMovement(bool32, u32, s32);
static s32 GetTypeIconBounceMovement(s32, u32);
const struct Coords16 sTypeIconPositions[][2] =
{
[B_POSITION_PLAYER_LEFT] =
{
[FALSE] = {221, 86},
[TRUE] = {144, 71},
},
[B_POSITION_OPPONENT_LEFT] =
{
[FALSE] = {20, 26},
[TRUE] = {97, 14},
},
[B_POSITION_PLAYER_RIGHT] =
{
[TRUE] = {156, 96},
},
[B_POSITION_OPPONENT_RIGHT] =
{
[TRUE] = {85, 39},
},
};
const union AnimCmd sSpriteAnim_TypeIcon_Normal[] =
{
ANIMCMD_FRAME(TYPE_ICON_1_FRAME(TYPE_NORMAL), 0),
ANIMCMD_END
};
const union AnimCmd sSpriteAnim_TypeIcon_Fighting[] =
{
ANIMCMD_FRAME(TYPE_ICON_1_FRAME(TYPE_FIGHTING), 0),
ANIMCMD_END
};
const union AnimCmd sSpriteAnim_TypeIcon_Flying[] =
{
ANIMCMD_FRAME(TYPE_ICON_1_FRAME(TYPE_FLYING), 0),
ANIMCMD_END
};
const union AnimCmd sSpriteAnim_TypeIcon_Poison[] =
{
ANIMCMD_FRAME(TYPE_ICON_1_FRAME(TYPE_POISON), 0),
ANIMCMD_END
};
const union AnimCmd sSpriteAnim_TypeIcon_Ground[] =
{
ANIMCMD_FRAME(TYPE_ICON_1_FRAME(TYPE_GROUND), 0),
ANIMCMD_END
};
const union AnimCmd sSpriteAnim_TypeIcon_Rock[] =
{
ANIMCMD_FRAME(TYPE_ICON_1_FRAME(TYPE_ROCK), 0),
ANIMCMD_END
};
const union AnimCmd sSpriteAnim_TypeIcon_Bug[] =
{
ANIMCMD_FRAME(TYPE_ICON_1_FRAME(TYPE_BUG), 0),
ANIMCMD_END
};
const union AnimCmd sSpriteAnim_TypeIcon_Ghost[] =
{
ANIMCMD_FRAME(TYPE_ICON_1_FRAME(TYPE_GHOST), 0),
ANIMCMD_END
};
const union AnimCmd sSpriteAnim_TypeIcon_Steel[] =
{
ANIMCMD_FRAME(TYPE_ICON_1_FRAME(TYPE_STEEL), 0),
ANIMCMD_END
};
const union AnimCmd sSpriteAnim_TypeIcon_Mystery[] =
{
ANIMCMD_FRAME(TYPE_ICON_1_FRAME(TYPE_MYSTERY), 0),
ANIMCMD_END
};
const union AnimCmd sSpriteAnim_TypeIcon_Fire[] =
{
ANIMCMD_FRAME(TYPE_ICON_2_FRAME(TYPE_FIRE), 0),
ANIMCMD_END
};
const union AnimCmd sSpriteAnim_TypeIcon_Water[] =
{
ANIMCMD_FRAME(TYPE_ICON_2_FRAME(TYPE_WATER), 0),
ANIMCMD_END
};
const union AnimCmd sSpriteAnim_TypeIcon_Grass[] =
{
ANIMCMD_FRAME(TYPE_ICON_2_FRAME(TYPE_GRASS), 0),
ANIMCMD_END
};
const union AnimCmd sSpriteAnim_TypeIcon_Electric[] =
{
ANIMCMD_FRAME(TYPE_ICON_2_FRAME(TYPE_ELECTRIC), 0),
ANIMCMD_END
};
const union AnimCmd sSpriteAnim_TypeIcon_Psychic[] =
{
ANIMCMD_FRAME(TYPE_ICON_2_FRAME(TYPE_PSYCHIC), 0),
ANIMCMD_END
};
const union AnimCmd sSpriteAnim_TypeIcon_Ice[] =
{
ANIMCMD_FRAME(TYPE_ICON_2_FRAME(TYPE_ICE), 0),
ANIMCMD_END
};
const union AnimCmd sSpriteAnim_TypeIcon_Dragon[] =
{
ANIMCMD_FRAME(TYPE_ICON_2_FRAME(TYPE_DRAGON), 0),
ANIMCMD_END
};
const union AnimCmd sSpriteAnim_TypeIcon_Dark[] =
{
ANIMCMD_FRAME(TYPE_ICON_2_FRAME(TYPE_DARK), 0),
ANIMCMD_END
};
const union AnimCmd sSpriteAnim_TypeIcon_Fairy[] =
{
ANIMCMD_FRAME(TYPE_ICON_2_FRAME(TYPE_FAIRY), 0),
ANIMCMD_END
};
const union AnimCmd *const sSpriteAnimTable_TypeIcons[] =
{
[TYPE_NONE] = sSpriteAnim_TypeIcon_Mystery,
[TYPE_NORMAL] = sSpriteAnim_TypeIcon_Normal,
[TYPE_FIGHTING] = sSpriteAnim_TypeIcon_Fighting,
[TYPE_FLYING] = sSpriteAnim_TypeIcon_Flying,
[TYPE_POISON] = sSpriteAnim_TypeIcon_Poison,
[TYPE_GROUND] = sSpriteAnim_TypeIcon_Ground,
[TYPE_ROCK] = sSpriteAnim_TypeIcon_Rock,
[TYPE_BUG] = sSpriteAnim_TypeIcon_Bug,
[TYPE_GHOST] = sSpriteAnim_TypeIcon_Ghost,
[TYPE_STEEL] = sSpriteAnim_TypeIcon_Steel,
[TYPE_MYSTERY] = sSpriteAnim_TypeIcon_Mystery,
[TYPE_FIRE] = sSpriteAnim_TypeIcon_Fire,
[TYPE_WATER] = sSpriteAnim_TypeIcon_Water,
[TYPE_GRASS] = sSpriteAnim_TypeIcon_Grass,
[TYPE_ELECTRIC] = sSpriteAnim_TypeIcon_Electric,
[TYPE_PSYCHIC] = sSpriteAnim_TypeIcon_Psychic,
[TYPE_ICE] = sSpriteAnim_TypeIcon_Ice,
[TYPE_DRAGON] = sSpriteAnim_TypeIcon_Dragon,
[TYPE_DARK] = sSpriteAnim_TypeIcon_Dark,
[TYPE_FAIRY] = sSpriteAnim_TypeIcon_Fairy,
[TYPE_STELLAR] = sSpriteAnim_TypeIcon_Mystery,
};
const struct CompressedSpritePalette sTypeIconPal1 =
{
.data = gBattleIcons_Pal1,
.tag = TYPE_ICON_TAG
};
const struct CompressedSpritePalette sTypeIconPal2 =
{
.data = gBattleIcons_Pal2,
.tag = TYPE_ICON_TAG_2
};
const struct OamData sOamData_TypeIcons =
{
.affineMode = ST_OAM_AFFINE_OFF,
.objMode = ST_OAM_OBJ_NORMAL,
.shape = SPRITE_SHAPE(8x16),
.size = SPRITE_SIZE(8x16),
.priority = 1,
};
const struct CompressedSpriteSheet sSpriteSheet_TypeIcons2 =
{
.data = gBattleIcons_Gfx2,
.size = (8*16) * 9,
.tag = TYPE_ICON_TAG_2,
};
const struct CompressedSpriteSheet sSpriteSheet_TypeIcons1 =
{
.data = gBattleIcons_Gfx1,
.size = (8*16) * 10,
.tag = TYPE_ICON_TAG,
};
const struct SpriteTemplate sSpriteTemplate_TypeIcons1 =
{
.tileTag = TYPE_ICON_TAG,
.paletteTag = TYPE_ICON_TAG,
.oam = &sOamData_TypeIcons,
.anims = sSpriteAnimTable_TypeIcons,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCB_TypeIcon
};
const struct SpriteTemplate sSpriteTemplate_TypeIcons2 =
{
.tileTag = TYPE_ICON_TAG_2,
.paletteTag = TYPE_ICON_TAG_2,
.oam = &sOamData_TypeIcons,
.anims = sSpriteAnimTable_TypeIcons,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCB_TypeIcon
};
void LoadTypeIcons(u32 battler)
{
u32 position;
if (B_SHOW_TYPES == SHOW_TYPES_NEVER)
return;
LoadTypeSpritesAndPalettes();
for (position = 0; position < gBattlersCount; ++position)
LoadTypeIconsPerBattler(battler, position);
}
static void LoadTypeSpritesAndPalettes(void)
{
if (IndexOfSpritePaletteTag(TYPE_ICON_TAG) != UCHAR_MAX)
return;
LoadCompressedSpriteSheet(&sSpriteSheet_TypeIcons1);
LoadCompressedSpriteSheet(&sSpriteSheet_TypeIcons2);
LoadCompressedSpritePalette(&sTypeIconPal1);
LoadCompressedSpritePalette(&sTypeIconPal2);
}
static void LoadTypeIconsPerBattler(u32 battler, u32 position)
{
u32 typeNum, types[2];
u32 battlerId = GetBattlerAtPosition(position);
bool32 useDoubleBattleCoords = UseDoubleBattleCoords(battlerId);
if (!IsBattlerAlive(battlerId))
return;
for (typeNum = 0; typeNum < 2; ++typeNum)
types[typeNum] = GetMonPublicType(battlerId, typeNum);
for (typeNum = 0; typeNum < 2; ++typeNum)
CreateSpriteFromType(position, useDoubleBattleCoords, types, typeNum, battler);
}
static bool32 UseDoubleBattleCoords(u32 position)
{
if (!IsDoubleBattle())
return FALSE;
if ((position == B_POSITION_PLAYER_LEFT) && (gBattleMons[B_POSITION_PLAYER_RIGHT].species == SPECIES_NONE))
return FALSE;
if ((position == B_POSITION_OPPONENT_LEFT) && (gBattleMons[B_POSITION_OPPONENT_RIGHT].species == SPECIES_NONE))
return FALSE;
return TRUE;
}
static u32 GetMonPublicType(u32 battlerId, u32 typeNum)
{
struct Pokemon* mon = GetBattlerData(battlerId);
u32 monSpecies = GetMonData(mon,MON_DATA_SPECIES,NULL);
struct Pokemon* monIllusion;
u32 illusionSpecies;
if (ShouldHideUncaughtType(monSpecies))
return TYPE_MYSTERY;
monIllusion = GetIllusionMonPtr(battlerId);
illusionSpecies = GetMonData(monIllusion,MON_DATA_SPECIES,NULL);
if (GetActiveGimmick(battlerId) == GIMMICK_TERA)
return GetMonDefensiveTeraType(mon,monIllusion,battlerId,typeNum,illusionSpecies,monSpecies);
if (IsIllusionActiveAndTypeUnchanged(monIllusion,monSpecies, battlerId))
return gSpeciesInfo[illusionSpecies].types[typeNum];
return gBattleMons[battlerId].types[typeNum];
}
static bool32 ShouldHideUncaughtType(u32 species)
{
if (B_SHOW_TYPES != SHOW_TYPES_CAUGHT)
return FALSE;
if (GetSetPokedexFlag(SpeciesToNationalPokedexNum(species),FLAG_GET_CAUGHT))
return FALSE;
return TRUE;
}
static u32 GetMonDefensiveTeraType(struct Pokemon * mon, struct Pokemon* monIllusion, u32 battlerId, u32 typeNum, u32 illusionSpecies, u32 monSpecies)
{
u32 teraType = GetBattlerTeraType(battlerId);
u32 targetSpecies;
if (teraType != TYPE_STELLAR)
return teraType;
targetSpecies = (monIllusion != NULL) ? illusionSpecies : monSpecies;
return gSpeciesInfo[targetSpecies].types[typeNum];
}
static u32 IsIllusionActiveAndTypeUnchanged(struct Pokemon* monIllusion, u32 monSpecies, u32 battlerId)
{
u32 typeNum;
if (monIllusion == NULL)
return FALSE;
for (typeNum = 0; typeNum < 2; typeNum++)
if (gSpeciesInfo[monSpecies].types[typeNum] != gBattleMons[battlerId].types[typeNum])
return FALSE;
return TRUE;
}
static void CreateSpriteFromType(u32 position, bool32 useDoubleBattleCoords, u32 types[], u32 typeNum, u32 battler)
{
s32 x = 0, y = 0;
if (ShouldSkipSecondType(types, typeNum))
return;
SetTypeIconXY(&x, &y, position, useDoubleBattleCoords, typeNum);
CreateSpriteAndSetTypeSpriteAttributes(types[typeNum], x, y, position, battler, useDoubleBattleCoords);
}
static bool32 ShouldSkipSecondType(u32 types[], u32 typeNum)
{
if (!typeNum)
return FALSE;
if (types[0] != types[1])
return FALSE;
return TRUE;
}
static void SetTypeIconXY(s32* x, s32* y, u32 position, bool32 useDoubleBattleCoords, u32 typeNum)
{
*x = sTypeIconPositions[position][useDoubleBattleCoords].x;
*y = sTypeIconPositions[position][useDoubleBattleCoords].y + (11 * typeNum);
}
static void CreateSpriteAndSetTypeSpriteAttributes(u32 type, u32 x, u32 y, u32 position, u32 battler, bool32 useDoubleBattleCoords)
{
struct Sprite* sprite;
const struct SpriteTemplate* spriteTemplate = gTypesInfo[type].useSecondTypeIconPalette ? &sSpriteTemplate_TypeIcons2 : &sSpriteTemplate_TypeIcons1;
u32 spriteId = CreateSpriteAtEnd(spriteTemplate, x, y, UCHAR_MAX);
if (spriteId == MAX_SPRITES)
return;
sprite = &gSprites[spriteId];
sprite->tMonPosition = position;
sprite->tBattlerId = battler;
sprite->tVerticalPosition = y;
sprite->hFlip = ShouldFlipTypeIcon(useDoubleBattleCoords, position, type);
StartSpriteAnim(sprite, type);
}
static bool32 ShouldFlipTypeIcon(bool32 useDoubleBattleCoords, u32 position, u32 typeId)
{
bool32 side = (useDoubleBattleCoords) ? B_SIDE_OPPONENT : B_SIDE_PLAYER;
if (GetBattlerSide(GetBattlerAtPosition(position)) != side)
return FALSE;
return !gTypesInfo[typeId].isSpecialCaseType;
}
static void SpriteCB_TypeIcon(struct Sprite* sprite)
{
u32 position = sprite->tMonPosition;
u32 battlerId = sprite->tBattlerId;
bool32 useDoubleBattleCoords = UseDoubleBattleCoords(GetBattlerAtPosition(position));
if (sprite->tHideIconTimer == NUM_FRAMES_HIDE_TYPE_ICON)
{
DestroyTypeIcon(sprite);
return;
}
if (ShouldHideTypeIcon(battlerId))
{
sprite->x += GetTypeIconHideMovement(useDoubleBattleCoords, position);
++sprite->tHideIconTimer;
return;
}
sprite->x += GetTypeIconSlideMovement(useDoubleBattleCoords,position, sprite->x);
sprite->y = GetTypeIconBounceMovement(sprite->tVerticalPosition,position);
}
static void DestroyTypeIcon(struct Sprite* sprite)
{
u32 i;
DestroySpriteAndFreeResources(sprite);
for (i = 0; i < MAX_SPRITES; ++i)
{
if (!gSprites[i].inUse)
continue;
if (gSprites[i].template->paletteTag == TYPE_ICON_TAG)
return;
}
FreeSpritePaletteByTag(TYPE_ICON_TAG);
FreeSpritePaletteByTag(TYPE_ICON_TAG_2);
}
static bool32 ShouldHideTypeIcon(u32 battlerId)
{
return gBattlerControllerFuncs[battlerId] != PlayerHandleChooseMove
&& gBattlerControllerFuncs[battlerId] != HandleInputChooseMove
&& gBattlerControllerFuncs[battlerId] != HandleChooseMoveAfterDma3
&& gBattlerControllerFuncs[battlerId] != HandleInputChooseMove
&& gBattlerControllerFuncs[battlerId] != HandleInputChooseTarget
&& gBattlerControllerFuncs[battlerId] != HandleMoveSwitching
&& gBattlerControllerFuncs[battlerId] != HandleInputChooseMove;
}
static s32 GetTypeIconHideMovement(bool32 useDoubleBattleCoords, u32 position)
{
if (useDoubleBattleCoords)
{
if (position == B_POSITION_PLAYER_LEFT || position == B_POSITION_PLAYER_RIGHT)
return 1;
else
return -1;
}
if (position == B_POSITION_PLAYER_LEFT)
return -1;
else
return 1;
}
static s32 GetTypeIconSlideMovement(bool32 useDoubleBattleCoords, u32 position, s32 xPos)
{
if (useDoubleBattleCoords)
{
switch (position)
{
case B_POSITION_PLAYER_LEFT:
case B_POSITION_PLAYER_RIGHT:
if (xPos > sTypeIconPositions[position][useDoubleBattleCoords].x - 10)
return -1;
break;
default:
case B_POSITION_OPPONENT_LEFT:
case B_POSITION_OPPONENT_RIGHT:
if (xPos < sTypeIconPositions[position][useDoubleBattleCoords].x + 10)
return 1;
break;
}
return 0;
}
if (position == B_POSITION_PLAYER_LEFT)
{
if (xPos < sTypeIconPositions[position][useDoubleBattleCoords].x + 10)
return 1;
}
else
{
if (xPos > sTypeIconPositions[position][useDoubleBattleCoords].x - 10)
return -1;
}
return 0;
}
static s32 GetTypeIconBounceMovement(s32 originalY, u32 position)
{
struct Sprite* healthbox = &gSprites[gHealthboxSpriteIds[GetBattlerAtPosition(position)]];
return originalY + healthbox->y2;
}