pokeemerald/src/script_movement.c

235 lines
6.4 KiB
C
Raw Normal View History

2018-04-10 11:25:25 +02:00
#include "global.h"
#include "script_movement.h"
#include "event_object_movement.h"
2018-04-10 11:25:25 +02:00
#include "task.h"
#include "util.h"
2019-09-15 21:30:35 +02:00
#include "constants/event_objects.h"
2019-11-21 20:03:35 +01:00
#include "constants/event_object_movement.h"
2018-04-10 11:25:25 +02:00
// static functions
2019-09-15 21:30:35 +02:00
static void ScriptMovement_StartMoveObjects(u8 priority);
static u8 GetMoveObjectsTaskId(void);
static bool8 ScriptMovement_TryAddNewMovement(u8 taskId, u8 objEventId, const u8 *movementScript);
static u8 GetMovementScriptIdFromObjectEventId(u8 taskId, u8 objEventId);
2019-09-15 21:30:35 +02:00
static bool8 IsMovementScriptFinished(u8 taskId, u8 moveScrId);
static void ScriptMovement_AddNewMovement(u8 taskId, u8 moveScrId, u8 objEventId, const u8 *movementScript);
2019-09-16 06:22:50 +02:00
static void ScriptMovement_UnfreezeActiveObjects(u8 taskId);
2019-09-15 21:30:35 +02:00
static void ScriptMovement_MoveObjects(u8 taskId);
static void ScriptMovement_TakeStep(u8 taskId, u8 moveScrId, u8 objEventId, const u8 *movementScript);
2018-04-10 11:25:25 +02:00
// EWRAM_DATA
static EWRAM_DATA const u8 *gMovementScripts[OBJECT_EVENTS_COUNT] = {0};
2018-04-10 11:25:25 +02:00
// text
bool8 ScriptMovement_StartObjectMovementScript(u8 localId, u8 mapNum, u8 mapGroup, const u8 *movementScript)
{
u8 objEventId;
2018-04-10 11:25:25 +02:00
if (TryGetObjectEventIdByLocalIdAndMap(localId, mapNum, mapGroup, &objEventId))
2018-04-10 11:25:25 +02:00
return TRUE;
2019-09-15 21:30:35 +02:00
if (!FuncIsActiveTask(ScriptMovement_MoveObjects))
ScriptMovement_StartMoveObjects(50);
return ScriptMovement_TryAddNewMovement(GetMoveObjectsTaskId(), objEventId, movementScript);
2018-04-10 11:25:25 +02:00
}
2019-09-15 21:30:35 +02:00
bool8 ScriptMovement_IsObjectMovementFinished(u8 localId, u8 mapNum, u8 mapGroup)
2018-04-10 11:25:25 +02:00
{
u8 objEventId;
2019-09-15 21:30:35 +02:00
u8 taskId;
u8 moveScrId;
2018-04-10 11:25:25 +02:00
if (TryGetObjectEventIdByLocalIdAndMap(localId, mapNum, mapGroup, &objEventId))
2018-04-10 11:25:25 +02:00
return TRUE;
2019-09-15 21:30:35 +02:00
taskId = GetMoveObjectsTaskId();
moveScrId = GetMovementScriptIdFromObjectEventId(taskId, objEventId);
if (moveScrId == OBJECT_EVENTS_COUNT)
2018-04-10 11:25:25 +02:00
return TRUE;
2019-09-15 21:30:35 +02:00
return IsMovementScriptFinished(taskId, moveScrId);
2018-04-10 11:25:25 +02:00
}
void ScriptMovement_UnfreezeObjectEvents(void)
2018-04-10 11:25:25 +02:00
{
u8 taskId;
2019-09-15 21:30:35 +02:00
taskId = GetMoveObjectsTaskId();
2018-04-10 11:25:25 +02:00
if (taskId != 0xFF)
{
2019-09-16 06:22:50 +02:00
ScriptMovement_UnfreezeActiveObjects(taskId);
2018-04-10 11:25:25 +02:00
DestroyTask(taskId);
}
}
2019-09-15 21:30:35 +02:00
static void ScriptMovement_StartMoveObjects(u8 priority)
2018-04-10 11:25:25 +02:00
{
u8 taskId;
u8 i;
2019-09-15 21:30:35 +02:00
taskId = CreateTask(ScriptMovement_MoveObjects, priority);
for (i = 1; i < NUM_TASK_DATA; i++)
2018-04-10 11:25:25 +02:00
gTasks[taskId].data[i] = 0xFFFF;
}
2019-09-15 21:30:35 +02:00
static u8 GetMoveObjectsTaskId(void)
2018-04-10 11:25:25 +02:00
{
2019-09-15 21:30:35 +02:00
return FindTaskIdByFunc(ScriptMovement_MoveObjects);
2018-04-10 11:25:25 +02:00
}
static bool8 ScriptMovement_TryAddNewMovement(u8 taskId, u8 objEventId, const u8 *movementScript)
2018-04-10 11:25:25 +02:00
{
2019-09-15 21:30:35 +02:00
u8 moveScrId;
2018-04-10 11:25:25 +02:00
moveScrId = GetMovementScriptIdFromObjectEventId(taskId, objEventId);
if (moveScrId != OBJECT_EVENTS_COUNT)
2018-04-10 11:25:25 +02:00
{
2019-09-15 21:30:35 +02:00
if (IsMovementScriptFinished(taskId, moveScrId) == 0)
2018-04-10 11:25:25 +02:00
{
return TRUE;
}
else
{
ScriptMovement_AddNewMovement(taskId, moveScrId, objEventId, movementScript);
2018-04-10 11:25:25 +02:00
return FALSE;
}
}
moveScrId = GetMovementScriptIdFromObjectEventId(taskId, OBJ_EVENT_ID_PLAYER);
if (moveScrId == OBJECT_EVENTS_COUNT)
2018-04-10 11:25:25 +02:00
{
return TRUE;
}
else
{
ScriptMovement_AddNewMovement(taskId, moveScrId, objEventId, movementScript);
2018-04-10 11:25:25 +02:00
return FALSE;
}
}
static u8 GetMovementScriptIdFromObjectEventId(u8 taskId, u8 objEventId)
2018-04-10 11:25:25 +02:00
{
2019-09-15 21:30:35 +02:00
u8 *moveScriptId;
2018-04-10 11:25:25 +02:00
u8 i;
2019-09-15 21:30:35 +02:00
moveScriptId = (u8 *)&gTasks[taskId].data[1];
for (i = 0; i < OBJECT_EVENTS_COUNT; i++, moveScriptId++)
2018-04-10 11:25:25 +02:00
{
if (*moveScriptId == objEventId)
2018-04-10 11:25:25 +02:00
return i;
}
return OBJECT_EVENTS_COUNT;
2018-04-10 11:25:25 +02:00
}
2019-11-21 06:14:40 +01:00
static void LoadObjectEventIdPtrFromMovementScript(u8 taskId, u8 moveScrId, u8 **pObjEventId)
2018-04-10 11:25:25 +02:00
{
u8 i;
2019-11-21 06:14:40 +01:00
*pObjEventId = (u8 *)&gTasks[taskId].data[1];
for (i = 0; i < moveScrId; i++, (*pObjEventId)++)
2018-04-10 11:25:25 +02:00
;
}
static void SetObjectEventIdAtMovementScript(u8 taskId, u8 moveScrId, u8 objEventId)
2018-04-10 11:25:25 +02:00
{
u8 *ptr;
LoadObjectEventIdPtrFromMovementScript(taskId, moveScrId, &ptr);
*ptr = objEventId;
2018-04-10 11:25:25 +02:00
}
static void LoadObjectEventIdFromMovementScript(u8 taskId, u8 moveScrId, u8 *objEventId)
2018-04-10 11:25:25 +02:00
{
u8 *ptr;
LoadObjectEventIdPtrFromMovementScript(taskId, moveScrId, &ptr);
*objEventId = *ptr;
2018-04-10 11:25:25 +02:00
}
2019-09-15 21:30:35 +02:00
static void ClearMovementScriptFinished(u8 taskId, u8 moveScrId)
2018-04-10 11:25:25 +02:00
{
2019-09-15 21:30:35 +02:00
u16 mask = ~gBitTable[moveScrId];
2018-04-10 11:25:25 +02:00
2019-09-15 21:30:35 +02:00
gTasks[taskId].data[0] &= mask;
2018-04-10 11:25:25 +02:00
}
2019-09-15 21:30:35 +02:00
static void SetMovementScriptFinished(u8 taskId, u8 moveScrId)
2018-04-10 11:25:25 +02:00
{
2019-09-15 21:30:35 +02:00
gTasks[taskId].data[0] |= gBitTable[moveScrId];
2018-04-10 11:25:25 +02:00
}
2019-09-15 21:30:35 +02:00
static bool8 IsMovementScriptFinished(u8 taskId, u8 moveScrId)
2018-04-10 11:25:25 +02:00
{
2019-09-15 21:30:35 +02:00
u16 moveScriptFinished = (u16)gTasks[taskId].data[0] & gBitTable[moveScrId];
2018-04-10 11:25:25 +02:00
2019-09-15 21:30:35 +02:00
if (moveScriptFinished != 0)
2018-04-10 11:25:25 +02:00
return TRUE;
else
return FALSE;
}
2019-09-15 21:30:35 +02:00
static void SetMovementScript(u8 moveScrId, const u8 *movementScript)
2018-04-10 11:25:25 +02:00
{
2019-09-15 21:30:35 +02:00
gMovementScripts[moveScrId] = movementScript;
2018-04-10 11:25:25 +02:00
}
2019-09-15 21:30:35 +02:00
static const u8 *GetMovementScript(u8 moveScrId)
2018-04-10 11:25:25 +02:00
{
2019-09-15 21:30:35 +02:00
return gMovementScripts[moveScrId];
2018-04-10 11:25:25 +02:00
}
static void ScriptMovement_AddNewMovement(u8 taskId, u8 moveScrId, u8 objEventId, const u8 *movementScript)
2018-04-10 11:25:25 +02:00
{
2019-09-15 21:30:35 +02:00
ClearMovementScriptFinished(taskId, moveScrId);
SetMovementScript(moveScrId, movementScript);
SetObjectEventIdAtMovementScript(taskId, moveScrId, objEventId);
2018-04-10 11:25:25 +02:00
}
2019-09-16 06:22:50 +02:00
static void ScriptMovement_UnfreezeActiveObjects(u8 taskId)
2018-04-10 11:25:25 +02:00
{
2019-11-21 06:14:40 +01:00
u8 *pObjEventId;
2018-04-10 11:25:25 +02:00
u8 i;
2019-11-21 06:14:40 +01:00
pObjEventId = (u8 *)&gTasks[taskId].data[1];
for (i = 0; i < OBJECT_EVENTS_COUNT; i++, pObjEventId++)
2018-04-10 11:25:25 +02:00
{
2019-11-21 06:14:40 +01:00
if (*pObjEventId != 0xFF)
UnfreezeObjectEvent(&gObjectEvents[*pObjEventId]);
2018-04-10 11:25:25 +02:00
}
}
2019-09-15 21:30:35 +02:00
static void ScriptMovement_MoveObjects(u8 taskId)
2018-04-10 11:25:25 +02:00
{
u8 i;
u8 objEventId;
2018-04-10 11:25:25 +02:00
for (i = 0; i < OBJECT_EVENTS_COUNT; i++)
2018-04-10 11:25:25 +02:00
{
LoadObjectEventIdFromMovementScript(taskId, i, &objEventId);
if (objEventId != 0xFF)
ScriptMovement_TakeStep(taskId, i, objEventId, GetMovementScript(i));
2018-04-10 11:25:25 +02:00
}
}
static void ScriptMovement_TakeStep(u8 taskId, u8 moveScrId, u8 objEventId, const u8 *movementScript)
2018-04-10 11:25:25 +02:00
{
2019-09-15 21:30:35 +02:00
u8 nextMoveActionId;
2018-04-10 11:25:25 +02:00
if (ObjectEventIsHeldMovementActive(&gObjectEvents[objEventId])
&& !ObjectEventClearHeldMovementIfFinished(&gObjectEvents[objEventId]))
2018-04-10 11:25:25 +02:00
return;
2019-09-15 21:30:35 +02:00
nextMoveActionId = *movementScript;
if (nextMoveActionId == MOVEMENT_ACTION_STEP_END)
2018-04-10 11:25:25 +02:00
{
2019-09-15 21:30:35 +02:00
SetMovementScriptFinished(taskId, moveScrId);
FreezeObjectEvent(&gObjectEvents[objEventId]);
2018-04-10 11:25:25 +02:00
}
else
{
if (!ObjectEventSetHeldMovement(&gObjectEvents[objEventId], nextMoveActionId))
2018-04-10 11:25:25 +02:00
{
2019-09-15 21:30:35 +02:00
movementScript++;
SetMovementScript(moveScrId, movementScript);
2018-04-10 11:25:25 +02:00
}
}
}