Decompile field_ground_effect into event_object_movement.c

This commit is contained in:
Marcus Huderle 2018-06-11 10:23:14 -05:00
parent 4018acfae1
commit 73327f0d44
13 changed files with 758 additions and 1919 deletions

File diff suppressed because it is too large Load Diff

View File

@ -4,66 +4,3 @@
.section .rodata
.align 2, 0
gUnknown_0850E5DC:: @ 850E5DC
.4byte 0x00000020, 0x00000010
gUnknown_0850E5E4:: @ 850E5E4
.4byte MetatileBehavior_IsTallGrass
.4byte MetatileBehavior_IsLongGrass
.4byte MetatileBehavior_IsPuddle
.4byte MetatileBehavior_IsSurfableWaterOrUnderwater
.4byte MetatileBehavior_IsShallowFlowingWater
.4byte ShouldDoJumpLandingDustEffect
gUnknown_0850E5FC:: @ 850E5FC
.4byte 0x00001000, 0x00002000, 0x00004000, 0x00008000, 0x00004000, 0x00010000
gUnknown_0850E614:: @ 850E614
.4byte MetatileBehavior_IsJumpSouth
.4byte MetatileBehavior_IsJumpNorth
.4byte MetatileBehavior_IsJumpWest
.4byte MetatileBehavior_IsJumpEast
gUnknown_0850E624:: @ 850E624
.byte 0x73, 0x73, 0x53, 0x73, 0x53, 0x73, 0x53, 0x73, 0x53, 0x73, 0x53, 0x73, 0x53, 0x00, 0x00, 0x73
gUnknown_0850E634:: @ 850E634
.byte 0x02, 0x02, 0x02, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x00, 0x00, 0x02
gUnknown_0850E644:: @ 850E644
.byte 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x00, 0x00, 0x01
gUnknown_0850E654:: @ 850E654
.4byte DoTracksGroundEffect_None
.4byte DoTracksGroundEffect_Footprints
.4byte DoTracksGroundEffect_BikeTireTracks
gUnknown_0850E660:: @ 850E660
.byte 13, 0
.byte 24, 0
gUnknown_0850E664:: @ 850E664
.byte 0x01, 0x02, 0x07, 0x08, 0x01, 0x02, 0x06, 0x05, 0x05, 0x08, 0x03, 0x04, 0x06, 0x07, 0x03, 0x04
gUnknown_0850E674:: @ 850E674
.4byte GroundEffect_SpawnOnTallGrass
.4byte GroundEffect_StepOnTallGrass
.4byte GroundEffect_SpawnOnLongGrass
.4byte GroundEffect_StepOnLongGrass
.4byte GroundEffect_WaterReflection
.4byte GroundEffect_IceReflection
.4byte GroundEffect_FlowingWater
.4byte GroundEffect_SandTracks
.4byte GroundEffect_DeepSandTracks
.4byte GroundEffect_Ripple
.4byte GroundEffect_StepOnPuddle
.4byte GroundEffect_SandHeap
.4byte GroundEffect_JumpOnTallGrass
.4byte GroundEffect_JumpOnLongGrass
.4byte GroundEffect_JumpOnShallowWater
.4byte GroundEffect_JumpOnWater
.4byte GroundEffect_JumpLandingDust
.4byte GroundEffect_ShortGrass
.4byte GroundEffect_HotSprings
.4byte GroundEffect_Seaweed

View File

@ -20,6 +20,27 @@ enum SpinnerRunnerFollowPatterns {
RUNFOLLOW_SOUTH_EAST_WEST
};
#define GROUND_EFFECT_FLAG_TALL_GRASS_ON_SPAWN (1 << 0)
#define GROUND_EFFECT_FLAG_TALL_GRASS_ON_MOVE (1 << 1)
#define GROUND_EFFECT_FLAG_LONG_GRASS_ON_SPAWN (1 << 2)
#define GROUND_EFFECT_FLAG_LONG_GRASS_ON_MOVE (1 << 3)
#define GROUND_EFFECT_FLAG_ICE_REFLECTION (1 << 4)
#define GROUND_EFFECT_FLAG_REFLECTION (1 << 5)
#define GROUND_EFFECT_FLAG_SHALLOW_FLOWING_WATER (1 << 6)
#define GROUND_EFFECT_FLAG_SAND (1 << 7)
#define GROUND_EFFECT_FLAG_DEEP_SAND (1 << 8)
#define GROUND_EFFECT_FLAG_RIPPLES (1 << 9)
#define GROUND_EFFECT_FLAG_PUDDLE (1 << 10)
#define GROUND_EFFECT_FLAG_SAND_PILE (1 << 11)
#define GROUND_EFFECT_FLAG_LAND_IN_TALL_GRASS (1 << 12)
#define GROUND_EFFECT_FLAG_LAND_IN_LONG_GRASS (1 << 13)
#define GROUND_EFFECT_FLAG_LAND_IN_SHALLOW_WATER (1 << 14)
#define GROUND_EFFECT_FLAG_LAND_IN_DEEP_WATER (1 << 15)
#define GROUND_EFFECT_FLAG_LAND_ON_NORMAL_GROUND (1 << 16)
#define GROUND_EFFECT_FLAG_SHORT_GRASS (1 << 17)
#define GROUND_EFFECT_FLAG_HOT_SPRINGS (1 << 18)
#define GROUND_EFFECT_FLAG_SEAWEED (1 << 19)
// Exported RAM declarations
// Exported ROM declarations
@ -95,6 +116,11 @@ u8 AddCameraObject(u8 linkedSpriteId);
void UpdateFieldObjectsForCameraUpdate(s16 x, s16 y);
u8 GetSimpleGoAnimId(u32);
u8 sub_8093514(u32);
bool8 AreZCoordsCompatible(u8, u8);
u8 ZCoordToPriority(u8);
void FieldObjectUpdateZCoord(struct MapObject *pObject);
void SetObjectSubpriorityByZCoord(u8, struct Sprite *, u8);
bool8 IsZCoordMismatchAt(u8, s16, s16);
// Exported data declarations

