fix form change tests

This commit is contained in:
cawtds 2025-02-10 18:43:55 +01:00
parent 889912b41c
commit d65ef7fa25
13 changed files with 101 additions and 119 deletions

View File

@ -2110,7 +2110,7 @@
.macro ai_vs_ai_battle trainer1:req, trainer2:req
setflag B_FLAG_AI_VS_AI_BATTLE
setvar VAR_0x8004, \trainer1
callnative CreateTrainerPartyForPlayer
callnative CreateTrainerPartyForPlayer, requests_effects=1
trainerbattle_no_intro \trainer2, NULL
.endm

View File

@ -51,7 +51,7 @@ extern const struct SpriteTemplate gBallSpriteTemplates[];
#define POKEBALL_PLAYER_SLIDEIN 0xFD
u8 DoPokeballSendOutAnimation(u32 battler, s16 pan, u8 kindOfThrow);
void CreatePokeballSpriteToReleaseMon(u8 monSpriteId, u8 monPalNum, u8 x, u8 y, u8 oamPriority, u8 subpriortiy, u8 delay, u32 fadePalettes);
void CreatePokeballSpriteToReleaseMon(u8 monSpriteId, u8 monPalNum, u8 x, u8 y, u8 oamPriority, u8 subpriority, u8 delay, u32 fadePalettes, u16 species);
u8 CreateTradePokeballSprite(u8 monSpriteId, u8 monPalNum, u8 x, u8 y, u8 oamPriority, u8 subPriority, u8 delay, u32 fadePalettes);
void DoHitAnimHealthboxEffect(u8 bank);
void LoadBallGfx(u8 ballId);

View File

@ -699,6 +699,7 @@ u8 GetItemEffectParamOffset(u32 battler, u16 itemId, u8 effectByte, u8 effectBit
u8 CanLearnTeachableMove(u16 species, u16 move);
u8 GetNature(struct Pokemon *mon);
u8 GetNatureFromPersonality(u32 personality);
u32 GetGMaxTargetSpecies(u32 species);
u16 GetEvolutionTargetSpecies(struct Pokemon *mon, enum EvolutionMode mode, u16 evolutionItem, struct Pokemon *tradePartner);
u16 NationalDexNumToSpecies(u16 nationalNum);
u16 SpeciesToNationalDexNum(u16 species);
@ -760,8 +761,8 @@ void DestroyMonSpritesGfxManager(u8 managerId);
u8 *MonSpritesGfxManager_GetSpritePtr(u8 managerId, u8 spriteNum);
u16 GetFormSpeciesId(u16 speciesId, u8 formId);
u8 GetFormIdFromFormSpeciesId(u16 formSpeciesId);
u16 GetFormChangeTargetSpecies(struct Pokemon *mon, u16 method, u32 arg);
u16 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *boxMon, u16 method, u32 arg);
u32 GetFormChangeTargetSpecies(struct Pokemon *mon, u16 method, u32 arg);
u32 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *boxMon, u16 method, u32 arg);
bool32 DoesSpeciesHaveFormChangeMethod(u16 species, u16 method);
void TryToSetBattleFormChangeMoves(struct Pokemon *mon, u16 method);
bool8 IsMonPastEvolutionLevel(struct Pokemon *mon);

View File

@ -936,12 +936,7 @@ void AnimTask_MetallicShine(u8 taskId)
species = SPECIES_NONE; // species = gContestResources->moveAnim->species;
}
else
{
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_SPECIES);
else
species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_SPECIES);
}
species = GetMonData(GetPartyBattlerData(gBattleAnimAttacker), MON_DATA_SPECIES);
spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER);
newSpriteId = CreateInvisibleSpriteCopy(gBattleAnimAttacker, spriteId, species);

View File

