summaryrefslogtreecommitdiff
path: root/src/rotating_tile_puzzle.c
diff options
context:
space:
mode:
authorGriffinR <griffin.richards@comcast.net>2019-10-16 04:09:30 -0400
committerGriffinR <griffin.richards@comcast.net>2019-10-16 04:09:30 -0400
commit0f15264595e66f1de9aa030b69a9fedc9c75f13e (patch)
tree47d88f9de8c8ba3f38edec030002a418c61cafd7 /src/rotating_tile_puzzle.c
parent90a05cf824b14861b7c1c942aebae31f9cb502ea (diff)
Document rotating_tile_puzzle
Diffstat (limited to 'src/rotating_tile_puzzle.c')
-rw-r--r--src/rotating_tile_puzzle.c173
1 files changed, 98 insertions, 75 deletions
diff --git a/src/rotating_tile_puzzle.c b/src/rotating_tile_puzzle.c
index acc1c11cc..7238ec751 100644
--- a/src/rotating_tile_puzzle.c
+++ b/src/rotating_tile_puzzle.c
@@ -8,32 +8,35 @@
#include "constants/event_objects.h"
#include "constants/metatile_labels.h"
-// Movement scripts.
-extern const u8 gUnknown_08612698[];
-extern const u8 gUnknown_0861269C[];
-extern const u8 gUnknown_086126A0[];
-extern const u8 gUnknown_086126A4[];
-extern const u8 MossdeepGym_Movement_FaceRight[];
-extern const u8 MossdeepGym_Movement_FaceDown[];
-extern const u8 MossdeepGym_Movement_FaceLeft[];
-extern const u8 MossdeepGym_Movement_FaceUp[];
-
-struct MossdeepSubStruct
+extern const u8 RotatingTilePuzzle_Movement_ShiftRight[];
+extern const u8 RotatingTilePuzzle_Movement_ShiftDown[];
+extern const u8 RotatingTilePuzzle_Movement_ShiftLeft[];
+extern const u8 RotatingTilePuzzle_Movement_ShiftUp[];
+extern const u8 RotatingTilePuzzle_Movement_FaceRight[];
+extern const u8 RotatingTilePuzzle_Movement_FaceDown[];
+extern const u8 RotatingTilePuzzle_Movement_FaceLeft[];
+extern const u8 RotatingTilePuzzle_Movement_FaceUp[];
+
+#define ROTATE_COUNTERCLOCKWISE 0
+#define ROTATE_CLOCKWISE 1
+#define ROTATE_NONE 2
+
+struct RotatingTileObject
{
- u8 unk0;
+ u8 prevPuzzleTileNum;
u8 eventTemplateId;
};
struct RotatingTilePuzzle
{
- struct MossdeepSubStruct objects[EVENT_OBJECTS_COUNT];
- u8 count;
+ struct RotatingTileObject objects[EVENT_OBJECTS_COUNT];
+ u8 numObjects;
bool8 isTrickHouse;
};
// This file's functions.
-static void AddEventObject(u8 eventTemplateId, u8 arg1);
-static void sub_81A8D94(u8 eventTemplateId, u8 arg1);
+static void SaveRotatingTileObject(u8 eventTemplateId, u8 arg1);
+static void TurnUnsavedRotatingTileObject(u8 eventTemplateId, u8 arg1);
// EWRAM vars
EWRAM_DATA static struct RotatingTilePuzzle *sRotatingTilePuzzle = NULL;
@@ -47,7 +50,7 @@ void InitRotatingTilePuzzle(bool8 isTrickHouse)
sRotatingTilePuzzle->isTrickHouse = isTrickHouse;
}
-void FinishMossdeepGymTiles(void)
+void FreeRotatingTilePuzzle(void)
{
u8 id;
@@ -59,7 +62,7 @@ void FinishMossdeepGymTiles(void)
ScriptMovement_UnfreezeEventObjects();
}
-u16 MossdeepGym_MoveEvents(u8 puzzleNumber)
+u16 MoveRotatingTileObjects(u8 puzzleNumber)
{
u8 i;
struct EventObjectTemplate *eventObjects = gSaveBlock1Ptr->eventObjectTemplates;
@@ -68,47 +71,54 @@ u16 MossdeepGym_MoveEvents(u8 puzzleNumber)
for (i = 0; i < EVENT_OBJECT_TEMPLATES_COUNT; i++)
{
s32 puzzleTileStart;
- u8 r5;
+ u8 puzzleTileNum;
s16 x = eventObjects[i].x + 7;
s16 y = eventObjects[i].y + 7;
u16 metatile = MapGridGetMetatileIdAt(x, y);
if (!sRotatingTilePuzzle->isTrickHouse)
- puzzleTileStart = METATILE_MossdeepGym_YellowRightArrow;
+ puzzleTileStart = METATILE_MossdeepGym_YellowArrow_Right;
else
puzzleTileStart = METATILE_TrickHousePuzzle_Arrow_YellowOnWhite_Right;
- if (metatile < METATILE_MossdeepGym_YellowRightArrow)
+ // Object is on a metatile before the puzzle tile section
+ // UB: Because this is not if (metatile < puzzleTileStart), for the trick house (metatile - puzzleTileStart) below can result in casting a negative value to u8
+ if (metatile < METATILE_MossdeepGym_YellowArrow_Right)
continue;
+ // Object is on a metatile after the puzzle tile section (never occurs, in both cases the puzzle tiles are last)
if ((u8)((metatile - puzzleTileStart) / 8) >= 5)
continue;
+
+ // Object is on a metatile in puzzle tile section, but not one of the currently rotating color
if ((u8)((metatile - puzzleTileStart) / 8) != puzzleNumber)
continue;
- r5 = (u8)((metatile - puzzleTileStart) % 8);
- if (r5 < 4)
+ puzzleTileNum = (u8)((metatile - puzzleTileStart) % 8);
+
+ // First 4 puzzle tiles are the colored arrows
+ if (puzzleTileNum < 4)
{
s8 x = 0;
s8 y = 0;
const u8 *movementScript;
- switch (r5)
+ switch (puzzleTileNum)
{
- case 0:
- movementScript = gUnknown_08612698;
+ case 0: // Right Arrow
+ movementScript = RotatingTilePuzzle_Movement_ShiftRight;
x = 1;
break;
- case 1:
- movementScript = gUnknown_0861269C;
+ case 1: // Down Arrow
+ movementScript = RotatingTilePuzzle_Movement_ShiftDown;
y = 1;
break;
- case 2:
- movementScript = gUnknown_086126A0;
+ case 2: // Left Arrow
+ movementScript = RotatingTilePuzzle_Movement_ShiftLeft;
x = -1;
break;
- case 3:
- movementScript = gUnknown_086126A4;
+ case 3: // Up Arrow
+ movementScript = RotatingTilePuzzle_Movement_ShiftUp;
y = -1;
break;
default:
@@ -119,13 +129,14 @@ u16 MossdeepGym_MoveEvents(u8 puzzleNumber)
eventObjects[i].y += y;
if (GetEventObjectIdByLocalIdAndMap(eventObjects[i].localId, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup) != EVENT_OBJECTS_COUNT)
{
- AddEventObject(i, r5);
+ SaveRotatingTileObject(i, puzzleTileNum);
localId = eventObjects[i].localId;
ScriptMovement_StartObjectMovementScript(localId, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, movementScript);
}
+ // Never reached in normal gameplay
else
{
- sub_81A8D94(i, r5);
+ TurnUnsavedRotatingTileObject(i, puzzleTileNum);
}
}
}
@@ -133,7 +144,7 @@ u16 MossdeepGym_MoveEvents(u8 puzzleNumber)
return localId;
}
-void MossdeepGym_TurnEvents(void)
+void TurnRotatingTileObjects(void)
{
u8 i;
s32 puzzleTileStart;
@@ -143,35 +154,44 @@ void MossdeepGym_TurnEvents(void)
return;
if (!sRotatingTilePuzzle->isTrickHouse)
- puzzleTileStart = METATILE_MossdeepGym_YellowRightArrow;
+ puzzleTileStart = METATILE_MossdeepGym_YellowArrow_Right;
else
puzzleTileStart = METATILE_TrickHousePuzzle_Arrow_YellowOnWhite_Right;
eventObjects = gSaveBlock1Ptr->eventObjectTemplates;
- for (i = 0; i < sRotatingTilePuzzle->count; i++)
+ for (i = 0; i < sRotatingTilePuzzle->numObjects; i++)
{
- s32 r6;
- s8 r0;
+ s32 rotation;
+ s8 tileDifference;
u8 eventObjectId;
s16 x = eventObjects[sRotatingTilePuzzle->objects[i].eventTemplateId].x + 7;
s16 y = eventObjects[sRotatingTilePuzzle->objects[i].eventTemplateId].y + 7;
u16 metatile = MapGridGetMetatileIdAt(x, y);
- r0 = (u8)((metatile - puzzleTileStart) % 8);
- r0 -= (sRotatingTilePuzzle->objects[i].unk0);
- if (r0 < 0 || r0 == 3)
+ // NOTE: The following 2 assignments and if else could all be replaced with rotation = ROTATE_COUNTERCLOCKWISE
+ // For an object to be saved in sRotatingTilePuzzle->objects, it must have been on a colored arrow tile
+ // After the first assignment, tileDifference will always be a number [0-3] representing which arrow tile the object is on now (0: right, 1: down, 2: left, 3: up)
+ // prevPuzzleTileNum will similarly be a number [0-3] representing the arrow tile the object just moved from
+ // All the puzzles are oriented counter-clockwise and can only move 1 step at a time, so the difference between the current tile and the previous tile will always either be -1 or 3 (0-1, 1-2, 2-3, 3-0)
+ // Which means tileDifference will always either be -1 or 3 after the below subtraction, and rotation will always be ROTATE_COUNTERCLOCKWISE after the following conditionals
+ tileDifference = (u8)((metatile - puzzleTileStart) % 8);
+ tileDifference -= (sRotatingTilePuzzle->objects[i].prevPuzzleTileNum);
+
+ // Always true, see above
+ if (tileDifference < 0 || tileDifference == 3)
{
- if (r0 == -3)
- r6 = 1;
+ // Always false, see above
+ if (tileDifference == -3)
+ rotation = ROTATE_CLOCKWISE;
else
- r6 = 0;
+ rotation = ROTATE_COUNTERCLOCKWISE;
}
else
{
- if (r0 > 0)
- r6 = 1;
+ if (tileDifference > 0)
+ rotation = ROTATE_CLOCKWISE;
else
- r6 = 2;
+ rotation = ROTATE_NONE;
}
eventObjectId = GetEventObjectIdByLocalIdAndMap(eventObjects[sRotatingTilePuzzle->objects[i].eventTemplateId].localId, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup);
@@ -179,24 +199,24 @@ void MossdeepGym_TurnEvents(void)
{
const u8 *movementScript;
u8 direction = gEventObjects[eventObjectId].facingDirection;
- if (r6 == 0)
+ if (rotation == ROTATE_COUNTERCLOCKWISE)
{
switch (direction)
{
case DIR_EAST:
- movementScript = MossdeepGym_Movement_FaceUp;
+ movementScript = RotatingTilePuzzle_Movement_FaceUp;
eventObjects[sRotatingTilePuzzle->objects[i].eventTemplateId].movementType = MOVEMENT_TYPE_FACE_UP;
break;
case DIR_SOUTH:
- movementScript = MossdeepGym_Movement_FaceRight;
+ movementScript = RotatingTilePuzzle_Movement_FaceRight;
eventObjects[sRotatingTilePuzzle->objects[i].eventTemplateId].movementType = MOVEMENT_TYPE_FACE_RIGHT;
break;
case DIR_WEST:
- movementScript = MossdeepGym_Movement_FaceDown;
+ movementScript = RotatingTilePuzzle_Movement_FaceDown;
eventObjects[sRotatingTilePuzzle->objects[i].eventTemplateId].movementType = MOVEMENT_TYPE_FACE_DOWN;
break;
case DIR_NORTH:
- movementScript = MossdeepGym_Movement_FaceLeft;
+ movementScript = RotatingTilePuzzle_Movement_FaceLeft;
eventObjects[sRotatingTilePuzzle->objects[i].eventTemplateId].movementType = MOVEMENT_TYPE_FACE_LEFT;
break;
default:
@@ -207,24 +227,25 @@ void MossdeepGym_TurnEvents(void)
gSaveBlock1Ptr->location.mapGroup,
movementScript);
}
- else if (r6 == 1)
+ // Never reached
+ else if (rotation == ROTATE_CLOCKWISE)
{
switch (direction)
{
case DIR_EAST:
- movementScript = MossdeepGym_Movement_FaceDown;
+ movementScript = RotatingTilePuzzle_Movement_FaceDown;
eventObjects[sRotatingTilePuzzle->objects[i].eventTemplateId].movementType = MOVEMENT_TYPE_FACE_DOWN;
break;
case DIR_SOUTH:
- movementScript = MossdeepGym_Movement_FaceLeft;
+ movementScript = RotatingTilePuzzle_Movement_FaceLeft;
eventObjects[sRotatingTilePuzzle->objects[i].eventTemplateId].movementType = MOVEMENT_TYPE_FACE_LEFT;
break;
case DIR_WEST:
- movementScript = MossdeepGym_Movement_FaceUp;
+ movementScript = RotatingTilePuzzle_Movement_FaceUp;
eventObjects[sRotatingTilePuzzle->objects[i].eventTemplateId].movementType = MOVEMENT_TYPE_FACE_UP;
break;
case DIR_NORTH:
- movementScript = MossdeepGym_Movement_FaceRight;
+ movementScript = RotatingTilePuzzle_Movement_FaceRight;
eventObjects[sRotatingTilePuzzle->objects[i].eventTemplateId].movementType = MOVEMENT_TYPE_FACE_RIGHT;
break;
default:
@@ -239,17 +260,18 @@ void MossdeepGym_TurnEvents(void)
}
}
-static void AddEventObject(u8 eventTemplateId, u8 arg1)
+static void SaveRotatingTileObject(u8 eventTemplateId, u8 puzzleTileNum)
{
- sRotatingTilePuzzle->objects[sRotatingTilePuzzle->count].eventTemplateId = eventTemplateId;
- sRotatingTilePuzzle->objects[sRotatingTilePuzzle->count].unk0 = arg1;
- sRotatingTilePuzzle->count++;
+ sRotatingTilePuzzle->objects[sRotatingTilePuzzle->numObjects].eventTemplateId = eventTemplateId;
+ sRotatingTilePuzzle->objects[sRotatingTilePuzzle->numObjects].prevPuzzleTileNum = puzzleTileNum;
+ sRotatingTilePuzzle->numObjects++;
}
-static void sub_81A8D94(u8 eventTemplateId, u8 arg1)
+// Functionally unused
+static void TurnUnsavedRotatingTileObject(u8 eventTemplateId, u8 puzzleTileNum)
{
- s8 r0;
- s32 r6;
+ s8 tileDifference;
+ s32 rotation;
s32 puzzleTileStart;
u16 movementType;
struct EventObjectTemplate *eventObjects = gSaveBlock1Ptr->eventObjectTemplates;
@@ -258,21 +280,22 @@ static void sub_81A8D94(u8 eventTemplateId, u8 arg1)
u16 metatile = MapGridGetMetatileIdAt(x, y);
if (!sRotatingTilePuzzle->isTrickHouse)
- puzzleTileStart = METATILE_MossdeepGym_YellowRightArrow;
+ puzzleTileStart = METATILE_MossdeepGym_YellowArrow_Right;
else
puzzleTileStart = METATILE_TrickHousePuzzle_Arrow_YellowOnWhite_Right;
- r0 = (u8)((metatile - puzzleTileStart) % 8);
- r0 -= arg1;
- if (r0 < 0 || r0 == 3)
- r6 = 0;
- else if (r0 > 0 || r0 == -3)
- r6 = 1;
+ tileDifference = (u8)((metatile - puzzleTileStart) % 8);
+ tileDifference -= puzzleTileNum;
+
+ if (tileDifference < 0 || tileDifference == 3)
+ rotation = ROTATE_COUNTERCLOCKWISE;
+ else if (tileDifference > 0 || tileDifference == -3)
+ rotation = ROTATE_CLOCKWISE;
else
- r6 = 2;
+ rotation = ROTATE_NONE;
movementType = eventObjects[eventTemplateId].movementType;
- if (r6 == 0)
+ if (rotation == ROTATE_COUNTERCLOCKWISE)
{
switch (movementType)
{
@@ -292,7 +315,7 @@ static void sub_81A8D94(u8 eventTemplateId, u8 arg1)
break;
}
}
- else if (r6 == 1)
+ else if (rotation == ROTATE_CLOCKWISE)
{
switch (movementType)
{