summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/field_ground_effect.c712
1 files changed, 690 insertions, 22 deletions
diff --git a/src/field_ground_effect.c b/src/field_ground_effect.c
index 42862d0ff..79729471c 100644
--- a/src/field_ground_effect.c
+++ b/src/field_ground_effect.c
@@ -1,9 +1,22 @@
#include "global.h"
#include "field_ground_effect.h"
+#include "field_effect.h"
+#include "field_effect_helpers.h"
+#include "field_map_obj_helpers.h"
#include "fieldmap.h"
#include "metatile_behavior.h"
extern u32 gUnknown_08376008[];
+extern u8 (*gUnknown_08376040[4])(u32 a);
+extern const u8 gFieldObjectPriorities_08376070[];
+extern const u8 gFieldObjectPriorities_08376060[];
+extern const u8 gUnknown_08376050[];
+extern void (*gUnknown_08376080[3])(struct MapObject *mapObj, struct Sprite *sprite, u8 a);
+extern const u8 gSandFootprints_FieldEffectData[4];
+extern const u8 gBikeTireTracks_Transitions[4][4];
+extern void (*gUnknown_083760A0[0x14])(struct MapObject *mapObj, struct Sprite *sprite);
+
+#define NUM_GROUND_EFFECTS (sizeof(gUnknown_083760A0) / sizeof(gUnknown_083760A0[0]))
void GetAllGroundEffectFlags_OnSpawn(struct MapObject *mapObj, u32 *flags)
{
@@ -100,8 +113,8 @@ void GetGroundEffectFlags_Tracks(struct MapObject *mapObj, u32 *flags)
{
*flags |= 0x100;
}
- else if (MetatileBehavior_IsSandOrDeepSand(mapObj->mapobj_unk_1F)
- || MetatileBehavior_IsUnusedFootprintMetatile(mapObj->mapobj_unk_1F))
+ else if (MetatileBehavior_IsSandOrDeepSand(mapObj->mapobj_unk_1F) ||
+ MetatileBehavior_IsUnusedFootprintMetatile(mapObj->mapobj_unk_1F))
{
*flags |= 0x80;
}
@@ -109,8 +122,8 @@ void GetGroundEffectFlags_Tracks(struct MapObject *mapObj, u32 *flags)
void GetGroundEffectFlags_SandPile(struct MapObject *mapObj, u32 *flags)
{
- if (MetatileBehavior_IsDeepSand(mapObj->mapobj_unk_1E)
- && MetatileBehavior_IsDeepSand(mapObj->mapobj_unk_1F))
+ if (MetatileBehavior_IsDeepSand(mapObj->mapobj_unk_1E) &&
+ MetatileBehavior_IsDeepSand(mapObj->mapobj_unk_1F))
{
if (!mapObj->mapobj_bit_20)
{
@@ -127,8 +140,10 @@ void GetGroundEffectFlags_SandPile(struct MapObject *mapObj, u32 *flags)
void GetGroundEffectFlags_ShallowFlowingWater(struct MapObject *mapObj, u32 *flags)
{
- if ((MetatileBehavior_IsShallowFlowingWater(mapObj->mapobj_unk_1E) && MetatileBehavior_IsShallowFlowingWater(mapObj->mapobj_unk_1F))
- || (MetatileBehavior_IsPacifidlogLog(mapObj->mapobj_unk_1E) && MetatileBehavior_IsPacifidlogLog(mapObj->mapobj_unk_1F)))
+ if ((MetatileBehavior_IsShallowFlowingWater(mapObj->mapobj_unk_1E) &&
+ MetatileBehavior_IsShallowFlowingWater(mapObj->mapobj_unk_1F)) ||
+ (MetatileBehavior_IsPacifidlogLog(mapObj->mapobj_unk_1E) &&
+ MetatileBehavior_IsPacifidlogLog(mapObj->mapobj_unk_1F)))
{
if (!mapObj->mapobj_bit_19)
{
@@ -145,8 +160,8 @@ void GetGroundEffectFlags_ShallowFlowingWater(struct MapObject *mapObj, u32 *fla
void GetGroundEffectFlags_Puddle(struct MapObject *mapObj, u32 *flags)
{
- if (MetatileBehavior_IsPuddle(mapObj->mapobj_unk_1E)
- && MetatileBehavior_IsPuddle(mapObj->mapobj_unk_1F))
+ if (MetatileBehavior_IsPuddle(mapObj->mapobj_unk_1E) &&
+ MetatileBehavior_IsPuddle(mapObj->mapobj_unk_1F))
{
*flags |= 0x400;
}
@@ -160,8 +175,8 @@ void GetGroundEffectFlags_Ripple(struct MapObject *mapObj, u32 *flags)
void GetGroundEffectFlags_ShortGrass(struct MapObject *mapObj, u32 *flags)
{
- if (MetatileBehavior_IsShortGrass(mapObj->mapobj_unk_1E)
- && MetatileBehavior_IsShortGrass(mapObj->mapobj_unk_1F))
+ if (MetatileBehavior_IsShortGrass(mapObj->mapobj_unk_1E) &&
+ MetatileBehavior_IsShortGrass(mapObj->mapobj_unk_1F))
{
if (!mapObj->mapobj_bit_18)
{
@@ -178,8 +193,8 @@ void GetGroundEffectFlags_ShortGrass(struct MapObject *mapObj, u32 *flags)
void GetGroundEffectFlags_HotSprings(struct MapObject *mapObj, u32 *flags)
{
- if (MetatileBehavior_IsHotSprings(mapObj->mapobj_unk_1E)
- && MetatileBehavior_IsHotSprings(mapObj->mapobj_unk_1F))
+ if (MetatileBehavior_IsHotSprings(mapObj->mapobj_unk_1E) &&
+ MetatileBehavior_IsHotSprings(mapObj->mapobj_unk_1F))
{
if (!mapObj->mapobj_bit_21)
{
@@ -204,8 +219,7 @@ void GetGroundEffectFlags_JumpLanding(struct MapObject *mapObj, u32 *flags)
{
typedef bool8 (*MetatileFunc)(u8);
- static const MetatileFunc metatileFuncs[] =
- {
+ static const MetatileFunc metatileFuncs[] = {
MetatileBehavior_IsTallGrass,
MetatileBehavior_IsLongGrass,
MetatileBehavior_IsPuddle,
@@ -214,14 +228,13 @@ void GetGroundEffectFlags_JumpLanding(struct MapObject *mapObj, u32 *flags)
MetatileBehavior_IsATile,
};
- static const u32 jumpLandingFlags[] =
- {
- 0x00001000, // Landing in tall grass
- 0x00002000, // Landing in long grass
- 0x00004000, // Landing on puddle
- 0x00008000, // Landing on surfable water or underwater
- 0x00004000, // Landing on shallow flowing water
- 0x00010000, // Landing on any other type of ground
+ static const u32 jumpLandingFlags[] = {
+ 0x00001000, // Landing in tall grass
+ 0x00002000, // Landing in long grass
+ 0x00004000, // Landing on puddle
+ 0x00008000, // Landing on surfable water or underwater
+ 0x00004000, // Landing on shallow flowing water
+ 0x00010000, // Landing on any other type of ground
};
if (mapObj->mapobj_bit_5 && !mapObj->mapobj_bit_25)
@@ -238,3 +251,658 @@ void GetGroundEffectFlags_JumpLanding(struct MapObject *mapObj, u32 *flags)
}
}
}
+
+#ifdef NONMATCHING
+u8 FieldObjectCheckForReflectiveSurface(struct MapObject *mapObj)
+{
+ const struct MapObjectGraphicsInfo *info = GetFieldObjectGraphicsInfo(mapObj->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;
+ register u32 a asm("r10");
+ register s32 aa asm("r7");
+
+ for (i = 0; i < height; i++)
+ {
+ a = 1;
+ b = MapGridGetMetatileBehaviorAt(mapObj->coords2.x, mapObj->coords2.y + a + i);
+ result = GetReflectionTypeByMetatileBehavior(b);
+
+ if (result)
+ return result;
+
+ b = MapGridGetMetatileBehaviorAt(mapObj->coords3.x, mapObj->coords3.y + a + i);
+ result = GetReflectionTypeByMetatileBehavior(b);
+
+ if (result)
+ return result;
+
+ for (j = 1; j < width; j++)
+ {
+ aa = 1;
+
+ b = MapGridGetMetatileBehaviorAt(mapObj->coords2.x + j, mapObj->coords2.y + aa + i);
+ result = GetReflectionTypeByMetatileBehavior(b);
+
+ if (result)
+ return result;
+
+ b = MapGridGetMetatileBehaviorAt(mapObj->coords2.x - j, mapObj->coords2.y + aa + i);
+ result = GetReflectionTypeByMetatileBehavior(b);
+
+ if (result)
+ return result;
+
+ b = MapGridGetMetatileBehaviorAt(mapObj->coords3.x + j, mapObj->coords3.y + aa + i);
+ result = GetReflectionTypeByMetatileBehavior(b);
+
+ if (result)
+ return result;
+
+ b = MapGridGetMetatileBehaviorAt(mapObj->coords3.x - j, mapObj->coords3.y + aa + i);
+ result = GetReflectionTypeByMetatileBehavior(b);
+
+ if (result)
+ return result;
+ }
+ }
+
+ return 0;
+}
+#else
+__attribute__((naked)) u8 FieldObjectCheckForReflectiveSurface(struct MapObject *mapObj)
+{
+ asm(".syntax unified\n\
+ push {r4-r7,lr}\n\
+ mov r7, r10\n\
+ mov r6, r9\n\
+ mov r5, r8\n\
+ push {r5-r7}\n\
+ sub sp, 0x8\n\
+ adds r5, r0, 0\n\
+ ldrb r0, [r5, 0x5]\n\
+ bl GetFieldObjectGraphicsInfo\n\
+ movs r2, 0x8\n\
+ ldrsh r1, [r0, r2]\n\
+ adds r1, 0x8\n\
+ lsls r1, 12\n\
+ lsrs r1, 16\n\
+ str r1, [sp]\n\
+ movs r1, 0xA\n\
+ ldrsh r0, [r0, r1]\n\
+ adds r0, 0x8\n\
+ lsls r0, 12\n\
+ movs r4, 0\n\
+ lsrs r2, r0, 16\n\
+ str r2, [sp, 0x4]\n\
+ asrs r0, 16\n\
+ cmp r4, r0\n\
+ blt _08063A7A\n\
+ b _08063B80\n\
+_08063A7A:\n\
+ movs r0, 0x1\n\
+ mov r10, r0\n\
+_08063A7E:\n\
+ movs r1, 0x10\n\
+ ldrsh r0, [r5, r1]\n\
+ movs r2, 0x12\n\
+ ldrsh r1, [r5, r2]\n\
+ add r1, r10\n\
+ lsls r4, 16\n\
+ asrs r6, r4, 16\n\
+ adds r1, r6\n\
+ bl MapGridGetMetatileBehaviorAt\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ bl GetReflectionTypeByMetatileBehavior\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ mov r9, r4\n\
+ cmp r0, 0\n\
+ bne _08063B82\n\
+ movs r1, 0x14\n\
+ ldrsh r0, [r5, r1]\n\
+ movs r2, 0x16\n\
+ ldrsh r1, [r5, r2]\n\
+ add r1, r10\n\
+ adds r1, r6\n\
+ bl MapGridGetMetatileBehaviorAt\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ bl GetReflectionTypeByMetatileBehavior\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ cmp r0, 0\n\
+ bne _08063B82\n\
+ movs r2, 0x1\n\
+ ldr r1, [sp]\n\
+ lsls r0, r1, 16\n\
+ asrs r1, r0, 16\n\
+ mov r8, r0\n\
+ cmp r2, r1\n\
+ bge _08063B6E\n\
+ movs r0, 0x80\n\
+ lsls r0, 9\n\
+ asrs r7, r0, 16\n\
+_08063AD8:\n\
+ movs r1, 0x10\n\
+ ldrsh r0, [r5, r1]\n\
+ lsls r1, r2, 16\n\
+ asrs r4, r1, 16\n\
+ adds r0, r4\n\
+ movs r2, 0x12\n\
+ ldrsh r1, [r5, r2]\n\
+ adds r1, r7\n\
+ adds r1, r6\n\
+ bl MapGridGetMetatileBehaviorAt\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ bl GetReflectionTypeByMetatileBehavior\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ cmp r0, 0\n\
+ bne _08063B82\n\
+ movs r1, 0x10\n\
+ ldrsh r0, [r5, r1]\n\
+ subs r0, r4\n\
+ movs r2, 0x12\n\
+ ldrsh r1, [r5, r2]\n\
+ adds r1, r7\n\
+ adds r1, r6\n\
+ bl MapGridGetMetatileBehaviorAt\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ bl GetReflectionTypeByMetatileBehavior\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ cmp r0, 0\n\
+ bne _08063B82\n\
+ movs r1, 0x14\n\
+ ldrsh r0, [r5, r1]\n\
+ adds r0, r4\n\
+ movs r2, 0x16\n\
+ ldrsh r1, [r5, r2]\n\
+ adds r1, r7\n\
+ adds r1, r6\n\
+ bl MapGridGetMetatileBehaviorAt\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ bl GetReflectionTypeByMetatileBehavior\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ cmp r0, 0\n\
+ bne _08063B82\n\
+ movs r1, 0x14\n\
+ ldrsh r0, [r5, r1]\n\
+ subs r0, r4\n\
+ movs r2, 0x16\n\
+ ldrsh r1, [r5, r2]\n\
+ adds r1, r7\n\
+ adds r1, r6\n\
+ bl MapGridGetMetatileBehaviorAt\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ bl GetReflectionTypeByMetatileBehavior\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ cmp r0, 0\n\
+ bne _08063B82\n\
+ adds r0, r4, 0x1\n\
+ lsls r0, 16\n\
+ lsrs r2, r0, 16\n\
+ cmp r0, r8\n\
+ blt _08063AD8\n\
+_08063B6E:\n\
+ movs r1, 0x80\n\
+ lsls r1, 9\n\
+ add r1, r9\n\
+ lsrs r4, r1, 16\n\
+ ldr r2, [sp, 0x4]\n\
+ lsls r0, r2, 16\n\
+ cmp r1, r0\n\
+ bge _08063B80\n\
+ b _08063A7E\n\
+_08063B80:\n\
+ movs r0, 0\n\
+_08063B82:\n\
+ add sp, 0x8\n\
+ pop {r3-r5}\n\
+ mov r8, r3\n\
+ mov r9, r4\n\
+ mov r10, r5\n\
+ pop {r4-r7}\n\
+ pop {r1}\n\
+ bx r1\n\
+.syntax divided\n");
+}
+#endif
+
+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)
+{
+ u8 b;
+ u8 index = z;
+
+ if (index == 0)
+ return 0;
+ else if (index > 4)
+ index -= 4;
+
+ index--;
+ b = MapGridGetMetatileBehaviorAt(x, y);
+
+ if (gUnknown_08376040[index](b) == 1)
+ return index + 1;
+
+ return 0;
+}
+
+void FieldObjectSetSpriteOamTableForLongGrass(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ if (mapObj->mapobj_bit_4)
+ return;
+
+ if (!MetatileBehavior_IsLongGrass(mapObj->mapobj_unk_1E))
+ return;
+
+ if (!MetatileBehavior_IsLongGrass(mapObj->mapobj_unk_1F))
+ return;
+
+ sprite->subspriteTableNum = 4;
+
+ if (ZCoordToPriority(mapObj->elevation) == 1)
+ sprite->subspriteTableNum = 5;
+}
+
+bool8 IsZCoordMismatchAt(u8 z, s16 x, s16 y)
+{
+ u8 mapZ;
+
+ if (z == 0)
+ return 0;
+
+ mapZ = MapGridGetZCoordAt(x, y);
+
+ if (mapZ == 0 || mapZ == 0xF)
+ return 0;
+
+ if (mapZ != z)
+ return 1;
+
+ return 0;
+}
+
+void FieldObjectUpdateZCoordAndPriority(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ if (mapObj->mapobj_bit_26)
+ return;
+
+ FieldObjectUpdateZCoord(mapObj);
+
+ sprite->subspriteTableNum = gFieldObjectPriorities_08376070[mapObj->elevation];
+ sprite->oam.priority = gFieldObjectPriorities_08376060[mapObj->elevation];
+}
+
+void InitObjectPriorityByZCoord(struct Sprite *sprite, u8 z)
+{
+ sprite->subspriteTableNum = gFieldObjectPriorities_08376070[z];
+ sprite->oam.priority = gFieldObjectPriorities_08376060[z];
+}
+
+u8 ZCoordToPriority(u8 z)
+{
+ return gFieldObjectPriorities_08376060[z];
+}
+
+void FieldObjectUpdateZCoord(struct MapObject *mapObj)
+{
+ u8 z = MapGridGetZCoordAt(mapObj->coords2.x, mapObj->coords2.y);
+ u8 z2 = MapGridGetZCoordAt(mapObj->coords3.x, mapObj->coords3.y);
+
+ if (z == 0xF || z2 == 0xF)
+ return;
+
+ mapObj->mapobj_unk_0B_0 = z;
+
+ if (z != 0 && z != 0xF)
+ mapObj->elevation = 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 + gUnknown_08376050[a] + b;
+}
+
+void FieldObjectUpdateSubpriority(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ if (mapObj->mapobj_bit_26)
+ return;
+
+ SetObjectSubpriorityByZCoord(mapObj->elevation, sprite, 1);
+}
+
+bool8 AreZCoordsCompatible(u8 a, u8 b)
+{
+ if (a == 0 || b == 0)
+ return TRUE;
+
+ if (a != b)
+ return FALSE;
+
+ return TRUE;
+}
+
+#define READ8(ptr, s, member) ((ptr)[offsetof(s, member)])
+
+void GroundEffect_SpawnOnTallGrass(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ u8 *ptr;
+
+ gUnknown_0202FF84[0] = mapObj->coords2.x;
+ gUnknown_0202FF84[1] = mapObj->coords2.y;
+ gUnknown_0202FF84[2] = mapObj->elevation;
+ gUnknown_0202FF84[3] = 2;
+ gUnknown_0202FF84[4] = (mapObj->localId << 8) | mapObj->mapNum;
+ gUnknown_0202FF84[5] = mapObj->mapGroup;
+
+ ptr = (u8 *)&gSaveBlock1;
+ gUnknown_0202FF84[6] = READ8(ptr, struct SaveBlock1, location.mapNum) << 8 |
+ READ8(ptr, struct SaveBlock1, location.mapGroup);
+
+ gUnknown_0202FF84[7] = 1;
+ FieldEffectStart(4);
+}
+
+void sub_8063E94(struct MapObject *mapObj)
+{
+ u8 *ptr;
+
+ gUnknown_0202FF84[0] = mapObj->coords2.x;
+ gUnknown_0202FF84[1] = mapObj->coords2.y;
+ gUnknown_0202FF84[2] = mapObj->elevation;
+ gUnknown_0202FF84[3] = 2;
+ gUnknown_0202FF84[4] = (mapObj->localId << 8) | mapObj->mapNum;
+ gUnknown_0202FF84[5] = mapObj->mapGroup;
+
+ ptr = (u8 *)&gSaveBlock1;
+ gUnknown_0202FF84[6] = READ8(ptr, struct SaveBlock1, location.mapNum) << 8 |
+ READ8(ptr, struct SaveBlock1, location.mapGroup);
+
+ gUnknown_0202FF84[7] = 0;
+ FieldEffectStart(4);
+}
+
+void sub_8063EE0(struct MapObject *mapObj)
+{
+ u8 *ptr;
+
+ gUnknown_0202FF84[0] = mapObj->coords2.x;
+ gUnknown_0202FF84[1] = mapObj->coords2.y;
+ gUnknown_0202FF84[2] = mapObj->elevation;
+ gUnknown_0202FF84[3] = 2;
+ gUnknown_0202FF84[4] = (mapObj->localId << 8) | mapObj->mapNum;
+ gUnknown_0202FF84[5] = mapObj->mapGroup;
+
+ ptr = (u8 *)&gSaveBlock1;
+ gUnknown_0202FF84[6] = READ8(ptr, struct SaveBlock1, location.mapNum) << 8 |
+ READ8(ptr, struct SaveBlock1, location.mapGroup);
+
+ gUnknown_0202FF84[7] = 1;
+ FieldEffectStart(17);
+}
+
+void sub_8063F2C(struct MapObject *mapObj)
+{
+ u8 *ptr;
+
+ gUnknown_0202FF84[0] = mapObj->coords2.x;
+ gUnknown_0202FF84[1] = mapObj->coords2.y;
+ gUnknown_0202FF84[2] = mapObj->elevation;
+ gUnknown_0202FF84[3] = 2;
+ gUnknown_0202FF84[4] = (mapObj->localId << 8) | mapObj->mapNum;
+ gUnknown_0202FF84[5] = mapObj->mapGroup;
+
+ ptr = (u8 *)&gSaveBlock1;
+ gUnknown_0202FF84[6] = READ8(ptr, struct SaveBlock1, location.mapNum) << 8 |
+ READ8(ptr, struct SaveBlock1, location.mapGroup);
+
+ gUnknown_0202FF84[7] = 0;
+ FieldEffectStart(17);
+}
+
+void GroundEffect_WaterReflection(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ SetUpReflection(mapObj, sprite, 0);
+}
+
+void GroundEffect_IceReflection(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ SetUpReflection(mapObj, sprite, 1);
+}
+
+void GroundEffect_FlowingWater(struct MapObject *mapObj)
+{
+ oe_exec_and_other_stuff(FLDEFF_FEET_IN_FLOWING_WATER, mapObj);
+}
+
+void sub_8063FA0(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ const struct MapObjectGraphicsInfo *info = GetFieldObjectGraphicsInfo(mapObj->graphicsId);
+ gUnknown_08376080[info->tracks](mapObj, sprite, 0);
+}
+
+void sub_8063FCC(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ const struct MapObjectGraphicsInfo *info = GetFieldObjectGraphicsInfo(mapObj->graphicsId);
+ gUnknown_08376080[info->tracks](mapObj, sprite, 1);
+}
+
+void nullsub_50(struct MapObject *mapObj, struct Sprite *sprite, u8 a)
+{
+}
+
+void DoTracksGroundEffect_Footprints(struct MapObject *mapObj, struct Sprite *sprite, u8 a)
+{
+ u16 buf[2];
+ memcpy(&buf, gSandFootprints_FieldEffectData, sizeof(gSandFootprints_FieldEffectData));
+ gUnknown_0202FF84[0] = mapObj->coords3.x;
+ gUnknown_0202FF84[1] = mapObj->coords3.y;
+ gUnknown_0202FF84[2] = 149;
+ gUnknown_0202FF84[3] = 2;
+ gUnknown_0202FF84[4] = mapObj->mapobj_unk_18;
+ FieldEffectStart(buf[a]);
+}
+
+void DoTracksGroundEffect_BikeTireTracks(struct MapObject *mapObj, struct Sprite *sprite, u8 a)
+{
+ if (mapObj->coords2.x != mapObj->coords3.x || mapObj->coords2.y != mapObj->coords3.y)
+ {
+ gUnknown_0202FF84[0] = mapObj->coords3.x;
+ gUnknown_0202FF84[1] = mapObj->coords3.y;
+ gUnknown_0202FF84[2] = 149;
+ gUnknown_0202FF84[3] = 2;
+ gUnknown_0202FF84[4] =
+ gBikeTireTracks_Transitions[mapObj->mapobj_unk_20][mapObj->mapobj_unk_18 - 5];
+ FieldEffectStart(FLDEFF_BIKE_TIRE_TRACKS);
+ }
+}
+
+void GroundEffect_Ripple(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ DoRippleFieldEffect(mapObj, sprite);
+}
+
+void GroundEffect_StepOnPuddle(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ oe_exec_and_other_stuff(FLDEFF_SPLASH, mapObj);
+}
+
+void GroundEffect_SandPile(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ oe_exec_and_other_stuff(FLDEFF_SAND_PILE, mapObj);
+}
+
+void GroundEffect_JumpOnTallGrass(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ u8 spriteId;
+
+ gUnknown_0202FF84[0] = mapObj->coords2.x;
+ gUnknown_0202FF84[1] = mapObj->coords2.y;
+ gUnknown_0202FF84[2] = mapObj->elevation;
+ gUnknown_0202FF84[3] = 2;
+ FieldEffectStart(FLDEFF_JUMP_TALL_GRASS);
+
+ spriteId = sub_8126FF0(
+ mapObj->localId, mapObj->mapNum, mapObj->mapGroup, mapObj->coords2.x, mapObj->coords2.y);
+
+ if (spriteId == MAX_SPRITES)
+ GroundEffect_SpawnOnTallGrass(mapObj, sprite);
+}
+
+void GroundEffect_JumpOnLongGrass(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ gUnknown_0202FF84[0] = mapObj->coords2.x;
+ gUnknown_0202FF84[1] = mapObj->coords2.y;
+ gUnknown_0202FF84[2] = mapObj->elevation;
+ gUnknown_0202FF84[3] = 2;
+ FieldEffectStart(FLDEFF_JUMP_LONG_GRASS);
+}
+
+void GroundEffect_JumpOnShallowWater(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ gUnknown_0202FF84[0] = mapObj->coords2.x;
+ gUnknown_0202FF84[1] = mapObj->coords2.y;
+ gUnknown_0202FF84[2] = mapObj->elevation;
+ gUnknown_0202FF84[3] = sprite->oam.priority;
+ FieldEffectStart(FLDEFF_JUMP_SMALL_SPLASH);
+}
+
+void GroundEffect_JumpOnWater(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ gUnknown_0202FF84[0] = mapObj->coords2.x;
+ gUnknown_0202FF84[1] = mapObj->coords2.y;
+ gUnknown_0202FF84[2] = mapObj->elevation;
+ gUnknown_0202FF84[3] = sprite->oam.priority;
+ FieldEffectStart(FLDEFF_JUMP_BIG_SPLASH);
+}
+
+void GroundEffect_JumpLandingDust(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ gUnknown_0202FF84[0] = mapObj->coords2.x;
+ gUnknown_0202FF84[1] = mapObj->coords2.y;
+ gUnknown_0202FF84[2] = mapObj->elevation;
+ gUnknown_0202FF84[3] = sprite->oam.priority;
+ FieldEffectStart(FLDEFF_DUST);
+}
+
+void GroundEffect_ShortGrass(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ oe_exec_and_other_stuff(FLDEFF_SHORT_GRASS, mapObj);
+}
+
+void GroundEffect_HotSprings(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ oe_exec_and_other_stuff(FLDEFF_HOT_SPRINGS_WATER, mapObj);
+}
+
+void GroundEffect_Seaweed(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ gUnknown_0202FF84[0] = mapObj->coords2.x;
+ gUnknown_0202FF84[1] = mapObj->coords2.y;
+ FieldEffectStart(FLDEFF_BUBBLES);
+}
+
+void sub_8064218(struct MapObject *mapObj, struct Sprite *sprite, u32 flags)
+{
+ u8 i;
+ for (i = 0; i < NUM_GROUND_EFFECTS; i++, flags >>= 1)
+ if (flags & 1)
+ gUnknown_083760A0[i](mapObj, sprite);
+}
+
+void filters_out_some_ground_effects(struct MapObject *mapObj, u32 *flags)
+{
+ if (mapObj->mapobj_bit_4)
+ {
+ mapObj->mapobj_bit_18 = 0;
+ mapObj->mapobj_bit_20 = 0;
+ mapObj->mapobj_bit_19 = 0;
+ mapObj->mapobj_bit_21 = 0;
+ *flags &= 0xFFF9F7BD;
+ }
+}
+
+void FilterOutStepOnPuddleGroundEffectIfJumping(struct MapObject *mapObj, u32 *flags)
+{
+ if (mapObj->mapobj_bit_5)
+ *flags &= 0xFFFFFBFF;
+}
+
+void DoGroundEffects_OnSpawn(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ u32 flags;
+
+ if (mapObj->mapobj_bit_2)
+ {
+ flags = 0;
+ FieldObjectUpdateZCoordAndPriority(mapObj, sprite);
+ GetAllGroundEffectFlags_OnSpawn(mapObj, &flags);
+ FieldObjectSetSpriteOamTableForLongGrass(mapObj, sprite);
+ sub_8064218(mapObj, sprite, flags);
+ mapObj->mapobj_bit_2 = 0;
+ mapObj->mapobj_bit_4 = 0;
+ }
+}
+
+void DoGroundEffects_OnBeginStep(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ u32 flags;
+
+ if (mapObj->mapobj_bit_2)
+ {
+ flags = 0;
+ FieldObjectUpdateZCoordAndPriority(mapObj, sprite);
+ GetAllGroundEffectFlags_OnBeginStep(mapObj, &flags);
+ FieldObjectSetSpriteOamTableForLongGrass(mapObj, sprite);
+ filters_out_some_ground_effects(mapObj, &flags);
+ sub_8064218(mapObj, sprite, flags);
+ mapObj->mapobj_bit_2 = 0;
+ mapObj->mapobj_bit_4 = 0;
+ }
+}
+
+void DoGroundEffects_OnFinishStep(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ u32 flags;
+
+ if (mapObj->mapobj_bit_3)
+ {
+ flags = 0;
+ FieldObjectUpdateZCoordAndPriority(mapObj, sprite);
+ GetAllGroundEffectFlags_OnFinishStep(mapObj, &flags);
+ FieldObjectSetSpriteOamTableForLongGrass(mapObj, sprite);
+ FilterOutStepOnPuddleGroundEffectIfJumping(mapObj, &flags);
+ sub_8064218(mapObj, sprite, flags);
+ mapObj->mapobj_bit_3 = 0;
+ mapObj->mapobj_bit_5 = 0;
+ }
+}