342 lines
9.7 KiB
C
342 lines
9.7 KiB
C
#include "global.h"
|
|
#include "event_data.h"
|
|
#include "task.h"
|
|
#include "field_player_avatar.h"
|
|
#include "fieldmap.h"
|
|
#include "field_camera.h"
|
|
#include "constants/metatile_labels.h"
|
|
|
|
static EWRAM_DATA u8 sEscalatorTaskId = 0;
|
|
|
|
static void SetEscalatorMetatile(u8 taskId, const s16 *metatileIds, u16 metatileMasks);
|
|
static void Task_DrawEscalator(u8 taskId);
|
|
static void Task_DrawTeleporterHousing(u8 taskId);
|
|
static void Task_DrawTeleporterCable(u8 taskId);
|
|
|
|
#define ESCALATOR_STAGES 3
|
|
#define LAST_ESCALATOR_STAGE (ESCALATOR_STAGES - 1)
|
|
|
|
static const u16 sEscalatorMetatiles_BottomNextRail[ESCALATOR_STAGES] =
|
|
{
|
|
METATILE_PokemonCenter_Escalator_BottomNextRail_Transition2,
|
|
METATILE_PokemonCenter_Escalator_BottomNextRail_Transition1,
|
|
METATILE_PokemonCenter_Escalator_BottomNextRail_Normal
|
|
};
|
|
|
|
static const u16 sEscalatorMetatiles_BottomRail[ESCALATOR_STAGES] =
|
|
{
|
|
METATILE_PokemonCenter_Escalator_BottomRail_Transition2,
|
|
METATILE_PokemonCenter_Escalator_BottomRail_Transition1,
|
|
METATILE_PokemonCenter_Escalator_BottomRail_Normal
|
|
};
|
|
|
|
static const u16 sEscalatorMetatiles_BottomNext[ESCALATOR_STAGES] =
|
|
{
|
|
METATILE_PokemonCenter_Escalator_BottomNext_Transition2,
|
|
METATILE_PokemonCenter_Escalator_BottomNext_Transition1,
|
|
METATILE_PokemonCenter_Escalator_BottomNext_Normal
|
|
};
|
|
|
|
static const u16 sEscalatorMetatiles_Bottom[ESCALATOR_STAGES] =
|
|
{
|
|
METATILE_PokemonCenter_Escalator_Bottom_Transition2,
|
|
METATILE_PokemonCenter_Escalator_Bottom_Transition1,
|
|
METATILE_PokemonCenter_Escalator_Bottom_Normal
|
|
};
|
|
|
|
static const u16 sEscalatorMetatiles_TopNext[ESCALATOR_STAGES] =
|
|
{
|
|
METATILE_PokemonCenter_Escalator_TopNext_Normal,
|
|
METATILE_PokemonCenter_Escalator_TopNext_Transition1,
|
|
METATILE_PokemonCenter_Escalator_TopNext_Transition2
|
|
};
|
|
|
|
static const u16 sEscalatorMetatiles_Top[ESCALATOR_STAGES] =
|
|
{
|
|
METATILE_PokemonCenter_Escalator_Top_Normal,
|
|
METATILE_PokemonCenter_Escalator_Top_Transition1,
|
|
METATILE_PokemonCenter_Escalator_Top_Transition2
|
|
};
|
|
|
|
static const u16 sEscalatorMetatiles_TopNextRail[ESCALATOR_STAGES] =
|
|
{
|
|
METATILE_PokemonCenter_Escalator_TopNextRail_Normal,
|
|
METATILE_PokemonCenter_Escalator_TopNextRail_Transition1,
|
|
METATILE_PokemonCenter_Escalator_TopNextRail_Transition2
|
|
};
|
|
|
|
#define tState data[0]
|
|
#define tTransitionStage data[1]
|
|
#define tGoingUp data[2]
|
|
#define tDrawingEscalator data[3]
|
|
#define tPlayerX data[4]
|
|
#define tPlayerY data[5]
|
|
|
|
static void SetEscalatorMetatile(u8 taskId, const s16 *metatileIds, u16 metatileMasks)
|
|
{
|
|
s16 x, y, transitionStage;
|
|
s16 i, j;
|
|
|
|
x = gTasks[taskId].tPlayerX - 1;
|
|
y = gTasks[taskId].tPlayerY - 1;
|
|
transitionStage = gTasks[taskId].tTransitionStage;
|
|
|
|
// Check all the escalator sections and only progress the selected one to the next stage
|
|
if (!gTasks[taskId].tGoingUp)
|
|
{
|
|
for (i = 0; i < 3; i++)
|
|
{
|
|
for (j = 0; j < 3; j++)
|
|
{
|
|
s32 id = MapGridGetMetatileIdAt(x + j, y + i);
|
|
|
|
if (metatileIds[transitionStage] == (s16)id)
|
|
{
|
|
if (transitionStage != LAST_ESCALATOR_STAGE)
|
|
MapGridSetMetatileIdAt(x + j, y + i, metatileMasks | metatileIds[transitionStage + 1]);
|
|
else
|
|
MapGridSetMetatileIdAt(x + j, y + i, metatileMasks | metatileIds[0]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (i = 0; i < 3; i++)
|
|
{
|
|
for (j = 0; j < 3; j++)
|
|
{
|
|
s32 id = MapGridGetMetatileIdAt(x + j, y + i);
|
|
|
|
if (metatileIds[LAST_ESCALATOR_STAGE - transitionStage] == (s16)id)
|
|
{
|
|
if (transitionStage != LAST_ESCALATOR_STAGE)
|
|
MapGridSetMetatileIdAt(x + j, y + i, metatileMasks | metatileIds[1 - transitionStage]);
|
|
else
|
|
MapGridSetMetatileIdAt(x + j, y + i, metatileMasks | metatileIds[LAST_ESCALATOR_STAGE]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void Task_DrawEscalator(u8 taskId)
|
|
{
|
|
s16 *data = gTasks[taskId].data;
|
|
u16 state;
|
|
|
|
tDrawingEscalator = TRUE;
|
|
|
|
// Set tile for each section of the escalator in sequence for current transition stage
|
|
switch (tState)
|
|
{
|
|
case 0:
|
|
SetEscalatorMetatile(taskId, sEscalatorMetatiles_BottomNextRail, 0);
|
|
break;
|
|
case 1:
|
|
SetEscalatorMetatile(taskId, sEscalatorMetatiles_BottomRail, 0);
|
|
break;
|
|
case 2:
|
|
SetEscalatorMetatile(taskId, sEscalatorMetatiles_BottomNext, METATILE_COLLISION_MASK);
|
|
break;
|
|
case 3:
|
|
SetEscalatorMetatile(taskId, sEscalatorMetatiles_Bottom, 0);
|
|
break;
|
|
case 4:
|
|
SetEscalatorMetatile(taskId, sEscalatorMetatiles_TopNext, METATILE_COLLISION_MASK);
|
|
break;
|
|
case 5:
|
|
SetEscalatorMetatile(taskId, sEscalatorMetatiles_Top, 0);
|
|
break;
|
|
case 6:
|
|
SetEscalatorMetatile(taskId, sEscalatorMetatiles_TopNextRail, 0);
|
|
default:
|
|
break;
|
|
}
|
|
|
|
tState = (tState + 1) & 7;
|
|
state = tState & 7;
|
|
|
|
// If all sections of the escalator have been set, draw map and progress to next stage
|
|
if (state == 0)
|
|
{
|
|
DrawWholeMapView();
|
|
tTransitionStage = (tTransitionStage + 1) % ESCALATOR_STAGES;
|
|
tDrawingEscalator = FALSE;
|
|
}
|
|
}
|
|
|
|
static u8 CreateEscalatorTask(bool16 goingUp)
|
|
{
|
|
u8 taskId;
|
|
s16 *data;
|
|
|
|
taskId = CreateTask(Task_DrawEscalator, 0);
|
|
data = gTasks[taskId].data;
|
|
PlayerGetDestCoords(&tPlayerX, &tPlayerY);
|
|
tState = 0;
|
|
tTransitionStage = 0;
|
|
tGoingUp = goingUp;
|
|
Task_DrawEscalator(taskId);
|
|
return taskId;
|
|
}
|
|
|
|
void StartEscalator(bool8 goingUp)
|
|
{
|
|
u8 taskId;
|
|
|
|
taskId = CreateEscalatorTask(goingUp);
|
|
sEscalatorTaskId = taskId;
|
|
}
|
|
|
|
void StopEscalator(void)
|
|
{
|
|
DestroyTask(sEscalatorTaskId);
|
|
}
|
|
|
|
bool8 IsEscalatorMoving(void)
|
|
{
|
|
if (gTasks[sEscalatorTaskId].tDrawingEscalator == FALSE)
|
|
{
|
|
if (gTasks[sEscalatorTaskId].tTransitionStage != LAST_ESCALATOR_STAGE)
|
|
return TRUE;
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
#undef tState
|
|
#undef tTransitionStage
|
|
#undef tGoingUp
|
|
#undef tDrawingEscalator
|
|
#undef tPlayerX
|
|
#undef tPlayerY
|
|
|
|
#define tTimer data[0]
|
|
#define tState data[1]
|
|
#define tX data[2]
|
|
#define tY data[3]
|
|
|
|
void AnimateTeleporterHousing(void)
|
|
{
|
|
u8 taskId;
|
|
s16 *data;
|
|
|
|
taskId = CreateTask(Task_DrawTeleporterHousing, 0);
|
|
gTasks[taskId].tTimer = 0;
|
|
gTasks[taskId].tState = 0;
|
|
data = gTasks[taskId].data;
|
|
PlayerGetDestCoords(&tX, &tY);
|
|
|
|
// Set the coords of whichever teleporter is being animated
|
|
// 0 for the right teleporter, 1 for the left teleporter
|
|
if (gSpecialVar_0x8004 == 0)
|
|
{
|
|
gTasks[taskId].tX += 6;
|
|
gTasks[taskId].tY -= 5;
|
|
}
|
|
else
|
|
{
|
|
gTasks[taskId].tX -= 1;
|
|
gTasks[taskId].tY -= 5;
|
|
}
|
|
}
|
|
|
|
static void Task_DrawTeleporterHousing(u8 taskId)
|
|
{
|
|
s16 *data = gTasks[taskId].data;
|
|
|
|
if (tTimer == 0)
|
|
{
|
|
// Alternate the teleporter light / brightness of the teleporter door
|
|
if ((tState & 1) == 0)
|
|
{
|
|
MapGridSetMetatileIdAt(tX, tY, METATILE_SeaCottage_Teleporter_Light_Yellow | METATILE_COLLISION_MASK);
|
|
MapGridSetMetatileIdAt(tX, tY + 2, METATILE_SeaCottage_Teleporter_Door_HalfGlowing | METATILE_COLLISION_MASK);
|
|
}
|
|
else
|
|
{
|
|
MapGridSetMetatileIdAt(tX, tY, METATILE_SeaCottage_Teleporter_Light_Red | METATILE_COLLISION_MASK);
|
|
MapGridSetMetatileIdAt(tX, tY + 2, METATILE_SeaCottage_Teleporter_Door_FullGlowing | METATILE_COLLISION_MASK);
|
|
}
|
|
CurrentMapDrawMetatileAt(tX, tY);
|
|
CurrentMapDrawMetatileAt(tX, tY + 2);
|
|
}
|
|
|
|
tTimer++;
|
|
if (tTimer != 16)
|
|
return;
|
|
|
|
tTimer = 0;
|
|
tState++;
|
|
if (tState != 13)
|
|
return;
|
|
|
|
MapGridSetMetatileIdAt(tX, tY, METATILE_SeaCottage_Teleporter_Light_Green | METATILE_COLLISION_MASK);
|
|
MapGridSetMetatileIdAt(tX, tY + 2, METATILE_SeaCottage_Teleporter_Door | METATILE_COLLISION_MASK);
|
|
CurrentMapDrawMetatileAt(tX, tY);
|
|
CurrentMapDrawMetatileAt(tX, tY + 2);
|
|
DestroyTask(taskId);
|
|
}
|
|
|
|
void AnimateTeleporterCable(void)
|
|
{
|
|
u8 taskId;
|
|
s16 *data;
|
|
|
|
taskId = CreateTask(Task_DrawTeleporterCable, 0);
|
|
gTasks[taskId].tTimer = 0;
|
|
gTasks[taskId].tState = 0;
|
|
data = gTasks[taskId].data;
|
|
PlayerGetDestCoords(&tX, &tY);
|
|
gTasks[taskId].tX += 4;
|
|
gTasks[taskId].tY -= 5;
|
|
}
|
|
|
|
static void Task_DrawTeleporterCable(u8 taskId)
|
|
{
|
|
s16 *data = gTasks[taskId].data;
|
|
|
|
if (tTimer == 0)
|
|
{
|
|
if (tState != 0)
|
|
{
|
|
// Set default cable tiles to clear the ball
|
|
MapGridSetMetatileIdAt(tX, tY, METATILE_SeaCottage_Teleporter_Cable_Top | METATILE_COLLISION_MASK);
|
|
MapGridSetMetatileIdAt(tX, tY + 1, METATILE_SeaCottage_Teleporter_Cable_Bottom | METATILE_COLLISION_MASK);
|
|
CurrentMapDrawMetatileAt(tX, tY);
|
|
CurrentMapDrawMetatileAt(tX, tY + 1);
|
|
|
|
// End after drawing 4 times (length of the cable)
|
|
if (tState == 4)
|
|
{
|
|
DestroyTask(taskId);
|
|
return;
|
|
}
|
|
|
|
tX--;
|
|
}
|
|
|
|
// Draw the cable ball
|
|
MapGridSetMetatileIdAt(tX, tY, METATILE_SeaCottage_Teleporter_CableBall_Top | METATILE_COLLISION_MASK);
|
|
MapGridSetMetatileIdAt(tX, tY + 1, METATILE_SeaCottage_Teleporter_CableBall_Bottom | METATILE_COLLISION_MASK);
|
|
CurrentMapDrawMetatileAt(tX, tY);
|
|
CurrentMapDrawMetatileAt(tX, tY + 1);
|
|
}
|
|
|
|
tTimer++;
|
|
if (tTimer == 4)
|
|
{
|
|
tTimer = 0;
|
|
tState++;
|
|
}
|
|
}
|
|
|
|
#undef tTimer
|
|
#undef tState
|
|
#undef tX
|
|
#undef tY
|