View File

@ -15,5 +15,8 @@ bool8 sub_8155DA0(struct MapObject *);
void sub_8155D78(struct MapObject *);
void sub_81555AC(u8, u8);
void ash(s16, s16, u16, s16);
void SetUpReflection(struct MapObject*, struct Sprite*, u8);
u32 StartFieldEffectForEventObject(u8, struct MapObject*);
u8 sub_81546C8(u8, u8, u8, s16, s16);
#endif //GUARD_FIELD_EFFECT_HELPERS_H

View File

@ -1,24 +0,0 @@
//
// Created by scott on 9/6/2017.
//
#ifndef GUARD_FIELD_GROUND_EFFECT_H
#define GUARD_FIELD_GROUND_EFFECT_H
// Exported type declarations
// Exported RAM declarations
// Exported ROM declarations
u8 ZCoordToPriority(u8);
void FieldObjectUpdateZCoord(struct MapObject *pObject);
void SetObjectSubpriorityByZCoord(u8, struct Sprite *, u8);
void InitObjectPriorityByZCoord(struct Sprite *, u8);
bool8 IsZCoordMismatchAt(u8, s16, s16);
bool8 AreZCoordsCompatible(u8, u8);
void FieldObjectUpdateSubpriority(struct MapObject *, struct Sprite *);
void DoGroundEffects_OnSpawn(struct MapObject *, struct Sprite *);
void DoGroundEffects_OnBeginStep(struct MapObject *, struct Sprite *);
void DoGroundEffects_OnFinishStep(struct MapObject *, struct Sprite *);
#endif //GUARD_FIELD_GROUND_EFFECT_H

View File

@ -14,6 +14,7 @@ int CanCameraMoveInDirection(int direction);
u16 GetBehaviorByMetatileId(u16 metatileId);
void sav1_camera_get_focus_coords(u16 *x, u16 *y);
u8 MapGridGetMetatileLayerTypeAt(s32 x, s32 y);
u8 MapGridGetZCoordAt(int x, int y);
u8 CameraMove(s32 deltaX, s32 deltaY);
void mapheader_copy_mapdata_with_padding(struct MapHeader *mapHeader);
void map_copy_with_padding(u16 *map, u16 width, u16 height);

View File

@ -1,7 +1,7 @@
#ifndef GUARD_METATILE_BEHAVIOR
#define GUARD_METATILE_BEHAVIOR
bool8 ShouldDoJumpLandingDustEffect(u8);
bool8 MetatileBehavior_IsATile(u8);
bool8 MetatileBehavior_IsEncounterTile(u8);
bool8 MetatileBehavior_IsJumpEast(u8);
bool8 MetatileBehavior_IsJumpWest(u8);

View File

@ -21,6 +21,7 @@ void sub_81D1EC0(void);
void sub_81D1D04(u8);
bool8 sub_81D1C44(u8);
void sub_81D5FB4(u16*);
bool8 sub_81D4A58(struct MapObject*);
#endif //GUARD_POKENAV_H

View File

