2018-04-10 11:25:25 +02:00
|
|
|
#include "global.h"
|
|
|
|
#include "script_movement.h"
|
2018-06-11 15:34:19 +02:00
|
|
|
#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"
|
|
|
|
#include "constants/event_object_movement_constants.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 eventObjId, const u8 *movementScript);
|
|
|
|
static u8 GetMovementScriptIdFromEventObjectId(u8 taskId, u8 eventObjId);
|
|
|
|
static bool8 IsMovementScriptFinished(u8 taskId, u8 moveScrId);
|
|
|
|
static void ScriptMovement_AddNewMovement(u8 taskId, u8 moveScrId, u8 eventObjId, 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 eventObjId, const u8 *movementScript);
|
2018-04-10 11:25:25 +02:00
|
|
|
|
|
|
|
// EWRAM_DATA
|
2019-09-15 21:30:35 +02:00
|
|
|
static EWRAM_DATA const u8 *gMovementScripts[EVENT_OBJECTS_COUNT] = {0};
|
2018-04-10 11:25:25 +02:00
|
|
|
|
|
|
|
// text
|
|
|
|
bool8 ScriptMovement_StartObjectMovementScript(u8 localId, u8 mapNum, u8 mapGroup, const u8 *movementScript)
|
|
|
|
{
|
2018-06-12 02:11:48 +02:00
|
|
|
u8 eventObjId;
|
2018-04-10 11:25:25 +02:00
|
|
|
|
2018-06-12 02:11:48 +02:00
|
|
|
if (TryGetEventObjectIdByLocalIdAndMap(localId, mapNum, mapGroup, &eventObjId))
|
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(), eventObjId, 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
|
|
|
{
|
2018-06-12 02:11:48 +02:00
|
|
|
u8 eventObjId;
|
2019-09-15 21:30:35 +02:00
|
|
|
u8 taskId;
|
|
|
|
u8 moveScrId;
|
2018-04-10 11:25:25 +02:00
|
|
|
|
2019-09-15 21:30:35 +02:00
|
|
|
if (TryGetEventObjectIdByLocalIdAndMap(localId, mapNum, mapGroup, &eventObjId))
|
2018-04-10 11:25:25 +02:00
|
|
|
return TRUE;
|
2019-09-15 21:30:35 +02:00
|
|
|
taskId = GetMoveObjectsTaskId();
|
|
|
|
moveScrId = GetMovementScriptIdFromEventObjectId(taskId, eventObjId);
|
|
|
|
if (moveScrId == EVENT_OBJECTS_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
|
|
|
}
|
|
|
|
|
2019-09-16 06:22:50 +02:00
|
|
|
void ScriptMovement_UnfreezeEventObjects(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
|
|
|
}
|
|
|
|
|
2019-09-15 21:30:35 +02:00
|
|
|
static bool8 ScriptMovement_TryAddNewMovement(u8 taskId, u8 eventObjId, 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
|
|
|
|
2019-09-15 21:30:35 +02:00
|
|
|
moveScrId = GetMovementScriptIdFromEventObjectId(taskId, eventObjId);
|
|
|
|
if (moveScrId != EVENT_OBJECTS_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
|
|
|
|
{
|
2019-09-15 21:30:35 +02:00
|
|
|
ScriptMovement_AddNewMovement(taskId, moveScrId, eventObjId, movementScript);
|
2018-04-10 11:25:25 +02:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
2019-09-15 21:30:35 +02:00
|
|
|
moveScrId = GetMovementScriptIdFromEventObjectId(taskId, EVENT_OBJ_ID_PLAYER);
|
|
|
|
if (moveScrId == EVENT_OBJECTS_COUNT)
|
2018-04-10 11:25:25 +02:00
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-09-15 21:30:35 +02:00
|
|
|
ScriptMovement_AddNewMovement(taskId, moveScrId, eventObjId, movementScript);
|
2018-04-10 11:25:25 +02:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-15 21:30:35 +02:00
|
|
|
static u8 GetMovementScriptIdFromEventObjectId(u8 taskId, u8 eventObjId)
|
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 < EVENT_OBJECTS_COUNT; i++, moveScriptId++)
|
2018-04-10 11:25:25 +02:00
|
|
|
{
|
2019-09-15 21:30:35 +02:00
|
|
|
if (*moveScriptId == eventObjId)
|
2018-04-10 11:25:25 +02:00
|
|
|
return i;
|
|
|
|
}
|
2019-09-15 21:30:35 +02:00
|
|
|
return EVENT_OBJECTS_COUNT;
|
2018-04-10 11:25:25 +02:00
|
|
|
}
|
|
|
|
|
2019-09-15 21:30:35 +02:00
|
|
|
static void LoadEventObjectIdPtrFromMovementScript(u8 taskId, u8 moveScrId, u8 **pEventObjId)
|
2018-04-10 11:25:25 +02:00
|
|
|
{
|
|
|
|
u8 i;
|
|
|
|
|
2019-09-15 21:30:35 +02:00
|
|
|
*pEventObjId = (u8 *)&gTasks[taskId].data[1];
|
|
|
|
for (i = 0; i < moveScrId; i++, (*pEventObjId)++)
|
2018-04-10 11:25:25 +02:00
|
|
|
;
|
|
|
|
}
|
|
|
|
|
2019-09-15 21:30:35 +02:00
|
|
|
static void SetEventObjectIdAtMovementScript(u8 taskId, u8 moveScrId, u8 eventObjId)
|
2018-04-10 11:25:25 +02:00
|
|
|
{
|
|
|
|
u8 *ptr;
|
|
|
|
|
2019-09-15 21:30:35 +02:00
|
|
|
LoadEventObjectIdPtrFromMovementScript(taskId, moveScrId, &ptr);
|
|
|
|
*ptr = eventObjId;
|
2018-04-10 11:25:25 +02:00
|
|
|
}
|
|
|
|
|
2019-09-15 21:30:35 +02:00
|
|
|
static void LoadEventObjectIdFromMovementScript(u8 taskId, u8 moveScrId, u8 *eventObjId)
|
2018-04-10 11:25:25 +02:00
|
|
|
{
|
|
|
|
u8 *ptr;
|
|
|
|
|
2019-09-15 21:30:35 +02:00
|
|
|
LoadEventObjectIdPtrFromMovementScript(taskId, moveScrId, &ptr);
|
|
|
|
*eventObjId = *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
|
|
|
}
|
|
|
|
|
2019-09-15 21:30:35 +02:00
|
|
|
static void ScriptMovement_AddNewMovement(u8 taskId, u8 moveScrId, u8 eventObjId, 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);
|
|
|
|
SetEventObjectIdAtMovementScript(taskId, moveScrId, eventObjId);
|
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
|
|
|
{
|
2018-06-12 02:11:48 +02:00
|
|
|
u8 *pEventObjId;
|
2018-04-10 11:25:25 +02:00
|
|
|
u8 i;
|
|
|
|
|
2018-06-12 02:11:48 +02:00
|
|
|
pEventObjId = (u8 *)&gTasks[taskId].data[1];
|
2019-09-15 21:30:35 +02:00
|
|
|
for (i = 0; i < EVENT_OBJECTS_COUNT; i++, pEventObjId++)
|
2018-04-10 11:25:25 +02:00
|
|
|
{
|
2018-06-12 02:11:48 +02:00
|
|
|
if (*pEventObjId != 0xFF)
|
2018-06-14 00:51:26 +02:00
|
|
|
UnfreezeEventObject(&gEventObjects[*pEventObjId]);
|
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;
|
2019-09-15 21:30:35 +02:00
|
|
|
u8 eventObjId;
|
2018-04-10 11:25:25 +02:00
|
|
|
|
2019-09-15 21:30:35 +02:00
|
|
|
for (i = 0; i < EVENT_OBJECTS_COUNT; i++)
|
2018-04-10 11:25:25 +02:00
|
|
|
{
|
2019-09-15 21:30:35 +02:00
|
|
|
LoadEventObjectIdFromMovementScript(taskId, i, &eventObjId);
|
|
|
|
if (eventObjId != 0xFF)
|
|
|
|
ScriptMovement_TakeStep(taskId, i, eventObjId, GetMovementScript(i));
|
2018-04-10 11:25:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-15 21:30:35 +02:00
|
|
|
static void ScriptMovement_TakeStep(u8 taskId, u8 moveScrId, u8 eventObjId, 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
|
|
|
|
2018-06-14 00:51:26 +02:00
|
|
|
if (EventObjectIsHeldMovementActive(&gEventObjects[eventObjId])
|
|
|
|
&& !EventObjectClearHeldMovementIfFinished(&gEventObjects[eventObjId]))
|
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);
|
2018-06-12 02:11:48 +02:00
|
|
|
FreezeEventObject(&gEventObjects[eventObjId]);
|
2018-04-10 11:25:25 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-09-15 21:30:35 +02:00
|
|
|
if (!EventObjectSetHeldMovement(&gEventObjects[eventObjId], 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
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|