@ -909,10 +909,7 @@ void AnimTask_SwitchOutBallEffect(u8 taskId)
u32 selectedPalettes;
spriteId = gBattlerSpriteIds[gBattleAnimAttacker];
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
ballId = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_POKEBALL);
else
ballId = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_POKEBALL);
ballId = GetMonData(GetPartyBattlerData(gBattleAnimAttacker), MON_DATA_POKEBALL);
switch (gTasks[taskId].data[0])
{

View File

@ -320,12 +320,7 @@ void AnimTask_DrawFallingWhiteLinesOnAttacker(u8 taskId)
species = SPECIES_NONE; // species = gContestResources->moveAnim->species;
}
else
{
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_SPECIES);
else
species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_SPECIES);
}
species = GetMonData(GetPartyBattlerData(gBattleAnimAttacker), MON_DATA_SPECIES);
spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER);
newSpriteId = CreateInvisibleSpriteCopy(gBattleAnimAttacker, spriteId, species);
@ -462,12 +457,7 @@ static void StatsChangeAnimation_Step1(u8 taskId)
sAnimStatsChangeData->species = SPECIES_NONE; // sAnimStatsChangeData->species = gContestResources->moveAnim->species;
}
else
{
if (GetBattlerSide(sAnimStatsChangeData->battler1) != B_SIDE_PLAYER)
sAnimStatsChangeData->species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[sAnimStatsChangeData->battler1]], MON_DATA_SPECIES);
else
sAnimStatsChangeData->species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[sAnimStatsChangeData->battler1]], MON_DATA_SPECIES);
}
sAnimStatsChangeData->species = GetMonData(GetPartyBattlerData(sAnimStatsChangeData->battler1), MON_DATA_SPECIES);
gTasks[taskId].func = StatsChangeAnimation_Step2;
}
@ -844,12 +834,7 @@ void StartMonScrollingBgMask(u8 taskId, int UNUSED unused, u16 scrollSpeed, u8 b
species = SPECIES_NONE; // species = gContestResources->moveAnim->species;
}
else
{
if (GetBattlerSide(battler) != B_SIDE_PLAYER)
species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battler]], MON_DATA_SPECIES);
else
species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_SPECIES);
}
species = GetMonData(GetPartyBattlerData(battler), MON_DATA_SPECIES);
spriteId = CreateInvisibleSpriteCopy(battler, gBattlerSpriteIds[battler], species);
if (includePartner)

View File

@ -477,9 +477,9 @@ static void RecordedPlayerHandleChooseItem(u32 battler)
static void RecordedPlayerHandleChoosePokemon(u32 battler)
{
*(gBattleStruct->monToSwitchIntoId + battler) = RecordedBattle_GetBattlerAction(RECORDED_PARTY_INDEX, battler);
gBattleStruct->monToSwitchIntoId[battler] = RecordedBattle_GetBattlerAction(RECORDED_PARTY_INDEX, battler);
gSelectedMonPartyId = gBattleStruct->monToSwitchIntoId[battler]; // Revival Blessing
BtlController_EmitChosenMonReturnValue(battler, BUFFER_B, *(gBattleStruct->monToSwitchIntoId + battler), NULL);
BtlController_EmitChosenMonReturnValue(battler, BUFFER_B, gBattleStruct->monToSwitchIntoId[battler], NULL);
RecordedPlayerBufferExecCompleted(battler);
}

View File

