2018-10-09 23:32:39 +02:00
|
|
|
#include "global.h"
|
|
|
|
#include "event_object_movement.h"
|
|
|
|
#include "field_camera.h"
|
|
|
|
#include "field_effect.h"
|
|
|
|
#include "field_effect_helpers.h"
|
2018-10-15 00:43:40 +02:00
|
|
|
#include "field_weather.h"
|
|
|
|
#include "fieldmap.h"
|
2018-10-10 18:02:02 +02:00
|
|
|
#include "gpu_regs.h"
|
2018-10-15 00:43:40 +02:00
|
|
|
#include "metatile_behavior.h"
|
|
|
|
#include "sound.h"
|
|
|
|
#include "sprite.h"
|
2018-10-10 18:02:02 +02:00
|
|
|
#include "trig.h"
|
2018-11-13 15:19:04 +01:00
|
|
|
#include "constants/field_effects.h"
|
2018-10-15 00:43:40 +02:00
|
|
|
#include "constants/songs.h"
|
|
|
|
|
2019-11-21 05:12:51 +01:00
|
|
|
#define OBJ_EVENT_PAL_TAG_NONE 0x11FF // duplicate of define in event_object_movement.c
|
2018-10-09 23:32:39 +02:00
|
|
|
|
2018-10-16 15:55:16 +02:00
|
|
|
static void UpdateObjectReflectionSprite(struct Sprite *);
|
2019-11-21 04:55:44 +01:00
|
|
|
static void LoadObjectReflectionPalette(struct ObjectEvent *objectEvent, struct Sprite *sprite);
|
|
|
|
static void LoadObjectHighBridgeReflectionPalette(struct ObjectEvent *, u8);
|
|
|
|
static void LoadObjectRegularReflectionPalette(struct ObjectEvent *, u8);
|
2018-10-16 15:55:16 +02:00
|
|
|
static void sub_81561FC(struct Sprite *, u8, u8);
|
|
|
|
static void FadeFootprintsTireTracks_Step0(struct Sprite *);
|
|
|
|
static void FadeFootprintsTireTracks_Step1(struct Sprite *);
|
|
|
|
static void UpdateFeetInFlowingWaterFieldEffect(struct Sprite *);
|
|
|
|
static void UpdateAshFieldEffect_Step0(struct Sprite *);
|
|
|
|
static void UpdateAshFieldEffect_Step1(struct Sprite *);
|
|
|
|
static void UpdateAshFieldEffect_Step2(struct Sprite *);
|
2019-11-21 04:55:44 +01:00
|
|
|
static void SynchroniseSurfAnim(struct ObjectEvent *, struct Sprite *);
|
|
|
|
static void sub_81556E8(struct ObjectEvent *, struct Sprite *);
|
|
|
|
static void CreateBobbingEffect(struct ObjectEvent *, struct Sprite *, struct Sprite *);
|
2018-10-16 15:55:16 +02:00
|
|
|
static void sub_8155850(struct Sprite *);
|
|
|
|
static u32 ShowDisguiseFieldEffect(u8, u8, u8);
|
2018-10-09 23:32:39 +02:00
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
void SetUpReflection(struct ObjectEvent *objectEvent, struct Sprite *sprite, bool8 stillReflection)
|
2018-10-09 23:32:39 +02:00
|
|
|
{
|
|
|
|
struct Sprite *reflectionSprite;
|
|
|
|
|
|
|
|
reflectionSprite = &gSprites[CreateCopySpriteAt(sprite, sprite->pos1.x, sprite->pos1.y, 0x98)];
|
2018-10-15 00:43:40 +02:00
|
|
|
reflectionSprite->callback = UpdateObjectReflectionSprite;
|
2018-10-09 23:32:39 +02:00
|
|
|
reflectionSprite->oam.priority = 3;
|
|
|
|
reflectionSprite->oam.paletteNum = gReflectionEffectPaletteMap[reflectionSprite->oam.paletteNum];
|
|
|
|
reflectionSprite->usingSheet = TRUE;
|
|
|
|
reflectionSprite->anims = gDummySpriteAnimTable;
|
|
|
|
StartSpriteAnim(reflectionSprite, 0);
|
|
|
|
reflectionSprite->affineAnims = gDummySpriteAffineAnimTable;
|
|
|
|
reflectionSprite->affineAnimBeginning = TRUE;
|
|
|
|
reflectionSprite->subspriteMode = SUBSPRITES_OFF;
|
|
|
|
reflectionSprite->data[0] = sprite->data[0];
|
2019-11-21 04:55:44 +01:00
|
|
|
reflectionSprite->data[1] = objectEvent->localId;
|
2018-10-09 23:32:39 +02:00
|
|
|
reflectionSprite->data[7] = stillReflection;
|
2019-11-21 04:55:44 +01:00
|
|
|
LoadObjectReflectionPalette(objectEvent, reflectionSprite);
|
2018-10-09 23:32:39 +02:00
|
|
|
|
|
|
|
if (!stillReflection)
|
|
|
|
reflectionSprite->oam.affineMode = ST_OAM_AFFINE_NORMAL;
|
|
|
|
}
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
static s16 GetReflectionVerticalOffset(struct ObjectEvent *objectEvent)
|
2018-10-09 23:32:39 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
return GetObjectEventGraphicsInfo(objectEvent->graphicsId)->height - 2;
|
2018-10-09 23:32:39 +02:00
|
|
|
}
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
static void LoadObjectReflectionPalette(struct ObjectEvent *objectEvent, struct Sprite *sprite)
|
2018-10-09 23:32:39 +02:00
|
|
|
{
|
|
|
|
u8 bridgeType;
|
|
|
|
u16 bridgeReflectionVerticalOffsets[] = { 12, 28, 44 };
|
|
|
|
sprite->data[2] = 0;
|
2019-11-21 04:55:44 +01:00
|
|
|
if (!GetObjectEventGraphicsInfo(objectEvent->graphicsId)->disableReflectionPaletteLoad && ((bridgeType = MetatileBehavior_GetBridgeType(objectEvent->previousMetatileBehavior)) || (bridgeType = MetatileBehavior_GetBridgeType(objectEvent->currentMetatileBehavior))))
|
2018-10-09 23:32:39 +02:00
|
|
|
{
|
|
|
|
sprite->data[2] = bridgeReflectionVerticalOffsets[bridgeType - 1];
|
2019-11-21 04:55:44 +01:00
|
|
|
LoadObjectHighBridgeReflectionPalette(objectEvent, sprite->oam.paletteNum);
|
2018-10-09 23:32:39 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
LoadObjectRegularReflectionPalette(objectEvent, sprite->oam.paletteNum);
|
2018-10-09 23:32:39 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
static void LoadObjectRegularReflectionPalette(struct ObjectEvent *objectEvent, u8 paletteIndex)
|
2018-10-09 23:32:39 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
const struct ObjectEventGraphicsInfo *graphicsInfo;
|
2018-10-09 23:32:39 +02:00
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
graphicsInfo = GetObjectEventGraphicsInfo(objectEvent->graphicsId);
|
2019-11-21 05:12:51 +01:00
|
|
|
if (graphicsInfo->paletteTag2 != OBJ_EVENT_PAL_TAG_NONE)
|
2018-10-09 23:32:39 +02:00
|
|
|
{
|
|
|
|
if (graphicsInfo->paletteSlot == 0)
|
|
|
|
{
|
|
|
|
LoadPlayerObjectReflectionPalette(graphicsInfo->paletteTag1, paletteIndex);
|
|
|
|
}
|
|
|
|
else if (graphicsInfo->paletteSlot == 10)
|
|
|
|
{
|
|
|
|
LoadSpecialObjectReflectionPalette(graphicsInfo->paletteTag1, paletteIndex);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PatchObjectPalette(GetObjectPaletteTag(paletteIndex), paletteIndex);
|
|
|
|
}
|
|
|
|
UpdateSpritePaletteWithWeather(paletteIndex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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.
|
2019-11-21 04:55:44 +01:00
|
|
|
static void LoadObjectHighBridgeReflectionPalette(struct ObjectEvent *objectEvent, u8 paletteNum)
|
2018-10-09 23:32:39 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
const struct ObjectEventGraphicsInfo *graphicsInfo;
|
2018-10-09 23:32:39 +02:00
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
graphicsInfo = GetObjectEventGraphicsInfo(objectEvent->graphicsId);
|
2019-11-21 05:12:51 +01:00
|
|
|
if (graphicsInfo->paletteTag2 != OBJ_EVENT_PAL_TAG_NONE)
|
2018-10-09 23:32:39 +02:00
|
|
|
{
|
|
|
|
PatchObjectPalette(graphicsInfo->paletteTag2, paletteNum);
|
|
|
|
UpdateSpritePaletteWithWeather(paletteNum);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-16 15:55:16 +02:00
|
|
|
static void UpdateObjectReflectionSprite(struct Sprite *reflectionSprite)
|
2018-10-09 23:32:39 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *objectEvent;
|
2018-10-09 23:32:39 +02:00
|
|
|
struct Sprite *mainSprite;
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
objectEvent = &gObjectEvents[reflectionSprite->data[0]];
|
|
|
|
mainSprite = &gSprites[objectEvent->spriteId];
|
|
|
|
if (!objectEvent->active || !objectEvent->hasReflection || objectEvent->localId != reflectionSprite->data[1])
|
2018-10-09 23:32:39 +02:00
|
|
|
{
|
|
|
|
reflectionSprite->inUse = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
reflectionSprite->oam.paletteNum = gReflectionEffectPaletteMap[mainSprite->oam.paletteNum];
|
|
|
|
reflectionSprite->oam.shape = mainSprite->oam.shape;
|
|
|
|
reflectionSprite->oam.size = mainSprite->oam.size;
|
2019-12-05 03:00:45 +01:00
|
|
|
reflectionSprite->oam.matrixNum = mainSprite->oam.matrixNum | ST_OAM_VFLIP;
|
2018-10-09 23:32:39 +02:00
|
|
|
reflectionSprite->oam.tileNum = mainSprite->oam.tileNum;
|
|
|
|
reflectionSprite->subspriteTables = mainSprite->subspriteTables;
|
|
|
|
reflectionSprite->subspriteTableNum = mainSprite->subspriteTableNum;
|
|
|
|
reflectionSprite->invisible = mainSprite->invisible;
|
|
|
|
reflectionSprite->pos1.x = mainSprite->pos1.x;
|
|
|
|
// reflectionSprite->data[2] holds an additional vertical offset, used by the high bridges on Route 120
|
2019-11-21 04:55:44 +01:00
|
|
|
reflectionSprite->pos1.y = mainSprite->pos1.y + GetReflectionVerticalOffset(objectEvent) + reflectionSprite->data[2];
|
2018-10-09 23:32:39 +02:00
|
|
|
reflectionSprite->centerToCornerVecX = mainSprite->centerToCornerVecX;
|
|
|
|
reflectionSprite->centerToCornerVecY = mainSprite->centerToCornerVecY;
|
|
|
|
reflectionSprite->pos2.x = mainSprite->pos2.x;
|
|
|
|
reflectionSprite->pos2.y = -mainSprite->pos2.y;
|
|
|
|
reflectionSprite->coordOffsetEnabled = mainSprite->coordOffsetEnabled;
|
2018-11-25 20:16:41 +01:00
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
if (objectEvent->hideReflection == TRUE)
|
2018-10-09 23:32:39 +02:00
|
|
|
reflectionSprite->invisible = TRUE;
|
|
|
|
|
|
|
|
// Check if the reflection is not still.
|
|
|
|
if (reflectionSprite->data[7] == FALSE)
|
|
|
|
{
|
|
|
|
// Sets the reflection sprite's rot/scale matrix to the appropriate
|
|
|
|
// matrix based on whether or not the main sprite is horizontally flipped.
|
|
|
|
// If the sprite is facing to the east, then it is flipped, and its matrixNum is 8.
|
|
|
|
reflectionSprite->oam.matrixNum = 0;
|
2019-12-05 03:00:45 +01:00
|
|
|
if (mainSprite->oam.matrixNum & ST_OAM_HFLIP)
|
2018-10-09 23:32:39 +02:00
|
|
|
reflectionSprite->oam.matrixNum = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extern const struct SpriteTemplate *const gFieldEffectObjectTemplatePointers[];
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
u8 CreateWarpArrowSprite(void)
|
2018-10-09 23:32:39 +02:00
|
|
|
{
|
|
|
|
u8 spriteId;
|
|
|
|
struct Sprite *sprite;
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[FLDEFFOBJ_ARROW], 0, 0, 0x52);
|
2018-10-09 23:32:39 +02:00
|
|
|
if (spriteId != MAX_SPRITES)
|
|
|
|
{
|
|
|
|
sprite = &gSprites[spriteId];
|
|
|
|
sprite->oam.priority = 1;
|
|
|
|
sprite->coordOffsetEnabled = TRUE;
|
|
|
|
sprite->invisible = TRUE;
|
|
|
|
}
|
|
|
|
return spriteId;
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
void SetSpriteInvisible(u8 spriteId)
|
2018-10-09 23:32:39 +02:00
|
|
|
{
|
|
|
|
gSprites[spriteId].invisible = TRUE;
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
void ShowWarpArrowSprite(u8 spriteId, u8 direction, s16 x, s16 y)
|
2018-10-09 23:32:39 +02:00
|
|
|
{
|
|
|
|
s16 x2;
|
|
|
|
s16 y2;
|
|
|
|
struct Sprite *sprite;
|
|
|
|
|
|
|
|
sprite = &gSprites[spriteId];
|
|
|
|
if (sprite->invisible || sprite->data[0] != x || sprite->data[1] != y)
|
|
|
|
{
|
2019-04-02 03:04:23 +02:00
|
|
|
SetSpritePosToMapCoords(x, y, &x2, &y2);
|
2018-10-09 23:32:39 +02:00
|
|
|
sprite = &gSprites[spriteId];
|
|
|
|
sprite->pos1.x = x2 + 8;
|
|
|
|
sprite->pos1.y = y2 + 8;
|
|
|
|
sprite->invisible = FALSE;
|
|
|
|
sprite->data[0] = x;
|
|
|
|
sprite->data[1] = y;
|
|
|
|
StartSpriteAnim(sprite, direction - 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
static const u8 sShadowEffectTemplateIds[] = {
|
|
|
|
FLDEFFOBJ_SHADOW_S,
|
|
|
|
FLDEFFOBJ_SHADOW_M,
|
|
|
|
FLDEFFOBJ_SHADOW_L,
|
|
|
|
FLDEFFOBJ_SHADOW_XL
|
2018-10-09 23:32:39 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
const u16 gShadowVerticalOffsets[] = {
|
|
|
|
4,
|
|
|
|
4,
|
|
|
|
4,
|
|
|
|
16
|
|
|
|
};
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
u32 FldEff_Shadow(void)
|
2018-10-09 23:32:39 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
u8 objectEventId;
|
|
|
|
const struct ObjectEventGraphicsInfo *graphicsInfo;
|
2018-10-09 23:32:39 +02:00
|
|
|
u8 spriteId;
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
objectEventId = GetObjectEventIdByLocalIdAndMap(gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
|
|
|
|
graphicsInfo = GetObjectEventGraphicsInfo(gObjectEvents[objectEventId].graphicsId);
|
2020-06-20 01:58:56 +02:00
|
|
|
spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[sShadowEffectTemplateIds[graphicsInfo->shadowSize]], 0, 0, 0x94);
|
2018-10-09 23:32:39 +02:00
|
|
|
if (spriteId != MAX_SPRITES)
|
|
|
|
{
|
|
|
|
gSprites[spriteId].coordOffsetEnabled = TRUE;
|
|
|
|
gSprites[spriteId].data[0] = gFieldEffectArguments[0];
|
|
|
|
gSprites[spriteId].data[1] = gFieldEffectArguments[1];
|
|
|
|
gSprites[spriteId].data[2] = gFieldEffectArguments[2];
|
|
|
|
gSprites[spriteId].data[3] = (graphicsInfo->height >> 1) - gShadowVerticalOffsets[graphicsInfo->shadowSize];
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
void UpdateShadowFieldEffect(struct Sprite *sprite)
|
2018-10-09 23:32:39 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
u8 objectEventId;
|
|
|
|
struct ObjectEvent *objectEvent;
|
2018-10-09 23:32:39 +02:00
|
|
|
struct Sprite *linkedSprite;
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
if (TryGetObjectEventIdByLocalIdAndMap(sprite->data[0], sprite->data[1], sprite->data[2], &objectEventId))
|
2018-10-09 23:32:39 +02:00
|
|
|
{
|
|
|
|
FieldEffectStop(sprite, FLDEFF_SHADOW);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
objectEvent = &gObjectEvents[objectEventId];
|
|
|
|
linkedSprite = &gSprites[objectEvent->spriteId];
|
2018-10-09 23:32:39 +02:00
|
|
|
sprite->oam.priority = linkedSprite->oam.priority;
|
|
|
|
sprite->pos1.x = linkedSprite->pos1.x;
|
|
|
|
sprite->pos1.y = linkedSprite->pos1.y + sprite->data[3];
|
2019-11-21 04:55:44 +01:00
|
|
|
if (!objectEvent->active || !objectEvent->hasShadow
|
|
|
|
|| MetatileBehavior_IsPokeGrass(objectEvent->currentMetatileBehavior)
|
|
|
|
|| MetatileBehavior_IsSurfableWaterOrUnderwater(objectEvent->currentMetatileBehavior)
|
|
|
|
|| MetatileBehavior_IsSurfableWaterOrUnderwater(objectEvent->previousMetatileBehavior)
|
|
|
|
|| MetatileBehavior_IsReflective(objectEvent->currentMetatileBehavior)
|
|
|
|
|| MetatileBehavior_IsReflective(objectEvent->previousMetatileBehavior))
|
2018-10-09 23:32:39 +02:00
|
|
|
{
|
|
|
|
FieldEffectStop(sprite, FLDEFF_SHADOW);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
u32 FldEff_TallGrass(void)
|
2018-10-09 23:32:39 +02:00
|
|
|
{
|
|
|
|
s16 x;
|
|
|
|
s16 y;
|
|
|
|
u8 spriteId;
|
|
|
|
struct Sprite *sprite;
|
|
|
|
|
|
|
|
x = gFieldEffectArguments[0];
|
|
|
|
y = gFieldEffectArguments[1];
|
|
|
|
sub_80930E0(&x, &y, 8, 8);
|
2020-06-20 01:58:56 +02:00
|
|
|
spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[FLDEFFOBJ_TALL_GRASS], x, y, 0);
|
2018-10-09 23:32:39 +02:00
|
|
|
if (spriteId != MAX_SPRITES)
|
|
|
|
{
|
|
|
|
sprite = &gSprites[spriteId];
|
|
|
|
sprite->coordOffsetEnabled = TRUE;
|
|
|
|
sprite->oam.priority = gFieldEffectArguments[3];
|
|
|
|
sprite->data[0] = gFieldEffectArguments[2];
|
|
|
|
sprite->data[1] = gFieldEffectArguments[0];
|
|
|
|
sprite->data[2] = gFieldEffectArguments[1];
|
|
|
|
sprite->data[3] = gFieldEffectArguments[4];
|
|
|
|
sprite->data[4] = gFieldEffectArguments[5];
|
|
|
|
sprite->data[5] = gFieldEffectArguments[6];
|
|
|
|
if (gFieldEffectArguments[7])
|
|
|
|
{
|
|
|
|
SeekSpriteAnim(sprite, 4);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
void UpdateTallGrassFieldEffect(struct Sprite *sprite)
|
2018-10-09 23:32:39 +02:00
|
|
|
{
|
|
|
|
u8 mapNum;
|
|
|
|
u8 mapGroup;
|
|
|
|
u8 metatileBehavior;
|
|
|
|
u8 localId;
|
2019-11-21 04:55:44 +01:00
|
|
|
u8 objectEventId;
|
|
|
|
struct ObjectEvent *objectEvent;
|
2018-10-09 23:32:39 +02:00
|
|
|
|
|
|
|
mapNum = sprite->data[5] >> 8;
|
|
|
|
mapGroup = sprite->data[5];
|
|
|
|
if (gCamera.active && (gSaveBlock1Ptr->location.mapNum != mapNum || gSaveBlock1Ptr->location.mapGroup != mapGroup))
|
|
|
|
{
|
|
|
|
sprite->data[1] -= gCamera.x;
|
|
|
|
sprite->data[2] -= gCamera.y;
|
|
|
|
sprite->data[5] = ((u8)gSaveBlock1Ptr->location.mapNum << 8) | (u8)gSaveBlock1Ptr->location.mapGroup;
|
|
|
|
}
|
|
|
|
localId = sprite->data[3] >> 8;
|
|
|
|
mapNum = sprite->data[3];
|
|
|
|
mapGroup = sprite->data[4];
|
|
|
|
metatileBehavior = MapGridGetMetatileBehaviorAt(sprite->data[1], sprite->data[2]);
|
2019-11-21 04:55:44 +01:00
|
|
|
if (TryGetObjectEventIdByLocalIdAndMap(localId, mapNum, mapGroup, &objectEventId) || !MetatileBehavior_IsTallGrass(metatileBehavior) || (sprite->data[7] && sprite->animEnded))
|
2018-10-09 23:32:39 +02:00
|
|
|
{
|
|
|
|
FieldEffectStop(sprite, FLDEFF_TALL_GRASS);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
objectEvent = &gObjectEvents[objectEventId];
|
|
|
|
if ((objectEvent->currentCoords.x != sprite->data[1] || objectEvent->currentCoords.y != sprite->data[2]) && (objectEvent->previousCoords.x != sprite->data[1] || objectEvent->previousCoords.y != sprite->data[2]))
|
2018-10-09 23:32:39 +02:00
|
|
|
sprite->data[7] = TRUE;
|
|
|
|
|
|
|
|
metatileBehavior = 0;
|
|
|
|
if (sprite->animCmdIndex == 0)
|
|
|
|
metatileBehavior = 4;
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
UpdateObjectEventSpriteVisibility(sprite, 0);
|
2018-10-09 23:32:39 +02:00
|
|
|
sub_81561FC(sprite, sprite->data[0], metatileBehavior);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
u32 FldEff_JumpTallGrass(void)
|
2018-10-09 23:32:39 +02:00
|
|
|
{
|
|
|
|
u8 spriteId;
|
|
|
|
struct Sprite *sprite;
|
|
|
|
|
|
|
|
sub_80930E0((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 12);
|
2020-06-20 01:58:56 +02:00
|
|
|
spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[FLDEFFOBJ_JUMP_TALL_GRASS], gFieldEffectArguments[0], gFieldEffectArguments[1], 0);
|
2018-10-09 23:32:39 +02:00
|
|
|
if (spriteId != MAX_SPRITES)
|
|
|
|
{
|
|
|
|
sprite = &gSprites[spriteId];
|
|
|
|
sprite->coordOffsetEnabled = TRUE;
|
|
|
|
sprite->oam.priority = gFieldEffectArguments[3];
|
|
|
|
sprite->data[0] = gFieldEffectArguments[2];
|
|
|
|
sprite->data[1] = 12;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
u8 FindTallGrassFieldEffectSpriteId(u8 localId, u8 mapNum, u8 mapGroup, s16 x, s16 y)
|
2018-10-09 23:32:39 +02:00
|
|
|
{
|
|
|
|
struct Sprite *sprite;
|
|
|
|
u8 i;
|
|
|
|
|
|
|
|
for (i = 0; i < MAX_SPRITES; i ++)
|
|
|
|
{
|
|
|
|
if (gSprites[i].inUse)
|
|
|
|
{
|
|
|
|
sprite = &gSprites[i];
|
2018-10-15 00:43:40 +02:00
|
|
|
if (sprite->callback == UpdateTallGrassFieldEffect && (x == sprite->data[1] && y == sprite->data[2]) && (localId == (u8)(sprite->data[3] >> 8) && mapNum == (sprite->data[3] & 0xFF) && mapGroup == sprite->data[4]))
|
2018-10-09 23:32:39 +02:00
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return MAX_SPRITES;
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
u32 FldEff_LongGrass(void)
|
2018-10-09 23:32:39 +02:00
|
|
|
{
|
|
|
|
s16 x;
|
|
|
|
s16 y;
|
|
|
|
u8 spriteId;
|
|
|
|
struct Sprite *sprite;
|
|
|
|
|
|
|
|
x = gFieldEffectArguments[0];
|
|
|
|
y = gFieldEffectArguments[1];
|
|
|
|
sub_80930E0(&x, &y, 8, 8);
|
2020-06-20 01:58:56 +02:00
|
|
|
spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[FLDEFFOBJ_LONG_GRASS], x, y, 0);
|
2018-10-09 23:32:39 +02:00
|
|
|
if (spriteId != MAX_SPRITES)
|
|
|
|
{
|
|
|
|
sprite = &gSprites[spriteId];
|
|
|
|
sprite->coordOffsetEnabled = TRUE;
|
|
|
|
sprite->oam.priority = ZCoordToPriority(gFieldEffectArguments[2]);
|
|
|
|
sprite->data[0] = gFieldEffectArguments[2];
|
|
|
|
sprite->data[1] = gFieldEffectArguments[0];
|
|
|
|
sprite->data[2] = gFieldEffectArguments[1];
|
|
|
|
sprite->data[3] = gFieldEffectArguments[4];
|
|
|
|
sprite->data[4] = gFieldEffectArguments[5];
|
|
|
|
sprite->data[5] = gFieldEffectArguments[6];
|
|
|
|
if (gFieldEffectArguments[7])
|
|
|
|
{
|
|
|
|
SeekSpriteAnim(sprite, 6);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
void UpdateLongGrassFieldEffect(struct Sprite *sprite)
|
2018-10-09 23:32:39 +02:00
|
|
|
{
|
|
|
|
u8 mapNum;
|
|
|
|
u8 mapGroup;
|
|
|
|
u8 metatileBehavior;
|
|
|
|
u8 localId;
|
2019-11-21 04:55:44 +01:00
|
|
|
u8 objectEventId;
|
|
|
|
struct ObjectEvent *objectEvent;
|
2018-10-09 23:32:39 +02:00
|
|
|
|
|
|
|
mapNum = sprite->data[5] >> 8;
|
|
|
|
mapGroup = sprite->data[5];
|
|
|
|
if (gCamera.active && (gSaveBlock1Ptr->location.mapNum != mapNum || gSaveBlock1Ptr->location.mapGroup != mapGroup))
|
|
|
|
{
|
|
|
|
sprite->data[1] -= gCamera.x;
|
|
|
|
sprite->data[2] -= gCamera.y;
|
|
|
|
sprite->data[5] = ((u8)gSaveBlock1Ptr->location.mapNum << 8) | (u8)gSaveBlock1Ptr->location.mapGroup;
|
|
|
|
}
|
|
|
|
localId = sprite->data[3] >> 8;
|
|
|
|
mapNum = sprite->data[3];
|
|
|
|
mapGroup = sprite->data[4];
|
|
|
|
metatileBehavior = MapGridGetMetatileBehaviorAt(sprite->data[1], sprite->data[2]);
|
2019-11-21 04:55:44 +01:00
|
|
|
if (TryGetObjectEventIdByLocalIdAndMap(localId, mapNum, mapGroup, &objectEventId) || !MetatileBehavior_IsLongGrass(metatileBehavior) || (sprite->data[7] && sprite->animEnded))
|
2018-10-09 23:32:39 +02:00
|
|
|
{
|
|
|
|
FieldEffectStop(sprite, FLDEFF_LONG_GRASS);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
objectEvent = &gObjectEvents[objectEventId];
|
|
|
|
if ((objectEvent->currentCoords.x != sprite->data[1] || objectEvent->currentCoords.y != sprite->data[2]) && (objectEvent->previousCoords.x != sprite->data[1] || objectEvent->previousCoords.y != sprite->data[2]))
|
2018-10-09 23:32:39 +02:00
|
|
|
{
|
|
|
|
sprite->data[7] = TRUE;
|
|
|
|
}
|
2019-11-21 04:55:44 +01:00
|
|
|
UpdateObjectEventSpriteVisibility(sprite, 0);
|
2018-10-09 23:32:39 +02:00
|
|
|
sub_81561FC(sprite, sprite->data[0], 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
u32 FldEff_JumpLongGrass(void)
|
2018-10-09 23:32:39 +02:00
|
|
|
{
|
|
|
|
u8 spriteId;
|
|
|
|
struct Sprite *sprite;
|
|
|
|
|
|
|
|
sub_80930E0((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 8);
|
2020-06-20 01:58:56 +02:00
|
|
|
spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[FLDEFFOBJ_JUMP_LONG_GRASS], gFieldEffectArguments[0], gFieldEffectArguments[1], 0);
|
2018-10-09 23:32:39 +02:00
|
|
|
if (spriteId != MAX_SPRITES)
|
|
|
|
{
|
|
|
|
sprite = &gSprites[spriteId];
|
|
|
|
sprite->coordOffsetEnabled = TRUE;
|
|
|
|
sprite->oam.priority = gFieldEffectArguments[3];
|
|
|
|
sprite->data[0] = gFieldEffectArguments[2];
|
|
|
|
sprite->data[1] = 18;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
u32 FldEff_ShortGrass(void)
|
2018-10-09 23:32:39 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
u8 objectEventId;
|
|
|
|
struct ObjectEvent *objectEvent;
|
2018-10-09 23:32:39 +02:00
|
|
|
u8 spriteId;
|
|
|
|
struct Sprite *sprite;
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
objectEventId = GetObjectEventIdByLocalIdAndMap(gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
|
|
|
|
objectEvent = &gObjectEvents[objectEventId];
|
2020-06-20 01:58:56 +02:00
|
|
|
spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[FLDEFFOBJ_SHORT_GRASS], 0, 0, 0);
|
2018-10-09 23:32:39 +02:00
|
|
|
if (spriteId != MAX_SPRITES)
|
|
|
|
{
|
|
|
|
sprite = &(gSprites[spriteId]);
|
|
|
|
sprite->coordOffsetEnabled = TRUE;
|
2019-11-21 04:55:44 +01:00
|
|
|
sprite->oam.priority = gSprites[objectEvent->spriteId].oam.priority;
|
2018-10-09 23:32:39 +02:00
|
|
|
sprite->data[0] = gFieldEffectArguments[0];
|
|
|
|
sprite->data[1] = gFieldEffectArguments[1];
|
|
|
|
sprite->data[2] = gFieldEffectArguments[2];
|
2019-11-21 04:55:44 +01:00
|
|
|
sprite->data[3] = gSprites[objectEvent->spriteId].pos1.x;
|
|
|
|
sprite->data[4] = gSprites[objectEvent->spriteId].pos1.y;
|
2018-10-09 23:32:39 +02:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
void UpdateShortGrassFieldEffect(struct Sprite *sprite)
|
2018-10-09 23:32:39 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
u8 objectEventId;
|
2018-10-09 23:32:39 +02:00
|
|
|
s16 x;
|
|
|
|
s16 y;
|
2019-11-21 04:55:44 +01:00
|
|
|
const struct ObjectEventGraphicsInfo *graphicsInfo;
|
2018-10-09 23:32:39 +02:00
|
|
|
struct Sprite *linkedSprite;
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
if (TryGetObjectEventIdByLocalIdAndMap(sprite->data[0], sprite->data[1], sprite->data[2], &objectEventId) || !gObjectEvents[objectEventId].inShortGrass)
|
2018-10-09 23:32:39 +02:00
|
|
|
{
|
|
|
|
FieldEffectStop(sprite, FLDEFF_SHORT_GRASS);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
graphicsInfo = GetObjectEventGraphicsInfo(gObjectEvents[objectEventId].graphicsId);
|
|
|
|
linkedSprite = &gSprites[gObjectEvents[objectEventId].spriteId];
|
2018-10-09 23:32:39 +02:00
|
|
|
y = linkedSprite->pos1.y;
|
|
|
|
x = linkedSprite->pos1.x;
|
|
|
|
if (x != sprite->data[3] || y != sprite->data[4])
|
|
|
|
{
|
|
|
|
sprite->data[3] = x;
|
|
|
|
sprite->data[4] = y;
|
|
|
|
if (sprite->animEnded)
|
|
|
|
{
|
|
|
|
StartSpriteAnim(sprite, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
sprite->pos1.x = x;
|
|
|
|
sprite->pos1.y = y;
|
|
|
|
sprite->pos2.y = (graphicsInfo->height >> 1) - 8;
|
|
|
|
sprite->subpriority = linkedSprite->subpriority - 1;
|
|
|
|
sprite->oam.priority = linkedSprite->oam.priority;
|
2019-11-21 04:55:44 +01:00
|
|
|
UpdateObjectEventSpriteVisibility(sprite, linkedSprite->invisible);
|
2018-10-09 23:32:39 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
u32 FldEff_SandFootprints(void)
|
2018-10-09 23:32:39 +02:00
|
|
|
{
|
|
|
|
u8 spriteId;
|
|
|
|
struct Sprite *sprite;
|
|
|
|
|
|
|
|
sub_80930E0((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 8);
|
2020-06-20 01:58:56 +02:00
|
|
|
spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[FLDEFFOBJ_SAND_FOOTPRINTS], gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
|
2018-10-09 23:32:39 +02:00
|
|
|
if (spriteId != MAX_SPRITES)
|
|
|
|
{
|
|
|
|
sprite = &gSprites[spriteId];
|
|
|
|
sprite->coordOffsetEnabled = TRUE;
|
|
|
|
sprite->oam.priority = gFieldEffectArguments[3];
|
|
|
|
sprite->data[7] = FLDEFF_SAND_FOOTPRINTS;
|
|
|
|
StartSpriteAnim(sprite, gFieldEffectArguments[4]);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
u32 FldEff_DeepSandFootprints(void)
|
2018-10-09 23:32:39 +02:00
|
|
|
{
|
|
|
|
u8 spriteId;
|
|
|
|
struct Sprite *sprite;
|
|
|
|
|
|
|
|
sub_80930E0((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 8);
|
2020-06-20 01:58:56 +02:00
|
|
|
spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[FLDEFFOBJ_DEEP_SAND_FOOTPRINTS], gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
|
2018-10-09 23:32:39 +02:00
|
|
|
if (spriteId != MAX_SPRITES)
|
|
|
|
{
|
|
|
|
sprite = &gSprites[spriteId];
|
|
|
|
sprite->coordOffsetEnabled = TRUE;
|
|
|
|
sprite->oam.priority = gFieldEffectArguments[3];
|
|
|
|
sprite->data[7] = FLDEFF_DEEP_SAND_FOOTPRINTS;
|
|
|
|
StartSpriteAnim(sprite, gFieldEffectArguments[4]);
|
|
|
|
}
|
|
|
|
return spriteId;
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
u32 FldEff_BikeTireTracks(void)
|
2018-10-09 23:32:39 +02:00
|
|
|
{
|
|
|
|
u8 spriteId;
|
|
|
|
struct Sprite *sprite;
|
|
|
|
|
|
|
|
sub_80930E0((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 8);
|
2020-06-20 01:58:56 +02:00
|
|
|
spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[FLDEFFOBJ_BIKE_TIRE_TRACKS], gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
|
2018-10-09 23:32:39 +02:00
|
|
|
if (spriteId != MAX_SPRITES)
|
|
|
|
{
|
|
|
|
sprite = &gSprites[spriteId];
|
|
|
|
sprite->coordOffsetEnabled = TRUE;
|
|
|
|
sprite->oam.priority = gFieldEffectArguments[3];
|
|
|
|
sprite->data[7] = FLDEFF_BIKE_TIRE_TRACKS;
|
|
|
|
StartSpriteAnim(sprite, gFieldEffectArguments[4]);
|
|
|
|
}
|
|
|
|
return spriteId;
|
|
|
|
}
|
2018-10-10 18:02:02 +02:00
|
|
|
|
|
|
|
void (*const gFadeFootprintsTireTracksFuncs[])(struct Sprite *) = {
|
2018-10-15 00:43:40 +02:00
|
|
|
FadeFootprintsTireTracks_Step0,
|
|
|
|
FadeFootprintsTireTracks_Step1
|
2018-10-10 18:02:02 +02:00
|
|
|
};
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
void UpdateFootprintsTireTracksFieldEffect(struct Sprite *sprite)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
gFadeFootprintsTireTracksFuncs[sprite->data[0]](sprite);
|
|
|
|
}
|
|
|
|
|
2018-10-16 15:55:16 +02:00
|
|
|
static void FadeFootprintsTireTracks_Step0(struct Sprite *sprite)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
// Wait 40 frames before the flickering starts.
|
|
|
|
if (++sprite->data[1] > 40)
|
|
|
|
sprite->data[0] = 1;
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
UpdateObjectEventSpriteVisibility(sprite, FALSE);
|
2018-10-10 18:02:02 +02:00
|
|
|
}
|
|
|
|
|
2018-10-16 15:55:16 +02:00
|
|
|
static void FadeFootprintsTireTracks_Step1(struct Sprite *sprite)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
sprite->invisible ^= 1;
|
|
|
|
sprite->data[1]++;
|
2019-11-21 04:55:44 +01:00
|
|
|
UpdateObjectEventSpriteVisibility(sprite, sprite->invisible);
|
2018-10-10 18:02:02 +02:00
|
|
|
if (sprite->data[1] > 56)
|
|
|
|
{
|
|
|
|
FieldEffectStop(sprite, sprite->data[7]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
u32 FldEff_Splash(void)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
u8 objectEventId;
|
|
|
|
struct ObjectEvent *objectEvent;
|
2018-10-10 18:02:02 +02:00
|
|
|
u8 spriteId;
|
|
|
|
struct Sprite *sprite;
|
2019-11-21 04:55:44 +01:00
|
|
|
const struct ObjectEventGraphicsInfo *graphicsInfo;
|
2018-10-10 18:02:02 +02:00
|
|
|
struct Sprite *linkedSprite;
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
objectEventId = GetObjectEventIdByLocalIdAndMap(gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
|
|
|
|
objectEvent = &gObjectEvents[objectEventId];
|
2020-06-20 01:58:56 +02:00
|
|
|
spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[FLDEFFOBJ_SPLASH], 0, 0, 0);
|
2018-10-10 18:02:02 +02:00
|
|
|
if (spriteId != MAX_SPRITES)
|
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
graphicsInfo = GetObjectEventGraphicsInfo(objectEvent->graphicsId);
|
2018-10-10 18:02:02 +02:00
|
|
|
sprite = &gSprites[spriteId];
|
|
|
|
sprite->coordOffsetEnabled = TRUE;
|
2019-11-21 04:55:44 +01:00
|
|
|
linkedSprite = &gSprites[objectEvent->spriteId];
|
2018-10-10 18:02:02 +02:00
|
|
|
sprite->oam.priority = linkedSprite->oam.priority;
|
|
|
|
sprite->data[0] = gFieldEffectArguments[0];
|
|
|
|
sprite->data[1] = gFieldEffectArguments[1];
|
|
|
|
sprite->data[2] = gFieldEffectArguments[2];
|
|
|
|
sprite->pos2.y = (graphicsInfo->height >> 1) - 4;
|
|
|
|
PlaySE(SE_MIZU);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
void UpdateSplashFieldEffect(struct Sprite *sprite)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
u8 objectEventId;
|
2018-10-10 18:02:02 +02:00
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
if (sprite->animEnded || TryGetObjectEventIdByLocalIdAndMap(sprite->data[0], sprite->data[1], sprite->data[2], &objectEventId))
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
FieldEffectStop(sprite, FLDEFF_SPLASH);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
sprite->pos1.x = gSprites[gObjectEvents[objectEventId].spriteId].pos1.x;
|
|
|
|
sprite->pos1.y = gSprites[gObjectEvents[objectEventId].spriteId].pos1.y;
|
|
|
|
UpdateObjectEventSpriteVisibility(sprite, FALSE);
|
2018-10-10 18:02:02 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
u32 FldEff_JumpSmallSplash(void)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
u8 spriteId;
|
|
|
|
struct Sprite *sprite;
|
|
|
|
|
|
|
|
sub_80930E0((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 12);
|
2020-06-20 01:58:56 +02:00
|
|
|
spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[FLDEFFOBJ_JUMP_SMALL_SPLASH], gFieldEffectArguments[0], gFieldEffectArguments[1], 0);
|
2018-10-10 18:02:02 +02:00
|
|
|
if (spriteId != MAX_SPRITES)
|
|
|
|
{
|
|
|
|
sprite = &gSprites[spriteId];
|
|
|
|
sprite->coordOffsetEnabled = TRUE;
|
|
|
|
sprite->oam.priority = gFieldEffectArguments[3];
|
|
|
|
sprite->data[0] = gFieldEffectArguments[2];
|
|
|
|
sprite->data[1] = FLDEFF_JUMP_SMALL_SPLASH;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
u32 FldEff_JumpBigSplash(void)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
u8 spriteId;
|
|
|
|
struct Sprite *sprite;
|
|
|
|
|
|
|
|
sub_80930E0((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 8);
|
2020-06-20 01:58:56 +02:00
|
|
|
spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[FLDEFFOBJ_JUMP_BIG_SPLASH], gFieldEffectArguments[0], gFieldEffectArguments[1], 0);
|
2018-10-10 18:02:02 +02:00
|
|
|
if (spriteId != MAX_SPRITES)
|
|
|
|
{
|
|
|
|
sprite = &gSprites[spriteId];
|
|
|
|
sprite->coordOffsetEnabled = TRUE;
|
|
|
|
sprite->oam.priority = gFieldEffectArguments[3];
|
|
|
|
sprite->data[0] = gFieldEffectArguments[2];
|
|
|
|
sprite->data[1] = FLDEFF_JUMP_BIG_SPLASH;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
u32 FldEff_FeetInFlowingWater(void)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
u8 objectEventId;
|
|
|
|
struct ObjectEvent *objectEvent;
|
2018-10-10 18:02:02 +02:00
|
|
|
u8 spriteId;
|
|
|
|
struct Sprite *sprite;
|
2019-11-21 04:55:44 +01:00
|
|
|
const struct ObjectEventGraphicsInfo *graphicsInfo;
|
2018-10-10 18:02:02 +02:00
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
objectEventId = GetObjectEventIdByLocalIdAndMap(gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
|
|
|
|
objectEvent = &gObjectEvents[objectEventId];
|
2020-06-20 01:58:56 +02:00
|
|
|
spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[FLDEFFOBJ_SPLASH], 0, 0, 0);
|
2018-10-10 18:02:02 +02:00
|
|
|
if (spriteId != MAX_SPRITES)
|
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
graphicsInfo = GetObjectEventGraphicsInfo(objectEvent->graphicsId);
|
2018-10-10 18:02:02 +02:00
|
|
|
sprite = &gSprites[spriteId];
|
2018-10-15 00:43:40 +02:00
|
|
|
sprite->callback = UpdateFeetInFlowingWaterFieldEffect;
|
2018-10-10 18:02:02 +02:00
|
|
|
sprite->coordOffsetEnabled = TRUE;
|
2019-11-21 04:55:44 +01:00
|
|
|
sprite->oam.priority = gSprites[objectEvent->spriteId].oam.priority;
|
2018-10-10 18:02:02 +02:00
|
|
|
sprite->data[0] = gFieldEffectArguments[0];
|
|
|
|
sprite->data[1] = gFieldEffectArguments[1];
|
|
|
|
sprite->data[2] = gFieldEffectArguments[2];
|
|
|
|
sprite->data[3] = -1;
|
|
|
|
sprite->data[4] = -1;
|
|
|
|
sprite->pos2.y = (graphicsInfo->height >> 1) - 4;
|
|
|
|
StartSpriteAnim(sprite, 1);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-10-16 15:55:16 +02:00
|
|
|
static void UpdateFeetInFlowingWaterFieldEffect(struct Sprite *sprite)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
u8 objectEventId;
|
2018-10-10 18:02:02 +02:00
|
|
|
struct Sprite *linkedSprite;
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *objectEvent;
|
2018-10-10 18:02:02 +02:00
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
if (TryGetObjectEventIdByLocalIdAndMap(sprite->data[0], sprite->data[1], sprite->data[2], &objectEventId) || !gObjectEvents[objectEventId].inShallowFlowingWater)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
FieldEffectStop(sprite, FLDEFF_FEET_IN_FLOWING_WATER);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
objectEvent = &gObjectEvents[objectEventId];
|
|
|
|
linkedSprite = &gSprites[objectEvent->spriteId];
|
2018-10-10 18:02:02 +02:00
|
|
|
sprite->pos1.x = linkedSprite->pos1.x;
|
|
|
|
sprite->pos1.y = linkedSprite->pos1.y;
|
|
|
|
sprite->subpriority = linkedSprite->subpriority;
|
2019-11-21 04:55:44 +01:00
|
|
|
UpdateObjectEventSpriteVisibility(sprite, FALSE);
|
|
|
|
if (objectEvent->currentCoords.x != sprite->data[3] || objectEvent->currentCoords.y != sprite->data[4])
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
sprite->data[3] = objectEvent->currentCoords.x;
|
|
|
|
sprite->data[4] = objectEvent->currentCoords.y;
|
2018-10-10 18:02:02 +02:00
|
|
|
if (!sprite->invisible)
|
|
|
|
{
|
|
|
|
PlaySE(SE_MIZU);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
u32 FldEff_Ripple(void)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
u8 spriteId;
|
|
|
|
struct Sprite *sprite;
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[FLDEFFOBJ_RIPPLE], gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
|
2018-10-10 18:02:02 +02:00
|
|
|
if (spriteId != MAX_SPRITES)
|
|
|
|
{
|
|
|
|
sprite = &gSprites[spriteId];
|
|
|
|
sprite->coordOffsetEnabled = TRUE;
|
|
|
|
sprite->oam.priority = gFieldEffectArguments[3];
|
|
|
|
sprite->data[0] = FLDEFF_RIPPLE;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
u32 FldEff_HotSpringsWater(void)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
u8 objectEventId;
|
|
|
|
struct ObjectEvent *objectEvent;
|
2018-10-10 18:02:02 +02:00
|
|
|
u8 spriteId;
|
|
|
|
struct Sprite *sprite;
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
objectEventId = GetObjectEventIdByLocalIdAndMap(gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
|
|
|
|
objectEvent = &gObjectEvents[objectEventId];
|
2020-06-20 01:58:56 +02:00
|
|
|
spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[FLDEFFOBJ_HOT_SPRINGS_WATER], 0, 0, 0);
|
2018-10-10 18:02:02 +02:00
|
|
|
if (spriteId != MAX_SPRITES)
|
|
|
|
{
|
|
|
|
sprite = &gSprites[spriteId];
|
|
|
|
sprite->coordOffsetEnabled = TRUE;
|
2019-11-21 04:55:44 +01:00
|
|
|
sprite->oam.priority = gSprites[objectEvent->spriteId].oam.priority;
|
2018-10-10 18:02:02 +02:00
|
|
|
sprite->data[0] = gFieldEffectArguments[0];
|
|
|
|
sprite->data[1] = gFieldEffectArguments[1];
|
|
|
|
sprite->data[2] = gFieldEffectArguments[2];
|
2019-11-21 04:55:44 +01:00
|
|
|
sprite->data[3] = gSprites[objectEvent->spriteId].pos1.x;
|
|
|
|
sprite->data[4] = gSprites[objectEvent->spriteId].pos1.y;
|
2018-10-10 18:02:02 +02:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
void UpdateHotSpringsWaterFieldEffect(struct Sprite *sprite)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
u8 objectEventId;
|
|
|
|
const struct ObjectEventGraphicsInfo *graphicsInfo;
|
2018-10-10 18:02:02 +02:00
|
|
|
struct Sprite *linkedSprite;
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
if (TryGetObjectEventIdByLocalIdAndMap(sprite->data[0], sprite->data[1], sprite->data[2], &objectEventId) || !gObjectEvents[objectEventId].inHotSprings)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
FieldEffectStop(sprite, FLDEFF_HOT_SPRINGS_WATER);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
graphicsInfo = GetObjectEventGraphicsInfo(gObjectEvents[objectEventId].graphicsId);
|
|
|
|
linkedSprite = &gSprites[gObjectEvents[objectEventId].spriteId];
|
2018-10-10 18:02:02 +02:00
|
|
|
sprite->pos1.x = linkedSprite->pos1.x;
|
|
|
|
sprite->pos1.y = (graphicsInfo->height >> 1) + linkedSprite->pos1.y - 8;
|
|
|
|
sprite->subpriority = linkedSprite->subpriority - 1;
|
2019-11-21 04:55:44 +01:00
|
|
|
UpdateObjectEventSpriteVisibility(sprite, FALSE);
|
2018-10-10 18:02:02 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
u32 FldEff_Unknown19(void)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
u8 spriteId;
|
|
|
|
struct Sprite *sprite;
|
|
|
|
|
|
|
|
sub_80930E0((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 8);
|
2020-06-20 01:58:56 +02:00
|
|
|
spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[FLDEFFOBJ_17], gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
|
2018-10-10 18:02:02 +02:00
|
|
|
if (spriteId != MAX_SPRITES)
|
|
|
|
{
|
|
|
|
sprite = &gSprites[spriteId];
|
|
|
|
sprite->coordOffsetEnabled = TRUE;
|
|
|
|
sprite->oam.priority = gFieldEffectArguments[3];
|
|
|
|
sprite->data[0] = FLDEFF_UNKNOWN_19;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
u32 FldEff_UnusedGrass(void)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
u8 spriteId;
|
|
|
|
struct Sprite *sprite;
|
|
|
|
|
|
|
|
sub_80930E0((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 8);
|
2020-06-20 01:58:56 +02:00
|
|
|
spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[FLDEFFOBJ_UNUSED_GRASS], gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
|
2018-10-10 18:02:02 +02:00
|
|
|
if (spriteId != MAX_SPRITES)
|
|
|
|
{
|
|
|
|
sprite = &gSprites[spriteId];
|
|
|
|
sprite->coordOffsetEnabled = TRUE;
|
|
|
|
sprite->oam.priority = gFieldEffectArguments[3];
|
2020-06-20 01:58:56 +02:00
|
|
|
sprite->data[0] = FLDEFF_UNUSED_GRASS;
|
2018-10-10 18:02:02 +02:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
u32 FldEff_Unknown21(void)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
u8 spriteId;
|
|
|
|
struct Sprite *sprite;
|
|
|
|
|
|
|
|
sub_80930E0((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 8);
|
2020-06-20 01:58:56 +02:00
|
|
|
spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[FLDEFFOBJ_19], gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
|
2018-10-10 18:02:02 +02:00
|
|
|
if (spriteId != MAX_SPRITES)
|
|
|
|
{
|
|
|
|
sprite = &gSprites[spriteId];
|
|
|
|
sprite->coordOffsetEnabled = TRUE;
|
|
|
|
sprite->oam.priority = gFieldEffectArguments[3];
|
|
|
|
sprite->data[0] = FLDEFF_UNKNOWN_21;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
u32 FldEff_Unknown22(void)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
u8 spriteId;
|
|
|
|
struct Sprite *sprite;
|
|
|
|
|
|
|
|
sub_80930E0((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 8);
|
2020-06-20 01:58:56 +02:00
|
|
|
spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[FLDEFFOBJ_20], gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
|
2018-10-10 18:02:02 +02:00
|
|
|
if (spriteId != MAX_SPRITES)
|
|
|
|
{
|
|
|
|
sprite = &gSprites[spriteId];
|
|
|
|
sprite->coordOffsetEnabled = TRUE;
|
|
|
|
sprite->oam.priority = gFieldEffectArguments[3];
|
|
|
|
sprite->data[0] = FLDEFF_UNKNOWN_22;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-06-12 03:32:27 +02:00
|
|
|
void StartAshFieldEffect(s16 x, s16 y, u16 metatileId, s16 d)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
gFieldEffectArguments[0] = x;
|
|
|
|
gFieldEffectArguments[1] = y;
|
|
|
|
gFieldEffectArguments[2] = 0x52;
|
|
|
|
gFieldEffectArguments[3] = 1;
|
2019-06-12 03:32:27 +02:00
|
|
|
gFieldEffectArguments[4] = metatileId;
|
2018-10-10 18:02:02 +02:00
|
|
|
gFieldEffectArguments[5] = d;
|
|
|
|
FieldEffectStart(FLDEFF_ASH);
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
u32 FldEff_Ash(void)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
s16 x;
|
|
|
|
s16 y;
|
|
|
|
u8 spriteId;
|
|
|
|
struct Sprite *sprite;
|
|
|
|
|
|
|
|
x = gFieldEffectArguments[0];
|
|
|
|
y = gFieldEffectArguments[1];
|
|
|
|
sub_80930E0(&x, &y, 8, 8);
|
2020-06-20 01:58:56 +02:00
|
|
|
spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[FLDEFFOBJ_ASH], x, y, gFieldEffectArguments[2]);
|
2018-10-10 18:02:02 +02:00
|
|
|
if (spriteId != MAX_SPRITES)
|
|
|
|
{
|
|
|
|
sprite = &gSprites[spriteId];
|
|
|
|
sprite->coordOffsetEnabled = TRUE;
|
|
|
|
sprite->oam.priority = gFieldEffectArguments[3];
|
|
|
|
sprite->data[1] = gFieldEffectArguments[0];
|
|
|
|
sprite->data[2] = gFieldEffectArguments[1];
|
|
|
|
sprite->data[3] = gFieldEffectArguments[4];
|
|
|
|
sprite->data[4] = gFieldEffectArguments[5];
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void (*const gAshFieldEffectFuncs[])(struct Sprite *) = {
|
2018-10-15 00:43:40 +02:00
|
|
|
UpdateAshFieldEffect_Step0,
|
|
|
|
UpdateAshFieldEffect_Step1,
|
|
|
|
UpdateAshFieldEffect_Step2
|
2018-10-10 18:02:02 +02:00
|
|
|
};
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
void UpdateAshFieldEffect(struct Sprite *sprite)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
gAshFieldEffectFuncs[sprite->data[0]](sprite);
|
|
|
|
}
|
|
|
|
|
2018-10-16 15:55:16 +02:00
|
|
|
static void UpdateAshFieldEffect_Step0(struct Sprite *sprite)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
sprite->invisible = TRUE;
|
|
|
|
sprite->animPaused = TRUE;
|
|
|
|
if (--sprite->data[4] == 0)
|
|
|
|
sprite->data[0] = 1;
|
|
|
|
}
|
|
|
|
|
2018-10-16 15:55:16 +02:00
|
|
|
static void UpdateAshFieldEffect_Step1(struct Sprite *sprite)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
sprite->invisible = FALSE;
|
|
|
|
sprite->animPaused = FALSE;
|
|
|
|
MapGridSetMetatileIdAt(sprite->data[1], sprite->data[2], sprite->data[3]);
|
|
|
|
CurrentMapDrawMetatileAt(sprite->data[1], sprite->data[2]);
|
2019-11-21 04:55:44 +01:00
|
|
|
gObjectEvents[gPlayerAvatar.objectEventId].triggerGroundEffectsOnMove = TRUE;
|
2018-10-10 18:02:02 +02:00
|
|
|
sprite->data[0] = 2;
|
|
|
|
}
|
|
|
|
|
2018-10-16 15:55:16 +02:00
|
|
|
static void UpdateAshFieldEffect_Step2(struct Sprite *sprite)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
UpdateObjectEventSpriteVisibility(sprite, FALSE);
|
2018-10-10 18:02:02 +02:00
|
|
|
if (sprite->animEnded)
|
|
|
|
FieldEffectStop(sprite, FLDEFF_ASH);
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
u32 FldEff_SurfBlob(void)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
u8 spriteId;
|
|
|
|
struct Sprite *sprite;
|
|
|
|
|
|
|
|
sub_80930E0((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 8);
|
2020-06-20 01:58:56 +02:00
|
|
|
spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[FLDEFFOBJ_SURF_BLOB], gFieldEffectArguments[0], gFieldEffectArguments[1], 0x96);
|
2018-10-10 18:02:02 +02:00
|
|
|
if (spriteId !=MAX_SPRITES)
|
|
|
|
{
|
|
|
|
sprite = &gSprites[spriteId];
|
|
|
|
sprite->coordOffsetEnabled = TRUE;
|
|
|
|
sprite->oam.paletteNum = 0;
|
|
|
|
sprite->data[2] = gFieldEffectArguments[2];
|
|
|
|
sprite->data[3] = -1;
|
|
|
|
sprite->data[6] = -1;
|
|
|
|
sprite->data[7] = -1;
|
|
|
|
}
|
|
|
|
FieldEffectActiveListRemove(FLDEFF_SURF_BLOB);
|
|
|
|
return spriteId;
|
|
|
|
}
|
|
|
|
|
|
|
|
void sub_81555AC(u8 spriteId, u8 value)
|
|
|
|
{
|
|
|
|
gSprites[spriteId].data[0] = (gSprites[spriteId].data[0] & ~0xF) | (value & 0xF);
|
|
|
|
}
|
|
|
|
|
|
|
|
void sub_81555D8(u8 spriteId, u8 value)
|
|
|
|
{
|
|
|
|
gSprites[spriteId].data[0] = (gSprites[spriteId].data[0] & ~0xF0) | ((value & 0xF) << 4);
|
|
|
|
}
|
|
|
|
|
|
|
|
void sub_8155604(u8 spriteId, u8 value, s16 data1)
|
|
|
|
{
|
|
|
|
gSprites[spriteId].data[0] = (gSprites[spriteId].data[0] & ~0xF00) | ((value & 0xF) << 8);
|
|
|
|
gSprites[spriteId].data[1] = data1;
|
|
|
|
}
|
|
|
|
|
2018-10-16 15:55:16 +02:00
|
|
|
static u8 sub_8155638(struct Sprite *sprite)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
return sprite->data[0] & 0xF;
|
|
|
|
}
|
|
|
|
|
2018-10-16 15:55:16 +02:00
|
|
|
static u8 sub_8155640(struct Sprite *sprite)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
return (sprite->data[0] & 0xF0) >> 4;
|
|
|
|
}
|
|
|
|
|
2018-10-16 15:55:16 +02:00
|
|
|
static u8 sub_815564C(struct Sprite *sprite)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
return (sprite->data[0] & 0xF00) >> 8;
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
void UpdateSurfBlobFieldEffect(struct Sprite *sprite)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *objectEvent;
|
2018-10-10 18:02:02 +02:00
|
|
|
struct Sprite *linkedSprite;
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
objectEvent = &gObjectEvents[sprite->data[2]];
|
|
|
|
linkedSprite = &gSprites[objectEvent->spriteId];
|
|
|
|
SynchroniseSurfAnim(objectEvent, sprite);
|
|
|
|
sub_81556E8(objectEvent, sprite);
|
|
|
|
CreateBobbingEffect(objectEvent, linkedSprite, sprite);
|
2018-10-10 18:02:02 +02:00
|
|
|
sprite->oam.priority = linkedSprite->oam.priority;
|
|
|
|
}
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
static void SynchroniseSurfAnim(struct ObjectEvent *objectEvent, struct Sprite *sprite)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
u8 surfBlobDirectionAnims[] = {
|
2018-12-05 15:31:01 +01:00
|
|
|
[DIR_NONE] = 0,
|
|
|
|
[DIR_SOUTH] = 0,
|
|
|
|
[DIR_NORTH] = 1,
|
|
|
|
[DIR_WEST] = 2,
|
|
|
|
[DIR_EAST] = 3,
|
|
|
|
[DIR_SOUTHWEST] = 0,
|
|
|
|
[DIR_SOUTHEAST] = 0,
|
|
|
|
[DIR_NORTHWEST] = 1,
|
|
|
|
[DIR_NORTHEAST] = 1,
|
2018-10-10 18:02:02 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
if (sub_8155640(sprite) == 0)
|
2019-11-21 04:55:44 +01:00
|
|
|
StartSpriteAnimIfDifferent(sprite, surfBlobDirectionAnims[objectEvent->movementDirection]);
|
2018-10-10 18:02:02 +02:00
|
|
|
}
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
void sub_81556E8(struct ObjectEvent *objectEvent, struct Sprite *sprite)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
u8 i;
|
2019-11-21 04:55:44 +01:00
|
|
|
s16 x = objectEvent->currentCoords.x;
|
|
|
|
s16 y = objectEvent->currentCoords.y;
|
2018-11-25 20:16:41 +01:00
|
|
|
s32 spriteY = sprite->pos2.y;
|
2018-10-10 18:02:02 +02:00
|
|
|
|
2018-11-25 20:16:41 +01:00
|
|
|
if (spriteY == 0 && (x != sprite->data[6] || y != sprite->data[7]))
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
2018-11-25 20:16:41 +01:00
|
|
|
sprite->data[5] = spriteY;
|
|
|
|
sprite->data[6] = x;
|
|
|
|
sprite->data[7] = y;
|
|
|
|
for (i = DIR_SOUTH; i <= DIR_EAST; i++, x = sprite->data[6], y = sprite->data[7])
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
MoveCoords(i, &x, &y);
|
|
|
|
if (MapGridGetZCoordAt(x, y) == 3)
|
|
|
|
{
|
|
|
|
sprite->data[5] ++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
static void CreateBobbingEffect(struct ObjectEvent *objectEvent, struct Sprite *linkedSprite, struct Sprite *sprite)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
u16 unk_085CDC6A[] = {3, 7};
|
|
|
|
u8 v0 = sub_8155638(sprite);
|
|
|
|
if (v0 != 0)
|
|
|
|
{
|
|
|
|
if (((u16)(++ sprite->data[4]) & unk_085CDC6A[sprite->data[5]]) == 0)
|
|
|
|
{
|
|
|
|
sprite->pos2.y += sprite->data[3];
|
|
|
|
}
|
|
|
|
if ((sprite->data[4] & 0x0F) == 0)
|
|
|
|
{
|
|
|
|
sprite->data[3] = -sprite->data[3];
|
|
|
|
}
|
|
|
|
if (v0 != 2)
|
|
|
|
{
|
|
|
|
if (sub_815564C(sprite) == 0)
|
|
|
|
linkedSprite->pos2.y = sprite->pos2.y;
|
|
|
|
else
|
|
|
|
linkedSprite->pos2.y = sprite->data[1] + sprite->pos2.y;
|
|
|
|
sprite->pos1.x = linkedSprite->pos1.x;
|
|
|
|
sprite->pos1.y = linkedSprite->pos1.y + 8;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
u8 sub_8155800(u8 oldSpriteId)
|
|
|
|
{
|
|
|
|
u8 spriteId;
|
|
|
|
struct Sprite *sprite;
|
|
|
|
|
|
|
|
spriteId = CreateSpriteAtEnd(&gDummySpriteTemplate, 0, 0, -1);
|
|
|
|
sprite = &gSprites[spriteId];
|
|
|
|
sprite->callback = sub_8155850;
|
|
|
|
sprite->invisible = TRUE;
|
|
|
|
sprite->data[0] = oldSpriteId;
|
|
|
|
sprite->data[1] = 1;
|
|
|
|
return spriteId;
|
|
|
|
}
|
|
|
|
|
2018-10-16 15:55:16 +02:00
|
|
|
static void sub_8155850(struct Sprite *sprite)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
struct Sprite *oldSprite;
|
|
|
|
|
|
|
|
oldSprite = &gSprites[sprite->data[0]];
|
|
|
|
if (((sprite->data[2]++) & 0x03) == 0)
|
|
|
|
{
|
|
|
|
oldSprite->pos2.y += sprite->data[1];
|
|
|
|
}
|
|
|
|
if ((sprite->data[2] & 0x0F) == 0)
|
|
|
|
{
|
|
|
|
sprite->data[1] = -sprite->data[1];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
u32 FldEff_Dust(void)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
u8 spriteId;
|
|
|
|
struct Sprite *sprite;
|
|
|
|
|
|
|
|
sub_80930E0((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 12);
|
2020-06-20 01:58:56 +02:00
|
|
|
spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[FLDEFFOBJ_GROUND_IMPACT_DUST], gFieldEffectArguments[0], gFieldEffectArguments[1], 0);
|
2018-10-10 18:02:02 +02:00
|
|
|
if (spriteId != MAX_SPRITES)
|
|
|
|
{
|
|
|
|
sprite = &gSprites[spriteId];
|
|
|
|
sprite->coordOffsetEnabled = TRUE;
|
|
|
|
sprite->oam.priority = gFieldEffectArguments[3];
|
|
|
|
sprite->data[0] = gFieldEffectArguments[2];
|
|
|
|
sprite->data[1] = 10;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
u32 FldEff_SandPile(void)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
u8 objectEventId;
|
|
|
|
struct ObjectEvent *objectEvent;
|
2018-10-10 18:02:02 +02:00
|
|
|
u8 spriteId;
|
|
|
|
struct Sprite *sprite;
|
2019-11-21 04:55:44 +01:00
|
|
|
const struct ObjectEventGraphicsInfo *graphicsInfo;
|
2018-10-10 18:02:02 +02:00
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
objectEventId = GetObjectEventIdByLocalIdAndMap(gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
|
|
|
|
objectEvent = &gObjectEvents[objectEventId];
|
2020-06-20 01:58:56 +02:00
|
|
|
spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[FLDEFFOBJ_SAND_PILE], 0, 0, 0);
|
2018-10-10 18:02:02 +02:00
|
|
|
if (spriteId != MAX_SPRITES)
|
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
graphicsInfo = GetObjectEventGraphicsInfo(objectEvent->graphicsId);
|
2018-10-10 18:02:02 +02:00
|
|
|
sprite = &gSprites[spriteId];
|
|
|
|
sprite->coordOffsetEnabled = TRUE;
|
2019-11-21 04:55:44 +01:00
|
|
|
sprite->oam.priority = gSprites[objectEvent->spriteId].oam.priority;
|
2018-10-10 18:02:02 +02:00
|
|
|
sprite->data[0] = gFieldEffectArguments[0];
|
|
|
|
sprite->data[1] = gFieldEffectArguments[1];
|
|
|
|
sprite->data[2] = gFieldEffectArguments[2];
|
2019-11-21 04:55:44 +01:00
|
|
|
sprite->data[3] = gSprites[objectEvent->spriteId].pos1.x;
|
|
|
|
sprite->data[4] = gSprites[objectEvent->spriteId].pos1.y;
|
2018-10-10 18:02:02 +02:00
|
|
|
sprite->pos2.y = (graphicsInfo->height >> 1) - 2;
|
|
|
|
SeekSpriteAnim(sprite, 2);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
void UpdateSandPileFieldEffect(struct Sprite *sprite)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
u8 objectEventId;
|
2018-10-10 18:02:02 +02:00
|
|
|
s16 x;
|
|
|
|
s16 y;
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
if (TryGetObjectEventIdByLocalIdAndMap(sprite->data[0], sprite->data[1], sprite->data[2], &objectEventId) || !gObjectEvents[objectEventId].inSandPile)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
FieldEffectStop(sprite, FLDEFF_SAND_PILE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
y = gSprites[gObjectEvents[objectEventId].spriteId].pos1.y;
|
|
|
|
x = gSprites[gObjectEvents[objectEventId].spriteId].pos1.x;
|
2018-10-10 18:02:02 +02:00
|
|
|
if (x != sprite->data[3] || y != sprite->data[4])
|
|
|
|
{
|
|
|
|
sprite->data[3] = x;
|
|
|
|
sprite->data[4] = y;
|
|
|
|
if (sprite->animEnded)
|
|
|
|
{
|
|
|
|
StartSpriteAnim(sprite, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
sprite->pos1.x = x;
|
|
|
|
sprite->pos1.y = y;
|
2019-11-21 04:55:44 +01:00
|
|
|
sprite->subpriority = gSprites[gObjectEvents[objectEventId].spriteId].subpriority;
|
|
|
|
UpdateObjectEventSpriteVisibility(sprite, FALSE);
|
2018-10-10 18:02:02 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
u32 FldEff_Bubbles(void)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
u8 spriteId;
|
|
|
|
struct Sprite *sprite;
|
|
|
|
|
|
|
|
sub_80930E0((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 0);
|
2020-06-20 01:58:56 +02:00
|
|
|
spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[FLDEFFOBJ_BUBBLES], gFieldEffectArguments[0], gFieldEffectArguments[1], 0x52);
|
2018-10-10 18:02:02 +02:00
|
|
|
if (spriteId != MAX_SPRITES)
|
|
|
|
{
|
|
|
|
sprite = &gSprites[spriteId];
|
|
|
|
sprite->coordOffsetEnabled = TRUE;
|
|
|
|
sprite->oam.priority = 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
void UpdateBubblesFieldEffect(struct Sprite *sprite)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
sprite->data[0] += 0x80;
|
|
|
|
sprite->data[0] &= 0x100;
|
|
|
|
sprite->pos1.y -= sprite->data[0] >> 8;
|
2019-11-21 04:55:44 +01:00
|
|
|
UpdateObjectEventSpriteVisibility(sprite, FALSE);
|
2018-10-10 18:02:02 +02:00
|
|
|
if (sprite->invisible || sprite->animEnded)
|
|
|
|
{
|
|
|
|
FieldEffectStop(sprite, FLDEFF_BUBBLES);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
u32 FldEff_BerryTreeGrowthSparkle(void)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
u8 spriteId;
|
|
|
|
struct Sprite *sprite;
|
|
|
|
|
|
|
|
sub_80930E0((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 4);
|
2020-06-20 01:58:56 +02:00
|
|
|
spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[FLDEFFOBJ_SPARKLE], gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
|
2018-10-10 18:02:02 +02:00
|
|
|
if (spriteId != MAX_SPRITES)
|
|
|
|
{
|
|
|
|
sprite = &gSprites[spriteId];
|
|
|
|
sprite->coordOffsetEnabled = TRUE;
|
|
|
|
sprite->oam.priority = gFieldEffectArguments[3];
|
|
|
|
sprite->oam.paletteNum = 5;
|
|
|
|
sprite->data[0] = FLDEFF_BERRY_TREE_GROWTH_SPARKLE;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 ShowTreeDisguiseFieldEffect(void)
|
|
|
|
{
|
2020-06-20 01:58:56 +02:00
|
|
|
return ShowDisguiseFieldEffect(FLDEFF_TREE_DISGUISE, FLDEFFOBJ_TREE_DISGUISE, 4);
|
2018-10-10 18:02:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
u32 ShowMountainDisguiseFieldEffect(void)
|
|
|
|
{
|
2020-06-20 01:58:56 +02:00
|
|
|
return ShowDisguiseFieldEffect(FLDEFF_MOUNTAIN_DISGUISE, FLDEFFOBJ_MOUNTAIN_DISGUISE, 3);
|
2018-10-10 18:02:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
u32 ShowSandDisguiseFieldEffect(void)
|
|
|
|
{
|
2020-06-20 01:58:56 +02:00
|
|
|
return ShowDisguiseFieldEffect(FLDEFF_SAND_DISGUISE, FLDEFFOBJ_SAND_DISGUISE, 2);
|
2018-10-10 18:02:02 +02:00
|
|
|
}
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
static u32 ShowDisguiseFieldEffect(u8 fldEff, u8 fldEffObj, u8 paletteNum)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
u8 spriteId;
|
|
|
|
struct Sprite *sprite;
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
if (TryGetObjectEventIdByLocalIdAndMap(gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2], &spriteId))
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
FieldEffectActiveListRemove(fldEff);
|
|
|
|
return MAX_SPRITES;
|
|
|
|
}
|
2020-06-20 01:58:56 +02:00
|
|
|
spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[fldEffObj], 0, 0, 0);
|
2018-10-10 18:02:02 +02:00
|
|
|
if (spriteId != MAX_SPRITES)
|
|
|
|
{
|
|
|
|
sprite = &gSprites[spriteId];
|
|
|
|
sprite->coordOffsetEnabled ++;
|
|
|
|
sprite->oam.paletteNum = paletteNum;
|
|
|
|
sprite->data[1] = fldEff;
|
|
|
|
sprite->data[2] = gFieldEffectArguments[0];
|
|
|
|
sprite->data[3] = gFieldEffectArguments[1];
|
|
|
|
sprite->data[4] = gFieldEffectArguments[2];
|
|
|
|
}
|
|
|
|
return spriteId;
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
void UpdateDisguiseFieldEffect(struct Sprite *sprite)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
u8 objectEventId;
|
|
|
|
const struct ObjectEventGraphicsInfo *graphicsInfo;
|
2018-10-10 18:02:02 +02:00
|
|
|
struct Sprite *linkedSprite;
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
if (TryGetObjectEventIdByLocalIdAndMap(sprite->data[2], sprite->data[3], sprite->data[4], &objectEventId))
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
FieldEffectStop(sprite, sprite->data[1]);
|
|
|
|
}
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
graphicsInfo = GetObjectEventGraphicsInfo(gObjectEvents[objectEventId].graphicsId);
|
|
|
|
linkedSprite = &gSprites[gObjectEvents[objectEventId].spriteId];
|
2018-10-10 18:02:02 +02:00
|
|
|
sprite->invisible = linkedSprite->invisible;
|
|
|
|
sprite->pos1.x = linkedSprite->pos1.x;
|
|
|
|
sprite->pos1.y = (graphicsInfo->height >> 1) + linkedSprite->pos1.y - 16;
|
|
|
|
sprite->subpriority = linkedSprite->subpriority - 1;
|
|
|
|
if (sprite->data[0] == 1)
|
|
|
|
{
|
|
|
|
sprite->data[0] ++;
|
|
|
|
StartSpriteAnim(sprite, 1);
|
|
|
|
}
|
|
|
|
if (sprite->data[0] == 2 && sprite->animEnded)
|
|
|
|
{
|
|
|
|
sprite->data[7] = 1;
|
|
|
|
}
|
|
|
|
if (sprite->data[0] == 3)
|
|
|
|
{
|
|
|
|
FieldEffectStop(sprite, sprite->data[1]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
void sub_8155D78(struct ObjectEvent *objectEvent)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
if (objectEvent->directionSequenceIndex == 1)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
gSprites[objectEvent->fieldEffectSpriteId].data[0]++;
|
2018-10-10 18:02:02 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
bool8 sub_8155DA0(struct ObjectEvent *objectEvent)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
struct Sprite *sprite;
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
if (objectEvent->directionSequenceIndex == 2)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
2019-11-21 04:55:44 +01:00
|
|
|
if (objectEvent->directionSequenceIndex == 0)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
2019-11-21 04:55:44 +01:00
|
|
|
sprite = &gSprites[objectEvent->fieldEffectSpriteId];
|
2018-10-10 18:02:02 +02:00
|
|
|
if (sprite->data[7])
|
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
objectEvent->directionSequenceIndex = 2;
|
2018-10-10 18:02:02 +02:00
|
|
|
sprite->data[0]++;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
u32 FldEff_Sparkle(void)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
u8 spriteId;
|
|
|
|
|
|
|
|
gFieldEffectArguments[0] += 7;
|
|
|
|
gFieldEffectArguments[1] += 7;
|
|
|
|
sub_80930E0((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 8);
|
2020-06-20 01:58:56 +02:00
|
|
|
spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[FLDEFFOBJ_SMALL_SPARKLE], gFieldEffectArguments[0], gFieldEffectArguments[1], 0x52);
|
2018-10-10 18:02:02 +02:00
|
|
|
if (spriteId != MAX_SPRITES)
|
|
|
|
{
|
|
|
|
gSprites[spriteId].oam.priority = gFieldEffectArguments[2];
|
|
|
|
gSprites[spriteId].coordOffsetEnabled = TRUE;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:43:40 +02:00
|
|
|
void UpdateSparkleFieldEffect(struct Sprite *sprite)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
if (sprite->data[0] == 0)
|
|
|
|
{
|
|
|
|
if (sprite->animEnded)
|
|
|
|
{
|
|
|
|
sprite->invisible = TRUE;
|
|
|
|
sprite->data[0]++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sprite->data[0] == 0)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (++sprite->data[1] > 34)
|
|
|
|
FieldEffectStop(sprite, FLDEFF_SPARKLE);
|
|
|
|
}
|
|
|
|
|
|
|
|
void sub_8155EA0(struct Sprite *sprite)
|
|
|
|
{
|
|
|
|
sprite->data[6] = 0;
|
|
|
|
sprite->data[7] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool8 sub_8155EA8(struct Sprite *sprite)
|
|
|
|
{
|
|
|
|
bool8 returnBool = FALSE;
|
2018-11-25 20:16:41 +01:00
|
|
|
|
2018-10-10 18:02:02 +02:00
|
|
|
switch (sprite->data[7])
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
sprite->pos2.x += sub_809773C(sprite->data[6]);
|
|
|
|
sprite->pos2.y += sub_8097728(sprite->data[6]);
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
sprite->pos2.x -= sub_809773C(0x47 - sprite->data[6]);
|
|
|
|
sprite->pos2.y += sub_8097728(0x47 - sprite->data[6]);
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
sprite->pos2.x -= sub_809773C(sprite->data[6]);
|
|
|
|
sprite->pos2.y += sub_8097728(sprite->data[6]);
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
sprite->pos2.x += sub_809773C(0x47 - sprite->data[6]);
|
|
|
|
sprite->pos2.y += sub_8097728(0x47 - sprite->data[6]);
|
|
|
|
break;
|
|
|
|
}
|
2018-11-25 20:16:41 +01:00
|
|
|
|
2018-10-10 18:02:02 +02:00
|
|
|
SetGpuReg(REG_OFFSET_BG0HOFS, -sprite->pos2.x);
|
|
|
|
if (++sprite->data[6] == 72)
|
|
|
|
{
|
|
|
|
sprite->data[6] = 0;
|
|
|
|
sprite->data[7]++;
|
|
|
|
}
|
|
|
|
if (sprite->data[7] == 4)
|
|
|
|
{
|
|
|
|
sprite->pos2.y = 0;
|
|
|
|
sprite->pos2.x = 0;
|
|
|
|
returnBool = TRUE;
|
|
|
|
}
|
2018-11-25 20:16:41 +01:00
|
|
|
|
2018-10-10 18:02:02 +02:00
|
|
|
return returnBool;
|
|
|
|
}
|
|
|
|
|
|
|
|
void sub_8155F80(struct Sprite *sprite)
|
|
|
|
{
|
|
|
|
u8 i, j;
|
2018-11-25 20:16:41 +01:00
|
|
|
|
2018-10-10 18:02:02 +02:00
|
|
|
switch (sprite->data[2])
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
SetGpuReg(REG_OFFSET_BG0VOFS, 0x78 - (sprite->data[0] / 3));
|
|
|
|
if (sprite->data[0] == 0x60)
|
|
|
|
{
|
|
|
|
for (i = 0; i < 3; i++)
|
|
|
|
{
|
|
|
|
for (j = 12; j < 18; j++)
|
|
|
|
{
|
2019-02-17 06:25:48 +01:00
|
|
|
((u16*)(BG_SCREEN_ADDR(31)))[i * 32 + j] = 0xBFF4 + i * 6 + j + 1;
|
2018-10-10 18:02:02 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (sprite->data[0] > 0x137)
|
|
|
|
{
|
|
|
|
sprite->data[2] = 1;
|
|
|
|
sprite->data[0] = 0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
sprite->pos1.y = (gSineTable[sprite->data[0] / 3] >> 2) + sprite->data[4];
|
|
|
|
if (sprite->data[0] == 0xBD)
|
|
|
|
{
|
|
|
|
sprite->data[2] = 2;
|
|
|
|
sprite->data[5] = 0;
|
|
|
|
sprite->data[0] = 0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
if (sprite->data[0] == 0x3C)
|
|
|
|
{
|
|
|
|
sprite->data[5]++;
|
|
|
|
sprite->data[0] = 0;
|
|
|
|
}
|
|
|
|
if (sprite->data[5] == 7)
|
|
|
|
{
|
|
|
|
sprite->data[5] = 0;
|
|
|
|
sprite->data[2] = 3;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
if (sprite->pos2.y == 0)
|
|
|
|
{
|
|
|
|
sprite->data[0] = 0;
|
|
|
|
sprite->data[2]++;
|
|
|
|
}
|
|
|
|
if (sprite->data[0] == 5)
|
|
|
|
{
|
|
|
|
sprite->data[0] = 0;
|
|
|
|
if (sprite->pos2.y > 0)
|
|
|
|
sprite->pos2.y--;
|
|
|
|
else
|
|
|
|
sprite->pos2.y++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
if (sprite->data[0] == 0x3C)
|
|
|
|
{
|
|
|
|
sprite->data[2] = 5;
|
|
|
|
sprite->data[0] = 0;
|
|
|
|
sprite->data[5] = 0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 5:
|
|
|
|
sub_8155EA0(sprite);
|
|
|
|
sprite->data[2] = 6;
|
|
|
|
sprite->data[0] = 0;
|
|
|
|
break;
|
|
|
|
case 6:
|
|
|
|
if (sub_8155EA8(sprite))
|
|
|
|
{
|
|
|
|
sprite->data[0] = 0;
|
|
|
|
if (++sprite->data[5] <= 2)
|
|
|
|
{
|
|
|
|
sub_8155EA0(sprite);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sprite->data[5] = 0;
|
|
|
|
sprite->data[2] = 7;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 7:
|
|
|
|
if (sprite->data[0] == 0x1E)
|
|
|
|
{
|
|
|
|
sprite->data[2] = 8;
|
|
|
|
sprite->data[0] = 0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 8:
|
|
|
|
for (i = 0; i < 15; i++)
|
|
|
|
{
|
|
|
|
for (j = 12; j < 18; j++)
|
|
|
|
{
|
2019-02-17 06:25:48 +01:00
|
|
|
((u16*)(BG_SCREEN_ADDR(31)))[i * 32 + j] = 0;
|
2018-10-10 18:02:02 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
SetGpuReg(REG_OFFSET_BG0VOFS, 0);
|
2019-03-22 17:25:51 +01:00
|
|
|
FieldEffectStop(sprite, FLDEFF_RAYQUAZA);
|
2018-10-10 18:02:02 +02:00
|
|
|
break;
|
|
|
|
}
|
2018-11-25 20:16:41 +01:00
|
|
|
|
2018-10-10 18:02:02 +02:00
|
|
|
if (sprite->data[2] == 1)
|
|
|
|
{
|
|
|
|
if ((sprite->data[1] & 7) == 0)
|
|
|
|
sprite->pos2.y += sprite->data[3];
|
|
|
|
if ((sprite->data[1] & 15) == 0)
|
|
|
|
sprite->data[3] = -sprite->data[3];
|
|
|
|
sprite->data[1]++;
|
|
|
|
}
|
2018-11-25 20:16:41 +01:00
|
|
|
|
2018-10-10 18:02:02 +02:00
|
|
|
sprite->data[0]++;
|
|
|
|
}
|
|
|
|
|
|
|
|
void sub_8156194(struct Sprite *sprite)
|
|
|
|
{
|
|
|
|
if (sprite->animEnded)
|
|
|
|
{
|
|
|
|
FieldEffectStop(sprite, sprite->data[1]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
UpdateObjectEventSpriteVisibility(sprite, FALSE);
|
2018-10-10 18:02:02 +02:00
|
|
|
SetObjectSubpriorityByZCoord(sprite->data[0], sprite, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-16 15:55:16 +02:00
|
|
|
void WaitFieldEffectSpriteAnim(struct Sprite *sprite)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
if (sprite->animEnded)
|
|
|
|
FieldEffectStop(sprite, sprite->data[0]);
|
|
|
|
else
|
2019-11-21 04:55:44 +01:00
|
|
|
UpdateObjectEventSpriteVisibility(sprite, FALSE);
|
2018-10-10 18:02:02 +02:00
|
|
|
}
|
|
|
|
|
2018-11-29 21:19:00 +01:00
|
|
|
static void sub_81561FC(struct Sprite *sprite, u8 z, u8 offset)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
u8 i;
|
2018-11-29 21:19:00 +01:00
|
|
|
s16 var, xhi, lyhi, yhi, ylo;
|
2019-11-21 04:55:44 +01:00
|
|
|
const struct ObjectEventGraphicsInfo *graphicsInfo; // Unused Variable
|
2018-11-29 21:19:00 +01:00
|
|
|
struct Sprite *linkedSprite;
|
2018-10-10 18:02:02 +02:00
|
|
|
|
|
|
|
SetObjectSubpriorityByZCoord(z, sprite, offset);
|
2019-11-21 05:12:51 +01:00
|
|
|
for (i = 0; i < OBJECT_EVENTS_COUNT; i ++)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *objectEvent = &gObjectEvents[i];
|
|
|
|
if (objectEvent->active)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
graphicsInfo = GetObjectEventGraphicsInfo(objectEvent->graphicsId);
|
|
|
|
linkedSprite = &gSprites[objectEvent->spriteId];
|
2018-10-10 18:02:02 +02:00
|
|
|
xhi = sprite->pos1.x + sprite->centerToCornerVecX;
|
2018-11-29 21:19:00 +01:00
|
|
|
var = sprite->pos1.x - sprite->centerToCornerVecX;
|
|
|
|
if (xhi < linkedSprite->pos1.x && var > linkedSprite->pos1.x)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
|
|
|
lyhi = linkedSprite->pos1.y + linkedSprite->centerToCornerVecY;
|
2018-11-29 21:19:00 +01:00
|
|
|
var = linkedSprite->pos1.y;
|
2018-10-10 18:02:02 +02:00
|
|
|
ylo = sprite->pos1.y - sprite->centerToCornerVecY;
|
|
|
|
yhi = ylo + linkedSprite->centerToCornerVecY;
|
2018-11-29 21:19:00 +01:00
|
|
|
if ((lyhi < yhi || lyhi < ylo) && var > yhi && sprite->subpriority <= linkedSprite->subpriority)
|
2018-10-10 18:02:02 +02:00
|
|
|
{
|
2018-11-29 21:19:00 +01:00
|
|
|
sprite->subpriority = linkedSprite->subpriority + 2;
|
|
|
|
break;
|
2018-10-10 18:02:02 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-12-23 14:52:47 +01:00
|
|
|
|
|
|
|
// Unused data. Feel free to remove.
|
|
|
|
static const u8 gUnknown_085CDC6E[] =
|
|
|
|
{
|
|
|
|
0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x02, 0x02,
|
|
|
|
0x01, 0x02, 0x02, 0x01, 0x02, 0x02, 0x01, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02,
|
|
|
|
0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
|
|
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00,
|
|
|
|
0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01,
|
|
|
|
0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00,
|
|
|
|
0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
|
|
|
|
0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
|
|
0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00
|
|
|
|
};
|