Merge branch 'followers' into followers-expanded-id

This commit is contained in:
Ariel A 2023-10-15 02:46:46 -04:00
commit f27a252958
5 changed files with 1632 additions and 894 deletions

View file

@ -85,6 +85,8 @@
#define SAFE_DIV(a, b) ((a) / (b)) #define SAFE_DIV(a, b) ((a) / (b))
#endif #endif
#define IS_POW_OF_TWO(n) (((n) & ((n)-1)) == 0)
// The below macro does a%n, but (to match) will switch to a&(n-1) if n is a power of 2. // The below macro does a%n, but (to match) will switch to a&(n-1) if n is a power of 2.
// There are cases where GF does a&(n-1) where we would really like to have a%n, because // There are cases where GF does a&(n-1) where we would really like to have a%n, because
// if n is changed to a value that isn't a power of 2 then a&(n-1) is unlikely to work as // if n is changed to a value that isn't a power of 2 then a&(n-1) is unlikely to work as

File diff suppressed because it is too large Load diff

View file

@ -6771,19 +6771,26 @@ bool8 MovementAction_ExitPokeball_Step1(struct ObjectEvent *objectEvent, struct
return TRUE; return TRUE;
// Set graphics, palette, and affine animation // Set graphics, palette, and affine animation
} else if ((duration == 0 && sprite->data[3] == 3) || (duration == 1 && sprite->data[3] == 7)) { } else if ((duration == 0 && sprite->data[3] == 3) || (duration == 1 && sprite->data[3] == 7)) {
FollowerSetGraphics(objectEvent, OW_SPECIES(objectEvent), OW_FORM(objectEvent), objectEvent->shiny); FollowerSetGraphics(objectEvent, OW_SPECIES(objectEvent), OW_FORM(objectEvent), objectEvent->shiny);
LoadFillColorPalette(RGB_WHITE, OBJ_EVENT_PAL_TAG_WHITE, sprite); LoadFillColorPalette(RGB_WHITE, OBJ_EVENT_PAL_TAG_WHITE, sprite);
// Initialize affine animation // Initialize affine animation
sprite->affineAnims = sAffineAnims_PokeballFollower; sprite->affineAnims = sAffineAnims_PokeballFollower;
sprite->oam.affineMode = ST_OAM_AFFINE_NORMAL; #if LARGE_OW_SUPPORT
InitSpriteAffineAnim(sprite); if (IS_POW_OF_TWO(-sprite->centerToCornerVecX)) {
StartSpriteAffineAnim(sprite, sprite->data[6] >> 4); #endif
sprite->affineAnims = sAffineAnims_PokeballFollower;
sprite->oam.affineMode = ST_OAM_AFFINE_NORMAL;
InitSpriteAffineAnim(sprite);
StartSpriteAffineAnim(sprite, sprite->data[6] >> 4);
#if LARGE_OW_SUPPORT
}
#endif
// Restore original palette & disable affine // Restore original palette & disable affine
} else if ((duration == 0 && sprite->data[3] == 1) || (duration == 1 && sprite->data[3] == 3)) { } else if ((duration == 0 && sprite->data[3] == 1) || (duration == 1 && sprite->data[3] == 3)) {
sprite->affineAnimEnded = TRUE; sprite->affineAnimEnded = TRUE;
FreeSpriteOamMatrix(sprite); FreeSpriteOamMatrix(sprite);
sprite->oam.affineMode = ST_OAM_AFFINE_OFF; sprite->oam.affineMode = ST_OAM_AFFINE_OFF;
FollowerSetGraphics(objectEvent, OW_SPECIES(objectEvent), OW_FORM(objectEvent), objectEvent->shiny); FollowerSetGraphics(objectEvent, OW_SPECIES(objectEvent), OW_FORM(objectEvent), objectEvent->shiny);
} }
return FALSE; return FALSE;
} }
@ -6805,21 +6812,27 @@ bool8 MovementAction_EnterPokeball_Step1(struct ObjectEvent *objectEvent, struct
sprite->data[2] = 2; sprite->data[2] = 2;
return FALSE; return FALSE;
} else if (sprite->data[3] == 11) { // Set palette to white & start affine } else if (sprite->data[3] == 11) { // Set palette to white & start affine
LoadFillColorPalette(RGB_WHITE, OBJ_EVENT_PAL_TAG_WHITE, sprite); LoadFillColorPalette(RGB_WHITE, OBJ_EVENT_PAL_TAG_WHITE, sprite);
sprite->affineAnims = sAffineAnims_PokeballFollower; #if LARGE_OW_SUPPORT
sprite->oam.affineMode = ST_OAM_AFFINE_NORMAL; // Only do affine if sprite width is power of 2
#if LARGE_OW_SUPPORT // (effect looks weird on sprites composed of subsprites like 48x48, etc)
sprite->subspriteTableNum = 1; if (IS_POW_OF_TWO(-sprite->centerToCornerVecX)) {
#endif #endif
InitSpriteAffineAnim(sprite); sprite->affineAnims = sAffineAnims_PokeballFollower;
StartSpriteAffineAnim(sprite, sprite->data[6]); sprite->oam.affineMode = ST_OAM_AFFINE_NORMAL;
InitSpriteAffineAnim(sprite);
StartSpriteAffineAnim(sprite, sprite->data[6]);
#if LARGE_OW_SUPPORT
}
#endif
sprite->subspriteTableNum = 0;
} else if (sprite->data[3] == 7) { // Free white palette and change to pokeball, disable affine } else if (sprite->data[3] == 7) { // Free white palette and change to pokeball, disable affine
sprite->affineAnimEnded = TRUE; sprite->affineAnimEnded = TRUE;
FreeSpriteOamMatrix(sprite); FreeSpriteOamMatrix(sprite);
sprite->oam.affineMode = ST_OAM_AFFINE_OFF; sprite->oam.affineMode = ST_OAM_AFFINE_OFF;
ObjectEventSetGraphicsId(objectEvent, OBJ_EVENT_GFX_ANIMATED_BALL); ObjectEventSetGraphicsId(objectEvent, OBJ_EVENT_GFX_ANIMATED_BALL);
objectEvent->graphicsId = graphicsId; objectEvent->graphicsId = graphicsId;
objectEvent->inanimate = FALSE; objectEvent->inanimate = FALSE;
} }
return FALSE; return FALSE;
} }
@ -8877,9 +8890,6 @@ void ObjectEventUpdateElevation(struct ObjectEvent *objEvent, struct Sprite *spr
#endif #endif
return; return;
} }
#if LARGE_OW_SUPPORT
sprite->subspriteMode = SUBSPRITES_ON;
#endif
objEvent->currentElevation = curElevation; objEvent->currentElevation = curElevation;
@ -9270,6 +9280,9 @@ static void DoGroundEffects_OnSpawn(struct ObjectEvent *objEvent, struct Sprite
if (objEvent->triggerGroundEffectsOnMove) if (objEvent->triggerGroundEffectsOnMove)
{ {
flags = 0; flags = 0;
#if LARGE_OW_SUPPORT
sprite->subspriteMode = SUBSPRITES_ON;
#endif
UpdateObjectEventElevationAndPriority(objEvent, sprite); UpdateObjectEventElevationAndPriority(objEvent, sprite);
GetAllGroundEffectFlags_OnSpawn(objEvent, &flags); GetAllGroundEffectFlags_OnSpawn(objEvent, &flags);
SetObjectEventSpriteOamTableForLongGrass(objEvent, sprite); SetObjectEventSpriteOamTableForLongGrass(objEvent, sprite);
@ -9286,6 +9299,9 @@ static void DoGroundEffects_OnBeginStep(struct ObjectEvent *objEvent, struct Spr
if (objEvent->triggerGroundEffectsOnMove) if (objEvent->triggerGroundEffectsOnMove)
{ {
flags = 0; flags = 0;
#if LARGE_OW_SUPPORT
sprite->subspriteMode = SUBSPRITES_ON;
#endif
UpdateObjectEventElevationAndPriority(objEvent, sprite); UpdateObjectEventElevationAndPriority(objEvent, sprite);
GetAllGroundEffectFlags_OnBeginStep(objEvent, &flags); GetAllGroundEffectFlags_OnBeginStep(objEvent, &flags);
SetObjectEventSpriteOamTableForLongGrass(objEvent, sprite); SetObjectEventSpriteOamTableForLongGrass(objEvent, sprite);

View file

@ -13,11 +13,15 @@
#include "trig.h" #include "trig.h"
#include "constants/event_objects.h" #include "constants/event_objects.h"
#include "constants/field_effects.h" #include "constants/field_effects.h"
#include "constants/rgb.h"
#include "constants/songs.h" #include "constants/songs.h"
#define OBJ_EVENT_PAL_TAG_NONE 0x11FF // duplicate of define in event_object_movement.c #define OBJ_EVENT_PAL_TAG_NONE 0x11FF // duplicate of define in event_object_movement.c
#define PAL_TAG_REFLECTION_OFFSET 0x2000 // reflection tag value is paletteTag + 0x2000 #define PAL_TAG_REFLECTION_OFFSET 0x2000 // reflection tag value is paletteTag + 0x2000
#define PAL_RAW_REFLECTION_OFFSET 0x4000 // raw reflection tag is paletteNum + 0x4000 #define PAL_RAW_REFLECTION_OFFSET 0x4000 // raw reflection tag is paletteNum + 0x4000
#define HIGH_BRIDGE_PAL_TAG 0x4010
// Build a unique tag for reflection's palette based on based tag, or paletteNum
#define REFLECTION_PAL_TAG(tag, num) ((tag) == TAG_NONE ? (num) + PAL_RAW_REFLECTION_OFFSET : (tag) + PAL_TAG_REFLECTION_OFFSET)
static void UpdateObjectReflectionSprite(struct Sprite *); static void UpdateObjectReflectionSprite(struct Sprite *);
static void LoadObjectReflectionPalette(struct ObjectEvent *objectEvent, struct Sprite *sprite); static void LoadObjectReflectionPalette(struct ObjectEvent *objectEvent, struct Sprite *sprite);
@ -65,8 +69,9 @@ void SetUpReflection(struct ObjectEvent *objectEvent, struct Sprite *sprite, boo
StartSpriteAnim(reflectionSprite, 0); StartSpriteAnim(reflectionSprite, 0);
reflectionSprite->affineAnims = gDummySpriteAffineAnimTable; reflectionSprite->affineAnims = gDummySpriteAffineAnimTable;
reflectionSprite->affineAnimBeginning = TRUE; reflectionSprite->affineAnimBeginning = TRUE;
reflectionSprite->subspriteMode = SUBSPRITES_OFF; reflectionSprite->subspriteMode = SUBSPRITES_IGNORE_PRIORITY;
reflectionSprite->sReflectionObjEventId = sprite->data[0]; reflectionSprite->subspriteTableNum = 0;
reflectionSprite->sReflectionObjEventId = sprite->sReflectionObjEventId;
reflectionSprite->sReflectionObjEventLocalId = objectEvent->localId; reflectionSprite->sReflectionObjEventLocalId = objectEvent->localId;
reflectionSprite->sIsStillReflection = stillReflection; reflectionSprite->sIsStillReflection = stillReflection;
LoadObjectReflectionPalette(objectEvent, reflectionSprite); LoadObjectReflectionPalette(objectEvent, reflectionSprite);
@ -93,7 +98,7 @@ static void LoadObjectReflectionPalette(struct ObjectEvent *objectEvent, struct
&& ((bridgeType = MetatileBehavior_GetBridgeType(objectEvent->previousMetatileBehavior)) && ((bridgeType = MetatileBehavior_GetBridgeType(objectEvent->previousMetatileBehavior))
|| (bridgeType = MetatileBehavior_GetBridgeType(objectEvent->currentMetatileBehavior)))) || (bridgeType = MetatileBehavior_GetBridgeType(objectEvent->currentMetatileBehavior))))
{ {
reflectionSprite->data[2] = bridgeReflectionVerticalOffsets[bridgeType - 1]; reflectionSprite->sReflectionVerticalOffset = bridgeReflectionVerticalOffsets[bridgeType - 1];
LoadObjectHighBridgeReflectionPalette(objectEvent, reflectionSprite); LoadObjectHighBridgeReflectionPalette(objectEvent, reflectionSprite);
} }
else else
@ -104,76 +109,71 @@ static void LoadObjectReflectionPalette(struct ObjectEvent *objectEvent, struct
// Apply a blue tint effect to a palette // Apply a blue tint effect to a palette
static void ApplyPondFilter(u8 paletteNum, u16 *dest) { static void ApplyPondFilter(u8 paletteNum, u16 *dest) {
u8 i, val, r, g, b; u32 i, r, g, b;
// CpuCopy16(gPlttBufferUnfaded + 0x100 + paletteNum * 16, dest, 32); // CpuCopy16(gPlttBufferUnfaded + 0x100 + paletteNum * 16, dest, 32);
u16 *src = gPlttBufferUnfaded + 0x100 + paletteNum * 16; u16 *src = gPlttBufferUnfaded + OBJ_PLTT_ID(paletteNum);
for (i = 0; i < 16; i++) { *dest++ = *src++; // copy transparency
r = src[i] & 0x1F; for (i = 0; i < 16 - 1; i++) {
g = (src[i] >> 5) & 0x1F; r = GET_R(src[i]);
b = (src[i] >> 10) & 0x1F; g = GET_G(src[i]);
b += 10; b = GET_B(src[i]);
if (b > 31) b += 10;
b = 31; if (b > 31)
*dest++ = (b << 10) | (g << 5) | r; b = 31;
} *dest++ = RGB2(r, g, b);
}
} }
// Apply a ice tint effect to a palette // Apply a ice tint effect to a palette
static void ApplyIceFilter(u8 paletteNum, u16 *dest) { static void ApplyIceFilter(u8 paletteNum, u16 *dest) {
u8 i, val, r, g, b; u32 i, r, g, b;
// CpuCopy16(gPlttBufferUnfaded + 0x100 + paletteNum * 16, dest, 32); // CpuCopy16(gPlttBufferUnfaded + 0x100 + paletteNum * 16, dest, 32);
u16 *src = gPlttBufferUnfaded + 0x100 + paletteNum * 16; u16 *src = gPlttBufferUnfaded + OBJ_PLTT_ID(paletteNum);
for (i = 0; i < 16; i++) { *dest++ = *src++; // copy transparency
r = src[i] & 0x1F; for (i = 0; i < 16 - 1; i++) {
r -= 5; r = GET_R(src[i]);
if (r > 31) r -= 5;
r = 0; if (r > 31)
g = (src[i] >> 5) & 0x1F; r = 0;
g += 3; g = GET_G(src[i]);
if (g > 31) g += 3;
g = 31; if (g > 31)
b = (src[i] >> 10) & 0x1F; g = 31;
b += 16; b = GET_B(src[i]);
if (b > 31) b += 16;
b = 31; if (b > 31)
*dest++ = (b << 10) | (g << 5) | r; b = 31;
} *dest++ = RGB2(r, g, b);
}
} }
static void LoadObjectRegularReflectionPalette(struct ObjectEvent *objectEvent, struct Sprite *sprite) static void LoadObjectRegularReflectionPalette(struct ObjectEvent *objectEvent, struct Sprite *sprite)
{ {
const struct ObjectEventGraphicsInfo *graphicsInfo = GetObjectEventGraphicsInfo(objectEvent->graphicsId);
const struct Sprite *mainSprite = &gSprites[objectEvent->spriteId]; const struct Sprite *mainSprite = &gSprites[objectEvent->spriteId];
u16 baseTag = GetSpritePaletteTagByPaletteNum(mainSprite->oam.paletteNum); u16 baseTag = GetSpritePaletteTagByPaletteNum(mainSprite->oam.paletteNum);
u16 paletteTag = baseTag == 0xFFFF ? mainSprite->oam.paletteNum + PAL_RAW_REFLECTION_OFFSET : baseTag + PAL_TAG_REFLECTION_OFFSET; u16 paletteTag = REFLECTION_PAL_TAG(baseTag, mainSprite->oam.paletteNum);
u8 paletteNum = IndexOfSpritePaletteTag(paletteTag); u8 paletteNum = IndexOfSpritePaletteTag(paletteTag);
if (paletteNum == 0xFF) { // Load filtered palette if (paletteNum <= 16) { // Load filtered palette
u16 filteredData[16] = {0}; u16 filteredData[16];
struct SpritePalette filteredPalette = {.tag = paletteTag, .data = filteredData}; struct SpritePalette filteredPal = {.tag = paletteTag, .data = filteredData};
if (sprite->data[7] == FALSE) { if (sprite->sIsStillReflection == FALSE)
ApplyPondFilter(mainSprite->oam.paletteNum, filteredData); ApplyPondFilter(mainSprite->oam.paletteNum, filteredData);
} else { else
ApplyIceFilter(mainSprite->oam.paletteNum, filteredData); ApplyIceFilter(mainSprite->oam.paletteNum, filteredData);
} paletteNum = LoadSpritePalette(&filteredPal);
paletteNum = LoadSpritePalette(&filteredPalette); UpdateSpritePaletteWithWeather(paletteNum);
UpdateSpritePaletteWithWeather(paletteNum);
} }
sprite->oam.paletteNum = paletteNum; sprite->oam.paletteNum = paletteNum;
sprite->oam.objMode = 1; // Alpha blending sprite->oam.objMode = ST_OAM_OBJ_BLEND;
} }
#define HIGH_BRIDGE_PAL_TAG 0x4010
// When walking on a bridge high above water (Route 120), the reflection is a solid dark blue color. // When walking on a bridge high above water (Route 120), the reflection is a solid dark blue color.
// This is so the sprite blends in with the dark water metatile underneath the bridge. // This is so the sprite blends in with the dark water metatile underneath the bridge.
static void LoadObjectHighBridgeReflectionPalette(struct ObjectEvent *objectEvent, struct Sprite *sprite) static void LoadObjectHighBridgeReflectionPalette(struct ObjectEvent *objectEvent, struct Sprite *sprite)
{ {
u16 blueData[16] = {0}; u16 blueData[16];
struct SpritePalette bluePalette = {.tag = HIGH_BRIDGE_PAL_TAG, .data = blueData}; struct SpritePalette bluePalette = {.tag = HIGH_BRIDGE_PAL_TAG, .data = blueData};
u8 i; CpuFill16(0x55C9, blueData, PLTT_SIZE_4BPP);
for (i = 1; i < 16; i++) {
blueData[i] = 0x55c9;
}
sprite->oam.paletteNum = LoadSpritePalette(&bluePalette); sprite->oam.paletteNum = LoadSpritePalette(&bluePalette);
UpdateSpritePaletteWithWeather(sprite->oam.paletteNum); UpdateSpritePaletteWithWeather(sprite->oam.paletteNum);
} }
@ -183,7 +183,7 @@ static void UpdateObjectReflectionSprite(struct Sprite *reflectionSprite)
struct ObjectEvent *objectEvent = &gObjectEvents[reflectionSprite->data[0]]; struct ObjectEvent *objectEvent = &gObjectEvents[reflectionSprite->data[0]];
struct Sprite *mainSprite = &gSprites[objectEvent->spriteId]; struct Sprite *mainSprite = &gSprites[objectEvent->spriteId];
if (!objectEvent->active || !objectEvent->hasReflection || objectEvent->localId != reflectionSprite->data[1]) if (!objectEvent->active || !objectEvent->hasReflection || objectEvent->localId != reflectionSprite->sReflectionObjEventLocalId)
{ {
reflectionSprite->inUse = FALSE; reflectionSprite->inUse = FALSE;
FieldEffectFreePaletteIfUnused(reflectionSprite->oam.paletteNum); FieldEffectFreePaletteIfUnused(reflectionSprite->oam.paletteNum);
@ -191,37 +191,37 @@ static void UpdateObjectReflectionSprite(struct Sprite *reflectionSprite)
} }
// Only filter palette if not using the high bridge blue palette // Only filter palette if not using the high bridge blue palette
// This is basically a copy of LoadObjectRegularReflectionPalette
if (IndexOfSpritePaletteTag(HIGH_BRIDGE_PAL_TAG) != reflectionSprite->oam.paletteNum) { if (IndexOfSpritePaletteTag(HIGH_BRIDGE_PAL_TAG) != reflectionSprite->oam.paletteNum) {
u16 baseTag = GetSpritePaletteTagByPaletteNum(mainSprite->oam.paletteNum); u16 baseTag = GetSpritePaletteTagByPaletteNum(mainSprite->oam.paletteNum);
u16 paletteTag = baseTag == 0xFFFF ? mainSprite->oam.paletteNum + PAL_RAW_REFLECTION_OFFSET : baseTag + PAL_TAG_REFLECTION_OFFSET; u16 paletteTag = REFLECTION_PAL_TAG(baseTag, mainSprite->oam.paletteNum);
u8 paletteNum = IndexOfSpritePaletteTag(paletteTag); u8 paletteNum = IndexOfSpritePaletteTag(paletteTag);
if (paletteNum == 0xFF) { // Build filtered palette if (paletteNum >= 16) { // Build filtered palette
u16 filteredData[16] = {0}; u16 filteredData[16];
struct SpritePalette filteredPalette = {.tag = paletteTag, .data = filteredData}; struct SpritePalette filteredPal = {.tag = paletteTag, .data = filteredData};
// Free palette if unused // Free palette if unused
reflectionSprite->inUse = FALSE; reflectionSprite->inUse = FALSE;
FieldEffectFreePaletteIfUnused(reflectionSprite->oam.paletteNum); FieldEffectFreePaletteIfUnused(reflectionSprite->oam.paletteNum);
reflectionSprite->inUse = TRUE; reflectionSprite->inUse = TRUE;
if (reflectionSprite->data[7] == FALSE) { if (reflectionSprite->sIsStillReflection == FALSE) {
ApplyPondFilter(mainSprite->oam.paletteNum, filteredData); ApplyPondFilter(mainSprite->oam.paletteNum, filteredData);
} else { } else {
ApplyIceFilter(mainSprite->oam.paletteNum, filteredData); ApplyIceFilter(mainSprite->oam.paletteNum, filteredData);
}
paletteNum = LoadSpritePalette(&filteredPal);
UpdateSpritePaletteWithWeather(paletteNum);
} }
paletteNum = LoadSpritePalette(&filteredPalette); reflectionSprite->oam.paletteNum = paletteNum;
UpdateSpritePaletteWithWeather(paletteNum);
}
reflectionSprite->oam.paletteNum = paletteNum;
} }
reflectionSprite->oam.shape = mainSprite->oam.shape; reflectionSprite->oam.shape = mainSprite->oam.shape;
reflectionSprite->oam.size = mainSprite->oam.size; reflectionSprite->oam.size = mainSprite->oam.size;
reflectionSprite->oam.matrixNum = mainSprite->oam.matrixNum | ST_OAM_VFLIP; reflectionSprite->oam.matrixNum = mainSprite->oam.matrixNum | ST_OAM_VFLIP;
reflectionSprite->oam.tileNum = mainSprite->oam.tileNum; reflectionSprite->oam.tileNum = mainSprite->oam.tileNum;
reflectionSprite->subspriteTables = mainSprite->subspriteTables; reflectionSprite->subspriteTables = mainSprite->subspriteTables;
reflectionSprite->subspriteTableNum = mainSprite->subspriteTableNum;
reflectionSprite->invisible = mainSprite->invisible; reflectionSprite->invisible = mainSprite->invisible;
reflectionSprite->x = mainSprite->x; reflectionSprite->x = mainSprite->x;
// reflectionSprite->data[2] holds an additional vertical offset, used by the high bridges on Route 120 // sReflectionVerticalOffset is only set for high bridges
reflectionSprite->y = mainSprite->y + GetReflectionVerticalOffset(objectEvent) + reflectionSprite->data[2]; reflectionSprite->y = mainSprite->y + GetReflectionVerticalOffset(objectEvent) + reflectionSprite->sReflectionVerticalOffset;
reflectionSprite->centerToCornerVecX = mainSprite->centerToCornerVecX; reflectionSprite->centerToCornerVecX = mainSprite->centerToCornerVecX;
reflectionSprite->centerToCornerVecY = mainSprite->centerToCornerVecY; reflectionSprite->centerToCornerVecY = mainSprite->centerToCornerVecY;
reflectionSprite->x2 = mainSprite->x2; reflectionSprite->x2 = mainSprite->x2;
@ -231,15 +231,17 @@ static void UpdateObjectReflectionSprite(struct Sprite *reflectionSprite)
if (objectEvent->hideReflection == TRUE) if (objectEvent->hideReflection == TRUE)
reflectionSprite->invisible = TRUE; reflectionSprite->invisible = TRUE;
// Check if the reflection is not still. // Support "virtual" sprites which can't be rotated via affines
if (reflectionSprite->data[7] == FALSE) if (reflectionSprite->subspriteTables[0].subsprites) {
reflectionSprite->oam.affineMode = ST_OAM_AFFINE_OFF;
return;
}
if (reflectionSprite->sIsStillReflection == FALSE)
{ {
// Sets the reflection sprite's rot/scale matrix to the appropriate // Sets the reflection sprite's rot/scale matrix to the correct
// matrix based on whether or not the main sprite is horizontally flipped. // water reflection matrix based on the main sprite's facing direction.
// If the sprite is facing to the east, then it is flipped, and its matrixNum is 8. // If the sprite is facing east, then it's flipped, and its matrixNum is 1.
reflectionSprite->oam.matrixNum = 0; reflectionSprite->oam.matrixNum = (mainSprite->oam.matrixNum & ST_OAM_HFLIP) ? 1 : 0;
if (mainSprite->oam.matrixNum & ST_OAM_HFLIP)
reflectionSprite->oam.matrixNum = 1;
} }
} }

View file

@ -3260,7 +3260,6 @@ void ScrollableMultichoice_ClosePersistentMenu(void)
#undef tTaskId #undef tTaskId
#define DEOXYS_ROCK_LEVELS 11 #define DEOXYS_ROCK_LEVELS 11
#define ROCK_PAL_ID 10
void DoDeoxysRockInteraction(void) void DoDeoxysRockInteraction(void)
{ {
@ -3337,11 +3336,13 @@ static void Task_DeoxysRockInteraction(u8 taskId)
} }
} }
// duplicate of event_object_movement
#define OBJ_EVENT_PAL_TAG_BIRTH_ISLAND_STONE 0x111F
static void ChangeDeoxysRockLevel(u8 rockLevel) static void ChangeDeoxysRockLevel(u8 rockLevel)
{ {
u8 objectEventId; u8 paletteNum = IndexOfSpritePaletteTag(OBJ_EVENT_PAL_TAG_BIRTH_ISLAND_STONE);
LoadPalette(&sDeoxysRockPalettes[rockLevel], OBJ_PLTT_ID(ROCK_PAL_ID), PLTT_SIZEOF(4)); LoadPalette(&sDeoxysRockPalettes[rockLevel], OBJ_PLTT_ID(paletteNum), PLTT_SIZEOF(4));
TryGetObjectEventIdByLocalIdAndMap(LOCALID_BIRTH_ISLAND_EXTERIOR_ROCK, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, &objectEventId);
if (rockLevel == 0) if (rockLevel == 0)
PlaySE(SE_M_CONFUSE_RAY); // Failure sound PlaySE(SE_M_CONFUSE_RAY); // Failure sound
@ -3387,10 +3388,13 @@ void IncrementBirthIslandRockStepCount(void)
} }
} }
// called before fade-in
void SetDeoxysRockPalette(void) void SetDeoxysRockPalette(void)
{ {
LoadPalette(&sDeoxysRockPalettes[(u8)VarGet(VAR_DEOXYS_ROCK_LEVEL)], OBJ_PLTT_ID(ROCK_PAL_ID), PLTT_SIZEOF(4)); u32 paletteNum = IndexOfSpritePaletteTag(OBJ_EVENT_PAL_TAG_BIRTH_ISLAND_STONE);
BlendPalettes(1 << (ROCK_PAL_ID + 16), 16, 0); LoadPalette(&sDeoxysRockPalettes[(u8)VarGet(VAR_DEOXYS_ROCK_LEVEL)], OBJ_PLTT_ID(paletteNum), PLTT_SIZEOF(4));
// Set faded to all black, weather blending handled during fade-in
CpuFill16(0, &gPlttBufferFaded[OBJ_PLTT_ID(paletteNum)], 32);
} }
void SetPCBoxToSendMon(u8 boxId) void SetPCBoxToSendMon(u8 boxId)