@ -93,7 +93,6 @@ SECTIONS {
src/field_door.o(.text);
asm/field_player_avatar.o(.text);
src/event_object_movement.o(.text);
asm/field_ground_effect.o(.text);
src/event_object_movement_helpers.o(.text);
src/field_message_box.o(.text);
src/map_obj_lock.o(.text);
@ -398,7 +397,7 @@ SECTIONS {
src/field_door.o(.rodata);
data/field_player_avatar.o(.rodata);
data/event_object_movement.o(.rodata);
data/field_ground_effect.o(.rodata);
src/event_object_movement.o(.rodata);
data/map_obj_8097404.o(.rodata);
src/text_window.o(.rodata);
src/scrcmd.o(.rodata);

View File

@ -13,7 +13,6 @@
#include "event_data.h"
#include "rom_818CFC8.h"
#include "rom_81BE66C.h"
#include "field_ground_effect.h"
#include "event_object_movement_helpers.h"
#include "mauville_old_man.h"
#include "metatile_behavior.h"
@ -23,6 +22,7 @@
#include "trainer_see.h"
#include "decoration.h"
#include "event_object_movement.h"
#include "pokenav.h"
#define NUM_FIELD_MAP_OBJECT_TEMPLATES 0x51
@ -175,7 +175,7 @@ extern u8 (*const gUnknown_0850DEE8[5])(u8);
extern const s16 gUnknown_0850DFBC[3];
extern const s16 gUnknown_0850DFC2[3];
/*static*/ void FieldObjectUpdateMetatileBehaviors(struct MapObject*);
static void FieldObjectUpdateMetatileBehaviors(struct MapObject*);
/*static*/ void GetAllGroundEffectFlags_OnBeginStep(struct MapObject*, u32*);
/*static*/ void GetGroundEffectFlags_Reflection(struct MapObject*, u32*);
/*static*/ void GetGroundEffectFlags_TallGrassOnSpawn(struct MapObject*, u32*);
@ -191,6 +191,17 @@ extern const s16 gUnknown_0850DFC2[3];
/*static*/ void GetGroundEffectFlags_Ripple(struct MapObject*, u32*);
/*static*/ void GetGroundEffectFlags_Seaweed(struct MapObject*, u32*);
/*static*/ void GetGroundEffectFlags_JumpLanding(struct MapObject*, u32*);
/*static*/ u8 FieldObjectCheckForReflectiveSurface(struct MapObject*);
static u8 GetReflectionTypeByMetatileBehavior(u32);
static void InitObjectPriorityByZCoord(struct Sprite *sprite, u8 z);
static void FieldObjectUpdateSubpriority(struct MapObject*, struct Sprite*);
static void DoTracksGroundEffect_None(struct MapObject*, struct Sprite*, u8);
static void DoTracksGroundEffect_Footprints(struct MapObject*, struct Sprite*, u8);
static void DoTracksGroundEffect_BikeTireTracks(struct MapObject*, struct Sprite*, u8);
/*static*/ void DoRippleFieldEffect(struct MapObject*, struct Sprite*);
static void DoGroundEffects_OnSpawn(struct MapObject*, struct Sprite*);
static void DoGroundEffects_OnBeginStep(struct MapObject*, struct Sprite*);
static void DoGroundEffects_OnFinishStep(struct MapObject*, struct Sprite*);
// Code
@ -5174,3 +5185,712 @@ static void npc_update_obj_anim_flag(struct MapObject *mapObject, struct Sprite
GetGroundEffectFlags_Seaweed(eventObj, flags);
GetGroundEffectFlags_JumpLanding(eventObj, flags);
}
static void FieldObjectUpdateMetatileBehaviors(struct MapObject *eventObj)
{
eventObj->previousMetatileBehavior = MapGridGetMetatileBehaviorAt(eventObj->previousCoords.x, eventObj->previousCoords.y);
eventObj->currentMetatileBehavior = MapGridGetMetatileBehaviorAt(eventObj->currentCoords.x, eventObj->currentCoords.y);
}
void GetGroundEffectFlags_Reflection(struct MapObject *eventObj, u32 *flags)
{
u32 reflectionFlags[2] = { GROUND_EFFECT_FLAG_REFLECTION, GROUND_EFFECT_FLAG_ICE_REFLECTION };
u8 type = FieldObjectCheckForReflectiveSurface(eventObj);
if (type)
{
if (!eventObj->hasReflection)
{
eventObj->hasReflection = 0;
eventObj->hasReflection = 1;
*flags |= reflectionFlags[type - 1];
}
}
else
{
eventObj->hasReflection = 0;
}
}
void GetGroundEffectFlags_TallGrassOnSpawn(struct MapObject *eventObj, u32 *flags)
{
if (MetatileBehavior_IsTallGrass(eventObj->currentMetatileBehavior))
*flags |= GROUND_EFFECT_FLAG_TALL_GRASS_ON_SPAWN;
}
void GetGroundEffectFlags_TallGrassOnBeginStep(struct MapObject *eventObj, u32 *flags)
{
if (MetatileBehavior_IsTallGrass(eventObj->currentMetatileBehavior))
*flags |= GROUND_EFFECT_FLAG_TALL_GRASS_ON_MOVE;
}
void GetGroundEffectFlags_LongGrassOnSpawn(struct MapObject *eventObj, u32 *flags)
{
if (MetatileBehavior_IsLongGrass(eventObj->currentMetatileBehavior))
*flags |= GROUND_EFFECT_FLAG_LONG_GRASS_ON_SPAWN;
}
void GetGroundEffectFlags_LongGrassOnBeginStep(struct MapObject *eventObj, u32 *flags)
{
if (MetatileBehavior_IsLongGrass(eventObj->currentMetatileBehavior))
*flags |= GROUND_EFFECT_FLAG_LONG_GRASS_ON_MOVE;
}
void GetGroundEffectFlags_Tracks(struct MapObject *eventObj, u32 *flags)
{
if (MetatileBehavior_IsDeepSand(eventObj->previousMetatileBehavior))
{
*flags |= GROUND_EFFECT_FLAG_DEEP_SAND;
}
else if (MetatileBehavior_IsSandOrDeepSand(eventObj->previousMetatileBehavior)
|| MetatileBehavior_IsUnusedFootprintMetatile(eventObj->previousMetatileBehavior))
{
*flags |= GROUND_EFFECT_FLAG_SAND;
}
}
void GetGroundEffectFlags_SandHeap(struct MapObject *eventObj, u32 *flags)
{
if (MetatileBehavior_IsDeepSand(eventObj->currentMetatileBehavior)
&& MetatileBehavior_IsDeepSand(eventObj->previousMetatileBehavior))
{
if (!eventObj->inSandPile)
{
eventObj->inSandPile = 0;
eventObj->inSandPile = 1;
*flags |= GROUND_EFFECT_FLAG_SAND_PILE;
}
}
else
{
eventObj->inSandPile = 0;
}
}
void GetGroundEffectFlags_ShallowFlowingWater(struct MapObject *eventObj, u32 *flags)
{
if ((MetatileBehavior_IsShallowFlowingWater(eventObj->currentMetatileBehavior)
&& MetatileBehavior_IsShallowFlowingWater(eventObj->previousMetatileBehavior))
|| (MetatileBehavior_IsPacifidlogLog(eventObj->currentMetatileBehavior)
&& MetatileBehavior_IsPacifidlogLog(eventObj->previousMetatileBehavior)))
{
if (!eventObj->inShallowFlowingWater)
{
eventObj->inShallowFlowingWater = 0;
eventObj->inShallowFlowingWater = 1;
*flags |= GROUND_EFFECT_FLAG_SHALLOW_FLOWING_WATER;
}
}
else
{
eventObj->inShallowFlowingWater = 0;
}
}
void GetGroundEffectFlags_Puddle(struct MapObject *eventObj, u32 *flags)
{
if (MetatileBehavior_IsPuddle(eventObj->currentMetatileBehavior)
&& MetatileBehavior_IsPuddle(eventObj->previousMetatileBehavior))
{
*flags |= GROUND_EFFECT_FLAG_PUDDLE;
}
}
void GetGroundEffectFlags_Ripple(struct MapObject *eventObj, u32 *flags)
{
if (MetatileBehavior_HasRipples(eventObj->currentMetatileBehavior))
*flags |= GROUND_EFFECT_FLAG_RIPPLES;
}
void GetGroundEffectFlags_ShortGrass(struct MapObject *eventObj, u32 *flags)
{
if (MetatileBehavior_IsShortGrass(eventObj->currentMetatileBehavior)
&& MetatileBehavior_IsShortGrass(eventObj->previousMetatileBehavior))
{
if (!eventObj->inShortGrass)
{
eventObj->inShortGrass = 0;
eventObj->inShortGrass = 1;
*flags |= GROUND_EFFECT_FLAG_SHORT_GRASS;
}
}
else
{
eventObj->inShortGrass = 0;
}
}
void GetGroundEffectFlags_HotSprings(struct MapObject *eventObj, u32 *flags)
{
if (MetatileBehavior_IsHotSprings(eventObj->currentMetatileBehavior)
&& MetatileBehavior_IsHotSprings(eventObj->previousMetatileBehavior))
{
if (!eventObj->inHotSprings)
{
eventObj->inHotSprings = 0;
eventObj->inHotSprings = 1;
*flags |= GROUND_EFFECT_FLAG_HOT_SPRINGS;
}
}
else
{
eventObj->inHotSprings = 0;
}
}
void GetGroundEffectFlags_Seaweed(struct MapObject *eventObj, u32 *flags)
{
if (MetatileBehavior_IsSeaweed(eventObj->currentMetatileBehavior))
*flags |= GROUND_EFFECT_FLAG_SEAWEED;
}
void GetGroundEffectFlags_JumpLanding(struct MapObject *eventObj, u32 *flags)
{
typedef bool8 (*MetatileFunc)(u8);
static const MetatileFunc metatileFuncs[] = {
MetatileBehavior_IsTallGrass,
MetatileBehavior_IsLongGrass,
MetatileBehavior_IsPuddle,
MetatileBehavior_IsSurfableWaterOrUnderwater,
MetatileBehavior_IsShallowFlowingWater,
MetatileBehavior_IsATile,
};
static const u32 jumpLandingFlags[] = {
GROUND_EFFECT_FLAG_LAND_IN_TALL_GRASS,
GROUND_EFFECT_FLAG_LAND_IN_LONG_GRASS,
GROUND_EFFECT_FLAG_LAND_IN_SHALLOW_WATER,
GROUND_EFFECT_FLAG_LAND_IN_DEEP_WATER,
GROUND_EFFECT_FLAG_LAND_IN_SHALLOW_WATER,
GROUND_EFFECT_FLAG_LAND_ON_NORMAL_GROUND,
};
if (eventObj->landingJump && !eventObj->disableJumpLandingGroundEffect)
{
u8 i;
for (i = 0; i < ARRAY_COUNT(metatileFuncs); i++)
{
if (metatileFuncs[i](eventObj->currentMetatileBehavior))
{
*flags |= jumpLandingFlags[i];
return;
}
}
}
}
u8 FieldObjectCheckForReflectiveSurface(struct MapObject *eventObj)
{
const struct MapObjectGraphicsInfo *info = GetFieldObjectGraphicsInfo(eventObj->graphicsId);
// ceil div by tile width?
s16 width = (info->width + 8) >> 4;
s16 height = (info->height + 8) >> 4;
s16 i;
s16 j;
u8 result;
u8 b;
s16 one;
#define RETURN_REFLECTION_TYPE_AT(x, y) \
b = MapGridGetMetatileBehaviorAt(x, y); \
result = GetReflectionTypeByMetatileBehavior(b); \
if (result != 0) \
return result;
for (i = 0, one = 1; i < height; i++)
{
RETURN_REFLECTION_TYPE_AT(eventObj->currentCoords.x, eventObj->currentCoords.y + one + i)
RETURN_REFLECTION_TYPE_AT(eventObj->previousCoords.x, eventObj->previousCoords.y + one + i)
for (j = 1; j < width; j++)
{
RETURN_REFLECTION_TYPE_AT(eventObj->currentCoords.x + j, eventObj->currentCoords.y + one + i)
RETURN_REFLECTION_TYPE_AT(eventObj->currentCoords.x - j, eventObj->currentCoords.y + one + i)
RETURN_REFLECTION_TYPE_AT(eventObj->previousCoords.x + j, eventObj->previousCoords.y + one + i)
RETURN_REFLECTION_TYPE_AT(eventObj->previousCoords.x - j, eventObj->previousCoords.y + one + i)
}
}
return 0;
#undef RETURN_REFLECTION_TYPE_AT
}
static u8 GetReflectionTypeByMetatileBehavior(u32 behavior)
{
if (MetatileBehavior_IsIce(behavior))
return 1;
else if (MetatileBehavior_IsReflective(behavior))
return 2;
else
return 0;
}
u8 GetLedgeJumpDirection(s16 x, s16 y, u8 z)
{
static bool8 (*const unknown_08376040[])(u8) = {
MetatileBehavior_IsJumpSouth,
MetatileBehavior_IsJumpNorth,
MetatileBehavior_IsJumpWest,
MetatileBehavior_IsJumpEast,
};
u8 b;
u8 index = z;
if (index == 0)
return 0;
else if (index > 4)
index -= 4;
index--;
b = MapGridGetMetatileBehaviorAt(x, y);
if (unknown_08376040[index](b) == 1)
return index + 1;
return 0;
}
void FieldObjectSetSpriteOamTableForLongGrass(struct MapObject *eventObj, struct Sprite *sprite)
{
if (eventObj->disableCoveringGroundEffects)
return;
if (!MetatileBehavior_IsLongGrass(eventObj->currentMetatileBehavior))
return;
if (!MetatileBehavior_IsLongGrass(eventObj->previousMetatileBehavior))
return;
sprite->subspriteTableNum = 4;
if (ZCoordToPriority(eventObj->previousElevation) == 1)
sprite->subspriteTableNum = 5;
}
bool8 IsZCoordMismatchAt(u8 z, s16 x, s16 y)
{
u8 mapZ;
if (z == 0)
return FALSE;
mapZ = MapGridGetZCoordAt(x, y);
if (mapZ == 0 || mapZ == 0xF)
return FALSE;
if (mapZ != z)
return TRUE;
return FALSE;
}
static const u8 sUnknown_08376050[] = {
0x73, 0x73, 0x53, 0x73, 0x53, 0x73, 0x53, 0x73, 0x53, 0x73, 0x53, 0x73, 0x53, 0x00, 0x00, 0x73
};
// Each byte corresponds to a sprite priority for an event object.
// This is directly the inverse of gEventObjectPriorities_08376070.
static const u8 sEventObjectPriorities_08376060[] = {
2, 2, 2, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 0, 0, 2
};
// Each byte corresponds to a sprite priority for an event object.
// This is the inverse of gEventObjectPriorities_08376060.
// 1 = Above player sprite
// 2 = Below player sprite
static const u8 sEventObjectPriorities_08376070[] = {
1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 0, 0, 1,
};
void FieldObjectUpdateZCoordAndPriority(struct MapObject *eventObj, struct Sprite *sprite)
{
if (eventObj->fixedPriority)
return;
FieldObjectUpdateZCoord(eventObj);
sprite->subspriteTableNum = sEventObjectPriorities_08376070[eventObj->previousElevation];
sprite->oam.priority = sEventObjectPriorities_08376060[eventObj->previousElevation];
}
static void InitObjectPriorityByZCoord(struct Sprite *sprite, u8 z)
{
sprite->subspriteTableNum = sEventObjectPriorities_08376070[z];
sprite->oam.priority = sEventObjectPriorities_08376060[z];
}
u8 ZCoordToPriority(u8 z)
{
return sEventObjectPriorities_08376060[z];
}
void FieldObjectUpdateZCoord(struct MapObject *eventObj)
{
u8 z = MapGridGetZCoordAt(eventObj->currentCoords.x, eventObj->currentCoords.y);
u8 z2 = MapGridGetZCoordAt(eventObj->previousCoords.x, eventObj->previousCoords.y);
if (z == 0xF || z2 == 0xF)
return;
eventObj->currentElevation = z;
if (z != 0 && z != 0xF)
eventObj->previousElevation = z;
}
void SetObjectSubpriorityByZCoord(u8 a, struct Sprite *sprite, u8 b)
{
s32 tmp = sprite->centerToCornerVecY;
u32 tmpa = *(u16 *)&sprite->pos1.y;
u32 tmpb = *(u16 *)&gSpriteCoordOffsetY;
s32 tmp2 = (tmpa - tmp) + tmpb;
u16 tmp3 = (0x10 - ((((u32)tmp2 + 8) & 0xFF) >> 4)) * 2;
sprite->subpriority = tmp3 + sUnknown_08376050[a] + b;
}
static void FieldObjectUpdateSubpriority(struct MapObject *eventObj, struct Sprite *sprite)
{
if (eventObj->fixedPriority)
return;
SetObjectSubpriorityByZCoord(eventObj->previousElevation, sprite, 1);
}
bool8 AreZCoordsCompatible(u8 a, u8 b)
{
if (a == 0 || b == 0)
return TRUE;
if (a != b)
return FALSE;
return TRUE;
}
void GroundEffect_SpawnOnTallGrass(struct MapObject *eventObj, struct Sprite *sprite)
{
gFieldEffectArguments[0] = eventObj->currentCoords.x;
gFieldEffectArguments[1] = eventObj->currentCoords.y;
gFieldEffectArguments[2] = eventObj->previousElevation;
gFieldEffectArguments[3] = 2;
gFieldEffectArguments[4] = eventObj->localId << 8 | eventObj->mapNum;
gFieldEffectArguments[5] = eventObj->mapGroup;
gFieldEffectArguments[6] = (u8)gSaveBlock1Ptr->location.mapNum << 8 | (u8)gSaveBlock1Ptr->location.mapGroup;
gFieldEffectArguments[7] = 1;
FieldEffectStart(FLDEFF_TALL_GRASS);
}
void GroundEffect_StepOnTallGrass(struct MapObject *eventObj, struct Sprite *sprite)
{
gFieldEffectArguments[0] = eventObj->currentCoords.x;
gFieldEffectArguments[1] = eventObj->currentCoords.y;
gFieldEffectArguments[2] = eventObj->previousElevation;
gFieldEffectArguments[3] = 2;
gFieldEffectArguments[4] = eventObj->localId << 8 | eventObj->mapNum;
gFieldEffectArguments[5] = eventObj->mapGroup;
gFieldEffectArguments[6] = (u8)gSaveBlock1Ptr->location.mapNum << 8 | (u8)gSaveBlock1Ptr->location.mapGroup;
gFieldEffectArguments[7] = 0;
FieldEffectStart(FLDEFF_TALL_GRASS);
}
void GroundEffect_SpawnOnLongGrass(struct MapObject *eventObj, struct Sprite *sprite)
{
gFieldEffectArguments[0] = eventObj->currentCoords.x;
gFieldEffectArguments[1] = eventObj->currentCoords.y;
gFieldEffectArguments[2] = eventObj->previousElevation;
gFieldEffectArguments[3] = 2;
gFieldEffectArguments[4] = eventObj->localId << 8 | eventObj->mapNum;
gFieldEffectArguments[5] = eventObj->mapGroup;
gFieldEffectArguments[6] = (u8)gSaveBlock1Ptr->location.mapNum << 8 | (u8)gSaveBlock1Ptr->location.mapGroup;
gFieldEffectArguments[7] = 1;
FieldEffectStart(FLDEFF_LONG_GRASS);
}
void GroundEffect_StepOnLongGrass(struct MapObject *eventObj, struct Sprite *sprite)
{
gFieldEffectArguments[0] = eventObj->currentCoords.x;
gFieldEffectArguments[1] = eventObj->currentCoords.y;
gFieldEffectArguments[2] = eventObj->previousElevation;
gFieldEffectArguments[3] = 2;
gFieldEffectArguments[4] = (eventObj->localId << 8) | eventObj->mapNum;
gFieldEffectArguments[5] = eventObj->mapGroup;
gFieldEffectArguments[6] = (u8)gSaveBlock1Ptr->location.mapNum << 8 | (u8)gSaveBlock1Ptr->location.mapGroup;
gFieldEffectArguments[7] = 0;
FieldEffectStart(FLDEFF_LONG_GRASS);
}
void GroundEffect_WaterReflection(struct MapObject *eventObj, struct Sprite *sprite)
{
SetUpReflection(eventObj, sprite, 0);
}
void GroundEffect_IceReflection(struct MapObject *eventObj, struct Sprite *sprite)
{
SetUpReflection(eventObj, sprite, 1);
}
void GroundEffect_FlowingWater(struct MapObject *eventObj, struct Sprite *sprite)
{
StartFieldEffectForEventObject(FLDEFF_FEET_IN_FLOWING_WATER, eventObj);
}
static void (*const sGroundEffectTracksFuncs[])(struct MapObject *eventObj, struct Sprite *sprite, u8 a) = {
DoTracksGroundEffect_None,
DoTracksGroundEffect_Footprints,
DoTracksGroundEffect_BikeTireTracks,
};
void GroundEffect_SandTracks(struct MapObject *eventObj, struct Sprite *sprite)
{
const struct MapObjectGraphicsInfo *info = GetFieldObjectGraphicsInfo(eventObj->graphicsId);
sGroundEffectTracksFuncs[info->tracks](eventObj, sprite, 0);
}
void GroundEffect_DeepSandTracks(struct MapObject *eventObj, struct Sprite *sprite)
{
const struct MapObjectGraphicsInfo *info = GetFieldObjectGraphicsInfo(eventObj->graphicsId);
sGroundEffectTracksFuncs[info->tracks](eventObj, sprite, 1);
}
static void DoTracksGroundEffect_None(struct MapObject *eventObj, struct Sprite *sprite, u8 a)
{
}
static void DoTracksGroundEffect_Footprints(struct MapObject *eventObj, struct Sprite *sprite, u8 a)
{
// First half-word is a Field Effect script id. (gFieldEffectScriptPointers)
u16 sandFootprints_FieldEffectData[2] = {
FLDEFF_SAND_FOOTPRINTS,
FLDEFF_DEEP_SAND_FOOTPRINTS
};
gFieldEffectArguments[0] = eventObj->previousCoords.x;
gFieldEffectArguments[1] = eventObj->previousCoords.y;
gFieldEffectArguments[2] = 149;
gFieldEffectArguments[3] = 2;
gFieldEffectArguments[4] = eventObj->facingDirection;
FieldEffectStart(sandFootprints_FieldEffectData[a]);
}
static void DoTracksGroundEffect_BikeTireTracks(struct MapObject *eventObj, struct Sprite *sprite, u8 a)
{
// Specifies which bike track shape to show next.
// For example, when the bike turns from up to right, it will show
// a track that curves to the right.
// Each 4-byte row corresponds to the initial direction of the bike, and
// each byte in that row is for the next direction of the bike in the order
// of down, up, left, right.
static const u8 bikeTireTracks_Transitions[4][4] = {
1, 2, 7, 8,
1, 2, 6, 5,
5, 8, 3, 4,
6, 7, 3, 4,
};
if (eventObj->currentCoords.x != eventObj->previousCoords.x || eventObj->currentCoords.y != eventObj->previousCoords.y)
{
gFieldEffectArguments[0] = eventObj->previousCoords.x;
gFieldEffectArguments[1] = eventObj->previousCoords.y;
gFieldEffectArguments[2] = 149;
gFieldEffectArguments[3] = 2;
gFieldEffectArguments[4] =
bikeTireTracks_Transitions[eventObj->previousMovementDirection][eventObj->facingDirection - 5];
FieldEffectStart(FLDEFF_BIKE_TIRE_TRACKS);
}
}
void GroundEffect_Ripple(struct MapObject *eventObj, struct Sprite *sprite)
{
DoRippleFieldEffect(eventObj, sprite);
}
void GroundEffect_StepOnPuddle(struct MapObject *eventObj, struct Sprite *sprite)
{
StartFieldEffectForEventObject(FLDEFF_SPLASH, eventObj);
}
void GroundEffect_SandHeap(struct MapObject *eventObj, struct Sprite *sprite)
{
StartFieldEffectForEventObject(FLDEFF_SAND_PILE, eventObj);
}
void GroundEffect_JumpOnTallGrass(struct MapObject *eventObj, struct Sprite *sprite)
{
u8 spriteId;
gFieldEffectArguments[0] = eventObj->currentCoords.x;
gFieldEffectArguments[1] = eventObj->currentCoords.y;
gFieldEffectArguments[2] = eventObj->previousElevation;
gFieldEffectArguments[3] = 2;
FieldEffectStart(FLDEFF_JUMP_TALL_GRASS);
spriteId = sub_81546C8(
eventObj->localId, eventObj->mapNum, eventObj->mapGroup, eventObj->currentCoords.x, eventObj->currentCoords.y);
if (spriteId == MAX_SPRITES)
GroundEffect_SpawnOnTallGrass(eventObj, sprite);
}
void GroundEffect_JumpOnLongGrass(struct MapObject *eventObj, struct Sprite *sprite)
{
gFieldEffectArguments[0] = eventObj->currentCoords.x;
gFieldEffectArguments[1] = eventObj->currentCoords.y;
gFieldEffectArguments[2] = eventObj->previousElevation;
gFieldEffectArguments[3] = 2;
FieldEffectStart(FLDEFF_JUMP_LONG_GRASS);
}
void GroundEffect_JumpOnShallowWater(struct MapObject *eventObj, struct Sprite *sprite)
{
gFieldEffectArguments[0] = eventObj->currentCoords.x;
gFieldEffectArguments[1] = eventObj->currentCoords.y;
gFieldEffectArguments[2] = eventObj->previousElevation;
gFieldEffectArguments[3] = sprite->oam.priority;
FieldEffectStart(FLDEFF_JUMP_SMALL_SPLASH);
}
void GroundEffect_JumpOnWater(struct MapObject *eventObj, struct Sprite *sprite)
{
gFieldEffectArguments[0] = eventObj->currentCoords.x;
gFieldEffectArguments[1] = eventObj->currentCoords.y;
gFieldEffectArguments[2] = eventObj->previousElevation;
gFieldEffectArguments[3] = sprite->oam.priority;
FieldEffectStart(FLDEFF_JUMP_BIG_SPLASH);
}
void GroundEffect_JumpLandingDust(struct MapObject *eventObj, struct Sprite *sprite)
{
gFieldEffectArguments[0] = eventObj->currentCoords.x;
gFieldEffectArguments[1] = eventObj->currentCoords.y;
gFieldEffectArguments[2] = eventObj->previousElevation;
gFieldEffectArguments[3] = sprite->oam.priority;
FieldEffectStart(FLDEFF_DUST);
}
void GroundEffect_ShortGrass(struct MapObject *eventObj, struct Sprite *sprite)
{
StartFieldEffectForEventObject(FLDEFF_SHORT_GRASS, eventObj);
}
void GroundEffect_HotSprings(struct MapObject *eventObj, struct Sprite *sprite)
{
StartFieldEffectForEventObject(FLDEFF_HOT_SPRINGS_WATER, eventObj);
}
void GroundEffect_Seaweed(struct MapObject *eventObj, struct Sprite *sprite)
{
gFieldEffectArguments[0] = eventObj->currentCoords.x;
gFieldEffectArguments[1] = eventObj->currentCoords.y;
FieldEffectStart(FLDEFF_BUBBLES);
}
static void (*const sGroundEffectFuncs[])(struct MapObject *eventObj, struct Sprite *sprite) = {
GroundEffect_SpawnOnTallGrass,
GroundEffect_StepOnTallGrass,
GroundEffect_SpawnOnLongGrass,
GroundEffect_StepOnLongGrass,
GroundEffect_WaterReflection,
GroundEffect_IceReflection,
GroundEffect_FlowingWater,
GroundEffect_SandTracks,
GroundEffect_DeepSandTracks,
GroundEffect_Ripple,
GroundEffect_StepOnPuddle,
GroundEffect_SandHeap,
GroundEffect_JumpOnTallGrass,
GroundEffect_JumpOnLongGrass,
GroundEffect_JumpOnShallowWater,
GroundEffect_JumpOnWater,
GroundEffect_JumpLandingDust,
GroundEffect_ShortGrass,
GroundEffect_HotSprings,
GroundEffect_Seaweed
};
/*static*/ void DoFlaggedGroundEffects(struct MapObject *eventObj, struct Sprite *sprite, u32 flags)
{
u8 i;
if (FieldObjectIsFarawayIslandMew(eventObj) == TRUE && !sub_81D4A58(eventObj))
return;
for (i = 0; i < ARRAY_COUNT(sGroundEffectFuncs); i++, flags >>= 1)
if (flags & 1)
sGroundEffectFuncs[i](eventObj, sprite);
}
void filters_out_some_ground_effects(struct MapObject *eventObj, u32 *flags)
{
if (eventObj->disableCoveringGroundEffects)
{
eventObj->inShortGrass = 0;
eventObj->inSandPile = 0;
eventObj->inShallowFlowingWater = 0;
eventObj->inHotSprings = 0;
*flags &= ~(GROUND_EFFECT_FLAG_HOT_SPRINGS
| GROUND_EFFECT_FLAG_SHORT_GRASS
| GROUND_EFFECT_FLAG_SAND_PILE
| GROUND_EFFECT_FLAG_SHALLOW_FLOWING_WATER
| GROUND_EFFECT_FLAG_TALL_GRASS_ON_MOVE);
}
}
void FilterOutStepOnPuddleGroundEffectIfJumping(struct MapObject *eventObj, u32 *flags)
{
if (eventObj->landingJump)
*flags &= ~GROUND_EFFECT_FLAG_PUDDLE;
}
static void DoGroundEffects_OnSpawn(struct MapObject *eventObj, struct Sprite *sprite)
{
u32 flags;
if (eventObj->triggerGroundEffectsOnMove)
{
flags = 0;
FieldObjectUpdateZCoordAndPriority(eventObj, sprite);
GetAllGroundEffectFlags_OnSpawn(eventObj, &flags);
FieldObjectSetSpriteOamTableForLongGrass(eventObj, sprite);
DoFlaggedGroundEffects(eventObj, sprite, flags);
eventObj->triggerGroundEffectsOnMove = 0;
eventObj->disableCoveringGroundEffects = 0;
}
}
static void DoGroundEffects_OnBeginStep(struct MapObject *eventObj, struct Sprite *sprite)
{
u32 flags;
if (eventObj->triggerGroundEffectsOnMove)
{
flags = 0;
FieldObjectUpdateZCoordAndPriority(eventObj, sprite);
GetAllGroundEffectFlags_OnBeginStep(eventObj, &flags);
FieldObjectSetSpriteOamTableForLongGrass(eventObj, sprite);
filters_out_some_ground_effects(eventObj, &flags);
DoFlaggedGroundEffects(eventObj, sprite, flags);
eventObj->triggerGroundEffectsOnMove = 0;
eventObj->disableCoveringGroundEffects = 0;
}
}
static void DoGroundEffects_OnFinishStep(struct MapObject *eventObj, struct Sprite *sprite)
{
u32 flags;
if (eventObj->triggerGroundEffectsOnStop)
{
flags = 0;
FieldObjectUpdateZCoordAndPriority(eventObj, sprite);
GetAllGroundEffectFlags_OnFinishStep(eventObj, &flags);
FieldObjectSetSpriteOamTableForLongGrass(eventObj, sprite);
FilterOutStepOnPuddleGroundEffectIfJumping(eventObj, &flags);
DoFlaggedGroundEffects(eventObj, sprite, flags);
eventObj->triggerGroundEffectsOnStop = 0;
eventObj->landingJump = 0;
}
}

View File

@ -1,5 +1,4 @@
#include "global.h"
#include "field_ground_effect.h"
#include "event_object_movement.h"
#include "field_effect.h"
#include "event_object_movement_helpers.h"
@ -504,7 +503,7 @@ bool32 sub_8097D9C(u8 var)
return FALSE;
}
u32 oe_exec_and_other_stuff(u8 fieldEffectId, struct MapObject *mapObject)
u32 StartFieldEffectForEventObject(u8 fieldEffectId, struct MapObject *mapObject)
{
FieldObjectGetLocalIdAndMap(mapObject, &gFieldEffectArguments[0], &gFieldEffectArguments[1], &gFieldEffectArguments[2]);
return FieldEffectStart(fieldEffectId);
@ -515,7 +514,7 @@ void DoShadowFieldEffect(struct MapObject *mapObject)
if (!mapObject->hasShadow)
{
mapObject->hasShadow = 1;
oe_exec_and_other_stuff(FLDEFF_SHADOW, mapObject);
StartFieldEffectForEventObject(FLDEFF_SHADOW, mapObject);
}
}

View File

@ -252,8 +252,7 @@ static const u8 sTileBitAttributes[] =
TILE_ATTRIBUTES(FALSE, FALSE, FALSE), // ? 0xEF
};
// only used as default case for checking jump landing in field_ground_effect.
bool8 ShouldDoJumpLandingDustEffect(u8 var)
bool8 MetatileBehavior_IsATile(u8 var)
{
return TRUE;
}

View File

@ -10,7 +10,6 @@
#include "field_control_avatar.h"
#include "field_effect.h"
#include "field_fadetransition.h"
#include "field_ground_effect.h"
#include "event_object_movement.h"
#include "event_object_movement_helpers.h"
#include "field_message_box.h"