2019-03-22 20:16:26 +01:00
|
|
|
#include "global.h"
|
|
|
|
#include "event_data.h"
|
|
|
|
#include "event_object_movement.h"
|
|
|
|
#include "field_weather.h"
|
|
|
|
#include "fieldmap.h"
|
|
|
|
#include "metatile_behavior.h"
|
|
|
|
#include "sprite.h"
|
|
|
|
#include "constants/event_objects.h"
|
2020-06-20 01:58:56 +02:00
|
|
|
#include "constants/field_effects.h"
|
2019-03-22 20:16:26 +01:00
|
|
|
#include "constants/metatile_behaviors.h"
|
|
|
|
|
2020-07-19 20:12:38 +02:00
|
|
|
static u8 GetValidMewMoveDirection(u8);
|
|
|
|
static bool8 ShouldMewMoveNorth(struct ObjectEvent*, u8);
|
|
|
|
static bool8 ShouldMewMoveSouth(struct ObjectEvent*, u8);
|
|
|
|
static bool8 ShouldMewMoveEast(struct ObjectEvent*, u8);
|
|
|
|
static bool8 ShouldMewMoveWest(struct ObjectEvent*, u8);
|
|
|
|
static u8 GetRandomMewDirectionCandidate(u8);
|
|
|
|
static bool8 CanMewMoveToCoords(s16, s16);
|
2019-03-22 20:16:26 +01:00
|
|
|
|
2020-07-19 20:12:38 +02:00
|
|
|
static EWRAM_DATA u8 sGrassSpriteId = 0;
|
2019-03-31 21:09:40 +02:00
|
|
|
|
|
|
|
static s16 sPlayerToMewDeltaX;
|
|
|
|
static s16 sPlayerToMewDeltaY;
|
|
|
|
static u8 sMewDirectionCandidates[4];
|
2019-03-22 20:16:26 +01:00
|
|
|
|
2020-07-02 10:59:52 +02:00
|
|
|
extern const struct SpritePalette gSpritePalette_GeneralFieldEffect1;
|
2019-03-22 20:16:26 +01:00
|
|
|
extern const struct SpriteTemplate *const gFieldEffectObjectTemplatePointers[];
|
|
|
|
|
|
|
|
static const s16 sFarawayIslandRockCoords[4][2] =
|
|
|
|
{
|
2021-10-09 18:12:18 +02:00
|
|
|
{14 + MAP_OFFSET, 9 + MAP_OFFSET},
|
|
|
|
{18 + MAP_OFFSET, 9 + MAP_OFFSET},
|
|
|
|
{ 9 + MAP_OFFSET, 10 + MAP_OFFSET},
|
|
|
|
{13 + MAP_OFFSET, 13 + MAP_OFFSET},
|
2019-03-22 20:16:26 +01:00
|
|
|
};
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
static u8 GetMewObjectEventId(void)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
u8 objectEventId;
|
2021-07-05 19:54:43 +02:00
|
|
|
TryGetObjectEventIdByLocalIdAndMap(LOCALID_FARAWAY_ISLAND_MEW, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, &objectEventId);
|
2019-11-21 04:55:44 +01:00
|
|
|
return objectEventId;
|
2019-03-22 20:16:26 +01:00
|
|
|
}
|
|
|
|
|
2020-07-19 20:12:38 +02:00
|
|
|
// When the player enters Faraway Island interior it begins a "hide and seek" minigame where Mew disappears into the grass
|
|
|
|
// This function returns the direction Mew will take a step, and is run every time the player takes a step
|
2019-03-31 21:09:40 +02:00
|
|
|
u32 GetMewMoveDirection(void)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
|
|
|
u8 i;
|
2020-07-19 20:12:38 +02:00
|
|
|
int mewSafeFromTrap;
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *mew = &gObjectEvents[GetMewObjectEventId()];
|
2019-03-22 20:16:26 +01:00
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
sPlayerToMewDeltaX = gObjectEvents[gPlayerAvatar.objectEventId].previousCoords.x - mew->currentCoords.x;
|
|
|
|
sPlayerToMewDeltaY = gObjectEvents[gPlayerAvatar.objectEventId].previousCoords.y - mew->currentCoords.y;
|
2019-03-31 21:09:40 +02:00
|
|
|
for (i = 0; i < ARRAY_COUNT(sMewDirectionCandidates); i++)
|
|
|
|
sMewDirectionCandidates[i] = DIR_NONE;
|
2019-03-22 20:16:26 +01:00
|
|
|
|
2020-07-19 20:12:38 +02:00
|
|
|
// Player hasn't moved (just facing new direction), don't move
|
2019-11-21 04:55:44 +01:00
|
|
|
if (gObjectEvents[gPlayerAvatar.objectEventId].previousCoords.x == gObjectEvents[gPlayerAvatar.objectEventId].currentCoords.x
|
|
|
|
&& gObjectEvents[gPlayerAvatar.objectEventId].previousCoords.y == gObjectEvents[gPlayerAvatar.objectEventId].currentCoords.y)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
|
|
|
return DIR_NONE;
|
|
|
|
}
|
|
|
|
|
2020-07-19 20:12:38 +02:00
|
|
|
// Mew is invisible except for every 8th step
|
2019-03-22 20:16:26 +01:00
|
|
|
if (VarGet(VAR_FARAWAY_ISLAND_STEP_COUNTER) % 8 == 0)
|
2020-07-19 20:12:38 +02:00
|
|
|
mew->invisible = FALSE;
|
2019-03-22 20:16:26 +01:00
|
|
|
else
|
2020-07-19 20:12:38 +02:00
|
|
|
mew->invisible = TRUE;
|
2019-03-22 20:16:26 +01:00
|
|
|
|
2020-07-19 20:12:38 +02:00
|
|
|
// Mew will stay in place for 1 step after its visible
|
2019-03-22 20:16:26 +01:00
|
|
|
if (VarGet(VAR_FARAWAY_ISLAND_STEP_COUNTER) % 9 == 0)
|
|
|
|
return DIR_NONE;
|
|
|
|
|
2020-07-19 20:12:38 +02:00
|
|
|
// Below loop is for Mew to try to avoid getting trapped between the player and a rock
|
2019-03-22 20:16:26 +01:00
|
|
|
for (i = 0; i < ARRAY_COUNT(sFarawayIslandRockCoords); i++)
|
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
if (gObjectEvents[gPlayerAvatar.objectEventId].previousCoords.x == sFarawayIslandRockCoords[i][0])
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2020-07-19 20:12:38 +02:00
|
|
|
mewSafeFromTrap = FALSE;
|
2019-11-21 04:55:44 +01:00
|
|
|
if (gObjectEvents[gPlayerAvatar.objectEventId].previousCoords.y < sFarawayIslandRockCoords[i][1])
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
|
|
|
if (mew->currentCoords.y <= sFarawayIslandRockCoords[i][1])
|
2020-07-19 20:12:38 +02:00
|
|
|
mewSafeFromTrap = TRUE;
|
2019-03-22 20:16:26 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (mew->currentCoords.y >= sFarawayIslandRockCoords[i][1])
|
2020-07-19 20:12:38 +02:00
|
|
|
mewSafeFromTrap = TRUE;
|
2019-03-22 20:16:26 +01:00
|
|
|
}
|
|
|
|
|
2020-07-19 20:12:38 +02:00
|
|
|
if (!mewSafeFromTrap)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2019-03-31 21:09:40 +02:00
|
|
|
if (sPlayerToMewDeltaX > 0)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
if (mew->currentCoords.x + 1 == gObjectEvents[gPlayerAvatar.objectEventId].previousCoords.x)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2020-07-19 20:12:38 +02:00
|
|
|
if (CanMewMoveToCoords(mew->currentCoords.x + 1, mew->currentCoords.y))
|
2019-03-22 20:16:26 +01:00
|
|
|
return DIR_EAST;
|
|
|
|
}
|
|
|
|
}
|
2019-03-31 21:09:40 +02:00
|
|
|
else if (sPlayerToMewDeltaX < 0)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
if (mew->currentCoords.x - 1 == gObjectEvents[gPlayerAvatar.objectEventId].previousCoords.x)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2020-07-19 20:12:38 +02:00
|
|
|
if (CanMewMoveToCoords(mew->currentCoords.x - 1, mew->currentCoords.y))
|
2019-03-22 20:16:26 +01:00
|
|
|
return DIR_WEST;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
if (mew->currentCoords.x == gObjectEvents[gPlayerAvatar.objectEventId].previousCoords.x)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2019-03-31 21:09:40 +02:00
|
|
|
if (sPlayerToMewDeltaY > 0)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2020-07-19 20:12:38 +02:00
|
|
|
if (CanMewMoveToCoords(mew->currentCoords.x, mew->currentCoords.y - 1))
|
2019-03-22 20:16:26 +01:00
|
|
|
return DIR_NORTH;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-07-19 20:12:38 +02:00
|
|
|
if (CanMewMoveToCoords(mew->currentCoords.x, mew->currentCoords.y + 1))
|
2019-03-22 20:16:26 +01:00
|
|
|
return DIR_SOUTH;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
if (gObjectEvents[gPlayerAvatar.objectEventId].previousCoords.y == sFarawayIslandRockCoords[i][1])
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2020-07-19 20:12:38 +02:00
|
|
|
mewSafeFromTrap = FALSE;
|
2019-11-21 04:55:44 +01:00
|
|
|
if (gObjectEvents[gPlayerAvatar.objectEventId].previousCoords.x < sFarawayIslandRockCoords[i][0])
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
|
|
|
if (mew->currentCoords.x <= sFarawayIslandRockCoords[i][0])
|
2020-07-19 20:12:38 +02:00
|
|
|
mewSafeFromTrap = TRUE;
|
2019-03-22 20:16:26 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (mew->currentCoords.x >= sFarawayIslandRockCoords[i][0])
|
2020-07-19 20:12:38 +02:00
|
|
|
mewSafeFromTrap = TRUE;
|
2019-03-22 20:16:26 +01:00
|
|
|
}
|
|
|
|
|
2020-07-19 20:12:38 +02:00
|
|
|
if (!mewSafeFromTrap)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2019-03-31 21:09:40 +02:00
|
|
|
if (sPlayerToMewDeltaY > 0)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
if (mew->currentCoords.y + 1 == gObjectEvents[gPlayerAvatar.objectEventId].previousCoords.y)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2020-07-19 20:12:38 +02:00
|
|
|
if (CanMewMoveToCoords(mew->currentCoords.x, mew->currentCoords.y + 1))
|
2019-03-22 20:16:26 +01:00
|
|
|
return DIR_SOUTH;
|
|
|
|
}
|
|
|
|
}
|
2019-03-31 21:09:40 +02:00
|
|
|
else if (sPlayerToMewDeltaY < 0)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
if (mew->currentCoords.y - 1 == gObjectEvents[gPlayerAvatar.objectEventId].previousCoords.y)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2020-07-19 20:12:38 +02:00
|
|
|
if (CanMewMoveToCoords(mew->currentCoords.x, mew->currentCoords.y - 1))
|
2019-03-22 20:16:26 +01:00
|
|
|
return DIR_NORTH;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
if (mew->currentCoords.y == gObjectEvents[gPlayerAvatar.objectEventId].previousCoords.y)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2019-03-31 21:09:40 +02:00
|
|
|
if (sPlayerToMewDeltaX > 0)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2020-07-19 20:12:38 +02:00
|
|
|
if (CanMewMoveToCoords(mew->currentCoords.x - 1, mew->currentCoords.y))
|
2019-03-22 20:16:26 +01:00
|
|
|
return DIR_WEST;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-07-19 20:12:38 +02:00
|
|
|
if (CanMewMoveToCoords(mew->currentCoords.x + 1, mew->currentCoords.y))
|
2019-03-22 20:16:26 +01:00
|
|
|
return DIR_EAST;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-19 20:12:38 +02:00
|
|
|
// Check if Mew can move in any direction without getting closer to the player
|
|
|
|
// If so load into sMewDirectionCandidates
|
|
|
|
// If Mew can move in two of the checked directions, choose one randomly
|
|
|
|
if (ShouldMewMoveNorth(mew, 0))
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2020-07-19 20:12:38 +02:00
|
|
|
if (ShouldMewMoveEast(mew, 1))
|
|
|
|
return GetRandomMewDirectionCandidate(2);
|
Undo PokeCodec's PRs
This commit undoes most of PokeCodec's PRs after the debate in chat. Some
harmless or completely superseded PRs have been left alone, as there is not
much benefit in attempting to undo them.
Reverts #1104, #1108, #1115, #1118, #1119, #1124, #1126, #1127, #1132, #1136,
#1137, #1139, #1140, #1144, #1148, #1149, #1150, #1153, #1155, #1177, #1179,
#1180, #1181, #1182 and #1183.
2020-09-13 09:22:50 +02:00
|
|
|
else if (ShouldMewMoveWest(mew, 1))
|
2020-07-19 20:12:38 +02:00
|
|
|
return GetRandomMewDirectionCandidate(2);
|
Undo PokeCodec's PRs
This commit undoes most of PokeCodec's PRs after the debate in chat. Some
harmless or completely superseded PRs have been left alone, as there is not
much benefit in attempting to undo them.
Reverts #1104, #1108, #1115, #1118, #1119, #1124, #1126, #1127, #1132, #1136,
#1137, #1139, #1140, #1144, #1148, #1149, #1150, #1153, #1155, #1177, #1179,
#1180, #1181, #1182 and #1183.
2020-09-13 09:22:50 +02:00
|
|
|
else
|
|
|
|
return DIR_NORTH;
|
2019-03-22 20:16:26 +01:00
|
|
|
}
|
|
|
|
|
2020-07-19 20:12:38 +02:00
|
|
|
if (ShouldMewMoveSouth(mew, 0))
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2020-07-19 20:12:38 +02:00
|
|
|
if (ShouldMewMoveEast(mew, 1))
|
|
|
|
return GetRandomMewDirectionCandidate(2);
|
Undo PokeCodec's PRs
This commit undoes most of PokeCodec's PRs after the debate in chat. Some
harmless or completely superseded PRs have been left alone, as there is not
much benefit in attempting to undo them.
Reverts #1104, #1108, #1115, #1118, #1119, #1124, #1126, #1127, #1132, #1136,
#1137, #1139, #1140, #1144, #1148, #1149, #1150, #1153, #1155, #1177, #1179,
#1180, #1181, #1182 and #1183.
2020-09-13 09:22:50 +02:00
|
|
|
else if (ShouldMewMoveWest(mew, 1))
|
2020-07-19 20:12:38 +02:00
|
|
|
return GetRandomMewDirectionCandidate(2);
|
Undo PokeCodec's PRs
This commit undoes most of PokeCodec's PRs after the debate in chat. Some
harmless or completely superseded PRs have been left alone, as there is not
much benefit in attempting to undo them.
Reverts #1104, #1108, #1115, #1118, #1119, #1124, #1126, #1127, #1132, #1136,
#1137, #1139, #1140, #1144, #1148, #1149, #1150, #1153, #1155, #1177, #1179,
#1180, #1181, #1182 and #1183.
2020-09-13 09:22:50 +02:00
|
|
|
else
|
|
|
|
return DIR_SOUTH;
|
2019-03-22 20:16:26 +01:00
|
|
|
}
|
|
|
|
|
2020-07-19 20:12:38 +02:00
|
|
|
if (ShouldMewMoveEast(mew, 0))
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2020-07-19 20:12:38 +02:00
|
|
|
if (ShouldMewMoveNorth(mew, 1))
|
|
|
|
return GetRandomMewDirectionCandidate(2);
|
Undo PokeCodec's PRs
This commit undoes most of PokeCodec's PRs after the debate in chat. Some
harmless or completely superseded PRs have been left alone, as there is not
much benefit in attempting to undo them.
Reverts #1104, #1108, #1115, #1118, #1119, #1124, #1126, #1127, #1132, #1136,
#1137, #1139, #1140, #1144, #1148, #1149, #1150, #1153, #1155, #1177, #1179,
#1180, #1181, #1182 and #1183.
2020-09-13 09:22:50 +02:00
|
|
|
else if (ShouldMewMoveSouth(mew, 1))
|
2020-07-19 20:12:38 +02:00
|
|
|
return GetRandomMewDirectionCandidate(2);
|
Undo PokeCodec's PRs
This commit undoes most of PokeCodec's PRs after the debate in chat. Some
harmless or completely superseded PRs have been left alone, as there is not
much benefit in attempting to undo them.
Reverts #1104, #1108, #1115, #1118, #1119, #1124, #1126, #1127, #1132, #1136,
#1137, #1139, #1140, #1144, #1148, #1149, #1150, #1153, #1155, #1177, #1179,
#1180, #1181, #1182 and #1183.
2020-09-13 09:22:50 +02:00
|
|
|
else
|
|
|
|
return DIR_EAST;
|
2019-03-22 20:16:26 +01:00
|
|
|
}
|
|
|
|
|
2020-07-19 20:12:38 +02:00
|
|
|
if (ShouldMewMoveWest(mew, 0))
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2020-07-19 20:12:38 +02:00
|
|
|
if (ShouldMewMoveNorth(mew, 1))
|
|
|
|
return GetRandomMewDirectionCandidate(2);
|
Undo PokeCodec's PRs
This commit undoes most of PokeCodec's PRs after the debate in chat. Some
harmless or completely superseded PRs have been left alone, as there is not
much benefit in attempting to undo them.
Reverts #1104, #1108, #1115, #1118, #1119, #1124, #1126, #1127, #1132, #1136,
#1137, #1139, #1140, #1144, #1148, #1149, #1150, #1153, #1155, #1177, #1179,
#1180, #1181, #1182 and #1183.
2020-09-13 09:22:50 +02:00
|
|
|
else if (ShouldMewMoveSouth(mew, 1))
|
2020-07-19 20:12:38 +02:00
|
|
|
return GetRandomMewDirectionCandidate(2);
|
Undo PokeCodec's PRs
This commit undoes most of PokeCodec's PRs after the debate in chat. Some
harmless or completely superseded PRs have been left alone, as there is not
much benefit in attempting to undo them.
Reverts #1104, #1108, #1115, #1118, #1119, #1124, #1126, #1127, #1132, #1136,
#1137, #1139, #1140, #1144, #1148, #1149, #1150, #1153, #1155, #1177, #1179,
#1180, #1181, #1182 and #1183.
2020-09-13 09:22:50 +02:00
|
|
|
else
|
|
|
|
return DIR_WEST;
|
2019-03-22 20:16:26 +01:00
|
|
|
}
|
|
|
|
|
2020-07-19 20:12:38 +02:00
|
|
|
// If this point is reached, Mew cannot move without getting closer to the player
|
|
|
|
|
|
|
|
// Avoid player on same Y, try move North/South
|
2019-03-31 21:09:40 +02:00
|
|
|
if (sPlayerToMewDeltaY == 0)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
if (gObjectEvents[gPlayerAvatar.objectEventId].currentCoords.y > mew->currentCoords.y)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2020-07-19 20:12:38 +02:00
|
|
|
if (CanMewMoveToCoords(mew->currentCoords.x, mew->currentCoords.y - 1))
|
2019-03-22 20:16:26 +01:00
|
|
|
return DIR_NORTH;
|
|
|
|
}
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
if (gObjectEvents[gPlayerAvatar.objectEventId].currentCoords.y < mew->currentCoords.y)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2020-07-19 20:12:38 +02:00
|
|
|
if (CanMewMoveToCoords(mew->currentCoords.x, mew->currentCoords.y + 1))
|
2019-03-22 20:16:26 +01:00
|
|
|
return DIR_SOUTH;
|
|
|
|
}
|
|
|
|
|
2020-07-19 20:12:38 +02:00
|
|
|
if (CanMewMoveToCoords(mew->currentCoords.x, mew->currentCoords.y - 1))
|
2019-03-22 20:16:26 +01:00
|
|
|
return DIR_NORTH;
|
|
|
|
|
2020-07-19 20:12:38 +02:00
|
|
|
if (CanMewMoveToCoords(mew->currentCoords.x, mew->currentCoords.y + 1))
|
2019-03-22 20:16:26 +01:00
|
|
|
return DIR_SOUTH;
|
|
|
|
}
|
|
|
|
|
2020-07-19 20:12:38 +02:00
|
|
|
// Avoid player on same X, try move West/East
|
2019-03-31 21:09:40 +02:00
|
|
|
if (sPlayerToMewDeltaX == 0)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
if (gObjectEvents[gPlayerAvatar.objectEventId].currentCoords.x > mew->currentCoords.x)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2020-07-19 20:12:38 +02:00
|
|
|
if (CanMewMoveToCoords(mew->currentCoords.x - 1, mew->currentCoords.y))
|
2019-03-22 20:16:26 +01:00
|
|
|
return DIR_WEST;
|
|
|
|
}
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
if (gObjectEvents[gPlayerAvatar.objectEventId].currentCoords.x < mew->currentCoords.x)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2020-07-19 20:12:38 +02:00
|
|
|
if (CanMewMoveToCoords(mew->currentCoords.x + 1, mew->currentCoords.y))
|
2019-03-22 20:16:26 +01:00
|
|
|
return DIR_EAST;
|
|
|
|
}
|
|
|
|
|
2020-07-19 20:12:38 +02:00
|
|
|
if (CanMewMoveToCoords(mew->currentCoords.x + 1, mew->currentCoords.y))
|
2019-03-22 20:16:26 +01:00
|
|
|
return DIR_EAST;
|
|
|
|
|
2020-07-19 20:12:38 +02:00
|
|
|
if (CanMewMoveToCoords(mew->currentCoords.x - 1, mew->currentCoords.y))
|
2019-03-22 20:16:26 +01:00
|
|
|
return DIR_WEST;
|
|
|
|
}
|
|
|
|
|
2020-07-19 20:12:38 +02:00
|
|
|
// Can't avoid player on axis, move any valid direction
|
|
|
|
return GetValidMewMoveDirection(DIR_NONE);
|
2019-03-22 20:16:26 +01:00
|
|
|
}
|
|
|
|
|
2020-07-19 20:12:38 +02:00
|
|
|
// Mew can move to any Tall/Long Grass metatile the player isn't currently on
|
|
|
|
static bool8 CanMewMoveToCoords(s16 x, s16 y)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
if (gObjectEvents[gPlayerAvatar.objectEventId].currentCoords.x == x
|
|
|
|
&& gObjectEvents[gPlayerAvatar.objectEventId].currentCoords.y == y)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return MetatileBehavior_IsPokeGrass(MapGridGetMetatileBehaviorAt(x, y));
|
|
|
|
}
|
|
|
|
|
2020-07-19 20:12:38 +02:00
|
|
|
// Last ditch effort to move, clear move candidates and try all directions again
|
|
|
|
static u8 GetValidMewMoveDirection(u8 ignoredDir)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
|
|
|
u8 i;
|
|
|
|
u8 count = 0;
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *mew = &gObjectEvents[GetMewObjectEventId()];
|
2019-03-22 20:16:26 +01:00
|
|
|
|
2019-03-31 21:09:40 +02:00
|
|
|
for (i = 0; i < ARRAY_COUNT(sMewDirectionCandidates); i++)
|
|
|
|
sMewDirectionCandidates[i] = DIR_NONE;
|
2019-03-22 20:16:26 +01:00
|
|
|
|
2020-07-19 20:12:38 +02:00
|
|
|
if (CanMewMoveToCoords(mew->currentCoords.x, mew->currentCoords.y - 1) == TRUE && ignoredDir != DIR_NORTH)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2019-03-31 21:09:40 +02:00
|
|
|
sMewDirectionCandidates[count] = DIR_NORTH;
|
2019-03-22 20:16:26 +01:00
|
|
|
count++;
|
|
|
|
}
|
|
|
|
|
2020-07-19 20:12:38 +02:00
|
|
|
if (CanMewMoveToCoords(mew->currentCoords.x + 1, mew->currentCoords.y) == TRUE && ignoredDir != DIR_EAST)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2019-03-31 21:09:40 +02:00
|
|
|
sMewDirectionCandidates[count] = DIR_EAST;
|
2019-03-22 20:16:26 +01:00
|
|
|
count++;
|
|
|
|
}
|
|
|
|
|
2020-07-19 20:12:38 +02:00
|
|
|
if (CanMewMoveToCoords(mew->currentCoords.x, mew->currentCoords.y + 1) == TRUE && ignoredDir != DIR_SOUTH)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2019-03-31 21:09:40 +02:00
|
|
|
sMewDirectionCandidates[count] = DIR_SOUTH;
|
2019-03-22 20:16:26 +01:00
|
|
|
count++;
|
|
|
|
}
|
|
|
|
|
2020-07-19 20:12:38 +02:00
|
|
|
if (CanMewMoveToCoords(mew->currentCoords.x - 1, mew->currentCoords.y) == TRUE && ignoredDir != DIR_WEST)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2019-03-31 21:09:40 +02:00
|
|
|
sMewDirectionCandidates[count] = DIR_WEST;
|
2019-03-22 20:16:26 +01:00
|
|
|
count++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (count > 1)
|
2019-03-31 21:09:40 +02:00
|
|
|
return sMewDirectionCandidates[VarGet(VAR_FARAWAY_ISLAND_STEP_COUNTER) % count];
|
Undo PokeCodec's PRs
This commit undoes most of PokeCodec's PRs after the debate in chat. Some
harmless or completely superseded PRs have been left alone, as there is not
much benefit in attempting to undo them.
Reverts #1104, #1108, #1115, #1118, #1119, #1124, #1126, #1127, #1132, #1136,
#1137, #1139, #1140, #1144, #1148, #1149, #1150, #1153, #1155, #1177, #1179,
#1180, #1181, #1182 and #1183.
2020-09-13 09:22:50 +02:00
|
|
|
else
|
|
|
|
return sMewDirectionCandidates[0];
|
2019-03-22 20:16:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void UpdateFarawayIslandStepCounter(void)
|
|
|
|
{
|
|
|
|
u16 steps = VarGet(VAR_FARAWAY_ISLAND_STEP_COUNTER);
|
|
|
|
if (gSaveBlock1Ptr->location.mapNum == MAP_NUM(FARAWAY_ISLAND_INTERIOR)
|
|
|
|
&& gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(FARAWAY_ISLAND_INTERIOR))
|
|
|
|
{
|
|
|
|
steps++;
|
|
|
|
if (steps >= 9999)
|
|
|
|
VarSet(VAR_FARAWAY_ISLAND_STEP_COUNTER, 0);
|
|
|
|
else
|
|
|
|
VarSet(VAR_FARAWAY_ISLAND_STEP_COUNTER, steps);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
bool8 ObjectEventIsFarawayIslandMew(struct ObjectEvent *objectEvent)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
|
|
|
if (gSaveBlock1Ptr->location.mapNum == MAP_NUM(FARAWAY_ISLAND_INTERIOR)
|
|
|
|
&& gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(FARAWAY_ISLAND_INTERIOR))
|
|
|
|
{
|
2019-11-21 05:12:51 +01:00
|
|
|
if (objectEvent->graphicsId == OBJ_EVENT_GFX_MEW)
|
2019-03-22 20:16:26 +01:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool8 IsMewPlayingHideAndSeek(void)
|
|
|
|
{
|
|
|
|
if (gSaveBlock1Ptr->location.mapNum == MAP_NUM(FARAWAY_ISLAND_INTERIOR)
|
|
|
|
&& gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(FARAWAY_ISLAND_INTERIOR))
|
|
|
|
{
|
|
|
|
if (FlagGet(FLAG_CAUGHT_MEW) != TRUE && FlagGet(FLAG_HIDE_MEW) != TRUE)
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-07-19 20:12:38 +02:00
|
|
|
// Every 4th step Mew will shake the grass it steps into
|
|
|
|
// Otherwise its movement leaves grass undisturbed
|
|
|
|
bool8 ShouldMewShakeGrass(struct ObjectEvent *objectEvent)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
|
|
|
if (VarGet(VAR_FARAWAY_ISLAND_STEP_COUNTER) != 0xFFFF
|
|
|
|
&& VarGet(VAR_FARAWAY_ISLAND_STEP_COUNTER) % 4 == 0)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-07-19 20:12:38 +02:00
|
|
|
void SetMewAboveGrass(void)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
|
|
|
s16 x;
|
|
|
|
s16 y;
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *mew = &gObjectEvents[GetMewObjectEventId()];
|
2019-03-22 20:16:26 +01:00
|
|
|
|
2020-07-19 20:12:38 +02:00
|
|
|
mew->invisible = FALSE;
|
2019-03-22 20:16:26 +01:00
|
|
|
if (gSpecialVar_0x8004 == 1)
|
|
|
|
{
|
2020-07-19 20:12:38 +02:00
|
|
|
// For after battle where Mew should still be present (e.g. if ran from battle)
|
2019-03-22 20:16:26 +01:00
|
|
|
mew->fixedPriority = 1;
|
|
|
|
gSprites[mew->spriteId].subspriteMode = SUBSPRITES_IGNORE_PRIORITY;
|
|
|
|
gSprites[mew->spriteId].subpriority = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-07-19 20:12:38 +02:00
|
|
|
// Mew emerging from grass when found
|
|
|
|
// Also do field effect for grass shaking as it emerges
|
2019-03-22 20:16:26 +01:00
|
|
|
VarSet(VAR_FARAWAY_ISLAND_STEP_COUNTER, 0xFFFF);
|
|
|
|
mew->fixedPriority = 1;
|
|
|
|
gSprites[mew->spriteId].subspriteMode = SUBSPRITES_IGNORE_PRIORITY;
|
|
|
|
if (gSpecialVar_Facing != DIR_NORTH)
|
|
|
|
gSprites[mew->spriteId].subpriority = 1;
|
|
|
|
|
2020-07-02 10:59:52 +02:00
|
|
|
LoadSpritePalette(&gSpritePalette_GeneralFieldEffect1);
|
|
|
|
UpdateSpritePaletteWithWeather(IndexOfSpritePaletteTag(gSpritePalette_GeneralFieldEffect1.tag));
|
2019-03-22 20:16:26 +01:00
|
|
|
|
|
|
|
x = mew->currentCoords.x;
|
|
|
|
y = mew->currentCoords.y;
|
2020-06-01 16:23:12 +02:00
|
|
|
SetSpritePosToOffsetMapCoords(&x, &y, 8, 8);
|
2020-07-23 16:31:52 +02:00
|
|
|
sGrassSpriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[FLDEFFOBJ_LONG_GRASS], x, y, gSprites[mew->spriteId].subpriority - 1);
|
2020-07-19 20:12:38 +02:00
|
|
|
if (sGrassSpriteId != MAX_SPRITES)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2020-07-19 20:12:38 +02:00
|
|
|
struct Sprite *sprite = &gSprites[sGrassSpriteId];
|
2019-03-22 20:16:26 +01:00
|
|
|
sprite->coordOffsetEnabled = 1;
|
|
|
|
sprite->oam.priority = 2;
|
|
|
|
sprite->callback = SpriteCallbackDummy;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-19 20:12:38 +02:00
|
|
|
void DestroyMewEmergingGrassSprite(void)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2020-07-19 20:12:38 +02:00
|
|
|
if (sGrassSpriteId != MAX_SPRITES)
|
|
|
|
DestroySprite(&gSprites[sGrassSpriteId]);
|
2019-03-22 20:16:26 +01:00
|
|
|
}
|
|
|
|
|
2020-07-19 20:12:38 +02:00
|
|
|
static bool8 ShouldMewMoveNorth(struct ObjectEvent *mew, u8 index)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2020-07-19 20:12:38 +02:00
|
|
|
if (sPlayerToMewDeltaY > 0 && CanMewMoveToCoords(mew->currentCoords.x, mew->currentCoords.y - 1))
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2019-03-31 21:09:40 +02:00
|
|
|
sMewDirectionCandidates[index] = DIR_NORTH;
|
2019-03-22 20:16:26 +01:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-07-19 20:12:38 +02:00
|
|
|
static bool8 ShouldMewMoveEast(struct ObjectEvent *mew, u8 index)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2020-07-19 20:12:38 +02:00
|
|
|
if (sPlayerToMewDeltaX < 0 && CanMewMoveToCoords(mew->currentCoords.x + 1, mew->currentCoords.y))
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2019-03-31 21:09:40 +02:00
|
|
|
sMewDirectionCandidates[index] = DIR_EAST;
|
2019-03-22 20:16:26 +01:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-07-19 20:12:38 +02:00
|
|
|
static bool8 ShouldMewMoveSouth(struct ObjectEvent *mew, u8 index)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2020-07-19 20:12:38 +02:00
|
|
|
if (sPlayerToMewDeltaY < 0 && CanMewMoveToCoords(mew->currentCoords.x, mew->currentCoords.y + 1))
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2019-03-31 21:09:40 +02:00
|
|
|
sMewDirectionCandidates[index] = DIR_SOUTH;
|
2019-03-22 20:16:26 +01:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-07-19 20:12:38 +02:00
|
|
|
static bool8 ShouldMewMoveWest(struct ObjectEvent *mew, u8 index)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2020-07-19 20:12:38 +02:00
|
|
|
if (sPlayerToMewDeltaX > 0 && CanMewMoveToCoords(mew->currentCoords.x - 1, mew->currentCoords.y))
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2019-03-31 21:09:40 +02:00
|
|
|
sMewDirectionCandidates[index] = DIR_WEST;
|
2019-03-22 20:16:26 +01:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-07-19 20:12:38 +02:00
|
|
|
static u8 GetRandomMewDirectionCandidate(u8 numDirections)
|
2019-03-22 20:16:26 +01:00
|
|
|
{
|
2020-07-19 20:12:38 +02:00
|
|
|
return sMewDirectionCandidates[VarGet(VAR_FARAWAY_ISLAND_STEP_COUNTER) % numDirections];
|
2019-03-22 20:16:26 +01:00
|
|
|
}
|