@ -2568,7 +2568,7 @@ void BtlController_HandleTrainerSlide(u32 battler, u32 trainerPicId)
{
DecompressTrainerFrontPic(trainerPicId, battler);
SetMultiuseSpriteTemplateToTrainerFront(trainerPicId, GetBattlerPosition(battler));
gBattleStruct->trainerSlideSpriteIds[battler] = CreateSprite(&gMultiuseSpriteTemplate, 176, (8 - gTrainerSprites[trainerPicId].frontPicCoords.size) * 4 + 40, 30);
gBattleStruct->trainerSlideSpriteIds[battler] = CreateSprite(&gMultiuseSpriteTemplate, 176, (8 - gTrainerSprites[trainerPicId].frontPicCoords.size) * 4 + 40, 0);
gSprites[gBattleStruct->trainerSlideSpriteIds[battler]].oam.affineParam = trainerPicId;
gSprites[gBattleStruct->trainerSlideSpriteIds[battler]].oam.paletteNum = IndexOfSpritePaletteTag(gTrainerSprites[trainerPicId].palette.tag);
gSprites[gBattleStruct->trainerSlideSpriteIds[battler]].x2 = 96;

View File

@ -381,7 +381,7 @@ bool8 IsBattleSEPlaying(u8 battlerId)
void BattleLoadMonSpriteGfx(struct Pokemon *mon, u32 battler)
{
u32 monsPersonality, currentPersonality, isShiny, species, paletteOffset, position;
u32 personalityValue, isShiny, species, paletteOffset, position;
const void *lzPaletteData;
struct Pokemon *illusionMon = GetIllusionMonPtr(battler);
if (illusionMon != NULL)
@ -390,52 +390,47 @@ void BattleLoadMonSpriteGfx(struct Pokemon *mon, u32 battler)
if (GetMonData(mon, MON_DATA_IS_EGG) || GetMonData(mon, MON_DATA_SPECIES) == SPECIES_NONE) // Don't load GFX of egg pokemon.
return;
monsPersonality = GetMonData(mon, MON_DATA_PERSONALITY);
isShiny = GetMonData(mon, MON_DATA_IS_SHINY);
if (gBattleSpritesDataPtr->battlerData[battler].transformSpecies == SPECIES_NONE)
{
species = GetMonData(mon, MON_DATA_SPECIES);
currentPersonality = monsPersonality;
personalityValue = GetMonData(mon, MON_DATA_PERSONALITY);
}
else
{
species = gBattleSpritesDataPtr->battlerData[battler].transformSpecies;
// If battler has Gigantamax factor, try convert gfx to G-Max version
if (GetActiveGimmick(battler) == GIMMICK_DYNAMAX && GetMonData(mon, MON_DATA_GIGANTAMAX_FACTOR))
gBattleSpritesDataPtr->battlerData[battler].transformSpecies = species = GetGMaxTargetSpecies(species);
if (B_TRANSFORM_SHINY >= GEN_4)
{
currentPersonality = gTransformedPersonalities[battler];
personalityValue = gTransformedPersonalities[battler];
isShiny = gTransformedShininess[battler];
}
else
{
currentPersonality = monsPersonality;
personalityValue = GetMonData(mon, MON_DATA_PERSONALITY);
}
}
position = GetBattlerPosition(battler);
if (GetBattlerSide(battler) == B_SIDE_OPPONENT)
{
HandleLoadSpecialPokePic(TRUE,
gMonSpritesGfxPtr->spritesGfx[position],
species, currentPersonality);
}
else
{
HandleLoadSpecialPokePic(FALSE,
gMonSpritesGfxPtr->spritesGfx[position],
species, currentPersonality);
}
HandleLoadSpecialPokePic((GetBattlerSide(battler) == B_SIDE_OPPONENT),
gMonSpritesGfxPtr->spritesGfx[position],
species, personalityValue);
paletteOffset = OBJ_PLTT_ID(battler);
if (gBattleSpritesDataPtr->battlerData[battler].transformSpecies == SPECIES_NONE)
lzPaletteData = GetMonFrontSpritePal(mon);
else
lzPaletteData = GetMonSpritePalFromSpeciesAndPersonality(species, isShiny, currentPersonality);
lzPaletteData = GetMonSpritePalFromSpeciesAndPersonality(species, isShiny, personalityValue);
LZDecompressWram(lzPaletteData, gDecompressionBuffer);
LoadPalette(gDecompressionBuffer, paletteOffset, PLTT_SIZE_4BPP);
LoadPalette(gDecompressionBuffer, BG_PLTT_ID(8) + BG_PLTT_ID(battler), PLTT_SIZE_4BPP);
void *buffer = MallocAndDecompress(lzPaletteData, NULL);
LoadPalette(buffer, paletteOffset, PLTT_SIZE_4BPP);
LoadPalette(buffer, BG_PLTT_ID(8) + BG_PLTT_ID(battler), PLTT_SIZE_4BPP);
Free(buffer);
// transform's pink color
if (gBattleSpritesDataPtr->battlerData[battler].transformSpecies != SPECIES_NONE)
@ -806,32 +801,36 @@ void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool32 megaEvo, bo
StartSpriteAnim(&gSprites[gBattlerSpriteIds[battlerAtk]], 0);
}
void BattleLoadSubstituteOrMonSpriteGfx(u8 battlerId, bool8 loadMonSprite)
void BattleLoadSubstituteOrMonSpriteGfx(u8 battler, bool8 loadMonSprite)
{
u8 position;
s32 i;
u32 palOffset;
s32 i, position, palOffset;
if (!loadMonSprite)
{
position = GetBattlerPosition(battlerId);
if (GetBattlerSide(battlerId) != B_SIDE_PLAYER)
if (IsContest())
position = B_POSITION_PLAYER_LEFT;
else
position = GetBattlerPosition(battler);
if (IsContest())
LZDecompressVram(gSubstituteDollTilemap, gMonSpritesGfxPtr->spritesGfx[position]);
else if (GetBattlerSide(battler) != B_SIDE_PLAYER)
LZDecompressVram(gSubstituteDollGfx, gMonSpritesGfxPtr->spritesGfx[position]);
else
LZDecompressVram(gSubstituteDollTilemap, gMonSpritesGfxPtr->spritesGfx[position]);
for (i = 1; i < 4; ++i)
for (i = 1; i < 4; i++)
{
Dma3CopyLarge32_(gMonSpritesGfxPtr->spritesGfx[position], &gMonSpritesGfxPtr->spritesGfx[position][MON_PIC_SIZE * i], MON_PIC_SIZE);
}
palOffset = OBJ_PLTT_ID(battlerId);
palOffset = OBJ_PLTT_ID(battler);
LoadCompressedPalette(gSubstituteDollPal, palOffset, PLTT_SIZE_4BPP);
}
else
{
if (GetBattlerSide(battlerId) != B_SIDE_PLAYER)
BattleLoadMonSpriteGfx(&gEnemyParty[gBattlerPartyIndexes[battlerId]], battlerId);
else
BattleLoadMonSpriteGfx(&gPlayerParty[gBattlerPartyIndexes[battlerId]], battlerId);
if (!IsContest())
BattleLoadMonSpriteGfx(&GetBattlerParty(battler)[gBattlerPartyIndexes[battler]], battler);
}
}
@ -1044,9 +1043,11 @@ void SpriteCB_EnemyShadow(struct Sprite *shadowSprite)
return;
}
s8 xOffset = 0, yOffset = 0, size = SHADOW_SIZE_S;
s8 xOffset = 0, UNUSED yOffset = 0, size = SHADOW_SIZE_S;
if (gAnimScriptActive || battlerSprite->invisible)
{
invisible = TRUE;
}
else if (transformSpecies != SPECIES_NONE)
{
xOffset = gSpeciesInfo[transformSpecies].enemyShadowXOffset;
@ -1064,21 +1065,19 @@ void SpriteCB_EnemyShadow(struct Sprite *shadowSprite)
yOffset = gSpeciesInfo[species].enemyShadowYOffset + 16;
size = gSpeciesInfo[species].enemyShadowSize;
}
else
{
yOffset = 29;
}
if (gBattleSpritesDataPtr->battlerData[battler].behindSubstitute)
invisible = TRUE;
shadowSprite->x = battlerSprite->x + xOffset;
shadowSprite->x2 = battlerSprite->x2;
shadowSprite->y = battlerSprite->y + yOffset;
shadowSprite->invisible = invisible;
if (B_ENEMY_MON_SHADOW_STYLE >= GEN_4 && P_GBA_STYLE_SPECIES_GFX == FALSE)
{
shadowSprite->oam.tileNum = shadowSprite->tBaseTileNum + (8 * size);
shadowSprite->y = battlerSprite->y + yOffset;
}
}
#undef tBattlerId

