diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/quest_log_objects.c | 44 | ||||
-rw-r--r-- | src/quest_log_player.c | 4 | ||||
-rw-r--r-- | src/trainer_see.c | 174 | ||||
-rw-r--r-- | src/vs_seeker.c | 4 |
4 files changed, 200 insertions, 26 deletions
diff --git a/src/quest_log_objects.c b/src/quest_log_objects.c index aecc5fd68..e029632f3 100644 --- a/src/quest_log_objects.c +++ b/src/quest_log_objects.c @@ -39,8 +39,8 @@ void SetQuestLogObjectEventsData(struct QuestLog * questLog) questLog->unk_008[i].localId = gObjectEvents[i].localId; questLog->unk_008[i].mapNum = gObjectEvents[i].mapNum; questLog->unk_008[i].mapGroup = gObjectEvents[i].mapGroup; - questLog->unk_008[i].x = gObjectEvents[i].coords2.x; - questLog->unk_008[i].y = gObjectEvents[i].coords2.y; + questLog->unk_008[i].x = gObjectEvents[i].currentCoords.x; + questLog->unk_008[i].y = gObjectEvents[i].currentCoords.y; questLog->unk_008[i].trainerRange_berryTreeId = gObjectEvents[i].trainerRange_berryTreeId; questLog->unk_008[i].mapobj_unk_1F = gObjectEvents[i].mapobj_unk_1F; questLog->unk_008[i].mapobj_unk_21 = gObjectEvents[i].mapobj_unk_21; @@ -83,8 +83,8 @@ void sub_815A1F8(const struct QuestLog * questLog, const struct ObjectEventTempl gObjectEvents[i].localId = questLogObjectEvents[i].localId; gObjectEvents[i].mapNum = questLogObjectEvents[i].mapNum; gObjectEvents[i].mapGroup = questLogObjectEvents[i].mapGroup; - gObjectEvents[i].coords2.x = questLogObjectEvents[i].x; - gObjectEvents[i].coords2.y = questLogObjectEvents[i].y; + gObjectEvents[i].currentCoords.x = questLogObjectEvents[i].x; + gObjectEvents[i].currentCoords.y = questLogObjectEvents[i].y; gObjectEvents[i].trainerRange_berryTreeId = questLogObjectEvents[i].trainerRange_berryTreeId; gObjectEvents[i].mapobj_unk_1F = questLogObjectEvents[i].mapobj_unk_1F; gObjectEvents[i].mapobj_unk_21 = questLogObjectEvents[i].mapobj_unk_21; @@ -94,38 +94,38 @@ void sub_815A1F8(const struct QuestLog * questLog, const struct ObjectEventTempl { if (gObjectEvents[i].localId == templates[j].localId) { - gObjectEvents[i].coords1.x = templates[j].x + 7; - gObjectEvents[i].coords1.y = templates[j].y + 7; + gObjectEvents[i].initialCoords.x = templates[j].x + 7; + gObjectEvents[i].initialCoords.y = templates[j].y + 7; gObjectEvents[i].range.as_nybbles.x = templates[j].movementRangeX; gObjectEvents[i].range.as_nybbles.y = templates[j].movementRangeY; } } - gObjectEvents[i].mapobj_unk_1E = MapGridGetMetatileBehaviorAt(gObjectEvents[i].coords2.x, gObjectEvents[i].coords2.y); - if (gObjectEvents[i].mapobj_unk_1F == MapGridGetMetatileBehaviorAt((s16)(gObjectEvents[i].coords2.x), (s16)(gObjectEvents[i].coords2.y))) + gObjectEvents[i].mapobj_unk_1E = MapGridGetMetatileBehaviorAt(gObjectEvents[i].currentCoords.x, gObjectEvents[i].currentCoords.y); + if (gObjectEvents[i].mapobj_unk_1F == MapGridGetMetatileBehaviorAt((s16)(gObjectEvents[i].currentCoords.x), (s16)(gObjectEvents[i].currentCoords.y))) { - gObjectEvents[i].coords3.x = gObjectEvents[i].coords2.x; - gObjectEvents[i].coords3.y = gObjectEvents[i].coords2.y; + gObjectEvents[i].previousCoords.x = gObjectEvents[i].currentCoords.x; + gObjectEvents[i].previousCoords.y = gObjectEvents[i].currentCoords.y; } - else if (gObjectEvents[i].mapobj_unk_1F == MapGridGetMetatileBehaviorAt((s16)(gObjectEvents[i].coords2.x - 1), (s16)(gObjectEvents[i].coords2.y))) + else if (gObjectEvents[i].mapobj_unk_1F == MapGridGetMetatileBehaviorAt((s16)(gObjectEvents[i].currentCoords.x - 1), (s16)(gObjectEvents[i].currentCoords.y))) { - gObjectEvents[i].coords3.x = gObjectEvents[i].coords2.x - 1; - gObjectEvents[i].coords3.y = gObjectEvents[i].coords2.y; + gObjectEvents[i].previousCoords.x = gObjectEvents[i].currentCoords.x - 1; + gObjectEvents[i].previousCoords.y = gObjectEvents[i].currentCoords.y; } - else if (gObjectEvents[i].mapobj_unk_1F == MapGridGetMetatileBehaviorAt((s16)(gObjectEvents[i].coords2.x + 1), (s16)(gObjectEvents[i].coords2.y))) + else if (gObjectEvents[i].mapobj_unk_1F == MapGridGetMetatileBehaviorAt((s16)(gObjectEvents[i].currentCoords.x + 1), (s16)(gObjectEvents[i].currentCoords.y))) { - gObjectEvents[i].coords3.x = gObjectEvents[i].coords2.x + 1; - gObjectEvents[i].coords3.y = gObjectEvents[i].coords2.y; + gObjectEvents[i].previousCoords.x = gObjectEvents[i].currentCoords.x + 1; + gObjectEvents[i].previousCoords.y = gObjectEvents[i].currentCoords.y; } - else if (gObjectEvents[i].mapobj_unk_1F == MapGridGetMetatileBehaviorAt((s16)(gObjectEvents[i].coords2.x), (s16)(gObjectEvents[i].coords2.y - 1))) + else if (gObjectEvents[i].mapobj_unk_1F == MapGridGetMetatileBehaviorAt((s16)(gObjectEvents[i].currentCoords.x), (s16)(gObjectEvents[i].currentCoords.y - 1))) { - gObjectEvents[i].coords3.x = gObjectEvents[i].coords2.x; - gObjectEvents[i].coords3.y = gObjectEvents[i].coords2.y - 1; + gObjectEvents[i].previousCoords.x = gObjectEvents[i].currentCoords.x; + gObjectEvents[i].previousCoords.y = gObjectEvents[i].currentCoords.y - 1; } - else if (gObjectEvents[i].mapobj_unk_1F == MapGridGetMetatileBehaviorAt((s16)(gObjectEvents[i].coords2.x), (s16)(gObjectEvents[i].coords2.y + 1))) + else if (gObjectEvents[i].mapobj_unk_1F == MapGridGetMetatileBehaviorAt((s16)(gObjectEvents[i].currentCoords.x), (s16)(gObjectEvents[i].currentCoords.y + 1))) { - gObjectEvents[i].coords3.x = gObjectEvents[i].coords2.x; - gObjectEvents[i].coords3.y = gObjectEvents[i].coords2.y + 1; + gObjectEvents[i].previousCoords.x = gObjectEvents[i].currentCoords.x; + gObjectEvents[i].previousCoords.y = gObjectEvents[i].currentCoords.y + 1; } } diff --git a/src/quest_log_player.c b/src/quest_log_player.c index 0d7a2bb50..d66c677d8 100644 --- a/src/quest_log_player.c +++ b/src/quest_log_player.c @@ -145,8 +145,8 @@ static void sub_8150708(void) sub_81507BC(objectEvent, sub_805C808(2)); ObjectEventTurn(objectEvent, objectEvent->placeholder18); SetPlayerAvatarStateMask(PLAYER_AVATAR_FLAG_SURFING); - gFieldEffectArguments[0] = objectEvent->coords2.x; - gFieldEffectArguments[1] = objectEvent->coords2.y; + gFieldEffectArguments[0] = objectEvent->currentCoords.x; + gFieldEffectArguments[1] = objectEvent->currentCoords.y; gFieldEffectArguments[2] = gPlayerAvatar.objectEventId; fieldEffectId = FieldEffectStart(FLDEFF_SURF_BLOB); objectEvent->mapobj_unk_1A = fieldEffectId; diff --git a/src/trainer_see.c b/src/trainer_see.c new file mode 100644 index 000000000..a04fe83ec --- /dev/null +++ b/src/trainer_see.c @@ -0,0 +1,174 @@ +#include "global.h" +#include "battle_setup.h" +#include "field_player_avatar.h" +#include "event_object_movement.h" +#include "quest_log.h" +#include "constants/battle_setup.h" + +static bool8 CheckTrainer(u8 objectEventId); +static u8 GetTrainerApproachDistance(struct ObjectEvent * objectEvent); +static u8 GetTrainerApproachDistanceSouth(struct ObjectEvent * objectEvent, s16 range, s16 x, s16 y); +static u8 GetTrainerApproachDistanceNorth(struct ObjectEvent * objectEvent, s16 range, s16 x, s16 y); +static u8 GetTrainerApproachDistanceWest(struct ObjectEvent * objectEvent, s16 range, s16 x, s16 y); +static u8 GetTrainerApproachDistanceEast(struct ObjectEvent * objectEvent, s16 range, s16 x, s16 y); +static u8 CheckPathBetweenTrainerAndPlayer(struct ObjectEvent * objectEvent, u8 approachDistance, u8 facingDirection); +void sub_8081E68(struct ObjectEvent * objectEvent, u8 approachDistance); + +const u16 gUnknown_83C6AC8[] = INCBIN_U16("graphics/object_events/emoticons.4bpp"); + +u8 (*const sDirectionalApproachDistanceFuncs[])(struct ObjectEvent *, s16 range, s16 x, s16 y) = { + GetTrainerApproachDistanceSouth, + GetTrainerApproachDistanceNorth, + GetTrainerApproachDistanceWest, + GetTrainerApproachDistanceEast +}; + +bool8 CheckForTrainersWantingBattle(void) +{ + u8 i; + if (sub_8111C2C() == TRUE) + return FALSE; + + for (i = 0; i < OBJECT_EVENTS_COUNT; i++) + { + if (gObjectEvents[i].active + && ( + gObjectEvents[i].trainerType == 1 + || gObjectEvents[i].trainerType == 3 + ) + && CheckTrainer(i) + ) + return TRUE; + } + return FALSE; +} + +static bool8 CheckTrainer(u8 objectEventId) +{ + const u8 *script = GetObjectEventScriptPointerByObjectEventId(objectEventId); + u8 approachDistance; + if (GetTrainerFlagFromScriptPointer(script)) + return FALSE; + approachDistance = GetTrainerApproachDistance(&gObjectEvents[objectEventId]); + if (approachDistance != 0) + { + if (script[1] == TRAINER_BATTLE_DOUBLE && GetMonsStateToDoubles()) + return FALSE; + ConfigureAndSetUpOneTrainerBattle(objectEventId, script); + sub_8081E68(&gObjectEvents[objectEventId], approachDistance - 1); + return TRUE; + } + return FALSE; +} + +static u8 GetTrainerApproachDistance(struct ObjectEvent *trainerObj) +{ + s16 x, y; + u8 i; + u8 approachDistance; + + PlayerGetDestCoords(&x, &y); + if (trainerObj->trainerType == 1) // can only see in one direction + { + approachDistance = sDirectionalApproachDistanceFuncs[trainerObj->facingDirection - 1](trainerObj, trainerObj->trainerRange_berryTreeId, x, y); + return CheckPathBetweenTrainerAndPlayer(trainerObj, approachDistance, trainerObj->facingDirection); + } + else // can see in all directions + { + for (i = 0; i < 4; i++) + { + approachDistance = sDirectionalApproachDistanceFuncs[i](trainerObj, trainerObj->trainerRange_berryTreeId, x, y); + if (CheckPathBetweenTrainerAndPlayer(trainerObj, approachDistance, i + 1)) // directions are 1-4 instead of 0-3. south north west east + return approachDistance; + } + } + + return 0; +} + +// Returns how far south the player is from trainer. 0 if out of trainer's sight. +static u8 GetTrainerApproachDistanceSouth(struct ObjectEvent *trainerObj, s16 range, s16 x, s16 y) +{ + if (trainerObj->currentCoords.x == x + && y > trainerObj->currentCoords.y + && y <= trainerObj->currentCoords.y + range) + { + if (range > 3 && sub_805DF30() == OBJECT_EVENTS_COUNT) + return 0; + return (y - trainerObj->currentCoords.y); + } + else + return 0; +} + +// Returns how far north the player is from trainer. 0 if out of trainer's sight. +static u8 GetTrainerApproachDistanceNorth(struct ObjectEvent *trainerObj, s16 range, s16 x, s16 y) +{ + if (trainerObj->currentCoords.x == x + && y < trainerObj->currentCoords.y + && y >= trainerObj->currentCoords.y - range) + return (trainerObj->currentCoords.y - y); + else + return 0; +} + +// Returns how far west the player is from trainer. 0 if out of trainer's sight. +static u8 GetTrainerApproachDistanceWest(struct ObjectEvent *trainerObj, s16 range, s16 x, s16 y) +{ + if (trainerObj->currentCoords.y == y + && x < trainerObj->currentCoords.x + && x >= trainerObj->currentCoords.x - range) + return (trainerObj->currentCoords.x - x); + else + return 0; +} + +// Returns how far east the player is from trainer. 0 if out of trainer's sight. +static u8 GetTrainerApproachDistanceEast(struct ObjectEvent *trainerObj, s16 range, s16 x, s16 y) +{ + if (trainerObj->currentCoords.y == y + && x > trainerObj->currentCoords.x + && x <= trainerObj->currentCoords.x + range) + return (x - trainerObj->currentCoords.x); + else + return 0; +} + +#define COLLISION_MASK (~1) + +static u8 CheckPathBetweenTrainerAndPlayer(struct ObjectEvent *trainerObj, u8 approachDistance, u8 direction) +{ + s16 x, y; + u8 unk19_temp; + u8 unk19b_temp; + u8 i; + u8 collision; + + if (approachDistance == 0) + return 0; + + x = trainerObj->currentCoords.x; + y = trainerObj->currentCoords.y; + + for (i = 0; i <= approachDistance - 1; i++, MoveCoords(direction, &x, &y)) + { + collision = GetCollisionFlagsAtCoords(trainerObj, x, y, direction); + if (collision != 0 && (collision & COLLISION_MASK)) + return 0; + } + + // preserve mapobj_unk_19 before clearing. + unk19_temp = trainerObj->range.as_nybbles.x; + unk19b_temp = trainerObj->range.as_nybbles.y; + trainerObj->range.as_nybbles.x = 0; + trainerObj->range.as_nybbles.y = 0; + + collision = GetCollisionAtCoords(trainerObj, x, y, direction); + + trainerObj->range.as_nybbles.x = unk19_temp; + trainerObj->range.as_nybbles.y = unk19b_temp; + if (collision == 4) + return approachDistance; + + return 0; +} diff --git a/src/vs_seeker.c b/src/vs_seeker.c index 9c9a4d67f..221108a8f 100644 --- a/src/vs_seeker.c +++ b/src/vs_seeker.c @@ -798,8 +798,8 @@ static void GatherNearbyTrainerInfo(void) sVsSeeker->trainerInfo[vsSeekerObjectIdx].localId = templates[objectEventIdx].localId; TryGetObjectEventIdByLocalIdAndMap(templates[objectEventIdx].localId, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, &objectEventId); sVsSeeker->trainerInfo[vsSeekerObjectIdx].objectEventId = objectEventId; - sVsSeeker->trainerInfo[vsSeekerObjectIdx].xCoord = gObjectEvents[objectEventId].coords2.x - 7; - sVsSeeker->trainerInfo[vsSeekerObjectIdx].yCoord = gObjectEvents[objectEventId].coords2.y - 7; + sVsSeeker->trainerInfo[vsSeekerObjectIdx].xCoord = gObjectEvents[objectEventId].currentCoords.x - 7; + sVsSeeker->trainerInfo[vsSeekerObjectIdx].yCoord = gObjectEvents[objectEventId].currentCoords.y - 7; sVsSeeker->trainerInfo[vsSeekerObjectIdx].graphicsId = templates[objectEventIdx].graphicsId; vsSeekerObjectIdx++; } |