2017-12-01 21:25:13 +01:00
|
|
|
#include "global.h"
|
|
|
|
#include "battle_setup.h"
|
2018-11-13 15:19:04 +01:00
|
|
|
#include "event_data.h"
|
2018-06-11 15:34:19 +02:00
|
|
|
#include "event_object_movement.h"
|
2018-11-13 15:19:04 +01:00
|
|
|
#include "field_effect.h"
|
2017-12-18 23:26:44 +01:00
|
|
|
#include "field_player_avatar.h"
|
2018-11-13 15:19:04 +01:00
|
|
|
#include "pokemon.h"
|
2017-12-18 23:26:44 +01:00
|
|
|
#include "script.h"
|
|
|
|
#include "script_movement.h"
|
2018-11-13 15:19:04 +01:00
|
|
|
#include "sprite.h"
|
|
|
|
#include "task.h"
|
|
|
|
#include "trainer_see.h"
|
2019-01-13 20:50:08 +01:00
|
|
|
#include "trainer_hill.h"
|
2018-11-13 15:19:04 +01:00
|
|
|
#include "util.h"
|
2018-11-18 17:52:22 +01:00
|
|
|
#include "battle_pyramid.h"
|
2019-01-20 17:11:45 +01:00
|
|
|
#include "constants/battle_setup.h"
|
2019-11-01 08:41:55 +01:00
|
|
|
#include "constants/event_objects.h"
|
2019-11-21 20:03:35 +01:00
|
|
|
#include "constants/event_object_movement.h"
|
2018-11-13 15:19:04 +01:00
|
|
|
#include "constants/field_effects.h"
|
2020-04-21 21:53:48 +02:00
|
|
|
#include "constants/trainer_types.h"
|
2017-12-01 21:25:13 +01:00
|
|
|
|
|
|
|
// this file's functions
|
2019-11-21 04:55:44 +01:00
|
|
|
static u8 CheckTrainer(u8 objectEventId);
|
|
|
|
static u8 GetTrainerApproachDistance(struct ObjectEvent *trainerObj);
|
|
|
|
static u8 CheckPathBetweenTrainerAndPlayer(struct ObjectEvent *trainerObj, u8 approachDistance, u8 direction);
|
|
|
|
static void TrainerApproachPlayer(struct ObjectEvent *trainerObj, u8 range);
|
2017-12-19 17:18:44 +01:00
|
|
|
static void Task_RunTrainerSeeFuncList(u8 taskId);
|
|
|
|
static void Task_DestroyTrainerApproachTask(u8 taskId);
|
|
|
|
static void SetIconSpriteData(struct Sprite *sprite, u16 fldEffId, u8 spriteAnimNum);
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
static u8 GetTrainerApproachDistanceSouth(struct ObjectEvent *trainerObj, s16 range, s16 x, s16 y);
|
|
|
|
static u8 GetTrainerApproachDistanceNorth(struct ObjectEvent *trainerObj, s16 range, s16 x, s16 y);
|
|
|
|
static u8 GetTrainerApproachDistanceWest(struct ObjectEvent *trainerObj, s16 range, s16 x, s16 y);
|
|
|
|
static u8 GetTrainerApproachDistanceEast(struct ObjectEvent *trainerObj, s16 range, s16 x, s16 y);
|
|
|
|
|
|
|
|
static bool8 sub_80B4178(u8 taskId, struct Task *task, struct ObjectEvent *trainerObj);
|
|
|
|
static bool8 TrainerExclamationMark(u8 taskId, struct Task *task, struct ObjectEvent *trainerObj);
|
|
|
|
static bool8 WaitTrainerExclamationMark(u8 taskId, struct Task *task, struct ObjectEvent *trainerObj);
|
|
|
|
static bool8 TrainerMoveToPlayer(u8 taskId, struct Task *task, struct ObjectEvent *trainerObj);
|
|
|
|
static bool8 PlayerFaceApproachingTrainer(u8 taskId, struct Task *task, struct ObjectEvent *trainerObj);
|
|
|
|
static bool8 WaitPlayerFaceApproachingTrainer(u8 taskId, struct Task *task, struct ObjectEvent *trainerObj);
|
|
|
|
static bool8 RevealDisguisedTrainer(u8 taskId, struct Task *task, struct ObjectEvent *trainerObj);
|
|
|
|
static bool8 WaitRevealDisguisedTrainer(u8 taskId, struct Task *task, struct ObjectEvent *trainerObj);
|
|
|
|
static bool8 RevealHiddenTrainer(u8 taskId, struct Task *task, struct ObjectEvent *trainerObj);
|
|
|
|
static bool8 PopOutOfAshHiddenTrainer(u8 taskId, struct Task *task, struct ObjectEvent *trainerObj);
|
|
|
|
static bool8 JumpInPlaceHiddenTrainer(u8 taskId, struct Task *task, struct ObjectEvent *trainerObj);
|
|
|
|
static bool8 WaitRevealHiddenTrainer(u8 taskId, struct Task *task, struct ObjectEvent *trainerObj);
|
2017-12-19 17:18:44 +01:00
|
|
|
|
|
|
|
static void SpriteCB_TrainerIcons(struct Sprite *sprite);
|
2017-12-18 19:35:50 +01:00
|
|
|
|
2017-12-19 17:33:07 +01:00
|
|
|
// IWRAM common
|
2019-11-01 08:41:55 +01:00
|
|
|
u16 gWhichTrainerToFaceAfterBattle;
|
|
|
|
u8 gPostBattleMovementScript[4];
|
2017-12-19 17:33:07 +01:00
|
|
|
struct ApproachingTrainer gApproachingTrainers[2];
|
|
|
|
u8 gNoOfApproachingTrainers;
|
2019-11-01 08:41:55 +01:00
|
|
|
bool8 gTrainerApproachedPlayer;
|
2017-12-19 17:33:07 +01:00
|
|
|
|
|
|
|
// EWRAM
|
|
|
|
EWRAM_DATA u8 gApproachingTrainerId = 0;
|
|
|
|
|
2017-12-18 19:35:50 +01:00
|
|
|
// const rom data
|
2017-12-19 17:18:44 +01:00
|
|
|
static const u8 sEmotion_ExclamationMarkGfx[] = INCBIN_U8("graphics/misc/emotion_exclamation.4bpp");
|
|
|
|
static const u8 sEmotion_QuestionMarkGfx[] = INCBIN_U8("graphics/misc/emotion_question.4bpp");
|
|
|
|
static const u8 sEmotion_HeartGfx[] = INCBIN_U8("graphics/misc/emotion_heart.4bpp");
|
2017-12-18 19:35:50 +01:00
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
static u8 (*const sDirectionalApproachDistanceFuncs[])(struct ObjectEvent *trainerObj, s16 range, s16 x, s16 y) =
|
2017-12-18 19:35:50 +01:00
|
|
|
{
|
|
|
|
GetTrainerApproachDistanceSouth,
|
|
|
|
GetTrainerApproachDistanceNorth,
|
|
|
|
GetTrainerApproachDistanceWest,
|
|
|
|
GetTrainerApproachDistanceEast,
|
|
|
|
};
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
static bool8 (*const sTrainerSeeFuncList[])(u8 taskId, struct Task *task, struct ObjectEvent *trainerObj) =
|
2017-12-18 19:35:50 +01:00
|
|
|
{
|
|
|
|
sub_80B4178,
|
2019-01-20 17:11:45 +01:00
|
|
|
TrainerExclamationMark,
|
|
|
|
WaitTrainerExclamationMark,
|
|
|
|
TrainerMoveToPlayer,
|
|
|
|
PlayerFaceApproachingTrainer,
|
|
|
|
WaitPlayerFaceApproachingTrainer,
|
|
|
|
RevealDisguisedTrainer,
|
|
|
|
WaitRevealDisguisedTrainer,
|
|
|
|
RevealHiddenTrainer,
|
|
|
|
PopOutOfAshHiddenTrainer,
|
|
|
|
JumpInPlaceHiddenTrainer,
|
|
|
|
WaitRevealHiddenTrainer,
|
2017-12-18 19:35:50 +01:00
|
|
|
};
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
static bool8 (*const sTrainerSeeFuncList2[])(u8 taskId, struct Task *task, struct ObjectEvent *trainerObj) =
|
2017-12-18 19:35:50 +01:00
|
|
|
{
|
2019-01-20 17:11:45 +01:00
|
|
|
RevealHiddenTrainer,
|
|
|
|
PopOutOfAshHiddenTrainer,
|
|
|
|
JumpInPlaceHiddenTrainer,
|
|
|
|
WaitRevealHiddenTrainer,
|
2017-12-18 19:35:50 +01:00
|
|
|
};
|
|
|
|
|
2017-12-19 17:18:44 +01:00
|
|
|
static const struct OamData sOamData_Icons =
|
2017-12-18 19:35:50 +01:00
|
|
|
{
|
|
|
|
.y = 0,
|
2019-12-04 21:25:13 +01:00
|
|
|
.affineMode = ST_OAM_AFFINE_OFF,
|
|
|
|
.objMode = ST_OAM_OBJ_NORMAL,
|
2017-12-18 19:35:50 +01:00
|
|
|
.mosaic = 0,
|
2019-12-04 21:25:13 +01:00
|
|
|
.bpp = ST_OAM_4BPP,
|
2019-03-11 08:12:15 +01:00
|
|
|
.shape = SPRITE_SHAPE(16x16),
|
2017-12-18 19:35:50 +01:00
|
|
|
.x = 0,
|
|
|
|
.matrixNum = 0,
|
2019-03-11 08:12:15 +01:00
|
|
|
.size = SPRITE_SIZE(16x16),
|
2017-12-18 19:35:50 +01:00
|
|
|
.tileNum = 0,
|
|
|
|
.priority = 1,
|
|
|
|
.paletteNum = 0,
|
|
|
|
.affineParam = 0,
|
|
|
|
};
|
|
|
|
|
2017-12-19 17:18:44 +01:00
|
|
|
static const struct SpriteFrameImage sSpriteImageTable_ExclamationQuestionMark[] =
|
2017-12-18 19:35:50 +01:00
|
|
|
{
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
|
|
|
.data = sEmotion_ExclamationMarkGfx,
|
|
|
|
.size = 0x80
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.data = sEmotion_QuestionMarkGfx,
|
|
|
|
.size = 0x80
|
|
|
|
}
|
2017-12-18 19:35:50 +01:00
|
|
|
};
|
2017-12-01 21:25:13 +01:00
|
|
|
|
2017-12-19 17:18:44 +01:00
|
|
|
static const struct SpriteFrameImage sSpriteImageTable_HeartIcon[] =
|
2017-12-18 19:35:50 +01:00
|
|
|
{
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
|
|
|
.data = sEmotion_HeartGfx,
|
|
|
|
.size = 0x80
|
|
|
|
}
|
2017-12-18 19:35:50 +01:00
|
|
|
};
|
|
|
|
|
2017-12-19 17:18:44 +01:00
|
|
|
static const union AnimCmd sSpriteAnim_Icons1[] =
|
2017-12-18 19:35:50 +01:00
|
|
|
{
|
|
|
|
ANIMCMD_FRAME(0, 60),
|
|
|
|
ANIMCMD_END
|
|
|
|
};
|
|
|
|
|
2017-12-19 17:18:44 +01:00
|
|
|
static const union AnimCmd sSpriteAnim_Icons2[] =
|
2017-12-18 19:35:50 +01:00
|
|
|
{
|
|
|
|
ANIMCMD_FRAME(1, 60),
|
|
|
|
ANIMCMD_END
|
|
|
|
};
|
|
|
|
|
2017-12-19 17:18:44 +01:00
|
|
|
static const union AnimCmd *const sSpriteAnimTable_Icons[] =
|
2017-12-18 19:35:50 +01:00
|
|
|
{
|
2017-12-19 17:18:44 +01:00
|
|
|
sSpriteAnim_Icons1,
|
|
|
|
sSpriteAnim_Icons2
|
2017-12-18 19:35:50 +01:00
|
|
|
};
|
|
|
|
|
2017-12-19 17:18:44 +01:00
|
|
|
static const struct SpriteTemplate sSpriteTemplate_ExclamationQuestionMark =
|
2017-12-18 19:35:50 +01:00
|
|
|
{
|
|
|
|
.tileTag = 0xffff,
|
|
|
|
.paletteTag = 0xffff,
|
2017-12-19 17:18:44 +01:00
|
|
|
.oam = &sOamData_Icons,
|
|
|
|
.anims = sSpriteAnimTable_Icons,
|
|
|
|
.images = sSpriteImageTable_ExclamationQuestionMark,
|
2017-12-18 19:35:50 +01:00
|
|
|
.affineAnims = gDummySpriteAffineAnimTable,
|
2017-12-19 17:18:44 +01:00
|
|
|
.callback = SpriteCB_TrainerIcons
|
2017-12-18 19:35:50 +01:00
|
|
|
};
|
|
|
|
|
2017-12-19 17:18:44 +01:00
|
|
|
static const struct SpriteTemplate sSpriteTemplate_HeartIcon =
|
2017-12-18 19:35:50 +01:00
|
|
|
{
|
|
|
|
.tileTag = 0xffff,
|
|
|
|
.paletteTag = 0x1004,
|
2017-12-19 17:18:44 +01:00
|
|
|
.oam = &sOamData_Icons,
|
|
|
|
.anims = sSpriteAnimTable_Icons,
|
|
|
|
.images = sSpriteImageTable_HeartIcon,
|
2017-12-18 19:35:50 +01:00
|
|
|
.affineAnims = gDummySpriteAffineAnimTable,
|
2017-12-19 17:18:44 +01:00
|
|
|
.callback = SpriteCB_TrainerIcons
|
2017-12-18 19:35:50 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
// code
|
2017-12-01 21:25:13 +01:00
|
|
|
bool8 CheckForTrainersWantingBattle(void)
|
|
|
|
{
|
|
|
|
u8 i;
|
|
|
|
|
|
|
|
gNoOfApproachingTrainers = 0;
|
|
|
|
gApproachingTrainerId = 0;
|
|
|
|
|
2019-11-21 05:12:51 +01:00
|
|
|
for (i = 0; i < OBJECT_EVENTS_COUNT; i++)
|
2017-12-01 21:25:13 +01:00
|
|
|
{
|
2020-04-21 21:53:48 +02:00
|
|
|
u8 numTrainers;
|
2017-12-01 21:25:13 +01:00
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
if (!gObjectEvents[i].active)
|
2017-12-01 21:25:13 +01:00
|
|
|
continue;
|
2020-04-21 21:53:48 +02:00
|
|
|
if (gObjectEvents[i].trainerType != TRAINER_TYPE_NORMAL && gObjectEvents[i].trainerType != TRAINER_TYPE_BURIED)
|
2017-12-01 21:25:13 +01:00
|
|
|
continue;
|
|
|
|
|
2020-04-21 21:53:48 +02:00
|
|
|
numTrainers = CheckTrainer(i);
|
|
|
|
if (numTrainers == 2)
|
|
|
|
break;
|
2017-12-01 21:25:13 +01:00
|
|
|
|
2020-04-21 21:53:48 +02:00
|
|
|
if (numTrainers == 0)
|
2017-12-01 21:25:13 +01:00
|
|
|
continue;
|
|
|
|
|
|
|
|
if (gNoOfApproachingTrainers > 1)
|
|
|
|
break;
|
|
|
|
if (GetMonsStateToDoubles_2() != 0) // one trainer found and cant have a double battle
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gNoOfApproachingTrainers == 1)
|
|
|
|
{
|
|
|
|
ResetTrainerOpponentIds();
|
2019-11-21 04:55:44 +01:00
|
|
|
ConfigureAndSetUpOneTrainerBattle(gApproachingTrainers[gNoOfApproachingTrainers - 1].objectEventId,
|
2017-12-01 21:25:13 +01:00
|
|
|
gApproachingTrainers[gNoOfApproachingTrainers - 1].trainerScriptPtr);
|
2019-11-01 08:41:55 +01:00
|
|
|
gTrainerApproachedPlayer = TRUE;
|
2017-12-01 21:25:13 +01:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else if (gNoOfApproachingTrainers == 2)
|
|
|
|
{
|
|
|
|
ResetTrainerOpponentIds();
|
|
|
|
for (i = 0; i < gNoOfApproachingTrainers; i++, gApproachingTrainerId++)
|
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
ConfigureTwoTrainersBattle(gApproachingTrainers[i].objectEventId,
|
2017-12-01 21:25:13 +01:00
|
|
|
gApproachingTrainers[i].trainerScriptPtr);
|
|
|
|
}
|
|
|
|
SetUpTwoTrainersBattle();
|
|
|
|
gApproachingTrainerId = 0;
|
2019-11-01 08:41:55 +01:00
|
|
|
gTrainerApproachedPlayer = TRUE;
|
2017-12-01 21:25:13 +01:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-11-01 08:41:55 +01:00
|
|
|
gTrainerApproachedPlayer = FALSE;
|
2017-12-01 21:25:13 +01:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
2017-12-18 19:35:50 +01:00
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
static u8 CheckTrainer(u8 objectEventId)
|
2017-12-18 19:35:50 +01:00
|
|
|
{
|
|
|
|
const u8 *scriptPtr;
|
|
|
|
u8 ret = 1;
|
|
|
|
u8 approachDistance;
|
|
|
|
|
|
|
|
if (InTrainerHill() == TRUE)
|
2019-08-04 21:35:35 +02:00
|
|
|
scriptPtr = GetTrainerHillTrainerScript();
|
2017-12-18 19:35:50 +01:00
|
|
|
else
|
2019-11-21 04:55:44 +01:00
|
|
|
scriptPtr = GetObjectEventScriptPointerByObjectEventId(objectEventId);
|
2017-12-18 19:35:50 +01:00
|
|
|
|
|
|
|
if (InBattlePyramid())
|
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
if (GetBattlePyramidTrainerFlag(objectEventId))
|
2017-12-18 19:35:50 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else if (InTrainerHill() == TRUE)
|
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
if (GetHillTrainerFlag(objectEventId))
|
2017-12-18 19:35:50 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (GetTrainerFlagFromScriptPointer(scriptPtr))
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
approachDistance = GetTrainerApproachDistance(&gObjectEvents[objectEventId]);
|
2017-12-18 19:35:50 +01:00
|
|
|
|
|
|
|
if (approachDistance != 0)
|
|
|
|
{
|
|
|
|
if (scriptPtr[1] == TRAINER_BATTLE_DOUBLE
|
|
|
|
|| scriptPtr[1] == TRAINER_BATTLE_REMATCH_DOUBLE
|
|
|
|
|| scriptPtr[1] == TRAINER_BATTLE_CONTINUE_SCRIPT_DOUBLE)
|
|
|
|
{
|
|
|
|
if (GetMonsStateToDoubles_2() != 0)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
ret = 2;
|
|
|
|
}
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
gApproachingTrainers[gNoOfApproachingTrainers].objectEventId = objectEventId;
|
2017-12-18 19:35:50 +01:00
|
|
|
gApproachingTrainers[gNoOfApproachingTrainers].trainerScriptPtr = scriptPtr;
|
|
|
|
gApproachingTrainers[gNoOfApproachingTrainers].radius = approachDistance;
|
2019-11-21 04:55:44 +01:00
|
|
|
TrainerApproachPlayer(&gObjectEvents[objectEventId], approachDistance - 1);
|
2017-12-18 19:35:50 +01:00
|
|
|
gNoOfApproachingTrainers++;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
static u8 GetTrainerApproachDistance(struct ObjectEvent *trainerObj)
|
2017-12-18 19:35:50 +01:00
|
|
|
{
|
|
|
|
s16 x, y;
|
|
|
|
u8 i;
|
|
|
|
u8 approachDistance;
|
|
|
|
|
|
|
|
PlayerGetDestCoords(&x, &y);
|
2020-04-21 21:53:48 +02:00
|
|
|
if (trainerObj->trainerType == TRAINER_TYPE_NORMAL) // can only see in one direction
|
2017-12-18 19:35:50 +01:00
|
|
|
{
|
2018-06-11 16:19:17 +02:00
|
|
|
approachDistance = sDirectionalApproachDistanceFuncs[trainerObj->facingDirection - 1](trainerObj, trainerObj->trainerRange_berryTreeId, x, y);
|
|
|
|
return CheckPathBetweenTrainerAndPlayer(trainerObj, approachDistance, trainerObj->facingDirection);
|
2017-12-18 19:35:50 +01:00
|
|
|
}
|
2020-04-21 21:53:48 +02:00
|
|
|
else // TRAINER_TYPE_SEE_ALL_DIRECTIONS, TRAINER_TYPE_BURIED
|
2017-12-18 19:35:50 +01:00
|
|
|
{
|
2020-04-21 21:53:48 +02:00
|
|
|
for (i = 0; i < ARRAY_COUNT(sDirectionalApproachDistanceFuncs); i++)
|
2017-12-18 19:35:50 +01:00
|
|
|
{
|
|
|
|
approachDistance = sDirectionalApproachDistanceFuncs[i](trainerObj, trainerObj->trainerRange_berryTreeId, x, y);
|
2017-12-18 23:26:44 +01:00
|
|
|
if (CheckPathBetweenTrainerAndPlayer(trainerObj, approachDistance, i + 1)) // directions are 1-4 instead of 0-3. south north west east
|
2017-12-18 19:35:50 +01:00
|
|
|
return approachDistance;
|
|
|
|
}
|
|
|
|
}
|
2017-12-18 23:26:44 +01:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Returns how far south the player is from trainer. 0 if out of trainer's sight.
|
2019-11-21 04:55:44 +01:00
|
|
|
static u8 GetTrainerApproachDistanceSouth(struct ObjectEvent *trainerObj, s16 range, s16 x, s16 y)
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
2018-06-11 16:19:17 +02:00
|
|
|
if (trainerObj->currentCoords.x == x
|
|
|
|
&& y > trainerObj->currentCoords.y
|
|
|
|
&& y <= trainerObj->currentCoords.y + range)
|
|
|
|
return (y - trainerObj->currentCoords.y);
|
2017-12-18 23:26:44 +01:00
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Returns how far north the player is from trainer. 0 if out of trainer's sight.
|
2019-11-21 04:55:44 +01:00
|
|
|
static u8 GetTrainerApproachDistanceNorth(struct ObjectEvent *trainerObj, s16 range, s16 x, s16 y)
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
2018-06-11 16:19:17 +02:00
|
|
|
if (trainerObj->currentCoords.x == x
|
|
|
|
&& y < trainerObj->currentCoords.y
|
|
|
|
&& y >= trainerObj->currentCoords.y - range)
|
|
|
|
return (trainerObj->currentCoords.y - y);
|
2017-12-18 23:26:44 +01:00
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Returns how far west the player is from trainer. 0 if out of trainer's sight.
|
2019-11-21 04:55:44 +01:00
|
|
|
static u8 GetTrainerApproachDistanceWest(struct ObjectEvent *trainerObj, s16 range, s16 x, s16 y)
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
2018-06-11 16:19:17 +02:00
|
|
|
if (trainerObj->currentCoords.y == y
|
|
|
|
&& x < trainerObj->currentCoords.x
|
|
|
|
&& x >= trainerObj->currentCoords.x - range)
|
|
|
|
return (trainerObj->currentCoords.x - x);
|
2017-12-18 23:26:44 +01:00
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Returns how far east the player is from trainer. 0 if out of trainer's sight.
|
2019-11-21 04:55:44 +01:00
|
|
|
static u8 GetTrainerApproachDistanceEast(struct ObjectEvent *trainerObj, s16 range, s16 x, s16 y)
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
2018-06-11 16:19:17 +02:00
|
|
|
if (trainerObj->currentCoords.y == y
|
|
|
|
&& x > trainerObj->currentCoords.x
|
|
|
|
&& x <= trainerObj->currentCoords.x + range)
|
|
|
|
return (x - trainerObj->currentCoords.x);
|
2017-12-18 23:26:44 +01:00
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define COLLISION_MASK (~1)
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
static u8 CheckPathBetweenTrainerAndPlayer(struct ObjectEvent *trainerObj, u8 approachDistance, u8 direction)
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
|
|
|
s16 x, y;
|
|
|
|
u8 unk19_temp;
|
|
|
|
u8 unk19b_temp;
|
|
|
|
u8 i;
|
|
|
|
u8 collision;
|
|
|
|
|
|
|
|
if (approachDistance == 0)
|
|
|
|
return 0;
|
|
|
|
|
2018-06-11 16:19:17 +02:00
|
|
|
x = trainerObj->currentCoords.x;
|
|
|
|
y = trainerObj->currentCoords.y;
|
2017-12-18 23:26:44 +01:00
|
|
|
|
|
|
|
MoveCoords(direction, &x, &y);
|
|
|
|
for (i = 0; i < approachDistance - 1; i++, MoveCoords(direction, &x, &y))
|
|
|
|
{
|
2018-06-14 00:51:26 +02:00
|
|
|
collision = GetCollisionFlagsAtCoords(trainerObj, x, y, direction);
|
2017-12-18 23:26:44 +01:00
|
|
|
if (collision != 0 && (collision & COLLISION_MASK))
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// preserve mapobj_unk_19 before clearing.
|
2020-09-18 00:24:11 +02:00
|
|
|
unk19_temp = trainerObj->rangeX;
|
|
|
|
unk19b_temp = trainerObj->rangeY;
|
|
|
|
trainerObj->rangeX = 0;
|
|
|
|
trainerObj->rangeY = 0;
|
2017-12-18 23:26:44 +01:00
|
|
|
|
2018-06-14 00:51:26 +02:00
|
|
|
collision = GetCollisionAtCoords(trainerObj, x, y, direction);
|
2017-12-18 23:26:44 +01:00
|
|
|
|
2020-09-18 00:24:11 +02:00
|
|
|
trainerObj->rangeX = unk19_temp;
|
|
|
|
trainerObj->rangeY = unk19b_temp;
|
2017-12-18 23:26:44 +01:00
|
|
|
if (collision == 4)
|
|
|
|
return approachDistance;
|
|
|
|
|
2017-12-18 19:35:50 +01:00
|
|
|
return 0;
|
|
|
|
}
|
2017-12-18 23:26:44 +01:00
|
|
|
|
|
|
|
#define tFuncId data[0]
|
|
|
|
#define tTrainerRange data[3]
|
2017-12-19 17:18:44 +01:00
|
|
|
#define tOutOfAshSpriteId data[4]
|
2019-11-21 04:55:44 +01:00
|
|
|
#define tTrainerObjectEventId data[7]
|
2017-12-18 23:26:44 +01:00
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
static void TrainerApproachPlayer(struct ObjectEvent *trainerObj, u8 range)
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
|
|
|
struct Task *task;
|
|
|
|
|
|
|
|
gApproachingTrainers[gNoOfApproachingTrainers].taskId = CreateTask(Task_RunTrainerSeeFuncList, 0x50);
|
|
|
|
task = &gTasks[gApproachingTrainers[gNoOfApproachingTrainers].taskId];
|
|
|
|
task->tTrainerRange = range;
|
2019-11-21 04:55:44 +01:00
|
|
|
task->tTrainerObjectEventId = gApproachingTrainers[gNoOfApproachingTrainers].objectEventId;
|
2017-12-18 23:26:44 +01:00
|
|
|
}
|
|
|
|
|
2017-12-19 17:18:44 +01:00
|
|
|
static void sub_80B40C8(TaskFunc followupFunc)
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
|
|
|
u8 taskId;
|
|
|
|
TaskFunc taskFunc;
|
|
|
|
|
|
|
|
if (gApproachingTrainerId == 0)
|
|
|
|
taskId = gApproachingTrainers[0].taskId;
|
|
|
|
else
|
|
|
|
taskId = gApproachingTrainers[1].taskId;
|
|
|
|
|
|
|
|
taskFunc = Task_RunTrainerSeeFuncList;
|
|
|
|
SetTaskFuncWithFollowupFunc(taskId, taskFunc, followupFunc);
|
|
|
|
gTasks[taskId].tFuncId = 1;
|
|
|
|
taskFunc(taskId);
|
|
|
|
}
|
|
|
|
|
2017-12-19 17:18:44 +01:00
|
|
|
static void Task_RunTrainerSeeFuncList(u8 taskId)
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
|
|
|
struct Task *task = &gTasks[taskId];
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *trainerObj = &gObjectEvents[task->tTrainerObjectEventId];
|
2017-12-18 23:26:44 +01:00
|
|
|
|
|
|
|
if (!trainerObj->active)
|
|
|
|
{
|
|
|
|
SwitchTaskToFollowupFunc(taskId);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-12-19 17:18:44 +01:00
|
|
|
while (sTrainerSeeFuncList[task->tFuncId](taskId, task, trainerObj));
|
2017-12-18 23:26:44 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
static bool8 sub_80B4178(u8 taskId, struct Task *task, struct ObjectEvent *trainerObj)
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
static bool8 TrainerExclamationMark(u8 taskId, struct Task *task, struct ObjectEvent *trainerObj)
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
|
|
|
u8 direction;
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
ObjectEventGetLocalIdAndMap(trainerObj, &gFieldEffectArguments[0], &gFieldEffectArguments[1], &gFieldEffectArguments[2]);
|
2018-06-14 00:51:26 +02:00
|
|
|
FieldEffectStart(FLDEFF_EXCLAMATION_MARK_ICON);
|
|
|
|
direction = GetFaceDirectionMovementAction(trainerObj->facingDirection);
|
2019-11-21 04:55:44 +01:00
|
|
|
ObjectEventSetHeldMovement(trainerObj, direction);
|
2017-12-18 23:26:44 +01:00
|
|
|
task->tFuncId++;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
static bool8 WaitTrainerExclamationMark(u8 taskId, struct Task *task, struct ObjectEvent *trainerObj)
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
2018-06-14 00:51:26 +02:00
|
|
|
if (FieldEffectActiveListContains(FLDEFF_EXCLAMATION_MARK_ICON))
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-12-19 17:18:44 +01:00
|
|
|
task->tFuncId++;
|
2019-01-20 17:11:45 +01:00
|
|
|
if (trainerObj->movementType == MOVEMENT_TYPE_TREE_DISGUISE || trainerObj->movementType == MOVEMENT_TYPE_MOUNTAIN_DISGUISE)
|
2017-12-19 17:18:44 +01:00
|
|
|
task->tFuncId = 6;
|
2019-01-20 17:11:45 +01:00
|
|
|
if (trainerObj->movementType == MOVEMENT_TYPE_HIDDEN)
|
2017-12-19 17:18:44 +01:00
|
|
|
task->tFuncId = 8;
|
2017-12-18 23:26:44 +01:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
static bool8 TrainerMoveToPlayer(u8 taskId, struct Task *task, struct ObjectEvent *trainerObj)
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
if (!ObjectEventIsMovementOverridden(trainerObj) || ObjectEventClearHeldMovementIfFinished(trainerObj))
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
2017-12-19 17:18:44 +01:00
|
|
|
if (task->tTrainerRange)
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
ObjectEventSetHeldMovement(trainerObj, GetWalkNormalMovementAction(trainerObj->facingDirection));
|
2017-12-19 17:18:44 +01:00
|
|
|
task->tTrainerRange--;
|
2017-12-18 23:26:44 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
ObjectEventSetHeldMovement(trainerObj, MOVEMENT_ACTION_FACE_PLAYER);
|
2017-12-19 17:18:44 +01:00
|
|
|
task->tFuncId++;
|
2017-12-18 23:26:44 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
static bool8 PlayerFaceApproachingTrainer(u8 taskId, struct Task *task, struct ObjectEvent *trainerObj)
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *playerObj;
|
2017-12-18 23:26:44 +01:00
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
if (ObjectEventIsMovementOverridden(trainerObj) && !ObjectEventClearHeldMovementIfFinished(trainerObj))
|
2017-12-18 23:26:44 +01:00
|
|
|
return FALSE;
|
|
|
|
|
2018-06-14 00:51:26 +02:00
|
|
|
SetTrainerMovementType(trainerObj, GetTrainerFacingDirectionMovementType(trainerObj->facingDirection));
|
2019-11-21 04:55:44 +01:00
|
|
|
TryOverrideTemplateCoordsForObjectEvent(trainerObj, GetTrainerFacingDirectionMovementType(trainerObj->facingDirection));
|
|
|
|
OverrideTemplateCoordsForObjectEvent(trainerObj);
|
2017-12-18 23:26:44 +01:00
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
playerObj = &gObjectEvents[gPlayerAvatar.objectEventId];
|
|
|
|
if (ObjectEventIsMovementOverridden(playerObj) && !ObjectEventClearHeldMovementIfFinished(playerObj))
|
2017-12-18 23:26:44 +01:00
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
sub_808BCE8();
|
2019-11-21 04:55:44 +01:00
|
|
|
ObjectEventSetHeldMovement(&gObjectEvents[gPlayerAvatar.objectEventId], GetFaceDirectionMovementAction(GetOppositeDirection(trainerObj->facingDirection)));
|
2017-12-19 17:18:44 +01:00
|
|
|
task->tFuncId++;
|
2017-12-18 23:26:44 +01:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
static bool8 WaitPlayerFaceApproachingTrainer(u8 taskId, struct Task *task, struct ObjectEvent *trainerObj)
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *playerObj = &gObjectEvents[gPlayerAvatar.objectEventId];
|
2017-12-18 23:26:44 +01:00
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
if (!ObjectEventIsMovementOverridden(playerObj)
|
|
|
|
|| ObjectEventClearHeldMovementIfFinished(playerObj))
|
2017-12-18 23:26:44 +01:00
|
|
|
SwitchTaskToFollowupFunc(taskId);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
static bool8 RevealDisguisedTrainer(u8 taskId, struct Task *task, struct ObjectEvent *trainerObj)
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
if (!ObjectEventIsMovementOverridden(trainerObj)
|
|
|
|
|| ObjectEventClearHeldMovementIfFinished(trainerObj))
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
ObjectEventSetHeldMovement(trainerObj, MOVEMENT_ACTION_REVEAL_TRAINER);
|
2017-12-19 17:18:44 +01:00
|
|
|
task->tFuncId++;
|
2017-12-18 23:26:44 +01:00
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
static bool8 WaitRevealDisguisedTrainer(u8 taskId, struct Task *task, struct ObjectEvent *trainerObj)
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
if (ObjectEventClearHeldMovementIfFinished(trainerObj))
|
2017-12-19 17:18:44 +01:00
|
|
|
task->tFuncId = 3;
|
2017-12-18 23:26:44 +01:00
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
static bool8 RevealHiddenTrainer(u8 taskId, struct Task *task, struct ObjectEvent *trainerObj)
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
if (!ObjectEventIsMovementOverridden(trainerObj)
|
|
|
|
|| ObjectEventClearHeldMovementIfFinished(trainerObj))
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
ObjectEventSetHeldMovement(trainerObj, MOVEMENT_ACTION_FACE_PLAYER);
|
2017-12-19 17:18:44 +01:00
|
|
|
task->tFuncId++;
|
2017-12-18 23:26:44 +01:00
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
static bool8 PopOutOfAshHiddenTrainer(u8 taskId, struct Task *task, struct ObjectEvent *trainerObj)
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
if (ObjectEventCheckHeldMovementStatus(trainerObj))
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
2018-06-11 16:19:17 +02:00
|
|
|
gFieldEffectArguments[0] = trainerObj->currentCoords.x;
|
|
|
|
gFieldEffectArguments[1] = trainerObj->currentCoords.y;
|
2017-12-18 23:26:44 +01:00
|
|
|
gFieldEffectArguments[2] = gSprites[trainerObj->spriteId].subpriority - 1;
|
|
|
|
gFieldEffectArguments[3] = 2;
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tOutOfAshSpriteId = FieldEffectStart(FLDEFF_ASH_PUFF);
|
2017-12-19 17:18:44 +01:00
|
|
|
task->tFuncId++;
|
2017-12-18 23:26:44 +01:00
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
static bool8 JumpInPlaceHiddenTrainer(u8 taskId, struct Task *task, struct ObjectEvent *trainerObj)
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
|
|
|
struct Sprite *sprite;
|
|
|
|
|
2017-12-19 17:18:44 +01:00
|
|
|
if (gSprites[task->tOutOfAshSpriteId].animCmdIndex == 2)
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
2018-06-11 16:19:17 +02:00
|
|
|
trainerObj->fixedPriority = 0;
|
|
|
|
trainerObj->triggerGroundEffectsOnMove = 1;
|
2017-12-18 23:26:44 +01:00
|
|
|
|
|
|
|
sprite = &gSprites[trainerObj->spriteId];
|
|
|
|
sprite->oam.priority = 2;
|
2019-11-21 04:55:44 +01:00
|
|
|
ObjectEventClearHeldMovementIfFinished(trainerObj);
|
|
|
|
ObjectEventSetHeldMovement(trainerObj, GetJumpInPlaceMovementAction(trainerObj->facingDirection));
|
2017-12-19 17:18:44 +01:00
|
|
|
task->tFuncId++;
|
2017-12-18 23:26:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
static bool8 WaitRevealHiddenTrainer(u8 taskId, struct Task *task, struct ObjectEvent *trainerObj)
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
if (!FieldEffectActiveListContains(FLDEFF_ASH_PUFF))
|
2017-12-19 17:18:44 +01:00
|
|
|
task->tFuncId = 3;
|
2017-12-18 23:26:44 +01:00
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2017-12-19 17:18:44 +01:00
|
|
|
#undef tFuncId
|
|
|
|
#undef tTrainerRange
|
|
|
|
#undef tOutOfAshSpriteId
|
2019-11-21 04:55:44 +01:00
|
|
|
#undef tTrainerObjectEventId
|
2017-12-19 17:18:44 +01:00
|
|
|
|
|
|
|
static void sub_80B44C8(u8 taskId)
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
|
|
|
struct Task *task = &gTasks[taskId];
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *objEvent;
|
2017-12-18 23:26:44 +01:00
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
// another objEvent loaded into by loadword?
|
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
|
|
|
LoadWordFromTwoHalfwords(&task->data[1], (u32 *)&objEvent);
|
2017-12-18 23:26:44 +01:00
|
|
|
if (!task->data[7])
|
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
ObjectEventClearHeldMovement(objEvent);
|
2017-12-18 23:26:44 +01:00
|
|
|
task->data[7]++;
|
|
|
|
}
|
2019-11-21 04:55:44 +01:00
|
|
|
sTrainerSeeFuncList2[task->data[0]](taskId, task, objEvent);
|
2020-06-24 22:27:00 +02:00
|
|
|
if (task->data[0] == 3 && !FieldEffectActiveListContains(FLDEFF_ASH_PUFF))
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
SetTrainerMovementType(objEvent, GetTrainerFacingDirectionMovementType(objEvent->facingDirection));
|
|
|
|
TryOverrideTemplateCoordsForObjectEvent(objEvent, GetTrainerFacingDirectionMovementType(objEvent->facingDirection));
|
2017-12-18 23:26:44 +01:00
|
|
|
DestroyTask(taskId);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
objEvent->heldMovementFinished = 0;
|
2017-12-18 23:26:44 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
void sub_80B4578(struct ObjectEvent *var)
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
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
|
|
|
StoreWordInTwoHalfwords(&gTasks[CreateTask(sub_80B44C8, 0)].data[1], (u32)var);
|
2017-12-18 23:26:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void EndTrainerApproach(void)
|
|
|
|
{
|
|
|
|
sub_80B40C8(Task_DestroyTrainerApproachTask);
|
|
|
|
}
|
|
|
|
|
2017-12-19 17:18:44 +01:00
|
|
|
static void Task_DestroyTrainerApproachTask(u8 taskId)
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
|
|
|
DestroyTask(taskId);
|
|
|
|
EnableBothScriptContexts();
|
|
|
|
}
|
|
|
|
|
2018-12-07 23:50:56 +01:00
|
|
|
void TryPrepareSecondApproachingTrainer(void)
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
|
|
|
if (gNoOfApproachingTrainers == 2)
|
|
|
|
{
|
|
|
|
if (gApproachingTrainerId == 0)
|
|
|
|
{
|
|
|
|
gApproachingTrainerId++;
|
2018-12-07 23:50:56 +01:00
|
|
|
gSpecialVar_Result = TRUE;
|
2019-11-21 04:55:44 +01:00
|
|
|
UnfreezeObjectEvents();
|
|
|
|
FreezeObjectEventsExceptOne(gApproachingTrainers[1].objectEventId);
|
2017-12-18 23:26:44 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gApproachingTrainerId = 0;
|
2018-12-07 23:50:56 +01:00
|
|
|
gSpecialVar_Result = FALSE;
|
2017-12-18 23:26:44 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-12-07 23:50:56 +01:00
|
|
|
gSpecialVar_Result = FALSE;
|
2017-12-18 23:26:44 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-19 17:18:44 +01:00
|
|
|
#define sLocalId data[0]
|
|
|
|
#define sMapNum data[1]
|
|
|
|
#define sMapGroup data[2]
|
|
|
|
#define sData3 data[3]
|
|
|
|
#define sData4 data[4]
|
|
|
|
#define sFldEffId data[7]
|
|
|
|
|
2018-06-14 00:51:26 +02:00
|
|
|
u8 FldEff_ExclamationMarkIcon(void)
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
2017-12-19 17:18:44 +01:00
|
|
|
u8 spriteId = CreateSpriteAtEnd(&sSpriteTemplate_ExclamationQuestionMark, 0, 0, 0x53);
|
2017-12-18 23:26:44 +01:00
|
|
|
|
|
|
|
if (spriteId != MAX_SPRITES)
|
2018-06-14 00:51:26 +02:00
|
|
|
SetIconSpriteData(&gSprites[spriteId], FLDEFF_EXCLAMATION_MARK_ICON, 0);
|
2017-12-18 23:26:44 +01:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-06-14 00:51:26 +02:00
|
|
|
u8 FldEff_QuestionMarkIcon(void)
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
2017-12-19 17:18:44 +01:00
|
|
|
u8 spriteId = CreateSpriteAtEnd(&sSpriteTemplate_ExclamationQuestionMark, 0, 0, 0x52);
|
2017-12-18 23:26:44 +01:00
|
|
|
|
|
|
|
if (spriteId != MAX_SPRITES)
|
2018-06-14 00:51:26 +02:00
|
|
|
SetIconSpriteData(&gSprites[spriteId], FLDEFF_QUESTION_MARK_ICON, 1);
|
2017-12-18 23:26:44 +01:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
u8 FldEff_HeartIcon(void)
|
|
|
|
{
|
2017-12-19 17:18:44 +01:00
|
|
|
u8 spriteId = CreateSpriteAtEnd(&sSpriteTemplate_HeartIcon, 0, 0, 0x52);
|
2017-12-18 23:26:44 +01:00
|
|
|
|
|
|
|
if (spriteId != MAX_SPRITES)
|
|
|
|
{
|
|
|
|
struct Sprite *sprite = &gSprites[spriteId];
|
|
|
|
|
2017-12-19 17:18:44 +01:00
|
|
|
SetIconSpriteData(sprite, FLDEFF_HEART_ICON, 0);
|
2017-12-18 23:26:44 +01:00
|
|
|
sprite->oam.paletteNum = 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-12-19 17:18:44 +01:00
|
|
|
static void SetIconSpriteData(struct Sprite *sprite, u16 fldEffId, u8 spriteAnimNum)
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
|
|
|
sprite->oam.priority = 1;
|
|
|
|
sprite->coordOffsetEnabled = 1;
|
|
|
|
|
2017-12-19 17:18:44 +01:00
|
|
|
sprite->sLocalId = gFieldEffectArguments[0];
|
|
|
|
sprite->sMapNum = gFieldEffectArguments[1];
|
|
|
|
sprite->sMapGroup = gFieldEffectArguments[2];
|
|
|
|
sprite->sData3 = -5;
|
|
|
|
sprite->sFldEffId = fldEffId;
|
2017-12-18 23:26:44 +01:00
|
|
|
|
2017-12-19 17:18:44 +01:00
|
|
|
StartSpriteAnim(sprite, spriteAnimNum);
|
2017-12-18 23:26:44 +01:00
|
|
|
}
|
|
|
|
|
2017-12-19 17:18:44 +01:00
|
|
|
static void SpriteCB_TrainerIcons(struct Sprite *sprite)
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
u8 objEventId;
|
2017-12-18 23:26:44 +01:00
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
if (TryGetObjectEventIdByLocalIdAndMap(sprite->sLocalId, sprite->sMapNum, sprite->sMapGroup, &objEventId)
|
2017-12-18 23:26:44 +01:00
|
|
|
|| sprite->animEnded)
|
|
|
|
{
|
2017-12-19 17:18:44 +01:00
|
|
|
FieldEffectStop(sprite, sprite->sFldEffId);
|
2017-12-18 23:26:44 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
struct Sprite *objEventSprite = &gSprites[gObjectEvents[objEventId].spriteId];
|
2017-12-19 17:18:44 +01:00
|
|
|
sprite->sData4 += sprite->sData3;
|
2019-11-21 04:55:44 +01:00
|
|
|
sprite->pos1.x = objEventSprite->pos1.x;
|
|
|
|
sprite->pos1.y = objEventSprite->pos1.y - 16;
|
|
|
|
sprite->pos2.x = objEventSprite->pos2.x;
|
|
|
|
sprite->pos2.y = objEventSprite->pos2.y + sprite->sData4;
|
2017-12-19 17:18:44 +01:00
|
|
|
if (sprite->sData4)
|
|
|
|
sprite->sData3++;
|
2017-12-18 23:26:44 +01:00
|
|
|
else
|
2017-12-19 17:18:44 +01:00
|
|
|
sprite->sData3 = 0;
|
2017-12-18 23:26:44 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-19 17:18:44 +01:00
|
|
|
#undef sLocalId
|
|
|
|
#undef sMapNum
|
|
|
|
#undef sMapGroup
|
|
|
|
#undef sData3
|
|
|
|
#undef sData4
|
|
|
|
#undef sFldEffId
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
u8 GetCurrentApproachingTrainerObjectEventId(void)
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
|
|
|
if (gApproachingTrainerId == 0)
|
2019-11-21 04:55:44 +01:00
|
|
|
return gApproachingTrainers[0].objectEventId;
|
2017-12-18 23:26:44 +01:00
|
|
|
else
|
2019-11-21 04:55:44 +01:00
|
|
|
return gApproachingTrainers[1].objectEventId;
|
2017-12-18 23:26:44 +01:00
|
|
|
}
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
u8 GetChosenApproachingTrainerObjectEventId(u8 arrayId)
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
|
|
|
if (arrayId >= ARRAY_COUNT(gApproachingTrainers))
|
|
|
|
return 0;
|
|
|
|
else if (arrayId == 0)
|
2019-11-21 04:55:44 +01:00
|
|
|
return gApproachingTrainers[0].objectEventId;
|
2017-12-18 23:26:44 +01:00
|
|
|
else
|
2019-11-21 04:55:44 +01:00
|
|
|
return gApproachingTrainers[1].objectEventId;
|
2017-12-18 23:26:44 +01:00
|
|
|
}
|
|
|
|
|
2019-11-01 08:41:55 +01:00
|
|
|
void PlayerFaceTrainerAfterBattle(void)
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *objEvent;
|
2017-12-18 23:26:44 +01:00
|
|
|
|
2019-11-01 08:41:55 +01:00
|
|
|
if (gTrainerApproachedPlayer == TRUE)
|
2017-12-18 23:26:44 +01:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
objEvent = &gObjectEvents[gApproachingTrainers[gWhichTrainerToFaceAfterBattle].objectEventId];
|
|
|
|
gPostBattleMovementScript[0] = GetFaceDirectionMovementAction(GetOppositeDirection(objEvent->facingDirection));
|
2019-11-01 08:41:55 +01:00
|
|
|
gPostBattleMovementScript[1] = MOVEMENT_ACTION_STEP_END;
|
2019-11-21 05:12:51 +01:00
|
|
|
ScriptMovement_StartObjectMovementScript(OBJ_EVENT_ID_PLAYER, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, gPostBattleMovementScript);
|
2017-12-18 23:26:44 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
objEvent = &gObjectEvents[gPlayerAvatar.objectEventId];
|
|
|
|
gPostBattleMovementScript[0] = GetFaceDirectionMovementAction(objEvent->facingDirection);
|
2019-11-01 08:41:55 +01:00
|
|
|
gPostBattleMovementScript[1] = MOVEMENT_ACTION_STEP_END;
|
2019-11-21 05:12:51 +01:00
|
|
|
ScriptMovement_StartObjectMovementScript(OBJ_EVENT_ID_PLAYER, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, gPostBattleMovementScript);
|
2017-12-18 23:26:44 +01:00
|
|
|
}
|
|
|
|
|
2019-11-21 05:12:51 +01:00
|
|
|
SetMovingNpcId(OBJ_EVENT_ID_PLAYER);
|
2017-12-18 23:26:44 +01:00
|
|
|
}
|