View File

@ -1193,7 +1193,7 @@ static void Task_OakSpeech_ReleaseNidoranFFromPokeBall(u8 taskId)
spriteId = gTasks[taskId].tNidoranFSpriteId;
gSprites[spriteId].invisible = FALSE;
gSprites[spriteId].tSpriteTimer = 0;
CreatePokeballSpriteToReleaseMon(spriteId, gSprites[spriteId].oam.paletteNum, 100, 66, 0, 0, 32, 0xFFFF1FFF);
CreatePokeballSpriteToReleaseMon(spriteId, gSprites[spriteId].oam.paletteNum, 100, 66, 0, 0, 32, 0xFFFF1FFF, INTRO_SPECIES);
gTasks[taskId].func = Task_OakSpeech_IsInhabitedFarAndWide;
gTasks[taskId].tTimer = 0;
}

View File

@ -1,19 +1,20 @@
#include "global.h"
#include "gflib.h"
#include "battle.h"
#include "battle_anim.h"
#include "decompress.h"
#include "graphics.h"
#include "item.h"
#include "main.h"
#include "m4a.h"
#include "pokeball.h"
#include "pokemon.h"
#include "sound.h"
#include "sprite.h"
#include "task.h"
#include "trig.h"
#include "util.h"
#include "link.h"
#include "battle_gfx_sfx_util.h"
#include "data.h"
#include "item.h"
#include "constants/songs.h"
#include "constants/sound.h"
static void Task_DoPokeballSendOutAnim(u8 taskId);
static inline void DoPokeballSendOutSoundEffect(u32 battler);
@ -206,6 +207,8 @@ static const union AnimCmd *const sBallAnimSequences[] =
sBallAnimSeq0,
sBallAnimSeq1,
sBallAnimSeq2,
// unused?
sBallAnimSeq3,
sBallAnimSeq4,
sBallAnimSeq5,
@ -573,7 +576,7 @@ static void Task_DoPokeballSendOutAnim(u8 taskId)
throwCaseId = gTasks[taskId].tThrowId;
battlerId = gTasks[taskId].tBattler;
ballId = ItemIdToBallId(GetBattlerPokeballItemId(battlerId));
ballId = GetBattlerPokeballItemId(battlerId);
LoadBallGfx(ballId);
ballSpriteId = CreateSprite(&gBallSpriteTemplates[ballId], 32, 80, 29);
gSprites[ballSpriteId].data[0] = 0x80;
@ -589,8 +592,8 @@ static void Task_DoPokeballSendOutAnim(u8 taskId)
break;
case POKEBALL_PLAYER_SENDOUT:
gBattlerTarget = battlerId;
gSprites[ballSpriteId].x = (gBattleTypeFlags & BATTLE_TYPE_POKEDUDE) ? 32 : 48;
gSprites[ballSpriteId].y = (gBattleTypeFlags & BATTLE_TYPE_POKEDUDE) ? 64 : 70;
gSprites[ballSpriteId].x = 24;
gSprites[ballSpriteId].y = 68;
gSprites[ballSpriteId].callback = SpriteCB_MonSendOut_1;
DoPokeballSendOutSoundEffect(battlerId);
break;
@ -662,7 +665,7 @@ static void SpriteCB_BallThrow(struct Sprite *sprite)
sprite->x2 = 0;
sprite->y2 = 0;
sprite->data[5] = 0;
ballId = ItemIdToBallId(GetBattlerPokeballItemId(opponentBattler));
ballId = GetBattlerPokeballItemId(opponentBattler);
AnimateBallOpenParticles(sprite->x, sprite->y - 5, 1, 28, ballId);
sprite->data[0] = LaunchBallFadeMonTask(FALSE, opponentBattler, 14, ballId);
sprite->sBattler = opponentBattler;
@ -978,7 +981,7 @@ static void SpriteCB_ReleaseMonFromBall(struct Sprite *sprite)
u32 ballId;
StartSpriteAnim(sprite, 1);
ballId = ItemIdToBallId(GetBattlerPokeballItemId(battlerId));
ballId = GetBattlerPokeballItemId(battlerId);
AnimateBallOpenParticles(sprite->x, sprite->y - 5, 1, 28, ballId);
sprite->data[0] = LaunchBallFadeMonTask(TRUE, sprite->sBattler, 14, ballId);
sprite->callback = HandleBallAnimEnd;
@ -990,16 +993,11 @@ static void SpriteCB_ReleaseMonFromBall(struct Sprite *sprite)
u16 wantedCryCase;
u8 taskId;
mon = GetPartyBattlerData(battlerId);
if (GetBattlerSide(battlerId) != B_SIDE_PLAYER)
{
mon = &gEnemyParty[gBattlerPartyIndexes[battlerId]];
pan = 25;
}
else
{
mon = &gPlayerParty[gBattlerPartyIndexes[battlerId]];
pan = -25;
}
if ((battlerId == GetBattlerAtPosition(B_POSITION_PLAYER_LEFT) || battlerId == GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT))
&& IsDoubleBattle() && gBattleSpritesDataPtr->animationData->introAnimActive)
@ -1132,7 +1130,7 @@ static void SpriteCB_BallThrow_CaptureMon(struct Sprite *sprite)
{
gDoingBattleAnim = FALSE;
m4aMPlayAllStop();
PlaySE(MUS_CAUGHT_INTRO);
PlaySE(MUS_EVOLVED);
}
else if (sprite->data[4] == 315)
{
@ -1260,7 +1258,10 @@ static u8 LaunchBallFadeMonTaskForPokeball(bool8 unFadeLater, u8 spritePalNum, u
return LaunchBallFadeMonTask(unFadeLater, spritePalNum, selectedPalettes, BALL_POKE);
}
// Sprite data for the pokeball
// Sprite data for the Pokémon
#define sSpecies data[7]
// Sprite data for the Poké Ball
#define sMonSpriteId data[0]
#define sDelay data[1]
#define sMonPalNum data[2]
@ -1270,14 +1271,14 @@ static u8 LaunchBallFadeMonTaskForPokeball(bool8 unFadeLater, u8 spritePalNum, u
#define sFinalMonY data[6]
#define sTrigIdx data[7]
// Pokeball in Oak intro, and when receiving via trade
void CreatePokeballSpriteToReleaseMon(u8 monSpriteId, u8 monPalNum, u8 x, u8 y, u8 oamPriority, u8 subpriortiy, u8 delay, u32 fadePalettes)
// Poké Ball in Birch intro, and when receiving via trade
void CreatePokeballSpriteToReleaseMon(u8 monSpriteId, u8 monPalNum, u8 x, u8 y, u8 oamPriority, u8 subpriority, u8 delay, u32 fadePalettes, u16 species)
{
u8 spriteId;
LoadCompressedSpriteSheetUsingHeap(&gBallSpriteSheets[BALL_POKE]);
LoadCompressedSpritePaletteUsingHeap(&gBallSpritePalettes[BALL_POKE]);
spriteId = CreateSprite(&gBallSpriteTemplates[BALL_POKE], x, y, subpriortiy);
spriteId = CreateSprite(&gBallSpriteTemplates[BALL_POKE], x, y, subpriority);
gSprites[spriteId].sMonSpriteId = monSpriteId;
gSprites[spriteId].sFinalMonX = gSprites[monSpriteId].x;
@ -1285,6 +1286,7 @@ void CreatePokeballSpriteToReleaseMon(u8 monSpriteId, u8 monPalNum, u8 x, u8 y,
gSprites[monSpriteId].x = x;
gSprites[monSpriteId].y = y;
gSprites[monSpriteId].sSpecies = species;
gSprites[spriteId].sDelay = delay;
gSprites[spriteId].sMonPalNum = monPalNum;
@ -1366,10 +1368,16 @@ static void SpriteCB_ReleasedMonFlyOut(struct Sprite *sprite)
}
if (sprite->animEnded && emergeAnimFinished && atFinalPosition)
{
if (gSprites[monSpriteId].sSpecies == SPECIES_EGG)
DoMonFrontSpriteAnimation(&gSprites[monSpriteId], gSprites[monSpriteId].sSpecies, TRUE, 0);
else
DoMonFrontSpriteAnimation(&gSprites[monSpriteId], gSprites[monSpriteId].sSpecies, FALSE, 0);
DestroySpriteAndFreeResources(sprite);
}
}
#undef sSpecies
#undef sFinalMonX
#undef sFinalMonY
#undef sTrigIdx
@ -1414,7 +1422,7 @@ static void SpriteCB_TradePokeball(struct Sprite *sprite)
sprite->callback = SpriteCB_TradePokeballSendOff;
#ifdef BUGFIX
// FIX: If this is used on a sprite that has previously had an affine animation, it will not
// play the shrink anim properly due to being paused.
// play the shrink anim properly due to being paused. Works together with the fix to ResetSpriteAfterAnim.
gSprites[monSpriteId].affineAnimPaused = FALSE;
#endif // BUGFIX
StartSpriteAffineAnim(&gSprites[monSpriteId], BATTLER_AFFINE_RETURN);
@ -1463,7 +1471,7 @@ static void SpriteCB_TradePokeballEnd(struct Sprite *sprite)
#undef sFadePalsHi
#undef sTimer
// Unreferenced in RSE, but used here, possibly by mistake.
// Unreferenced here and in RS, but used in FRLG, possibly by mistake.
void DestroySpriteAndFreeResources_Ball(struct Sprite *sprite)
{
DestroySpriteAndFreeResources(sprite);
@ -1546,7 +1554,7 @@ void LoadBallGfx(u8 ballId)
{
u16 var;
if (GetSpriteTileStartByTag(gBallSpriteSheets[ballId].tag) == TAG_NONE)
if (GetSpriteTileStartByTag(gBallSpriteSheets[ballId].tag) == 0xFFFF)
{
LoadCompressedSpriteSheetUsingHeap(&gBallSpriteSheets[ballId]);
LoadCompressedSpritePaletteUsingHeap(&gBallSpritePalettes[ballId]);
@ -1572,12 +1580,8 @@ void FreeBallGfx(u8 ballId)
static u16 GetBattlerPokeballItemId(u8 battlerId)
{
struct Pokemon *mon, *illusionMon;
if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
mon = &gPlayerParty[gBattlerPartyIndexes[battlerId]];
else
mon = &gEnemyParty[gBattlerPartyIndexes[battlerId]];
struct Pokemon *illusionMon;
struct Pokemon *mon = GetPartyBattlerData(battlerId);
illusionMon = GetIllusionMonPtr(battlerId);
if (illusionMon != NULL)
@ -1595,4 +1599,3 @@ enum PokeBall ItemIdToBallId(u32 ballItem)
return secondaryId;
}

View File

@ -4190,16 +4190,16 @@ u8 GetNatureFromPersonality(u32 personality)
return personality % NUM_NATURES;
}
static u32 GetGMaxTargetSpecies(u32 species)
u32 GetGMaxTargetSpecies(u32 species)
{
const struct FormChange *formChanges = GetSpeciesFormChanges(species);
u32 i;
for (i = 0; formChanges[i].method != FORM_CHANGE_TERMINATOR; i++)
for (i = 0; formChanges != NULL && formChanges[i].method != FORM_CHANGE_TERMINATOR; i++)
{
if (formChanges[i].method == FORM_CHANGE_BATTLE_GIGANTAMAX)
return formChanges[i].targetSpecies;
}
return SPECIES_NONE;
return species;
}
u16 GetEvolutionTargetSpecies(struct Pokemon *mon, enum EvolutionMode mode, u16 evolutionItem, struct Pokemon *tradePartner)
@ -4377,7 +4377,7 @@ u16 GetEvolutionTargetSpecies(struct Pokemon *mon, enum EvolutionMode mode, u16
{
for (j = 0; j < MAX_MON_MOVES; j++)
{
if (gMovesInfo[GetMonData(mon, MON_DATA_MOVE1 + j, NULL)].type == evolutions[i].param)
if (GetMoveType(GetMonData(mon, MON_DATA_MOVE1 + j, NULL)) == evolutions[i].param)
{
targetSpecies = evolutions[i].targetSpecies;
break;
@ -4637,8 +4637,8 @@ u16 GetEvolutionTargetSpecies(struct Pokemon *mon, enum EvolutionMode mode, u16
// Gigantamax Factor. We assume that is because their evolutions
// do not have a Gigantamax Form.
if (GetMonData(mon, MON_DATA_GIGANTAMAX_FACTOR, NULL)
&& GetGMaxTargetSpecies(species) != SPECIES_NONE
&& GetGMaxTargetSpecies(targetSpecies) == SPECIES_NONE)
&& GetGMaxTargetSpecies(species) != species
&& GetGMaxTargetSpecies(targetSpecies) == targetSpecies)
{
return SPECIES_NONE;
}
@ -6195,17 +6195,18 @@ u8 GetFormIdFromFormSpeciesId(u16 formSpeciesId)
return targetFormId;
}
u16 GetFormChangeTargetSpecies(struct Pokemon *mon, u16 method, u32 arg)
// Returns the current species if no form change is possible
u32 GetFormChangeTargetSpecies(struct Pokemon *mon, u16 method, u32 arg)
{
return GetFormChangeTargetSpeciesBoxMon(&mon->box, method, arg);
}
// Returns SPECIES_NONE if no form change is possible
u16 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *boxMon, u16 method, u32 arg)
// Returns the current species if no form change is possible
u32 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *boxMon, u16 method, u32 arg)
{
u32 i;
u16 targetSpecies = SPECIES_NONE;
u16 species = GetBoxMonData(boxMon, MON_DATA_SPECIES, NULL);
u32 species = GetBoxMonData(boxMon, MON_DATA_SPECIES, NULL);
u32 targetSpecies = species;
const struct FormChange *formChanges = GetSpeciesFormChanges(species);
u16 heldItem;
u32 ability;
@ -6270,6 +6271,7 @@ u16 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *boxMon, u16 method, u32
targetSpecies = formChanges[i].targetSpecies;
break;
case FORM_CHANGE_WITHDRAW:
case FORM_CHANGE_DEPOSIT:
case FORM_CHANGE_FAINT:
case FORM_CHANGE_DAYS_PASSED:
targetSpecies = formChanges[i].targetSpecies;

View File

@ -1712,7 +1712,7 @@ static bool8 DoTradeAnim_Cable(void)
gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].x2 = 0;
gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].y2 = 0;
StartSpriteAnim(&gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]], 0);
CreatePokeballSpriteToReleaseMon(sTradeAnim->monSpriteIds[TRADE_PARTNER], gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].oam.paletteNum, 120, 84, 2, 1, 20, 0xFFFFF);
CreatePokeballSpriteToReleaseMon(sTradeAnim->monSpriteIds[TRADE_PARTNER], gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].oam.paletteNum, 120, 84, 2, 1, 20, 0xFFFFF, sTradeAnim->monSpecies[TRADE_PARTNER]);
FreeSpriteOamMatrix(&gSprites[sTradeAnim->bouncingPokeballSpriteId]);
DestroySprite(&gSprites[sTradeAnim->bouncingPokeballSpriteId]);
sTradeAnim->state++;
@ -2212,7 +2212,7 @@ static bool8 DoTradeAnim_Wireless(void)
gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].x2 = 0;
gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].y2 = 0;
StartSpriteAnim(&gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]], 0);
CreatePokeballSpriteToReleaseMon(sTradeAnim->monSpriteIds[TRADE_PARTNER], gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].oam.paletteNum, 120, 84, 2, 1, 20, 0xFFFFF);
CreatePokeballSpriteToReleaseMon(sTradeAnim->monSpriteIds[TRADE_PARTNER], gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].oam.paletteNum, 120, 84, 2, 1, 20, 0xFFFFF, sTradeAnim->monSpecies[TRADE_PARTNER]);
FreeSpriteOamMatrix(&gSprites[sTradeAnim->bouncingPokeballSpriteId]);
DestroySprite(&gSprites[sTradeAnim->bouncingPokeballSpriteId]);
sTradeAnim->state++;