diff --git a/asm/macros/event.inc b/asm/macros/event.inc index 1ca134c3b..3df5d1389 100644 --- a/asm/macros/event.inc +++ b/asm/macros/event.inc @@ -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 diff --git a/include/pokeball.h b/include/pokeball.h index 766b6313b..29d8ccfe0 100644 --- a/include/pokeball.h +++ b/include/pokeball.h @@ -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); diff --git a/include/pokemon.h b/include/pokemon.h index 1afec283f..7ee2c5590 100644 --- a/include/pokemon.h +++ b/include/pokemon.h @@ -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); diff --git a/src/battle_anim_dark.c b/src/battle_anim_dark.c index 3045243cc..7aa5cfba9 100644 --- a/src/battle_anim_dark.c +++ b/src/battle_anim_dark.c @@ -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); diff --git a/src/battle_anim_throw.c b/src/battle_anim_throw.c index a930c7597..47554ff50 100644 --- a/src/battle_anim_throw.c +++ b/src/battle_anim_throw.c @@ -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]) { diff --git a/src/battle_anim_utility_funcs.c b/src/battle_anim_utility_funcs.c index d093a9b48..6306654da 100644 --- a/src/battle_anim_utility_funcs.c +++ b/src/battle_anim_utility_funcs.c @@ -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) diff --git a/src/battle_controller_recorded_player.c b/src/battle_controller_recorded_player.c index 004d7c2f6..fd53c0b95 100644 --- a/src/battle_controller_recorded_player.c +++ b/src/battle_controller_recorded_player.c @@ -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); } diff --git a/src/battle_controllers.c b/src/battle_controllers.c index 14d86e738..0204446e9 100644 --- a/src/battle_controllers.c +++ b/src/battle_controllers.c @@ -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; diff --git a/src/battle_gfx_sfx_util.c b/src/battle_gfx_sfx_util.c index 28d63a8fe..8a7b364d3 100644 --- a/src/battle_gfx_sfx_util.c +++ b/src/battle_gfx_sfx_util.c @@ -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 diff --git a/src/oak_speech.c b/src/oak_speech.c index c26582867..e6d7a55ae 100644 --- a/src/oak_speech.c +++ b/src/oak_speech.c @@ -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; } diff --git a/src/pokeball.c b/src/pokeball.c index 5bdc34ddf..91278d876 100644 --- a/src/pokeball.c +++ b/src/pokeball.c @@ -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; } - diff --git a/src/pokemon.c b/src/pokemon.c index 8aaf487d8..bb88953c5 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -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; diff --git a/src/trade_scene.c b/src/trade_scene.c index 68d868b16..8d30957f6 100644 --- a/src/trade_scene.c +++ b/src/trade_scene.c @@ -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++;